wangqifan 3 ani în urmă
părinte
comite
c8d841ed01

+ 184 - 4
src/main/java/com/izouma/nineth/service/StatisticService.java

@@ -1,7 +1,10 @@
 package com.izouma.nineth.service;
 
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.domain.PriceInfo;
+import com.github.kevinsawicki.http.HttpRequest;
 import com.izouma.nineth.domain.BalanceRecord;
 import com.izouma.nineth.domain.Order;
 import com.izouma.nineth.domain.RechargeOrder;
@@ -11,15 +14,15 @@ import com.izouma.nineth.enums.CollectionSource;
 import com.izouma.nineth.enums.OrderStatus;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
+import com.izouma.nineth.utils.netease.CheckSumBuilder;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.RandomStringUtils;
 import org.springframework.stereotype.Service;
 
 import javax.xml.stream.events.EndDocument;
 import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.YearMonth;
+import java.sql.Timestamp;
+import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -210,4 +213,181 @@ public class StatisticService {
                 .map(Order::getPrice).reduce(BigDecimal::add).orElse(BigDecimal.ZERO));
         return map;
     }
+
+    //其他平台统计
+    public Map<String, Object> otherStatistic() {
+        Map<String, Object> resultMap = new HashMap<>();
+        Map<String, Object> amountMap = new HashMap<>();
+        Map<String, Object> transfer = new HashMap<>();
+        Map<String, Object> official = new HashMap<>();
+        Map<String, Object> transferNum = new HashMap<>();
+        Map<String, Object> officialNum = new HashMap<>();
+        Map<String, Object> userNum = new HashMap<>();
+        Map<String, Object> numMap = new HashMap<>();
+        //modern point
+        try {
+            String mpToken = getToken("admin", "pZ&VYa^Na&l6n^sMMdDtL", "https://modern.9space.vip/auth/login");
+            Map<String, Object> mpParams = new HashMap<>();
+            String mpResultString = httpPost(mpParams, "https://modern.9space.vip/statistic/total", mpToken);
+            JSONObject mpResult = JSONObject.parseObject(mpResultString);
+            transfer.put("MP", mpResult.getBigDecimal("transferPrice"));
+            transferNum.put("MP", mpResult.getLong("transferNum"));
+            official.put("MP", mpResult.getBigDecimal("officialPrice"));
+            officialNum.put("MP", mpResult.getLong("officialNum"));
+            userNum.put("MP", mpResult.getLong("userNum"));
+        } catch (Exception ignored) {
+
+        }
+
+        //art
+        try {
+            String artToken = getToken("xingadmin", "eq6bVqLqkZpoqLpH", "https://art.hopesilence.com/auth/login");
+            Map<String, Object> artParams = new HashMap<>();
+            String artResultString = httpPost(artParams, "https://art.hopesilence.com/statistic/total", artToken);
+            JSONObject artResult = JSONObject.parseObject(artResultString);
+            transfer.put("ART", artResult.getBigDecimal("transferPrice"));
+            transferNum.put("ART", artResult.getLong("transferNum"));
+            official.put("ART", artResult.getBigDecimal("officialPrice"));
+            officialNum.put("ART", artResult.getLong("officialNum"));
+            userNum.put("ART", artResult.getLong("userNum"));
+        } catch (Exception ignored) {
+
+        }
+
+        //cosmos
+        try {
+            String cosToken = getToken("xingadmin", "EnLs#(CkQdLS23BaY", "https://cos.9space.vip/auth/login");
+            Map<String, Object> params = new HashMap<>();
+            params.put("page", 0);
+            params.put("search", "");
+            params.put("size", 1);
+            params.put("sort", "createdAt,desc");
+            Map<String, Object> query = new HashMap<>();
+            query.put("collectionId", "");
+            query.put("createdAt", "");
+            query.put("name", "");
+            query.put("officialCollectionId", "");
+            query.put("orderNo", "");
+            query.put("transactionId", "");
+            query.put("del", false);
+            query.put("projectId", "1");
+            query.put("source", "TRANSFER");
+            query.put("status", "FINISH");
+            params.put("query", query);
+            String resultString = httpPost(params, "https://cos.9space.vip/order/all", cosToken);
+            JSONObject result = JSONObject.parseObject(resultString);
+            BigDecimal transferAmount = result.getBigDecimal("totalAmount");
+            String transferElements = result.getString("totalElements");
+            transfer.put("COS", transferAmount);
+            transferNum.put("COS", transferElements);
+            query.put("source", "OFFICIAL");
+            params.put("query", query);
+            resultString = httpPost(params, "https://cos.9space.vip/order/all", cosToken);
+            result = JSONObject.parseObject(resultString);
+            BigDecimal officialAmount = result.getBigDecimal("totalAmount");
+            String officialElements = result.getString("totalElements");
+            official.put("COS", officialAmount);
+            officialNum.put("COS", officialElements);
+            Map<String, Object> userQuery = new HashMap<>();
+            userQuery.put("createdAt", "");
+            userQuery.put("del", false);
+            userQuery.put("phone", "");
+            userQuery.put("invitor", "");
+            userQuery.put("projectId", "1");
+            params.put("query", userQuery);
+            //用户
+            resultString = httpPost(params, "https://cos.9space.vip/user/all", cosToken);
+            result = JSONObject.parseObject(resultString);
+            Long cosUserCount = result.getLong("totalElements");
+            userNum.put("COS", cosUserCount);
+        } catch (Exception ignored2) {
+
+        }
+
+        //第九空间
+        try {
+            String ninthToken = getToken("xingadmin", "123456", "https://nft.9space.vip/auth/login");
+            Map<String, Object> params1 = new HashMap<>();
+            params1.put("page", 0);
+            params1.put("search", "");
+            params1.put("size", 1);
+            params1.put("sort", "createdAt,desc");
+            Map<String, Object> query1 = new HashMap<>();
+            query1.put("collectionId", "");
+            query1.put("createdAt", "");
+            query1.put("name", "");
+            query1.put("officialCollectionId", "");
+            query1.put("orderNo", "");
+            query1.put("transactionId", "");
+            query1.put("del", false);
+            query1.put("projectId", "0");
+            query1.put("source", "TRANSFER");
+            query1.put("status", "FINISH");
+            params1.put("query", query1);
+            //二手市场
+            String resultString1 = httpPost(params1, "https://nft.9space.vip/order/all", ninthToken);
+            JSONObject result1 = JSONObject.parseObject(resultString1);
+            BigDecimal transferAmount1 = result1.getBigDecimal("totalAmount");
+            String transferElements1 = result1.getString("totalElements");
+            transfer.put("NINTH", transferAmount1);
+            transferNum.put("NINTH", transferElements1);
+            query1.put("source", "OFFICIAL");
+            params1.put("query", query1);
+            //官方订单
+            resultString1 = httpPost(params1, "https://nft.9space.vip/order/all", ninthToken);
+            result1 = JSONObject.parseObject(resultString1);
+            BigDecimal officialAmount1 = result1.getBigDecimal("totalAmount");
+            String officialElements1 = result1.getString("totalElements");
+            official.put("NINTH", officialAmount1);
+            officialNum.put("NINTH", officialElements1);
+            Map<String, Object> userQuery1 = new HashMap<>();
+            userQuery1.put("createdAt", "");
+            userQuery1.put("del", false);
+            userQuery1.put("phone", "");
+            userQuery1.put("invitor", "");
+            userQuery1.put("projectId", "0");
+            params1.put("query", userQuery1);
+            //用户
+            resultString1 = httpPost(params1, "https://nft.9space.vip/user/all", ninthToken);
+            result1 = JSONObject.parseObject(resultString1);
+            Long ninthUserCount = result1.getLong("totalElements");
+            userNum.put("NINTH", ninthUserCount);
+        } catch (Exception ignored) {
+
+        }
+        amountMap.put("transfer", transfer);
+        amountMap.put("official", official);
+        numMap.put("transfer", transferNum);
+        numMap.put("official", officialNum);
+        numMap.put("userCount", userNum);
+        resultMap.put("priceInfo", amountMap);
+        resultMap.put("numInfo", numMap);
+        return resultMap;
+    }
+
+    public String httpPost(Map<String, Object> params, String url, String token) {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Authorization", "Bearer " + token);
+        headers.put("Content-Type", "application/json; charset=UTF-8");
+        headers.put("Accept", "application/json, text/plain, */*");
+        return HttpRequest.post(url)
+                .contentType(HttpRequest.CONTENT_TYPE_JSON)
+                .headers(headers)
+                .send(JSON.toJSONString(params))
+                .body();
+    }
+
+    public String getToken(String username, String password, String url) {
+        Map<String, Object> params = new HashMap<>();
+        Map<String, String> headers = new HashMap<>();
+        params.put("username", username);
+        params.put("password", password);
+        return HttpRequest.post(url)
+                .contentType("application/x-www-form-urlencoded")
+                .headers(headers)
+                .form(params)
+                .body();
+    }
+
+
 }

