licailing 4 лет назад
Родитель
Сommit
a3139354dc

+ 31 - 0
src/main/java/com/izouma/nineth/dto/InvitePhoneDTO.java

@@ -0,0 +1,31 @@
+package com.izouma.nineth.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.izouma.nineth.domain.User;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+
+import java.time.LocalDateTime;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class InvitePhoneDTO {
+    @ExcelProperty(value = "昵称")
+    private String nickName;
+
+    @ExcelProperty(value = "手机号")
+    private String phone;
+
+    @ExcelProperty("注册时间")
+    private LocalDateTime createdAt;
+
+    @ExcelProperty("邀请人")
+    private String invitorName;
+
+    public InvitePhoneDTO(User user) {
+        BeanUtils.copyProperties(user, this);
+    }
+}

+ 11 - 4
src/main/java/com/izouma/nineth/web/UserController.java

@@ -2,10 +2,7 @@ package com.izouma.nineth.web;
 
 import com.huifu.adapay.core.exception.BaseAdaPayException;
 import com.izouma.nineth.domain.User;
-import com.izouma.nineth.dto.PageQuery;
-import com.izouma.nineth.dto.UserBankCard;
-import com.izouma.nineth.dto.UserDTO;
-import com.izouma.nineth.dto.UserRegister;
+import com.izouma.nineth.dto.*;
 import com.izouma.nineth.enums.AuthorityName;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.UserBankCardRepo;
@@ -243,6 +240,16 @@ public class UserController extends BaseController {
     public Map<String, Object> batchRegister(@RequestParam String phones, @RequestParam String defaultPassword) {
         return userService.batchRegister(phones, defaultPassword);
     }
+
+    @PreAuthorize("hasAnyRole('ADMIN')")
+    @PostMapping("/exportInvite")
+    @ResponseBody
+    public void exportInvite(HttpServletResponse response, @RequestBody PageQuery pageQuery) throws IOException {
+        List<InvitePhoneDTO> data = userService.all(pageQuery)
+                .map(InvitePhoneDTO::new)
+                .getContent();
+        ExcelUtils.export(response, data);
+    }
 }
 
 

+ 21 - 6
src/main/vue/src/components/CreatedAtPicker.vue

@@ -4,19 +4,34 @@
         type="datetimerange"
         :picker-options="pickerOptions"
         range-separator="至"
-        start-placeholder="创建开始时间"
-        end-placeholder="创建结束时间"
+        :start-placeholder="`${name}开始时间`"
+        :end-placeholder="`${name}结束时间`"
         align="right"
         value-format="yyyy-MM-dd HH:mm:ss"
         :default-time="['00:00:00', '23:59:59']"
         @change="changeSelect"
