wangqifan %!s(int64=2) %!d(string=hai) anos
pai
achega
d9543976db

+ 37 - 0
src/main/java/com/izouma/nineth/repo/TradeAuctionOrderRepo.java

@@ -10,6 +10,7 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -24,4 +25,40 @@ public interface TradeAuctionOrderRepo extends JpaRepository<TradeAuctionOrder,
     List<TradeAuctionOrder> findByStatusAndDelFalse(AuctionOrderStatus status);
 
     List<TradeAuctionOrder> findByPaybackStatus(PaybackStatus status);
+
+    @Query("select sum(serviceCharge) from TradeAuctionOrder where paymentType = 'DEPOSIT' and status = 'FINISH'")
+    BigDecimal sumDepositAmount();
+
+    @Query("select sum(purchasedPrice) from TradeAuctionOrder where paymentType = 'PURCHASE_PRICE' and status = 'FINISH'")
+    BigDecimal sumPurchasedAmount();
+
+    @Query("select sum(price) from TradeAuctionOrder where paymentType = 'FIXED_PRICE' and status = 'FINISH'")
+    BigDecimal sumFixedAmount();
+
+    @Query("select sum(price) from TradeAuctionOrder where paymentType = 'DEPOSIT' and status = 'FINISH'")
+    BigDecimal sumComi();
+
+    @Query("select sum(earnedPrice) from TradeAuctionOrder where  paybackStatus = 'PAYED'")
+    BigDecimal earningPrice();
+
+    @Query("select sum(serviceCharge) from TradeAuctionOrder where  paybackStatus = 'PAYED'")
+    BigDecimal serviceCharge();
+
+    @Query("select sum(serviceCharge) from TradeAuctionOrder where paymentType = 'DEPOSIT' and status = 'FINISH' and tradeAuctionId = ?1")
+    BigDecimal sumDepositAmountById(Long tradeAuctionId);
+
+    @Query("select sum(purchasedPrice) from TradeAuctionOrder where paymentType = 'PURCHASE_PRICE' and status = 'FINISH' and tradeAuctionId = ?1")
+    BigDecimal sumPurchasedAmountById(Long tradeAuctionId);
+
+    @Query("select sum(price) from TradeAuctionOrder where paymentType = 'FIXED_PRICE' and status = 'FINISH' and tradeAuctionId = ?1")
+    BigDecimal sumFixedAmountById(Long tradeAuctionId);
+
+    @Query("select sum(price) from TradeAuctionOrder where paymentType = 'DEPOSIT' and status = 'FINISH' and tradeAuctionId = ?1")
+    BigDecimal sumComiById(Long tradeAuctionId);
+
+    @Query("select sum(earnedPrice) from TradeAuctionOrder where  paybackStatus = 'PAYED' and tradeAuctionId = ?1")
+    BigDecimal earningPriceById(Long tradeAuctionId);
+
+    @Query("select sum(serviceCharge) from TradeAuctionOrder where  paybackStatus = 'PAYED' and tradeAuctionId = ?1")
+    BigDecimal serviceChargeById(Long tradeAuctionId);
 }

+ 71 - 4
src/main/java/com/izouma/nineth/service/TradeAuctionOrderService.java

@@ -17,14 +17,13 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
+import javax.management.Query;
 import javax.transaction.Transactional;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 
 @Service
