From dc95d625e60c1583536c1f9cb4a80aed507d79df Mon Sep 17 00:00:00 2001 From: huangqizhen <15552608129@163.com> Date: Tue, 1 Jul 2025 17:29:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E8=B7=91=EF=BC=88=E4=B8=8D=E5=90=88?= =?UTF-8?q?=E5=B9=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/demo/Export/ExportService.java | 25 + .../com/example/demo/Export/ExportServiceImpl.java | 177 +++++ .../example/demo/controller/AdminController.java | 43 + .../example/demo/controller/ExportController.java | 75 +- .../demo/controller/GoldDetailController.java | 19 + .../com/example/demo/domain/DTO/ConsumeDTO.java | 42 + .../com/example/demo/domain/DTO/GoldDetailDTO.java | 6 +- .../com/example/demo/domain/DTO/GoldUserDTO.java | 42 + .../com/example/demo/domain/DTO/RechargeDTO.java | 43 + .../com/example/demo/domain/DTO/RefundDTO.java | 42 + .../java/com/example/demo/domain/entity/Admin.java | 66 +- .../java/com/example/demo/mapper/ExportMapper.java | 6 +- .../com/example/demo/mapper/GoldDetailMapper.java | 2 +- .../com/example/demo/security/TokenFilter.java | 268 +------ .../com/example/demo/security/UploadFilter.java | 43 - .../com/example/demo/service/AdminService.java | 15 + .../com/example/demo/service/AiEmotionService.java | 2 +- .../example/demo/service/ExportExcelService.java | 10 +- .../example/demo/service/GoldDetailService.java | 6 +- .../service/listen/AiEmotionExportListener.java | 4 +- .../demo/service/listen/ConsumeListener.java | 81 ++ .../example/demo/service/listen/GoldListener.java | 82 ++ .../demo/service/listen/RechargeListener.java | 81 ++ .../demo/service/listen/RefundListener.java | 81 ++ .../example/demo/serviceImpl/AdminServiceImpl.java | 64 ++ .../demo/serviceImpl/AiEmotionServiceImpl.java | 2 +- .../demo/serviceImpl/ExportExcelServiceImpl.java | 877 ++++++++++++++++++++- .../demo/serviceImpl/GoldDetailServiceImpl.java | 52 +- src/main/resources/mapper/AiEmotionMapper.xml | 4 +- src/main/resources/mapper/ExportMapper.xml | 10 + src/main/resources/mapper/GoldDetailMapper.xml | 4 +- src/main/resources/mapper/PermissionMapper.xml | 6 +- 32 files changed, 1942 insertions(+), 338 deletions(-) create mode 100644 src/main/java/com/example/demo/Export/ExportService.java create mode 100644 src/main/java/com/example/demo/Export/ExportServiceImpl.java create mode 100644 src/main/java/com/example/demo/controller/AdminController.java create mode 100644 src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java create mode 100644 src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java create mode 100644 src/main/java/com/example/demo/domain/DTO/RechargeDTO.java create mode 100644 src/main/java/com/example/demo/domain/DTO/RefundDTO.java delete mode 100644 src/main/java/com/example/demo/security/UploadFilter.java create mode 100644 src/main/java/com/example/demo/service/AdminService.java create mode 100644 src/main/java/com/example/demo/service/listen/ConsumeListener.java create mode 100644 src/main/java/com/example/demo/service/listen/GoldListener.java create mode 100644 src/main/java/com/example/demo/service/listen/RechargeListener.java create mode 100644 src/main/java/com/example/demo/service/listen/RefundListener.java create mode 100644 src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java diff --git a/src/main/java/com/example/demo/Export/ExportService.java b/src/main/java/com/example/demo/Export/ExportService.java new file mode 100644 index 0000000..f8a35ad --- /dev/null +++ b/src/main/java/com/example/demo/Export/ExportService.java @@ -0,0 +1,25 @@ +package com.example.demo.Export; + +import com.example.demo.domain.DTO.ConsumeDTO; +import com.example.demo.domain.DTO.GoldDetailDTO; +import com.example.demo.domain.DTO.RechargeDTO; +import com.example.demo.domain.DTO.RefundDTO; +import com.example.demo.domain.vo.Result; + +/** + * @program: GOLD + * @ClassName ExportService + * @description: + * @author: huangqizhen + * @create: 2025−07-01 16:06 + * @Version 1.0 + **/ +public interface ExportService { + //充值导出 + Result addExportRecharge(RechargeDTO dto); + //退款导出 + Result addExportRefund(RefundDTO dto); + //消费导出 + Result addExportConsume(ConsumeDTO dto); + +} diff --git a/src/main/java/com/example/demo/Export/ExportServiceImpl.java b/src/main/java/com/example/demo/Export/ExportServiceImpl.java new file mode 100644 index 0000000..2c52080 --- /dev/null +++ b/src/main/java/com/example/demo/Export/ExportServiceImpl.java @@ -0,0 +1,177 @@ +package com.example.demo.Export; + +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.vo.Result; +import com.example.demo.exception.SystemException; +import com.example.demo.mapper.GoldDetailMapper; +import com.example.demo.Util.RedisUtil; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + +/** + * @program: GOLD + * @ClassName ExportServiceImpl + * @description: + * @author: huangqizhen + * @create: 2025−07-01 16:11 + * @Version 1.0 + **/ +@Service +public class ExportServiceImpl implements ExportService{ + @Autowired + private GoldDetailMapper goldDetailMapper; + @Autowired + private RedisUtil redisUtil; + + @Override + public Result addExportRecharge(RechargeDTO dto) { + // 生成文件名 + String fileName = String.format("%s_%s_%s.xlsx", + "充值明细", + "操作人", + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + System.out.println(fileName); + dto.setAccount(123456); + dto.setUrl(""); + dto.setFileName(fileName); + dto.setDataNum(0); + try{ + // 调用方式 + GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder(); + goldDetailMapper.insertExportRecord( + idHolder, // 用于接收主键 + dto.getAccount(), + dto.getType(), + dto.getState(), + dto.getUrl(), + dto.getFileName(), + dto.getDataNum() + ); + // 获取主键 + Long recordId = idHolder.getId(); + // 2. 构造完整的 JSON 数据(包含所有请求参数) + Map exportData = new HashMap<>(); + exportData.put("recordId", recordId); + + // 手动构造请求数据(避免 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()); + exportData.put("requestData", requestData); + + // 3. 发送到 Redis 消息队列 + String jsonData = new ObjectMapper().writeValueAsString(exportData); + redisUtil.sendMessage("recharge:queue:export_queue", jsonData); + }catch (Exception e){ + e.printStackTrace(); + throw new SystemException("导出数据异常,请稍后重试", e); + } + return Result.success(); + } + + @Override + public Result addExportRefund(RefundDTO dto) { + // 生成文件名 + String fileName = String.format("%s_%s_%s.xlsx", + "退款明细", + "操作人", + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + System.out.println(fileName); + dto.setAccount(123456); + dto.setUrl(""); + dto.setFileName(fileName); + dto.setDataNum(0); + try{ + // 调用方式 + GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder(); + goldDetailMapper.insertExportRecord( + idHolder, // 用于接收主键 + dto.getAccount(), + dto.getType(), + dto.getState(), + dto.getUrl(), + dto.getFileName(), + dto.getDataNum() + ); + // 获取主键 + Long recordId = idHolder.getId(); + // 2. 构造完整的 JSON 数据(包含所有请求参数) + Map exportData = new HashMap<>(); + exportData.put("recordId", recordId); + + // 手动构造请求数据(避免 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()); + exportData.put("requestData", requestData); + + // 3. 发送到 Redis 消息队列 + String jsonData = new ObjectMapper().writeValueAsString(exportData); + redisUtil.sendMessage("refund:queue:export_queue", jsonData); + }catch (Exception e){ + e.printStackTrace(); + throw new SystemException("导出数据异常,请稍后重试", e); + } + return Result.success(); + } + + @Override + public Result addExportConsume(ConsumeDTO dto) { + // 生成文件名 + String fileName = String.format("%s_%s_%s.xlsx", + "消费明细", + "操作人", + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + System.out.println(fileName); + dto.setAccount(123456); + dto.setUrl(""); + dto.setFileName(fileName); + dto.setDataNum(0); + try{ + // 调用方式 + GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder(); + goldDetailMapper.insertExportRecord( + idHolder, // 用于接收主键 + dto.getAccount(), + dto.getType(), + dto.getState(), + dto.getUrl(), + dto.getFileName(), + dto.getDataNum() + ); + // 获取主键 + Long recordId = idHolder.getId(); + // 2. 构造完整的 JSON 数据(包含所有请求参数) + Map exportData = new HashMap<>(); + exportData.put("recordId", recordId); + + // 手动构造请求数据(避免 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()); + exportData.put("requestData", requestData); + + // 3. 发送到 Redis 消息队列 + String jsonData = new ObjectMapper().writeValueAsString(exportData); + redisUtil.sendMessage("refund:queue:export_queue", jsonData); + }catch (Exception e){ + e.printStackTrace(); + throw new SystemException("导出数据异常,请稍后重试", e); + } + return Result.success(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/controller/AdminController.java b/src/main/java/com/example/demo/controller/AdminController.java new file mode 100644 index 0000000..c117b3e --- /dev/null +++ b/src/main/java/com/example/demo/controller/AdminController.java @@ -0,0 +1,43 @@ +package com.example.demo.controller; + +import com.example.demo.Util.JWTUtil; +import com.example.demo.domain.entity.Admin; +import com.example.demo.domain.vo.Result; +import com.example.demo.service.AdminService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * @program: GOLD + * @ClassName AdminController + * @description: + * @author: huangqizhen + * @create: 2025−07-01 10:39 + * @Version 1.0 + **/ +@RestController +@RequestMapping("/admin") +@RequiredArgsConstructor +@Slf4j +@CrossOrigin +public class AdminController { + @Autowired + private AdminService adminService; + @PostMapping("/login") + public Result login(@RequestBody Admin admin){ + + try { + admin = adminService.login(admin); + admin.setPassword(null); + System.out.println("达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达瓦达"); + return Result.success(admin); + } catch (Exception e) { + e.printStackTrace(); + log.error(e.getMessage()); + return Result.error(e.getMessage()); + } + + } +} diff --git a/src/main/java/com/example/demo/controller/ExportController.java b/src/main/java/com/example/demo/controller/ExportController.java index 4302859..2269657 100644 --- a/src/main/java/com/example/demo/controller/ExportController.java +++ b/src/main/java/com/example/demo/controller/ExportController.java @@ -1,12 +1,24 @@ package com.example.demo.controller; +import com.example.demo.Util.BusinessException; +import com.example.demo.Util.RedisLockUtil; +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.Export; import com.example.demo.domain.vo.Result; +import com.example.demo.service.ExportExcelService; +import com.example.demo.service.GoldDetailService; +import com.example.demo.Export.ExportService; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.util.List; +import java.util.UUID; + /** * @program: GOLD * @ClassName ExportController @@ -21,8 +33,67 @@ import org.springframework.web.bind.annotation.*; @Slf4j @CrossOrigin public class ExportController { + @Autowired + private ExportExcelService exportExcelService; + @Autowired + private RedisLockUtil redisLockUtil; + @Autowired + private GoldDetailService goldDetailService; + @Autowired + private ExportService exportService; @PostMapping("/export") - public Result export(@RequestBody Export export){ - return null; + public Result export(@RequestBody Export Export){ + return Result.success(exportExcelService.getExcel(Export)); + } + @PostMapping("/exportRecharge") + public Result export(@Valid @RequestBody RechargeDTO dto) { + String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分) + String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁) + long expireTime = 5000; // 锁过期时间(5秒)s + try { + // 尝试获取锁 + if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { + throw new BusinessException("操作太频繁,请稍后重试"); + } + // 执行业务逻辑 + return exportService.addExportRecharge(dto); + } finally { + // 释放锁 + redisLockUtil.unlock(lockKey, requestId); + } + } + @PostMapping("/exportRefund") + public Result export(@Valid @RequestBody RefundDTO dto) { + String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分) + String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁) + long expireTime = 5000; // 锁过期时间(5秒)s + try { + // 尝试获取锁 + if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { + throw new BusinessException("操作太频繁,请稍后重试"); + } + // 执行业务逻辑 + return exportService.addExportRefund(dto); + } finally { + // 释放锁 + redisLockUtil.unlock(lockKey, requestId); + } + } + @PostMapping("/exportConsume") + public Result export(@Valid @RequestBody ConsumeDTO dto) { + String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分) + String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁) + long expireTime = 5000; // 锁过期时间(5秒)s + try { + // 尝试获取锁 + if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { + throw new BusinessException("操作太频繁,请稍后重试"); + } + // 执行业务逻辑 + return exportService.addExportConsume(dto); + } finally { + // 释放锁 + redisLockUtil.unlock(lockKey, requestId); + } } } diff --git a/src/main/java/com/example/demo/controller/GoldDetailController.java b/src/main/java/com/example/demo/controller/GoldDetailController.java index e188e13..dde8d2d 100644 --- a/src/main/java/com/example/demo/controller/GoldDetailController.java +++ b/src/main/java/com/example/demo/controller/GoldDetailController.java @@ -3,6 +3,7 @@ package com.example.demo.controller; import com.example.demo.Util.BusinessException; import com.example.demo.Util.RedisLockUtil; import com.example.demo.domain.DTO.GoldDetailDTO; +import com.example.demo.domain.DTO.GoldUserDTO; import com.example.demo.domain.entity.User; import com.example.demo.domain.vo.GoldDetail; import com.example.demo.domain.vo.Page; @@ -89,4 +90,22 @@ public class GoldDetailController { redisLockUtil.unlock(lockKey, requestId); } } + @PostMapping("/exportGold") + public Result export(@Valid @RequestBody GoldUserDTO dto) { + String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分) + String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁) + long expireTime = 5000; // 锁过期时间(5秒)s + try { + // 尝试获取锁 + if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { + throw new BusinessException("操作太频繁,请稍后重试"); + } + // 执行业务逻辑 + return goldDetailService.addExportRecordGold(dto); + } finally { + // 释放锁 + redisLockUtil.unlock(lockKey, requestId); + } + } + } diff --git a/src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java b/src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java new file mode 100644 index 0000000..d8a7b01 --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/ConsumeDTO.java @@ -0,0 +1,42 @@ +package com.example.demo.domain.DTO; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName ConsumeDTO + * @description: + * @author: huangqizhen + * @create: 2025−07-01 16:17 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +public class ConsumeDTO { + private String token; + private String url = ""; + private String fileName = ""; + private Integer sort = 0; + private String field = ""; + private Integer account; + private Integer type = 4; //类型 + 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; + + @Override + public String toString() { + return String.format( + "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)", + account, type, state, dataNum + ); + } +} diff --git a/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java b/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java index 9aa1dd0..b03acca 100644 --- a/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java +++ b/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java @@ -22,7 +22,7 @@ public class GoldDetailDTO { private String fileName = ""; private Integer sort = 0; private String field = ""; - private Integer jwcode; + private Integer account; private Integer type = 0; //类型 private Integer state = 0; //状态 private String text = ""; //关键词搜索 @@ -37,8 +37,8 @@ public class GoldDetailDTO { @Override public String toString() { return String.format( - "AiEmotionExport(jwcode=%d, type=%d, state=%d, dataNum=%d)", - jwcode, type, state, dataNum + "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)", + account, type, state, dataNum ); } } diff --git a/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java b/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java new file mode 100644 index 0000000..0087f6f --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java @@ -0,0 +1,42 @@ +package com.example.demo.domain.DTO; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName GoldDTO + * @description: + * @author: huangqizhen + * @create: 2025−06-30 23:40 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +public class GoldUserDTO { + private String token; + private String url = ""; + private String fileName = ""; + private Integer sort = 0; + private String field = ""; + private Integer account; + private Integer type = 1; //类型 + 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; + + @Override + public String toString() { + return String.format( + "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)", + account, type, state, dataNum + ); + } +} diff --git a/src/main/java/com/example/demo/domain/DTO/RechargeDTO.java b/src/main/java/com/example/demo/domain/DTO/RechargeDTO.java new file mode 100644 index 0000000..d9608c4 --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/RechargeDTO.java @@ -0,0 +1,43 @@ +package com.example.demo.domain.DTO; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName RechargeDTO + * @description: + * @author: huangqizhen + * @create: 2025−07-01 16:15 + * @Version 1.0 + **/ + +@Data +@NoArgsConstructor +public class RechargeDTO { + private String token; + private String url = ""; + private String fileName = ""; + private Integer sort = 0; + private String field = ""; + private Integer account; + private Integer type = 2; //类型 + 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; + + @Override + public String toString() { + return String.format( + "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)", + account, type, state, dataNum + ); + } +} diff --git a/src/main/java/com/example/demo/domain/DTO/RefundDTO.java b/src/main/java/com/example/demo/domain/DTO/RefundDTO.java new file mode 100644 index 0000000..dcd232d --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/RefundDTO.java @@ -0,0 +1,42 @@ +package com.example.demo.domain.DTO; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName RefundDTO + * @description: + * @author: huangqizhen + * @create: 2025−07-01 16:16 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +public class RefundDTO { + private String token; + private String url = ""; + private String fileName = ""; + private Integer sort = 0; + private String field = ""; + private Integer account; + private Integer type = 3; //类型 + 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; + + @Override + public String toString() { + return String.format( + "AiEmotionExport(account=%d, type=%d, state=%d, dataNum=%d)", + account, type, state, dataNum + ); + } +} diff --git a/src/main/java/com/example/demo/domain/entity/Admin.java b/src/main/java/com/example/demo/domain/entity/Admin.java index 666c30a..86dbb80 100644 --- a/src/main/java/com/example/demo/domain/entity/Admin.java +++ b/src/main/java/com/example/demo/domain/entity/Admin.java @@ -1,17 +1,19 @@ package com.example.demo.domain.entity; import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; import java.io.Serializable; -import java.util.Date; +import java.util.*; @Data @NoArgsConstructor -@JsonIgnoreProperties(ignoreUnknown = true) -public class Admin implements Serializable { +public class Admin implements UserDetails, Serializable { private static final long serialVersionUID = 1L; private Integer id; // 主键ID @@ -30,4 +32,60 @@ public class Admin implements Serializable { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date updateTime; // 更新时间 private Integer roleId; + + + @Override + public Collection getAuthorities() { + Set authorities = new HashSet<>(); + Optional.ofNullable(postiton) + .map(Integer::valueOf) + .ifPresent(permValue -> { + switch (permValue) { + case 1: + authorities.add(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN")); + break; + case 2: + authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); + break; + case 3: + authorities.add(new SimpleGrantedAuthority("ROLE_AUDITORS")); + break; + case 5: + authorities.add(new SimpleGrantedAuthority("Branch_Manager")); + break; + default: + // 可以添加默认角色或处理未知权限 + break; + } + }); + return authorities; + } + @Override + public String getUsername() { + return account; + } + + @Override + @JsonIgnore + public boolean isAccountNonExpired() { + return true; // 默认账户未过期 + } + + @Override + @JsonIgnore + public boolean isAccountNonLocked() { + return true; // 默认账户未锁定 + } + + @Override + @JsonIgnore + public boolean isCredentialsNonExpired() { + return true; // 默认凭证未过期 + } + + @Override + @JsonIgnore + public boolean isEnabled() { + return adminStatus != null && adminStatus == 1; + } } \ No newline at end of file diff --git a/src/main/java/com/example/demo/mapper/ExportMapper.java b/src/main/java/com/example/demo/mapper/ExportMapper.java index 3d95954..4bb7cd6 100644 --- a/src/main/java/com/example/demo/mapper/ExportMapper.java +++ b/src/main/java/com/example/demo/mapper/ExportMapper.java @@ -1,8 +1,11 @@ package com.example.demo.mapper; +import com.example.demo.domain.entity.Export; import com.example.demo.domain.vo.ExportVo; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + /** * @program: GOLD * @ClassName ExportMapper @@ -14,6 +17,7 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface ExportMapper { ExportVo getExportData(Integer id); - ExportVo updateExportData(Long recordId, Integer state, String url, String reason, Integer dataNum); + int updateExportData(Long recordId, Integer state, String url, String reason, Integer dataNum); + List getExportRecord(Integer account); } diff --git a/src/main/java/com/example/demo/mapper/GoldDetailMapper.java b/src/main/java/com/example/demo/mapper/GoldDetailMapper.java index 0bbaf61..7494332 100644 --- a/src/main/java/com/example/demo/mapper/GoldDetailMapper.java +++ b/src/main/java/com/example/demo/mapper/GoldDetailMapper.java @@ -29,7 +29,7 @@ public interface GoldDetailMapper { } void insertExportRecord( @Param("recordId") ExportRecordIdHolder recordId, // 用于接收主键 - @Param("jwcode") Integer jwcode, + @Param("account") Integer account, @Param("type") Integer type, @Param("state") Integer state, @Param("url") String url, diff --git a/src/main/java/com/example/demo/security/TokenFilter.java b/src/main/java/com/example/demo/security/TokenFilter.java index 7652567..00db23e 100644 --- a/src/main/java/com/example/demo/security/TokenFilter.java +++ b/src/main/java/com/example/demo/security/TokenFilter.java @@ -1,209 +1,14 @@ -//package com.example.demo.security; -// -// -//import com.example.demo.Util.JWTUtil; -//import com.example.demo.Util.RequestWrapper; -//import com.example.demo.domain.entity.Admin; -//import jakarta.servlet.FilterChain; -//import jakarta.servlet.ServletException; -//import jakarta.servlet.http.HttpServletRequest; -//import jakarta.servlet.http.HttpServletResponse; -//import org.springframework.core.annotation.Order; -//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -//import org.springframework.security.core.context.SecurityContextHolder; -//import org.springframework.security.core.userdetails.UserDetails; -//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -//import org.springframework.stereotype.Component; -//import org.springframework.util.ObjectUtils; -//import org.springframework.util.StringUtils; -//import org.springframework.web.filter.OncePerRequestFilter; -//import java.io.IOException; -// -// -//@Component -//public class TokenFilter extends OncePerRequestFilter { -// @Override -// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { -// // 取Token 生成登录信息 -// String token = request.getHeader("token"); -// -// -// System.out.println(token+"123132132"); -// -// // token不为空 -// if (StringUtils.hasText(token)){ -// try { -// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); -// if ( ! ObjectUtils.isEmpty(userDetails)) { -// // 将这个用户注册到Security中 -// UsernamePasswordAuthenticationToken authenticationToken -// = new UsernamePasswordAuthenticationToken( -// userDetails, null, -// userDetails.getAuthorities()); -// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); -// SecurityContextHolder.getContext().setAuthentication(authenticationToken); -// } -// } catch (Exception e) { -// e.printStackTrace(); -// // Token无效, -// } -// } -// // 过滤器放行 -// filterChain.doFilter(request, response); -// } -//} -//package com.example.demo.security; -// -//import com.example.demo.Util.JWTUtil; -//import com.example.demo.Util.RequestWrapper; -//import com.example.demo.Util.TokenPayload; -//import com.example.demo.domain.entity.Admin; -//import com.fasterxml.jackson.databind.ObjectMapper; -//import jakarta.servlet.FilterChain; -//import jakarta.servlet.ServletException; -//import jakarta.servlet.http.HttpServletRequest; -//import jakarta.servlet.http.HttpServletResponse; -//import org.springframework.core.annotation.Order; -//import org.springframework.security.access.prepost.PreFilter; -//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -//import org.springframework.security.core.context.SecurityContextHolder; -//import org.springframework.security.core.userdetails.UserDetails; -//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -//import org.springframework.stereotype.Component; -//import org.springframework.util.ObjectUtils; -//import org.springframework.util.StringUtils; -//import org.springframework.web.filter.OncePerRequestFilter; -//import java.io.IOException; -//import java.io.InputStream; -// -// -//@Component -//public class TokenFilter extends OncePerRequestFilter { -// -// @Override -// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) -// throws ServletException, IOException { -// // 使用RequestWrapper包装原始的HttpServletRequest,使其输入流可以被重复读取 -// RequestWrapper requestWrapper = new RequestWrapper(request); -// // 确保请求体只被读取一次 -// boolean hasRequestBody = "POST".equals(requestWrapper.getMethod()); -// System.out.println("/*-/*-/*"+requestWrapper.getBodyString()); -// if (hasRequestBody) { -// // 获取输入流 -// InputStream inputStream = requestWrapper.getInputStream(); -// // 使用Jackson ObjectMapper解析JSON -// ObjectMapper objectMapper = new ObjectMapper(); -// TokenPayload tokenPayload = objectMapper.readValue(inputStream, TokenPayload.class); -// -// // 检查tokenPayload中是否存在token属性,并且这个属性不为空 -// String token = tokenPayload.getToken(); -// if (StringUtils.hasText(token)) { -// try { -// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); -// if (!ObjectUtils.isEmpty(userDetails)) { -// // 将这个用户注册到Security中 -// UsernamePasswordAuthenticationToken authenticationToken -// = new UsernamePasswordAuthenticationToken( -// userDetails, null, -// userDetails.getAuthorities()); -// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(requestWrapper)); -// SecurityContextHolder.getContext().setAuthentication(authenticationToken); -// } -// } catch (Exception e) { -// e.printStackTrace(); -// // Token无效,可以在这里添加相应的处理逻辑,例如返回401状态码等 -// } -// } -// } -// filterChain.doFilter(requestWrapper, response); // 注意这里使用requestWrapper -// } -//} -//package com.example.demo.security; -// -//import com.example.demo.Util.JWTUtil; -//import com.example.demo.Util.RequestWrapper; -//import com.example.demo.Util.TokenPayload; -//import com.example.demo.domain.entity.Admin; -//import com.fasterxml.jackson.databind.ObjectMapper; -//import jakarta.servlet.FilterChain; -//import jakarta.servlet.ServletException; -//import jakarta.servlet.http.HttpServletRequest; -//import jakarta.servlet.http.HttpServletResponse; -//import org.springframework.core.annotation.Order; -//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -//import org.springframework.security.core.context.SecurityContextHolder; -//import org.springframework.security.core.userdetails.UserDetails; -//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; -//import org.springframework.stereotype.Component; -//import org.springframework.util.ObjectUtils; -//import org.springframework.util.StringUtils; -//import org.springframework.web.filter.OncePerRequestFilter; -//import java.io.IOException; -//import java.io.InputStream; -// -//@Component -//public class TokenFilter extends OncePerRequestFilter { -// -// @Override -// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) -// throws ServletException, IOException { -// // 检查是否是上传请求 -// boolean isUploadRequest = request.getRequestURI().startsWith("/upload"); -// System.out.println(request.getRequestURI()); -// System.out.println(isUploadRequest); -// if (isUploadRequest) { -// // 如果是上传请求,直接将请求传递给下一个过滤器或目标资源 -// filterChain.doFilter(request, response); -// return; -// } else { -// // 使用RequestWrapper包装原始的HttpServletRequest,使其输入流可以被重复读取 -// RequestWrapper requestWrapper = new RequestWrapper(request); -// System.out.println(request); -// // 确保请求体只被读取一次 -// boolean hasRequestBody = "POST".equals(requestWrapper.getMethod()); -// if (hasRequestBody) { -// // 获取输入流 -// InputStream inputStream = requestWrapper.getInputStream(); -// // 使用Jackson ObjectMapper解析JSON -// ObjectMapper objectMapper = new ObjectMapper(); -// TokenPayload tokenPayload = objectMapper.readValue(inputStream, TokenPayload.class); -// -// // 检查tokenPayload中是否存在token属性,并且这个属性不为空 -// String token = tokenPayload.getToken(); -// if (StringUtils.hasText(token)) { -// try { -// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); -// if (!ObjectUtils.isEmpty(userDetails)) { -// // 将这个用户注册到Security中 -// UsernamePasswordAuthenticationToken authenticationToken -// = new UsernamePasswordAuthenticationToken( -// userDetails, null, -// userDetails.getAuthorities()); -// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(requestWrapper)); -// SecurityContextHolder.getContext().setAuthentication(authenticationToken); -// } -// } catch (Exception e) { -// e.printStackTrace(); -// // Token无效,可以在这里添加相应的处理逻辑,例如返回401状态码等 -// } -// } -// } -// // 非上传请求,继续执行过滤器链 -// filterChain.doFilter(requestWrapper, response); -// } -// } -//} package com.example.demo.security; + import com.example.demo.Util.JWTUtil; import com.example.demo.Util.RequestWrapper; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.example.demo.domain.entity.Admin; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.annotation.Order; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; @@ -212,66 +17,24 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; - import java.io.IOException; -import java.io.InputStream; -import java.util.Map; + @Component public class TokenFilter extends OncePerRequestFilter { - - private final ObjectMapper objectMapper = new ObjectMapper(); - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - // 检查是否是上传请求 - 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); - if (isUploadRequest ) { - // 如果是上传请求,直接将请求传递给下一个过滤器或目标资源 - filterChain.doFilter(request, response); - return; - } else { - // 使用RequestWrapper包装原始的HttpServletRequest,使其输入流可以被重复读取 - RequestWrapper requestWrapper = new RequestWrapper(request); -// System.out.println(request); - - // 确保请求体只被读取一次 - boolean hasRequestBody = "POST".equals(requestWrapper.getMethod()); - if (hasRequestBody) { - // 获取输入流 - InputStream inputStream = requestWrapper.getInputStream(); + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + // 取Token 生成登录信息 + String token = request.getHeader("token"); - try { - // 尝试将输入流转换为Map - Map jsonMap = objectMapper.readValue(inputStream, new TypeReference>() {}); - // 提取并处理token字段 - String token = (String) jsonMap.get("token"); - /* if (StringUtils.hasText(token)) { - processToken(token, requestWrapper); - }*/ + System.out.println(token+"123132132"); - // 处理其他字段(如recharge列表) - // 这里可以根据需要进一步解析其他字段 - } catch (JsonProcessingException e) { - e.printStackTrace(); - // JSON解析失败,可以在这里添加相应的处理逻辑,例如返回400状态码等 - } - } - // 非上传请求,继续执行过滤器链 - filterChain.doFilter(requestWrapper, response); - } - } - - /* private void processToken(String token, HttpServletRequest request) { - if (StringUtils.hasText(token)) { + // token不为空 + if (StringUtils.hasText(token)){ try { UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); - if (!ObjectUtils.isEmpty(userDetails)) { + if ( ! ObjectUtils.isEmpty(userDetails)) { // 将这个用户注册到Security中 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( @@ -282,11 +45,10 @@ public class TokenFilter extends OncePerRequestFilter { } } catch (Exception e) { e.printStackTrace(); - // Token无效,可以在这里添加相应的处理逻辑,例如返回401状态码等 + // Token无效, } } - }*/ + // 过滤器放行 + filterChain.doFilter(request, response); + } } - - - diff --git a/src/main/java/com/example/demo/security/UploadFilter.java b/src/main/java/com/example/demo/security/UploadFilter.java deleted file mode 100644 index a23be26..0000000 --- a/src/main/java/com/example/demo/security/UploadFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.example.demo.security; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; -import org.springframework.web.multipart.MultipartResolver; - -import java.io.IOException; - - -@Component -public class UploadFilter extends OncePerRequestFilter { - - private final MultipartResolver multipartResolver; - - public UploadFilter(MultipartResolver multipartResolver) { - this.multipartResolver = multipartResolver; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - - // 检查请求是否为上传请求,这里假设上传请求的路径以 "/upload" 开头 - boolean isUploadRequest = request.getRequestURI().startsWith("/upload"); - System.out.println(isUploadRequest); - System.out.println("MultipartResolver: " + multipartResolver); - if (isUploadRequest ) { - System.out.println("执行upload-------------------------------"); - // 如果是上传请求且Content-Type为multipart/form-data,直接将请求传递给下一个过滤器或目标资源 - filterChain.doFilter(request, response); - } else { - // 如果不是上传请求,执行一些自定义逻辑 - // 例如,可以在这里添加令牌验证或其他安全检查 - - // 继续执行过滤器链 - filterChain.doFilter(request, response); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/example/demo/service/AdminService.java b/src/main/java/com/example/demo/service/AdminService.java new file mode 100644 index 0000000..8f24f2d --- /dev/null +++ b/src/main/java/com/example/demo/service/AdminService.java @@ -0,0 +1,15 @@ +package com.example.demo.service; + +import com.example.demo.domain.entity.Admin; + +/** + * @program: GOLD + * @ClassName adminService + * @description: + * @author: huangqizhen + * @create: 2025−07-01 10:40 + * @Version 1.0 + **/ +public interface AdminService { + Admin login(Admin admin)throws Exception; +} diff --git a/src/main/java/com/example/demo/service/AiEmotionService.java b/src/main/java/com/example/demo/service/AiEmotionService.java index 919e782..c9b4f96 100644 --- a/src/main/java/com/example/demo/service/AiEmotionService.java +++ b/src/main/java/com/example/demo/service/AiEmotionService.java @@ -13,7 +13,7 @@ import com.example.demo.domain.vo.ExportVo; **/ public interface AiEmotionService { - ExportVo updateStatus(Long recordId, int i, String s, String s1, int i1); + int updateStatus(Long recordId, int i, String s, String s1, int i1); AiEmotionExportRecordVO getRecordById(Long id) throws Exception; } diff --git a/src/main/java/com/example/demo/service/ExportExcelService.java b/src/main/java/com/example/demo/service/ExportExcelService.java index 7db47e3..bf7134c 100644 --- a/src/main/java/com/example/demo/service/ExportExcelService.java +++ b/src/main/java/com/example/demo/service/ExportExcelService.java @@ -1,6 +1,8 @@ package com.example.demo.service; -import com.example.demo.domain.vo.AiEmotionExportRecordVO; +import com.example.demo.domain.entity.Export; + +import java.util.List; /** * @program: GOLD @@ -12,5 +14,9 @@ import com.example.demo.domain.vo.AiEmotionExportRecordVO; **/ public interface ExportExcelService { Exception handleExcelExportData(String message) throws Exception; - + Exception handleExcel(String message) throws Exception; + Exception rechargeExcel(String message) throws Exception; + Exception consumeExcel(String message) throws Exception; + Exception refundExcel(String message) throws Exception; + List getExcel(Export export); } \ No newline at end of file diff --git a/src/main/java/com/example/demo/service/GoldDetailService.java b/src/main/java/com/example/demo/service/GoldDetailService.java index 6106f9e..6ac1d18 100644 --- a/src/main/java/com/example/demo/service/GoldDetailService.java +++ b/src/main/java/com/example/demo/service/GoldDetailService.java @@ -1,14 +1,14 @@ package com.example.demo.service; import com.example.demo.domain.DTO.GoldDetailDTO; +import com.example.demo.domain.DTO.GoldUserDTO; import com.example.demo.domain.entity.User; import com.example.demo.domain.vo.GoldDetail; + import com.example.demo.domain.vo.Result; import com.example.demo.domain.vo.Total; import com.github.pagehelper.PageInfo; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; /** * @program: GOLD @@ -26,4 +26,6 @@ public interface GoldDetailService { Total GoldTotal(User user); //异步导出客户明细 Result addExportRecord(GoldDetailDTO dto); + //异步导出金币余额 + Result addExportRecordGold(GoldUserDTO dto); } diff --git a/src/main/java/com/example/demo/service/listen/AiEmotionExportListener.java b/src/main/java/com/example/demo/service/listen/AiEmotionExportListener.java index c2b3903..635ecdb 100644 --- a/src/main/java/com/example/demo/service/listen/AiEmotionExportListener.java +++ b/src/main/java/com/example/demo/service/listen/AiEmotionExportListener.java @@ -48,7 +48,7 @@ public class AiEmotionExportListener extends AbstractMessageListener { exportExcelService.handleExcelExportData(message); } catch (Exception e) { logError(e, message); - throw new RuntimeException("Failed to process AI emotion export: " + e.getMessage(), e); + throw new RuntimeException("Failed to process HWGOLD export: " + e.getMessage(), e); } @@ -67,7 +67,7 @@ public class AiEmotionExportListener extends AbstractMessageListener { context, e.getStackTrace()[0].getFileName(), e.getStackTrace()[0].getLineNumber(), - "AI Emotion Export Error: " + e.getMessage() + " 底层错误: " + cause , + "HWGOLD Export Error: " + e.getMessage() + " 底层错误: " + cause , "Failed message: " + message ); } catch (Exception alertEx) { diff --git a/src/main/java/com/example/demo/service/listen/ConsumeListener.java b/src/main/java/com/example/demo/service/listen/ConsumeListener.java new file mode 100644 index 0000000..853b0be --- /dev/null +++ b/src/main/java/com/example/demo/service/listen/ConsumeListener.java @@ -0,0 +1,81 @@ +package com.example.demo.service.listen; + +import cn.hutool.core.util.StrUtil; +import com.example.demo.Export.ExportService; +import com.example.demo.Util.ExecutionContextUtil; +import com.example.demo.Util.FeiShuAlertUtil; +import com.example.demo.Util.RedisUtil; +import com.example.demo.domain.vo.ExecutionContext; +import com.example.demo.service.ExportExcelService; +import com.example.demo.service.queue.AbstractMessageListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @program: GOLD + * @ClassName RechargeListener + * @description: + * @author: huangqizhen + * @create: 2025−07-01 15:46 + * @Version 1.0 + **/ +@Component +public class ConsumeListener extends AbstractMessageListener { + //注入ExportExcelService + @Autowired + private ExportExcelService exportService; + + @Autowired + public ConsumeListener( + RedisUtil redisQueueUtil + + ) { + super(redisQueueUtil, "consume:queue:export_queue"); + System.out.println("监听器已启动,队列: "); + } + + @Override + protected void handleMessage(String message) { + if (StrUtil.isBlank(message)) { + System.err.println("redis消息队列数据为空" + message); + } + try { + Thread.sleep(5000); + exportService.consumeExcel(message); + } catch (Exception e) { + logError(e, message); + throw new RuntimeException("Failed to process HWGOLD export: " + e.getMessage(), e); + } + + + } + + private void logError(Exception e, String message) { + System.err.println("Export data listener exception: " + e.getMessage()); + e.printStackTrace(); + try { + ExecutionContext context = ExecutionContextUtil.getExecutionContext(); + String cause = ""; + if (e.getCause() != null) { + cause = e.getCause().getMessage(); + } + FeiShuAlertUtil.sendAlertMessage( + context, + e.getStackTrace()[0].getFileName(), + e.getStackTrace()[0].getLineNumber(), + "HWGOLD Export Error: " + e.getMessage() + " 底层错误: " + cause , + "Failed message: " + message + ); + } catch (Exception alertEx) { + System.err.println("Failed to send Feishu alert: " + alertEx.getMessage()); + } + } + + @Override + protected void handleError(Exception e, String message) { + System.err.println("处理消息失败: " + message); + e.printStackTrace(); + } + +} + diff --git a/src/main/java/com/example/demo/service/listen/GoldListener.java b/src/main/java/com/example/demo/service/listen/GoldListener.java new file mode 100644 index 0000000..3736216 --- /dev/null +++ b/src/main/java/com/example/demo/service/listen/GoldListener.java @@ -0,0 +1,82 @@ +package com.example.demo.service.listen; + +import cn.hutool.core.util.StrUtil; + +import com.example.demo.Util.ExecutionContextUtil; +import com.example.demo.Util.FeiShuAlertUtil; +import com.example.demo.Util.RedisUtil; +import com.example.demo.domain.vo.ExecutionContext; +import com.example.demo.service.ExportExcelService; +import com.example.demo.service.GoldDetailService; +import com.example.demo.service.queue.AbstractMessageListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @program: GOLD + * @ClassName GoldListener + * @description: + * @author: huangqizhen + * @create: 2025−07-01 15:43 + * @Version 1.0 + **/ +@Component +public class GoldListener extends AbstractMessageListener { + //注入ExportExcelService + @Autowired + private ExportExcelService exportExcelService; + + @Autowired + public GoldListener( + RedisUtil redisQueueUtil + + ) { + super(redisQueueUtil, "gold:queue:export_queue"); + System.out.println("监听器已启动,队列: "); + } + + @Override + protected void handleMessage(String message) { + if (StrUtil.isBlank(message)) { + System.err.println("redis消息队列数据为空" + message); + } + try { + Thread.sleep(5000); + exportExcelService.handleExcel(message); + } catch (Exception e) { + logError(e, message); + throw new RuntimeException("Failed to process HWGOLD export: " + e.getMessage(), e); + } + + + } + + private void logError(Exception e, String message) { + System.err.println("Export data listener exception: " + e.getMessage()); + e.printStackTrace(); + try { + ExecutionContext context = ExecutionContextUtil.getExecutionContext(); + String cause = ""; + if (e.getCause() != null) { + cause = e.getCause().getMessage(); + } + FeiShuAlertUtil.sendAlertMessage( + context, + e.getStackTrace()[0].getFileName(), + e.getStackTrace()[0].getLineNumber(), + "HWGOLD Export Error: " + e.getMessage() + " 底层错误: " + cause , + "Failed message: " + message + ); + } catch (Exception alertEx) { + System.err.println("Failed to send Feishu alert: " + alertEx.getMessage()); + } + } + + @Override + protected void handleError(Exception e, String message) { + System.err.println("处理消息失败: " + message); + e.printStackTrace(); + } + +} + diff --git a/src/main/java/com/example/demo/service/listen/RechargeListener.java b/src/main/java/com/example/demo/service/listen/RechargeListener.java new file mode 100644 index 0000000..8240be4 --- /dev/null +++ b/src/main/java/com/example/demo/service/listen/RechargeListener.java @@ -0,0 +1,81 @@ +package com.example.demo.service.listen; + +import cn.hutool.core.util.StrUtil; +import com.example.demo.Export.ExportService; +import com.example.demo.Util.ExecutionContextUtil; +import com.example.demo.Util.FeiShuAlertUtil; +import com.example.demo.Util.RedisUtil; +import com.example.demo.domain.vo.ExecutionContext; +import com.example.demo.service.ExportExcelService; +import com.example.demo.service.queue.AbstractMessageListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @program: GOLD + * @ClassName RechargeListener + * @description: + * @author: huangqizhen + * @create: 2025−07-01 15:46 + * @Version 1.0 + **/ +@Component +public class RechargeListener extends AbstractMessageListener { + //注入ExportExcelService + @Autowired + private ExportExcelService exportService; + + @Autowired + public RechargeListener( + RedisUtil redisQueueUtil + + ) { + super(redisQueueUtil, "recharge:queue:export_queue"); + System.out.println("监听器已启动,队列: "); + } + + @Override + protected void handleMessage(String message) { + if (StrUtil.isBlank(message)) { + System.err.println("redis消息队列数据为空" + message); + } + try { + Thread.sleep(5000); + exportService.rechargeExcel(message); + } catch (Exception e) { + logError(e, message); + throw new RuntimeException("Failed to process HWGOLD export: " + e.getMessage(), e); + } + + + } + + private void logError(Exception e, String message) { + System.err.println("Export data listener exception: " + e.getMessage()); + e.printStackTrace(); + try { + ExecutionContext context = ExecutionContextUtil.getExecutionContext(); + String cause = ""; + if (e.getCause() != null) { + cause = e.getCause().getMessage(); + } + FeiShuAlertUtil.sendAlertMessage( + context, + e.getStackTrace()[0].getFileName(), + e.getStackTrace()[0].getLineNumber(), + "HWGOLD Export Error: " + e.getMessage() + " 底层错误: " + cause , + "Failed message: " + message + ); + } catch (Exception alertEx) { + System.err.println("Failed to send Feishu alert: " + alertEx.getMessage()); + } + } + + @Override + protected void handleError(Exception e, String message) { + System.err.println("处理消息失败: " + message); + e.printStackTrace(); + } + +} + diff --git a/src/main/java/com/example/demo/service/listen/RefundListener.java b/src/main/java/com/example/demo/service/listen/RefundListener.java new file mode 100644 index 0000000..fa71944 --- /dev/null +++ b/src/main/java/com/example/demo/service/listen/RefundListener.java @@ -0,0 +1,81 @@ +package com.example.demo.service.listen; + +import cn.hutool.core.util.StrUtil; +import com.example.demo.Export.ExportService; +import com.example.demo.Util.ExecutionContextUtil; +import com.example.demo.Util.FeiShuAlertUtil; +import com.example.demo.Util.RedisUtil; +import com.example.demo.domain.vo.ExecutionContext; +import com.example.demo.service.ExportExcelService; +import com.example.demo.service.queue.AbstractMessageListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @program: GOLD + * @ClassName RechargeListener + * @description: + * @author: huangqizhen + * @create: 2025−07-01 15:46 + * @Version 1.0 + **/ +@Component +public class RefundListener extends AbstractMessageListener { + //注入ExportExcelService + @Autowired + private ExportExcelService exportExcelService; + + @Autowired + public RefundListener( + RedisUtil redisQueueUtil + + ) { + super(redisQueueUtil, "refund:queue:export_queue"); + System.out.println("监听器已启动,队列: "); + } + + @Override + protected void handleMessage(String message) { + if (StrUtil.isBlank(message)) { + System.err.println("redis消息队列数据为空" + message); + } + try { + Thread.sleep(5000); + exportExcelService.refundExcel(message); + } catch (Exception e) { + logError(e, message); + throw new RuntimeException("Failed to process HWGOLD export: " + e.getMessage(), e); + } + + + } + + private void logError(Exception e, String message) { + System.err.println("Export data listener exception: " + e.getMessage()); + e.printStackTrace(); + try { + ExecutionContext context = ExecutionContextUtil.getExecutionContext(); + String cause = ""; + if (e.getCause() != null) { + cause = e.getCause().getMessage(); + } + FeiShuAlertUtil.sendAlertMessage( + context, + e.getStackTrace()[0].getFileName(), + e.getStackTrace()[0].getLineNumber(), + "HWGOLD Export Error: " + e.getMessage() + " 底层错误: " + cause , + "Failed message: " + message + ); + } catch (Exception alertEx) { + System.err.println("Failed to send Feishu alert: " + alertEx.getMessage()); + } + } + + @Override + protected void handleError(Exception e, String message) { + System.err.println("处理消息失败: " + message); + e.printStackTrace(); + } + +} + diff --git a/src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java new file mode 100644 index 0000000..d9b1620 --- /dev/null +++ b/src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java @@ -0,0 +1,64 @@ +package com.example.demo.serviceImpl; + +import com.example.demo.domain.entity.Admin; +import com.example.demo.mapper.AdminMapper; +import com.example.demo.service.AdminService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@Service +@RequiredArgsConstructor +public class AdminServiceImpl implements AdminService { + + @Autowired + private AuthenticationManager authenticationManager; + @Autowired + private AdminMapper adminMapper; + + @Override + public Admin login(Admin admin) throws Exception { + try { + Admin admin1 = adminMapper.getAdmin(admin.getAccount()); + String[] machineIds = admin1.getMachineId().split(","); + + boolean flag = false; + for (String machineId : machineIds) { + if (admin.getMachineId() != null && admin.getMachineId().equals(machineId)) + flag = true; + } + if (!flag) { + throw new RuntimeException("你没有使用该机器的权限!"); + } + System.out.println(admin.getAccount()); + System.out.println(admin.getPassword()+"---------------------------"); + UsernamePasswordAuthenticationToken token = + new UsernamePasswordAuthenticationToken(admin.getAccount(),admin.getPassword()); + System.out.println( token+"---------------------------"); +// Authentication authentication = authenticationManager.authenticate(token); +// Admin loginAdmin = (Admin) authentication.getPrincipal(); + Admin loginAdmin = (Admin) authenticationManager.authenticate(token).getPrincipal(); + + return loginAdmin; + + }catch (NullPointerException e){ + throw new RuntimeException("无此精网号"); + }catch(BadCredentialsException exception){ + throw new BadCredentialsException("密码错误"); + }catch (Exception e){ + throw new RuntimeException("你没有使用该机器的权限!"); + } + + + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/serviceImpl/AiEmotionServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/AiEmotionServiceImpl.java index e709ee4..3d68db2 100644 --- a/src/main/java/com/example/demo/serviceImpl/AiEmotionServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/AiEmotionServiceImpl.java @@ -24,7 +24,7 @@ public class AiEmotionServiceImpl implements AiEmotionService { private AiEmotionMapper aiEmotionMapper; @Override - public ExportVo updateStatus(Long recordId, int i, String s, String s1, int i1) { + public int updateStatus(Long recordId, int i, String s, String s1, int i1) { return exportMapper.updateExportData(recordId, i, s, s1, i1); } diff --git a/src/main/java/com/example/demo/serviceImpl/ExportExcelServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/ExportExcelServiceImpl.java index 5895109..98efdd1 100644 --- a/src/main/java/com/example/demo/serviceImpl/ExportExcelServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/ExportExcelServiceImpl.java @@ -5,10 +5,15 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.example.demo.Util.ExcelUploadUtil; +import com.example.demo.controller.ConsumeController; import com.example.demo.controller.GoldDetailController; +import com.example.demo.controller.RechargeController; +import com.example.demo.controller.RefundController; +import com.example.demo.domain.entity.Export; import com.example.demo.domain.export.Goldmingxi; import com.example.demo.domain.vo.*; +import com.example.demo.mapper.ExportMapper; import com.example.demo.service.ExportExcelService; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -17,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.example.demo.service.AiEmotionService; +import com.github.pagehelper.PageInfo; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -25,7 +31,6 @@ import org.springframework.transaction.annotation.Transactional; import java.io.*; import java.util.List; -import java.util.Map; @Service @@ -40,9 +45,17 @@ public class ExportExcelServiceImpl implements ExportExcelService { //注入GoldDetailController @Autowired private GoldDetailController goldDetailController; + @Autowired + private RechargeController rechargeController; + @Autowired + private RefundController refundController; + @Autowired + private ConsumeController consumeController; // 每页查询的数据量 private static final int PAGE_SIZE = 1000; + @Autowired + private ExportMapper exportMapper; @Transactional @@ -92,20 +105,31 @@ public class ExportExcelServiceImpl implements ExportExcelService { Result pageResult = goldDetailController.getGoldDetail(page); Integer code = pageResult.getCode(); Object data = pageResult.getData(); + if (code == 200) { - Map rawData = (Map) data; - Long total = (Long) rawData.get("total"); - List> list = (List>) rawData.get("list"); - // 检查是否还有数据 + // 判断 data 是否是 PageInfo 类型 + if (!(data instanceof PageInfo)) { + log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); + hasMore = false; + continue; + } + + @SuppressWarnings("unchecked") + PageInfo pageInfo = (PageInfo) data; + + Long total = (long) pageInfo.getTotal(); // 转换为 long + List list = pageInfo.getList(); + if (list == null || list.isEmpty()) { hasMore = false; } else { - // 写入数据(注意:finish()应在所有数据写入后调用) + // 写入 Excel 数据 excelWriter.write(list, writeSheet); + page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); - // 检查是否还有更多数据 + hasMore = totalCount < total; } } else { @@ -136,16 +160,35 @@ public class ExportExcelServiceImpl implements ExportExcelService { // 3. 执行上传 String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); // 1. 解析JSON任务 +// JsonNode uploadResult = objectMapper.readTree(result); +// System.out.println(uploadResult+"11111111111111111111111"); +// long code = uploadResult.path("code").asLong(); +// String url = String.valueOf(uploadResult.path("data")); +// url = url.replace("\"", ""); +// if (code == 1) { +// // 3. 验证导出记录decodecode +// aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); +// } else { +// //更新失败 +// aiEmotionService.updateStatus(recordId, 3, "", url, 0); +// } JsonNode uploadResult = objectMapper.readTree(result); long code = uploadResult.path("code").asLong(); - String url = String.valueOf(uploadResult.path("data")); - url = url.replace("\"", ""); - if (code == 1) { - // 3. 验证导出记录decodecode - aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); + + String fileUrl = ""; + JsonNode dataNode = uploadResult.path("data"); + if (dataNode.isObject()) { + fileUrl = dataNode.path("url").asText(); + } else if (dataNode.isTextual()) { + fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL + } + + log.info("解析到的URL: {}", fileUrl); + + if (code == 200 && !fileUrl.isEmpty()) { + aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); } else { - //更新失败 - aiEmotionService.updateStatus(recordId, 3, "", url, 0); + aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); } } catch (Exception e) { //更新失败 @@ -215,6 +258,812 @@ public class ExportExcelServiceImpl implements ExportExcelService { } + + @Transactional + @Override + public Exception handleExcel(String message) throws Exception { + System.out.println("明细导出excel数据开始执行:" + message); + long startTime = System.currentTimeMillis(); + Long recordId = null; + String fileName = null; + File tempFile = null; + OutputStream outputStream = null; + ExcelWriter excelWriter = null; + + try { + // 1. 解析JSON任务 + JsonNode rootNode = objectMapper.readTree(message); + // 2. 获取基本参数 + recordId = rootNode.path("recordId").asLong(); + JsonNode requestDataNode = rootNode.path("requestData"); + // 3. 验证导出记录 + AiEmotionExportRecordVO record = validateExportRecord(recordId); + if (record == null) return null; + //4. 更新状态为处理中 + aiEmotionService.updateStatus(recordId, 1, "", "", 0); + // 5. 准备Excel文件 + fileName = record.getFileName(); + // 初始化临时文件(保存到本地临时目录) + tempFile = File.createTempFile("export_", ".xlsx"); + outputStream = new FileOutputStream(tempFile); // 使用文件输出流 + // 从JSON中提取单个值 + String text = requestDataNode.has("text") ? requestDataNode.get("text").asText() : null; + Integer sort = requestDataNode.has("sort") ? requestDataNode.get("sort").asInt() : null; + String field = requestDataNode.has("field") ? requestDataNode.get("field").asText() : null; + String deptId = requestDataNode.has("deptId") ? requestDataNode.get("deptId").asText() : null; + + try { + // 6. 初始化Excel写入器(指向本地文件流) + excelWriter = initExcelWriter(outputStream, "user"); + WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); + // 7. 分页查询并写入数据 + Page page = new Page(); + page.setPageNum(1); + page.setPageSize(1000); + Integer totalCount = 0; + boolean hasMore = true; + while (hasMore) { + Result pageResult = goldDetailController.getGold(page); + Integer code = pageResult.getCode(); + Object data = pageResult.getData(); + + if (code == 200) { + // 判断 data 是否是 PageInfo 类型 + if (!(data instanceof PageInfo)) { + log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); + hasMore = false; + continue; + } + + @SuppressWarnings("unchecked") + PageInfo pageInfo = (PageInfo) data; + + Long total = (long) pageInfo.getTotal(); // 转换为 long + List list = pageInfo.getList(); + + if (list == null || list.isEmpty()) { + hasMore = false; + } else { + // 写入 Excel 数据 + excelWriter.write(list, writeSheet); + + page.setPageNum(page.getPageNum() + 1); + totalCount += list.size(); + log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); + + hasMore = totalCount < total; + } + } else { + hasMore = false; + log.error("获取数据失败,状态码: {}", code); + } + } + // 7. 完成Excel写入(所有数据写入后关闭写入器) + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.flush(); // 确保所有数据写入 + outputStream.close(); // 关闭文件流 + } + // 检查文件是否存在且不为空 + if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { + // 8. 上传到OSS(读取本地临时文件) + // 获取接口的基础 URL + String uploadUrl = "http://39.101.133.168:8828/hljw/api/aws/upload"; + try { + // 1. 创建上传工具实例 + ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); + + // 2. 准备要上传的文件 + File excelFile = new File(tempFile.toURI()); + try { + // 3. 执行上传 + String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); + // 1. 解析JSON任务 +// JsonNode uploadResult = objectMapper.readTree(result); +// System.out.println(uploadResult+"11111111111111111111111"); +// long code = uploadResult.path("code").asLong(); +// String url = String.valueOf(uploadResult.path("data")); +// url = url.replace("\"", ""); +// if (code == 1) { +// // 3. 验证导出记录decodecode +// aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); +// } else { +// //更新失败 +// aiEmotionService.updateStatus(recordId, 3, "", url, 0); +// } + JsonNode uploadResult = objectMapper.readTree(result); + long code = uploadResult.path("code").asLong(); + + String fileUrl = ""; + JsonNode dataNode = uploadResult.path("data"); + if (dataNode.isObject()) { + fileUrl = dataNode.path("url").asText(); + } else if (dataNode.isTextual()) { + fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL + } + + log.info("解析到的URL: {}", fileUrl); + + if (code == 200 && !fileUrl.isEmpty()) { + aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); + } else { + aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); + } + } catch (Exception e) { + //更新失败 + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + throw new Exception("文件上传云端失败1", e); + } + } catch (Exception e) { + log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); + //更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("文件上传云端失败2", e); + } + } else { + throw new Exception("导出的Excel文件不存在或为空"); + } + + } catch (Exception e) { + System.out.println("导出异常" + e.getMessage()); + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("导出异常", e); + } finally { + // 确保资源被关闭 + try { + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (Exception e) { + log.error("关闭资源失败", e); + throw new Exception("excel文件关闭资源失败", e); + } + } + } catch (Exception e) { + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + System.out.println("<导出失败>" + e.getMessage()); + throw new Exception("导出任务处理失败", e); + } finally { + // 清理临时文件 + if (tempFile != null && tempFile.exists()) { + try { + if (tempFile.delete()) { + log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); + } else { + log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); + } + } catch (Exception e) { + log.error("删除临时文件失败", e.getMessage()); + throw new Exception("删除临时文件失败", e); + } + } + long endTime = System.currentTimeMillis(); + log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); + } + return null; + } + + @Transactional + @Override + public Exception rechargeExcel(String message) throws Exception { + System.out.println("明细导出excel数据开始执行:" + message); + long startTime = System.currentTimeMillis(); + Long recordId = null; + String fileName = null; + File tempFile = null; + OutputStream outputStream = null; + ExcelWriter excelWriter = null; + + try { + // 1. 解析JSON任务 + JsonNode rootNode = objectMapper.readTree(message); + // 2. 获取基本参数 + recordId = rootNode.path("recordId").asLong(); + JsonNode requestDataNode = rootNode.path("requestData"); + // 3. 验证导出记录 + AiEmotionExportRecordVO record = validateExportRecord(recordId); + if (record == null) return null; + //4. 更新状态为处理中 + aiEmotionService.updateStatus(recordId, 1, "", "", 0); + // 5. 准备Excel文件 + fileName = record.getFileName(); + // 初始化临时文件(保存到本地临时目录) + tempFile = File.createTempFile("export_", ".xlsx"); + outputStream = new FileOutputStream(tempFile); // 使用文件输出流 + // 从JSON中提取单个值 + String text = requestDataNode.has("text") ? requestDataNode.get("text").asText() : null; + Integer sort = requestDataNode.has("sort") ? requestDataNode.get("sort").asInt() : null; + String field = requestDataNode.has("field") ? requestDataNode.get("field").asText() : null; + String deptId = requestDataNode.has("deptId") ? requestDataNode.get("deptId").asText() : null; + + try { + // 6. 初始化Excel写入器(指向本地文件流) + excelWriter = initExcelWriter(outputStream, "user"); + WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); + // 7. 分页查询并写入数据 + Page page = new Page(); + page.setPageNum(1); + page.setPageSize(1000); + Integer totalCount = 0; + boolean hasMore = true; + while (hasMore) { + Result pageResult = rechargeController.selcetBy( page); + Integer code = pageResult.getCode(); + Object data = pageResult.getData(); + + if (code == 200) { + // 判断 data 是否是 PageInfo 类型 + if (!(data instanceof PageInfo)) { + log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); + hasMore = false; + continue; + } + + @SuppressWarnings("unchecked") + PageInfo pageInfo = (PageInfo) data; + + Long total = (long) pageInfo.getTotal(); // 转换为 long + List list = pageInfo.getList(); + + if (list == null || list.isEmpty()) { + hasMore = false; + } else { + // 写入 Excel 数据 + excelWriter.write(list, writeSheet); + + page.setPageNum(page.getPageNum() + 1); + totalCount += list.size(); + log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); + + hasMore = totalCount < total; + } + } else { + hasMore = false; + log.error("获取数据失败,状态码: {}", code); + } + } + // 7. 完成Excel写入(所有数据写入后关闭写入器) + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.flush(); // 确保所有数据写入 + outputStream.close(); // 关闭文件流 + } + // 检查文件是否存在且不为空 + if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { + // 8. 上传到OSS(读取本地临时文件) + // 获取接口的基础 URL + String uploadUrl = "http://39.101.133.168:8828/hljw/api/aws/upload"; + try { + // 1. 创建上传工具实例 + ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); + + // 2. 准备要上传的文件 + File excelFile = new File(tempFile.toURI()); + try { + // 3. 执行上传 + String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); + // 1. 解析JSON任务 +// JsonNode uploadResult = objectMapper.readTree(result); +// System.out.println(uploadResult+"11111111111111111111111"); +// long code = uploadResult.path("code").asLong(); +// String url = String.valueOf(uploadResult.path("data")); +// url = url.replace("\"", ""); +// if (code == 1) { +// // 3. 验证导出记录decodecode +// aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); +// } else { +// //更新失败 +// aiEmotionService.updateStatus(recordId, 3, "", url, 0); +// } + JsonNode uploadResult = objectMapper.readTree(result); + long code = uploadResult.path("code").asLong(); + + String fileUrl = ""; + JsonNode dataNode = uploadResult.path("data"); + if (dataNode.isObject()) { + fileUrl = dataNode.path("url").asText(); + } else if (dataNode.isTextual()) { + fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL + } + + log.info("解析到的URL: {}", fileUrl); + + if (code == 200 && !fileUrl.isEmpty()) { + aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); + } else { + aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); + } + } catch (Exception e) { + //更新失败 + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + throw new Exception("文件上传云端失败1", e); + } + } catch (Exception e) { + log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); + //更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("文件上传云端失败2", e); + } + } else { + throw new Exception("导出的Excel文件不存在或为空"); + } + + } catch (Exception e) { + System.out.println("导出异常" + e.getMessage()); + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("导出异常", e); + } finally { + // 确保资源被关闭 + try { + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (Exception e) { + log.error("关闭资源失败", e); + throw new Exception("excel文件关闭资源失败", e); + } + } + } catch (Exception e) { + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + System.out.println("<导出失败>" + e.getMessage()); + throw new Exception("导出任务处理失败", e); + } finally { + // 清理临时文件 + if (tempFile != null && tempFile.exists()) { + try { + if (tempFile.delete()) { + log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); + } else { + log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); + } + } catch (Exception e) { + log.error("删除临时文件失败", e.getMessage()); + throw new Exception("删除临时文件失败", e); + } + } + long endTime = System.currentTimeMillis(); + log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); + } + return null; + } + + @Transactional + @Override + public Exception consumeExcel(String message) throws Exception { + System.out.println("明细导出excel数据开始执行:" + message); + long startTime = System.currentTimeMillis(); + Long recordId = null; + String fileName = null; + File tempFile = null; + OutputStream outputStream = null; + ExcelWriter excelWriter = null; + + try { + // 1. 解析JSON任务 + JsonNode rootNode = objectMapper.readTree(message); + // 2. 获取基本参数 + recordId = rootNode.path("recordId").asLong(); + JsonNode requestDataNode = rootNode.path("requestData"); + // 3. 验证导出记录 + AiEmotionExportRecordVO record = validateExportRecord(recordId); + if (record == null) return null; + //4. 更新状态为处理中 + aiEmotionService.updateStatus(recordId, 1, "", "", 0); + // 5. 准备Excel文件 + fileName = record.getFileName(); + // 初始化临时文件(保存到本地临时目录) + tempFile = File.createTempFile("export_", ".xlsx"); + outputStream = new FileOutputStream(tempFile); // 使用文件输出流 + // 从JSON中提取单个值 + String text = requestDataNode.has("text") ? requestDataNode.get("text").asText() : null; + Integer sort = requestDataNode.has("sort") ? requestDataNode.get("sort").asInt() : null; + String field = requestDataNode.has("field") ? requestDataNode.get("field").asText() : null; + String deptId = requestDataNode.has("deptId") ? requestDataNode.get("deptId").asText() : null; + + try { + // 6. 初始化Excel写入器(指向本地文件流) + excelWriter = initExcelWriter(outputStream, "user"); + WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); + // 7. 分页查询并写入数据 + Page page = new Page(); + page.setPageNum(1); + page.setPageSize(1000); + Integer totalCount = 0; + boolean hasMore = true; + while (hasMore) { + Result pageResult = refundController.selcetBy(page); + Integer code = pageResult.getCode(); + Object data = pageResult.getData(); + + if (code == 200) { + // 判断 data 是否是 PageInfo 类型 + if (!(data instanceof PageInfo)) { + log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); + hasMore = false; + continue; + } + + @SuppressWarnings("unchecked") + PageInfo pageInfo = (PageInfo) data; + + Long total = (long) pageInfo.getTotal(); // 转换为 long + List list = pageInfo.getList(); + + if (list == null || list.isEmpty()) { + hasMore = false; + } else { + // 写入 Excel 数据 + excelWriter.write(list, writeSheet); + + page.setPageNum(page.getPageNum() + 1); + totalCount += list.size(); + log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); + + hasMore = totalCount < total; + } + } else { + hasMore = false; + log.error("获取数据失败,状态码: {}", code); + } + } + // 7. 完成Excel写入(所有数据写入后关闭写入器) + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.flush(); // 确保所有数据写入 + outputStream.close(); // 关闭文件流 + } + // 检查文件是否存在且不为空 + if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { + // 8. 上传到OSS(读取本地临时文件) + // 获取接口的基础 URL + String uploadUrl = "http://39.101.133.168:8828/hljw/api/aws/upload"; + try { + // 1. 创建上传工具实例 + ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); + + // 2. 准备要上传的文件 + File excelFile = new File(tempFile.toURI()); + try { + // 3. 执行上传 + String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); + // 1. 解析JSON任务 +// JsonNode uploadResult = objectMapper.readTree(result); +// System.out.println(uploadResult+"11111111111111111111111"); +// long code = uploadResult.path("code").asLong(); +// String url = String.valueOf(uploadResult.path("data")); +// url = url.replace("\"", ""); +// if (code == 1) { +// // 3. 验证导出记录decodecode +// aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); +// } else { +// //更新失败 +// aiEmotionService.updateStatus(recordId, 3, "", url, 0); +// } + JsonNode uploadResult = objectMapper.readTree(result); + long code = uploadResult.path("code").asLong(); + + String fileUrl = ""; + JsonNode dataNode = uploadResult.path("data"); + if (dataNode.isObject()) { + fileUrl = dataNode.path("url").asText(); + } else if (dataNode.isTextual()) { + fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL + } + + log.info("解析到的URL: {}", fileUrl); + + if (code == 200 && !fileUrl.isEmpty()) { + aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); + } else { + aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); + } + } catch (Exception e) { + //更新失败 + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + throw new Exception("文件上传云端失败1", e); + } + } catch (Exception e) { + log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); + //更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("文件上传云端失败2", e); + } + } else { + throw new Exception("导出的Excel文件不存在或为空"); + } + + } catch (Exception e) { + System.out.println("导出异常" + e.getMessage()); + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("导出异常", e); + } finally { + // 确保资源被关闭 + try { + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (Exception e) { + log.error("关闭资源失败", e); + throw new Exception("excel文件关闭资源失败", e); + } + } + } catch (Exception e) { + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + System.out.println("<导出失败>" + e.getMessage()); + throw new Exception("导出任务处理失败", e); + } finally { + // 清理临时文件 + if (tempFile != null && tempFile.exists()) { + try { + if (tempFile.delete()) { + log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); + } else { + log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); + } + } catch (Exception e) { + log.error("删除临时文件失败", e.getMessage()); + throw new Exception("删除临时文件失败", e); + } + } + long endTime = System.currentTimeMillis(); + log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); + } + return null; + } + + @Transactional + @Override + public Exception refundExcel(String message) throws Exception { + System.out.println("明细导出excel数据开始执行:" + message); + long startTime = System.currentTimeMillis(); + Long recordId = null; + String fileName = null; + File tempFile = null; + OutputStream outputStream = null; + ExcelWriter excelWriter = null; + + try { + // 1. 解析JSON任务 + JsonNode rootNode = objectMapper.readTree(message); + // 2. 获取基本参数 + recordId = rootNode.path("recordId").asLong(); + JsonNode requestDataNode = rootNode.path("requestData"); + // 3. 验证导出记录 + AiEmotionExportRecordVO record = validateExportRecord(recordId); + if (record == null) return null; + //4. 更新状态为处理中 + aiEmotionService.updateStatus(recordId, 1, "", "", 0); + // 5. 准备Excel文件 + fileName = record.getFileName(); + // 初始化临时文件(保存到本地临时目录) + tempFile = File.createTempFile("export_", ".xlsx"); + outputStream = new FileOutputStream(tempFile); // 使用文件输出流 + // 从JSON中提取单个值 + String text = requestDataNode.has("text") ? requestDataNode.get("text").asText() : null; + Integer sort = requestDataNode.has("sort") ? requestDataNode.get("sort").asInt() : null; + String field = requestDataNode.has("field") ? requestDataNode.get("field").asText() : null; + String deptId = requestDataNode.has("deptId") ? requestDataNode.get("deptId").asText() : null; + + try { + // 6. 初始化Excel写入器(指向本地文件流) + excelWriter = initExcelWriter(outputStream, "user"); + WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); + // 7. 分页查询并写入数据 + Page page = new Page(); + page.setPageNum(1); + page.setPageSize(1000); + Integer totalCount = 0; + boolean hasMore = true; + while (hasMore) { + Result pageResult = consumeController.selcetBy(page); + Integer code = pageResult.getCode(); + Object data = pageResult.getData(); + + if (code == 200) { + // 判断 data 是否是 PageInfo 类型 + if (!(data instanceof PageInfo)) { + log.error("返回数据类型错误,期望 PageInfo,实际为:{}", data.getClass()); + hasMore = false; + continue; + } + + @SuppressWarnings("unchecked") + PageInfo pageInfo = (PageInfo) data; + + Long total = (long) pageInfo.getTotal(); // 转换为 long + List list = pageInfo.getList(); + + if (list == null || list.isEmpty()) { + hasMore = false; + } else { + // 写入 Excel 数据 + excelWriter.write(list, writeSheet); + + page.setPageNum(page.getPageNum() + 1); + totalCount += list.size(); + log.info("导出进度 recordId: {}, 已处理: {}条", recordId, totalCount); + + hasMore = totalCount < total; + } + } else { + hasMore = false; + log.error("获取数据失败,状态码: {}", code); + } + } + // 7. 完成Excel写入(所有数据写入后关闭写入器) + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.flush(); // 确保所有数据写入 + outputStream.close(); // 关闭文件流 + } + // 检查文件是否存在且不为空 + if (tempFile != null && tempFile.exists() && tempFile.length() > 0) { + // 8. 上传到OSS(读取本地临时文件) + // 获取接口的基础 URL + String uploadUrl = "http://39.101.133.168:8828/hljw/api/aws/upload"; + try { + // 1. 创建上传工具实例 + ExcelUploadUtil uploadUtil = new ExcelUploadUtil(uploadUrl); + + // 2. 准备要上传的文件 + File excelFile = new File(tempFile.toURI()); + try { + // 3. 执行上传 + String result = uploadUtil.uploadExcel(excelFile, "export/excel/"); + // 1. 解析JSON任务 +// JsonNode uploadResult = objectMapper.readTree(result); +// System.out.println(uploadResult+"11111111111111111111111"); +// long code = uploadResult.path("code").asLong(); +// String url = String.valueOf(uploadResult.path("data")); +// url = url.replace("\"", ""); +// if (code == 1) { +// // 3. 验证导出记录decodecode +// aiEmotionService.updateStatus(recordId, 2, url, "", totalCount); +// } else { +// //更新失败 +// aiEmotionService.updateStatus(recordId, 3, "", url, 0); +// } + JsonNode uploadResult = objectMapper.readTree(result); + long code = uploadResult.path("code").asLong(); + + String fileUrl = ""; + JsonNode dataNode = uploadResult.path("data"); + if (dataNode.isObject()) { + fileUrl = dataNode.path("url").asText(); + } else if (dataNode.isTextual()) { + fileUrl = dataNode.asText(); // 如果 data 是直接字符串 URL + } + + log.info("解析到的URL: {}", fileUrl); + + if (code == 200 && !fileUrl.isEmpty()) { + aiEmotionService.updateStatus(recordId, 2, fileUrl, "", totalCount); + } else { + aiEmotionService.updateStatus(recordId, 3, "", "上传成功但URL为空或解析失败", 0); + } + } catch (Exception e) { + //更新失败 + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + throw new Exception("文件上传云端失败1", e); + } + } catch (Exception e) { + log.error("上传文件失败 recordId: {}, 文件名: {}", recordId, fileName, e); + //更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("文件上传云端失败2", e); + } + } else { + throw new Exception("导出的Excel文件不存在或为空"); + } + + } catch (Exception e) { + System.out.println("导出异常" + e.getMessage()); + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + throw new Exception("导出异常", e); + } finally { + // 确保资源被关闭 + try { + if (excelWriter != null) { + excelWriter.finish(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (Exception e) { + log.error("关闭资源失败", e); + throw new Exception("excel文件关闭资源失败", e); + } + } + } catch (Exception e) { + log.error("导出任务处理失败 recordId: {}", recordId, e); + // 更新状态为失败 + if (recordId != null) { + aiEmotionService.updateStatus(recordId, 3, "", StringUtils.substring(e.getMessage(), 0, 500), 0); + } + System.out.println("<导出失败>" + e.getMessage()); + throw new Exception("导出任务处理失败", e); + } finally { + // 清理临时文件 + if (tempFile != null && tempFile.exists()) { + try { + if (tempFile.delete()) { + log.info("临时文件已删除: {}", tempFile.getAbsolutePath()); + } else { + log.warn("无法删除临时文件: {}", tempFile.getAbsolutePath()); + } + } catch (Exception e) { + log.error("删除临时文件失败", e.getMessage()); + throw new Exception("删除临时文件失败", e); + } + } + long endTime = System.currentTimeMillis(); + log.info("导出任务完成,耗时: {}毫秒", (endTime - startTime)); + } + return null; + } + + + @Override + public List getExcel(Export export) { + List list = exportMapper.getExportRecord(export.getAccount()); + System.out.println(list+"-------------------------------"); + return list; + } + + /** * 验证导出记录 */ diff --git a/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java index 7d0dbcf..9fb1f91 100644 --- a/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/GoldDetailServiceImpl.java @@ -2,6 +2,7 @@ package com.example.demo.serviceImpl; import com.example.demo.Util.RedisUtil; import com.example.demo.domain.DTO.GoldDetailDTO; +import com.example.demo.domain.DTO.GoldUserDTO; import com.example.demo.domain.entity.User; import com.example.demo.domain.vo.GoldDetail; import com.example.demo.domain.vo.Result; @@ -74,7 +75,7 @@ public class GoldDetailServiceImpl implements GoldDetailService { "操作人", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); System.out.println(fileName); - dto.setJwcode(123456); + dto.setAccount(123456); dto.setUrl(""); dto.setFileName(fileName); dto.setDataNum(0); @@ -83,7 +84,7 @@ public class GoldDetailServiceImpl implements GoldDetailService { GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder(); goldDetailMapper.insertExportRecord( idHolder, // 用于接收主键 - dto.getJwcode(), + dto.getAccount(), dto.getType(), dto.getState(), dto.getUrl(), @@ -114,6 +115,53 @@ public class GoldDetailServiceImpl implements GoldDetailService { return Result.success(); } + @Override + public Result addExportRecordGold(GoldUserDTO dto) { + // 生成文件名 + String fileName = String.format("%s_%s_%s.xlsx", + "金币余额明细", + "操作人", + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + System.out.println(fileName); + dto.setAccount(123456); + dto.setUrl(""); + dto.setFileName(fileName); + dto.setDataNum(0); + try{ + // 调用方式 + GoldDetailMapper.ExportRecordIdHolder idHolder = new GoldDetailMapper.ExportRecordIdHolder(); + goldDetailMapper.insertExportRecord( + idHolder, // 用于接收主键 + dto.getAccount(), + dto.getType(), + dto.getState(), + dto.getUrl(), + dto.getFileName(), + dto.getDataNum() + ); + // 获取主键 + Long recordId = idHolder.getId(); + // 2. 构造完整的 JSON 数据(包含所有请求参数) + Map exportData = new HashMap<>(); + exportData.put("recordId", recordId); + + // 手动构造请求数据(避免 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()); + exportData.put("requestData", requestData); + + // 3. 发送到 Redis 消息队列 + String jsonData = new ObjectMapper().writeValueAsString(exportData); + redisUtil.sendMessage("gold:queue:export_queue", jsonData); + }catch (Exception e){ + e.printStackTrace(); + throw new SystemException("导出数据异常,请稍后重试", e); + } + return Result.success(); + } } diff --git a/src/main/resources/mapper/AiEmotionMapper.xml b/src/main/resources/mapper/AiEmotionMapper.xml index 2824bba..a927bd0 100644 --- a/src/main/resources/mapper/AiEmotionMapper.xml +++ b/src/main/resources/mapper/AiEmotionMapper.xml @@ -2,7 +2,7 @@ - UPDATE admin_export_record + UPDATE export state = #{state}, url = #{url}, @@ -12,6 +12,6 @@ WHERE id = #{recordId} \ No newline at end of file diff --git a/src/main/resources/mapper/ExportMapper.xml b/src/main/resources/mapper/ExportMapper.xml index 8cfcb31..f67834b 100644 --- a/src/main/resources/mapper/ExportMapper.xml +++ b/src/main/resources/mapper/ExportMapper.xml @@ -15,4 +15,14 @@ + + + \ No newline at end of file diff --git a/src/main/resources/mapper/GoldDetailMapper.xml b/src/main/resources/mapper/GoldDetailMapper.xml index 10d027b..cdb9a4e 100644 --- a/src/main/resources/mapper/GoldDetailMapper.xml +++ b/src/main/resources/mapper/GoldDetailMapper.xml @@ -2,8 +2,8 @@ - insert into excprt (jwcode,type,state,url,file_name,data_num) - values(#{jwcode},#{type},#{state},#{url},#{fileName},#{dataNum}) + insert into export (account,type,state,url,file_name,data_num) + values(#{account},#{type},#{state},#{url},#{fileName},#{dataNum}) - \ No newline at end of file +