diff --git a/src/main/java/com/example/demo/Util/ExcelHeaderTranslator.java b/src/main/java/com/example/demo/Util/ExcelHeaderTranslator.java index 4dbda49..753fd2d 100644 --- a/src/main/java/com/example/demo/Util/ExcelHeaderTranslator.java +++ b/src/main/java/com/example/demo/Util/ExcelHeaderTranslator.java @@ -423,6 +423,86 @@ public class ExcelHeaderTranslator { } /** + * 获取用户金币余额的Excel表头映射 + * 返回 Map<字段名, 中文表头> + */ + public Map getUserHeaders(String lang) { + Map headers = new LinkedHashMap<>(); + + // 定义所有表头的原始中文名称(对应 User 类的字段) + headers.put("id", "客户id"); + headers.put("jwcode", "精网号"); + headers.put("name", "姓名"); + headers.put("market", "所属地区"); + headers.put("sumGold", "金币总数"); + headers.put("currentPermanentGold", "当前永久金币"); + headers.put("currentFreeJune", "当前六月到期免费金币"); + headers.put("currentFreeDecember", "当前十二月到期免费金币"); + headers.put("currentTaskGold", "当前任务金币"); + headers.put("rechargeNum", "充值次数(25年起)"); + headers.put("consumeNum", "消费次数(25年起)"); + headers.put("firstRecharge", "首充日期"); + headers.put("createTime", "创建时间"); + headers.put("updateTime", "更新时间"); + + // 如果需要翻译,则翻译表头 + if (!isChineseLanguage(lang)) { + return translateHeaders(headers, lang); + } + + return headers; + } + + /** + * 获取用户金币余额表头顺序 + */ + public List getUserColumnOrder() { + return Arrays.asList( + "id", "jwcode", "name", "market", "sumGold", "currentPermanentGold", + "currentFreeJune", "currentFreeDecember", "currentTaskGold", "rechargeNum", + "consumeNum", "firstRecharge", "createTime", "updateTime" + ); + } + + /** + * 获取金币明细的Excel表头映射 + * 返回 Map<字段名, 中文表头> + */ + public Map getGoldDetailHeaders(String lang) { + Map headers = new LinkedHashMap<>(); + + // 定义所有表头的原始中文名称(对应 GoldDetail 类的字段) + headers.put("name", "姓名"); + headers.put("jwcode", "精网号"); + headers.put("market", "所属地区"); + headers.put("payPlatform", "平台信息"); + headers.put("typeDesc", "更新类型"); + headers.put("sumGold", "金币数量"); + headers.put("permanentGold", "永久金币"); + headers.put("freeGold", "免费金币"); + headers.put("taskGold", "任务金币"); + headers.put("adminName", "提交人"); + headers.put("auditTime", "更新时间"); + + // 如果需要翻译,则翻译表头 + if (!isChineseLanguage(lang)) { + return translateHeaders(headers, lang); + } + + return headers; + } + + /** + * 获取金币明细表头顺序 + */ + public List getGoldDetailColumnOrder() { + return Arrays.asList( + "name", "jwcode", "market", "payPlatform", "typeDesc", "sumGold", + "permanentGold", "freeGold", "taskGold", "adminName", "auditTime" + ); + } + + /** * 翻译表头 */ private Map translateHeaders(Map headers, String lang) { diff --git a/src/main/java/com/example/demo/controller/coin/GoldDetailController.java b/src/main/java/com/example/demo/controller/coin/GoldDetailController.java index cf7bfdf..8ce9a89 100644 --- a/src/main/java/com/example/demo/controller/coin/GoldDetailController.java +++ b/src/main/java/com/example/demo/controller/coin/GoldDetailController.java @@ -266,10 +266,20 @@ public class GoldDetailController { @PostMapping("/export") - public Result export(@Valid @RequestBody GoldDetailDTO dto) { + public Result export(@Valid @RequestBody GoldDetailDTO dto, @RequestHeader(defaultValue = "zh_CN") String lang) { String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分) String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁) long expireTime = 5000; // 锁过期时间(5秒)s + dto.setLang(lang); // 设置语言参数 + + // 解析语言代码 + String languageCode = parseLanguageCode(lang); + + // 如果不是中文环境,将查询条件中的翻译文本转换为中文简体 + if (!"zh".equalsIgnoreCase(languageCode) && !"zh_cn".equalsIgnoreCase(languageCode)) { + convertGoldDetailTranslatedFieldsToChinese(dto.getGoldDetail(), languageCode); + } + try { // 尝试获取锁 if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { @@ -283,10 +293,20 @@ public class GoldDetailController { } } @PostMapping("/exportGold") - public Result export(@Valid @RequestBody GoldUserDTO dto) { + public Result export(@Valid @RequestBody GoldUserDTO dto, @RequestHeader(defaultValue = "zh_CN") String lang) { String lockKey = "export:lock:" + dto.getToken(); // 锁的 Key(可按用户/业务区分) String requestId = UUID.randomUUID().toString(); // 请求 ID(防止误删锁) long expireTime = 5000; // 锁过期时间(5秒)s + dto.setLang(lang); + + // 解析语言代码 + String languageCode = parseLanguageCode(lang); + + // 如果不是中文环境,将查询条件中的翻译文本转换为中文简体 + if (!"zh".equalsIgnoreCase(languageCode) && !"zh_cn".equalsIgnoreCase(languageCode)) { + convertUserTranslatedFieldsToChinese(dto.getUser(), languageCode); + } + try { // 尝试获取锁 if (!redisLockUtil.tryLock(lockKey, requestId, expireTime)) { 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 637a138..617876e 100644 --- a/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java +++ b/src/main/java/com/example/demo/domain/DTO/GoldDetailDTO.java @@ -30,6 +30,7 @@ public class GoldDetailDTO { private Integer dataNum = 0; private String deptid = ""; private GoldDetail goldDetail; + private String lang; @NotNull(message = "page不能为空") private Integer page = 1; diff --git a/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java b/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java index 1ca77f6..233be9e 100644 --- a/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java +++ b/src/main/java/com/example/demo/domain/DTO/GoldUserDTO.java @@ -28,6 +28,7 @@ public class GoldUserDTO { private Integer dataNum = 0; private String deptid = ""; private User user; + private String lang; @NotNull(message = "page不能为空") private Integer page = 1; diff --git a/src/main/java/com/example/demo/domain/entity/User.java b/src/main/java/com/example/demo/domain/entity/User.java index 1fee4db..38886d1 100644 --- a/src/main/java/com/example/demo/domain/entity/User.java +++ b/src/main/java/com/example/demo/domain/entity/User.java @@ -20,13 +20,9 @@ import java.util.Set; public class User implements Serializable { private static final long serialVersionUID = 1L; - @ExcelProperty("客户id") private Integer id; // 客户id - @ExcelProperty("精网号") private Integer jwcode; // 精网号 - @ExcelProperty("姓名") private String name; // 客户姓名 - @ExcelProperty("所属地区") private String market; // 所属地区 @ExcelIgnore private String marketName; // 所属地区 @@ -38,21 +34,14 @@ public class User implements Serializable { private BigDecimal sumFreeDecember; // 历史十二月免费金币 @ExcelIgnore private BigDecimal sumTaskGold; // 历史任务金币 - @ExcelProperty("金币总数") private BigDecimal sumGold;// 金币总数 - @ExcelProperty("当前永久金币") private BigDecimal currentPermanentGold; // 当前永久金币 - @ExcelProperty("当前六月到期免费金币") private BigDecimal currentFreeJune; // 当前六月免费金币 - @ExcelProperty("当前十二月到期免费金币") private BigDecimal currentFreeDecember; // 当前十二月免费金币 - @ExcelProperty("当前任务金币") private BigDecimal currentTaskGold; // 当前任务金币 - @ExcelProperty("充值次数(25年起)") private Integer rechargeNum; // 充值次数 @ExcelIgnore private Integer sumConsume; // 历史消费 - @ExcelProperty("消费次数(25年起)") private Integer consumeNum; // 消费次数 @ExcelIgnore private BigDecimal sumConsumePermanent; @@ -62,13 +51,10 @@ public class User implements Serializable { private BigDecimal sumConsumeFree; @ExcelIgnore private List markets; -@ExcelProperty("首充日期") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date firstRecharge; // 首充日期 - @ExcelProperty("创建时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date createTime; // 创建时间 - @ExcelProperty("更新时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date updateTime; // 更新时间 @ExcelIgnore diff --git a/src/main/java/com/example/demo/domain/vo/coin/GoldDetail.java b/src/main/java/com/example/demo/domain/vo/coin/GoldDetail.java index 467cefe..cdcfdf0 100644 --- a/src/main/java/com/example/demo/domain/vo/coin/GoldDetail.java +++ b/src/main/java/com/example/demo/domain/vo/coin/GoldDetail.java @@ -26,31 +26,21 @@ public class GoldDetail { @ExcelIgnore private String token; - @ExcelProperty("姓名") private String name; // 名称 - @ExcelProperty("精网号") private Integer jwcode; // 精网号 - @ExcelProperty("所属地区") private String market; // 所属地区 - @ExcelProperty("平台信息") private String payPlatform; // 支付平台 @ExcelIgnore private Integer type; // 类型 - @ExcelProperty("更新类型") private String typeDesc; // 类型描述(用于多语言翻译) - @ExcelProperty("金币数量") private BigDecimal sumGold; // 总金币 - @ExcelProperty("永久金币") private BigDecimal permanentGold; //永久金币 - @ExcelProperty("免费金币") private BigDecimal freeGold; @ExcelIgnore private BigDecimal freeJune; // 免费金币六月到期 @ExcelIgnore private BigDecimal freeDecember; // 免费金币十二月到期 - @ExcelProperty("任务金币") private BigDecimal taskGold; // 任务金币 - @ExcelProperty("提交人") private String adminName; //提交人 @ExcelIgnore @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") @@ -62,7 +52,6 @@ public class GoldDetail { private String sortField; //排序字段 @ExcelIgnore private String sortOrder; //排序顺序 - @ExcelProperty("更新时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") private Date auditTime; @ExcelIgnore 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 048e2f6..f6d8a9e 100644 --- a/src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/coin/ExportExcelServiceImpl.java @@ -662,6 +662,46 @@ public class ExportExcelServiceImpl implements ExportExcelService { writeSheet = EasyExcel.writerSheet("Sheet1") .head(head) .build(); + } + // 如果是金币明细,添加动态表头处理器 + else if ("goldDetail".equals(exportType)) { + Map headers = excelHeaderTranslator.getGoldDetailHeaders(lang); + List columnOrder = excelHeaderTranslator.getGoldDetailColumnOrder(); + + // 构建自定义表头 + List> head = new ArrayList<>(); + for (String fieldName : columnOrder) { + String headerText = headers.get(fieldName); + if (headerText != null) { + List headItems = new ArrayList<>(); + headItems.add(headerText); + head.add(headItems); + } + } + + writeSheet = EasyExcel.writerSheet("Sheet1") + .head(head) + .build(); + } + // 如果是用户表,添加动态表头处理器 + else if ("user".equals(exportType)) { + Map headers = excelHeaderTranslator.getUserHeaders(lang); + List columnOrder = excelHeaderTranslator.getUserColumnOrder(); + + // 构建自定义表头 + List> head = new ArrayList<>(); + for (String fieldName : columnOrder) { + String headerText = headers.get(fieldName); + if (headerText != null) { + List headItems = new ArrayList<>(); + headItems.add(headerText); + head.add(headItems); + } + } + + writeSheet = EasyExcel.writerSheet("Sheet1") + .head(head) + .build(); } else { writeSheet = EasyExcel.writerSheet("Sheet1").build(); } @@ -673,7 +713,6 @@ public class ExportExcelServiceImpl implements ExportExcelService { Integer totalCount = 0; boolean hasMore = true; - // 在 exportExcelGeneric 方法中的适当位置添加类型转换 while (hasMore) { Result pageResult = dataFetcher.apply(page); Integer code = pageResult.getCode(); @@ -753,6 +792,11 @@ public class ExportExcelServiceImpl implements ExportExcelService { translateCashCollectionList((List) list, lang); } + // 添加用户金币余额翻译支持 + if ("goldUser".equals(exportType) && list.get(0) instanceof User) { + translateUserList((List) list, lang); + } + excelWriter.write(list, writeSheet); page.setPageNum(page.getPageNum() + 1); totalCount += list.size(); @@ -1300,4 +1344,19 @@ public class ExportExcelServiceImpl implements ExportExcelService { } } } + + /** + * 翻译用户金币余额列表 + */ + private void translateUserList(List list, String lang) { + if (list == null || list.isEmpty() || "zh_CN".equalsIgnoreCase(lang) || "zh".equalsIgnoreCase(lang)) { + return; + } + for (User item : list) { + // 翻译所属地区名称 + if (item.getMarketName() != null && !item.getMarketName().isEmpty()) { + item.setMarketName(languageTranslationUtil.translate(item.getMarketName(), lang)); + } + } + } } diff --git a/src/main/java/com/example/demo/serviceImpl/coin/GoldDetailServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/coin/GoldDetailServiceImpl.java index 8c5c12e..936f9cf 100644 --- a/src/main/java/com/example/demo/serviceImpl/coin/GoldDetailServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/coin/GoldDetailServiceImpl.java @@ -122,12 +122,13 @@ public class GoldDetailServiceImpl implements GoldDetailService { // 2. 构造完整的 JSON 数据(包含所有请求参数) Map exportData = new HashMap<>(); exportData.put("recordId", recordId); + exportData.put("lang", dto.getLang()); // 添加语言参数 // 手动构造请求数据(避免 toString() 只返回部分字段) - Map headers = new HashMap<>(); Map requestData = new HashMap<>(); requestData.put("token", token); requestData.put("goldDetail", dto.getGoldDetail()); + requestData.put("lang", dto.getLang()); // 添加语言参数 exportData.put("requestData", requestData); // 3. 发送到 Redis 消息队列 @@ -178,11 +179,13 @@ public class GoldDetailServiceImpl implements GoldDetailService { // 2. 构造完整的 JSON 数据(包含所有请求参数) Map exportData = new HashMap<>(); exportData.put("recordId", recordId); + exportData.put("lang", dto.getLang()); // 添加语言参数 // 手动构造请求数据(避免 toString() 只返回部分字段) Map requestData = new HashMap<>(); requestData.put("token", token); requestData.put("user", dto.getUser()); + requestData.put("lang", dto.getLang()); // 添加语言参数 exportData.put("requestData", requestData); // 3. 发送到 Redis 消息队列 @@ -194,7 +197,7 @@ public class GoldDetailServiceImpl implements GoldDetailService { } return Result.success(); } - // 在 GoldDetailServiceImpl.java 中添加以下方法 + /** * 将类型数字转换为中文描述 */