Browse Source

6-24更新统计数据part2(余量外属性)

huangqizheng/feature-20250626103451-权限页面
jianlin 1 week ago
parent
commit
5496460df7
  1. 18
      src/main/java/com/example/demo/controller/StatisticsController.java
  2. 53
      src/main/java/com/example/demo/mapper/StatisticsMapper.java
  3. 14
      src/main/java/com/example/demo/service/GeneralService.java
  4. 18
      src/main/java/com/example/demo/service/StatisticsService.java
  5. 55
      src/main/java/com/example/demo/serviceImpl/GeneralServiceImpl.java
  6. 222
      src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java
  7. 4
      src/main/resources/application.yml
  8. 102
      src/main/resources/mapper/StatisticsMapper.xml

18
src/main/java/com/example/demo/controller/StatisticsController.java

@ -1,13 +1,20 @@
package com.example.demo.controller;
import com.example.demo.domain.entity.Statistics;
import com.example.demo.domain.vo.Result;
import com.example.demo.service.GeneralService;
import com.example.demo.service.StatisticsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
/**
* @program: gold-java
* @ClassName StatisticsController
@ -25,4 +32,15 @@ import org.springframework.web.bind.annotation.RestController;
public class StatisticsController {
@Autowired
private StatisticsService statisticsService;
@Autowired
private GeneralService generalService;
//测试定时任务1
@PostMapping("/Hourly")
public void HourlyTask() {
statisticsService.runHourlyTask();
}
}

53
src/main/java/com/example/demo/mapper/StatisticsMapper.java

@ -0,0 +1,53 @@
package com.example.demo.mapper;
import com.example.demo.domain.entity.Statistics;
import com.example.demo.domain.entity.UserGoldRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* @program: gold-java
* @ClassName StatisticsMapper
* @description:
* @author: Ethan
* @create: 202506-23 14:08
* @Version 1.0
**/
@Mapper
public interface StatisticsMapper {
//根据地区审核状态起止时间查询订单表数据
List<UserGoldRecord> findByMarketAndAuditStatus(@Param("market") String market,
@Param("auditStatusList") List<Integer> auditStatusList,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
//获取某地区当前永久金币余量
Integer sumCurrentPermanentGold(@Param("market") String market);
//获取某地区当前六月免费金币余量
Integer sumCurrentFreeJune(@Param("market") String market);
//获取某地区当前永久金币余量
Integer sumCurrentFreeDecember(@Param("market") String market);
//获取某地区当前永久金币余量
Integer sumCurrentTaskGold(@Param("market") String market);
//计算该天充值人数
int countRechargeNum(
@Param("market") String market,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
//计算该天首充人数
int countFirstRecharge(
@Param("market") String market,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
//新增part2统计数据
void insertPart2(Statistics statistics);
//更新part2统计数据
void updatePart2(Statistics statistics);
//获取某地区某天的数据
Statistics selectByMarketAndDate(@Param("market") String market,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate);
}

14
src/main/java/com/example/demo/service/GeneralService.java

@ -1,5 +1,9 @@
package com.example.demo.service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
/**
@ -12,6 +16,16 @@ import java.util.List;
**/
public interface GeneralService {
//获取所有市场地区
List<String> getMarket();
//获取平台
List<String> getPlatform();
//获取昨天的日期
Date getYesterday();
//获取某天的开始时间(00:00:00)
Date getStartOfDay(Date date);
//转换日期格式为yyyy-MM-dd
String formatDate(Date date) ;
//获取时间段内的所有日期包含起始和结束日
List<Date> getAllDatesBetween(Date start, Date end);
}

18
src/main/java/com/example/demo/service/StatisticsService.java

@ -1,5 +1,9 @@
package com.example.demo.service;
import com.example.demo.domain.entity.Statistics;
import java.util.Date;
/**
* @program: gold-java
* @ClassName StatisticsService
@ -11,4 +15,18 @@ package com.example.demo.service;
public interface StatisticsService {
//12点18点执行定时任务更新当天数据
public void runHourlyTask();
//0点执行定时任务更新近一周数据
public void runDailyTask();
//查询某地区某天是否已存在统计数据
public Statistics getExistStatistics(String market,Date date);
//新增或更新或不修改某地区某天统计数据
public void saveStatistics(String market, Date date);
//根据地区与日期获取part1(余量属性)统计数据
public Statistics getStatisticsPart1(String market, Date date);
//根据地区与日期获取part2(余量外属性)统计数据
public Statistics getStatisticsPart2(String market, Date date);
}

55
src/main/java/com/example/demo/serviceImpl/GeneralServiceImpl.java

@ -5,6 +5,12 @@ import com.example.demo.service.GeneralService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
@ -32,4 +38,53 @@ public class GeneralServiceImpl implements GeneralService {
List<String> list = generalMapper.getPlatform();
return list;
}
/*
获取昨天的日期
*/
@Override
public Date getYesterday() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, -1); //当前天数-1
return getStartOfDay(cal.getTime()); //昨天的00:00:00
}
/*
获取某天的开始时间(00:00:00)
*/
@Override
public Date getStartOfDay(Date date) {
LocalDateTime localDate = date.toInstant()
.atZone(ZoneId.systemDefault()) // 转换为本地时区
.toLocalDateTime()
.with(LocalTime.MIN); // 设置时间为当天 00:00:00
return Date.from(localDate.atZone(ZoneId.systemDefault()).toInstant());
}
/*
转换日期格式为yyyy-MM-dd
*/
@Override
public String formatDate(Date date) {
return date.toInstant()
.atZone(ZoneId.systemDefault())
.format(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE); // 输出格式如 "2025-10-01"
}
/*
获取时间段内的所有日期包含起始和结束日
*/
@Override
public List<Date> getAllDatesBetween(Date start, Date end) {
List<Date> dates = new ArrayList<>();
//初始化日历对象
Calendar tempStart = Calendar.getInstance();
tempStart.setTime(start);
Calendar tempEnd = Calendar.getInstance();
tempEnd.setTime(end);
while (!tempStart.after(tempEnd)) {
dates.add(tempStart.getTime()); // 将当前日期添加到列表中
tempStart.add(Calendar.DAY_OF_YEAR, 1); // 每次增加一天
}
return dates;
}
}

