diff --git a/src/main/java/com/example/demo/Export/ExportServiceImpl.java b/src/main/java/com/example/demo/Export/ExportServiceImpl.java index 78cc419..1e177eb 100644 --- a/src/main/java/com/example/demo/Export/ExportServiceImpl.java +++ b/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 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 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 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); diff --git a/src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java b/src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java index 0036465..b455b49 100644 --- a/src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java +++ b/src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java @@ -34,8 +34,9 @@ public class MysqlServiceImpl implements MysqlService { Set 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 validOneTypes = new HashSet<>(Arrays.asList(9, 15, 17, 25, 27, 37, 41, 42, 43, 50, 51, 62)); - Set validTwoTypes = new HashSet<>(Arrays.asList(52, 55, 56, 57, 58, 59, 61)); + Set validTwoTypes = new HashSet<>(Arrays.asList(52,61)); Set validThreeTypes = new HashSet<>(Arrays.asList(10, 16, 30, 31, 32, 33, 34, 39, 44)); + Set 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); diff --git a/src/main/java/com/example/demo/Util/CacheRefreshTask.java b/src/main/java/com/example/demo/Util/CacheRefreshTask.java new file mode 100644 index 0000000..e2f2f0d --- /dev/null +++ b/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); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/config/RedisConfig.java b/src/main/java/com/example/demo/config/RedisConfig.java index 3cae685..a019ee2 100644 --- a/src/main/java/com/example/demo/config/RedisConfig.java +++ b/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 redisTemplate(RedisConnectionFactory factory) { + RedisTemplate 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 workbenchCardRedisTemplate(RedisConnectionFactory factory) { + RedisTemplate 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; + } } diff --git a/src/main/java/com/example/demo/controller/AdminController.java b/src/main/java/com/example/demo/controller/AdminController.java index ba835a4..ab56559 100644 --- a/src/main/java/com/example/demo/controller/AdminController.java +++ b/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){ diff --git a/src/main/java/com/example/demo/controller/AuditController.java b/src/main/java/com/example/demo/controller/AuditController.java index 349df97..4506952 100644 --- a/src/main/java/com/example/demo/controller/AuditController.java +++ b/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 { diff --git a/src/main/java/com/example/demo/controller/StatisticsController.java b/src/main/java/com/example/demo/controller/StatisticsController.java index c1a9726..0b9e37f 100644 --- a/src/main/java/com/example/demo/controller/StatisticsController.java +++ b/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() { diff --git a/src/main/java/com/example/demo/controller/WorkbenchController.java b/src/main/java/com/example/demo/controller/WorkbenchController.java index 5d02ba9..dd21035 100644 --- a/src/main/java/com/example/demo/controller/WorkbenchController.java +++ b/src/main/java/com/example/demo/controller/WorkbenchController.java @@ -43,7 +43,7 @@ public class WorkbenchController { */ @PostMapping("getCard") public ResponseEntity 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 updateCard(@RequestBody WorkbenchCard workbench){ statisticsService.runHourlyTaskPart1(); //更新余量数据 statisticsService.runHourlyTaskPart2(); //更新余量外数据 + WorkbenchCard result =workbenchService.getCard(); //获取卡片数据 return ResponseEntity.ok(result); } diff --git a/src/main/java/com/example/demo/domain/entity/Statistics.java b/src/main/java/com/example/demo/domain/entity/Statistics.java index 5bb64e3..3e3ce93 100644 --- a/src/main/java/com/example/demo/domain/entity/Statistics.java +++ b/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) diff --git a/src/main/java/com/example/demo/domain/vo/MarketRechargeStat.java b/src/main/java/com/example/demo/domain/vo/MarketRechargeStat.java new file mode 100644 index 0000000..ac6e1ca --- /dev/null +++ b/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; // 年累计充值人数 + + +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java b/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java index 48b2ef0..fb1ea4b 100644 --- a/src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java +++ b/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;*/ + } diff --git a/src/main/java/com/example/demo/mapper/AdminMapper.java b/src/main/java/com/example/demo/mapper/AdminMapper.java index 67c46b8..a2a41ef 100644 --- a/src/main/java/com/example/demo/mapper/AdminMapper.java +++ b/src/main/java/com/example/demo/mapper/AdminMapper.java @@ -26,4 +26,5 @@ public interface AdminMapper { void updatePassword(Admin admin); + String getName(String account); } diff --git a/src/main/java/com/example/demo/mapper/GeneralMapper.java b/src/main/java/com/example/demo/mapper/GeneralMapper.java index 56246c2..3880ea1 100644 --- a/src/main/java/com/example/demo/mapper/GeneralMapper.java +++ b/src/main/java/com/example/demo/mapper/GeneralMapper.java @@ -15,9 +15,7 @@ import java.util.List; @Mapper public interface GeneralMapper { List getMarket(); - List getPlatform(); - //获取商品 List getGoods(); diff --git a/src/main/java/com/example/demo/mapper/StatisticsMapper.java b/src/main/java/com/example/demo/mapper/StatisticsMapper.java index d54f350..9cb41bf 100644 --- a/src/main/java/com/example/demo/mapper/StatisticsMapper.java +++ b/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 selectByMarketsAndDate(@Param("markets") List markets, @Param("startDate") Date startDate, @Param("endDate") Date endDate); + //根据地区、审核状态、起止时间查询订单表数据 List findByMarketAndAuditStatus(@Param("market") String market, @Param("auditStatusList") List 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); + } diff --git a/src/main/java/com/example/demo/service/AdminService.java b/src/main/java/com/example/demo/service/AdminService.java index 5c0d4f4..7b90e1d 100644 --- a/src/main/java/com/example/demo/service/AdminService.java +++ b/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); } + diff --git a/src/main/java/com/example/demo/service/RateService.java b/src/main/java/com/example/demo/service/RateService.java index 0a14b2f..e0b2b1f 100644 --- a/src/main/java/com/example/demo/service/RateService.java +++ b/src/main/java/com/example/demo/service/RateService.java @@ -7,7 +7,7 @@ import com.github.pagehelper.PageInfo; public interface RateService { - PageInfo selectAll(Integer pageNum, Integer pageSize); + PageInfo selectAll(Integer pageNum, Integer pageSize); Rate selectById(Integer id); diff --git a/src/main/java/com/example/demo/service/StatisticsService.java b/src/main/java/com/example/demo/service/StatisticsService.java index dc86550..dcd591f 100644 --- a/src/main/java/com/example/demo/service/StatisticsService.java +++ b/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); } diff --git a/src/main/java/com/example/demo/service/WorkbenchService.java b/src/main/java/com/example/demo/service/WorkbenchService.java index 8efa2fe..c41e316 100644 --- a/src/main/java/com/example/demo/service/WorkbenchService.java +++ b/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 markets); //根据类型获取年初至今的统计数据 diff --git a/src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java index 9333f2c..f044210 100644 --- a/src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java +++ b/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; diff --git a/src/main/java/com/example/demo/serviceImpl/ConsumeServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/ConsumeServiceImpl.java index 2186971..1a7ef1a 100644 --- a/src/main/java/com/example/demo/serviceImpl/ConsumeServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/ConsumeServiceImpl.java @@ -166,11 +166,11 @@ public class ConsumeServiceImpl implements ConsumeService { user.setConsumeNum(gold.getConsumeNum() + 1); user.setSumConsume(-(consumeUser.getPermanentGold() + consumeUser.getFreeGold() + consumeUser.getTaskGold())); userMapper.updateGold(user); - // if(consumeUser.getJwcode().equals(94226013)){ - GoldTistV2.addCoinNew(userGoldRecord.getJwcode().toString(), 65, - (double) (userGoldRecord.getPermanentGold() + userGoldRecord.getFreeDecember() + userGoldRecord.getFreeJune() + userGoldRecord.getTaskGold()) /100, - userGoldRecord.getRemark(),((double) userGoldRecord.getPermanentGold() /100), userGoldRecord.getPayPlatform(), userGoldRecord.getGoodsName()); - // } + // if(consumeUser.getJwcode().equals(94226013)){ + GoldTistV2.addCoinNew(userGoldRecord.getJwcode().toString(), 65, + (double) (userGoldRecord.getPermanentGold() + userGoldRecord.getFreeDecember() + userGoldRecord.getFreeJune() + userGoldRecord.getTaskGold()) /100, + userGoldRecord.getRemark(),((double) userGoldRecord.getPermanentGold() /100), userGoldRecord.getPayPlatform(), userGoldRecord.getGoodsName()); + // } return Result.success(); } } diff --git a/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java index 98fa424..1b08c1d 100644 --- a/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java +++ b/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 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(""); diff --git a/src/main/java/com/example/demo/serviceImpl/RateServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/RateServiceImpl.java index e2b55aa..e60f2aa 100644 --- a/src/main/java/com/example/demo/serviceImpl/RateServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/RateServiceImpl.java @@ -22,9 +22,9 @@ public class RateServiceImpl implements RateService { @Override - public PageInfo selectAll(Integer pageNum, Integer pageSize) { + public PageInfo selectAll(Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum, pageSize); - List rates = rateMapper.selectAll(); + List rates = rateMapper.selectAll(); return new PageInfo<>(rates); } @@ -45,6 +45,6 @@ public class RateServiceImpl implements RateService { if (rate.getNum() == null || rate.getNum().equals(BigDecimal.ZERO)) { return Result.error("汇率数值存在异常"); }else { - return Result.success("编辑成功"); - }} + return Result.success("编辑成功"); + }} } diff --git a/src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java index 0cc29bd..8794abe 100644 --- a/src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java +++ b/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,7 +341,29 @@ 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 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(余量属性)是否相同 */ private boolean isSameStatisticsPart1(Statistics oldStats, Statistics newStats) { @@ -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()) ;} } diff --git a/src/main/java/com/example/demo/serviceImpl/WorkbenchServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/WorkbenchServiceImpl.java index 2ea536a..3ad82e7 100644 --- a/src/main/java/com/example/demo/serviceImpl/WorkbenchServiceImpl.java +++ b/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 redisTemplate; + // private final StatisticsMapper statisticsMapper; @Autowired private WorkBenchMapper workBenchMapper; @Autowired private GeneralService generalService; @Autowired private StatisticsMapper statisticsMapper; + @Autowired + public WorkbenchServiceImpl(RedisTemplate 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类型 - Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant()); + LocalDate firstDayOfYear = LocalDate.now().withDayOfYear(1); + Date yearlyStartDate = Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant()); List markets = generalService.getMarket(); + + // 批量获取统计数据 + List currentStatsList = statisticsMapper.selectByMarketsAndDate(markets, + Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()), + Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())); + + List ydayStatsList = statisticsMapper.selectByMarketsAndDate(markets, + Date.from(startOfYday.atZone(ZoneId.systemDefault()).toInstant()), + Date.from(endOfYday.atZone(ZoneId.systemDefault()).toInstant())); + // 将 List 转换为 Map + Map currentStatsMap = currentStatsList.stream() + .collect(Collectors.toMap(Statistics::getMarket, Function.identity(), (existing, replacement) -> existing)); + + Map ydayStatsMap = ydayStatsList.stream() + .collect(Collectors.toMap(Statistics::getMarket, Function.identity(), (existing, replacement) -> existing)); + // 并行处理市场列表,创建市场卡片列表 List marketCards = markets.parallelStream() - // 过滤掉空或全空格的市场名称 .filter(market -> market != null && !market.trim().isEmpty()) - .map(market -> { - // 根据市场名称和日期范围查询统计信息 - Statistics currentStatistics = statisticsMapper.selectByMarketAndDate( - 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); - }) - // 收集并行流结果为列表 + .map(market -> createWorkbenchMarketCard( + market, + 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 yearlyStats = calculateAllSum(market, yearlyStartDate, date); + // Map 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 calculateAllSum(String market, Date startDate, Date endDate) { WorkbenchFullStatistics stats = workBenchMapper.getFullStatisticsByMarketAndDate(market, startDate, endDate); Map result = new HashMap<>(); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ef7a018..8e726da 100644 --- a/src/main/resources/application.yml +++ b/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 diff --git a/src/main/resources/mapper/AdminMapper.xml b/src/main/resources/mapper/AdminMapper.xml index 15f0e8b..83a9c7f 100644 --- a/src/main/resources/mapper/AdminMapper.xml +++ b/src/main/resources/mapper/AdminMapper.xml @@ -22,4 +22,8 @@ update_time = #{updateTime} where account = #{account} + diff --git a/src/main/resources/mapper/ConsumeMapper.xml b/src/main/resources/mapper/ConsumeMapper.xml index 8263303..aa46c39 100644 --- a/src/main/resources/mapper/ConsumeMapper.xml +++ b/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 ugr.type = 1 diff --git a/src/main/resources/mapper/RechargeMapper.xml b/src/main/resources/mapper/RechargeMapper.xml index 3358e7a..84bd95d 100644 --- a/src/main/resources/mapper/RechargeMapper.xml +++ b/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 ugr.type = 0 AND ugr.audit_status IN (1,3) diff --git a/src/main/resources/mapper/RefundMapper.xml b/src/main/resources/mapper/RefundMapper.xml index df4aaea..c04a435 100644 --- a/src/main/resources/mapper/RefundMapper.xml +++ b/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) @@ -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 ugr.type = 2 AND ugr.audit_status IN (1,3) diff --git a/src/main/resources/mapper/StatisticsMapper.xml b/src/main/resources/mapper/StatisticsMapper.xml index 99398d7..9192a94 100644 --- a/src/main/resources/mapper/StatisticsMapper.xml +++ b/src/main/resources/mapper/StatisticsMapper.xml @@ -37,10 +37,29 @@ ) + + + 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} + + ) + UPDATE statistics SET + recharge = #{recharge}, money = #{money}, consume_permanent = #{consumePermanent}, @@ -53,6 +72,9 @@ refund_task = #{refundTask}, recharge_num = #{rechargeNum}, first_recharge = #{firstRecharge} + + ,update_time = #{updateTime} + WHERE market = #{market} and current_datetime = #{currentDatetime} @@ -67,6 +89,18 @@ current_task = #{currentTask} WHERE market = #{market} and current_datetime = #{currentDatetime} + + + 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} + + @@ -142,5 +176,14 @@ AND current_datetime >= #{startDate} AND current_datetime <= #{endDate} + + diff --git a/src/main/resources/mapper/WorkBenchMapper.xml b/src/main/resources/mapper/WorkBenchMapper.xml index b40242f..3230f2a 100644 --- a/src/main/resources/mapper/WorkBenchMapper.xml +++ b/src/main/resources/mapper/WorkBenchMapper.xml @@ -90,23 +90,22 @@