diff --git a/src/main/java/com/example/demo/Export/ExportService.java b/src/main/java/com/example/demo/Export/ExportService.java index 6fc145c..6e77ea5 100644 --- a/src/main/java/com/example/demo/Export/ExportService.java +++ b/src/main/java/com/example/demo/Export/ExportService.java @@ -20,5 +20,8 @@ public interface ExportService { Result addExportConsume(ConsumeDTO dto); //金豆直播导出 Result addExportLive(LiveDTO dto); - + //金豆粉丝导出 + Result addExportFan(FanDTO dto); + //金豆文章导出 + Result addExportArticle(ArticleDTO dto); } diff --git a/src/main/java/com/example/demo/Export/ExportServiceImpl.java b/src/main/java/com/example/demo/Export/ExportServiceImpl.java index b89460b..5af6232 100644 --- a/src/main/java/com/example/demo/Export/ExportServiceImpl.java +++ b/src/main/java/com/example/demo/Export/ExportServiceImpl.java @@ -1,10 +1,7 @@ package com.example.demo.Export; import com.example.demo.Util.JWTUtil; -import com.example.demo.domain.DTO.ConsumeDTO; -import com.example.demo.domain.DTO.LiveDTO; -import com.example.demo.domain.DTO.RechargeDTO; -import com.example.demo.domain.DTO.RefundDTO; +import com.example.demo.domain.DTO.*; import com.example.demo.domain.entity.Admin; import com.example.demo.domain.vo.coin.Result; import com.example.demo.exception.SystemException; @@ -107,6 +104,11 @@ public class ExportServiceImpl implements ExportService { liveDTO.setUrl(""); liveDTO.setFileName(generateFileName("直播明细", adminName)); liveDTO.setDataNum(0); + } else if (dto instanceof FanDTO fanDTO) { + fanDTO.setAccount(Integer.valueOf(account)); + fanDTO.setUrl(""); + fanDTO.setFileName(generateFileName("铁粉明细", adminName)); + fanDTO.setDataNum(0); } } @@ -154,6 +156,26 @@ public class ExportServiceImpl implements ExportService { liveDTO.getFileName(), liveDTO.getDataNum() ); + } else if (dto instanceof FanDTO fanDTO) { + goldDetailMapper.insertExportRecord( + idHolder, + account, + fanDTO.getType(), + fanDTO.getState(), + fanDTO.getUrl(), + fanDTO.getFileName(), + fanDTO.getDataNum() + ); + } else if (dto instanceof ArticleDTO articleDTO) { + goldDetailMapper.insertExportRecord( + idHolder, + account, + articleDTO.getType(), + articleDTO.getState(), + articleDTO.getUrl(), + articleDTO.getFileName(), + articleDTO.getDataNum() + ); } } @@ -174,6 +196,10 @@ public class ExportServiceImpl implements ExportService { requestData.put(requestDataKey, consumeDTO.getConsumeUser()); } else if(dto instanceof LiveDTO liveDTO){ requestData.put(requestDataKey, liveDTO.getBeanConsumeLive()); + } else if (dto instanceof FanDTO fanDTO) { + requestData.put(requestDataKey, fanDTO.getBeanConsumeFan()); + } else if (dto instanceof ArticleDTO articleDTO) { + requestData.put(requestDataKey, articleDTO.getBeanConsumeArticle()); } exportData.put("requestData", requestData); @@ -209,4 +235,14 @@ public class ExportServiceImpl implements ExportService { public Result addExportLive(LiveDTO dto) { return addExport(dto, "直播明细", "live:queue:export_queue", "beanConsumeLive"); } + + @Override + public Result addExportFan(FanDTO dto) { + return addExport(dto, "铁粉明细", "fan:queue:export_queue", "beanConsumeFan"); + } + + @Override + public Result addExportArticle(ArticleDTO dto) { + return addExport(dto, "文章明细", "article:queue:export_queue", "beanConsumeArticle"); + } } \ No newline at end of file diff --git a/src/main/java/com/example/demo/controller/coin/ExportController.java b/src/main/java/com/example/demo/controller/coin/ExportController.java index fdb397c..c3b85bc 100644 --- a/src/main/java/com/example/demo/controller/coin/ExportController.java +++ b/src/main/java/com/example/demo/controller/coin/ExportController.java @@ -3,10 +3,7 @@ package com.example.demo.controller.coin; import com.example.demo.Util.BusinessException; import com.example.demo.Util.JWTUtil; import com.example.demo.Util.RedisLockUtil; -import com.example.demo.domain.DTO.ConsumeDTO; -import com.example.demo.domain.DTO.LiveDTO; -import com.example.demo.domain.DTO.RechargeDTO; -import com.example.demo.domain.DTO.RefundDTO; +import com.example.demo.domain.DTO.*; import com.example.demo.domain.entity.Admin; import com.example.demo.domain.entity.Export; import com.example.demo.domain.vo.coin.Result; @@ -118,4 +115,38 @@ public class ExportController { redisLockUtil.unlock(lockKey, requestId); } } + @PostMapping("/exportFan") + public Result export(@Valid @RequestBody FanDTO dto){ + String lockKey = "export:lock:" + dto.getToken(); + String requestId = UUID.randomUUID().toString(); + long expireTime = 5000; + try { + // 尝试获取锁 + if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { + throw new BusinessException("操作太频繁,请稍后重试"); + } + // 执行业务逻辑 + return exportService.addExportFan(dto); + } finally { + // 释放锁 + redisLockUtil.unlock(lockKey, requestId); + } + } + @PostMapping("/exportArticle") + public Result export(@Valid @RequestBody ArticleDTO dto){ + String lockKey = "export:lock:" + dto.getToken(); + String requestId = UUID.randomUUID().toString(); + long expireTime = 5000; + try { + // 尝试获取锁 + if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { + throw new BusinessException("操作太频繁,请稍后重试"); + } + // 执行业务逻辑 + return exportService.addExportArticle(dto); + } finally { + // 释放锁 + redisLockUtil.unlock(lockKey, requestId); + } + } } \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/DTO/ArticleDTO.java b/src/main/java/com/example/demo/domain/DTO/ArticleDTO.java new file mode 100644 index 0000000..c5853e0 --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/ArticleDTO.java @@ -0,0 +1,37 @@ +package com.example.demo.domain.DTO; + +import com.example.demo.domain.vo.bean.BeanConsumeArticle; +import com.example.demo.domain.vo.bean.BeanConsumeFan; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName ArticleDTO + * @description: + * @author: huangqizhen + * @create: 2025−08-01 17:33 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +public class ArticleDTO { + private String token; + private String url = ""; + private String fileName = ""; + private Integer sort = 0; + private String field = ""; + private Integer account; + private Integer type = 7; //类型 + private Integer state = 0; //状态 + private String text = ""; //关键词搜索 + private Integer dataNum = 0; + private String deptid = ""; + + @NotNull(message = "page不能为空") + private Integer page = 1; + @NotNull(message = "pageSize不能为空") + private Integer pageSize = 20; + private BeanConsumeArticle beanConsumeArticle; +} diff --git a/src/main/java/com/example/demo/domain/DTO/FanDTO.java b/src/main/java/com/example/demo/domain/DTO/FanDTO.java new file mode 100644 index 0000000..d917fec --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/FanDTO.java @@ -0,0 +1,37 @@ +package com.example.demo.domain.DTO; + +import com.example.demo.domain.vo.bean.BeanConsumeFan; +import com.example.demo.domain.vo.bean.BeanConsumeLive; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName FanDTO + * @description: + * @author: huangqizhen + * @create: 2025−08-01 15:45 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +public class FanDTO { + private String token; + private String url = ""; + private String fileName = ""; + private Integer sort = 0; + private String field = ""; + private Integer account; + private Integer type = 7; //类型 + private Integer state = 0; //状态 + private String text = ""; //关键词搜索 + private Integer dataNum = 0; + private String deptid = ""; + + @NotNull(message = "page不能为空") + private Integer page = 1; + @NotNull(message = "pageSize不能为空") + private Integer pageSize = 20; + private BeanConsumeFan beanConsumeFan; +} diff --git a/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeArticle.java b/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeArticle.java index 01a33d1..b837145 100644 --- a/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeArticle.java +++ b/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeArticle.java @@ -1,5 +1,7 @@ package com.example.demo.domain.vo.bean; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; @@ -20,22 +22,37 @@ import java.util.Date; @JsonIgnoreProperties(ignoreUnknown = true) public class BeanConsumeArticle { private static final long serialVersionUID = 1L; + @ExcelProperty("姓名") private String name; //姓名 + @ExcelProperty("精网号") private Integer jwcode; //精网号 + @ExcelProperty("地区/分部") private String dept; //地区/分部 + @ExcelProperty("类型") private String type; //类型source_type 9、10打赏,11付费 + @ExcelIgnore private Integer payMode; // 0 打赏 1 付费 2 其他 + @ExcelProperty("金豆数量") private String beanNum; //金豆数量 + @ExcelProperty("文章/视频ID") private Integer articleId; //文章/视频ID + @ExcelProperty("文章/视频标题") private String articleName; //文章/视频标题(source_name) + @ExcelProperty("作者") private String author; //作者 + @ExcelProperty("支付类型") private String payType; //支付类型 1-5:直播 7铁粉 8文章 + @ExcelIgnore private String sortField; //排序字段 + @ExcelIgnore private String sortOrder; //排序顺序 + @ExcelProperty("付费时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date consumeTime; // 付费时间 (时间戳转化) + @ExcelIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date startTime; // 开始时间 + @ExcelIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date endTime; // 结束时间 } diff --git a/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeFan.java b/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeFan.java index 636a00c..1273187 100644 --- a/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeFan.java +++ b/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeFan.java @@ -1,5 +1,7 @@ package com.example.demo.domain.vo.bean; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; @@ -20,19 +22,31 @@ import java.util.Date; @JsonIgnoreProperties(ignoreUnknown = true) public class BeanConsumeFan { private static final long serialVersionUID = 1L; + @ExcelProperty("姓名") private String name; //姓名 + @ExcelProperty("精网号") private Integer jwcode; //精网号 + @ExcelProperty("地区/分部") private String dept; //地区/分部 + @ExcelProperty("金豆数量") private String beanNum; //金豆数量 + @ExcelProperty("频道名称") private String channel; //频道名称(source_name) + @ExcelProperty("消费方式") private String type; //类型source_type 单月,连续包月 + @ExcelProperty("支付方式") private Integer payType; //支付方式(直播:12345,铁粉:7,文章:8) + @ExcelIgnore private String sortField; //排序字段 + @ExcelIgnore private String sortOrder; //排序顺序 + @ExcelProperty("消费时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date consumeTime; // 消费时间 (时间戳转化) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") + @ExcelIgnore private Date startTime; // 开始时间 + @ExcelIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date endTime; // 结束时间 } diff --git a/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeLive.java b/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeLive.java index 9dc736f..666b7d2 100644 --- a/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeLive.java +++ b/src/main/java/com/example/demo/domain/vo/bean/BeanConsumeLive.java @@ -1,5 +1,8 @@ package com.example.demo.domain.vo.bean; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; @@ -21,23 +24,37 @@ import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) public class BeanConsumeLive { private static final long serialVersionUID = 1L; + @ExcelProperty("姓名") private String name; //姓名 + @ExcelProperty("精网号") private Integer jwcode; //精网号 + @ExcelProperty("地区/分部") private String dept; //地区/分部 //类型 直播: 1. 发礼物2. 发红包3. 发福袋4. 付费直播5. 加入粉丝团6. 发弹幕 //文章: 1. 打赏2. 付费 + @ExcelProperty("类型") private String type; //类型 + @ExcelProperty("礼物名称") private String gift; //礼物名称 + @ExcelProperty("金豆数量") private String beanNum; //金豆数量 + @ExcelProperty("频道名称") private String liveChannel; //频道名称(截取content) + @ExcelProperty("直播名称") private String liveName; //直播间名称 + @ExcelProperty("消费时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date consumeTime; // 消费时间 (时间戳转化) + @ExcelProperty("支付方式") private Integer payType; //支付方式(直播:12345,铁粉:7,文章:8) + @ExcelIgnore private String sortField; //排序字段 + @ExcelIgnore private String sortOrder; //排序顺序 + @ExcelIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date startTime; // 开始时间 + @ExcelIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date endTime; // 结束时间 } diff --git a/src/main/java/com/example/demo/service/coin/ExportExcelService.java b/src/main/java/com/example/demo/service/coin/ExportExcelService.java index 583c880..5957dde 100644 --- a/src/main/java/com/example/demo/service/coin/ExportExcelService.java +++ b/src/main/java/com/example/demo/service/coin/ExportExcelService.java @@ -24,6 +24,8 @@ public interface ExportExcelService { Exception refundExcel(String message) throws Exception; Exception LiveExcel(String message) throws Exception; + Exception FanExcel(String message) throws Exception; + Exception ArticleExcel(String message) throws Exception; List getExcel(Export export); @Transactional diff --git a/src/main/java/com/example/demo/service/listen/ArticleListener.java b/src/main/java/com/example/demo/service/listen/ArticleListener.java new file mode 100644 index 0000000..ba4b186 --- /dev/null +++ b/src/main/java/com/example/demo/service/listen/ArticleListener.java @@ -0,0 +1,38 @@ +package com.example.demo.service.listen; + +import com.example.demo.Util.RedisUtil; +import com.example.demo.service.coin.ExportExcelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import static org.ehcache.core.exceptions.StorePassThroughException.handleException; + +/** + * @program: GOLD + * @ClassName ArticleListener + * @description: + * @author: huangqizhen + * @create: 2025−08-01 17:45 + * @Version 1.0 + **/ +@Component +public class ArticleListener extends BaseMessageListener { + @Autowired + private ExportExcelService exportExcelService; + + @Autowired + public ArticleListener(RedisUtil redisQueueUtil) { + super(redisQueueUtil, "article:queue:export_queue"); + } + + @Override + protected void handleMessage(String message) { + validateMessage( message); + try { + Thread.sleep(5000); + exportExcelService.ArticleExcel(message); + } catch (Exception e) { + handleException(e, message); + } + } +} diff --git a/src/main/java/com/example/demo/service/listen/FanListener.java b/src/main/java/com/example/demo/service/listen/FanListener.java new file mode 100644 index 0000000..4b9c18c --- /dev/null +++ b/src/main/java/com/example/demo/service/listen/FanListener.java @@ -0,0 +1,40 @@ +package com.example.demo.service.listen; + +import com.example.demo.Util.RedisUtil; +import com.example.demo.service.coin.ExportExcelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import static org.ehcache.core.exceptions.StorePassThroughException.handleException; + +/** + * @program: GOLD + * @ClassName FanListener + * @description: + * @author: huangqizhen + * @create: 2025−08-01 16:49 + * @Version 1.0 + **/ +@Component +public class FanListener extends BaseMessageListener { + + + @Autowired + private ExportExcelService exportExcelService; + + @Autowired + public FanListener(RedisUtil redisQueueUtil) { + super(redisQueueUtil, "fan:queue:export_queue"); + } + + @Override + protected void handleMessage(String message) { + validateMessage( message); + try { + Thread.sleep(5000); + exportExcelService.FanExcel(message); + } catch (Exception e) { + handleException(e, message); + } + } +} diff --git a/src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java index 29c3499..21fff15 100644 --- a/src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java @@ -15,6 +15,8 @@ import com.example.demo.domain.entity.Admin; import com.example.demo.domain.entity.Export; import com.example.demo.domain.entity.User; import com.example.demo.domain.export.Goldmingxi; +import com.example.demo.domain.vo.bean.BeanConsumeArticle; +import com.example.demo.domain.vo.bean.BeanConsumeFan; import com.example.demo.domain.vo.bean.BeanConsumeLive; import com.example.demo.domain.vo.coin.*; @@ -149,6 +151,28 @@ public class ExportExcelServiceImpl implements ExportExcelService { } @Override + public Exception FanExcel(String message) throws Exception { + return exportExcelGeneric(message, "fanUser", page -> { + try { + return beanConsumeController.selectFanBy(page); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Override + public Exception ArticleExcel(String message) throws Exception { + return exportExcelGeneric(message, "articleUser", page -> { + try { + return beanConsumeController.selectArticleBy(page); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Override public List getExcel(Export export) { List list = exportMapper.getExportRecord(export.getAccount(),export.getType()); System.out.println(list+"-------------------------------"); @@ -347,8 +371,12 @@ public class ExportExcelServiceImpl implements ExportExcelService { return ConsumeUser.class; case "refundUser": return RefundUser.class; - case "liveUser": + case "liveUser": return BeanConsumeLive.class; + case "fanUser": + return BeanConsumeFan.class; + case "articleUser": + return BeanConsumeArticle.class; default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); }