222
src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java

@ -1,8 +1,21 @@
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.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
/**
* @program: gold-java
* @ClassName StatisticsServiceImpl
@ -14,4 +27,213 @@ import org.springframework.stereotype.Service;
@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点执行定时任务更新当天数据
*/
@Override
@Scheduled(cron = "0 0 12,18 * * ?")
public void runHourlyTask() {
Date today = new Date(); //取当天日期
for(String market : generalService.getMarket()){
saveStatistics(market,today);
}
}
/*
0点执行定时任务更新近一周数据
*/
@Override
@Scheduled(cron = "0 0 0 * * ?")
public void runDailyTask() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, -7); // 一周前
Date startDate = cal.getTime();
Date endDate = generalService.getYesterday(); // 昨天
//近一周的日期列表
List<Date> dateList =generalService.getAllDatesBetween(startDate, endDate);
for (Date date : dateList) {
for (String market : generalService.getMarket()) {
saveStatistics(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()));
}
/*
新增或更新或不修改某地区某天统计数据
*/
@Override
public void saveStatistics(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{
log.atInfo().log("数据未发生改变");
}
}
}
//根据地区与日期获取part1(余量属性)统计数据
@Override
public Statistics getStatisticsPart1(String market, Date date) {
//初始化Statistics对象
Statistics statistics = new Statistics();
statistics.setMarket(market);
//计算属性
//当前金币余量
Integer currentGold = statisticsMapper.sumCurrentPermanentGold(market)+
statisticsMapper.sumCurrentFreeJune( market)+
statisticsMapper.sumCurrentFreeDecember(market)+
statisticsMapper.sumCurrentTaskGold( market);
statistics.setCurrentGold(currentGold);
//当前永久金币
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) {
//把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(date);
//计算属性
//充值相关-当日充值永久+免费
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;
}
/*
* 判断两个统计对象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());
}
}

4
src/main/resources/application.yml

@ -4,7 +4,7 @@ spring:
fail-on-unknown-properties: false
datasource:
mysql1:
jdbc-url: jdbc:mysql://localhost:3306/hwgold?serverTimezone=Asia/Shanghai
jdbc-url: jdbc:mysql://192.168.8.220:3306/hwgold?serverTimezone=Asia/Shanghai
username: hwgold
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
@ -91,7 +91,7 @@ upload:
server:
port: 8080
port: 8081
logging:
level:

102
src/main/resources/mapper/StatisticsMapper.xml

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.StatisticsMapper">
<!--新增part2统计数据-->
<insert id="insertPart2">
INSERT INTO statistics (
market, current_datetime,
recharge, money,
consume_permanent, consume_free_june,
consume_free_december, consume_task,
refund_permanent, refund_free_june,
refund_free_december,refund_task,
recharge_num, first_recharge
) VALUES (
#{market}, #{currentDatetime},
#{recharge}, #{money},
#{consumePermanent}, #{consumeFreeJune},
#{consumeFreeDecember}, #{consumeTask},
#{refundPermanent}, #{refundFreeJune},
#{refundFreeDecember}, #{refundTask},
#{rechargeNum}, #{firstRecharge}
)
</insert>
<!--更新part2统计数据-->
<update id="updatePart2">
UPDATE statistics
SET
recharge = #{recharge},
money = #{money},
consume_permanent = #{consumePermanent},
consume_free_june = #{consumeFreeJune},
consume_free_december = #{consumeFreeDecember},
consume_task = #{consumeTask},
refund_permanent = #{refundPermanent},
refund_free_june = #{refundFreeJune},
refund_free_december = #{refundFreeDecember},
refund_task = #{refundTask},
recharge_num = #{rechargeNum},
first_recharge = #{firstRecharge},
WHERE id = #{id}
</update>
<!--根据地区、审核状态、起止时间查询订单表数据-->
<select id="findByMarketAndAuditStatus"
resultType="com.example.demo.domain.entity.UserGoldRecord">
SELECT u.market, ugr.*
FROM user_gold_record ugr
INNER JOIN user u ON ugr.jwcode = u.jwcode
WHERE u.market = #{market}
AND ugr.audit_status IN
<foreach item="status" collection="auditStatusList" open="(" separator="," close=")">
#{status}
</foreach>
AND ugr.pay_time BETWEEN #{startTime} AND #{endTime}
</select>
<!-- 计算该天充值人数-->
<select id="countRechargeNum" resultType="java.lang.Integer">
SELECT COUNT(DISTINCT ugr.jwcode)
FROM user_gold_record ugr
INNER JOIN user u ON ugr.jwcode = u.jwcode
WHERE u.market = #{market}
AND ugr.audit_status = 1
AND ugr.pay_time BETWEEN #{startTime} AND #{endTime}
</select>
<!--计算该天首充人数-->
<select id="countFirstRecharge" resultType="java.lang.Integer">
SELECT COUNT(DISTINCT ugr.jwcode)
FROM user_gold_record ugr
INNER JOIN user u ON ugr.jwcode = u.jwcode
WHERE u.market = #{market}
AND ugr.audit_status = 1
AND ugr.pay_time BETWEEN #{startTime} AND #{endTime}
AND u.first_recharge = #{startTime}
</select>
<select id="selectByMarketAndDate" resultType="com.example.demo.domain.entity.Statistics">
SELECT *
FROM statistics
WHERE market = #{market}
AND current_datetime >= #{startDate}
AND current_datetime &lt;= #{endDate}
LIMIT 1
</select>
<select id="sumCurrentPermanentGold" resultType="java.lang.Integer">
SELECT SUM(u.currentPermanentGold)
FROM user u
WHERE u.market = #{market}
</select>
<select id="sumCurrentFreeJune" resultType="java.lang.Integer">
SELECT SUM(u.currentFreeJune)
FROM user u
WHERE u.market = #{market}
</select>
<select id="sumCurrentFreeDecember" resultType="java.lang.Integer">
SELECT SUM(u.currentFreeDecember)
FROM user u
WHERE u.market = #{market}
</select>
<select id="sumCurrentTaskGold" resultType="java.lang.Integer">
SELECT SUM(u.currentTaskGold)
FROM user u
WHERE u.market = #{market}
</select>
</mapper>
Loading…
Cancel
Save