Commit beea186507ca6598d58f163512127ef8883a4425

Authored by YunaiV
1 parent dcf6cc29

全局:增加 VO 数据翻译的支持

Showing 18 changed files with 160 additions and 134 deletions
yudao-dependencies/pom.xml
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 <mybatis-plus-generator.version>3.5.5</mybatis-plus-generator.version> 27 <mybatis-plus-generator.version>3.5.5</mybatis-plus-generator.version>
28 <dynamic-datasource.version>4.3.0</dynamic-datasource.version> 28 <dynamic-datasource.version>4.3.0</dynamic-datasource.version>
29 <mybatis-plus-join.version>1.4.10</mybatis-plus-join.version> 29 <mybatis-plus-join.version>1.4.10</mybatis-plus-join.version>
  30 + <easy-trans.version>2.2.11</easy-trans.version>
30 <redisson.version>3.26.0</redisson.version> 31 <redisson.version>3.26.0</redisson.version>
31 <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version> 32 <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version>
32 <!-- 消息队列 --> 33 <!-- 消息队列 -->
@@ -198,6 +199,32 @@ @@ -198,6 +199,32 @@
198 </dependency> 199 </dependency>
199 200
200 <dependency> 201 <dependency>
  202 + <groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
  203 + <artifactId>easy-trans-spring-boot-starter</artifactId>
  204 + <version>${easy-trans.version}</version>
  205 + <exclusions>
  206 + <exclusion>
  207 + <groupId>org.springframework</groupId>
  208 + <artifactId>spring-context</artifactId>
  209 + </exclusion>
  210 + <exclusion>
  211 + <groupId>org.springframework.cloud</groupId>
  212 + <artifactId>spring-cloud-commons</artifactId>
  213 + </exclusion>
  214 + </exclusions>
  215 + </dependency>
  216 + <dependency>
  217 + <groupId>com.fhs-opensource</groupId>
  218 + <artifactId>easy-trans-mybatis-plus-extend</artifactId>
  219 + <version>${easy-trans.version}</version>
  220 + </dependency>
  221 + <dependency>
  222 + <groupId>com.fhs-opensource</groupId>
  223 + <artifactId>easy-trans-anno</artifactId>
  224 + <version>${easy-trans.version}</version>
  225 + </dependency>
  226 +
  227 + <dependency>
201 <groupId>cn.iocoder.boot</groupId> 228 <groupId>cn.iocoder.boot</groupId>
202 <artifactId>yudao-spring-boot-starter-redis</artifactId> 229 <artifactId>yudao-spring-boot-starter-redis</artifactId>
203 <version>${revision}</version> 230 <version>${revision}</version>
yudao-framework/yudao-common/pom.xml
@@ -137,6 +137,11 @@ @@ -137,6 +137,11 @@
137 <artifactId>transmittable-thread-local</artifactId> 137 <artifactId>transmittable-thread-local</artifactId>
138 </dependency> 138 </dependency>
139 139
  140 + <dependency>
  141 + <groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
  142 + <artifactId>easy-trans-anno</artifactId> <!-- 默认引入的原因,方便 xxx-module-api 包使用 -->
  143 + </dependency>
  144 +
140 <!-- Test 测试相关 --> 145 <!-- Test 测试相关 -->
141 <dependency> 146 <dependency>
142 <groupId>org.springframework.boot</groupId> 147 <groupId>org.springframework.boot</groupId>
yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
@@ -77,6 +77,15 @@ @@ -77,6 +77,15 @@
77 <groupId>com.github.yulichang</groupId> 77 <groupId>com.github.yulichang</groupId>
78 <artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> 78 <artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 -->
79 </dependency> 79 </dependency>
  80 +
  81 + <dependency>
  82 + <groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
  83 + <artifactId>easy-trans-spring-boot-starter</artifactId>
  84 + </dependency>
  85 + <dependency>
  86 + <groupId>com.fhs-opensource</groupId>
  87 + <artifactId>easy-trans-mybatis-plus-extend</artifactId>
  88 + </dependency>
