19 Commits

Author SHA1 Message Date
jianlin 98bb1296e1 6-27工作台卡片及图表数据(缺图表统计) 5 days ago
huangqizhen 58f24b11fd Merge remote-tracking branch 'origin/milestone-20250702-金币重构一期' into milestone-20250702-金币重构一期 1 week ago
huangqizhen ceb65f8110 6.24 合并冲突部分修复 1 week ago
jianlin 67508049dc Merge remote-tracking branch 'origin/milestone-20250702-金币重构一期' into milestone-20250702-金币重构一期 1 week ago
huangqizhen ed6ef8996e Merge remote-tracking branch 'origin/milestone-20250702-金币重构一期' into milestone-20250702-金币重构一期 1 week ago
huangqizhen cdd1c51dbd Merge remote-tracking branch 'refs/remotes/origin/huangqizheng/feature-20250623110001-客户金币明细' into milestone-20250702-金币重构一期 1 week ago
jianlin a4c8cb6875 Merge branch 'refs/heads/lijianlin/feature-20250623120104-工作台与审核' into milestone-20250702-金币重构一期 1 week ago
huangqizhen 3dcdb9f7b5 6.24 客户金币余额,异步部分 1 week ago
sunjiabei 9ad7f3af69 消费模块,筛选查询详情 1 week ago
sunjiabei 99a0b0f800 消费模块,消费详情分页,商品查询 1 week ago
sunjiabei 0341bc2ab3 Merge remote-tracking branch 'origin/milestone-20250702-金币重构一期' into milestone-20250702-金币重构一期 1 week ago
huangqizhen f827e86e7a Merge branch 'refs/heads/huangqizheng/feature-20250623110001-客户金币明细' into milestone-20250702-金币重构一期 1 week ago
huangqizhen e885ab526a 6.23 客户金币明细页面查询与合计 1 week ago
sunjiabei be8c77e80e 消费模块,消费金币统计接口 1 week ago
sunjiabei b8a58b038a 消费模块,消费金币统计接口 1 week ago
sunjiabei 9cffd95b79 消费模块,消息详情接口 1 week ago
sunjiabei d4c77f990d 消费模块,消息详情接口 1 week ago
sunjiabei 4fddb8ad5f 消费模块,消息详情接口 1 week ago
sunjiabei e9464c8998 测试 1 week ago
  1. 5
      pom.xml
  2. 2
      src/main/java/com/example/demo/DemoApplication.java
  3. 31
      src/main/java/com/example/demo/Util/BusinessException.java
  4. 190
      src/main/java/com/example/demo/Util/RedisUtil.java
  5. 2
      src/main/java/com/example/demo/config/RedisConfig.java
  6. 70
      src/main/java/com/example/demo/controller/ConsumeController.java
  7. 6
      src/main/java/com/example/demo/controller/GeneralController.java
  8. 60
      src/main/java/com/example/demo/controller/GoldDetailController.java
  9. 13
      src/main/java/com/example/demo/controller/StatisticsController.java
  10. 49
      src/main/java/com/example/demo/controller/WorkbenchController.java
  11. 33
      src/main/java/com/example/demo/domain/entity/Export.java
  12. 8
      src/main/java/com/example/demo/domain/entity/Statistics.java
  13. 3
      src/main/java/com/example/demo/domain/entity/User.java
  14. 45
      src/main/java/com/example/demo/domain/vo/Consume.java
  15. 26
      src/main/java/com/example/demo/domain/vo/Gold.java
  16. 42
      src/main/java/com/example/demo/domain/vo/GoldDetail.java
  17. 26
      src/main/java/com/example/demo/domain/vo/Page.java
  18. 64
      src/main/java/com/example/demo/domain/vo/Result.java
  19. 17
      src/main/java/com/example/demo/domain/vo/TestRequest.java
  20. 25
      src/main/java/com/example/demo/domain/vo/Total.java
  21. 45
      src/main/java/com/example/demo/domain/vo/WorkbenchCard.java
  22. 65
      src/main/java/com/example/demo/domain/vo/WorkbenchMarketCard.java
  23. 23
      src/main/java/com/example/demo/mapper/ConsumeMapper.java
  24. 1
      src/main/java/com/example/demo/mapper/GeneralMapper.java
  25. 25
      src/main/java/com/example/demo/mapper/GoldDetailMapper.java
  26. 15
      src/main/java/com/example/demo/mapper/StatisticsMapper.java
  27. 23
      src/main/java/com/example/demo/mapper/WorkBenchMapper.java
  28. 6
      src/main/java/com/example/demo/security/TokenFilter.java
  29. 26
      src/main/java/com/example/demo/service/ConsumeService.java
  30. 2
      src/main/java/com/example/demo/service/GeneralService.java
  31. 22
      src/main/java/com/example/demo/service/GoldDetailService.java
  32. 16
      src/main/java/com/example/demo/service/StatisticsService.java
  33. 19
      src/main/java/com/example/demo/service/WorkbenchService.java
  34. 79
      src/main/java/com/example/demo/serviceImpl/ConsumeServiceImpl.java
  35. 9
      src/main/java/com/example/demo/serviceImpl/GeneralServiceImpl.java
  36. 52
      src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java
  37. 103
      src/main/java/com/example/demo/serviceImpl/StatisticsServiceImpl.java
  38. 212
      src/main/java/com/example/demo/serviceImpl/WorkbenchServiceImpl.java
  39. 6
      src/main/resources/application.yml
  40. 62
      src/main/resources/mapper/ConsumeMapper.xml
  41. 3
      src/main/resources/mapper/GeneralMapper.xml
  42. 94
      src/main/resources/mapper/GoldDetailMapper.xml
  43. 68
      src/main/resources/mapper/StatisticsMapper.xml
  44. 86
      src/main/resources/mapper/WorkBenchMapper.xml

5
pom.xml

@ -84,6 +84,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
</dependencies>
<build>

2
src/main/java/com/example/demo/DemoApplication.java

