You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
16 KiB

1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
  1. package com.example.demo.serviceImpl;
  2. import com.example.demo.domain.entity.Statistics;
  3. import com.example.demo.domain.vo.WorkbenchCard;
  4. import com.example.demo.domain.vo.WorkbenchMarketCard;
  5. import com.example.demo.mapper.StatisticsMapper;
  6. import com.example.demo.mapper.WorkBenchMapper;
  7. import com.example.demo.service.GeneralService;
  8. import com.example.demo.service.StatisticsService;
  9. import com.example.demo.service.WorkbenchService;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12. import java.time.LocalDate;
  13. import java.time.DayOfWeek;
  14. import java.time.LocalDateTime;
  15. import java.time.LocalTime;
  16. import java.time.ZoneId;
  17. import java.util.ArrayList;
  18. import java.util.Calendar;
  19. import java.util.Date;
  20. import java.util.List;
  21. import java.util.stream.Collectors;
  22. /**
  23. * @program: gold-java
  24. * @ClassName WorkbenchServiceImpl
  25. * @description:
  26. * @author: Ethan
  27. * @create: 202506-18 10:47
  28. * @Version 1.0
  29. **/
  30. @Service
  31. public class WorkbenchServiceImpl implements WorkbenchService {
  32. @Autowired
  33. private WorkBenchMapper workBenchMapper;
  34. @Autowired
  35. private GeneralService generalService;
  36. @Autowired
  37. private StatisticsMapper statisticsMapper;
  38. @Override
  39. public WorkbenchCard getCard(String token) {
  40. Date date=new Date();
  41. // 获取开始时间和结束时间(当天)
  42. LocalDateTime startOfDay = date.toInstant()
  43. .atZone(ZoneId.systemDefault())
  44. .toLocalDateTime()
  45. .with(LocalTime.MIN);
  46. LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
  47. // 获取当前日期
  48. LocalDate today = LocalDate.now();
  49. // 获取当前年份的第一天
  50. LocalDate firstDayOfYear = today.withDayOfYear(1);
  51. // 将年份的第一天日期转换为Date类型
  52. Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant());
  53. List<String> markets = generalService.getMarket();
  54. // 并行处理市场列表,创建市场卡片列表
  55. List<WorkbenchMarketCard> marketCards = markets.parallelStream()
  56. // 过滤掉空或全空格的市场名称
  57. .filter(market -> market != null && !market.trim().isEmpty())
  58. .map(market -> {
  59. // 根据市场名称和日期范围查询统计信息
  60. Statistics statistics = statisticsMapper.selectByMarketAndDate(
  61. market,
  62. Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
  63. Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
  64. );
  65. // 创建并返回市场卡片对象
  66. return createWorkbenchMarketCard(market, statistics, yearlyStartDate, date);
  67. })
  68. // 收集并行流结果为列表
  69. .collect(Collectors.toList());
  70. return new WorkbenchCard(token, marketCards, markets, date, date);
  71. /* List<WorkbenchMarketCard> marketCards = new ArrayList<>();
  72. // 遍历每个 marketCard 并填充数据
  73. for (String market : markets) {
  74. if (market == null || market.trim().isEmpty()) continue;
  75. // 查询该地区当天的数据
  76. Statistics statistics = statisticsMapper.selectByMarketAndDate(
  77. market,
  78. Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
  79. Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
  80. );
  81. WorkbenchMarketCard card = new WorkbenchMarketCard();
  82. card.setMarket(market);
  83. if (statistics != null){
  84. // 卡片一:当前金币相关
  85. card.setCurrentPermanent(statistics.getCurrentPermanent());//余量-永久金币
  86. card.setCurrentFreeJune(statistics.getCurrentFreeJune()); //余量-免费六月金币
  87. card.setCurrentFreeDecember(statistics.getCurrentFreeDecember()); //余量-免费十二月金币
  88. card.setCurrentTask(statistics.getCurrentTask()); //余量-任务金币
  89. card.setCurrentFree(card.getCurrentFreeJune() + card.getCurrentFreeDecember()); //余量-免费金币
  90. card.setCurrentGold(card.getCurrentPermanent() + card.getCurrentFree() + card.getCurrentTask()); //余量-总金币
  91. card.setDailyChange(statistics.getDailyChange()); //较前一日变化
  92. // 卡片二:充值相关
  93. card.setRecharge(statistics.getRecharge()); //充值-当日充值
  94. card.setMoney(statistics.getMoney()); //充值-当日金额(永久)
  95. card.setYearlyRecharge(calculateSum(market, "recharge",yearlyStartDate ,date));//充值-全年累计充值
  96. card.setYearlyMoney(calculateSum(market, "money",yearlyStartDate ,date)); //充值-全年累计金额(永久)
  97. // 卡片三:消费与退款
  98. card.setConsumePermanent(statistics.getConsumePermanent());//消费-永久金币
  99. card.setConsumeFreeJune(statistics.getConsumeFreeJune());//消费-免费六月金币
  100. card.setConsumeFreeDecember(statistics.getConsumeFreeDecember());//消费-免费十二月金币
  101. card.setConsumeTask(statistics.getConsumeTask());//消费-任务金币
  102. card.setRefundPermanent(statistics.getRefundPermanent());//退款-永久金币
  103. card.setRefundFreeJune(statistics.getRefundFreeJune());//退款-免费六月金币
  104. card.setRefundFreeDecember(statistics.getRefundFreeDecember());//退款-免费十二月金币
  105. card.setRefundTask(statistics.getRefundTask());//退款-任务金币
  106. //当日总消费
  107. int totalConsume = card.getConsumePermanent() + card.getConsumeFreeJune() + card.getConsumeFreeDecember() + card.getConsumeTask();
  108. //当日总退款
  109. int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
  110. card.setDailyReduce(totalConsume - totalRefund);//当日总消耗
  111. card.setYearlyConsume(calculateSum(market, "consume", yearlyStartDate,date));//年累计消费
  112. card.setYearlyRefund(calculateSum(market, "refund",yearlyStartDate ,date));//年累计退款
  113. card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
  114. // 卡片四:人头数相关
  115. card.setRechargeNum(statistics.getRechargeNum());
  116. card.setFirstRecharge(statistics.getFirstRecharge());
  117. card.setYearlyRechargeNum(calculateSum(market,"rechargeNum",yearlyStartDate,date));
  118. // 周环比、日同比
  119. card.setWow(calculateWeekOverWeek(market, date));
  120. card.setDaily(calculateDayOverDay(market, date));
  121. marketCards.add(card);
  122. }
  123. }
  124. return new WorkbenchCard(token, marketCards,markets,date,date);*/
  125. }
  126. /*
  127. 获取卡片数据
  128. */
  129. @Override
  130. public WorkbenchMarketCard createWorkbenchMarketCard(String market, Statistics statistics, Date yearlyStartDate, Date currentDate) {
  131. Date date=new Date();
  132. WorkbenchMarketCard card = new WorkbenchMarketCard();
  133. card.setMarket(market);
  134. if (statistics != null) {
  135. // 卡片一:当前金币相关
  136. card.setCurrentPermanent(statistics.getCurrentPermanent());//余量-永久金币
  137. card.setCurrentFreeJune(statistics.getCurrentFreeJune()); //余量-免费六月金币
  138. card.setCurrentFreeDecember(statistics.getCurrentFreeDecember()); //余量-免费十二月金币
  139. card.setCurrentTask(statistics.getCurrentTask()); //余量-任务金币
  140. card.setCurrentFree(card.getCurrentFreeJune() + card.getCurrentFreeDecember()); //余量-免费金币
  141. card.setCurrentGold(card.getCurrentPermanent() + card.getCurrentFree() + card.getCurrentTask()); //余量-总金币
  142. card.setDailyChange(statistics.getDailyChange()); //较前一日变化
  143. // 卡片二:充值相关
  144. card.setRecharge(statistics.getRecharge()); //充值-当日充值
  145. card.setMoney(statistics.getMoney()); //充值-当日金额(永久)
  146. card.setYearlyRecharge(calculateSum(market, "recharge",yearlyStartDate ,date));//充值-全年累计充值
  147. card.setYearlyMoney(calculateSum(market, "money",yearlyStartDate ,date)); //充值-全年累计金额(永久)
  148. // 卡片三:消费与退款
  149. card.setConsumePermanent(statistics.getConsumePermanent());//消费-永久金币
  150. card.setConsumeFreeJune(statistics.getConsumeFreeJune());//消费-免费六月金币
  151. card.setConsumeFreeDecember(statistics.getConsumeFreeDecember());//消费-免费十二月金币
  152. card.setConsumeTask(statistics.getConsumeTask());//消费-任务金币
  153. card.setRefundPermanent(statistics.getRefundPermanent());//退款-永久金币
  154. card.setRefundFreeJune(statistics.getRefundFreeJune());//退款-免费六月金币
  155. card.setRefundFreeDecember(statistics.getRefundFreeDecember());//退款-免费十二月金币
  156. card.setRefundTask(statistics.getRefundTask());//退款-任务金币
  157. //当日总消费
  158. int totalConsume = card.getConsumePermanent() + card.getConsumeFreeJune() + card.getConsumeFreeDecember() + card.getConsumeTask();
  159. //当日总退款
  160. int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
  161. card.setDailyReduce(totalConsume - totalRefund);//当日总消耗
  162. card.setYearlyConsume(calculateSum(market, "consume", yearlyStartDate,date));//年累计消费
  163. card.setYearlyRefund(calculateSum(market, "refund",yearlyStartDate ,date));//年累计退款
  164. card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
  165. // 卡片四:人头数相关
  166. card.setRechargeNum(statistics.getRechargeNum());
  167. card.setFirstRecharge(statistics.getFirstRecharge());
  168. card.setYearlyRechargeNum(calculateSum(market,"rechargeNum",yearlyStartDate,date));
  169. // 周环比、日同比
  170. card.setWow(calculateWeekOverWeek(market, currentDate));
  171. card.setDaily(calculateDayOverDay(market, currentDate));
  172. }
  173. return card;
  174. }
  175. @Override
  176. public WorkbenchCard getGraph(String token, Date startDate, Date endDate, List<String> markets) {
  177. List<WorkbenchMarketCard> marketCards = new ArrayList<>();
  178. for (String market : markets) {
  179. WorkbenchMarketCard cards = new WorkbenchMarketCard();
  180. cards.setMarket(market);
  181. cards.setSumRechargePermanent(calculateSum(market, "money",startDate,endDate));
  182. cards.setSumRechargeFree(calculateSum(market, "rFree",startDate,endDate));
  183. cards.setSumConsumePermanent(calculateSum(market, "cPermanent",startDate,endDate));
  184. cards.setSumConsumeFree(calculateSum(market, "cFree",startDate,endDate));
  185. cards.setSumConsumeTask(calculateSum(market, "cTask",startDate,endDate));
  186. marketCards.add( cards);
  187. }
  188. return new WorkbenchCard(token, marketCards,markets,startDate,endDate);
  189. }
  190. /*
  191. 根据类型获取统计数据
  192. */
  193. @Override
  194. public Integer calculateSum(String market, String type, Date startDate,Date endDate) {
  195. //判断类型
  196. switch
  197. (type) {
  198. case "recharge": //获取累计充值
  199. return workBenchMapper.sumRecharge(market, startDate,endDate);
  200. case "money": //获取累计金额(永久)
  201. return workBenchMapper.sumMoney(market,startDate,endDate);
  202. case "rFree": //获取累计充值(免费)
  203. return workBenchMapper.sumRecharge(market,startDate,endDate)-
  204. workBenchMapper.sumMoney(market,startDate,endDate);
  205. case "consume": //获取累计消费
  206. return workBenchMapper.sumConsume(market,startDate,endDate);
  207. case "cPermanent": //获取累计消费-永久
  208. return workBenchMapper.sumCPermanent(market,startDate,endDate);
  209. case "cFree": //获取累计消费- 免费
  210. return workBenchMapper.sumCFree(market,startDate,endDate);
  211. case "cTask": //获取累计消费- 任务
  212. return workBenchMapper.sumCTask(market,startDate,endDate);
  213. case "refund": //获取累计退款
  214. return workBenchMapper.sumRefund(market,startDate,endDate);
  215. case "rechargeNum": //获取累计充值人数
  216. return workBenchMapper.countRechargeNum(market,startDate,endDate);
  217. default:
  218. return 0;
  219. }
  220. }
  221. /*
  222. 获取该日期该市场的日同比
  223. */
  224. @Override
  225. public Integer calculateDayOverDay(String market, Date date) {
  226. //传入日期的数据
  227. LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
  228. LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
  229. Statistics currentStatistics = statisticsMapper.selectByMarketAndDate(market,
  230. Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
  231. Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
  232. //空数据或数量为零,为避免0除数错误,返回增长率为0
  233. if (currentStatistics == null || currentStatistics.getRechargeNum() == null) {
  234. return 0;
  235. }
  236. Date yesterday = addDays(date, -1); //传入日期减一,昨天
  237. Statistics yesterdayStatistics = statisticsMapper.selectByMarketAndDate(market,
  238. Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()),
  239. Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
  240. //空数据或数量为零,为避免0除数错误,返回增长率为0
  241. if (yesterdayStatistics == null || yesterdayStatistics.getRechargeNum() == null || yesterdayStatistics.getRechargeNum() == 0) {
  242. return 0;
  243. }
  244. //计算增长率
  245. double rate = ((double) (currentStatistics.getRechargeNum() - yesterdayStatistics.getRechargeNum()) / yesterdayStatistics.getRechargeNum()) * 100;
  246. return (int) Math.round(rate);
  247. }
  248. /*
  249. 获取该日期该市场的周环比
  250. */
  251. @Override
  252. public Integer calculateWeekOverWeek(String market, Date date) {
  253. //获取传入日期所在周的周一
  254. Date thisWeekStart = getStartOfWeek(date);
  255. //获取传入日期上一周的周一
  256. Date lastWeekStart = addDays(thisWeekStart, -7);
  257. // 获取本周周一至今天的充值人数总和
  258. int thisWeekTotal = statisticsMapper.countRechargeNum(market, thisWeekStart, date);
  259. // 获取上周同一时间段的充值人数总和
  260. int lastWeekTotal = statisticsMapper.countRechargeNum(market, lastWeekStart, addDays(date, -7));
  261. if (lastWeekTotal == 0) {
  262. return 0; // 避免除以零的情况
  263. }
  264. double rate = ((double) (thisWeekTotal - lastWeekTotal) / lastWeekTotal) * 100;
  265. return (int) Math.round(rate);
  266. }
  267. @Override
  268. public Date addDays(Date date, int days) {
  269. Calendar cal = Calendar.getInstance();
  270. cal.setTime(date); //设置日期为传入的日期
  271. cal.add(Calendar.DATE, days); //传入日期加上多少天
  272. return cal.getTime(); //返回处理后的日期
  273. }
  274. @Override
  275. public Date getStartOfWeek(Date date) {
  276. // 将 Date 转换为 LocalDate
  277. LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
  278. // 获取周一作为一周的第一天
  279. DayOfWeek firstDayOfWeek = DayOfWeek.MONDAY;
  280. // 返回所在周的第一天,转换回Date格式
  281. return Date.from(localDate.with(firstDayOfWeek)
  282. .atStartOfDay(ZoneId.systemDefault())
  283. .toInstant());
  284. }
  285. }