80 </dependencies> 89 </dependencies>
81 90
82 </project> 91 </project>
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject; @@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject;
3 import com.baomidou.mybatisplus.annotation.FieldFill; 3 import com.baomidou.mybatisplus.annotation.FieldFill;
4 import com.baomidou.mybatisplus.annotation.TableField; 4 import com.baomidou.mybatisplus.annotation.TableField;
5 import com.baomidou.mybatisplus.annotation.TableLogic; 5 import com.baomidou.mybatisplus.annotation.TableLogic;
  6 +import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  7 +import com.fhs.core.trans.vo.TransPojo;
6 import lombok.Data; 8 import lombok.Data;
7 import org.apache.ibatis.type.JdbcType; 9 import org.apache.ibatis.type.JdbcType;
8 10
@@ -12,10 +14,14 @@ import java.time.LocalDateTime; @@ -12,10 +14,14 @@ import java.time.LocalDateTime;
12 /** 14 /**
13 * 基础实体对象 15 * 基础实体对象
14 * 16 *
  17 + * 为什么实现 {@link TransPojo} 接口?
  18 + * 因为使用 Easy-Trans TransType.SIMPLE 模式,集成 MyBatis Plus 查询
  19 + *
15 * @author 芋道源码 20 * @author 芋道源码
16 */ 21 */
17 @Data 22 @Data
18 -public abstract class BaseDO implements Serializable { 23 +@JsonIgnoreProperties(value = "transMap") // 由于 Easy-Trans 会添加 transMap 属性,避免 Jackson 在 Spring Cache 反序列化报错
  24 +public abstract class BaseDO implements Serializable, TransPojo {
19 25
20 /** 26 /**
21 * 创建时间 27 * 创建时间
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/package-info.java deleted
1 -package cn.iocoder.yudao.framework;  
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/translate/config/YudaoTranslateAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.translate.config;
  2 +
  3 +import cn.iocoder.yudao.framework.translate.core.TranslateUtils;
  4 +import com.fhs.trans.service.impl.TransService;
  5 +import org.springframework.boot.autoconfigure.AutoConfiguration;
  6 +import org.springframework.context.annotation.Bean;
  7 +
  8 +@AutoConfiguration
  9 +public class YudaoTranslateAutoConfiguration {
  10 +
  11 + @Bean
  12 + @SuppressWarnings({"InstantiationOfUtilityClass", "SpringJavaInjectionPointsAutowiringInspection"})
  13 + public TranslateUtils translateUtils(TransService transService) {
  14 + TranslateUtils.init(transService);
  15 + return new TranslateUtils();
  16 + }
  17 +
  18 +}
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/translate/core/TranslateUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.translate.core;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import com.fhs.core.trans.vo.VO;
  5 +import com.fhs.trans.service.impl.TransService;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * VO 数据翻译 Utils
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public class TranslateUtils {
  15 +
  16 + private static TransService transService;
  17 +
  18 + public static void init(TransService transService) {
  19 + TranslateUtils.transService = transService;
  20 + }
  21 +
  22 + /**
  23 + * 数据翻译
  24 + *
  25 + * 使用场景:无法使用 @TransMethodResult 注解的场景,只能通过手动触发翻译
  26 + *
  27 + * @param data 数据
  28 + * @return 翻译结果
  29 + */
  30 + public static <T extends VO> List<T> translate(List<T> data) {
  31 + if (CollUtil.isNotEmpty((data))) {
  32 + transService.transBatch(data);
  33 + }
  34 + return data;
  35 + }
  36 +
  37 +}
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/translate/package-info.java 0 → 100644
  1 +/**
  2 + * 使用 Easy-Trans 提升使用 VO 数据翻译的开发效率
  3 + */
  4 +package cn.iocoder.yudao.framework.translate;
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1 cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration 1 cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration
2 -cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration  
3 \ No newline at end of file 2 \ No newline at end of file
  3 +cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration
  4 +cn.iocoder.yudao.framework.translate.config.YudaoTranslateAutoConfiguration
4 \ No newline at end of file 5 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java
1 package cn.iocoder.yudao.module.crm.controller.admin.product; 1 package cn.iocoder.yudao.module.crm.controller.admin.product;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;  
8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
10 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  9 +import cn.iocoder.yudao.framework.translate.core.TranslateUtils;
11 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
12 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductRespVO; 11 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductRespVO;
13 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; 12 import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO;
14 -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;  
15 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; 13 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
16 import cn.iocoder.yudao.module.crm.enums.product.CrmProductStatusEnum; 14 import cn.iocoder.yudao.module.crm.enums.product.CrmProductStatusEnum;
17 -import cn.iocoder.yudao.module.crm.service.product.CrmProductCategoryService;  
18 import cn.iocoder.yudao.module.crm.service.product.CrmProductService; 15 import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 16 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
20 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
21 import io.swagger.v3.oas.annotations.Operation; 17 import io.swagger.v3.oas.annotations.Operation;
22 import io.swagger.v3.oas.annotations.Parameter; 18 import io.swagger.v3.oas.annotations.Parameter;
23 import io.swagger.v3.oas.annotations.tags.Tag; 19 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -29,15 +25,11 @@ import org.springframework.validation.annotation.Validated; @@ -29,15 +25,11 @@ import org.springframework.validation.annotation.Validated;
29 import org.springframework.web.bind.annotation.*; 25 import org.springframework.web.bind.annotation.*;
30 26
31 import java.io.IOException; 27 import java.io.IOException;
32 -import java.util.Collections;  
33 import java.util.List; 28 import java.util.List;
34 -import java.util.Map;  
35 -import java.util.stream.Stream;  
36 29
37 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
38 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
39 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 32 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
40 -import static java.util.Collections.singletonList;  
41 33
42 @Tag(name = "管理后台 - CRM 产品") 34 @Tag(name = "管理后台 - CRM 产品")
43 @RestController 35 @RestController
@@ -48,9 +40,6 @@ public class CrmProductController { @@ -48,9 +40,6 @@ public class CrmProductController {
48 @Resource 40 @Resource
49 private CrmProductService productService; 41 private CrmProductService productService;
50 @Resource 42 @Resource
51 - private CrmProductCategoryService productCategoryService;  
52 -  
53 - @Resource  
54 private AdminUserApi adminUserApi; 43 private AdminUserApi adminUserApi;
55 44
56 @PostMapping("/create") 45 @PostMapping("/create")
@@ -83,14 +72,7 @@ public class CrmProductController { @@ -83,14 +72,7 @@ public class CrmProductController {
83 @PreAuthorize("@ss.hasPermission('crm:product:query')") 72 @PreAuthorize("@ss.hasPermission('crm:product:query')")
84 public CommonResult<CrmProductRespVO> getProduct(@RequestParam("id") Long id) { 73 public CommonResult<CrmProductRespVO> getProduct(@RequestParam("id") Long id) {
85 CrmProductDO product = productService.getProduct(id); 74 CrmProductDO product = productService.getProduct(id);
86 - return success(buildProductDetail(product));  
87 - }  
88 -  
89 - private CrmProductRespVO buildProductDetail(CrmProductDO product) {  
90 - if (product == null) {  
91 - return null;  
92 - }  
93 - return buildProductDetailList(singletonList(product)).get(0); 75 + return success(BeanUtils.toBean(product, CrmProductRespVO.class));
94 } 76 }
95 77
96 @GetMapping("/simple-list") 78 @GetMapping("/simple-list")
@@ -106,7 +88,7 @@ public class CrmProductController { @@ -106,7 +88,7 @@ public class CrmProductController {
106 @PreAuthorize("@ss.hasPermission('crm:product:query')") 88 @PreAuthorize("@ss.hasPermission('crm:product:query')")
107 public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) { 89 public CommonResult<PageResult<CrmProductRespVO>> getProductPage(@Valid CrmProductPageReqVO pageVO) {
108 PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO); 90 PageResult<CrmProductDO> pageResult = productService.getProductPage(pageVO);
109 - return success(new PageResult<>(buildProductDetailList(pageResult.getList()), pageResult.getTotal())); 91 + return success(BeanUtils.toBean(pageResult, CrmProductRespVO.class));
110 } 92 }
111 93
112 @GetMapping("/export-excel") 94 @GetMapping("/export-excel")
@@ -119,27 +101,7 @@ public class CrmProductController { @@ -119,27 +101,7 @@ public class CrmProductController {
119 List<CrmProductDO> list = productService.getProductPage(exportReqVO).getList(); 101 List<CrmProductDO> list = productService.getProductPage(exportReqVO).getList();
120 // 导出 Excel 102 // 导出 Excel
121 ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class, 103 ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class,
122 - buildProductDetailList(list));  
123 - }  
124 -  
125 - private List<CrmProductRespVO> buildProductDetailList(List<CrmProductDO> list) {  
126 - if (CollUtil.isEmpty(list)) {  
127 - return Collections.emptyList();  
128 - }  
129 - // 1.1 获得用户信息  
130 - Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(  
131 - convertSetByFlatMap(list, user -> Stream.of(Long.valueOf(user.getCreator()), user.getOwnerUserId())));  
132 - // 1.2 获得分类信息  
133 - Map<Long, CrmProductCategoryDO> categoryMap = productCategoryService.getProductCategoryMap(  
134 - convertSet(list, CrmProductDO::getCategoryId));  
135 - // 2. 拼接数据  
136 - return BeanUtils.toBean(list, CrmProductRespVO.class, productVO -> {  
137 - // 2.1 设置用户信息  
138 - MapUtils.findAndThen(userMap, productVO.getOwnerUserId(), user -> productVO.setOwnerUserName(user.getNickname()));  
139 - MapUtils.findAndThen(userMap, Long.valueOf(productVO.getCreator()), user -> productVO.setCreatorName(user.getNickname()));  
140 - // 2.2 设置分类名称  
141 - MapUtils.findAndThen(categoryMap, productVO.getCategoryId(), category -> productVO.setCategoryName(category.getName()));  
142 - }); 104 + TranslateUtils.translate(BeanUtils.toBean(list, CrmProductRespVO.class)));
143 } 105 }
144 106
145 } 107 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java
@@ -2,9 +2,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product; @@ -2,9 +2,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.product.vo.product;
2 2
3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; 4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO;
5 import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; 6 import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
6 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 7 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
7 import com.alibaba.excel.annotation.ExcelProperty; 8 import com.alibaba.excel.annotation.ExcelProperty;
  9 +import com.fhs.core.trans.anno.Trans;
  10 +import com.fhs.core.trans.constant.TransType;
  11 +import com.fhs.core.trans.vo.VO;
8 import io.swagger.v3.oas.annotations.media.Schema; 12 import io.swagger.v3.oas.annotations.media.Schema;
9 import lombok.Data; 13 import lombok.Data;
10 14
@@ -14,7 +18,7 @@ import java.time.LocalDateTime; @@ -14,7 +18,7 @@ import java.time.LocalDateTime;
14 @Schema(description = "管理后台 - CRM 产品 Response VO") 18 @Schema(description = "管理后台 - CRM 产品 Response VO")
15 @Data 19 @Data
16 @ExcelIgnoreUnannotated 20 @ExcelIgnoreUnannotated
17 -public class CrmProductRespVO { 21 +public class CrmProductRespVO implements VO {
18 22
19 @Schema(description = "产品编号", example = "20529") 23 @Schema(description = "产品编号", example = "20529")
20 @ExcelProperty("产品编号") 24 @ExcelProperty("产品编号")
@@ -43,6 +47,7 @@ public class CrmProductRespVO { @@ -43,6 +47,7 @@ public class CrmProductRespVO {
43 private Integer status; 47 private Integer status;
44 48
45 @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 49 @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  50 + @Trans(type = TransType.SIMPLE, target = CrmProductCategoryDO.class, fields = "name", ref = "categoryName")
46 private Long categoryId; 51 private Long categoryId;
47 @Schema(description = "产品分类名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "衣服") 52 @Schema(description = "产品分类名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "衣服")
48 @ExcelProperty("产品分类") 53 @ExcelProperty("产品分类")
@@ -53,12 +58,16 @@ public class CrmProductRespVO { @@ -53,12 +58,16 @@ public class CrmProductRespVO {
53 private String description; 58 private String description;
54 59
55 @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926") 60 @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31926")
  61 + @Trans(type = TransType.RPC, targetClassName = "cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO",
  62 + fields = "nickname", ref = "ownerUserName")
56 private Long ownerUserId; 63 private Long ownerUserId;
57 @Schema(description = "负责人的用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码") 64 @Schema(description = "负责人的用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
58 @ExcelProperty("负责人") 65 @ExcelProperty("负责人")
59 private String ownerUserName; 66 private String ownerUserName;
60 67
61 @Schema(description = "创建人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 68 @Schema(description = "创建人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  69 + @Trans(type = TransType.RPC, targetClassName = "cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO",
  70 + fields = "nickname", ref = "creatorName")
62 private String creator; 71 private String creator;
63 @Schema(description = "创建人名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码") 72 @Schema(description = "创建人名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
64 @ExcelProperty("创建人") 73 @ExcelProperty("创建人")
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java
1 package cn.iocoder.yudao.module.system.api.logger.dto; 1 package cn.iocoder.yudao.module.system.api.logger.dto;
2 2
  3 +import com.fhs.core.trans.anno.Trans;
  4 +import com.fhs.core.trans.constant.TransType;
  5 +import com.fhs.core.trans.vo.VO;
3 import lombok.Data; 6 import lombok.Data;
4 7
5 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
@@ -10,15 +13,21 @@ import java.time.LocalDateTime; @@ -10,15 +13,21 @@ import java.time.LocalDateTime;
10 * @author HUIHUI 13 * @author HUIHUI
11 */ 14 */
12 @Data 15 @Data
13 -public class OperateLogV2RespDTO { 16 +public class OperateLogV2RespDTO implements VO {
14 17
15 /** 18 /**
  19 + * 日志编号
  20 + */
  21 + private Long id;
  22 + /**
16 * 链路追踪编号 23 * 链路追踪编号
17 */ 24 */
18 private String traceId; 25 private String traceId;
19 /** 26 /**
20 * 用户编号 27 * 用户编号
21 */ 28 */
  29 + @Trans(type = TransType.RPC, targetClassName = "cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO",
  30 + fields = "nickname", ref = "userName")
22 private Long userId; 31 private Long userId;
23 /** 32 /**
24 * 用户名称 33 * 用户名称
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java
@@ -2,24 +2,19 @@ package cn.iocoder.yudao.module.system.api.logger; @@ -2,24 +2,19 @@ package cn.iocoder.yudao.module.system.api.logger;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; 6 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
6 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO; 7 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2CreateReqDTO;
7 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO; 8 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2PageReqDTO;
8 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; 9 import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;
9 -import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert;  
10 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;
11 -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;  
12 import cn.iocoder.yudao.module.system.service.logger.OperateLogService; 11 import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
13 -import cn.iocoder.yudao.module.system.service.user.AdminUserService; 12 +import com.fhs.core.trans.anno.TransMethodResult;
14 import jakarta.annotation.Resource; 13 import jakarta.annotation.Resource;
15 import org.springframework.scheduling.annotation.Async; 14 import org.springframework.scheduling.annotation.Async;
16 import org.springframework.stereotype.Service; 15 import org.springframework.stereotype.Service;
17 import org.springframework.validation.annotation.Validated; 16 import org.springframework.validation.annotation.Validated;
18 17
19 -import java.util.List;  
20 -  
21 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
22 -  
23 /** 18 /**
24 * 操作日志 API 实现类 19 * 操作日志 API 实现类
25 * 20 *
@@ -31,8 +26,6 @@ public class OperateLogApiImpl implements OperateLogApi { @@ -31,8 +26,6 @@ public class OperateLogApiImpl implements OperateLogApi {
31 26
32 @Resource 27 @Resource
33 private OperateLogService operateLogService; 28 private OperateLogService operateLogService;
34 - @Resource  
35 - private AdminUserService adminUserService;  
36 29
37 @Override 30 @Override
38 public void createOperateLog(OperateLogCreateReqDTO createReqDTO) { 31 public void createOperateLog(OperateLogCreateReqDTO createReqDTO) {
@@ -46,16 +39,13 @@ public class OperateLogApiImpl implements OperateLogApi { @@ -46,16 +39,13 @@ public class OperateLogApiImpl implements OperateLogApi {
46 } 39 }
47 40
48 @Override 41 @Override
  42 + @TransMethodResult
49 public PageResult<OperateLogV2RespDTO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO) { 43 public PageResult<OperateLogV2RespDTO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO) {
50 PageResult<OperateLogV2DO> operateLogPage = operateLogService.getOperateLogPage(pageReqVO); 44 PageResult<OperateLogV2DO> operateLogPage = operateLogService.getOperateLogPage(pageReqVO);
51 if (CollUtil.isEmpty(operateLogPage.getList())) { 45 if (CollUtil.isEmpty(operateLogPage.getList())) {
52 return PageResult.empty(); 46 return PageResult.empty();
53 } 47 }
54 -  
55 - // 获取用户  
56 - List<AdminUserDO> userList = adminUserService.getUserList(  
57 - convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId));  
58 - return OperateLogConvert.INSTANCE.convertPage(operateLogPage, userList); 48 + return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class);
59 } 49 }
60 50
61 } 51 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.http
1 -### 请求 /system/operate-log/demo 接口 => 成功  
2 -GET {{baseUrl}}/system/operate-log/demo 1 +### 请求 /system/operate-log/page 接口 => 成功
  2 +GET {{baseUrl}}/system/operate-log/page
3 Authorization: Bearer {{token}} 3 Authorization: Bearer {{token}}
4 tenant-id: {{adminTenentId}} 4 tenant-id: {{adminTenentId}}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java
@@ -3,32 +3,29 @@ package cn.iocoder.yudao.module.system.controller.admin.logger; @@ -3,32 +3,29 @@ package cn.iocoder.yudao.module.system.controller.admin.logger;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  9 +import cn.iocoder.yudao.framework.translate.core.TranslateUtils;
8 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; 10 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
9 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO; 11 import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO;
10 -import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert;  
11 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; 12 import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
12 -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;  
13 import cn.iocoder.yudao.module.system.service.logger.OperateLogService; 13 import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
14 -import cn.iocoder.yudao.module.system.service.user.AdminUserService;  
15 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
16 import io.swagger.v3.oas.annotations.tags.Tag; 15 import io.swagger.v3.oas.annotations.tags.Tag;
  16 +import jakarta.annotation.Resource;
  17 +import jakarta.servlet.http.HttpServletResponse;
  18 +import jakarta.validation.Valid;
17 import org.springframework.security.access.prepost.PreAuthorize; 19 import org.springframework.security.access.prepost.PreAuthorize;
18 import org.springframework.validation.annotation.Validated; 20 import org.springframework.validation.annotation.Validated;
19 import org.springframework.web.bind.annotation.GetMapping; 21 import org.springframework.web.bind.annotation.GetMapping;
20 import org.springframework.web.bind.annotation.RequestMapping; 22 import org.springframework.web.bind.annotation.RequestMapping;
21 import org.springframework.web.bind.annotation.RestController; 23 import org.springframework.web.bind.annotation.RestController;
22 24
23 -import jakarta.annotation.Resource;  
24 -import jakarta.servlet.http.HttpServletResponse;  
25 -import jakarta.validation.Valid;  
26 import java.io.IOException; 25 import java.io.IOException;
27 import java.util.List; 26 import java.util.List;
28 -import java.util.Map;  
29 27
30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
31 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
32 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 29 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
33 30
34 @Tag(name = "管理后台 - 操作日志") 31 @Tag(name = "管理后台 - 操作日志")
@@ -39,19 +36,13 @@ public class OperateLogController { @@ -39,19 +36,13 @@ public class OperateLogController {
39 36
40 @Resource 37 @Resource
41 private OperateLogService operateLogService; 38 private OperateLogService operateLogService;
42 - @Resource  
43 - private AdminUserService userService;  
44 39
45 @GetMapping("/page") 40 @GetMapping("/page")
46 @Operation(summary = "查看操作日志分页列表") 41 @Operation(summary = "查看操作日志分页列表")
47 @PreAuthorize("@ss.hasPermission('system:operate-log:query')") 42 @PreAuthorize("@ss.hasPermission('system:operate-log:query')")
48 public CommonResult<PageResult<OperateLogRespVO>> pageOperateLog(@Valid OperateLogPageReqVO pageReqVO) { 43 public CommonResult<PageResult<OperateLogRespVO>> pageOperateLog(@Valid OperateLogPageReqVO pageReqVO) {
49 PageResult<OperateLogDO> pageResult = operateLogService.getOperateLogPage(pageReqVO); 44 PageResult<OperateLogDO> pageResult = operateLogService.getOperateLogPage(pageReqVO);
50 - // 获得拼接需要的数据  
51 - Map<Long, AdminUserDO> userMap = userService.getUserMap(  
52 - convertList(pageResult.getList(), OperateLogDO::getUserId));  
53 - return success(new PageResult<>(OperateLogConvert.INSTANCE.convertList(pageResult.getList(), userMap),  
54 - pageResult.getTotal())); 45 + return success(BeanUtils.toBean(pageResult, OperateLogRespVO.class));
55 } 46 }
56 47
57 @Operation(summary = "导出操作日志") 48 @Operation(summary = "导出操作日志")
@@ -61,11 +52,8 @@ public class OperateLogController { @@ -61,11 +52,8 @@ public class OperateLogController {
61 public void exportOperateLog(HttpServletResponse response, @Valid OperateLogPageReqVO exportReqVO) throws IOException { 52 public void exportOperateLog(HttpServletResponse response, @Valid OperateLogPageReqVO exportReqVO) throws IOException {
62 exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); 53 exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
63 List<OperateLogDO> list = operateLogService.getOperateLogPage(exportReqVO).getList(); 54 List<OperateLogDO> list = operateLogService.getOperateLogPage(exportReqVO).getList();
64 - // 输出  
65 - Map<Long, AdminUserDO> userMap = userService.getUserMap(  
66 - convertList(list, OperateLogDO::getUserId));  
67 ExcelUtils.write(response, "操作日志.xls", "数据列表", OperateLogRespVO.class, 55 ExcelUtils.write(response, "操作日志.xls", "数据列表", OperateLogRespVO.class,
68 - OperateLogConvert.INSTANCE.convertList(list, userMap)); 56 + TranslateUtils.translate(BeanUtils.toBean(list, OperateLogRespVO.class)));
69 } 57 }
70 58
71 } 59 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java
@@ -2,20 +2,24 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog; @@ -2,20 +2,24 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog;
2 2
3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; 4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
  5 +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
5 import cn.iocoder.yudao.module.system.enums.DictTypeConstants; 6 import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
6 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 7 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
7 import com.alibaba.excel.annotation.ExcelProperty; 8 import com.alibaba.excel.annotation.ExcelProperty;
  9 +import com.fhs.core.trans.anno.Trans;
  10 +import com.fhs.core.trans.constant.TransType;
  11 +import com.fhs.core.trans.vo.VO;
8 import io.swagger.v3.oas.annotations.media.Schema; 12 import io.swagger.v3.oas.annotations.media.Schema;
  13 +import jakarta.validation.constraints.NotEmpty;
9 import lombok.Data; 14 import lombok.Data;
10 15
11 -import jakarta.validation.constraints.NotEmpty;  
12 import java.time.LocalDateTime; 16 import java.time.LocalDateTime;
13 import java.util.Map; 17 import java.util.Map;
14 18
15 @Schema(description = "管理后台 - 操作日志 Response VO") 19 @Schema(description = "管理后台 - 操作日志 Response VO")
16 @Data 20 @Data
17 @ExcelIgnoreUnannotated 21 @ExcelIgnoreUnannotated
18 -public class OperateLogRespVO { 22 +public class OperateLogRespVO implements VO {
19 23
20 @Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 24 @Schema(description = "日志编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
21 @ExcelProperty("日志编号") 25 @ExcelProperty("日志编号")
@@ -25,6 +29,7 @@ public class OperateLogRespVO { @@ -25,6 +29,7 @@ public class OperateLogRespVO {
25 private String traceId; 29 private String traceId;
26 30
27 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") 31 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  32 + @Trans(type = TransType.SIMPLE, target = AdminUserDO.class, fields = "nickname", ref = "userNickname")
28 private Long userId; 33 private Long userId;
29 34
30 @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") 35 @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/logger/OperateLogConvert.java deleted
1 -package cn.iocoder.yudao.module.system.convert.logger;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
5 -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;  
6 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
7 -import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO;  
8 -import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO;  
9 -import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;  
10 -import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO;  
11 -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;  
12 -import org.mapstruct.Mapper;  
13 -import org.mapstruct.factory.Mappers;  
14 -  
15 -import java.util.List;  
16 -import java.util.Map;  
17 -  
18 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
19 -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;  
20 -  
21 -@Mapper  
22 -public interface OperateLogConvert {  
23 -  
24 - OperateLogConvert INSTANCE = Mappers.getMapper(OperateLogConvert.class);  
25 -  
26 - default List<OperateLogRespVO> convertList(List<OperateLogDO> list, Map<Long, AdminUserDO> userMap) {  
27 - return CollectionUtils.convertList(list, log -> {  
28 - OperateLogRespVO logVO = BeanUtils.toBean(log, OperateLogRespVO.class);  
29 - MapUtils.findAndThen(userMap, log.getUserId(), user -> logVO.setUserNickname(user.getNickname()));  
30 - return logVO;  
31 - });  
32 - }  
33 -  
34 - default PageResult<OperateLogV2RespDTO> convertPage(PageResult<OperateLogV2DO> operateLogPage, List<AdminUserDO> userList) {  
35 - return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class).setList(setUserInfo(operateLogPage.getList(), userList));  
36 - }  
37 -  
38 - OperateLogV2RespDTO convert(OperateLogV2DO operateLogV2DO);  
39 -  
40 - default List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) {  
41 - Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId);  
42 - return CollectionUtils.convertList(logList, item -> {  
43 - OperateLogV2RespDTO respDTO = convert(item);  
44 - findAndThen(userMap, item.getUserId(), user -> respDTO.setUserName(user.getNickname()));  
45 - return respDTO;  
46 - });  
47 - }  
48 -  
49 -}  
yudao-server/src/main/resources/application.yaml
@@ -91,6 +91,12 @@ spring: @@ -91,6 +91,12 @@ spring:
91 redis: 91 redis:
92 repositories: 92 repositories:
93 enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度 93 enabled: false # 项目未使用到 Spring Data Redis 的 Repository,所以直接禁用,保证启动速度
  94 +
  95 +# VO 转换(数据翻译)相关
  96 +easy-trans:
  97 + is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口
  98 + is-enable-cloud: false # 禁用 TransType.RPC 微服务模式
  99 +
94 --- #################### 验证码相关配置 #################### 100 --- #################### 验证码相关配置 ####################
95 101
96 aj: 102 aj: