Browse Source

Merge branch 'milestone-20250711-金币重构二期' into sunjiabei/feature-20250710132313-二期模块

# Conflicts:
#	src/main/java/com/example/demo/controller/AdminController.java
#	src/main/java/com/example/demo/mapper/GeneralMapper.java
#	src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java
huangqizheng/feature-20250717200321-优化导出
sunjiabei 1 month ago
parent
commit
d31de78076
  1. 28
      src/main/java/com/example/demo/Export/ExportServiceImpl.java
  2. 6
      src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java
  3. 32
      src/main/java/com/example/demo/Util/CacheRefreshTask.java
  4. 33
      src/main/java/com/example/demo/config/RedisConfig.java
  5. 3
      src/main/java/com/example/demo/controller/AdminController.java
  6. 2
      src/main/java/com/example/demo/controller/AuditController.java
  7. 5
      src/main/java/com/example/demo/controller/StatisticsController.java
  8. 3
      src/main/java/com/example/demo/controller/WorkbenchController.java
  9. 8
      src/main/java/com/example/demo/domain/entity/Statistics.java
  10. 18
      src/main/java/com/example/demo/domain/vo/MarketRechargeStat.java
  11. 11
      src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java
  12. 1
      src/main/java/com/example/demo/mapper/AdminMapper.java
  13. 2
      src/main/java/com/example/demo/mapper/GeneralMapper.java
  14. 9
      src/main/java/com/example/demo/mapper/StatisticsMapper.java
  15. 2
      src/main/java/com/example/demo/service/AdminService.java
  16. 2
      src/main/java/com/example/demo/service/RateService.java
  17. 6
      src/main/java/com/example/demo/service/StatisticsService.java
  18. 4
      src/main/java/com/example/demo/service/WorkbenchService.java
  19. 6
      src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java
  20. 9
      src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java
  21. 4
      src/main/java/com/example/demo/serviceImpl/RateServiceImpl.java
  22. 81
      src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java
  23. 111
      src/main/java/com/example/demo/serviceImpl/WorkbenchServiceImpl.java
  24. 6
      src/main/resources/application.yml
  25. 4
      src/main/resources/mapper/AdminMapper.xml
  26. 8
      src/main/resources/mapper/ConsumeMapper.xml
  27. 8
      src/main/resources/mapper/RechargeMapper.xml
  28. 12
      src/main/resources/mapper/RefundMapper.xml
  29. 51
      src/main/resources/mapper/StatisticsMapper.xml
  30. 23
      src/main/resources/mapper/WorkBenchMapper.xml

28
src/main/java/com/example/demo/Export/ExportServiceImpl.java

@ -5,10 +5,13 @@ import com.example.demo.domain.DTO.ConsumeDTO;
import com.example.demo.domain.DTO.RechargeDTO;
import com.example.demo.domain.DTO.RefundDTO;
import com.example.demo.domain.entity.Admin;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.Result;
import com.example.demo.exception.SystemException;
import com.example.demo.mapper.GoldDetailMapper;
import com.example.demo.Util.RedisUtil;
import com.example.demo.service.AdminService;
import com.example.demo.service.UserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
@ -22,6 +25,8 @@ import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;
/**
* @program: GOLD
* @ClassName ExportServiceImpl
@ -36,6 +41,8 @@ public class ExportServiceImpl implements ExportService{
private GoldDetailMapper goldDetailMapper;
@Autowired
private RedisUtil redisUtil;
@Autowired
private AdminService adminService;
@Override
public Result addExportRecharge(RechargeDTO dto) {
@ -48,10 +55,11 @@ public class ExportServiceImpl implements ExportService{
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
String admin = adminService.getName(String.valueOf(dto.getAccount()));
// 生成文件名
String fileName = String.format("%s_%s_%s.xlsx",
"充值明细",
"操作人",
admin,
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
System.out.println(fileName);
dto.setUrl("");
@ -78,10 +86,6 @@ public class ExportServiceImpl implements ExportService{
// 手动构造请求数据避免 toString() 只返回部分字段
Map<String, Object> requestData = new HashMap<>();
requestData.put("text", dto.getText());
requestData.put("sort", dto.getSort());
requestData.put("field", dto.getField());
requestData.put("deptId", dto.getDeptid());
requestData.put("rechargeUser", dto.getRechargeUser());
exportData.put("requestData", requestData);
@ -106,10 +110,11 @@ public class ExportServiceImpl implements ExportService{
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
String admin = adminService.getName(String.valueOf(dto.getAccount()));
// 生成文件名
String fileName = String.format("%s_%s_%s.xlsx",
"退款明细",
"操作人",
admin,
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
System.out.println(fileName);
dto.setUrl("");
@ -135,10 +140,6 @@ public class ExportServiceImpl implements ExportService{
// 手动构造请求数据避免 toString() 只返回部分字段
Map<String, Object> requestData = new HashMap<>();
requestData.put("text", dto.getText());
requestData.put("sort", dto.getSort());
requestData.put("field", dto.getField());
requestData.put("deptId", dto.getDeptid());
requestData.put("refundUser", dto.getRefundUser());
exportData.put("requestData", requestData);
@ -163,10 +164,11 @@ public class ExportServiceImpl implements ExportService{
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
String admin = adminService.getName(String.valueOf(dto.getAccount()));
// 生成文件名
String fileName = String.format("%s_%s_%s.xlsx",
"消耗明细",
"操作人",
admin,
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
System.out.println(fileName);
dto.setUrl("");
@ -192,10 +194,6 @@ public class ExportServiceImpl implements ExportService{
// 手动构造请求数据避免 toString() 只返回部分字段
Map<String, Object> requestData = new HashMap<>();
requestData.put("text", dto.getText());
requestData.put("sort", dto.getSort());
requestData.put("field", dto.getField());
requestData.put("deptId", dto.getDeptid());
requestData.put("consumeUser", dto.getConsumeUser());
exportData.put("requestData", requestData);

6
src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java

@ -34,8 +34,9 @@ public class MysqlServiceImpl implements MysqlService {
Set<Integer> validZeroTypes = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 18, 19, 20, 21, 22, 23, 24, 26, 28, 29, 35, 36, 40, 45, 46, 47, 48, 49, 53, 54, 60));
Set<Integer> validOneTypes = new HashSet<>(Arrays.asList(9, 15, 17, 25, 27, 37, 41, 42, 43, 50, 51, 62));
Set<Integer> validTwoTypes = new HashSet<>(Arrays.asList(52, 55, 56, 57, 58, 59, 61));
Set<Integer> validTwoTypes = new HashSet<>(Arrays.asList(52,61));
Set<Integer> validThreeTypes = new HashSet<>(Arrays.asList(10, 16, 30, 31, 32, 33, 34, 39, 44));
Set<Integer> validFourTypes = new HashSet<>(Arrays.asList(55, 56, 57, 58, 59, 63, 64, 65));
LocalDateTime now = LocalDateTime.now();
Month currentMonth = now.getMonth();
@Autowired
@ -102,6 +103,9 @@ public class MysqlServiceImpl implements MysqlService {
Random random = new Random();
int randomNumber = random.nextInt(900) + 100;
// 判断gtype
if(validFourTypes.contains(gtype)){
continue;
}
if(validZeroTypes.contains(gtype)){
mysqlStmt.setInt(13, 0);
mysqlStmt.setString(1, "ERPCZ"+timestampPart+randomNumber);

32
src/main/java/com/example/demo/Util/CacheRefreshTask.java

@ -0,0 +1,32 @@
package com.example.demo.Util;
import com.example.demo.service.WorkbenchService;
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.Component;
@Component
public class CacheRefreshTask {
private static final Logger logger = LoggerFactory.getLogger(CacheRefreshTask.class);
private final WorkbenchService workbenchService;
@Autowired
public CacheRefreshTask(WorkbenchService workbenchService) {
this.workbenchService = workbenchService;
}
// 每小时执行一次1分0秒
@Scheduled(cron = "0 1 * * * ?")
public void refreshCache() {
try {
workbenchService.getCardCache(); // 内部会重新查询并写入缓存
logger.info("缓存刷新成功:" + new java.util.Date());
} catch (Exception e) {
logger.error("缓存刷新失败:" + e.getMessage(), e);
}
}
}

33
src/main/java/com/example/demo/config/RedisConfig.java

@ -1,6 +1,7 @@
package com.example.demo.config;
import com.example.demo.domain.vo.WorkbenchCard;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -8,6 +9,8 @@ import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@ -42,6 +45,36 @@ public class RedisConfig {
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置键的序列化方式为 String
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 设置 Hash Key Value 的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
@Bean
public RedisTemplate<String, WorkbenchCard> workbenchCardRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, WorkbenchCard> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 设置键的序列化方式为 String
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 设置 Hash Key Value 的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}

3
src/main/java/com/example/demo/controller/AdminController.java

@ -55,6 +55,7 @@ public class AdminController {
System.out.println("1/*/*/*/*//*-*-*-*-*-*-1" + token);
try {
System.out.println("/+/+/+/+/+/+/+//" + JWTUtil.getUserDetailsList(String.valueOf(token), Admin.class));
return JWTUtil.getUserDetailsList(String.valueOf(token), Admin.class);
} catch (Exception e) {
throw new RuntimeException(e);
@ -74,7 +75,6 @@ public class AdminController {
}
}
//更新用户密码
@PostMapping("/password")
public Result updatePassword(@RequestBody Password password){
@ -87,7 +87,6 @@ public class AdminController {
}
//更新用户密码
@PostMapping("/reset")
public Result resetPassword(@RequestBody Password password){

2
src/main/java/com/example/demo/controller/AuditController.java

@ -23,7 +23,7 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/audit")
@RequiredArgsConstructor
@Slf4j
@Transactional
@CrossOrigin
public class AuditController {

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

@ -44,6 +44,11 @@ public class StatisticsController {
public void HourlyTask2() {
statisticsService.runHourlyTaskPart2();
}
//测试定时任务年度
@PostMapping("/HourlyYear")
public void HourlyYear() {
statisticsService.runHourlyTaskYear();
}
//测试一周内定时任务part2
@PostMapping("/Daily2")
public void DailyTask2() {

3
src/main/java/com/example/demo/controller/WorkbenchController.java

@ -43,7 +43,7 @@ public class WorkbenchController {
*/
@PostMapping("getCard")
public ResponseEntity<WorkbenchCard> card1(@RequestBody WorkbenchCard workbench){
WorkbenchCard result =workbenchService.getCard();
WorkbenchCard result =workbenchService.getCardCache();
return ResponseEntity.ok(result);
}
/*
@ -61,6 +61,7 @@ public class WorkbenchController {
public ResponseEntity<WorkbenchCard> updateCard(@RequestBody WorkbenchCard workbench){
statisticsService.runHourlyTaskPart1(); //更新余量数据
statisticsService.runHourlyTaskPart2(); //更新余量外数据
WorkbenchCard result =workbenchService.getCard(); //获取卡片数据
return ResponseEntity.ok(result);
}

8
src/main/java/com/example/demo/domain/entity/Statistics.java

@ -47,6 +47,14 @@ public class Statistics implements Serializable {
private Integer refundTask; // 当日新增退款(任务)
private Integer rechargeNum; // 当日充值人数
private Integer firstRecharge; // 当日首充人数
private Integer yearlyRecharge; // 全年累计充值
private Integer yearlyMoney; // 全年累计金额
private Integer yearlyConsume; // 全年累计消费
private Integer yearlyRefund; // 全年累计退款
private Integer yearlyRechargeNum; // 全年累计充值人数
// 数据日期
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = LocalDateDeserializer.class)

18
src/main/java/com/example/demo/domain/vo/MarketRechargeStat.java

@ -0,0 +1,18 @@
package com.example.demo.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MarketRechargeStat {
private String market;
private Integer todayRechargeUsers; // 今日充值人数
private Integer yesterdayRechargeUsers; // 昨日充值人数
private Integer yearlyRechargeUsers; // 年累计充值人数
}

11
src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java

@ -61,13 +61,8 @@ public class WorkbenchMarketCard implements Serializable {
private Integer sumDaily; // 总日环比%
private Integer yearlyRechargeNum; // 全年累计充值人头数
//更新时间
/* //更新时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updateTime;
//图表
private Integer SumRechargePermanent; //合计充值永久金币
private Integer SumRechargeFree; //合计充值免费金币
private Integer SumConsumePermanent; //合计消费永久金币
private Integer SumConsumeFree; //合计消费免费金币
private Integer SumConsumeTask; //合计消费任务金币
private Date updateTime;*/
}