+ 7 - 4
src/main/java/com/izouma/nineth/web/StatisticController.java

@@ -8,11 +8,9 @@ import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
+import javax.print.DocFlavor;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -111,4 +109,9 @@ public class StatisticController {
         LocalDateTime start = LocalDateTime.of(2022, 5, 30, 20, 0, 0);
         return statisticService.top(start, LocalDateTime.now(), 50);
     }
+
+    @GetMapping("/otherStatistic")
+    public Map<String, Object> otherStatistic() {
+        return statisticService.otherStatistic();
+    }
 }

+ 5 - 2
src/main/vue/src/views/Dashboard.vue

@@ -41,6 +41,7 @@ import PieChartWidget from '../widgets/PieChartWidget';
 import TopWidget from '../widgets/TopWidget';
 import UserHoldTop from '../widgets/UserHoldTop';
 import MonthWidget from '../widgets/MonthWidget';
+import OtherStatistic from '../widgets/OtherStatistic';
 
 export default {
     created() {},
@@ -69,7 +70,8 @@ export default {
                     { x: 0, y: 4, w: 6, h: 12, i: '6', name: 'PieChartWidget' },
                     { x: 0, y: 20, w: 6, h: 10, i: '8', name: 'MonthWidget' },
                     { x: 6, y: 20, w: 6, h: 10, i: '7', name: 'TopWidget' },
-                    { x: 6, y: 20, w: 12, h: 10, i: '9', name: 'UserHoldTop' }
+                    { x: 6, y: 20, w: 12, h: 10, i: '9', name: 'UserHoldTop' },
+                    { x: 6, y: 20, w: 12, h: 10, i: '10', name: 'OtherStatistic' }
                 ];
             } else {
                 this.layout = [
@@ -102,7 +104,8 @@ export default {
         PieChartWidget,
         TopWidget,
         MonthWidget,
-        UserHoldTop
+        UserHoldTop,
+        OtherStatistic
     }
 };
 </script>

+ 197 - 0
src/main/vue/src/widgets/OtherStatistic.vue

@@ -0,0 +1,197 @@
+<template>
+    <widget-card :bodyStyle="bodyStyle" ref="container">
+        <template #header>
+            <div class="header">
+                <span>销售业绩</span>
+                <el-select
+                    style="width: 120px;"
+                    size="mini"
+                    v-model="value"
+                    @change="changeSelect"
+                    placeholder="请选择"
+                >
+                    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
+                    </el-option>
+                </el-select>
+            </div>
+        </template>
+        <div class="box-content" ref="box">
+            <div class="box">
+                <div class="text1">官方销售额/二手市场</div>
+                <div class="text2">
+                    <span v-html="getNum(official, true)"></span>/ <span v-html="getNum(transfer, true)"></span>
+                </div>
+            </div>
+            <div class="box">
+                <div class="text1">官方订单/二手市场(单)/总用户(人)</div>
+                <div class="text2">{{ officialNum }}/{{ transferNum }}/{{ userCount }}</div>
+            </div>
+        </div>
+        <div class="chart-box">
+            <canvas ref="chart" class="chart"></canvas>
+        </div>
+    </widget-card>
+</template>
+<script>
+import WidgetCard from './WidgetCard';
+import VueCharts from 'vue-chartjs';
+import {format} from 'date-fns';
+import acc from '../mixins/acc';
+import addDays from 'date-fns/esm/addDays';
+
+export default {
+    data() {
+        return {
+            myChart: null,
+            bodyStyle: {
+                display: 'flex',
+                alignItems: 'center',
+                justifyContent: ' space-around'
+            },
+            official: 0,
+            transfer: 0,
+            userCount: 0,
+            officialNum: 0,
+            transferNum: 0,
+            value: '',
+            options: [
+                {
+                    label: 'MP',
+                    value: 'MP'
+                },
+                {
+                    label: '莫望',
+                    value: 'ART'
+                },
+                {
+                    label: 'COSMOS',
+                    value: 'COS'
+                },
+                {
+                    label: '第九空间',
+                    value: 'NINTH'
+                },
+
+            ],
+            numInfo: {},
+            priceInfo: {},
+            config: null
+        };
+    },
+    mixins: [acc],
+    computed: {
+        total() {
+            return this.accAdd(this.officialAmount, this.transferAmount);
+        },
+        totalNum() {
+            return this.accAdd(this.officialElements, this.transferElements);
+        }
+    },
+    mounted() {
+        this.value = 'MP';
+        this.$http
+            .get('/statistic/otherStatistic')
+            .then(res => {
+                this.numInfo = res.numInfo;
+                this.priceInfo = res.priceInfo;
+                this.$refs.chart.width = this.$refs.container.$el.offsetWidth - this.$refs.box.offsetWidth - 40;
+                this.$refs.chart.height = this.$refs.container.$el.offsetHeight - 100;
+                this.$nextTick(() => {
+                    this.config = {
+                        type: 'doughnut',
+                        data: {
+                            labels: ['官方销售额', '二手市场销售额'],
+                            datasets: []
+                        },
+                        options: {
+                            responsive: true
+                        }
+                    };
+                    this.myChart = new Chart(this.$refs.chart.getContext('2d'), this.config);
+                    this.init(this.value);
+                });
+            });
+    },
+    methods: {
+        init(value) {
+            this.officialNum = this.numInfo.official ? this.numInfo.official[value] || 0 : 0;
+            this.transferNum = this.numInfo.transfer ? this.numInfo.transfer[value] || 0 : 0;
+            this.official = this.priceInfo.official ? this.priceInfo.official[value] || 0 : 0;
+            this.transfer = this.priceInfo.transfer ? this.priceInfo.transfer[value] || 0 : 0;
+            this.userCount = this.numInfo.userCount ? this.numInfo.userCount[value] || 0 : 0;
+            this.config.data.datasets = [
+                {
+                    title: '销售额',
+                    backgroundColor: ['#FEB30E', '#FF7970'],
+                    data: [this.official, this.transfer]
+                }
+            ];
+            this.myChart.update();
+        },
+        changeSelect() {
+            this.$nextTick(() => {
+                this.init(this.value);
+            });
+        }
+    },
+    components: {
+        WidgetCard
+    }
+};
+</script>
+<style lang="less" scoped>
+.box-content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: space-around;
+    align-self: stretch;
+    padding: 30px;
+}
+
+.box {
+    padding: 0 20px;
+    height: 125px;
+    background: #f5f7fa;
+    border-radius: 16px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    min-width: 153px;
+    box-sizing: border-box;
+
+    .text1 {
+        font-size: 14px;
+        font-weight: bold;
+        color: #666666;
+        line-height: 20px;
+        white-space: nowrap;
+    }
+
+    .text2 {
+        color: #feb30e;
+        font-size: 22px;
+        font-weight: bold;
+        line-height: 29px;
+        margin-top: 2px;
+        white-space: nowrap;
+
+        /deep/ small {
+            font-size: 12px;
+        }
+    }
+
+    &:nth-child(2) {
+        .text2 {
+            color: #4dcc6f;
+        }
+    }
+}
+
+.header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
+</style>