Explorar o código

铸造管理后台/ 统计

licailing %!s(int64=3) %!d(string=hai) anos
pai
achega
e2ab2c765d

+ 4 - 0
src/main/java/com/izouma/nineth/repo/MintActivityRepo.java

@@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
+import java.util.Collection;
+import java.util.List;
 import java.util.Optional;
 
 public interface MintActivityRepo extends JpaRepository<MintActivity, Long>, JpaSpecificationExecutor<MintActivity> {
@@ -21,4 +23,6 @@ public interface MintActivityRepo extends JpaRepository<MintActivity, Long>, Jpa
     @Modifying
     @Transactional
     void addStock(Long id);
+
+    List<MintActivity> findAllByIdInAndDelFalse(Collection<Long> id);
 }

+ 3 - 0
src/main/java/com/izouma/nineth/repo/OrderRepo.java

@@ -9,6 +9,7 @@ import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
 import java.time.LocalDateTime;
+import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
 
@@ -38,4 +39,6 @@ public interface OrderRepo extends JpaRepository<Order, Long>, JpaSpecificationE
 
     Order findByTransactionId(String txId);
 
+    long countAllByPayTimeAfter(LocalDateTime payTime);
+
 }

+ 5 - 0
src/main/java/com/izouma/nineth/repo/UserRepo.java

@@ -11,8 +11,10 @@ import org.springframework.data.jpa.repository.Query;
 import org.springframework.lang.NonNull;
 
 import javax.transaction.Transactional;
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 
 public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
     @Transactional
@@ -168,4 +170,7 @@ public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExe
 
     @Query("select phone from User where id = ?1 and del = false")
     String findPhoneById(Long id);
+
+    //每日普通用户新增
+    long countAllByCreatedAtAfterAndAuthoritiesContainsAndDelFalse(LocalDateTime createdAt, Authority authority);
 }

+ 29 - 0
src/main/java/com/izouma/nineth/service/StatisticService.java

@@ -0,0 +1,29 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.enums.AuthorityName;
+import com.izouma.nineth.repo.OrderRepo;
+import com.izouma.nineth.repo.UserRepo;
+import com.izouma.nineth.security.Authority;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+@Service
+@AllArgsConstructor
+public class StatisticService {
+
+    private UserRepo  userRepo;
+    private OrderRepo orderRepo;
+
+    public void dayAdd() {
+        LocalDateTime day = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
+        // 用户今日新增
+        long user = userRepo.countAllByCreatedAtAfterAndAuthoritiesContainsAndDelFalse(day, Authority.get(AuthorityName.ROLE_USER));
+        // 订单今日新增
+        long order = orderRepo.countAllByPayTimeAfter(day);
+
+    }
+}

+ 14 - 1
src/main/java/com/izouma/nineth/web/MintOrderController.java

@@ -1,8 +1,10 @@
 package com.izouma.nineth.web;
 
 import com.izouma.nineth.converter.LongArrayConverter;
+import com.izouma.nineth.domain.MintActivity;
 import com.izouma.nineth.domain.MintOrder;
 import com.izouma.nineth.dto.MintOrderDTO;
+import com.izouma.nineth.repo.MintActivityRepo;
 import com.izouma.nineth.service.MintOrderService;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.exception.BusinessException;