+        :size="size"
     >
     </el-date-picker>
 </template>
 
 <script>
 export default {
-    props: ['value'],
+    // props: ['value', 'name'],
+    props: {
+        size: {
+            type: String,
+            default: ''
+        },
+        name: {
+            type: String,
+            default: '创建'
+        },
+        value: {
+            type: String | Array,
+            default: ''
+        }
+    },
     data() {
         return {
             date: '',
@@ -60,9 +75,9 @@ export default {
     },
     watch: {
         value() {
-            if (this.value) {
-                this.date = this.value;
-            }
+            // if (this.value) {
+            this.date = this.value;
+            // }
         }
     }
 };

+ 4 - 2
src/main/vue/src/views/CouponList.vue

@@ -21,6 +21,7 @@
             </el-button> -->
         </page-title>
         <div class="filters-container">
+            <created-at-picker v-model="expiration" @input="getData" name="到期" style="margin-right: 10px"></created-at-picker>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -99,7 +100,8 @@ export default {
             multipleMode: false,
             search: '',
             url: '/coupon/all',
-            downloading: false
+            downloading: false,
+            expiration: ''
         };
     },
     computed: {
@@ -109,7 +111,7 @@ export default {
     },
     methods: {
         beforeGetData() {
-            return { search: this.search, query: { del: false } };
+            return { search: this.search, query: { del: false, expiration: this.expiration } };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;

+ 62 - 7
src/main/vue/src/views/InviteList.vue

@@ -10,7 +10,7 @@
             >
                 新增
             </el-button>
-            <el-button
+            <!-- <el-button
                 @click="download"
                 icon="el-icon-upload2"
                 :loading="downloading"
@@ -18,7 +18,7 @@
                 class="filter-item"
             >
                 导出
-            </el-button>
+            </el-button> -->
         </page-title>
         <div class="filters-container">
             <el-input
@@ -84,16 +84,33 @@
             </el-pagination>
         </div>
         <el-dialog :visible.sync="showDialog" title="邀请列表" width="800px" top="10vh">
+            <div>
+                <el-button
+                    style="margin: 0 10px 10px 25px"
+                    size="mini"
+                    type="primary"
+                    @click="downloadPhone"
+                    :disabled="downloading"
+                    >导出手机号</el-button
+                >
+                <created-at-picker
+                    v-model="createdAt"
+                    name="注册"
+                    @input="getInviteInfo"
+                    size="mini"
+                ></created-at-picker>
+            </div>
             <el-table :data="list" v-loading="dialogLoading" height="60vh">
                 <el-table-column prop="id" label="ID" width="80"></el-table-column>
                 <el-table-column prop="nickname" label="昵称"></el-table-column>
                 <el-table-column prop="phone" label="手机"></el-table-column>
+                <el-table-column prop="createdAt" label="注册时间"></el-table-column>
             </el-table>
         </el-dialog>
 
         <el-dialog :visible.sync="showCodeDialog" title="二维码" width="400px" center>
-            <vue-qrcode :value="codeValue" :options="{ width: 300, margin: 2 }" style="margin-left:25px"></vue-qrcode>
-            <div style="margin-left:40px;font-size:16px">右键点击二维码可保存</div>
+            <vue-qrcode :value="codeValue" :options="{ width: 300, margin: 2 }" style="margin-left: 25px"></vue-qrcode>
+            <div style="margin-left: 40px; font-size: 16px">右键点击二维码可保存</div>
         </el-dialog>
     </div>
 </template>
@@ -115,7 +132,9 @@ export default {
             dialogLoading: false,
             list: [],
             showCodeDialog: false,
-            codeValue: 'Hello, World!'
+            codeValue: 'Hello, World!',
+            inviteCode: '',
+            createdAt: ''
         };
     },
     computed: {
@@ -199,10 +218,19 @@ export default {
         },
         detail(row) {
             this.list = [];
-            this.dialogLoading = true;
+            this.createdAt = '';
             this.showDialog = true;
+            this.inviteCode = row.code;
+            this.getInviteInfo();
+        },
+        getInviteInfo() {
+            this.dialogLoading = true;
             this.$http
-                .post('/user/all', { size: 10000, query: { inviteCode: row.code } }, { body: 'json' })
+                .post(
+                    '/user/all',
+                    { size: 10000, sort: 'id,desc', query: { inviteCode: this.inviteCode, createdAt: this.createdAt } },
+                    { body: 'json' }
+                )
                 .then(res => {
                     this.list = res.content;
                     this.dialogLoading = false;
@@ -211,6 +239,33 @@ export default {
         showCode(row) {
             this.codeValue = 'https://www.raex.vip/9th/?inviteCode=' + row.code;
             this.showCodeDialog = true;
+        },
+        downloadPhone() {
+            this.downloading = true;
+            this.$axios
+                .post(
+                    '/user/exportInvite',
+                    { size: 10000, sort: 'id,desc', query: { inviteCode: this.inviteCode, createdAt: this.createdAt } },
+                    {
+                        responseType: 'blob'
+                    }
+                )
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', '手机号.xlsx');
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
         }
     }
 };

+ 2 - 2
src/main/vue/src/views/OrderList.vue

@@ -29,7 +29,7 @@
                     :label="item.label"
                 ></el-option>
             </el-select>
-            <created-at-picker v-model="createdAt" @input="getData"></created-at-picker>
+            <created-at-picker v-model="createdAt" name="下单" @input="getData"></created-at-picker>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -72,7 +72,7 @@
             <el-table-column prop="status" label="状态" :formatter="statusFormatter"> </el-table-column>
             <el-table-column prop="payMethod" label="支付方式" :formatter="payMethodFormatter"> </el-table-column>
             <el-table-column prop="transactionId" label="交易ID" show-overflow-tooltip> </el-table-column>
-            <el-table-column prop="createdAt" label="创建时间" width="140"> </el-table-column>
+            <el-table-column prop="createdAt" label="下单时间" width="140"> </el-table-column>
             <el-table-column prop="payTime" label="支付时间" width="140"> </el-table-column>
             <el-table-column prop="txHash" label="链上hash" show-overflow-tooltip> </el-table-column>
             <el-table-column prop="gasUsed" label="消耗gas"></el-table-column>

+ 2 - 2
src/main/vue/src/views/UserList.vue

@@ -9,7 +9,7 @@
             </el-button>
         </page-title>
         <div class="filters-container" @keyup.enter="getData">
-            <created-at-picker v-model="createdAt" @input="getData"></created-at-picker>
+            <created-at-picker v-model="createdAt" name="注册" @input="getData"></created-at-picker>
             <el-input placeholder="搜索..." v-model="search" clearable class="filter-item search">
                 <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
             </el-input>
@@ -43,7 +43,7 @@
                 </template>
             </el-table-column>
             <el-table-column label="手机" prop="phone"></el-table-column>
-            <el-table-column label="创建时间" prop="createdAt" width="150"></el-table-column>
+            <el-table-column label="注册时间" prop="createdAt" width="150"></el-table-column>
             <el-table-column label="操作" align="center" fixed="right" width="200">
                 <template slot-scope="{ row }">
                     <el-button @click="editRow(row)" type="text">编辑</el-button>

+ 17 - 0
src/test/java/com/izouma/nineth/service/UserServiceTest.java

@@ -4,6 +4,7 @@ import com.github.kevinsawicki.http.HttpRequest;
 import com.izouma.nineth.ApplicationTests;
 import com.izouma.nineth.config.Constants;
 import com.izouma.nineth.domain.User;
+import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.UserRegister;
 import com.izouma.nineth.enums.AuthorityName;
 import com.izouma.nineth.repo.UserRepo;
@@ -17,6 +18,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 public class UserServiceTest extends ApplicationTests {
 
@@ -101,4 +105,17 @@ public class UserServiceTest extends ApplicationTests {
                 "13799940755\n" +
                 "18301015323", "123456");
     }
+
+    @Test
+    public void test() {
+        PageQuery pageQuery = new PageQuery();
+        Map<String, Object> query = pageQuery.getQuery();
+        query.put("inviteCode", "JL21FF");
+        pageQuery.setSize(5000);
+        List<User> phone = userService.all(pageQuery)
+                .getContent();
+        phone.forEach(user -> System.out.println(user.getPhone() + ":" + user.getCreatedAt()));
+        // 2022-01-14T15:53:58 504 第一次查询
+        phone.forEach(user -> System.out.print(user.getPhone() + " "));
+    }
 }