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