@@ -18,6 +20,9 @@ import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/mintOrder")
@@ -25,6 +30,7 @@ import java.util.List;
 public class MintOrderController extends BaseController {
     private MintOrderService mintOrderService;
     private MintOrderRepo    mintOrderRepo;
+    private MintActivityRepo mintActivityRepo;
 
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
@@ -41,7 +47,14 @@ public class MintOrderController extends BaseController {
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/all")
     public Page<MintOrder> all(@RequestBody PageQuery pageQuery) {
-        return mintOrderService.all(pageQuery);
+        Page<MintOrder> all = mintOrderService.all(pageQuery);
+        Set<Long> mids = all.map(MintOrder::getMintActivityId).stream().collect(Collectors.toSet());
+        Map<Long, String> activityMap = mintActivityRepo.findAllByIdInAndDelFalse(mids)
+                .stream()
+                .collect(Collectors.toMap(MintActivity::getId, MintActivity::getName));
+        return all.map(mintOrder -> {
+            return mintOrder;
+        });
     }
 
     @GetMapping("/get/{id}")

+ 98 - 18
src/main/vue/src/views/MintActivityEdit.vue

@@ -19,7 +19,7 @@
                     <el-form-item prop="name" label="活动名称">
                         <el-input v-model="formData.name"></el-input>
                     </el-form-item>
-                    <el-form-item prop="owner" label="铸造者">
+                    <el-form-item prop="minterId" label="铸造者">
                         <minter-select v-model="formData.minterId" @detail="onMinterDetail"></minter-select>
                     </el-form-item>
                     <el-form-item prop="cover" label="封面">
@@ -29,24 +29,30 @@
                         <rich-text v-model="formData.detail"></rich-text>
                     </el-form-item>
                     <el-form-item prop="collectionName" label="藏品名称">
-                        <el-input v-model="formData.collectionName"></el-input>
-                    </el-form-item>
-                    <el-form-item prop="num" label="藏品数量">
-                        <el-input-number type="number" v-model="formData.num"></el-input-number>
-                    </el-form-item>
-                    <el-form-item prop="consume" label="是否消耗藏品">
-                        <el-radio v-model="formData.consume" :label="true">是</el-radio>
-                        <el-radio v-model="formData.consume" :label="false">否</el-radio>
-                    </el-form-item>
-                    <el-form-item prop="gasPrice" label="铸造gas费">
-                        <el-input-number v-model="formData.gasPrice"></el-input-number>
-                    </el-form-item>
-                    <el-form-item prop="total" label="发行数量">
-                        <el-input-number type="number" v-model="formData.total"></el-input-number>
+                        <el-input v-model="formData.collectionName" :disabled="!canEdit"></el-input>
                     </el-form-item>
+                    <div class="inline-wrapper">
+                        <el-form-item prop="num" label="藏品数量">
+                            <el-input-number type="number" v-model="formData.num" :disabled="!canEdit"></el-input-number>
+                        </el-form-item>
+                        <el-form-item prop="total" label="发行数量">
+                            <el-input-number type="number" v-model="formData.total" :disabled="!canEdit"></el-input-number>
+                        </el-form-item>
+                    </div>
+                    <div class="inline-wrapper">
+                        <el-form-item prop="consume" label="是否消耗藏品">
+                            <el-radio-group v-model="formData.consume" :disabled="!canEdit">
+                                <el-radio :label="true">是</el-radio>
+                                <el-radio :label="false">否</el-radio>
+                            </el-radio-group>
+                        </el-form-item>
+                        <el-form-item prop="gasPrice" label="铸造gas费">
+                            <el-input-number v-model="formData.gasPrice" :disabled="!canEdit"></el-input-number>
+                        </el-form-item>
+                    </div>
                     <el-form-item prop="airDrop" label="类型">
-                        <el-radio v-model="formData.airDrop" :label="true">空投铸造</el-radio>
-                        <el-radio v-model="formData.airDrop" :label="false">实物铸造</el-radio>
+                        <el-radio v-model="formData.airDrop" :label="true" :disabled="!canEdit">空投铸造</el-radio>
+                        <el-radio v-model="formData.airDrop" :label="false" :disabled="!canEdit">实物铸造</el-radio>
                     </el-form-item>
                     <el-form-item class="form-submit">
                         <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
@@ -80,7 +86,80 @@ export default {
         return {
             saving: false,
             formData: {},
-            rules: {}
+            rules: {
+                name: [
+                    {
+                        required: true,
+                        message: '请输入名称',
+                        trigger: 'blur'
+                    }
+                ],
+                minterId: [
+                    {
+                        required: true,
+                        message: '请输入铸造者ID',
+                        trigger: 'blur'
+                    }
+                ],
+                cover: [
+                    {
+                        validator: (rule, value, callback) => {
+                            if (value) {
+                                if (!(value instanceof Array)) {
+                                    callback(new Error('请上传内容'));
+                                    return;
+                                } else {
+                                    for (let f of value) {
+                                        if (!f.url) {
+                                            callback(new Error('请上传内容'));
+                                            return;
+                                        }
+                                    }
+                                }
+                                callback();
+                            } else {
+                                callback(new Error('请上传内容'));
+                            }
+                        },
+                        trigger: 'blur'
+                    }
+                ],
+                total: [
+                    {
+                        required: true,
+                        message: '请输入发行数量',
+                        trigger: 'blur'
+                    }
+                ],
+                num: [
+                    {
+                        required: true,
+                        message: '请输入藏品数量',
+                        trigger: 'blur'
+                    }
+                ],
+                consume: [
+                    {
+                        required: true,
+                        message: '请选择是否消耗藏品',
+                        trigger: 'blur'
+                    }
+                ],
+                gasPrice: [
+                    {
+                        required: true,
+                        message: '请输入铸造GAS费',
+                        trigger: 'blur'
+                    }
+                ],
+                airDrop: [
+                    {
+                        required: true,
+                        message: '请选择类型',
+                        trigger: 'blur'
+                    }
+                ]
+            }
         };
     },
     computed: {
@@ -143,6 +222,7 @@ export default {
 .inline-wrapper {
     .el-form-item {
         display: inline-block;
+        width: 270px;
     }
 }
 </style>

+ 4 - 5
src/main/vue/src/views/MintActivityList.vue

@@ -61,14 +61,13 @@
                     <el-tag type="info" v-else>否</el-tag>
                 </template>
             </el-table-column>
-
-            <el-table-column prop="stock" label="剩余数量"> </el-table-column>
             <el-table-column prop="total" label="发行数量"> </el-table-column>
+            <el-table-column prop="stock" label="剩余数量"> </el-table-column>
             <el-table-column prop="gasPrice" label="GAS费"></el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" width="150">
+            <el-table-column label="操作" align="center" fixed="right" width="120">
                 <template slot-scope="{ row }">
-                    <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button>
-                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button>
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain>详情</el-button>
+                    <!-- <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button> -->
                 </template>
             </el-table-column>
         </el-table>

+ 20 - 8
src/main/vue/src/views/MintOrderList.vue

@@ -44,22 +44,32 @@
             v-loading="fetchingData"
         >
             <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
-            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="id" label="订单编号" width="100"> </el-table-column>
             <el-table-column prop="userId" label="用户ID"> </el-table-column>
             <el-table-column prop="phone" label="手机号"> </el-table-column>
-            <el-table-column prop="createdAt" label="铸造时间" min-width="120"> </el-table-column>
-            <!-- <el-table-column prop="mintActivityId" label="活动名称"> </el-table-column> -->
-            <el-table-column prop="material" label="铸造材料" min-width="120">
+            <el-table-column prop="mintActivityId" label="铸造活动ID"> </el-table-column>
+            <el-table-column prop="mintActivity" label="活动名称"></el-table-column>
+            <!-- <el-table-column prop="createdAt" label="铸造时间" min-width="120"> </el-table-column> -->
+            <el-table-column prop="material" label="铸造材料详情" min-width="120">
                 <template slot-scope="{ row }">
                     <span v-for="item in row.material" :key="item.assestId">{{ item.name }}<br /></span>
                 </template>
             </el-table-column>
-            <el-table-column prop="consume" label="消耗藏品" width="90" align="center">
+            <!-- <el-table-column prop="consume" label="消耗藏品" width="90" align="center">
                 <template v-slot="{ row }">
                     <el-tag type="success" v-if="row.consume">是</el-tag>
                     <el-tag type="info" v-else>否</el-tag>
                 </template>
+            </el-table-column> -->
+            <el-table-column label="收件人信息">
+                <template slot-scope="{ row }">
+                    <span>{{ row.contactName }}</span>
+                    <span style="margin-left: 10px">{{ row.contactPhone }}</span
+                    ><br />
+                    <span>{{ row.address }}</span>
+                </template>
             </el-table-column>
+            <el-table-column prop="payAt" label="支付时间"></el-table-column>
             <!-- <el-table-column prop="payMethod" label="支付方式" :formatter="payMethodFormatter"> </el-table-column>
             <el-table-column prop="payAt" label="支付时间"> </el-table-column>
             <el-table-column prop="contactName" label="收货人"> </el-table-column>
@@ -67,9 +77,11 @@
             <el-table-column prop="address" label="收货地址"> </el-table-column>
             <el-table-column prop="gasPrice" label="gas费"> </el-table-column> -->
             <el-table-column prop="status" label="状态" :formatter="statusFormatter"> </el-table-column>
-            <el-table-column label="操作" align="center" fixed="right" width="160">
+            <el-table-column label="操作" align="right" fixed="right" width="160">
                 <template slot-scope="{ row }">
-                    <el-button @click="finish(row)" type="warning" size="mini" plain v-if="row.status == 'AIR_DROP'">已空投</el-button>
+                    <el-button @click="finish(row)" type="warning" size="mini" plain v-if="row.status == 'AIR_DROP'"
+                        >已空投</el-button
+                    >
                     <el-button @click="editRow(row)" type="primary" size="mini" plain>查看</el-button>
                     <!-- <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button> -->
                 </template>
@@ -147,7 +159,7 @@ export default {
             return '';
         },
         beforeGetData() {
-            return { search: this.search, query: { del: false, createdAt: this.createdAt } };
+            return { search: this.search, query: { del: false, payAt: this.createdAt } };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;