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.

330 lines
15 KiB

package com.example.demo.serviceImpl;
import com.example.demo.domain.entity.Statistics;
import com.example.demo.domain.entity.UserGoldRecord;
import com.example.demo.mapper.StatisticsMapper;
import com.example.demo.service.GeneralService;
import com.example.demo.service.StatisticsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* @program: gold-java
* @ClassName StatisticsServiceImpl
* @description: 统计相关
* @author: Ethan
* @create: 2025−06-18 12:00
* @Version 1.0
**/
@Service
public class StatisticsServiceImpl implements StatisticsService {
private static final Logger log = LoggerFactory.getLogger(StatisticsServiceImpl.class);
@Autowired
private StatisticsMapper statisticsMapper;
@Autowired
private GeneralService generalService;
/*
12点,18点,23点30分执行定时任务更新当天part1数据
*/
@Override
@Scheduled(cron = "0 0 12,18 * * ?") // 分别在 12:00 和 18:00 执行
@Scheduled(cron = "0 30 23 * * ?") // 在 23:30 执行
public void runHourlyTaskPart1() {
Date today = new Date(); //取当天日期
for(String market : generalService.getMarket()){
saveStatisticsPart1(market,today);
}
}
/*
12点,18点执行定时任务更新当天part2数据
*/
@Override
@Scheduled(cron = "0 0 12,18 * * ?")
public void runHourlyTaskPart2() {
Date today = new Date(); //取当天日期
for(String market : generalService.getMarket()){
saveStatisticsPart2(market,today);
}
}
/*
0点执行定时任务更新近一周part2数据
*/
@Override
@Scheduled(cron = "0 0 0 * * ?")
public void runDailyTaskPart2() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, -7); // 一周前
Date startDate = cal.getTime();
Date yesterday = generalService.getYesterday(); // 昨天
// 获取 Calendar 实例并设置为昨天的日期
Calendar calendar = Calendar.getInstance();
calendar.setTime(yesterday);
// 设置时间为昨天的23:55
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 55);
//把yesterday的结束时间设为结束时间
Date endDate= calendar.getTime();
//近一周的日期列表
List<Date> dateList =generalService.getAllDatesBetween(startDate, endDate);
for (Date date : dateList) {
for (String market : generalService.getMarket()) {
saveStatisticsPart2(market, date);
}
}
}
/*
查询某地区某天已存在的统计数据
*/
@Override
public Statistics getExistStatistics(String market, Date date) {
LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
return statisticsMapper.selectByMarketAndDate(market,
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
}
/*
新增或更新或不修改某地区某天part1统计数据
*/
@Override
public void saveStatisticsPart1(String market, Date date) {
//获取该地区该日期part1(余量属性)统计数据
Statistics newStats=getStatisticsPart1(market,date);
//获取该地区该日期已存在的数据
Statistics existStats = getExistStatistics(market, date);
//判断是否存在已存在的数据
if(existStats==null){
//没有记录,新增
statisticsMapper.insertPart1(newStats );
}else {
//判断新旧数据part1部分(余量属性)是否一致
if (!isSameStatisticsPart1(existStats,newStats)){
statisticsMapper.updatePart1(newStats);
}else{
System.out.println("数据未发生改变");
}
}
}
/*
新增或更新或不修改某地区某天part2统计数据
*/
@Override
public void saveStatisticsPart2(String market, Date date){
//获取该地区该日期part2(余量外属性)统计数据
Statistics newStats=getStatisticsPart2(market,date);
//获取该地区该日期已存在的数据
Statistics existStats = getExistStatistics(market, date);
//判断是否存在已存在的数据
if(existStats==null){
//没有记录,新增
statisticsMapper.insertPart2(newStats );
}else {
//判断新旧数据part2部分(余量外属性)是否一致
if (!isSameStatisticsPart2(existStats,newStats)){
statisticsMapper.updatePart2(newStats);
}else{
System.out.println("数据未发生改变");
}
}
}
//根据地区与日期获取part1(余量属性)统计数据
@Override
public Statistics getStatisticsPart1(String market, Date date) {
//获取日期
LocalDate localDate=date.toInstant()
.atZone(ZoneId.of("Asia/Shanghai")) // 使用系统默认时区
.toLocalDate();
//初始化Statistics对象
Statistics statistics = new Statistics();
statistics.setMarket(market);
statistics.setCurrentDatetime(localDate);
//计算属性
//当前金币余量
Integer currentGold = statisticsMapper.sumCurrentPermanentGold(market)+
statisticsMapper.sumCurrentFreeJune( market)+
statisticsMapper.sumCurrentFreeDecember(market)+
statisticsMapper.sumCurrentTaskGold( market);
statistics.setCurrentGold(currentGold);
//较前一日变化
Date yesterday =generalService.getYesterday();
//把yesterday改为昨天的开始时间和结束时间
LocalDateTime startTime = yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
//昨天金币余量
Statistics ydayStats = statisticsMapper.selectByMarketAndDate(market, Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
Integer yesterdayGold=0;
if (ydayStats != null) {
yesterdayGold = ydayStats.getCurrentGold();
}
Integer dailyChange = currentGold - yesterdayGold;
statistics.setDailyChange(dailyChange);
//当前永久金币
Integer currentPermanent = statisticsMapper.sumCurrentPermanentGold(market);
statistics.setCurrentPermanent(currentPermanent);
//当前免费六月金币
Integer currentFreeJune = statisticsMapper.sumCurrentFreeJune(market);
statistics.setCurrentFreeJune(currentFreeJune);
//当前免费十二月金币
Integer currentFreeDecember = statisticsMapper.sumCurrentFreeDecember(market);
statistics.setCurrentFreeDecember(currentFreeDecember);
//当前任务金币
Integer currentTask = statisticsMapper.sumCurrentTaskGold(market);
statistics.setCurrentTask(currentTask);
return statistics;
}
/*
根据地区与日期获取part2(余量外属性)统计数据
*/
@Override
public Statistics getStatisticsPart2(String market, Date date) {
//获取日期
LocalDate localDate=date.toInstant()
.atZone(ZoneId.of("Asia/Shanghai")) // 使用系统默认时区
.toLocalDate();
//把date改为当天的开始时间和结束时间
LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
//定义审核状态列表
List<Integer> auditStatusList = new ArrayList<>();
auditStatusList.add(1); // 审核通过
auditStatusList.add(3); // 外部传入默认通过
//查询当天该地区审核通过的所有数据
List<UserGoldRecord> records = statisticsMapper.findByMarketAndAuditStatus(market, auditStatusList,
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
//初始化Statistics对象
Statistics statistics = new Statistics();
statistics.setMarket(market);
statistics.setCurrentDatetime(localDate);
//计算属性
//充值相关-当日充值(永久+免费)
Integer recharge = records.stream()
.filter(record -> record.getType() == 0) // 类型为充值
.mapToInt(record -> record.getPermanentGold() + record.getFreeJune() + record.getFreeDecember() + record.getTaskGold())
.sum();
statistics.setRecharge(recharge);
//充值相关-当日金额(永久)
Integer money = records.stream()
.filter(record -> record.getType() == 0) // 类型为充值
.mapToInt(UserGoldRecord::getPermanentGold)
.sum();
statistics.setMoney(money);
//消费相关-当日新增消费(永久)
Integer consumePermanent = records.stream()
.filter(record -> record.getType() == 1) // 类型为消费
.mapToInt(UserGoldRecord::getPermanentGold)
.sum();
statistics.setConsumePermanent(consumePermanent);
//消费相关-当日新增消费(六月免费)
Integer consumeFreeJune = records.stream()
.filter(record -> record.getType() == 1) // 类型为消费
.mapToInt(UserGoldRecord::getFreeJune)
.sum();
statistics.setConsumeFreeJune(consumeFreeJune);
//消费相关-当日新增消费(十二月免费)
Integer consumeFreeDecember = records.stream()
.filter(record -> record.getType() == 1) // 类型为消费
.mapToInt(UserGoldRecord::getFreeDecember)
.sum();
statistics.setConsumeFreeDecember(consumeFreeDecember);
//消费相关-当日新增消费(任务)
Integer consumeTask = records.stream()
.filter(record -> record.getType() == 1) // 类型为消费
.mapToInt(UserGoldRecord::getTaskGold)
.sum();
statistics.setConsumeTask(consumeTask);
//退款相关-当日退款(永久)
Integer refundPermanent = records.stream()
.filter(record -> record.getType() == 2) // 类型为退款
.mapToInt(UserGoldRecord::getPermanentGold)
.sum();
statistics.setRefundPermanent(refundPermanent);
//退款相关-当日退款(六月免费)
Integer refundFreeJune = records.stream()
.filter(record -> record.getType() == 2) // 类型为退款
.mapToInt(UserGoldRecord::getFreeJune)
.sum();
statistics.setRefundFreeJune(refundFreeJune);
//退款相关-当日退款(十二月免费)
Integer refundFreeDecember = records.stream()
.filter(record -> record.getType() == 2) // 类型为退款
.mapToInt(UserGoldRecord::getFreeDecember)
.sum();
statistics.setRefundFreeDecember(refundFreeDecember);
//退款相关-当日退款(任务)
Integer refundTask = records.stream()
.filter(record -> record.getType() == 2) // 类型为退款
.mapToInt(UserGoldRecord::getTaskGold)
.sum();
statistics.setRefundTask(refundTask);
//充值人数
int rechargeNum= statisticsMapper.countRechargeNum(market,Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
statistics.setRechargeNum(rechargeNum);
//首充人数
int firstRecharge= statisticsMapper.countFirstRecharge(market,Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
statistics.setFirstRecharge(firstRecharge);
return statistics;
}
/*
* 判断两个统计对象part1(余量属性)是否相同
*/
private boolean isSameStatisticsPart1(Statistics oldStats, Statistics newStats) {
return Objects.equals(oldStats.getCurrentGold(), newStats.getCurrentGold()) &&
Objects.equals(oldStats.getCurrentPermanent(), newStats.getCurrentPermanent()) &&
Objects.equals(oldStats.getCurrentFreeJune(), newStats.getCurrentFreeJune()) &&
Objects.equals(oldStats.getCurrentFreeDecember(), newStats.getCurrentFreeDecember()) &&
Objects.equals(oldStats.getCurrentTask(), newStats.getCurrentTask()) &&
Objects.equals(oldStats.getDailyChange(), newStats.getDailyChange()) ;
}
/*
* 判断两个统计对象part2(余量外属性)是否相同
*/
private boolean isSameStatisticsPart2(Statistics oldStats, Statistics newStats) {
return Objects.equals(oldStats.getRecharge(), newStats.getRecharge()) &&
Objects.equals(oldStats.getMoney(), newStats.getMoney()) &&
Objects.equals(oldStats.getConsumePermanent(), newStats.getConsumePermanent()) &&
Objects.equals(oldStats.getConsumeFreeJune(), newStats.getConsumeFreeJune()) &&
Objects.equals(oldStats.getConsumeFreeDecember(), newStats.getConsumeFreeDecember()) &&
Objects.equals(oldStats.getConsumeTask(), newStats.getConsumeTask()) &&
Objects.equals(oldStats.getRefundPermanent(), newStats.getRefundPermanent()) &&
Objects.equals(oldStats.getRefundFreeJune(), newStats.getRefundFreeJune()) &&
Objects.equals(oldStats.getRefundFreeDecember(), newStats.getRefundFreeDecember()) &&
Objects.equals(oldStats.getRefundTask(), newStats.getRefundTask()) &&
Objects.equals(oldStats.getRechargeNum(), newStats.getRechargeNum()) &&
Objects.equals(oldStats.getFirstRecharge(), newStats.getFirstRecharge()) &&
Objects.equals(oldStats.getCurrentGold(), newStats.getCurrentGold()) &&
Objects.equals(oldStats.getDailyChange(), newStats.getDailyChange()) &&
Objects.equals(oldStats.getCurrentPermanent(), newStats.getCurrentPermanent()) &&
Objects.equals(oldStats.getCurrentFreeJune(), newStats.getCurrentFreeJune()) &&
Objects.equals(oldStats.getCurrentFreeDecember(), newStats.getCurrentFreeDecember()) &&
Objects.equals(oldStats.getCurrentTask(), newStats.getCurrentTask());
}
}