licailing 4 년 전
부모
커밋
5c0f5bfabc

+ 3 - 0
src/main/java/com/izouma/nineth/domain/Order.java

@@ -71,6 +71,9 @@ public class Order {
     @Searchable
     private Long userId;
 
+    @Transient
+    private String nickname;
+
     @ApiModelProperty("藏品ID")
     @Searchable
     private Long collectionId;

+ 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);
+    }
+}

+ 7 - 1
src/main/java/com/izouma/nineth/utils/JpaUtils.java

@@ -96,6 +96,9 @@ public class JpaUtils {
                                 .toLocalDateTime((String) list.get(0), "yyyy-MM-dd HH:mm:ss");
                         and.add(criteriaBuilder.greaterThanOrEqualTo(root.get(property), start));
                     } else if (list.size() == 2) {
+                        LocalDateTime start = DateTimeUtils
+                                .toLocalDateTime((String) list.get(0), "yyyy-MM-dd HH:mm:ss");
+                        and.add(criteriaBuilder.greaterThanOrEqualTo(root.get(property), start));
                         LocalDateTime end = DateTimeUtils
                                 .toLocalDateTime((String) list.get(1), "yyyy-MM-dd HH:mm:ss");
                         and.add(criteriaBuilder.lessThanOrEqualTo(root.get(property), end));
@@ -119,6 +122,9 @@ public class JpaUtils {
                                 .toLocalDate((String) list.get(0), "yyyy-MM-dd");
                         and.add(criteriaBuilder.greaterThanOrEqualTo(root.get(property), start));
                     } else if (list.size() == 2) {
+                        LocalDate start = DateTimeUtils
+                                .toLocalDate((String) list.get(0), "yyyy-MM-dd");
+                        and.add(criteriaBuilder.greaterThanOrEqualTo(root.get(property), start));
                         LocalDate end = DateTimeUtils
                                 .toLocalDate((String) list.get(1), "yyyy-MM-dd");
                         and.add(criteriaBuilder.lessThanOrEqualTo(root.get(property), end));
@@ -186,7 +192,7 @@ public class JpaUtils {
             }
             clazz = clazz.getSuperclass();
         }
-        log.error("no such field [{}] in class [{}]", property, className);
+        //log.error("no such field [{}] in class [{}]", property, className);
         return null;
     }
 }

+ 19 - 2
src/main/java/com/izouma/nineth/web/OrderController.java

@@ -2,6 +2,7 @@ package com.izouma.nineth.web;
 
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.izouma.nineth.domain.Order;
+import com.izouma.nineth.domain.User;
 import com.izouma.nineth.dto.OrderDTO;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.enums.CollectionType;
@@ -9,6 +10,7 @@ import com.izouma.nineth.enums.OrderStatus;
 import com.izouma.nineth.enums.PayMethod;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.OrderRepo;
+import com.izouma.nineth.repo.UserRepo;
 import com.izouma.nineth.service.OrderService;
 import com.izouma.nineth.utils.ObjUtils;
 import com.izouma.nineth.utils.SecurityUtils;
