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.

237 lines
12 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. 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. /**
  22. * @program: gold-java
  23. * @ClassName WorkbenchServiceImpl
  24. * @description:
  25. * @author: Ethan
  26. * @create: 202506-18 10:47
  27. * @Version 1.0
  28. **/
  29. @Service
  30. public class WorkbenchServiceImpl implements WorkbenchService {
  31. @Autowired
  32. private WorkBenchMapper workBenchMapper;
  33. @Autowired
  34. private GeneralService generalService;
  35. @Autowired
  36. private StatisticsMapper statisticsMapper;
  37. @Override
  38. public WorkbenchCard getCard(String token, List<String> markets) {
  39. Date date=new Date();
  40. // 获取开始时间和结束时间(当天)
  41. LocalDateTime startOfDay = date.toInstant()
  42. .atZone(ZoneId.systemDefault())
  43. .toLocalDateTime()
  44. .with(LocalTime.MIN);
  45. LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
  46. // 获取当前日期
  47. LocalDate today = LocalDate.now();
  48. // 获取当前年份的第一天
  49. LocalDate firstDayOfYear = today.withDayOfYear(1);
  50. Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant());
  51. List<WorkbenchMarketCard> marketCards = new ArrayList<>();
  52. // 遍历每个 marketCard 并填充数据
  53. for (String market : markets) {
  54. if (market == null || market.trim().isEmpty()) continue;
  55. // 查询该地区当天的数据
  56. Statistics statistics = statisticsMapper.selectByMarketAndDate(
  57. market,
  58. Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
  59. Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
  60. );
  61. WorkbenchMarketCard card = new WorkbenchMarketCard();
  62. card.setMarket(market);
  63. if (statistics != null){
  64. // 卡片一:当前金币相关
  65. card.setCurrentPermanent(statistics.getCurrentPermanent());//余量-永久金币
  66. card.setCurrentFreeJune(statistics.getCurrentFreeJune()); //余量-免费六月金币
  67. card.setCurrentFreeDecember(statistics.getCurrentFreeDecember()); //余量-免费十二月金币
  68. card.setCurrentTask(statistics.getCurrentTask()); //余量-任务金币
  69. card.setCurrentFree(card.getCurrentFreeJune() + card.getCurrentFreeDecember()); //余量-免费金币
  70. card.setCurrentGold(card.getCurrentPermanent() + card.getCurrentFree() + card.getCurrentTask()); //余量-总金币
  71. card.setDailyChange(statistics.getDailyChange()); //较前一日变化
  72. // 卡片二:充值相关
  73. card.setRecharge(statistics.getRecharge()); //充值-当日充值
  74. card.setMoney(statistics.getMoney()); //充值-当日金额(永久)
  75. card.setYearlyRecharge(calculateSum(market, "recharge",yearlyStartDate ,date));//充值-全年累计充值
  76. card.setYearlyMoney(calculateSum(market, "money",yearlyStartDate ,date)); //充值-全年累计金额(永久)
  77. // 卡片三:消费与退款
  78. card.setConsumePermanent(statistics.getConsumePermanent());//消费-永久金币
  79. card.setConsumeFreeJune(statistics.getConsumeFreeJune());//消费-免费六月金币
  80. card.setConsumeFreeDecember(statistics.getConsumeFreeDecember());//消费-免费十二月金币
  81. card.setConsumeTask(statistics.getConsumeTask());//消费-任务金币
  82. card.setRefundPermanent(statistics.getRefundPermanent());//退款-永久金币
  83. card.setRefundFreeJune(statistics.getRefundFreeJune());//退款-免费六月金币
  84. card.setRefundFreeDecember(statistics.getRefundFreeDecember());//退款-免费十二月金币
  85. card.setRefundTask(statistics.getRefundTask());//退款-任务金币
  86. //当日总消费
  87. int totalConsume = card.getConsumePermanent() + card.getConsumeFreeJune() + card.getConsumeFreeDecember() + card.getConsumeTask();
  88. //当日总退款
  89. int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
  90. card.setDailyConsume(totalConsume - totalRefund);//当日总消耗
  91. card.setYearlyConsume(calculateSum(market, "consume", yearlyStartDate,date));//年累计消费
  92. card.setYearlyRefund(calculateSum(market, "refund",yearlyStartDate ,date));//年累计退款
  93. card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
  94. // 卡片四:人头数相关
  95. card.setRechargeNum(statistics.getRechargeNum());
  96. card.setFirstRecharge(statistics.getFirstRecharge());
  97. card.setYearlyRechargeNum(calculateSum(market,"rechargeNum",yearlyStartDate,date));
  98. // 周环比、日同比
  99. card.setWow(calculateWeekOverWeek(market, date));
  100. card.setDaily(calculateDayOverDay(market, date));
  101. marketCards.add(card);
  102. }
  103. }
  104. return new WorkbenchCard(token, marketCards,markets,date,date);
  105. }
  106. @Override
  107. public WorkbenchCard getGraph(String token, Date startDate, Date endDate, List<String> markets) {
  108. List<WorkbenchMarketCard> marketCards = new ArrayList<>();
  109. for (String market : markets) {
  110. WorkbenchMarketCard cards = new WorkbenchMarketCard();
  111. cards.setMarket(market);
  112. cards.setSumRechargePermanent(calculateSum(market, "money",startDate,endDate));
  113. cards.setSumRechargeFree(calculateSum(market, "rFree",startDate,endDate));
  114. cards.setSumConsumePermanent(calculateSum(market, "cPermanent",startDate,endDate));
  115. cards.setSumConsumeFree(calculateSum(market, "cFree",startDate,endDate));
  116. cards.setSumConsumeTask(calculateSum(market, "cTask",startDate,endDate));
  117. marketCards.add( cards);
  118. }
  119. return new WorkbenchCard(token, marketCards,markets,startDate,endDate);
  120. }
  121. /*
  122. 根据类型获取统计数据
  123. */
  124. @Override
  125. public Integer calculateSum(String market, String type, Date startDate,Date endDate) {
  126. //判断类型
  127. switch
  128. (type) {
  129. case "recharge": //获取累计充值
  130. return workBenchMapper.sumRecharge(market, startDate,endDate);
  131. case "money": //获取累计金额(永久)
  132. return workBenchMapper.sumMoney(market,startDate,endDate);
  133. case "rFree": //获取累计充值(免费)
  134. return workBenchMapper.sumRecharge(market,startDate,endDate)-
  135. workBenchMapper.sumMoney(market,startDate,endDate);
  136. case "consume": //获取累计消费
  137. return workBenchMapper.sumConsume(market,startDate,endDate);
  138. case "cPermanent": //获取累计消费-永久
  139. return workBenchMapper.sumCPermanent(market,startDate,endDate);
  140. case "cFree": //获取累计消费- 免费
  141. return workBenchMapper.sumCFree(market,startDate,endDate);
  142. case "cTask": //获取累计消费- 任务
  143. return workBenchMapper.sumCTask(market,startDate,endDate);
  144. case "refund": //获取累计退款
  145. return workBenchMapper.sumRefund(market,startDate,endDate);
  146. case "rechargeNum": //获取累计充值人数
  147. return workBenchMapper.countRechargeNum(market,startDate,endDate);
  148. default:
  149. return 0;
  150. }
  151. }
  152. /*
  153. 获取该日期该市场的日同比
  154. */
  155. @Override
  156. public Integer calculateDayOverDay(String market, Date date) {
  157. //传入日期的数据
  158. LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
  159. LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
  160. Statistics currentStatistics = statisticsMapper.selectByMarketAndDate(market,
  161. Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
  162. Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
  163. //空数据或数量为零,为避免0除数错误,返回增长率为0
  164. if (currentStatistics == null || currentStatistics.getRechargeNum() == null) {
  165. return 0;
  166. }
  167. Date yesterday = addDays(date, -1); //传入日期减一,昨天
  168. Statistics yesterdayStatistics = statisticsMapper.selectByMarketAndDate(market,
  169. Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()),
  170. Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
  171. //空数据或数量为零,为避免0除数错误,返回增长率为0
  172. if (yesterdayStatistics == null || yesterdayStatistics.getRechargeNum() == null || yesterdayStatistics.getRechargeNum() == 0) {
  173. return 0;
  174. }
  175. //计算增长率
  176. double rate = ((double) (currentStatistics.getRechargeNum() - yesterdayStatistics.getRechargeNum()) / yesterdayStatistics.getRechargeNum()) * 100;
  177. return (int) Math.round(rate);
  178. }
  179. /*
  180. 获取该日期该市场的周环比
  181. */
  182. @Override
  183. public Integer calculateWeekOverWeek(String market, Date date) {
  184. //获取传入日期所在周的周一
  185. Date thisWeekStart = getStartOfWeek(date);
  186. //获取传入日期上一周的周一
  187. Date lastWeekStart = addDays(thisWeekStart, -7);
  188. // 获取本周周一至今天的充值人数总和
  189. int thisWeekTotal = statisticsMapper.countRechargeNum(market, thisWeekStart, date);
  190. // 获取上周同一时间段的充值人数总和
  191. int lastWeekTotal = statisticsMapper.countRechargeNum(market, lastWeekStart, addDays(date, -7));
  192. if (lastWeekTotal == 0) {
  193. return 0; // 避免除以零的情况
  194. }
  195. double rate = ((double) (thisWeekTotal - lastWeekTotal) / lastWeekTotal) * 100;
  196. return (int) Math.round(rate);
  197. }
  198. @Override
  199. public Date addDays(Date date, int days) {
  200. Calendar cal = Calendar.getInstance();
  201. cal.setTime(date); //设置日期为传入的日期
  202. cal.add(Calendar.DATE, days); //传入日期加上多少天
  203. return cal.getTime(); //返回处理后的日期
  204. }
  205. @Override
  206. public Date getStartOfWeek(Date date) {
  207. // 将 Date 转换为 LocalDate
  208. LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
  209. // 获取周一作为一周的第一天
  210. DayOfWeek firstDayOfWeek = DayOfWeek.MONDAY;
  211. // 返回所在周的第一天,转换回Date格式
  212. return Date.from(localDate.with(firstDayOfWeek)
  213. .atStartOfDay(ZoneId.systemDefault())
  214. .toInstant());
  215. }
  216. }