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