|
|
@@ -1,20 +1,177 @@
|
|
|
package com.kym.service.impl;
|
|
|
|
|
|
+import cn.dev33.satoken.stp.StpUtil;
|
|
|
+import com.github.pagehelper.PageHelper;
|
|
|
+import com.kym.common.utils.CommUtil;
|
|
|
import com.kym.entity.MonthStat;
|
|
|
+import com.kym.entity.SettlementRecord;
|
|
|
+import com.kym.entity.StatSyncLog;
|
|
|
+import com.kym.entity.common.PageBean;
|
|
|
+import com.kym.entity.queryParams.MonthStatQueryParam;
|
|
|
+import com.kym.entity.vo.MonthStatVo;
|
|
|
import com.kym.mapper.MonthStatMapper;
|
|
|
-import com.kym.service.MonthStatService;
|
|
|
+import com.kym.service.*;
|
|
|
+import com.kym.service.cache.KymCache;
|
|
|
import com.kym.service.mybatisplus.MyBaseServiceImpl;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.YearMonth;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.Stream;
|
|
|
|
|
|
/**
|
|
|
- * <p>
|
|
|
- * 日统计表 服务实现类
|
|
|
- * </p>
|
|
|
+ * 月统计表 服务实现类
|
|
|
*
|
|
|
* @author skyline
|
|
|
* @since 2025-04-03
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
public class MonthStatServiceImpl extends MyBaseServiceImpl<MonthStatMapper, MonthStat> implements MonthStatService {
|
|
|
|
|
|
+ private final WashOrderService washOrderService;
|
|
|
+ private final UserService userService;
|
|
|
+ private final SplitRecordService splitRecordService;
|
|
|
+ private final WashStationService washStationService;
|
|
|
+ private final StatSyncLogService statSyncLogService;
|
|
|
+ private final SettlementService settlementService;
|
|
|
+
|
|
|
+ public MonthStatServiceImpl(WashOrderService washOrderService, UserService userService,
|
|
|
+ SplitRecordService splitRecordService, WashStationService washStationService,
|
|
|
+ StatSyncLogService statSyncLogService, SettlementService settlementService) {
|
|
|
+ this.washOrderService = washOrderService;
|
|
|
+ this.userService = userService;
|
|
|
+ this.splitRecordService = splitRecordService;
|
|
|
+ this.washStationService = washStationService;
|
|
|
+ this.statSyncLogService = statSyncLogService;
|
|
|
+ this.settlementService = settlementService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PageBean<MonthStatVo> listMonthStat(MonthStatQueryParam params) {
|
|
|
+ var query = lambdaQuery()
|
|
|
+ .eq(CommUtil.isNotEmptyAndNull(params.getStationId()),
|
|
|
+ MonthStat::getStationId, params.getStationId())
|
|
|
+ .eq(CommUtil.isNotEmptyAndNull(params.getStatMonth()),
|
|
|
+ MonthStat::getStatMonth, params.getStatMonth())
|
|
|
+ .orderByDesc(MonthStat::getStatMonth);
|
|
|
+
|
|
|
+ var page = PageHelper.startPage(params.getPageNum(), params.getPageSize());
|
|
|
+ var list = query.list();
|
|
|
+
|
|
|
+ var voList = list.stream().map(item -> {
|
|
|
+ var vo = new MonthStatVo();
|
|
|
+ BeanUtils.copyProperties(item, vo);
|
|
|
+ vo.setStationName(KymCache.INSTANCE.getStationNameById(item.getStationId()));
|
|
|
+ return vo;
|
|
|
+ }).toList();
|
|
|
+
|
|
|
+ var bean = new PageBean<>(voList);
|
|
|
+ bean.setPages(page.getPages());
|
|
|
+ bean.setPageNum(page.getPageNum());
|
|
|
+ bean.setPageSize(page.getPageSize());
|
|
|
+ bean.setTotal(page.getTotal());
|
|
|
+ return bean;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void syncMonthlyStat(String statMonth) {
|
|
|
+ var yearMonth = YearMonth.parse(statMonth);
|
|
|
+ var statDay = yearMonth.atDay(1);
|
|
|
+ log.info("手动同步月统计: {}", statMonth);
|
|
|
+
|
|
|
+ Map<String, Integer> amountMap = washOrderService.sumMonthAmount(statDay);
|
|
|
+ Map<String, Integer> registerMap = userService.countMonthRegister(statDay);
|
|
|
+ Map<String, Integer> ordersCountMap = washOrderService.countMonthOrders(statDay);
|
|
|
+ Map<String, Integer> incomeMap = splitRecordService.sumMonthIncome(statDay);
|
|
|
+ Map<String, Integer> crossIncomeMap = splitRecordService.sumMonthIncome(statDay, Boolean.TRUE);
|
|
|
+ Map<String, Integer> expendMap = splitRecordService.sumMonthExpend(statDay);
|
|
|
+ Map<String, Integer> refundMap = splitRecordService.sumMonthRefund(statDay);
|
|
|
+ Map<String, Integer> rechargeCountMap = splitRecordService.countMonthRecharge(statDay);
|
|
|
+ Map<String, Integer> refundCountMap = splitRecordService.countMonthRefund(statDay);
|
|
|
+ Map<String, Integer> activeUserMap = washOrderService.countMonthActiveUsers(statDay);
|
|
|
+
|
|
|
+ var platformFeeMap = settlementService.lambdaQuery()
|
|
|
+ .eq(SettlementRecord::getSettlementPeriod, statMonth)
|
|
|
+ .list()
|
|
|
+ .stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ SettlementRecord::getStationId,
|
|
|
+ SettlementRecord::getPlatformFee,
|
|
|
+ Integer::sum));
|
|
|
+
|
|
|
+ var allStationIds = Stream.of(amountMap, registerMap, ordersCountMap, incomeMap,
|
|
|
+ crossIncomeMap, expendMap, refundMap, rechargeCountMap, refundCountMap,
|
|
|
+ activeUserMap, platformFeeMap)
|
|
|
+ .flatMap(m -> m.keySet().stream())
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ long operatorId = 0;
|
|
|
+ String operatorName = "系统";
|
|
|
+ try {
|
|
|
+ operatorId = StpUtil.getLoginIdAsLong();
|
|
|
+ operatorName = StpUtil.getLoginIdAsString();
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ }
|
|
|
+
|
|
|
+ var now = LocalDateTime.now();
|
|
|
+ var statList = new ArrayList<MonthStat>();
|
|
|
+
|
|
|
+ for (var stationId : allStationIds) {
|
|
|
+ try {
|
|
|
+ var stat = new MonthStat();
|
|
|
+ stat.setStatMonth(statMonth);
|
|
|
+ stat.setStationId(stationId);
|
|
|
+ stat.setConsumption(amountMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setRegistrations(registerMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setOrdersCount(ordersCountMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setTotalIncome(incomeMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setCrossIncome(crossIncomeMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setCrossExpend(expendMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setTotalRefund(refundMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setPlatformFee(platformFeeMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setRechargeCount(rechargeCountMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setRefundCount(refundCountMap.getOrDefault(stationId, 0));
|
|
|
+ stat.setActiveUserCount(activeUserMap.getOrDefault(stationId, 0));
|
|
|
+ statList.add(stat);
|
|
|
+
|
|
|
+ var syncLog = new StatSyncLog()
|
|
|
+ .setStatType(StatSyncLog.TYPE_MONTHLY)
|
|
|
+ .setStatKey(statMonth)
|
|
|
+ .setStationId(stationId)
|
|
|
+ .setSyncStatus(StatSyncLog.STATUS_SUCCESS)
|
|
|
+ .setSyncBy(operatorId)
|
|
|
+ .setSyncByName(operatorName)
|
|
|
+ .setStartTime(now)
|
|
|
+ .setEndTime(LocalDateTime.now());
|
|
|
+ statSyncLogService.save(syncLog);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("同步月统计失败: statMonth={}, stationId={}", statMonth, stationId, e);
|
|
|
+ var syncLog = new StatSyncLog()
|
|
|
+ .setStatType(StatSyncLog.TYPE_MONTHLY)
|
|
|
+ .setStatKey(statMonth)
|
|
|
+ .setStationId(stationId)
|
|
|
+ .setSyncStatus(StatSyncLog.STATUS_FAILED)
|
|
|
+ .setSyncBy(operatorId)
|
|
|
+ .setSyncByName(operatorName)
|
|
|
+ .setErrorMsg(e.getMessage())
|
|
|
+ .setStartTime(now)
|
|
|
+ .setEndTime(LocalDateTime.now());
|
|
|
+ statSyncLogService.save(syncLog);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!statList.isEmpty()) {
|
|
|
+ replaceBatch(statList);
|
|
|
+ }
|
|
|
+ log.info("月统计同步完成: {}, 站点数: {}", statMonth, statList.size());
|
|
|
+ }
|
|
|
}
|