1
src/main/java/com/example/demo/mapper/AdminMapper.java

@ -26,4 +26,5 @@ public interface AdminMapper {
void updatePassword(Admin admin);
String getName(String account);
}

2
src/main/java/com/example/demo/mapper/GeneralMapper.java

@ -15,9 +15,7 @@ import java.util.List;
@Mapper
public interface GeneralMapper {
List<String> getMarket();
List<String> getPlatform();
//获取商品
List<String> getGoods();

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

@ -2,6 +2,7 @@ package com.example.demo.mapper;
import com.example.demo.domain.entity.Statistics;
import com.example.demo.domain.entity.UserGoldRecord;
import com.example.demo.domain.vo.MarketRechargeStat;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -20,6 +21,9 @@ import java.util.List;
@Mapper
public interface StatisticsMapper {
//批量查询
List<Statistics> selectByMarketsAndDate(@Param("markets") List<String> markets, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
//根据地区审核状态起止时间查询订单表数据
List<UserGoldRecord> findByMarketAndAuditStatus(@Param("market") String market,
@Param("auditStatusList") List<Integer> auditStatusList,
@ -51,6 +55,10 @@ public interface StatisticsMapper {
void insertPart2(Statistics statistics);
//更新part2统计数据
void updatePart2(Statistics statistics);
//新增年度统计数据
void insertYear(Statistics statistics);
//更新年度统计数据
void updateYear(Statistics statistics);
//获取某地区某时间所在日期的数据仅一条
Statistics selectByMarketAndDate(@Param("market") String market,
@Param("startDate") Date startDate,
@ -59,4 +67,5 @@ public interface StatisticsMapper {
Statistics selectSumByMarketAndDate(@Param("market") String market,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate);
}

2
src/main/java/com/example/demo/service/AdminService.java

@ -17,6 +17,7 @@ public interface AdminService {
//获取用户ID
String getId(String account);
String getName(String account);
//更新密码
Result updatePassword(Password password);
@ -24,3 +25,4 @@ public interface AdminService {
//重置密码
Result resetPassword(Password password);
}

2
src/main/java/com/example/demo/service/RateService.java

@ -7,7 +7,7 @@ import com.github.pagehelper.PageInfo;
public interface RateService {
PageInfo<Rate> selectAll(Integer pageNum, Integer pageSize);
PageInfo<RateDetail> selectAll(Integer pageNum, Integer pageSize);
Rate selectById(Integer id);

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

@ -19,6 +19,8 @@ public interface StatisticsService {
public void runHourlyTaskPart1();
//每小时执行定时任务更新当天part2数据
public void runHourlyTaskPart2();
//每小时执行定身任务更新当天全年累计数据
public void runHourlyTaskYear();
//0点执行定时任务更新近一周part2数据
public void runDailyTaskPart2();
//查询某地区某天是否已存在统计数据
@ -26,11 +28,15 @@ public interface StatisticsService {
//新增或更新或不修改某地区某天part1统计数据
public void saveStatisticsPart1(String market, Date date);
//新增或更新或不修改某地区某天年度统计数据
public void saveStatisticsYear(String market,Date yearlyStartDate, Date date);
//新增或更新或不修改某地区某天part2统计数据
public void saveStatisticsPart2(String market, Date date);
//根据地区与日期获取part1(余量属性)统计数据
public Statistics getStatisticsPart1(String market, Date date);
//根据地区与日期获取part2(余量外属性)统计数据
public Statistics getStatisticsPart2(String market, Date date);
//根据地区与日期获取全年累计统计数据
public Statistics getYearlyStatistics(String market,Date yearlyStartDate, Date date);
}

4
src/main/java/com/example/demo/service/WorkbenchService.java

@ -21,8 +21,10 @@ import java.util.Map;
public interface WorkbenchService {
//获取不同地区的工作台统计卡片
WorkbenchCard getCard( );
//缓存卡片数据
WorkbenchCard getCardCache();
//获取卡片数据
WorkbenchMarketCard createWorkbenchMarketCard(String market, Statistics currentStatistics,Statistics ydayStatistics, Date yearlyStartDate, Date currentDate);
WorkbenchMarketCard createWorkbenchMarketCard(String market, Statistics currentStatistics,Statistics ydayStatistics, Date currentDate);
//获取不同地区的工作台柱状图数据根据类型起止时间地区查询
WorkbenchCard getGraph(Date startDate, Date endDate, List<String> markets);
//根据类型获取年初至今的统计数据

6
src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java

@ -63,12 +63,18 @@ public class AdminServiceImpl implements AdminService {
throw new RuntimeException("登录失败,请稍后再试", e);
}
}
//获取用户ID
@Override
public String getId(String account) {
return adminMapper.getAdmin(account).getId().toString();
}
@Override
public String getName(String account) {
return adminMapper.getName(account);
}
private boolean hasPermissionToMachine(Admin admin, String targetMachineId) {
if (targetMachineId == null || admin.getMachineId() == null) {
return false;

9
src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java

@ -9,6 +9,7 @@ import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.*;
import com.example.demo.exception.SystemException;
import com.example.demo.mapper.GoldDetailMapper;
import com.example.demo.service.AdminService;
import com.example.demo.service.GoldDetailService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
@ -42,6 +43,8 @@ public class GoldDetailServiceImpl implements GoldDetailService {
private GoldDetailMapper goldDetailMapper;
@Autowired
private RedisUtil redisUtil;
@Autowired
private AdminService adminService;
@Override
public PageInfo<GoldDetail> getGoldDetail(Integer pageNum, Integer pageSize, GoldDetail goldDetail) {
@ -124,10 +127,11 @@ public class GoldDetailServiceImpl implements GoldDetailService {
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
String admin = adminService.getName(String.valueOf(dto.getAccount()));
// 生成文件名
String fileName = String.format("%s_%s_%s.xlsx",
"客户金币明细",
"操作人",
admin,
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
System.out.println(fileName);
dto.setUrl("");
@ -182,10 +186,11 @@ public class GoldDetailServiceImpl implements GoldDetailService {
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
String admin = adminService.getName(String.valueOf(dto.getAccount()));
// 生成文件名
String fileName = String.format("%s_%s_%s.xlsx",
"金币余额明细",
"操作人",
admin,
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
System.out.println(fileName);
dto.setUrl("");

4
src/main/java/com/example/demo/serviceImpl/RateServiceImpl.java

@ -22,9 +22,9 @@ public class RateServiceImpl implements RateService {
@Override
public PageInfo<Rate> selectAll(Integer pageNum, Integer pageSize) {
public PageInfo<RateDetail> selectAll(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<Rate> rates = rateMapper.selectAll();
List<RateDetail> rates = rateMapper.selectAll();
return new PageInfo<>(rates);
}

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

@ -5,6 +5,7 @@ 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 com.example.demo.service.WorkbenchService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -34,6 +35,8 @@ public class StatisticsServiceImpl implements StatisticsService {
private StatisticsMapper statisticsMapper;
@Autowired
private GeneralService generalService;
@Autowired
private WorkbenchService workbenchService;
/*
每小时执行定时任务更新当天part1数据
@ -59,6 +62,27 @@ public class StatisticsServiceImpl implements StatisticsService {
}
}
/*
每小时执行定时任务更新年度数据
*/
@Override
@Scheduled(cron = "0 0 * * * ?") // 每小时执行一次
public void runHourlyTaskYear() {
Date today = new Date();
// 获取当前日期
LocalDate today1 = LocalDate.now();
// 获取当前年份的第一天
LocalDate firstDayOfYear = today1.withDayOfYear(1);
// 将年份的第一天日期转换为Date类型
Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant());
for(String market : generalService.getMarket()){
saveStatisticsYear(market,yearlyStartDate,today);
}
}
/*
0点执行定时任务更新近一周part2数据
*/
@Override
@ -122,6 +146,29 @@ public class StatisticsServiceImpl implements StatisticsService {
}
}
}
/*
新增或更新或不修改某地区某天年度统计数据
*/
@Override
public void saveStatisticsYear(String market,Date yearlyStartDate, Date date) {
//获取该地区该日期年度统计数据
Statistics newStats=getYearlyStatistics(market,yearlyStartDate,date);
//获取该地区该日期已存在的数据
Statistics existStats = getExistStatistics(market, date);
//判断是否存在已存在的数据
if(existStats==null){
//没有记录新增
statisticsMapper.insertYear(newStats );
}else {
//判断新旧数据年度部分是否一致
if (!isSameStatisticsYear(existStats,newStats)){
statisticsMapper.updateYear(newStats);
}else{
System.out.println("数据未发生改变");
}
}
}
/*
新增或更新或不修改某地区某天part2统计数据
@ -141,6 +188,8 @@ public class StatisticsServiceImpl implements StatisticsService {
if (!isSameStatisticsPart2(existStats,newStats)){
statisticsMapper.updatePart2(newStats);
}else{
// existStats.setUpdateTime(date);
// statisticsMapper.updatePart2(existStats);
System.out.println("数据未发生改变");
}
}
@ -292,6 +341,28 @@ public class StatisticsServiceImpl implements StatisticsService {
return statistics;
}
@Override
public Statistics getYearlyStatistics(String market,Date yearlyStartDate, Date date) {
//获取日期
LocalDate localDate=date.toInstant()
.atZone(ZoneId.of("Asia/Shanghai")) // 使用系统默认时区
.toLocalDate();
// 一次性获取全年统计数据从年初到今天
Map<String, Integer> yearlyStats = workbenchService.calculateAllSum(market, yearlyStartDate, date);
//初始化Statistics对象
Statistics statistics = new Statistics();
statistics.setMarket(market);
statistics.setCurrentDatetime(localDate);
statistics.setYearlyRecharge(yearlyStats.getOrDefault("recharge", 0)); // 充值-全年累计充值
statistics.setYearlyMoney(yearlyStats.getOrDefault("money", 0)); // 充值-全年累计金额永久//充值-全年累计金额永久
statistics.setYearlyConsume(yearlyStats.getOrDefault("consume", 0)); // 年累计消费
statistics.setYearlyRefund(yearlyStats.getOrDefault("refund", 0)); // 年累计退款
statistics.setYearlyRechargeNum(yearlyStats.getOrDefault("rechargeNum", 0));//年累计充值人数
return statistics;
}
/*
* 判断两个统计对象part1(余量属性)是否相同
*/
@ -326,4 +397,14 @@ private boolean isSameStatisticsPart1(Statistics oldStats, Statistics newStats)
Objects.equals(oldStats.getCurrentFreeDecember(), newStats.getCurrentFreeDecember()) &&
Objects.equals(oldStats.getCurrentTask(), newStats.getCurrentTask());
}
/*
* 判断两个统计对象年度统计是否相同
*/
private boolean isSameStatisticsYear(Statistics oldStats, Statistics newStats) {
return Objects.equals(oldStats.getYearlyRecharge(), newStats.getYearlyRecharge()) &&
Objects.equals(oldStats.getYearlyMoney(), newStats.getYearlyMoney()) &&
Objects.equals(oldStats.getYearlyConsume(), newStats.getYearlyConsume()) &&
Objects.equals(oldStats.getYearlyRefund(), newStats.getYearlyRefund()) &&
Objects.equals(oldStats.getYearlyRechargeNum(), newStats.getYearlyRechargeNum()) ;}
}

111
src/main/java/com/example/demo/serviceImpl/WorkbenchServiceImpl.java

@ -11,6 +11,8 @@ import com.example.demo.service.GeneralService;
import com.example.demo.service.StatisticsService;
import com.example.demo.service.WorkbenchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
@ -19,6 +21,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -32,71 +35,94 @@ import java.util.stream.Collectors;
@Service
public class WorkbenchServiceImpl implements WorkbenchService {
private final RedisTemplate<String, WorkbenchCard> redisTemplate;
// private final StatisticsMapper statisticsMapper;
@Autowired
private WorkBenchMapper workBenchMapper;
@Autowired
private GeneralService generalService;
@Autowired
private StatisticsMapper statisticsMapper;
@Autowired
public WorkbenchServiceImpl(RedisTemplate<String, WorkbenchCard> redisTemplate, StatisticsMapper statisticsMapper) {
this.redisTemplate = redisTemplate;
this.statisticsMapper = statisticsMapper;
}
private static final String CACHE_KEY = "workbench_card_cache";
@Override
public WorkbenchCard getCard( ) {
Date date=new Date();//当天
Date yday=generalService.getYesterday();
// 获取开始时间和结束时间当天
LocalDateTime startOfDay = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
.with(LocalTime.MIN);
LocalDateTime startOfDay = LocalDateTime.now().with(LocalTime.MIN);
LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
// 获取开始时间和结束时间当天
LocalDateTime startOfYday = yday.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
.with(LocalTime.MIN);
LocalDateTime endOfYday = startOfYday.plusDays(1).minusSeconds(1);
// 获取当前日期
LocalDate today = LocalDate.now();
// 获取开始时间和结束时间昨天
LocalDateTime startOfYday = startOfDay.minusDays(1);
LocalDateTime endOfYday = endOfDay.minusDays(1);
// 获取当前年份的第一天
LocalDate firstDayOfYear = today.withDayOfYear(1);
// 将年份的第一天日期转换为Date类型
LocalDate firstDayOfYear = LocalDate.now().withDayOfYear(1);
Date yearlyStartDate = Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant());
List<String> markets = generalService.getMarket();
// 批量获取统计数据
List<Statistics> currentStatsList = statisticsMapper.selectByMarketsAndDate(markets,
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()));
List<Statistics> ydayStatsList = statisticsMapper.selectByMarketsAndDate(markets,
Date.from(startOfYday.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endOfYday.atZone(ZoneId.systemDefault()).toInstant()));
// List<Statistics> 转换为 Map<String, Statistics>
Map<String, Statistics> currentStatsMap = currentStatsList.stream()
.collect(Collectors.toMap(Statistics::getMarket, Function.identity(), (existing, replacement) -> existing));
Map<String, Statistics> ydayStatsMap = ydayStatsList.stream()
.collect(Collectors.toMap(Statistics::getMarket, Function.identity(), (existing, replacement) -> existing));
// 并行处理市场列表创建市场卡片列表
List<WorkbenchMarketCard> marketCards = markets.parallelStream()
// 过滤掉空或全空格的市场名称
.filter(market -> market != null && !market.trim().isEmpty())
.map(market -> {
// 根据市场名称和日期范围查询统计信息
Statistics currentStatistics = statisticsMapper.selectByMarketAndDate(
.map(market -> createWorkbenchMarketCard(
market,
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
);
Statistics ydayStatistics = statisticsMapper.selectByMarketAndDate(
market,
Date.from(startOfYday.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endOfYday.atZone(ZoneId.systemDefault()).toInstant())
);
// 创建并返回市场卡片对象
return createWorkbenchMarketCard(market, currentStatistics,ydayStatistics, yearlyStartDate, date);
})
// 收集并行流结果为列表
currentStatsMap.getOrDefault(market, null),
ydayStatsMap.getOrDefault(market, null),
new Date()))
.collect(Collectors.toList());
return new WorkbenchCard( marketCards,new ArrayList<>(), markets, date, date);
return new WorkbenchCard(marketCards, new ArrayList<>(), markets, new Date(), new Date());
}
@Override
public WorkbenchCard getCardCache() {
WorkbenchCard cached = redisTemplate.opsForValue().get(CACHE_KEY);
if (cached != null) {
System.out.println("读取缓存数据: " + new Date());
return cached;
}
try {
WorkbenchCard freshData = getCard();
redisTemplate.opsForValue().set(CACHE_KEY, freshData, 1, java.util.concurrent.TimeUnit.HOURS);
System.out.println("刷新缓存并存储新数据: " + new Date());
return freshData;
} catch (Exception e) {
System.err.println("查询数据库失败,尝试使用旧缓存数据或抛出异常:" + e.getMessage());
throw e; // 或者你可以选择返回上次的缓存数据如果有
}
}
/*
获取卡片数据
*/
@Override
public WorkbenchMarketCard createWorkbenchMarketCard(String market,Statistics currentStatistics, Statistics ydayStatistics, Date yearlyStartDate, Date currentDate) {
public WorkbenchMarketCard createWorkbenchMarketCard(String market,Statistics currentStatistics, Statistics ydayStatistics, Date currentDate) {
Date date=new Date();
WorkbenchMarketCard card = new WorkbenchMarketCard();
card.setMarket(market);
if (currentStatistics != null&& ydayStatistics != null) {
// 一次性获取全年统计数据从年初到今天
Map<String, Integer> yearlyStats = calculateAllSum(market, yearlyStartDate, date);
// Map<String, Integer> yearlyStats = calculateAllSum(market, yearlyStartDate, date);
// 卡片一当前金币相关
card.setCurrentPermanent(currentStatistics.getCurrentPermanent());//余量-永久金币
card.setCurrentFreeJune(currentStatistics.getCurrentFreeJune()); //余量-免费六月金币
@ -108,8 +134,8 @@ public class WorkbenchServiceImpl implements WorkbenchService {
// 卡片二充值相关
card.setRecharge(ydayStatistics.getRecharge()); //充值-昨日充值
card.setMoney(ydayStatistics.getMoney()); //充值-昨日金额永久
card.setYearlyRecharge(yearlyStats.getOrDefault("recharge", 0)); // 充值-全年累计充值
card.setYearlyMoney(yearlyStats.getOrDefault("money", 0)); // 充值-全年累计金额永久//充值-全年累计金额永久
card.setYearlyRecharge(currentStatistics.getYearlyRecharge()); // 充值-全年累计充值
card.setYearlyMoney(currentStatistics.getYearlyMoney()); // 充值-全年累计金额永久//充值-全年累计金额永久
// 卡片三消费与退款
card.setConsumePermanent(ydayStatistics.getConsumePermanent());//昨日消费-永久金币
card.setConsumeFreeJune(ydayStatistics.getConsumeFreeJune());//昨日消费-免费六月金币
@ -124,20 +150,20 @@ public class WorkbenchServiceImpl implements WorkbenchService {
//昨日总退款
int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
card.setDailyReduce(totalConsume - totalRefund);//昨日总消耗
card.setYearlyConsume(yearlyStats.getOrDefault("consume", 0)); // 年累计消费
card.setYearlyRefund(yearlyStats.getOrDefault("refund", 0)); // 年累计退款
card.setYearlyConsume(currentStatistics.getYearlyConsume()); // 年累计消费
card.setYearlyRefund(currentStatistics.getYearlyRefund()); // 年累计退款
card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
// 卡片四人头数相关
card.setRechargeNum(currentStatistics.getRechargeNum());
card.setFirstRecharge(currentStatistics.getFirstRecharge());
card.setYearlyRechargeNum(yearlyStats.getOrDefault("rechargeNum", 0));
card.setYearlyRechargeNum(currentStatistics.getYearlyRechargeNum());
// 周环比日同比
card.setWow(calculateWeekOverWeek(market, currentDate));
card.setSumWow(calculateAllWeekOverWeek(date));
card.setDaily(calculateDayOverDay(market, currentDate));
card.setSumDaily(calculateAllDayOverDay(date));
//更新时间
card.setUpdateTime(currentStatistics.getUpdateTime());
/* //更新时间
card.setUpdateTime(currentStatistics.getUpdateTime());*/
}
return card;
}
@ -166,6 +192,7 @@ public class WorkbenchServiceImpl implements WorkbenchService {
根据类型获取统计数据
*/
@Override
public Map<String, Integer> calculateAllSum(String market, Date startDate, Date endDate) {
WorkbenchFullStatistics stats = workBenchMapper.getFullStatisticsByMarketAndDate(market, startDate, endDate);
Map<String, Integer> result = new HashMap<>();

6
src/main/resources/application.yml

@ -4,9 +4,9 @@ spring:
fail-on-unknown-properties: false
datasource:
mysql1:
jdbc-url: jdbc:mysql://18.143.76.3:3306/hwgoldc?serverTimezone=Asia/Shanghai
username: hwgoldc
password: zB48T55wCsHC8KPz
jdbc-url: jdbc:mysql://18.143.76.3:3306/hwgold?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true
username: hwgold
password: aDiw7MERSATdfGta
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
pool-name: mysql1HikariCP

4
src/main/resources/mapper/AdminMapper.xml

@ -22,4 +22,8 @@
update_time = #{updateTime}
where account = #{account}
</update>
<select id="getName" resultType="java.lang.String">
select admin_name from admin
where account= #{account}
</select>
</mapper>

8
src/main/resources/mapper/ConsumeMapper.xml

@ -72,10 +72,10 @@
ugr.remark AS remark,
a.admin_name AS adminName,
ugr.create_time AS createTime
FROM user u
JOIN
user_gold_record ugr ON u.jwcode = ugr.jwcode
JOIN
FROM user_gold_record ugr
left JOIN
user u ON u.jwcode = ugr.jwcode
left JOIN
admin a ON ugr.admin_id = a.id
<where>
ugr.type = 1

8
src/main/resources/mapper/RechargeMapper.xml

@ -79,10 +79,10 @@
ugr.admin_id AS adminId,
a.admin_name AS adminName,
ugr.pay_time AS payTime
FROM user u
JOIN user_gold_record ugr ON u.jwcode = ugr.jwcode
JOIN admin a ON ugr.admin_id = a.id
JOIN rate r ON ugr.rate_id = r.id
FROM user_gold_record ugr
left JOIN user u ON u.jwcode = ugr.jwcode
left JOIN admin a ON ugr.admin_id = a.id
left JOIN rate r ON ugr.rate_id = r.id
<where>
ugr.type = 0 AND ugr.audit_status IN (1,3)
<if test="jwcode != null and jwcode != ''">

12
src/main/resources/mapper/RefundMapper.xml

@ -19,9 +19,9 @@
a.admin_name AS adminName,
ugr.create_time AS createTime
FROM user u
JOIN
left JOIN
user_gold_record ugr ON u.jwcode = ugr.jwcode
JOIN
left JOIN
admin a ON ugr.admin_id = a.id
WHERE ugr.type = 2 AND ugr.audit_status IN (1,3)
<trim prefix="ORDER BY" suffixOverrides=",">
@ -76,10 +76,10 @@
ugr.remark AS remark,
a.admin_name AS adminName,
ugr.create_time AS createTime
FROM user u
JOIN
user_gold_record ugr ON u.jwcode = ugr.jwcode
JOIN
FROM user_gold_record ugr
left JOIN
user u ON u.jwcode = ugr.jwcode
left JOIN
admin a ON ugr.admin_id = a.id
<where>
ugr.type = 2 AND ugr.audit_status IN (1,3)

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

@ -37,10 +37,29 @@
)
</insert>
<!--新增年度统计-->
<insert id="insertYear">
INSERT INTO statistics (
market, current_datetime,
yearly_recharge,
yearly_money,
yearly_consume,
yearly_refund,
yearly_recharge_num
) VALUES (
#{market}, #{currentDatetime},
#{yearlyRecharge},#{yearlyMoney},
#{yearlyConsume},#{yearlyRefund},
#{yearlyRechargeNum}
)
</insert>
<!--更新part2统计数据-->
<update id="updatePart2" parameterType="map">
UPDATE statistics
SET
recharge = #{recharge},
money = #{money},
consume_permanent = #{consumePermanent},
@ -53,6 +72,9 @@
refund_task = #{refundTask},
recharge_num = #{rechargeNum},
first_recharge = #{firstRecharge}
<if test="updateTime != null">
,update_time = #{updateTime}
</if>
WHERE market = #{market} and current_datetime = #{currentDatetime}
</update>
<!--更新part1统计数据-->
@ -67,6 +89,18 @@
current_task = #{currentTask}
WHERE market = #{market} and current_datetime = #{currentDatetime}
</update>
<!--更新年度统计数据-->
<update id="updateYear" parameterType="map">
update statistics
SET
yearly_recharge=#{yearlyRecharge},
yearly_money=#{yearlyMoney},
yearly_consume=#{yearlyConsume},
yearly_refund=#{yearlyRefund},
yearly_recharge_num=#{yearlyRechargeNum}
WHERE market = #{market} and current_datetime = #{currentDatetime}
</update>
<!--根据地区、审核状态、起止时间查询订单表数据-->
<select id="findByMarketAndAuditStatus"
resultType="com.example.demo.domain.entity.UserGoldRecord">
@ -110,22 +144,22 @@
</select>
<select id="sumCurrentPermanentGold" resultType="java.lang.Integer">
SELECT SUM(user.current_permanent_gold)
SELECT COALESCE(SUM(current_permanent_gold), 0)
FROM user
WHERE user.market = #{market}
</select>
<select id="sumCurrentFreeJune" resultType="java.lang.Integer">
SELECT SUM(u.current_free_june)
SELECT COALESCE(SUM(u.current_free_june),0)
FROM user as u
WHERE u.market = #{market}
</select>
<select id="sumCurrentFreeDecember" resultType="java.lang.Integer">
SELECT SUM(u.current_free_december)
SELECT COALESCE(SUM(u.current_free_december),0)
FROM user as u
WHERE u.market = #{market}
</select>
<select id="sumCurrentTaskGold" resultType="java.lang.Integer">
SELECT SUM(u.current_task_gold)
SELECT COALESCE(SUM(u.current_task_gold),0)
FROM user as u
WHERE u.market = #{market}
</select>
@ -142,5 +176,14 @@
AND current_datetime >= #{startDate}
AND current_datetime &lt;= #{endDate}
</select>
<select id="selectByMarketsAndDate" resultType="com.example.demo.domain.entity.Statistics">
SELECT * FROM statistics
WHERE market IN
<foreach item="market" collection="markets" open="(" separator="," close=")">
#{market}
</foreach>
AND current_datetime BETWEEN #{startDate} AND #{endDate}
</select>
</mapper>

23
src/main/resources/mapper/WorkBenchMapper.xml

@ -90,23 +90,22 @@
<!-- 获取指定地区在时间段内的全部统计数据 -->
<select id="getFullStatisticsByMarketAndDate" resultType="com.example.demo.domain.vo.WorkbenchFullStatistics">
SELECT
SUM(recharge) AS totalRecharge,
SUM(money) AS totalMoney,
SUM(consume_permanent) AS totalConsumePermanent,
SUM(consume_free_june + consume_free_december) AS totalConsumeFree,
SUM(consume_task) AS totalConsumeTask,
SUM(refund_permanent + refund_free_june + refund_free_december + refund_task) AS totalRefund,
COUNT(DISTINCT ugr.jwcode) AS totalRechargeNum
FROM statistics s
LEFT JOIN (
SELECT DISTINCT ugr.jwcode
SUM(s.recharge) AS totalRecharge,
SUM(s.money) AS totalMoney,
SUM(s.consume_permanent) AS totalConsumePermanent,
SUM(s.consume_free_june + s.consume_free_december) AS totalConsumeFree,
SUM(s.consume_task) AS totalConsumeTask,
SUM(s.refund_permanent + s.refund_free_june + s.refund_free_december + s.refund_task) AS totalRefund,
(
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.pay_time BETWEEN #{startDate} AND #{endDate}
AND ugr.audit_status IN (1, 3)
) ugr ON 1=1
) AS totalRechargeNum
FROM statistics s
WHERE s.market = #{market}
AND s.current_datetime BETWEEN #{startDate} AND #{endDate}
AND s.current_datetime BETWEEN #{startDate} AND #{endDate};
</select>
</mapper>
Loading…
Cancel
Save