@@ -24,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -33,6 +36,7 @@ import java.util.stream.Collectors;
 public class OrderController extends BaseController {
     private OrderService orderService;
     private OrderRepo    orderRepo;
+    private UserRepo     userRepo;
 
     //@PreAuthorize("hasRole('ADMIN')")
     @PostMapping("/save")
@@ -52,6 +56,19 @@ public class OrderController extends BaseController {
         return orderService.all(pageQuery);
     }
 
+    @PostMapping("/backAll")
+    public Page<Order> backAll(@RequestBody PageQuery pageQuery) {
+        Page<Order> all = orderService.all(pageQuery);
+        List<Long> userIds = all.getContent().stream().map(Order::getUserId).distinct().collect(Collectors.toList());
+        Map<Long, String> userMap = userRepo.findAllById(userIds)
+                .stream()
+                .collect(Collectors.toMap(User::getId, User::getNickname));
+        return all.map(order -> {
+            order.setNickname(userMap.get(order.getUserId()));
+            return order;
+        });
+    }
+
     @GetMapping("/get/{id}")
     public Order get(@PathVariable Long id) {
         return orderRepo.findById(id).orElseThrow(new BusinessException("无记录"));
@@ -62,9 +79,9 @@ public class OrderController extends BaseController {
         orderRepo.softDelete(id);
     }
 
-    @GetMapping("/excel")
+    @PostMapping("/excel")
     @ResponseBody
-    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+    public void excel(HttpServletResponse response, @RequestBody PageQuery pageQuery) throws IOException {
         List<Order> data = all(pageQuery).getContent();
         ExcelUtils.export(response, data.stream().map(order -> {
             OrderDTO dto = new OrderDTO();

+ 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);
+    }
 }
 
 

+ 86 - 0
src/main/vue/src/components/CreatedAtPicker.vue

@@ -0,0 +1,86 @@
+<template>
+    <el-date-picker
+        v-model="date"
+        type="datetimerange"
+        :picker-options="pickerOptions"
+        range-separator="至"
+        :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', 'name'],
+    props: {
+        size: {
+            type: String,
+            default: ''
+        },
+        name: {
+            type: String,
+            default: '创建'
+        },
+        value: {
+            type: String | Array,
+            default: ''
+        }
+    },
+    data() {
+        return {
+            date: '',
+            pickerOptions: {
+                shortcuts: [
+                    {
+                        text: '最近一周',
+                        onClick(picker) {
+                            const end = new Date();
+                            const start = new Date();
+                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+                            picker.$emit('pick', [start, end]);
+                        }
+                    },
+                    {
+                        text: '最近一个月',
+                        onClick(picker) {
+                            const end = new Date();
+                            const start = new Date();
+                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+                            picker.$emit('pick', [start, end]);
+                        }
+                    },
+                    {
+                        text: '最近三个月',
+                        onClick(picker) {
+                            const end = new Date();
+                            const start = new Date();
+                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+                            picker.$emit('pick', [start, end]);
+                        }
+                    }
+                ]
+            }
+        };
+    },
+    methods: {
+        changeSelect(val) {
+            this.$emit('input', val);
+        }
+    },
+    watch: {
+        value() {
+            // if (this.value) {
+            this.date = this.value;
+            // }
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped></style>

+ 100 - 0
src/main/vue/src/components/MinterFilter.vue

@@ -0,0 +1,100 @@
+<template>
+    <el-select
+        v-model="minterId"
+        filterable
+        remote
+        reserve-keyword
+        placeholder="请输入铸造者"
+        :remote-method="searchMinter"
+        :loading="searchingMinter"
+        @change="changeSelect"
+        :disabled="disabled"
+        clearable
+    >
+        <el-option
+            v-for="item in minters"
+            :key="item.id"
+            :label="item.nickname"
+            :value="item.id"
+            class="minter-item"
+        >
+            <el-image :src="item.avatar" fit="cover" class="avatar"></el-image>
+            <div class="content">
+                <div class="name">{{ item.nickname }}</div>
+                <div class="id">#{{ item.id }}</div>
+            </div>
+        </el-option>
+    </el-select>
+</template>
+<script>
+export default {
+    props: {
+        value: {},
+        disabled: {
+            default() {
+                return false;
+            }
+        }
+    },
+    data() {
+        return {
+            minters: [],
+            minterId: null,
+            searchingMinter: false,
+            selected: null
+        };
+    },
+    created() {
+        this.$http.post('/user/all', { size: 30, query: { hasRole: 'ROLE_MINTER' } }, { body: 'json' }).then(res => {
+            this.minters = res.content;
+        });
+    },
+    methods: {
+        searchMinter(query) {
+            this.searchingMinter = true;
+            this.$http
+                .post('/user/all', { search: query, size: 30, query: { hasRole: 'ROLE_MINTER' } }, { body: 'json' })
+                .then(res => {
+                    this.minters = res.content;
+                    this.searchingMinter = false;
+                });
+        },
+        changeSelect(val) {
+            this.$emit('input', val);
+        }
+    },
+    watch: {
+        value(val) {
+            if (this.minterId !== val) {
+                this.minterId = val;
+            }
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.minter-item {
+    .flex();
+    height: 44px;
+    .avatar {
+        width: 32px;
+        height: 32px;
+        border-radius: 50%;
+    }
+    .content {
+        margin-left: 10px;
+        line-height: 1;
+        .flex-col();
+        justify-content: center;
+        .name {
+            font-size: 14px;
+            color: @text2;
+        }
+        .id {
+            font-size: 12px;
+            color: @text3;
+            margin-top: 5px;
+        }
+    }
+}
+</style>

+ 4 - 0
src/main/vue/src/main.js

@@ -16,8 +16,10 @@ import DistrictChoose from '@/components/DistrictChoose';
 import Formatters from '@/mixins/formatters';
 import PageTitle from '@/components/PageTitle';
 import MinterSelect from '@/components/MinterSelect';
+import MinterFilter from '@/components/MinterFilter';
 import ObjectUpload from '@/components/ObjectUpload';
 import CollectionSearch from '@/components/CollectionSearch';
+import CreatedAtPicker from '@/components/CreatedAtPicker';
 
 import 'normalize.css/normalize.css';
 import './styles/element_theme/index.css';
@@ -58,8 +60,10 @@ Vue.component('crop-upload', CropUpload);
 Vue.component('district-choose', DistrictChoose);
 Vue.component('page-title', PageTitle);
 Vue.component('minter-select', MinterSelect);
+Vue.component('minter-filter', MinterFilter);
 Vue.component('object-upload', ObjectUpload);
 Vue.component('collection-search', CollectionSearch);
+Vue.component('created-at-picker', CreatedAtPicker);
 Vue.mixin(Formatters);
 Vue.prototype.$theme = theme;
 console.log(theme);

+ 4 - 0
src/main/vue/src/styles/app.less

@@ -82,6 +82,10 @@ li {
         margin-bottom: 10px;
         margin-right: 10px;
         margin-left: 0;
+        &.el-date-editor {
+            position: relative;
+            top: 1px;
+        }
     }
 
     .filter-item.el-input {

+ 8 - 2
src/main/vue/src/views/AirDropList.vue

@@ -15,6 +15,10 @@
             </el-button> -->
         </page-title>
         <div class="filters-container">
+            <created-at-picker v-model="createdAt" @input="getData" style="margin-right: 10px"></created-at-picker>
+            <el-select v-model="type" clearable placeholder="请选择空投类型" @change="getData">
+                <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
+            </el-select>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -90,7 +94,9 @@ export default {
             typeOptions: [
                 { label: '藏品', value: 'asset' },
                 { label: '兑换券', value: 'coupon' }
-            ]
+            ],
+            createdAt: '',
+            type: ''
         };
     },
     computed: {
@@ -107,7 +113,7 @@ export default {
             return '';
         },
         beforeGetData() {
-            return { search: this.search, query: { del: false } };
+            return { search: this.search, query: { del: false, createdAt: this.createdAt, type: this.type } };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;

+ 9 - 2
src/main/vue/src/views/BlindBoxList.vue

@@ -21,6 +21,8 @@
             </el-button> -->
         </page-title>
         <div class="filters-container">
+            <created-at-picker v-model="createdAt" @input="getData" class="filter-item"></created-at-picker>
+            <minter-filter v-model="minterId" @input="getData" class="filter-item"></minter-filter>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -119,7 +121,9 @@ export default {
                 { label: '官方', value: 'OFFICIAL' },
                 { label: '用户铸造', value: 'USER' },
                 { label: '转让', value: 'TRANSFER' }
-            ]
+            ],
+            createdAt: '',
+            minterId: ''
         };
     },
     computed: {
@@ -143,7 +147,10 @@ export default {
             return '';
         },
         beforeGetData() {
-            return { search: this.search, query: { del: false, type: 'BLIND_BOX' } };
+            return {
+                search: this.search,
+                query: { del: false, type: 'BLIND_BOX', createdAt: this.createdAt, minterId: this.minterId }
+            };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;

+ 11 - 3
src/main/vue/src/views/CollectionList.vue

@@ -21,6 +21,8 @@
             </el-button> -->
         </page-title>
         <div class="filters-container">
+            <created-at-picker v-model="createdAt" @input="getData" class="filter-item"></created-at-picker>
+            <minter-filter v-model="minterId" @input="getData" class="filter-item"></minter-filter>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -126,9 +128,10 @@
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 import SortableHeader from '../components/SortableHeader.vue';
+import MinterSelect from '../components/MinterSelect.vue';
 
 export default {
-    components: { SortableHeader },
+    components: { SortableHeader, MinterSelect },
     name: 'CollectionList',
     mixins: [pageableTable],
     data() {
@@ -148,7 +151,9 @@ export default {
                 { label: '转让', value: 'TRANSFER' }
             ],
             sort: { sort: 'desc' },
-            sortStr: 'sort,desc'
+            sortStr: 'sort,desc',
+            createdAt: '',
+            minterId: ''
         };
     },
     computed: {
@@ -172,7 +177,10 @@ export default {
             return '';
         },
         beforeGetData() {
-            return { search: this.search, query: { del: false, source: 'OFFICIAL' } };
+            return {
+                search: this.search,
+                query: { del: false, source: 'OFFICIAL', createdAt: this.createdAt, minterId: this.minterId }
+            };
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;

+ 5 - 1
src/main/vue/src/views/CommissionRecordList.vue

@@ -50,7 +50,11 @@
             <el-table-column prop="orderId" label="订单ID"> </el-table-column>
             <el-table-column prop="totalPrice" label="订单总价"> </el-table-column>
             <el-table-column prop="shareRatio" label="分成比例"> </el-table-column>
-            <el-table-column prop="shareAmount" label="分成金额"> </el-table-column>
+            <el-table-column prop="shareAmount" label="分成金额">
+                <template slot="header" slot-scope="{ column }">
+                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
+                </template>
+            </el-table-column>
         </el-table>
         <div class="pagination-wrapper">
             <!-- <div class="multiple-mode-wrapper">

+ 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;

+ 68 - 9
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
@@ -48,7 +48,11 @@
             <el-table-column prop="phone" label="手机"> </el-table-column>
             <el-table-column prop="code" label="邀请码"> </el-table-column>
             <el-table-column prop="remark" label="备注"> </el-table-column>
-            <el-table-column prop="inviteNum" label="邀请人数"> </el-table-column>
+            <el-table-column prop="inviteNum" label="邀请人数">
+                <template slot="header" slot-scope="{ column }">
+                    <sortable-header :column="column" :current-sort="sort" @changeSort="changeSort"> </sortable-header>
+                </template>
+            </el-table-column>
             <el-table-column label="操作" align="center" fixed="right" width="350">
                 <template slot-scope="{ row }">
                     <el-button @click="detail(row)" size="mini">邀请列表</el-button>
@@ -80,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">
-            <vue-qrcode :value="codeValue" :options="{ width: 300, margin: 2 }"></vue-qrcode>
-            <div>右键点击二维码可保存</div>
+        <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>
         </el-dialog>
     </div>
 </template>
@@ -111,7 +132,9 @@ export default {
             dialogLoading: false,
             list: [],
             showCodeDialog: false,
-            codeValue: 'Hello, World!'
+            codeValue: 'Hello, World!',
+            inviteCode: '',
+            createdAt: ''
         };
     },
     computed: {
@@ -195,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;
@@ -207,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);
+                });
         }
     }
 };

+ 35 - 10
src/main/vue/src/views/OrderList.vue

@@ -21,7 +21,7 @@
             </el-button>
         </page-title>
         <div class="filters-container">
-            <el-select v-model="status" placeholder="筛选状态" clearable @change="getData">
+            <el-select v-model="status" placeholder="筛选状态" clearable @change="getData" class="filter-item">
                 <el-option
                     v-for="item in statusOptions"
                     :key="item.value"
@@ -29,6 +29,7 @@
                     :label="item.label"
                 ></el-option>
             </el-select>
+            <created-at-picker v-model="createdAt" @input="getData" name="下单" class="filter-item"></created-at-picker>
             <el-input
                 placeholder="搜索..."
                 v-model="search"
@@ -51,10 +52,11 @@
             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="ID" width="155"> </el-table-column>
             <el-table-column prop="userId" label="用户ID"> </el-table-column>
+            <el-table-column prop="nickname" label="用户昵称" show-overflow-tooltip> </el-table-column>
             <el-table-column prop="collectionId" label="藏品ID"> </el-table-column>
-            <el-table-column prop="name" label="名称" show-overflow-tooltip> </el-table-column>
+            <el-table-column prop="name" label="名称" min-width="120" show-overflow-tooltip> </el-table-column>
             <el-table-column prop="pic" label="图片" width="80">
                 <template slot-scope="{ row }">
                     <el-image
@@ -71,7 +73,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>
@@ -109,15 +111,17 @@
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
+import CreatedAtPicker from '../components/CreatedAtPicker.vue';
 
 export default {
+    components: { CreatedAtPicker },
     name: 'OrderList',
     mixins: [pageableTable],
     data() {
         return {
             multipleMode: false,
             search: '',
-            url: '/order/all',
+            url: '/order/backAll',
             downloading: false,
             statusOptions: [
                 { label: '未支付', value: 'NOT_PAID' },
@@ -129,7 +133,8 @@ export default {
                 { label: '微信', value: 'WEIXIN' },
                 { label: '支付宝', value: 'ALIPAY' }
             ],
-            status: null
+            status: null,
+            createdAt: []
         };
     },
     computed: {
@@ -152,8 +157,27 @@ export default {
             }
             return '';
         },
+        getParams() {
+            let data = {
+                // sort: 'createdAt,desc',
+                query: {
+                    del: false
+                }
+            };
+            if (this.search) {
+                data.search = this.search;
+            }
+            if (this.createdAt) {
+                data.query.createdAt = this.createdAt;
+            }
+            if (this.status) {
+                data.query.status = this.status;
+            }
+            return data;
+        },
         beforeGetData() {
-            return { search: this.search, query: { del: false, status: this.status } };
+            // return { search: this.search, query: { del: false, status: this.status } };
+            return this.getParams();
         },
         toggleMultipleMode(multipleMode) {
             this.multipleMode = multipleMode;
@@ -179,10 +203,11 @@ export default {
         },
         download() {
             this.downloading = true;
+            let params = this.getParams();
+            params.size = 10000;
             this.$axios
-                .get('/order/excel', {
-                    responseType: 'blob',
-                    params: { size: 10000 }
+                .post('/order/excel', params, {
+                    responseType: 'blob'
                 })
                 .then(res => {
                     console.log(res);

+ 1 - 1
src/main/vue/src/views/RecommendList.vue

@@ -12,7 +12,7 @@
             </el-button>
         </page-title>
         <div class="filters-container">
-            <el-select v-model="type" clearable @change="getData">
+            <el-select v-model="type" clearable @change="getData" placeholder="请选择类型">
                 <el-option v-for="item in typeOptions" :label="item.label" :value="item.value" :key="item.value"></el-option>
             </el-select>
             <el-input

+ 5 - 3
src/main/vue/src/views/UserList.vue

@@ -9,6 +9,7 @@
             </el-button>
         </page-title>
         <div class="filters-container" @keyup.enter="getData">
+            <created-at-picker v-model="createdAt" @input="getData" name="注册" class="filter-item"></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>
@@ -42,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>
@@ -82,7 +83,8 @@ export default {
             multipleMode: false,
             search: '',
             url: '/user/all',
-            downloading: false
+            downloading: false,
+            createdAt: ''
         };
     },
     computed: {
@@ -93,7 +95,7 @@ export default {
     },
     methods: {
         beforeGetData() {
-            return { search: this.search, query: {} };
+            return { search: this.search, query: { createdAt: this.createdAt } };
         },
         afterGetData(res) {
             // let i = this.tableData.findIndex(i => i.username === 'root');