@ -2,8 +2,10 @@ package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling // 启用调度功能
public class DemoApplication {
public static void main(String[] args) {

31
src/main/java/com/example/demo/Util/BusinessException.java

@ -0,0 +1,31 @@
package com.example.demo.Util;
/**
* @program: GOLD
* @ClassName BusinessException
* @description:
* @author: huangqizhen
* @create: 202506-23 14:58
* @Version 1.0
**/
import lombok.Getter;
/**
* 业务异常可抛出到前端
*/
@Getter
public class BusinessException extends RuntimeException {
private int code; // 业务状态码
// 使用默认状态码0的构造方法
public BusinessException(String message) {
this(400, message); // 默认状态码400
}
// 指定状态码的构造方法
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
}

190
src/main/java/com/example/demo/Util/RedisUtil.java

@ -0,0 +1,190 @@
/*
package com.example.demo.Util;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.concurrent.*;
@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, Object> redisTemplate;
// 线程池用于处理延迟消息
private ExecutorService delayMessageExecutor;
// 延迟消息处理线程数
private static final int DELAY_THREAD_POOL_SIZE = 4;
// 延迟队列轮询间隔(毫秒)
private static final long DELAY_QUEUE_POLL_INTERVAL = 1000L;
@PostConstruct
public void init() {
// 初始化线程池
delayMessageExecutor = Executors.newFixedThreadPool(DELAY_THREAD_POOL_SIZE);
}
*/
/**
* 发送消息到队列
* @param queueName 队列名称
* @param message 消息内容
*//*
public void sendMessage(String queueName, Object message) {
redisTemplate.opsForList().rightPush(queueName, message);
}
*/
/**
* 阻塞获取消息(优化版增加重试机制)
* @param queueName 队列名称
* @param timeout 超时时间()
* @return 消息内容
*//*
public Object blockingGetMessage(String queueName, long timeout) {
// 分段获取避免长时间阻塞
long endTime = System.currentTimeMillis() + timeout * 1000;
while (System.currentTimeMillis() < endTime) {
Object message = redisTemplate.opsForList().leftPop(queueName, 1, TimeUnit.SECONDS);
if (message != null) {
return message;
}
}
return null;
}
*/
/**
* 非阻塞获取消息
* @param queueName 队列名称
* @return 消息内容
*//*
public Object getMessage(String queueName) {
return redisTemplate.opsForList().leftPop(queueName);
}
*/
/**
* 获取队列长度
* @param queueName 队列名称
* @return 队列长度
*//*
public Long getQueueSize(String queueName) {
return redisTemplate.opsForList().size(queueName);
}
*/
/**
* 发送延迟消息(优化版)
* @param queueName 队列名称
* @param message 消息内容
* @param delay 延迟时间()
*//*
public void sendDelayMessage(String queueName, Object message, long delay) {
String delayQueueKey = getDelayQueueKey(queueName);
String messageId = generateMessageId();
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) {
connection.openPipeline();
// 直接存储消息内容到ZSet的value中
connection.zAdd(
delayQueueKey.getBytes(),
System.currentTimeMillis() + delay * 1000,
serializeMessage(messageId, message)
);
connection.closePipeline();
return null;
}
});
}
*/
/**
* 启动延迟消息处理任务
*//*
@Scheduled(fixedRate = DELAY_QUEUE_POLL_INTERVAL)
public void processDelayMessages() {
Set<String> delayQueues = redisTemplate.keys("delay:*");
if (delayQueues != null) {
for (String delayQueue : delayQueues) {
delayMessageExecutor.execute(() -> {
String queueName = delayQueue.substring(6); // 去掉"delay:"前缀
processSingleDelayQueue(queueName);
});
}
}
}
*/
/**
* 处理单个延迟队列
*//*
private void processSingleDelayQueue(String queueName) {
String delayQueueKey = getDelayQueueKey(queueName);
long now = System.currentTimeMillis();
// 获取所有已到期的消息
Set<ZSetOperations.TypedTuple<Object>> messages = redisTemplate.opsForZSet()
.rangeByScoreWithScores(delayQueueKey, 0, now);
if (messages != null && !messages.isEmpty()) {
for (ZSetOperations.TypedTuple<Object> tuple : messages) {
Object messageWithId = tuple.getValue();
if (messageWithId != null) {
// 反序列化消息
Object message = deserializeMessage(messageWithId.toString());
// 发送到实际队列
sendMessage(queueName, message);
// 从延迟队列中移除
redisTemplate.opsForZSet().remove(delayQueueKey, messageWithId);
}
}
}
}
// 生成消息ID
private String generateMessageId() {
return java.util.UUID.randomUUID().toString();
}
// 获取延迟队列key
private String getDelayQueueKey(String queueName) {
return "delay:" + queueName;
}
// 序列化消息(可根据实际需求实现)
private byte[] serializeMessage(String messageId, Object message) {
// 这里简单实现实际项目中可以使用JSON序列化等
return (messageId + ":" + message.toString()).getBytes();
}
// 反序列化消息(可根据实际需求实现)
private Object deserializeMessage(String serialized) {
// 简单实现根据实际序列化方式调整
int separatorIndex = serialized.indexOf(':');
if (separatorIndex > 0) {
return serialized.substring(separatorIndex + 1);
}
return serialized;
}
}*/

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

@ -1,3 +1,4 @@
/*
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
@ -44,3 +45,4 @@ public class RedisConfig {
}
*/

70
src/main/java/com/example/demo/controller/ConsumeController.java

@ -0,0 +1,70 @@
package com.example.demo.controller;
import com.example.demo.domain.vo.Consume;
import com.example.demo.domain.vo.Gold;
import com.example.demo.domain.vo.Page;
import com.example.demo.domain.vo.Result;
import com.example.demo.service.ConsumeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @program: gold-java
* @ClassName ConsumeController
* @description:消费模块
* @author: Double
* @create: 202506-23 13:06
* @Version 1.0
**/
@RestController
@RequestMapping("/consume")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
public class ConsumeController {
@Autowired
private ConsumeService consumeService;
//消耗明细
@PostMapping("/selectAll")
public Result selcetAll(@RequestBody Page page) {
if (ObjectUtils.isEmpty(page.getPageNum())) {
return Result.error("页码数为空!");
}
if (ObjectUtils.isEmpty(page.getPageSize())) {
return Result.error("页大小为空!");
} else {
return Result.success(consumeService.selectAll(page.getPageNum(), page.getPageSize()));
}
}
//消耗明细筛选
@PostMapping("/selectBy")
public Result selcetBy(@RequestBody Page page) {
if (ObjectUtils.isEmpty(page.getPageNum())) {
return Result.error("页码数为空!");
}
if (ObjectUtils.isEmpty(page.getPageSize())) {
return Result.error("页大小为空!");
} else {
return Result.success(consumeService.selectBy(page.getPageNum(), page.getPageSize(), page.getConsume()));
}
}
//消耗金币统计
@PostMapping("/statsGold")
public Result statsGold() {
Gold gold = consumeService.statsGold();
return Result.success(gold);
}
}

6
src/main/java/com/example/demo/controller/GeneralController.java

@ -41,4 +41,10 @@ public class GeneralController {
List<String> list = generalService.getPlatform();
return Result.success(list);
}
@PostMapping("/goods")
public Result getGoods()
{
List<String> list = generalService.getGoods();
return Result.success(list);
}
}

60
src/main/java/com/example/demo/controller/GoldDetailController.java

@ -0,0 +1,60 @@
package com.example.demo.controller;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.GoldDetail;
import com.example.demo.domain.vo.Page;
import com.example.demo.domain.vo.Result;
import com.example.demo.service.GoldDetailService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
/**
* @program: GOLD
* @ClassName GoldDetailController
* @description:
* @author: huangqizhen
* @create: 202506-23 14:41
* @Version 1.0
**/
@RestController
@RequestMapping("/goldDetail")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
public class GoldDetailController {
private final GoldDetailService goldDetailService;
@PostMapping("/getGoldDetail")
public Result getGoldDetail(@RequestBody Page page){
if(ObjectUtils.isEmpty(page.getPageNum())){
return Result.error("页码数为空!");
}
if(ObjectUtils.isEmpty(page.getPageSize())){
return Result.error("页大小为空!");
}
else{
return Result.success(goldDetailService.getGoldDetail(page.getPageNum(), page.getPageSize(), page.getGoldDetail()));
}
}
@PostMapping("/getTotal")
public Result getTotal(@RequestBody GoldDetail goldDetail) {
return Result.success(goldDetailService.getTotal(goldDetail));
}
@PostMapping("/goldTotal")
public Result GoldTotal(@RequestBody User user) {
return Result.success(goldDetailService.GoldTotal(user));
}
@PostMapping("/getGold")
public Result getGold(@RequestBody Page page) {
if(ObjectUtils.isEmpty(page.getPageNum())){
return Result.error("页码数为空!");
}
if(ObjectUtils.isEmpty(page.getPageSize())){
return Result.error("页大小为空!");
}
return Result.success(goldDetailService.getGold(page.getPageNum(), page.getPageSize(), page.getUser()));
}
}

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

@ -34,10 +34,15 @@ public class StatisticsController {
private StatisticsService statisticsService;
@Autowired
private GeneralService generalService;
//测试定时任务1
@PostMapping("/Hourly")
public void HourlyTask() {
statisticsService.runHourlyTask();
//测试定时任务part1
@PostMapping("/Hourly1")
public void HourlyTask1() {
statisticsService.runHourlyTaskPart1();
}
//测试定时任务part2
@PostMapping("/Hourly2")
public void HourlyTask2() {
statisticsService.runHourlyTaskPart2();
}

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

@ -1,12 +1,20 @@
package com.example.demo.controller;
import com.example.demo.domain.entity.Statistics;
import com.example.demo.domain.vo.TestRequest;
import com.example.demo.domain.vo.WorkbenchCard;
import com.example.demo.mapper.StatisticsMapper;
import com.example.demo.service.StatisticsService;
import com.example.demo.service.WorkbenchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.Map;
/**
* @program: gold-java
* @ClassName WorkbenchController
@ -24,27 +32,40 @@ import org.springframework.web.bind.annotation.*;
public class WorkbenchController {
@Autowired
private WorkbenchService WorkbenchService;
private WorkbenchService workbenchService;
@Autowired
private StatisticsService statisticsService;
@Autowired
private StatisticsMapper statisticsMapper;
/*
获取工作台卡片一的数据
获取各地区工作台卡片的数据
*/
@PostMapping("card1")
public WorkbenchCard card1(@RequestBody WorkbenchCard workbench){
return WorkbenchService.getCard1(workbench.getToken(),workbench.getMarket());
@PostMapping("getCard")
public ResponseEntity<WorkbenchCard> card1(@RequestBody WorkbenchCard workbench){
WorkbenchCard result =workbenchService.getCard(workbench.getToken(),workbench.getMarkets());
return ResponseEntity.ok(result);
}
/*
获取工作台卡片二的数据
获取各地区工作台图表的数据
*/
@PostMapping("card2")
public WorkbenchCard card2(@RequestBody WorkbenchCard workbench){
return WorkbenchService.getCard2(workbench.getToken(),workbench.getMarket());
@PostMapping("getGraph")
public ResponseEntity<WorkbenchCard> graph1(@RequestBody WorkbenchCard workbench){
WorkbenchCard result =workbenchService.getGraph(workbench.getToken(),workbench.getStartDate(),workbench.getEndDate(),workbench.getMarkets());
return ResponseEntity.ok(result);
}
/*
获取工作台卡片三的数据
测试一段时间内的统计数据
*/
@PostMapping("card3")
public WorkbenchCard card3(@RequestBody WorkbenchCard workbench){
return WorkbenchService.getCard3(workbench.getToken(),workbench.getMarket());
}
/* @PostMapping("testSum")
public Statistics testSum( @RequestBody TestRequest request){
String market = request.getMarket();
Date date = request.getDate();
//获取传入日期所在周的周一
Date thisWeekStart = workbenchService.getStartOfWeek(date);
return statisticsMapper.selectSumByMarketAndDate(market, thisWeekStart, date);
}*/
}

33
src/main/java/com/example/demo/domain/entity/Export.java

@ -0,0 +1,33 @@
package com.example.demo.domain.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @program: GOLD
* @ClassName Export
* @description:
* @author: huangqizhen
* @create: 202506-24 16:17
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class Export {
private String token;
private Integer account;
private String url;
private String fileName;
private Byte type;
private Byte state;
private Integer dataNum;
private String reason;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updateTime;
}

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

@ -2,10 +2,13 @@ package com.example.demo.domain.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Date;
/**
@ -45,8 +48,9 @@ public class Statistics implements Serializable {
private Integer rechargeNum; // 当日充值人数
private Integer firstRecharge; // 当日首充人数
// 数据日期
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
private Date currentDatetime;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate currentDatetime;
// 创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date createTime;

3
src/main/java/com/example/demo/domain/entity/User.java

@ -27,6 +27,7 @@ public class User implements Serializable {
private Integer currentFreeDecember; // 当前十二月免费金币
private Integer currentTaskGold; // 当前任务金币
private Integer rechargeNum; // 充值次数
private Integer sumConsume; // 消费总额
private Integer consumeNum; // 消费次数
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
@ -37,4 +38,6 @@ public class User implements Serializable {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date updateTime; // 更新时间
private String sortField; //排序字段
private String sortOrder; //排序顺序
}

45
src/main/java/com/example/demo/domain/vo/Consume.java

@ -0,0 +1,45 @@
package com.example.demo.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* @program: gold-java
* @ClassName Consume
* @description: 消费明细
* @author: Double
* @create: 202506-23 11:53
* @Version 1.0
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Consume implements Serializable {
private static final long serialVersionUID = 1L;
private String name; // 客户姓名
private Integer jwcode; // 精网号
private String market; // 所属地区
private String goodsName; // 商品名称
private String payPlatform; // 消费平台
private Integer sumGold; // 金币总数
private Integer permanentGold; // 永久金币
private Integer freeGold; // 免费金币
private Integer taskGold; // 任务金币
private String remark; // 备注
private String adminName; //提交人姓名
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date payTime; // 消费时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date startTime; // 开始时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date endTime; // 结束时间
}

26
src/main/java/com/example/demo/domain/vo/Gold.java

@ -0,0 +1,26 @@
package com.example.demo.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @program: gold-java
* @ClassName Gold
* @description: 金币信息
* @author: Double
* @create: 202506-23 15:53
* @Version 1.0
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Gold implements Serializable {
private static final long serialVersionUID = 1L;
private Integer permanentGolds; // 永久金币总数
private Integer freeGolds; // 免费金币总数
private Integer taskGolds; // 任务金币总数
}

42
src/main/java/com/example/demo/domain/vo/GoldDetail.java

@ -0,0 +1,42 @@
package com.example.demo.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @program: GOLD
* @ClassName GoldDetail
* @description:
* @author: huangqizhen
* @create: 202506-23 13:03
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class GoldDetail {
private static final long serialVersionUID = 1L;
private String token;
private String name; // 名称
private Integer jwcode; // 精网号
private String market; // 所属地区
private String payPlatform; // 支付平台
private Integer type; // 类型
private Integer sumGold; // 总金币
private Integer permentGold; //永久金币
private Integer freeJune; // 免费金币六月到期
private Integer freeDecember; // 免费金币七月到期
private Integer taskGold; // 任务金币
private String adminName; //提交人
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date startTime; // 开始时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date endTime; // 结束时间
private String sortField; //排序字段
private String sortOrder; //排序顺序
}

26
src/main/java/com/example/demo/domain/vo/Page.java

@ -0,0 +1,26 @@
package com.example.demo.domain.vo;
import com.example.demo.domain.entity.User;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: GOLD
* @ClassName Page
* @description:
* @author: huangqizhen
* @create: 202506-23 16:23
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class Page {
private static final long serialVersionUID = 1L;
private Integer pageNum;
private Integer pageSize;
private GoldDetail goldDetail;
private Consume consume;
private User user;
}

64
src/main/java/com/example/demo/domain/vo/Result.java

@ -1,5 +1,6 @@
package com.example.demo.domain.vo;
import com.example.demo.Util.BusinessException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
@ -8,40 +9,67 @@ import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.HashMap;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private String msg;
private Object data;
private Integer code; // 响应码200 代表成功401 代表未授权
private String msg; // 响应消息
private Object data; // 返回的数据
public static Result success(Integer code, String msg, Object data) {
return new Result(code, msg, data);
// 成功响应不需要给前端返回数据
public static Result success() {
return new Result(200, "success", new HashMap<>());
}
public static Result success(Integer code, Object data) {
return success(code, "操作成功", data);
// 查询成功响应把查询结果作为返回数据响应给前端
public static Result success(Object data) {
return new Result(200, "success", data);
}
public static Result success(String msg, Object data) {return success(200, msg, data);}
public static Result success(Object data){
return success(200, data);
// 失败响应
public static Result error(String msg) {
return new Result(0, msg, new HashMap<>());
}
public static Result success(){
return success(null);
// 失败响应可以自定义错误码
public static Result error(int code, String msg) {
return new Result(code, msg, new HashMap<>());
}
public static Result error(Integer code, String msg, Object data){
return new Result(code, msg, data);
// 成功响应可以自定义消息和数据
public static Result success(String msg, HashMap<String, Object> resultData) {
return new Result(200, msg, resultData); // 返回成功响应状态码为 200
}
public static Result error(Integer code, String msg){
return error(code, msg, null);
// 未授权响应可以自定义错误码
public static Result unauthorized(int code, String msg) {
return new Result(code, msg, new HashMap<>());
}
public static Result error(String msg){
return error(0, msg);
// 错误响应状态码为200code为401
public static Result unauthorized(String msg) {
return new Result(401, msg, new HashMap<>());
}
//失败响应 自定义状态码 默认为500
public static Result error(BusinessException e) {
Result response = new Result();
// 定义默认错误码映射
final int defaultErrorCode = 400;
// 检查 getCode() 是否为 null如果是 Integer
Integer code = e.getCode();
if (code == null || code == 0) {
response.setCode(defaultErrorCode); // 默认错误码
} else {
response.setCode(code);
}
response.setMsg(e.getMessage());
return response;
}
public String toJson() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);

17
src/main/java/com/example/demo/domain/vo/TestRequest.java

@ -0,0 +1,17 @@
package com.example.demo.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
public class TestRequest {
private String market;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
}

25
src/main/java/com/example/demo/domain/vo/Total.java

@ -0,0 +1,25 @@
package com.example.demo.domain.vo;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: GOLD
* @ClassName Total
* @description:
* @author: huangqizhen
* @create: 202506-23 16:53
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class Total {
private static final long serialVersionUID = 1L;
private String token;
private Integer Goldtotal;
private Integer permanentGold;
private Integer freeGold;
private Integer taskGold;
}

45
src/main/java/com/example/demo/domain/vo/WorkbenchCard.java

@ -1,16 +1,18 @@
package com.example.demo.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @program: gold-java
* @ClassName Workbench
* @description: 工作台请求参数
* @description: 工作台顶层容器
* @author: Ethan
* @create: 202506-17 17:43
* @Version 1.0
@ -21,41 +23,12 @@ import java.util.List;
@AllArgsConstructor
public class WorkbenchCard implements Serializable {
private String token; //用户token
private List<String> market; // 地区
// 卡片一当前金币相关
private Integer currentGold; // 当前金币余量
private Integer dailyChange; // 余量较前一天的变化
private Integer currentPermanent; // 永久金币余量
private Integer currentFreeJune; // 六月到期免费金币余量
private Integer currentFreeDecember; // 十二月到期免费金币余量
private Integer currentTask; // 任务金币余量
private Integer currentFree; // 免费金币余量currentFreeJune + currentFreeDecember
private List<WorkbenchMarketCard> marketCards; // 地区卡片数据
private List<String> markets; // 地区列表
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date startDate; // 起始时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date endDate; // 结束时间
// 卡片二充值相关
private Integer recharge; // 当日充值金币数
private Integer money; // 当日金额永久金币
private Integer yearlyRecharge; // 全年累计充值金币数
private Integer yearlyMoney; // 全年累计金额
// 卡片三当日消费/退款/消耗相关
private Integer consumePermanent; // 当日新增消费永久
private Integer consumeFreeJune; // 当日新增消费六月免费
private Integer consumeFreeDecember; // 当日新增消费十二月免费
private Integer consumeTask; // 当日新增消费任务
private Integer refundPermanent; // 当日新增退款永久
private Integer refundFreeJune; // 当日新增退款六月免费
private Integer refundFreeDecember; // 当日新增退款十二月免费
private Integer refundTask; // 当日新增退款任务
private Integer dailyConsume; // 当日总消耗 = consumePermanent + consumeFreeJune + consumeFreeDecember + consumeTask - (refundPermanent + refundFreeJune + refundFreeDecember + refundTask)
private Integer yearlyConsume; // 全年累计消费
private Integer yearlyRefund; // 全年累计退款金币数
private Integer yearlyReduce; // 全年累计消耗金币数 = yearlyConsume - yearlyRefund
// 卡片四人头数相关
private Integer rechargeNum; // 当日充值人数
private Integer firstRecharge; // 当日首充人数
private Integer wow; // 周同比%
private Integer daily; // 日环比%
private Integer yearlyRechargeNum; // 全年累计充值人头数
}

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

@ -0,0 +1,65 @@
package com.example.demo.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @program: gold-java
* @ClassName WorkbenchMarketCard
* @description:
* @author: Ethan
* @create: 202506-25 16:20
* @Version 1.0
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WorkbenchMarketCard implements Serializable {
private String market;//地区
// 卡片一当前金币相关
private Integer currentGold; // 当前金币余量
private Integer dailyChange; // 余量较前一天的变化
private Integer currentPermanent; // 永久金币余量
private Integer currentFreeJune; // 六月到期免费金币余量
private Integer currentFreeDecember; // 十二月到期免费金币余量
private Integer currentTask; // 任务金币余量
private Integer currentFree; // 免费金币余量currentFreeJune + currentFreeDecember
// 卡片二充值相关
private Integer recharge; // 当日充值金币数
private Integer money; // 当日金额永久金币
private Integer yearlyRecharge; // 全年累计充值金币数
private Integer yearlyMoney; // 全年累计金额
// 卡片三当日消费/退款/消耗相关
private Integer consumePermanent; // 当日新增消费永久
private Integer consumeFreeJune; // 当日新增消费六月免费
private Integer consumeFreeDecember; // 当日新增消费十二月免费
private Integer consumeTask; // 当日新增消费任务
private Integer refundPermanent; // 当日新增退款永久
private Integer refundFreeJune; // 当日新增退款六月免费
private Integer refundFreeDecember; // 当日新增退款十二月免费
private Integer refundTask; // 当日新增退款任务
private Integer dailyConsume; // 当日总消耗 = consumePermanent + consumeFreeJune + consumeFreeDecember + consumeTask - (refundPermanent + refundFreeJune + refundFreeDecember + refundTask)
private Integer yearlyConsume; // 全年累计消费
private Integer yearlyRefund; // 全年累计退款金币数
private Integer yearlyReduce; // 全年累计消耗金币数 = yearlyConsume - yearlyRefund
// 卡片四人头数相关
private Integer rechargeNum; // 当日充值人数
private Integer firstRecharge; // 当日首充人数
private Integer wow; // 周同比%
private Integer daily; // 日环比%
private Integer yearlyRechargeNum; // 全年累计充值人头数
//图表
private Integer SumRechargePermanent; //合计充值永久金币
private Integer SumRechargeFree; //合计充值免费金币
private Integer SumConsumePermanent; //合计消费永久金币
private Integer SumConsumeFree; //合计消费免费金币
private Integer SumConsumeTask; //合计消费任务金币
}

23
src/main/java/com/example/demo/mapper/ConsumeMapper.java

@ -0,0 +1,23 @@
package com.example.demo.mapper;
import com.example.demo.domain.vo.Consume;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @program: gold-java
* @ClassName ConsumeMapper
* @description:
* @author: Double
* @create: 202506-23 13:45
* @Version 1.0
**/
@Mapper
public interface ConsumeMapper {
List<Consume> selectAll();
List<Consume> selectBy(Consume consume);
}

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

@ -16,4 +16,5 @@ import java.util.List;
public interface GeneralMapper {
List<String> getMarket();
List<String> getPlatform();
List<String> getGoods();
}

25
src/main/java/com/example/demo/mapper/GoldDetailMapper.java

@ -0,0 +1,25 @@
package com.example.demo.mapper;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.GoldDetail;
import com.example.demo.domain.vo.Total;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @program: GOLD
* @ClassName GoldDetailMapper
* @description:
* @author: huangqizhen
* @create: 202506-23 13:47
* @Version 1.0
**/
@Mapper
public interface GoldDetailMapper {
List<GoldDetail> getGoldDetail(GoldDetail goldDetail);
Total getTotal(GoldDetail goldDetail);
List<User> getGold(User user);
Total GoldTotal(User user);
}

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

@ -5,6 +5,7 @@ import com.example.demo.domain.entity.UserGoldRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
@ -33,21 +34,29 @@ public interface StatisticsMapper {
//获取某地区当前永久金币余量
Integer sumCurrentTaskGold(@Param("market") String market);
//计算该天充值人数
int countRechargeNum(
Integer countRechargeNum(
@Param("market") String market,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
//计算该天首充人数
int countFirstRecharge(
Integer countFirstRecharge(
@Param("market") String market,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
//新增part1统计数据
void insertPart1(Statistics statistics);
//更新part1统计数据
void updatePart1(Statistics statistics);
//新增part2统计数据
void insertPart2(Statistics statistics);
//更新part2统计数据
void updatePart2(Statistics statistics);
//获取某地区某天的数据
//获取某地区某时间所在日期的数据仅一条
Statistics selectByMarketAndDate(@Param("market") String market,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate);
//获取某地区某时间段的统计数据仅一条
Statistics selectSumByMarketAndDate(@Param("market") String market,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate);
}

23
src/main/java/com/example/demo/mapper/WorkBenchMapper.java

@ -3,6 +3,7 @@ package com.example.demo.mapper;
import com.example.demo.domain.vo.WorkbenchCard;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
/**
@ -16,10 +17,20 @@ import java.util.List;
@Mapper
public interface WorkBenchMapper {
//工作台卡片一
public WorkbenchCard getCard1(List<String> areas);
//工作台卡片二
public WorkbenchCard getCard2(List<String> areas);
//工作台卡片三
public WorkbenchCard getCard3(List<String> areas);
//给定时间范围内的该地区充值金币数永久+免费
Integer sumRecharge(String market, Date startDate, Date endDate);
//给定时间范围内的该地区充值金额永久金币数
Integer sumMoney(String market, Date startDate, Date endDate);
//给定时间范围内的该地区消费金币数永久+免费+任务
Integer sumConsume(String market, Date startDate, Date endDate);
//给定时间范围内的该地区消费永久金币数
Integer sumCPermanent(String market, Date startDate, Date endDate);
//给定时间范围内的该地区消费免费金币数
Integer sumCFree(String market, Date startDate, Date endDate);
//给定时间范围内的该地区消费任务金币数
Integer sumCTask(String market, Date startDate, Date endDate);
//给定时间范围内的该地区退款金币数永久+免费+任务
Integer sumRefund(String market,Date startDate, Date endDate);
//给定时间范围内的该地区充值人头数根据精网号去重老数据有多人共用一个精网号的问题
Integer countRechargeNum(String market, Date startDate, Date endDate);
}

6
src/main/java/com/example/demo/security/TokenFilter.java

@ -228,8 +228,8 @@ public class TokenFilter extends OncePerRequestFilter {
// 检查是否是上传请求
boolean isErpRequest = request.getRequestURI().startsWith("/ERP") || request.getRequestURI().contains("ERP");
boolean isUploadRequest = request.getRequestURI().startsWith("/upload");
System.out.println(request.getRequestURI());
System.out.println(isUploadRequest);
// System.out.println(request.getRequestURI());
// System.out.println(isUploadRequest);
if (isUploadRequest ) {
// 如果是上传请求直接将请求传递给下一个过滤器或目标资源
filterChain.doFilter(request, response);
@ -237,7 +237,7 @@ public class TokenFilter extends OncePerRequestFilter {
} else {
// 使用RequestWrapper包装原始的HttpServletRequest使其输入流可以被重复读取
RequestWrapper requestWrapper = new RequestWrapper(request);
System.out.println(request);
// System.out.println(request);
// 确保请求体只被读取一次
boolean hasRequestBody = "POST".equals(requestWrapper.getMethod());

26
src/main/java/com/example/demo/service/ConsumeService.java

@ -0,0 +1,26 @@
package com.example.demo.service;
import com.example.demo.domain.vo.Consume;
import com.example.demo.domain.vo.Gold;
import com.example.demo.domain.vo.GoldDetail;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* @program: gold-java
* @ClassName ConsumeService
* @description: 消费模块
* @author: Double
* @create: 202506-23 13:58
* @Version 1.0
**/
public interface ConsumeService {
PageInfo<Consume> selectAll(Integer pageNum, Integer pageSize);
Gold statsGold();
PageInfo<Consume> selectBy(Integer pageNum, Integer pageSize, Consume consume);
}

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

@ -20,6 +20,7 @@ public interface GeneralService {
List<String> getMarket();
//获取平台
List<String> getPlatform();
List<String> getGoods();
//获取昨天的日期
Date getYesterday();
//获取某天的开始时间(00:00:00)
@ -28,4 +29,5 @@ public interface GeneralService {
String formatDate(Date date) ;
//获取时间段内的所有日期包含起始和结束日
List<Date> getAllDatesBetween(Date start, Date end);
}

22
src/main/java/com/example/demo/service/GoldDetailService.java

@ -0,0 +1,22 @@
package com.example.demo.service;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.GoldDetail;
import com.example.demo.domain.vo.Total;
import com.github.pagehelper.PageInfo;
/**
* @program: GOLD
* @ClassName GoldDetailService
* @description:
* @author: huangqizhen
* @create: 202506-23 11:59
* @Version 1.0
**/
public interface GoldDetailService {
PageInfo<GoldDetail> getGoldDetail(Integer pageNum, Integer pageSize, GoldDetail goldDetail);
Total getTotal(GoldDetail goldDetail);
PageInfo<User> getGold(Integer pageNum, Integer pageSize, User user);
Total GoldTotal(User user);
}

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

@ -15,15 +15,19 @@ import java.util.Date;
public interface StatisticsService {
//12点18点执行定时任务更新当天数据
public void runHourlyTask();
//0点执行定时任务更新近一周数据
public void runDailyTask();
//12点18点,23点30分执行定时任务更新当天part2数据
public void runHourlyTaskPart1();
//12点18点执行定时任务更新当天part2数据
public void runHourlyTaskPart2();
//0点执行定时任务更新近一周part2数据
public void runDailyTaskPart2();
//查询某地区某天是否已存在统计数据
public Statistics getExistStatistics(String market,Date date);
//新增或更新或不修改某地区某天统计数据
public void saveStatistics(String market, Date date);
//新增或更新或不修改某地区某天part1统计数据
public void saveStatisticsPart1(String market, Date date);
//新增或更新或不修改某地区某天part2统计数据
public void saveStatisticsPart2(String market, Date date);
//根据地区与日期获取part1(余量属性)统计数据
public Statistics getStatisticsPart1(String market, Date date);
//根据地区与日期获取part2(余量外属性)统计数据

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

@ -1,7 +1,9 @@
package com.example.demo.service;
import com.example.demo.domain.vo.WorkbenchCard;
import com.example.demo.domain.vo.WorkbenchMarketCard;
import java.util.Date;
import java.util.List;
/**
@ -15,7 +17,18 @@ import java.util.List;
public interface WorkbenchService {
WorkbenchCard getCard1(String token, List<String>areas);
WorkbenchCard getCard2(String token, List<String>areas);
WorkbenchCard getCard3(String token, List<String>areas);
//获取不同地区的工作台统计卡片
WorkbenchCard getCard(String token, List<String> markets);
//获取不同地区的工作台柱状图数据根据类型起止时间地区查询
WorkbenchCard getGraph(String token, Date startDate, Date endDate, List<String> markets);
//根据类型获取年初至今的统计数据
Integer calculateSum(String market, String type, Date startDate,Date endDate);
//获取该日期该市场的日同比
Integer calculateDayOverDay(String market,Date date);
//获取该日期该市场的周环比
Integer calculateWeekOverWeek(String market, Date date);
//获取与传入的日期相差XX天的日期
Date addDays(Date date, int days);
//获取传入时间所在周的第一天周一
Date getStartOfWeek(Date date);
}

79
src/main/java/com/example/demo/serviceImpl/ConsumeServiceImpl.java

@ -0,0 +1,79 @@
package com.example.demo.serviceImpl;
import com.example.demo.domain.vo.Consume;
import com.example.demo.domain.vo.Gold;
import com.example.demo.mapper.ConsumeMapper;
import com.example.demo.service.ConsumeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @program: gold-java
* @ClassName ConsumeServiceImpl
* @description: 消费模块
* @author: Double
* @create: 202506-23 13:58
* @Version 1.0
**/
@Service
public class ConsumeServiceImpl implements ConsumeService {
@Autowired
private ConsumeMapper consumeMapper;
//消耗明细
@Override
public PageInfo<Consume> selectAll(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<Consume> consumes = consumeMapper.selectAll();
return new PageInfo<>(consumes);
}
//消耗金币统计
@Override
public Gold statsGold() {
Gold gold = new Gold();
List<Consume> consumes = consumeMapper.selectAll();
// 初始化累加器
int permanentGoldSum = 0;
int freeGoldSum = 0;
int taskGoldSum = 0;
// 遍历消费记录并累加金币
for (Consume consume : consumes) {
// 累加永久金币
if (consume.getPermanentGold() != null) {
permanentGoldSum += consume.getPermanentGold();
}
// 累加免费金币
if (consume.getFreeGold() != null) {
freeGoldSum += consume.getFreeGold();
}
// 累加任务金币
if (consume.getTaskGold() != null) {
taskGoldSum += consume.getTaskGold();
}
}
// 将累加结果设置到Gold对象
gold.setPermanentGolds(permanentGoldSum);
gold.setFreeGolds(freeGoldSum);
gold.setTaskGolds(taskGoldSum);
return gold;
}
//消耗明细筛选
@Override
public PageInfo<Consume> selectBy(Integer pageNum, Integer pageSize, Consume consume) {
PageHelper.startPage(pageNum, pageSize);
List<Consume> consumes = consumeMapper.selectBy(consume);
return new PageInfo<>(consumes);
}
}

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

@ -39,6 +39,12 @@ public class GeneralServiceImpl implements GeneralService {
return list;
}
@Override
public List<String> getGoods() {
List<String> list = generalMapper.getGoods();
return list;
}
/*
获取昨天的日期
*/
@ -87,4 +93,7 @@ public class GeneralServiceImpl implements GeneralService {
return dates;
}
}

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

@ -0,0 +1,52 @@
package com.example.demo.serviceImpl;
import com.example.demo.domain.entity.User;
import com.example.demo.domain.vo.GoldDetail;
import com.example.demo.domain.vo.Total;
import com.example.demo.mapper.GoldDetailMapper;
import com.example.demo.service.GoldDetailService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @program: GOLD
* @ClassName GoldDetailServiceImpl
* @description:
* @author: huangqizhen
* @create: 202506-23 13:44
* @Version 1.0
**/
@Service
public class GoldDetailServiceImpl implements GoldDetailService {
@Autowired
private GoldDetailMapper goldDetailMapper;
@Override
public PageInfo<GoldDetail> getGoldDetail(Integer pageNum, Integer pageSize, GoldDetail goldDetail) {
PageHelper.startPage(pageNum, pageSize);
List<GoldDetail> list= goldDetailMapper.getGoldDetail(goldDetail);
return new PageInfo<>(list);
}
@Override
public Total getTotal(GoldDetail goldDetail) {
return goldDetailMapper.getTotal(goldDetail);
}
@Override
public PageInfo<User> getGold(Integer pageNum, Integer pageSize, User user) {
PageHelper.startPage(pageNum, pageSize);
List<User> list= goldDetailMapper.getGold(user);
return new PageInfo<>(list);
}
@Override
public Total GoldTotal(User user) {
return goldDetailMapper.GoldTotal(user);
}
}

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

@ -11,9 +11,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
@ -32,23 +34,37 @@ public class StatisticsServiceImpl implements StatisticsService {
private StatisticsMapper statisticsMapper;
@Autowired
private GeneralService generalService;
/*
12点18点执行定时任务更新当天数据
*/
12点18点23点30分执行定时任务更新当天part1数据
*/
@Override
@Scheduled(cron = "0 0 12,18 * * ?") // 分别在 12:00 18:00 执行
@Scheduled(cron = "0 30 23 * * ?") // 23:30 执行
public void runHourlyTaskPart1() {
Date today = new Date(); //取当天日期
for(String market : generalService.getMarket()){
saveStatisticsPart1(market,today);
}
}
/*
12点18点执行定时任务更新当天part2数据
*/
@Override
@Scheduled(cron = "0 0 12,18 * * ?")
public void runHourlyTask() {
public void runHourlyTaskPart2() {
Date today = new Date(); //取当天日期
for(String market : generalService.getMarket()){
saveStatistics(market,today);
saveStatisticsPart2(market,today);
}
}
/*
0点执行定时任务更新近一周数据
0点执行定时任务更新近一周part2数据
*/
@Override
@Scheduled(cron = "0 0 0 * * ?")
public void runDailyTask() {
public void runDailyTaskPart2() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, -7); // 一周前
Date startDate = cal.getTime();
@ -58,7 +74,7 @@ public class StatisticsServiceImpl implements StatisticsService {
for (Date date : dateList) {
for (String market : generalService.getMarket()) {
saveStatistics(market, date);
saveStatisticsPart2(market, date);
}
}
}
@ -74,11 +90,35 @@ public class StatisticsServiceImpl implements StatisticsService {
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
}
/*
新增或更新或不修改某地区某天part1统计数据
*/
@Override
public void saveStatisticsPart1(String market, Date date) {
//获取该地区该日期part1(余量属性)统计数据
Statistics newStats=getStatisticsPart1(market,date);
//获取该地区该日期已存在的数据
Statistics existStats = getExistStatistics(market, date);
//判断是否存在已存在的数据
if(existStats==null){
//没有记录新增
statisticsMapper.insertPart1(newStats );
}else {
//判断新旧数据part1部分(余量属性)是否一致
if (!isSameStatisticsPart1(existStats,newStats)){
statisticsMapper.updatePart1(newStats);
}else{
System.out.println("数据未发生改变");
}
}
}
/*
新增或更新或不修改某地区某天统计数据
新增或更新或不修改某地区某天part2统计数据
*/
@Override
public void saveStatistics(String market, Date date){
public void saveStatisticsPart2(String market, Date date){
//获取该地区该日期part2(余量外属性)统计数据
Statistics newStats=getStatisticsPart2(market,date);
//获取该地区该日期已存在的数据
@ -92,7 +132,7 @@ public class StatisticsServiceImpl implements StatisticsService {
if (!isSameStatisticsPart2(existStats,newStats)){
statisticsMapper.updatePart2(newStats);
}else{
log.atInfo().log("数据未发生改变");
System.out.println("数据未发生改变");
}
}
}
@ -100,9 +140,14 @@ public class StatisticsServiceImpl implements StatisticsService {
//根据地区与日期获取part1(余量属性)统计数据
@Override
public Statistics getStatisticsPart1(String market, Date date) {
//获取日期
LocalDate localDate=date.toInstant()
.atZone(ZoneId.of("Asia/Shanghai")) // 使用系统默认时区
.toLocalDate();
//初始化Statistics对象
Statistics statistics = new Statistics();
statistics.setMarket(market);
statistics.setCurrentDatetime(localDate);
//计算属性
//当前金币余量
Integer currentGold = statisticsMapper.sumCurrentPermanentGold(market)+
@ -110,6 +155,25 @@ public class StatisticsServiceImpl implements StatisticsService {
statisticsMapper.sumCurrentFreeDecember(market)+
statisticsMapper.sumCurrentTaskGold( market);
statistics.setCurrentGold(currentGold);
//较前一日变化
Date yesterday =generalService.getYesterday();
//把yesterday改为昨天的开始时间和结束时间
LocalDateTime startTime = yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
//昨天金币余量
Statistics ydayStats = statisticsMapper.selectByMarketAndDate(market, Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
Integer yesterdayGold=0;
if (ydayStats != null) {
yesterdayGold = ydayStats.getCurrentGold();
}
Integer dailyChange = currentGold - yesterdayGold;
statistics.setDailyChange(dailyChange);
//当前永久金币
Integer currentPermanent = statisticsMapper.sumCurrentPermanentGold(market);
statistics.setCurrentPermanent(currentPermanent);
@ -130,6 +194,10 @@ public class StatisticsServiceImpl implements StatisticsService {
*/
@Override
public Statistics getStatisticsPart2(String market, Date date) {
//获取日期
LocalDate localDate=date.toInstant()
.atZone(ZoneId.of("Asia/Shanghai")) // 使用系统默认时区
.toLocalDate();
//把date改为当天的开始时间和结束时间
LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
@ -143,7 +211,8 @@ public class StatisticsServiceImpl implements StatisticsService {
//初始化Statistics对象
Statistics statistics = new Statistics();
statistics.setMarket(market);
statistics.setCurrentDatetime(date);
statistics.setCurrentDatetime(localDate);
//计算属性
//充值相关-当日充值永久+免费
Integer recharge = records.stream()
@ -213,6 +282,18 @@ public class StatisticsServiceImpl implements StatisticsService {
statistics.setFirstRecharge(firstRecharge);
return statistics;
}
/*
* 判断两个统计对象part1(余量属性)是否相同
*/
private boolean isSameStatisticsPart1(Statistics oldStats, Statistics newStats) {
return Objects.equals(oldStats.getCurrentGold(), newStats.getCurrentGold()) &&
Objects.equals(oldStats.getCurrentPermanent(), newStats.getCurrentPermanent()) &&
Objects.equals(oldStats.getCurrentFreeJune(), newStats.getCurrentFreeJune()) &&
Objects.equals(oldStats.getCurrentFreeDecember(), newStats.getCurrentFreeDecember()) &&
Objects.equals(oldStats.getCurrentTask(), newStats.getCurrentTask()) &&
Objects.equals(oldStats.getDailyChange(), newStats.getDailyChange()) ;
}
/*
* 判断两个统计对象part2(余量外属性)是否相同
*/

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

@ -1,11 +1,24 @@
package com.example.demo.serviceImpl;
import com.example.demo.domain.entity.Statistics;
import com.example.demo.domain.vo.WorkbenchCard;
import com.example.demo.domain.vo.WorkbenchMarketCard;
import com.example.demo.mapper.StatisticsMapper;
import com.example.demo.mapper.WorkBenchMapper;
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.stereotype.Service;
import java.time.LocalDate;
import java.time.DayOfWeek;
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;
/**
@ -19,23 +32,206 @@ import java.util.List;
@Service
public class WorkbenchServiceImpl implements WorkbenchService {
@Autowired
private WorkBenchMapper workbenchMapper;
private WorkBenchMapper workBenchMapper;
@Autowired
private GeneralService generalService;
@Autowired
private StatisticsMapper statisticsMapper;
@Override
public WorkbenchCard getCard(String token, List<String> markets) {
Date date=new Date();
// 获取开始时间和结束时间当天
LocalDateTime startOfDay = date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
.with(LocalTime.MIN);
LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
// 获取当前日期
LocalDate today = LocalDate.now();
// 获取当前年份的第一天
LocalDate firstDayOfYear = today.withDayOfYear(1);
Date yearlyStartDate=Date.from(firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant());
List<WorkbenchMarketCard> marketCards = new ArrayList<>();
// 遍历每个 marketCard 并填充数据
for (String market : markets) {
if (market == null || market.trim().isEmpty()) continue;
// 查询该地区当天的数据
Statistics statistics = statisticsMapper.selectByMarketAndDate(
market,
Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant())
);
WorkbenchMarketCard card = new WorkbenchMarketCard();
card.setMarket(market);
if (statistics != null){
// 卡片一当前金币相关
card.setCurrentPermanent(statistics.getCurrentPermanent());//余量-永久金币
card.setCurrentFreeJune(statistics.getCurrentFreeJune()); //余量-免费六月金币
card.setCurrentFreeDecember(statistics.getCurrentFreeDecember()); //余量-免费十二月金币
card.setCurrentTask(statistics.getCurrentTask()); //余量-任务金币
card.setCurrentFree(card.getCurrentFreeJune() + card.getCurrentFreeDecember()); //余量-免费金币
card.setCurrentGold(card.getCurrentPermanent() + card.getCurrentFree() + card.getCurrentTask()); //余量-总金币
card.setDailyChange(statistics.getDailyChange()); //较前一日变化
// 卡片二充值相关
card.setRecharge(statistics.getRecharge()); //充值-当日充值
card.setMoney(statistics.getMoney()); //充值-当日金额永久
card.setYearlyRecharge(calculateSum(market, "recharge",yearlyStartDate ,date));//充值-全年累计充值
card.setYearlyMoney(calculateSum(market, "money",yearlyStartDate ,date)); //充值-全年累计金额永久
// 卡片三消费与退款
card.setConsumePermanent(statistics.getConsumePermanent());//消费-永久金币
card.setConsumeFreeJune(statistics.getConsumeFreeJune());//消费-免费六月金币
card.setConsumeFreeDecember(statistics.getConsumeFreeDecember());//消费-免费十二月金币
card.setConsumeTask(statistics.getConsumeTask());//消费-任务金币
card.setRefundPermanent(statistics.getRefundPermanent());//退款-永久金币
card.setRefundFreeJune(statistics.getRefundFreeJune());//退款-免费六月金币
card.setRefundFreeDecember(statistics.getRefundFreeDecember());//退款-免费十二月金币
card.setRefundTask(statistics.getRefundTask());//退款-任务金币
//当日总消费
int totalConsume = card.getConsumePermanent() + card.getConsumeFreeJune() + card.getConsumeFreeDecember() + card.getConsumeTask();
//当日总退款
int totalRefund = card.getRefundPermanent() + card.getRefundFreeJune() + card.getRefundFreeDecember() + card.getRefundTask();
card.setDailyConsume(totalConsume - totalRefund);//当日总消耗
card.setYearlyConsume(calculateSum(market, "consume", yearlyStartDate,date));//年累计消费
card.setYearlyRefund(calculateSum(market, "refund",yearlyStartDate ,date));//年累计退款
card.setYearlyReduce(card.getYearlyConsume() - card.getYearlyRefund());//年累计消耗
// 卡片四人头数相关
card.setRechargeNum(statistics.getRechargeNum());
card.setFirstRecharge(statistics.getFirstRecharge());
card.setYearlyRechargeNum(calculateSum(market,"rechargeNum",yearlyStartDate,date));
// 周环比日同比
card.setWow(calculateWeekOverWeek(market, date));
card.setDaily(calculateDayOverDay(market, date));
marketCards.add(card);
}
}
return new WorkbenchCard(token, marketCards,markets,date,date);
}
@Override
public WorkbenchCard getCard1(String token, List<String> areas) {
return workbenchMapper.getCard1(areas);
public WorkbenchCard getGraph(String token, Date startDate, Date endDate, List<String> markets) {
List<WorkbenchMarketCard> marketCards = new ArrayList<>();
for (String market : markets) {
WorkbenchMarketCard cards = new WorkbenchMarketCard();
cards.setMarket(market);
cards.setSumRechargePermanent(calculateSum(market, "money",startDate,endDate));
cards.setSumRechargeFree(calculateSum(market, "rFree",startDate,endDate));
cards.setSumConsumePermanent(calculateSum(market, "cPermanent",startDate,endDate));
cards.setSumConsumeFree(calculateSum(market, "cFree",startDate,endDate));
cards.setSumConsumeTask(calculateSum(market, "cTask",startDate,endDate));
marketCards.add( cards);
}
return new WorkbenchCard(token, marketCards,markets,startDate,endDate);
}
/*
根据类型获取统计数据
*/
@Override
public Integer calculateSum(String market, String type, Date startDate,Date endDate) {
//判断类型
switch
(type) {
case "recharge": //获取累计充值
return workBenchMapper.sumRecharge(market, startDate,endDate);
case "money": //获取累计金额永久
return workBenchMapper.sumMoney(market,startDate,endDate);
case "rFree": //获取累计充值免费
return workBenchMapper.sumRecharge(market,startDate,endDate)-
workBenchMapper.sumMoney(market,startDate,endDate);
case "consume": //获取累计消费
return workBenchMapper.sumConsume(market,startDate,endDate);
case "cPermanent": //获取累计消费-永久
return workBenchMapper.sumCPermanent(market,startDate,endDate);
case "cFree": //获取累计消费- 免费
return workBenchMapper.sumCFree(market,startDate,endDate);
case "cTask": //获取累计消费- 任务
return workBenchMapper.sumCTask(market,startDate,endDate);
case "refund": //获取累计退款
return workBenchMapper.sumRefund(market,startDate,endDate);
case "rechargeNum": //获取累计充值人数
return workBenchMapper.countRechargeNum(market,startDate,endDate);
default:
return 0;
}
}
/*
获取该日期该市场的日同比
*/
@Override
public WorkbenchCard getCard2(String token, List<String> areas) {
public Integer calculateDayOverDay(String market, Date date) {
//传入日期的数据
LocalDateTime startTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN);
LocalDateTime endTime= startTime.plusDays(1).minusSeconds(1);
Statistics currentStatistics = statisticsMapper.selectByMarketAndDate(market,
Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()));
//空数据或数量为零为避免0除数错误返回增长率为0
if (currentStatistics == null || currentStatistics.getRechargeNum() == null) {
return 0;
}
Date yesterday = addDays(date, -1); //传入日期减一昨天
Statistics yesterdayStatistics = statisticsMapper.selectByMarketAndDate(market,
Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant()),
Date.from(yesterday.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()));
//空数据或数量为零为避免0除数错误返回增长率为0
if (yesterdayStatistics == null || yesterdayStatistics.getRechargeNum() == null || yesterdayStatistics.getRechargeNum() == 0) {
return 0;
}
//计算增长率
double rate = ((double) (currentStatistics.getRechargeNum() - yesterdayStatistics.getRechargeNum()) / yesterdayStatistics.getRechargeNum()) * 100;
return (int) Math.round(rate);
}
/*
获取该日期该市场的周环比
*/
@Override
public Integer calculateWeekOverWeek(String market, Date date) {
//获取传入日期所在周的周一
Date thisWeekStart = getStartOfWeek(date);
//获取传入日期上一周的周一
Date lastWeekStart = addDays(thisWeekStart, -7);
// 获取本周周一至今天的充值人数总和
int thisWeekTotal = statisticsMapper.countRechargeNum(market, thisWeekStart, date);
// 获取上周同一时间段的充值人数总和
int lastWeekTotal = statisticsMapper.countRechargeNum(market, lastWeekStart, addDays(date, -7));
if (lastWeekTotal == 0) {
return 0; // 避免除以零的情况
}
double rate = ((double) (thisWeekTotal - lastWeekTotal) / lastWeekTotal) * 100;
return (int) Math.round(rate);
}
return workbenchMapper.getCard2(areas);
@Override
public Date addDays(Date date, int days) {
Calendar cal = Calendar.getInstance();
cal.setTime(date); //设置日期为传入的日期
cal.add(Calendar.DATE, days); //传入日期加上多少天
return cal.getTime(); //返回处理后的日期
}
@Override
public WorkbenchCard getCard3(String token, List<String> areas) {
public Date getStartOfWeek(Date date) {
// Date 转换为 LocalDate
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
// 获取周一作为一周的第一天
DayOfWeek firstDayOfWeek = DayOfWeek.MONDAY;
return workbenchMapper.getCard3(areas);
// 返回所在周的第一天转换回Date格式
return Date.from(localDate.with(firstDayOfWeek)
.atStartOfDay(ZoneId.systemDefault())
.toInstant());
}
}

6
src/main/resources/application.yml

@ -62,9 +62,9 @@ spring:
data:
redis:
database: 0
host: 54.251.137.151
port: 10703
password: 8912h12jhhajsd
host: 192.168.8.94
port: 6379
password:
timeout: 1000
lettuce:
pool:

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

@ -0,0 +1,62 @@
<?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.ConsumeMapper">
<!-- 查询所有消费记录 -->
<select id="selectAll" resultType="com.example.demo.domain.vo.Consume">
SELECT u.name AS name,
u.jwcode AS jwcode,
u.market AS market,
ugr.goods_name AS goodsName,
ugr.pay_platform AS payPlatform,
ugr.sum_gold AS sumGold,
ugr.permanent_gold AS permanentGold,
(COALESCE(ugr.free_june, 0) + COALESCE(ugr.free_december, 0)) AS freeGold,
ugr.task_gold AS taskGold,
ugr.remark AS remark,
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
WHERE ugr.type = 1
</select>
<!-- 查询筛选后消费记录 -->
<select id="selectBy" resultType="com.example.demo.domain.vo.Consume">
SELECT u.name AS name,
u.jwcode AS jwcode,
u.market AS market,
ugr.goods_name AS goodsName,
ugr.pay_platform AS payPlatform,
ugr.sum_gold AS sumGold,
ugr.permanent_gold AS permanentGold,
(COALESCE(ugr.free_june, 0) + COALESCE(ugr.free_december, 0)) AS freeGold,
ugr.task_gold AS taskGold,
ugr.remark AS remark,
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
<where>
ugr.type = 1
<if test="goodsName != null and goodsName != ''">
AND ugr.goods_name = #{goodsName}
</if>
<if test="market != null and market != ''">
AND u.market = #{market}
</if>
<if test="payPlatform != null and payPlatform != ''">
AND ugr.pay_platform = #{payPlatform}
</if>
<if test="startTime != null and endTime != null">
AND ugr.pay_time BETWEEN #{startTime} AND #{endTime}
</if>
</where>
</select>
</mapper>

3
src/main/resources/mapper/GeneralMapper.xml

@ -8,4 +8,7 @@
<select id="getPlatform" resultType="java.lang.String">
select DISTINCT pay_platform from user_gold_record
</select>
<select id="getGoods" resultType="java.lang.String">
select DISTINCT goods_name from user_gold_record
</select>
</mapper>

94
src/main/resources/mapper/GoldDetailMapper.xml

@ -0,0 +1,94 @@
<?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.GoldDetailMapper">
<select id="getGoldDetail" resultType="com.example.demo.domain.vo.GoldDetail">
select `user`.name, `user`.jwcode, `user`.market, `ugr`.pay_platform, `ugr`.type, `ugr`.sum_gold, `ugr`.permanent_gold, `ugr`.free_june, `ugr`.free_december, `ugr`.task_gold, `admin`.admin_name, `ugr`.audit_time
from user_gold_record ugr
left join `user` on `user`.jwcode = `ugr`.jwcode
left join `admin` on `admin`.id = `ugr`.admin_id
<where>
<if test="jwcode != null and jwcode.length > 0">
and `ugr`.jwcode = #{jwcode}
</if>
<if test="payPlatform != null and payPlatform.length > 0">
and `ugr`.pay_platform = #{payPlatform}
</if>
<if test="type != null and type.length > 0">
and `ugr`.type = #{type}
</if>
<if test="market != null and market.length > 0">
and `user`.market = #{market}
</if>
<if test="startTime != null and endTime != null">
and ugr.`audit_time` BETWEEN #{startTime} AND #{endTime}
</if>
</where>
<choose>
<when test="sortField != null and sortField.length > 0 or sortOrder != null and sortOrder.length > 0">
ORDER BY ${sortField} ${sortOrder}
</when>
<otherwise>
ORDER BY audit_time DESC
</otherwise>
</choose>
</select>
<select id="getTotal" resultType="com.example.demo.domain.vo.Total">
select sum(sum_gold) as Goldtotal, sum(permanent_gold) as permanentGold, sum(free_june+free_december) as freeGold, sum(task_gold) as taskGold
from user_gold_record
<where>
<if test="jwcode != null and jwcode.length > 0">
and `ugr`.jwcode = #{jwcode}
</if>
<if test="payPlatform != null and payPlatform.length > 0">
and `ugr`.pay_platform = #{payPlatform}
</if>
<if test="type != null and type.length > 0">
and `ugr`.type = #{type}
</if>
<if test="market != null and market.length > 0">
and `user`.market = #{market}
</if>
<if test="startTime != null and endTime != null">
and ugr.`audit_time` BETWEEN #{startTime} AND #{endTime}
</if>
</where>
</select>
<select id="getGold" resultType="com.example.demo.domain.entity.User">
select * from user
<where>
<if test="jwcode != null and jwcode.length > 0">
and jwcode = #{jwcode}
</if>
<if test="market != null and market.length > 0">
and market = #{market}
</if>
</where>
<choose>
<when test="sortField != null and sortField.length > 0 or sortOrder != null and sortOrder.length > 0">
ORDER BY ${sortField} ${sortOrder}
</when>
<otherwise>
ORDER BY create_time DESC
</otherwise>
</choose>
</select>
<select id="GoldTotal" resultType="com.example.demo.domain.vo.Total">
select
sum(current_permanent_gold) as permanentGold,
sum(current_free_june + current_free_december) as freeGold,
sum(current_task_gold) as taskGold,
sum(current_permanent_gold) + sum(current_free_june + current_free_december) + sum(current_task_gold) as Goldtotal
from `user`
<where>
<if test="jwcode != null and jwcode.length > 0">
and jwcode = #{jwcode}
</if>
<if test="market != null and market.length > 0">
and market = #{market}
</if>
</where>
</select>
</mapper>

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

@ -21,8 +21,24 @@
#{rechargeNum}, #{firstRecharge}
)
</insert>
<!--新增part1统计数据-->
<insert id="insertPart1">
INSERT INTO statistics (
market, current_datetime,
current_gold, daily_change,
current_permanent, current_free_june,
current_free_december, current_task,
) VALUES (
#{market}, #{currentDatetime},
#{currentGold}, #{dailyChange},
#{currentPermanent}, #{currentFreeJune},
#{currentFreeDecember}, #{currentTask},
)
</insert>
<!--更新part2统计数据-->
<update id="updatePart2">
<update id="updatePart2" parameterType="map">
UPDATE statistics
SET
recharge = #{recharge},
@ -36,8 +52,20 @@
refund_free_december = #{refundFreeDecember},
refund_task = #{refundTask},
recharge_num = #{rechargeNum},
first_recharge = #{firstRecharge},
WHERE id = #{id}
first_recharge = #{firstRecharge}
WHERE market = #{market} and current_datetime = #{currentDatetime}
</update>
<!--更新part1统计数据-->
<update id="updatePart1" parameterType="map">
update statistics
SET
current_gold = #{currentGold},
daily_change = #{dailyChange},
current_permanent = #{currentPermanent},
current_free_june = #{currentFreeJune},
current_free_december = #{currentFreeDecember},
current_task = #{currentTask}
WHERE market = #{market} and current_datetime = #{currentDatetime}
</update>
<!--根据地区、审核状态、起止时间查询订单表数据-->
<select id="findByMarketAndAuditStatus"
@ -58,7 +86,7 @@
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.audit_status IN (1,3)
AND ugr.pay_time BETWEEN #{startTime} AND #{endTime}
</select>
<!--计算该天首充人数-->
@ -80,23 +108,37 @@
LIMIT 1
</select>
<select id="sumCurrentPermanentGold" resultType="java.lang.Integer">
SELECT SUM(u.currentPermanentGold)
FROM user u
WHERE u.market = #{market}
SELECT SUM(user.current_permanent_gold)
FROM user
WHERE user.market = #{market}
</select>
<select id="sumCurrentFreeJune" resultType="java.lang.Integer">
SELECT SUM(u.currentFreeJune)
FROM user u
SELECT SUM(u.current_free_june)
FROM user as u
WHERE u.market = #{market}
</select>
<select id="sumCurrentFreeDecember" resultType="java.lang.Integer">
SELECT SUM(u.currentFreeDecember)
FROM user u
SELECT SUM(u.current_free_december)
FROM user as u
WHERE u.market = #{market}
</select>
<select id="sumCurrentTaskGold" resultType="java.lang.Integer">
SELECT SUM(u.currentTaskGold)
FROM user u
SELECT SUM(u.current_task_gold)
FROM user as u
WHERE u.market = #{market}
</select>
<select id="selectSumByMarketAndDate" resultType="com.example.demo.domain.entity.Statistics">
select sum(s.recharge) as recharge,
sum(s.money) as money,
sum(s.consume_permanent) as consume_permanent,
sum(s.consume_free_june) as consume_free_june,
sum(s.consume_free_december) as consume_free_december,
sum(s.consume_task) as consume_task,
sum(s.recharge_num) as recharge_num
from statistics as s
WHERE market = #{market}
AND current_datetime >= #{startDate}
AND current_datetime &lt;= #{endDate}
</select>
</mapper>

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

@ -1,5 +1,91 @@
<?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.WorkBenchMapper">
<!--起止时间内的该地区充值金币数(永久+免费)若为空则默认0-->
<select id="sumRecharge" resultType="java.lang.Integer">
select sum(
COALESCE(recharge, 0)
)
from statistics
where market = #{market}
and current_datetime
between #{startDate} and #{endDate}
</select>
<!--起止时间内的该地区充值金额(永久金币数)-->
<select id="sumMoney" resultType="java.lang.Integer">
SELECT SUM(money)
FROM statistics
WHERE market = #{market}
AND current_datetime BETWEEN #{startDate} and #{endDate}
</select>
<!-- 起止时间内该地区消费金币数(永久+免费+任务)-->
<select id="sumConsume" resultType="java.lang.Integer">
SELECT SUM(
COALESCE(consume_permanent, 0) +
COALESCE(consume_free_june, 0) +
COALESCE(consume_free_december, 0) +
COALESCE(consume_task, 0)
)
FROM statistics
WHERE market = #{market}
AND current_datetime BETWEEN
#{startDate} and #{endDate}
</select>
<!--起止时间内的该地区退款金币数(永久+免费+任务)-->
<select id="sumRefund" resultType="java.lang.Integer">
SELECT SUM(
COALESCE(refund_permanent, 0) +
COALESCE(refund_free_june, 0) +
COALESCE(refund_free_december, 0) +
COALESCE(refund_task, 0)
)
FROM statistics
WHERE market = #{market}
AND current_datetime BETWEEN
#{startDate} and #{endDate}
</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.pay_time BETWEEN
#{startDate} and #{endDate}
AND ugr.audit_status IN (1,3)
</select>
<!--给定时间范围内的该地区消费永久金币数-->
<select id="sumCPermanent" resultType="java.lang.Integer">
SELECT SUM(
COALESCE(consume_permanent, 0)
)
FROM statistics
WHERE market = #{market}
AND current_datetime BETWEEN
#{startDate} and #{endDate}
</select>
<!--给定时间范围内的该地区消费免费金币数-->
<select id="sumCFree" resultType="java.lang.Integer">
SELECT SUM(
COALESCE(refund_free_june, 0) +
COALESCE(refund_free_december, 0)
)
FROM statistics
WHERE market = #{market}
AND current_datetime BETWEEN
#{startDate} and #{endDate}
</select>
<!--给定时间范围内的该地区消费任务金币数-->
<select id="sumCTask" resultType="java.lang.Integer">
SELECT SUM(
COALESCE(refund_task, 0)
)
FROM statistics
WHERE market = #{market}
AND current_datetime BETWEEN
#{startDate} and #{endDate}
</select>
</mapper>
Loading…
Cancel
Save