shinnosuke
2026-08-27 b0edd6c4bd7912e706ef3af5a221caf0d6c78fac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.talentcard.server.service;
 
import com.talentcard.server.common.BusinessException;
import com.talentcard.server.common.ErrorCode;
import com.talentcard.server.mapper.AdminWorkbenchStatisticsMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
 
@Service
public class AdminWorkbenchStatisticsService {
    private final AdminWorkbenchStatisticsMapper mapper;
 
    public AdminWorkbenchStatisticsService(AdminWorkbenchStatisticsMapper mapper) {
        this.mapper = mapper;
    }
 
    @Transactional(readOnly = true)
    public Map<String, Object> summary(String period) {
        Map<String, Object> row = mapper.selectSummary();
        Map<String, Object> compareRow = mapper.selectCompareSummary();
        if (row == null || compareRow == null) {
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "工作台统计查询失败");
        }
 
        long subsidyCents = number(row.get("subsidyAmountCents"));
        long monthlyVerification = number(row.get("monthlyVerificationCount"));
        long talentCount = number(row.get("talentCount"));
 
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("totalSubsidyAmountCents", subsidyCents);
        result.put("totalSubsidyAmount", money(subsidyCents));
        result.put("cumulativeSubsidyTotal", money(subsidyCents));
        result.put("monthlyVerificationCount", monthlyVerification);
        result.put("monthlyVerificationOrders", monthlyVerification);
        result.put("talentCount", talentCount);
        result.put("cardholderTotal", talentCount);
        result.put("talentCompare", number(compareRow.get("talentCompare")));
        result.put("monthlyVerificationCompare", number(compareRow.get("monthlyVerificationCompare")));
        result.put("subsidyCompare", money(number(compareRow.get("subsidyCompareCents"))));
        List<Map<String, Object>> summaryTrend = mapper.selectSummaryTrend();
        result.put("talentSpark", trendValues(summaryTrend, "talent"));
        result.put("verificationSpark", trendValues(summaryTrend, "verification"));
        result.put("subsidySpark", trendValues(summaryTrend, "subsidy"));
        result.put("budgetConfigured", false);
        result.put("budgetUsageRate", BigDecimal.ZERO.setScale(2));
        result.put("budgetUsageRateText", "0.00%");
 
        List<Map<String, Object>> alerts = new ArrayList<>();
        addAlert(alerts, "待处理订单", number(row.get("pendingOrderCount")));
        addAlert(alerts, "待审核商家", number(row.get("pendingProductCount")));
        addAlert(alerts, "待处理申请", number(row.get("pendingApplicationCount")));
        result.put("alertCount", alerts.stream().mapToLong(a -> number(a.get("count"))).sum());
        result.put("alerts", alerts);
        result.put("statisticsBasis", "补贴仅统计政府承担的商品补贴和政府补贴券金额,商家自行让利不计入政府补贴");
 
        result.put("verificationTrend", verificationTrend(period));
        result.put("verificationPeriod", normalizePeriod(period));
        result.put("pendingItems", mapper.selectPendingItems());
        List<Map<String, Object>> hotMerchants = mapper.selectHotMerchants();
        for (int index = 0; index < hotMerchants.size(); index++) {
            hotMerchants.get(index).put("rank", index + 1);
        }
        result.put("hotMerchants", hotMerchants);
        result.put("orderCategoryShares", mapper.selectOrderCategoryShares());
        return result;
    }
 
    private List<Map<String, Object>> verificationTrend(String period) {
        return switch (normalizePeriod(period)) {
            case "week" -> mapper.selectWeeklyVerificationTrend();
            case "year" -> mapper.selectYearlyVerificationTrend();
            default -> mapper.selectMonthlyVerificationTrend();
        };
    }
 
    private String normalizePeriod(String period) {
        if (period == null || period.isBlank()) {
            return "month";
        }
        String normalized = period.trim().toLowerCase();
        return switch (normalized) {
            case "week", "month", "year" -> normalized;
            default -> "month";
        };
    }
 
    private void addAlert(List<Map<String, Object>> alerts, String type, long count) {
        if (count <= 0) return;
        Map<String, Object> alert = new LinkedHashMap<>();
        alert.put("type", type);
        alert.put("count", count);
        alerts.add(alert);
    }
 
    private List<BigDecimal> trendValues(List<Map<String, Object>> rows, String key) {
        if (rows == null) {
            return List.of();
        }
        return rows.stream()
                .map(row -> decimal(row.get(key)))
                .toList();
    }
 
    private BigDecimal decimal(Object value) {
        if (value instanceof BigDecimal decimal) {
            return decimal;
        }
        if (value instanceof Number number) {
            return BigDecimal.valueOf(number.doubleValue());
        }
        return BigDecimal.ZERO;
    }
 
    private long number(Object value) {
        return value instanceof Number n ? n.longValue() : 0L;
    }
 
    private BigDecimal money(long cents) {
        return BigDecimal.valueOf(cents, 2).setScale(2, RoundingMode.HALF_UP);
    }
}