@@ -236,7 +235,8 @@ public class TradeAuctionOrderService {
     public void checkHasAirdrop(Long userId) {
         Long collectionId = Long.valueOf(sysConfigService.getString("tradeAcution_collectionId"));
         if (collectionId != null) {
-            Asset asset = assetRepo.findFirstByCollectionIdAndUserIdAndSource(collectionId, userId, AssetSource.OFFICIAL);
+            Asset asset = assetRepo
+                    .findFirstByCollectionIdAndUserIdAndSource(collectionId, userId, AssetSource.OFFICIAL);
             if (asset == null) {
                 User user = userRepo.findById(userId).orElseThrow(new BusinessException("暂无该用户"));
                 airDropService.create(AirDrop.builder()
@@ -370,4 +370,71 @@ public class TradeAuctionOrderService {
             });
         }
     }
+
+    public Map<String, Object> statistic(Long tradeAuctionId) {
+        Map<String, Object> result = new HashMap<>();
+        if (tradeAuctionId == null) {
+            //总流水
+            BigDecimal deposit = tradeAuctionOrderRepo.sumDepositAmount();
+            BigDecimal purchased = tradeAuctionOrderRepo.sumPurchasedAmount();
+            BigDecimal fixed = tradeAuctionOrderRepo.sumFixedAmount();
+            BigDecimal comi = tradeAuctionOrderRepo.sumComi();
+            BigDecimal commi = (BigDecimal.valueOf(3).multiply(comi)
+                    .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
+            if (fixed == null) {
+                fixed = BigDecimal.ZERO;
+            }
+            BigDecimal payed = deposit.add(purchased).add(fixed);
+            result.put("payed", payed.setScale(1, RoundingMode.DOWN));
+            //总手续费
+            result.put("comi", commi.setScale(1, RoundingMode.DOWN));
+            //用户收益
+            BigDecimal earning = tradeAuctionOrderRepo.earningPrice();
+            BigDecimal serviceCharge = tradeAuctionOrderRepo.serviceCharge();
+            BigDecimal userEarning = earning.subtract(serviceCharge);
+            result.put("userEarning", userEarning.setScale(1, RoundingMode.DOWN));
+            //平台收益
+            BigDecimal platEarning = payed.subtract(userEarning);
+            result.put("platEarning", platEarning.setScale(1, RoundingMode.DOWN));
+        } else {
+            //总流水
+            BigDecimal deposit = tradeAuctionOrderRepo.sumDepositAmountById(tradeAuctionId);
+            if (deposit == null) {
+                deposit = BigDecimal.ZERO;
+            }
+            BigDecimal purchased = tradeAuctionOrderRepo.sumPurchasedAmountById(tradeAuctionId);
+            if (purchased == null) {
+                purchased = BigDecimal.ZERO;
+            }
+            BigDecimal fixed = tradeAuctionOrderRepo.sumFixedAmountById(tradeAuctionId);
+            if (fixed == null) {
+                fixed = BigDecimal.ZERO;
+            }
+            BigDecimal comi = tradeAuctionOrderRepo.sumComiById(tradeAuctionId);
+            BigDecimal commi = BigDecimal.ZERO;
+            if (comi != null) {
+                commi = (BigDecimal.valueOf(3).multiply(comi)
+                        .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
+            }
+            BigDecimal payed = deposit.add(purchased).add(fixed);
+            result.put("payed", payed.setScale(1, RoundingMode.DOWN));
+            //总手续费
+            result.put("comi", commi);
+            //用户收益
+            BigDecimal earning = tradeAuctionOrderRepo.earningPriceById(tradeAuctionId);
+            if (earning == null) {
+                earning = BigDecimal.ZERO;
+            }
+            BigDecimal serviceCharge = tradeAuctionOrderRepo.serviceChargeById(tradeAuctionId);
+            if (serviceCharge == null) {
+                serviceCharge = BigDecimal.ZERO;
+            }
+            BigDecimal userEarning = earning.subtract(serviceCharge);
+            result.put("userEarning", userEarning.setScale(1, RoundingMode.DOWN));
+            //平台收益
+            BigDecimal platEarning = payed.subtract(userEarning);
+            result.put("platEarning", platEarning.setScale(1, RoundingMode.DOWN));
+        }
+        return result;
+    }
 }

+ 7 - 0
src/main/java/com/izouma/nineth/web/TradeAuctionOrderController.java

@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/tradeAuctionOrder")
@@ -74,6 +75,12 @@ public class TradeAuctionOrderController extends BaseController {
 //        return tradeAuctionOrderService.createFixedPrice(tradeAuctionId, userId, price);
 //    }
 
+    @PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/statistic")
+    public Map<String, Object> statistic(@RequestParam(required = false) Long tradeAuctionId) {
+        return tradeAuctionOrderService.statistic(tradeAuctionId);
+    }
+
     @PostMapping("/testPay")
     public void create(Long orderId) {
         tradeAuctionOrderService.notify(orderId, RandomStringUtils

+ 9 - 1
src/main/vue/src/router.js

@@ -1644,7 +1644,15 @@ const router = new Router({
                     meta: {
                        title: '快照管理',
                     },
-               }
+               },
+                {
+                    path: '/tradeAuctionOrderList',
+                    name: 'TradeAuctionOrderList',
+                    component: () => import(/* webpackChunkName: "TradeAuctionOrderList" */ '@/views/TradeAuctionOrderList.vue'),
+                    meta: {
+                        title: '易拍订单',
+                    },
+                }
                 /**INSERT_LOCATION**/
             ]
         },

+ 369 - 0
src/main/vue/src/views/TradeAuctionOrderList.vue

@@ -0,0 +1,369 @@
+<template>
+    <div class="list-view">
+        <page-title>
+        </page-title>
+        <div class="filters-container">
+            <el-input
+                placeholder="搜索..."
+                v-model="search"
+                clearable
+                class="filter-item search"
+                @keyup.enter.native="getData"
+            >
+                <el-button @click="getData" slot="append" icon="el-icon-search"></el-button>
+            </el-input>
+            <el-select v-model="status" placeholder="筛选状态" clearable @change="getData" class="filter-item">
+                <el-option
+                    v-for="item in statusOptions"
+                    :key="item.value"
+                    :value="item.value"
+                    :label="item.label"
+                ></el-option>
+            </el-select>
+            <el-select v-model="tradeAuctionId" filterable remote :remote-method="search" clearable>
+                <el-option v-for="item in tradeAuctionOptions" :label="item.name" :value="item.id" :key="item.id">
+                    <span style="float: left">{{ item.name }}</span>
+                    <span style="float: right; color: #8492a6; font-size: 13px">#{{ item.id }}</span>
+                </el-option>
+            </el-select>
+            <div class="tool-wrapper">
+                <div class="tool-right">
+                    <el-tag>总流水({{ payed || 0 }}¥)</el-tag>
+                    <el-tag>用户收益({{ userEarning || 0 }}¥)</el-tag>
+                    <el-tag>平台收益({{ platEarning || 0 }}¥)</el-tag>
+                    <el-tag>总手续费({{ comi || 0 }}¥)</el-tag>
+                </div>
+            </div>
+        </div>
+        <el-table :data="tableData" row-key="id" ref="table"
+                  header-row-class-name="table-header-row"
+                  header-cell-class-name="table-header-cell"
+                  row-class-name="table-row" cell-class-name="table-cell"
+                  :height="tableHeight" 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"
+            >
+            </el-table-column>
+            <el-table-column prop="userId" label="用户ID"
+            >
+            </el-table-column>
+            <el-table-column prop="nickname" label="昵称"
+            >
+            </el-table-column>
+            <el-table-column prop="name" label="名称"
+            >
+            </el-table-column>
+            <!--            <el-table-column prop="pic" label="图片"-->
+            <!--            >-->
+            <!--            </el-table-column>-->
+            <el-table-column prop="serviceCharge" label="手续费"
+            >
+            </el-table-column>
+            <el-table-column prop="earnedPrice" label="收益补偿"
+            >
+            </el-table-column>
+            <el-table-column prop="source" label="拍卖类型"
+                             :formatter="sourceFormatter"
+            >
+            </el-table-column>
+            <el-table-column prop="paymentType" label="支付类型"
+                             :formatter="paymentTypeFormatter"
+            >
+            </el-table-column>
+            <el-table-column prop="originPrice" label="价格"
+            >
+            </el-table-column>
+            <el-table-column prop="price" label="价格"
+            >
+            </el-table-column>
+            <el-table-column prop="totalPrice" label="总价"
+            >
+            </el-table-column>
+            <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"
+            >
+            </el-table-column>
+            <el-table-column prop="payTime" label="支付时间"
+            >
+            </el-table-column>
+            <el-table-column prop="cancelTime" label="取消时间"
+            >
+            </el-table-column>
+            <el-table-column prop="refundTime" label="退款时间"
+            >
+            </el-table-column>
+            <el-table-column prop="paybackStatus" label="补偿状态"
+                             :formatter="paybackStatusFormatter"
+            >
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <!-- <div class="multiple-mode-wrapper">
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
+                <el-button-group v-else>
+                    <el-button @click="operation1">批量操作1</el-button>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination background @size-change="onSizeChange"
+                           @current-change="onCurrentChange" :current-page="page"
+                           :page-sizes="[10, 20, 30, 40, 50]" :page-size="pageSize"
+                           layout="total, sizes, prev, pager, next, jumper"
+                           :total="totalElements">
+            </el-pagination>
+        </div>
+
+    </div>
+</template>
+<script>
+import {mapState} from "vuex";
+import pageableTable from "@/mixins/pageableTable";
+
+export default {
+    props: ['value'],
+    name: 'TradeAuctionOrderList',
+    mixins: [pageableTable],
+    created() {
+        this.$http
+            .post(
+                '/tradeAuction/all',
+                {
+                    sort: 'createdAt,desc',
+                    size: 100,
+                    query: {del: false}
+                },
+                {body: 'json'}
+            )
+            .then(res => {
+                this.tradeAuctionOptions = res.content;
+            });
+        this.$http
+            .post('/tradeAuctionOrder/statistic')
+            .then(res => {
+                this.payed = res.payed;
+                this.comi = res.comi;
+                this.userEarning = res.userEarning;
+                this.platEarning = res.platEarning;
+            })
+            .catch(e => {
+                console.log(e);
+                this.saving = false;
+                this.$message.error(e.error);
+            });
+    },
+    data() {
+        return {
+            multipleMode: false,
+            search: "",
+            status: '',
+            name: '',
+            payed: 0,
+            comi: 0,
+            userEarning: 0,
+            platEarning: 0,
+            tradeAuctionId: null,
+            url: "/tradeAuctionOrder/all",
+            downloading: false,
+            sourceOptions: [{"label": "官方拍卖", "value": "OFFICIAL"}, {"label": "转让拍卖", "value": "TRANSFER"}],
+            tradeAuctionOptions: [],
+            paymentTypeOptions: [{"label": "保证金", "value": "DEPOSIT"}, {
+                "label": "成交金",
+                "value": "PURCHASE_PRICE"
+            }, {"label": "一口价", "value": "FIXED_PRICE"}],
+            statusOptions: [{"label": "未支付", "value": "NOT_PAID"}, {"label": "已完成", "value": "FINISH"}, {
+                "label": "已取消",
+                "value": "CANCELLED"
+            }, {"label": "退款中", "value": "REFUNDING"}, {"label": "已退款", "value": "REFUNDED"}, {
+                "label": "待发货",
+                "value": "DELIVERY"
+            }, {"label": "待收货", "value": "RECEIVE"}, {"label": "待空投", "value": "AIR_DROP"}],
+            payMethodOptions: [{"label": "微信", "value": "WEIXIN"}, {
+                "label": "支付宝",
+                "value": "ALIPAY"
+            }, {"label": "无GAS费", "value": "FREE"}, {"label": "衫德支付", "value": "SANDPAY"}, {
+                "label": "河马支付",
+                "value": "HMPAY"
+            }, {"label": "首信易", "value": "PAYEASE"}, {"label": "余额支付", "value": "BALANCE"}, {
+                "label": "销毁藏品",
+                "value": "DESTROY"
+            }],
+            paybackStatusOptions: [{"label": "未出局", "value": "NOPASSED"}, {
+                "label": "已出局",
+                "value": "PASSED"
+            }, {"label": "已补偿", "value": "PAYED"}],
+        }
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        search(query) {
+            this.$http
+                .post(
+                    '/tradeAuction/all',
+                    {
+                        sort: 'createdAt,desc',
+                        search: query,
+                        query: {del: false}
+                    },
+                    {body: 'json'}
+                )
+                .then(res => {
+                    this.tradeAuctionOptions = res.content;
+                });
+        },
+        sourceFormatter(row, column, cellValue, index) {
+            let selectedOption = this.sourceOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        paymentTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.paymentTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        statusFormatter(row, column, cellValue, index) {
+            let selectedOption = this.statusOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        payMethodFormatter(row, column, cellValue, index) {
+            let selectedOption = this.payMethodOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        paybackStatusFormatter(row, column, cellValue, index) {
+            let selectedOption = this.paybackStatusOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            this.$http
+                .post('/tradeAuctionOrder/statistic', {tradeAuctionId: this.tradeAuctionId})
+                .then(res => {
+                    this.payed = res.payed;
+                    this.comi = res.comi;
+                    this.userEarning = res.userEarning;
+                    this.platEarning = res.platEarning;
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.saving = false;
+                    this.$message.error(e.error);
+                });
+            let data = {search: this.search, query: {del: false}};
+            data.query.tradeAuctionId = this.tradeAuctionId;
+            data.query.status = this.status;
+            return data;
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: "/tradeAuctionOrderEdit",
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: "/tradeAuctionOrderEdit",
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get("/tradeAuctionOrder/excel", {
+                    responseType: "blob",
+                    params: {size: 10000}
+                })
+                .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",
+                        res.headers["content-disposition"].split("filename=")[1]
+                    );
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', {type: 'error'}).then(() => {
+                return this.$http.post(`/tradeAuctionOrder/del/${row.id}`)
+            }).then(() => {
+                this.$message.success('删除成功');
+                this.getData();
+            }).catch(e => {
+                if (e !== 'cancel') {
+                    this.$message.error(e.error);
+                }
+            })
+        },
+    },
+    watch: {
+        tradeAuctionId(val) {
+            this.$emit('input', val);
+            if (val) {
+                this.selected = this.tradeAuctionOptions.find(i => i.id === val);
+                this.$emit('select', this.selected);
+            }
+        },
+        value(val) {
+            this.tradeAuctionId = val;
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+</style>