Browse Source

多模块重构 11:修改代码生成器的实现

YunaiV 3 years ago
parent
commit
352a67c530
46 changed files with 766 additions and 315 deletions
  1. 0 9
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/TestDemoController.http
  2. 1 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/package-info.java
  3. 9 9
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoBaseVO.java
  4. 4 4
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoCreateReqVO.java
  5. 0 42
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoExcelVO.java
  6. 9 10
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoExportReqVO.java
  7. 8 12
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoPageReqVO.java
  8. 4 8
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoRespVO.java
  9. 5 8
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoUpdateReqVO.java
  10. 40 46
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/AppTestDemoController.java
  11. 34 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoBaseVO.java
  12. 14 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoCreateReqVO.java
  13. 38 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoExcelVO.java
  14. 38 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoExportReqVO.java
  15. 40 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoPageReqVO.java
  16. 19 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoRespVO.java
  17. 18 0
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoUpdateReqVO.java
  18. 12 10
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/convert/test/TestDemoConvert.java
  19. 3 2
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/dal/dataobject/test/TestDemoDO.java
  20. 47 19
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/dal/mysql/test/TestDemoMapper.java
  21. 13 2
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/enums/codegen/CodegenSceneEnum.java
  22. 31 28
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java
  23. 7 11
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/test/TestDemoService.java
  24. 7 11
      yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/test/TestDemoServiceImpl.java
  25. 19 19
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/controller.vm
  26. 2 2
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/baseVO.vm
  27. 3 3
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/createReqVO.vm
  28. 2 2
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/excelVO.vm
  29. 3 3
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/exportReqVO.vm
  30. 3 3
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/pageReqVO.vm
  31. 3 3
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/respVO.vm
  32. 3 3
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/updateReqVO.vm
  33. 7 7
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/convert/convert.vm
  34. 17 17
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/mapper.vm
  35. 1 0
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/enums/errorcode.vm
  36. 5 5
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/service/service.vm
  37. 5 6
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/service/serviceImpl.vm
  38. 8 8
      yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/test/serviceTest.vm
  39. 1 0
      yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/service/package-info.java
  40. 187 0
      yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/service/test/TestDemoServiceImplTest.java
  41. 39 0
      yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/test/BaseDbUnitTest.java
  42. 47 0
      yudao-module-tool/yudao-module-tool-impl/src/test/resources/application-unit-test.yaml
  43. 4 0
      yudao-module-tool/yudao-module-tool-impl/src/test/resources/logback.xml
  44. 0 0
      yudao-module-tool/yudao-module-tool-impl/src/test/resources/sql/clean.sql
  45. 0 0
      yudao-module-tool/yudao-module-tool-impl/src/test/resources/sql/create_tables.sql
  46. 6 3
      更新日志.md

+ 0 - 9
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/TestDemoController.http

@@ -1,9 +0,0 @@
-### 请求 /tool/test-demo/get 接口 => 成功
-GET {{baseUrl}}/tool/test-demo/get?id=1
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenentId}}
-
-### 请求 /tool/test-demo/list 接口 => 成功
-GET {{baseUrl}}/tool/test-demo/list?ids=1
-Authorization: Bearer {{token}}
-tenant-id: {{adminTenentId}}

+ 1 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.module.tool.controller.admin.test;

+ 9 - 9
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoBaseVO.java

@@ -1,9 +1,9 @@
 package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
 
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-import javax.validation.constraints.NotNull;
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
 
 /**
 * 字典类型 Base VO,提供给添加、修改、详细的子 VO 使用
@@ -12,23 +12,23 @@ import javax.validation.constraints.NotNull;
 @Data
 public class TestDemoBaseVO {
 
-    @ApiModelProperty(value = "名字", required = true, example = "芋道")
+    @ApiModelProperty(value = "名字", required = true)
     @NotNull(message = "名字不能为空")
     private String name;
 
-    @ApiModelProperty(value = "状态", required = true, example = "1")
+    @ApiModelProperty(value = "状态", required = true)
     @NotNull(message = "状态不能为空")
     private Integer status;
 
-    @ApiModelProperty(value = "类型", required = true, example = "2")
+    @ApiModelProperty(value = "类型", required = true)
     @NotNull(message = "类型不能为空")
     private Integer type;
 
-    @ApiModelProperty(value = "分类", required = true, example = "3")
+    @ApiModelProperty(value = "分类", required = true)
     @NotNull(message = "分类不能为空")
     private Integer category;
 
-    @ApiModelProperty(value = "备注", example = "我是备注")
+    @ApiModelProperty(value = "备注")
     private String remark;
 
 }

+ 4 - 4
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoCreateReqVO.java

@@ -1,9 +1,9 @@
 package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
 
-import io.swagger.annotations.ApiModel;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
 
 @ApiModel("管理后台 - 字典类型创建 Request VO")
 @Data

+ 0 - 42
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoExcelVO.java

@@ -1,42 +0,0 @@
-package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import com.alibaba.excel.annotation.ExcelProperty;
-import lombok.Data;
-
-import java.util.Date;
-
-/**
- * 测试示例 Excel VO
- *
- * @author 芋艿
- */
-@Data
-public class TestDemoExcelVO {
-
-    @ExcelProperty("编号")
-    private Long id;
-
-    @ExcelProperty("名字")
-    private String name;
-
-    @ExcelProperty(value = "状态", converter = DictConvert.class)
-    @DictFormat("")
-    private Integer status;
-
-    @ExcelProperty(value = "类型", converter = DictConvert.class)
-    @DictFormat("sys_common_status")
-    private Integer type;
-
-    @ExcelProperty(value = "分类", converter = DictConvert.class)
-    @DictFormat("inf_redis_timeout_type")
-    private Integer category;
-
-    @ExcelProperty("备注")
-    private String remark;
-
-    @ExcelProperty("创建时间")
-    private Date createTime;
-
-}

+ 9 - 10
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoExportReqVO.java

@@ -1,31 +1,30 @@
 package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
 
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import org.springframework.format.annotation.DateTimeFormat;
 
-import java.util.Date;
-
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
 @ApiModel(value = "管理后台 - 字典类型 Excel 导出 Request VO", description = "参数和 TestDemoPageReqVO 是一致的")
 @Data
 public class TestDemoExportReqVO {
 
-    @ApiModelProperty(value = "名字", example = "芋道")
+    @ApiModelProperty(value = "名字")
     private String name;
 
-    @ApiModelProperty(value = "状态", example = "1")
+    @ApiModelProperty(value = "状态")
     private Integer status;
 
-    @ApiModelProperty(value = "类型", example = "2")
+    @ApiModelProperty(value = "类型")
     private Integer type;
 
-    @ApiModelProperty(value = "分类", example = "3")
+    @ApiModelProperty(value = "分类")
     private Integer category;
 
-    @ApiModelProperty(value = "备注", example = "我是备注")
+    @ApiModelProperty(value = "备注")
     private String remark;
 
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

+ 8 - 12
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoPageReqVO.java

@@ -1,15 +1,11 @@
 package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
 
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
 
-import java.util.Date;
-
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
 @ApiModel("管理后台 - 字典类型分页 Request VO")
@@ -18,19 +14,19 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @ToString(callSuper = true)
 public class TestDemoPageReqVO extends PageParam {
 
-    @ApiModelProperty(value = "名字", example = "芋道")
+    @ApiModelProperty(value = "名字")
     private String name;
 
-    @ApiModelProperty(value = "状态", example = "1")
+    @ApiModelProperty(value = "状态")
     private Integer status;
 
-    @ApiModelProperty(value = "类型", example = "2")
+    @ApiModelProperty(value = "类型")
     private Integer type;
 
-    @ApiModelProperty(value = "分类", example = "3")
+    @ApiModelProperty(value = "分类")
     private Integer category;
 
-    @ApiModelProperty(value = "备注", example = "我是备注")
+    @ApiModelProperty(value = "备注")
     private String remark;
 
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

+ 4 - 8
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoRespVO.java

@@ -1,12 +1,8 @@
 package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
 
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.util.Date;
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
 
 @ApiModel("管理后台 - 字典类型 Response VO")
 @Data
@@ -14,7 +10,7 @@ import java.util.Date;
 @ToString(callSuper = true)
 public class TestDemoRespVO extends TestDemoBaseVO {
 
-    @ApiModelProperty(value = "编号", required = true, example = "1")
+    @ApiModelProperty(value = "编号", required = true)
     private Long id;
 
     @ApiModelProperty(value = "创建时间", required = true)

+ 5 - 8
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/vo/TestDemoUpdateReqVO.java

@@ -1,12 +1,9 @@
 package cn.iocoder.yudao.module.tool.controller.admin.test.vo;
 
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import javax.validation.constraints.NotNull;
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
 
 @ApiModel("管理后台 - 字典类型更新 Request VO")
 @Data
@@ -14,7 +11,7 @@ import javax.validation.constraints.NotNull;
 @ToString(callSuper = true)
 public class TestDemoUpdateReqVO extends TestDemoBaseVO {
 
-    @ApiModelProperty(value = "编号", required = true, example = "1")
+    @ApiModelProperty(value = "编号", required = true)
     @NotNull(message = "编号不能为空")
     private Long id;
 

+ 40 - 46
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/admin/test/TestDemoController.java → yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/AppTestDemoController.java

@@ -1,101 +1,95 @@
-package cn.iocoder.yudao.module.tool.controller.admin.test;
+package cn.iocoder.yudao.module.tool.controller.app.test;
 
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.*;
-import cn.iocoder.yudao.module.tool.convert.test.TestDemoConvert;
-import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
-import cn.iocoder.yudao.module.tool.service.test.TestDemoService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiOperation;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-
 import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
+import org.springframework.validation.annotation.Validated;
+
+import io.swagger.annotations.*;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
 import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
 
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
-@Api(tags = "管理后台 - 测试示例")
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.*;
+import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
+import cn.iocoder.yudao.module.tool.convert.test.TestDemoConvert;
+import cn.iocoder.yudao.module.tool.service.test.TestDemoService;
+
+@Api(tags = "用户 APP - 字典类型")
 @RestController
 @RequestMapping("/tool/test-demo")
 @Validated
-public class TestDemoController {
+public class AppTestDemoController {
 
     @Resource
     private TestDemoService testDemoService;
 
     @PostMapping("/create")
-    @ApiOperation("创建测试示例")
-    @PreAuthorize("@ss.hasPermission('tool:test-demo:create')")
-    public CommonResult<Long> createTestDemo(@Valid @RequestBody TestDemoCreateReqVO createReqVO) {
+    @ApiOperation("创建字典类型")
+    public CommonResult<Long> createTestDemo(@Valid @RequestBody AppTestDemoCreateReqVO createReqVO) {
         return success(testDemoService.createTestDemo(createReqVO));
     }
 
     @PutMapping("/update")
-    @ApiOperation("更新测试示例")
-    @PreAuthorize("@ss.hasPermission('tool:test-demo:update')")
-    public CommonResult<Boolean> updateTestDemo(@Valid @RequestBody TestDemoUpdateReqVO updateReqVO) {
+    @ApiOperation("更新字典类型")
+    public CommonResult<Boolean> updateTestDemo(@Valid @RequestBody AppTestDemoUpdateReqVO updateReqVO) {
         testDemoService.updateTestDemo(updateReqVO);
         return success(true);
     }
 
     @DeleteMapping("/delete")
-    @ApiOperation("删除测试示例")
+    @ApiOperation("删除字典类型")
     @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
-    @PreAuthorize("@ss.hasPermission('tool:test-demo:delete')")
     public CommonResult<Boolean> deleteTestDemo(@RequestParam("id") Long id) {
         testDemoService.deleteTestDemo(id);
         return success(true);
     }
 
     @GetMapping("/get")
-    @ApiOperation("获得测试示例")
-    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+    @ApiOperation("获得字典类型")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('tool:test-demo:query')")
-//    @Lock4j // 分布式锁
-    public CommonResult<TestDemoRespVO> getTestDemo(@RequestParam("id") Long id) {
+    public CommonResult<AppTestDemoRespVO> getTestDemo(@RequestParam("id") Long id) {
         TestDemoDO testDemo = testDemoService.getTestDemo(id);
         return success(TestDemoConvert.INSTANCE.convert(testDemo));
     }
 
     @GetMapping("/list")
-    @ApiOperation("获得测试示例列表")
-    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class)
-    @PreAuthorize("@ss.hasPermission('tool:test-demo:query')")
-//    @RateLimiter(name = "backendA")
-    public CommonResult<List<TestDemoRespVO>> getTestDemoList(@RequestParam("ids") Collection<Long> ids) {
+    @ApiOperation("获得字典类型列表")
+    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+    public CommonResult<List<AppTestDemoRespVO>> getTestDemoList(@RequestParam("ids") Collection<Long> ids) {
         List<TestDemoDO> list = testDemoService.getTestDemoList(ids);
         return success(TestDemoConvert.INSTANCE.convertList(list));
     }
 
     @GetMapping("/page")
-    @ApiOperation("获得测试示例分页")
-    @PreAuthorize("@ss.hasPermission('tool:test-demo:query')")
-    public CommonResult<PageResult<TestDemoRespVO>> getTestDemoPage(@Valid TestDemoPageReqVO pageVO) {
+    @ApiOperation("获得字典类型分页")
+    public CommonResult<PageResult<AppTestDemoRespVO>> getTestDemoPage(@Valid AppTestDemoPageReqVO pageVO) {
         PageResult<TestDemoDO> pageResult = testDemoService.getTestDemoPage(pageVO);
         return success(TestDemoConvert.INSTANCE.convertPage(pageResult));
     }
 
     @GetMapping("/export-excel")
-    @ApiOperation("导出测试示例 Excel")
-    @PreAuthorize("@ss.hasPermission('tool:test-demo:export')")
+    @ApiOperation("导出字典类型 Excel")
     @OperateLog(type = EXPORT)
-    public void exportTestDemoExcel(@Valid TestDemoExportReqVO exportReqVO,
+    public void exportTestDemoExcel(@Valid AppTestDemoExportReqVO exportReqVO,
                                     HttpServletResponse response) throws IOException {
         List<TestDemoDO> list = testDemoService.getTestDemoList(exportReqVO);
         // 导出 Excel
-        List<TestDemoExcelVO> datas = TestDemoConvert.INSTANCE.convertList02(list);
-        ExcelUtils.write(response, "测试示例.xls", "数据", TestDemoExcelVO.class, datas);
+        List<AppTestDemoExcelVO> datas = TestDemoConvert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "字典类型.xls", "数据", AppTestDemoExcelVO.class, datas);
     }
 
 }

+ 34 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoBaseVO.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+/**
+* 字典类型 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class AppTestDemoBaseVO {
+
+    @ApiModelProperty(value = "名字", required = true)
+    @NotNull(message = "名字不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "状态", required = true)
+    @NotNull(message = "状态不能为空")
+    private Integer status;
+
+    @ApiModelProperty(value = "类型", required = true)
+    @NotNull(message = "类型不能为空")
+    private Integer type;
+
+    @ApiModelProperty(value = "分类", required = true)
+    @NotNull(message = "分类不能为空")
+    private Integer category;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+}

+ 14 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoCreateReqVO.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("用户 APP - 字典类型创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppTestDemoCreateReqVO extends AppTestDemoBaseVO {
+
+}

+ 38 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoExcelVO.java

@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+
+/**
+ * 字典类型 Excel VO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class AppTestDemoExcelVO {
+
+    @ExcelProperty("编号")
+    private Long id;
+
+    @ExcelProperty("名字")
+    private String name;
+
+    @ExcelProperty("状态")
+    private Integer status;
+
+    @ExcelProperty("类型")
+    private Integer type;
+
+    @ExcelProperty("分类")
+    private Integer category;
+
+    @ExcelProperty("备注")
+    private String remark;
+
+    @ExcelProperty("创建时间")
+    private Date createTime;
+
+}

+ 38 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoExportReqVO.java

@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "用户 APP - 字典类型 Excel 导出 Request VO", description = "参数和 TestDemoPageReqVO 是一致的")
+@Data
+public class AppTestDemoExportReqVO {
+
+    @ApiModelProperty(value = "名字")
+    private String name;
+
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "类型")
+    private Integer type;
+
+    @ApiModelProperty(value = "分类")
+    private Integer category;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 40 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoPageReqVO.java

@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("用户 APP - 字典类型分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppTestDemoPageReqVO extends PageParam {
+
+    @ApiModelProperty(value = "名字")
+    private String name;
+
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "类型")
+    private Integer type;
+
+    @ApiModelProperty(value = "分类")
+    private Integer category;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "开始创建时间")
+    private Date beginCreateTime;
+
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    @ApiModelProperty(value = "结束创建时间")
+    private Date endCreateTime;
+
+}

+ 19 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoRespVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("用户 APP - 字典类型 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppTestDemoRespVO extends AppTestDemoBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true)
+    private Long id;
+
+    @ApiModelProperty(value = "创建时间", required = true)
+    private Date createTime;
+
+}

+ 18 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/controller/app/test/vo/AppTestDemoUpdateReqVO.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.tool.controller.app.test.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("用户 APP - 字典类型更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AppTestDemoUpdateReqVO extends AppTestDemoBaseVO {
+
+    @ApiModelProperty(value = "编号", required = true)
+    @NotNull(message = "编号不能为空")
+    private Long id;
+
+}

+ 12 - 10
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/convert/test/TestDemoConvert.java

@@ -4,29 +4,31 @@ import java.util.*;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoCreateReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoExcelVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoRespVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoUpdateReqVO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.*;
 import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
 
+/**
+ * 字典类型 Convert
+ *
+ * @author 芋道源码
+ */
 @Mapper
 public interface TestDemoConvert {
 
     TestDemoConvert INSTANCE = Mappers.getMapper(TestDemoConvert.class);
 
-    TestDemoDO convert(TestDemoCreateReqVO bean);
+    TestDemoDO convert(AppTestDemoCreateReqVO bean);
 
-    TestDemoDO convert(TestDemoUpdateReqVO bean);
+    TestDemoDO convert(AppTestDemoUpdateReqVO bean);
 
-    TestDemoRespVO convert(TestDemoDO bean);
+    AppTestDemoRespVO convert(TestDemoDO bean);
 
-    List<TestDemoRespVO> convertList(List<TestDemoDO> list);
+    List<AppTestDemoRespVO> convertList(List<TestDemoDO> list);
 
-    PageResult<TestDemoRespVO> convertPage(PageResult<TestDemoDO> page);
+    PageResult<AppTestDemoRespVO> convertPage(PageResult<TestDemoDO> page);
 
-    List<TestDemoExcelVO> convertList02(List<TestDemoDO> list);
+    List<AppTestDemoExcelVO> convertList02(List<TestDemoDO> list);
 
 }

+ 3 - 2
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/dal/dataobject/test/TestDemoDO.java

@@ -1,13 +1,14 @@
 package cn.iocoder.yudao.module.tool.dal.dataobject.test;
 
 import lombok.*;
+import java.util.*;
 import com.baomidou.mybatisplus.annotation.*;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 
 /**
- * 测试示例 DO
+ * 字典类型 DO
  *
- * @author 芋
+ * @author 芋道源码
  */
 @TableName("tool_test_demo")
 @Data

+ 47 - 19
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/dal/mysql/test/TestDemoMapper.java

@@ -3,36 +3,64 @@ package cn.iocoder.yudao.module.tool.dal.mysql.test;
 import java.util.*;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoExportReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoPageReqVO;
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.AppTestDemoExportReqVO;
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.AppTestDemoPageReqVO;
 import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
 import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.tool.controller.admin.test.vo.*;
 
+/**
+ * 字典类型 Mapper
+ *
+ * @author 芋道源码
+ */
 @Mapper
 public interface TestDemoMapper extends BaseMapperX<TestDemoDO> {
 
     default PageResult<TestDemoDO> selectPage(TestDemoPageReqVO reqVO) {
-        return selectPage(reqVO, new QueryWrapperX<TestDemoDO>()
-                .likeIfPresent("name", reqVO.getName())
-                .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("type", reqVO.getType())
-                .eqIfPresent("category", reqVO.getCategory())
-                .eqIfPresent("remark", reqVO.getRemark())
-                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
-                .orderByDesc("id"));
+        return selectPage(reqVO, new LambdaQueryWrapperX<TestDemoDO>()
+                .likeIfPresent(TestDemoDO::getName, reqVO.getName())
+                .eqIfPresent(TestDemoDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(TestDemoDO::getType, reqVO.getType())
+                .eqIfPresent(TestDemoDO::getCategory, reqVO.getCategory())
+                .eqIfPresent(TestDemoDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc(TestDemoDO::getId));
     }
 
     default List<TestDemoDO> selectList(TestDemoExportReqVO reqVO) {
-        return selectList(new QueryWrapperX<TestDemoDO>()
-                .likeIfPresent("name", reqVO.getName())
-                .eqIfPresent("status", reqVO.getStatus())
-                .eqIfPresent("type", reqVO.getType())
-                .eqIfPresent("category", reqVO.getCategory())
-                .eqIfPresent("remark", reqVO.getRemark())
-                .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
-                .orderByDesc("id"));
+        return selectList(new LambdaQueryWrapperX<TestDemoDO>()
+                .likeIfPresent(TestDemoDO::getName, reqVO.getName())
+                .eqIfPresent(TestDemoDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(TestDemoDO::getType, reqVO.getType())
+                .eqIfPresent(TestDemoDO::getCategory, reqVO.getCategory())
+                .eqIfPresent(TestDemoDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc(TestDemoDO::getId));
+    }
+
+    default PageResult<TestDemoDO> selectPage(AppTestDemoPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<TestDemoDO>()
+                .likeIfPresent(TestDemoDO::getName, reqVO.getName())
+                .eqIfPresent(TestDemoDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(TestDemoDO::getType, reqVO.getType())
+                .eqIfPresent(TestDemoDO::getCategory, reqVO.getCategory())
+                .eqIfPresent(TestDemoDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc(TestDemoDO::getId));
+    }
+
+    default List<TestDemoDO> selectList(AppTestDemoExportReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<TestDemoDO>()
+                .likeIfPresent(TestDemoDO::getName, reqVO.getName())
+                .eqIfPresent(TestDemoDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(TestDemoDO::getType, reqVO.getType())
+                .eqIfPresent(TestDemoDO::getCategory, reqVO.getCategory())
+                .eqIfPresent(TestDemoDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(TestDemoDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
+                .orderByDesc(TestDemoDO::getId));
     }
 
 }

+ 13 - 2
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/enums/codegen/CodegenSceneEnum.java

@@ -1,8 +1,11 @@
 package cn.iocoder.yudao.module.tool.enums.codegen;
 
+import cn.hutool.core.util.ArrayUtil;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import static cn.hutool.core.util.ArrayUtil.*;
+
 /**
  * 代码生成的场景枚举
  *
@@ -12,8 +15,8 @@ import lombok.Getter;
 @Getter
 public enum CodegenSceneEnum {
 
-    ADMIN(1, "管理后台", "admin"),
-    APP(2, "用户 APP", "app");
+    ADMIN(1, "管理后台", "admin", ""),
+    APP(2, "用户 APP", "app", "App");
 
     /**
      * 场景
@@ -27,5 +30,13 @@ public enum CodegenSceneEnum {
      * 基础包名
      */
     private final String basePackage;
+    /**
+     * Controller 和 VO 类的前缀
+     */
+    private final String prefixClass;
+
+    public static CodegenSceneEnum valueOf(Integer scene) {
+        return firstMatch(sceneEnum -> sceneEnum.getScene().equals(scene), values());
+    }
 
 }

+ 31 - 28
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java

@@ -9,6 +9,8 @@ import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.tool.enums.codegen.CodegenSceneEnum;
 import cn.iocoder.yudao.module.tool.framework.codegen.config.CodegenProperties;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
@@ -54,22 +56,14 @@ public class CodegenEngine {
      */
     private static final Map<String, String> TEMPLATES = MapUtil.<String, String>builder(new LinkedHashMap<>()) // 有序
             // Java module-impl Main
-            .put(javaTemplatePath("controller/vo/baseVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}BaseVO"))
-            .put(javaTemplatePath("controller/vo/createReqVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}CreateReqVO"))
-            .put(javaTemplatePath("controller/vo/pageReqVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}PageReqVO"))
-            .put(javaTemplatePath("controller/vo/respVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}RespVO"))
-            .put(javaTemplatePath("controller/vo/updateReqVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}UpdateReqVO"))
-            .put(javaTemplatePath("controller/vo/exportReqVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}ExportReqVO"))
-            .put(javaTemplatePath("controller/vo/excelVO"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/vo/${table.className}ExcelVO"))
-            .put(javaTemplatePath("controller/controller"),
-                    javaModuleImplMainFilePath("controller/${table.businessName}/${table.className}Controller"))
+            .put(javaTemplatePath("controller/vo/baseVO"), javaModuleImplVOFilePath("BaseVO"))
+            .put(javaTemplatePath("controller/vo/createReqVO"), javaModuleImplVOFilePath("CreateReqVO"))
+            .put(javaTemplatePath("controller/vo/pageReqVO"), javaModuleImplVOFilePath("PageReqVO"))
+            .put(javaTemplatePath("controller/vo/respVO"), javaModuleImplVOFilePath("RespVO"))
+            .put(javaTemplatePath("controller/vo/updateReqVO"), javaModuleImplVOFilePath("UpdateReqVO"))
+            .put(javaTemplatePath("controller/vo/exportReqVO"), javaModuleImplVOFilePath("ExportReqVO"))
+            .put(javaTemplatePath("controller/vo/excelVO"), javaModuleImplVOFilePath("ExcelVO"))
+            .put(javaTemplatePath("controller/controller"), javaModuleImplControllerFilePath())
             .put(javaTemplatePath("convert/convert"),
                     javaModuleImplMainFilePath("convert/${table.businessName}/${table.className}Convert"))
             .put(javaTemplatePath("dal/do"),
@@ -84,8 +78,7 @@ public class CodegenEngine {
             .put(javaTemplatePath("test/serviceTest"),
                     javaModuleImplTestFilePath("service/${table.businessName}/${table.className}ServiceTest"))
             // Java module-api Main
-            .put(javaTemplatePath("enums/errorcode"),
-                    javaModuleApiMainFilePath("enums/ErrorCodeConstants"))
+            .put(javaTemplatePath("enums/errorcode"), javaModuleApiMainFilePath("enums/ErrorCodeConstants"))
             // Vue
             .put(vueTemplatePath("views/index.vue"),
                     vueFilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
@@ -95,9 +88,6 @@ public class CodegenEngine {
             .put("codegen/sql/sql.vm", "sql/sql.sql")
             .build();
 
-    @Resource
-    private CodegenBuilder codegenBuilder;
-
     @Resource
     private CodegenProperties codegenProperties;
 
@@ -121,8 +111,7 @@ public class CodegenEngine {
     private void initGlobalBindingMap() {
         // 全局配置
         globalBindingMap.put("basePackage", codegenProperties.getBasePackage());
-        globalBindingMap.put("baseFrameworkPackage", StrUtil.subBefore(codegenProperties.getBasePackage(),
-                '.', true) + '.' + "framework"); // 用于后续获取测试类的 package 地址
+        globalBindingMap.put("baseFrameworkPackage", codegenProperties.getBasePackage() + '.' + "framework"); // 用于后续获取测试类的 package 地址
         // 全局 Java Bean
         globalBindingMap.put("CommonResultClassName", CommonResult.class.getName());
         globalBindingMap.put("PageResultClassName", PageResult.class.getName());
@@ -132,7 +121,7 @@ public class CodegenEngine {
         // DO 类,独有字段
         globalBindingMap.put("baseDOFields", CodegenBuilder.BASE_DO_FIELDS);
         globalBindingMap.put("BaseDOClassName", BaseDO.class.getName());
-        globalBindingMap.put("QueryWrapperClassName", QueryWrapperX.class.getName());
+        globalBindingMap.put("QueryWrapperClassName", LambdaQueryWrapperX.class.getName());
         globalBindingMap.put("BaseMapperClassName", BaseMapperX.class.getName());
         // Util 工具类
         globalBindingMap.put("ServiceExceptionUtilClassName", ServiceExceptionUtil.class.getName());
@@ -150,13 +139,15 @@ public class CodegenEngine {
         bindingMap.put("table", table);
         bindingMap.put("columns", columns);
         bindingMap.put("primaryColumn", CollectionUtils.findFirst(columns, CodegenColumnDO::getPrimaryKey)); // 主键字段
+        bindingMap.put("sceneEnum", CodegenSceneEnum.valueOf(table.getScene()));
         // className 相关
-        // 去掉指定前缀  将 TestDictType 转换成 DictType. 因为在 create 等方法后,不需要带上 Test 前缀
+        // 去掉指定前缀将 TestDictType 转换成 DictType. 因为在 create 等方法后,不需要带上 Test 前缀
         String simpleClassName = removePrefix(table.getClassName(), upperFirst(table.getModuleName()));
         bindingMap.put("simpleClassName", simpleClassName);
         bindingMap.put("simpleClassName_underlineCase", toUnderlineCase(simpleClassName)); // 将 DictType 转换成 dict_type
         bindingMap.put("classNameVar", lowerFirst(simpleClassName)); // 将 DictType 转换成 dictType,用于变量
-        String simpleClassNameStrikeCase = toSymbolCase(simpleClassName, '-'); // 将 DictType 转换成 dict-type
+        // 将 DictType 转换成 dict-type
+        String simpleClassNameStrikeCase = toSymbolCase(simpleClassName, '-');
         bindingMap.put("simpleClassName_strikeCase", simpleClassNameStrikeCase);
         // permission 前缀
         bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
@@ -176,7 +167,10 @@ public class CodegenEngine {
                 getStr(bindingMap, "basePackage").replaceAll("\\.", "/"));
         filePath = StrUtil.replace(filePath, "${classNameVar}",
                 getStr(bindingMap, "classNameVar"));
-
+        // sceneEnum 包含的字段
+        CodegenSceneEnum sceneEnum = (CodegenSceneEnum) bindingMap.get("sceneEnum");
+        filePath = StrUtil.replace(filePath, "${sceneEnum.prefixClass}", sceneEnum.getPrefixClass());
+        filePath = StrUtil.replace(filePath, "${sceneEnum.basePackage}", sceneEnum.getBasePackage());
         // table 包含的字段
         CodegenTableDO table = (CodegenTableDO) bindingMap.get("table");
         filePath = StrUtil.replace(filePath, "${table.moduleName}", table.getModuleName());
@@ -189,13 +183,22 @@ public class CodegenEngine {
         return "codegen/java/" + path + ".vm";
     }
 
+    private static String javaModuleImplVOFilePath(String path) {
+        return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
+                "vo/${sceneEnum.prefixClass}${table.className}" + path, "impl", "main");
+    }
+
+    private static String javaModuleImplControllerFilePath() {
+        return javaModuleFilePath("controller/${sceneEnum.basePackage}/${table.businessName}/" +
+                "${sceneEnum.prefixClass}${table.className}Controller", "impl", "main");
+    }
+
     private static String javaModuleImplMainFilePath(String path) {
         return javaModuleFilePath(path, "impl", "main");
     }
 
     private static String javaModuleApiMainFilePath(String path) {
         return javaModuleFilePath(path, "api", "main");
-
     }
 
     private static String javaModuleImplTestFilePath(String path) {

+ 7 - 11
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/test/TestDemoService.java

@@ -2,18 +2,14 @@ package cn.iocoder.yudao.module.tool.service.test;
 
 import java.util.*;
 import javax.validation.*;
-
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoCreateReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoExportReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoPageReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoUpdateReqVO;
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.*;
 import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
 /**
- * 测试示例 Service 接口
+ * 字典类型 Service 接口
  *
- * @author 芋
+ * @author 芋道源码
  */
 public interface TestDemoService {
 
@@ -23,14 +19,14 @@ public interface TestDemoService {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    Long createTestDemo(@Valid TestDemoCreateReqVO createReqVO);
+    Long createTestDemo(@Valid AppTestDemoCreateReqVO createReqVO);
 
     /**
      * 更新字典类型
      *
      * @param updateReqVO 更新信息
      */
-    void updateTestDemo(@Valid TestDemoUpdateReqVO updateReqVO);
+    void updateTestDemo(@Valid AppTestDemoUpdateReqVO updateReqVO);
 
     /**
      * 删除字典类型
@@ -61,7 +57,7 @@ public interface TestDemoService {
      * @param pageReqVO 分页查询
      * @return 字典类型分页
      */
-    PageResult<TestDemoDO> getTestDemoPage(TestDemoPageReqVO pageReqVO);
+    PageResult<TestDemoDO> getTestDemoPage(AppTestDemoPageReqVO pageReqVO);
 
     /**
      * 获得字典类型列表, 用于 Excel 导出
@@ -69,6 +65,6 @@ public interface TestDemoService {
      * @param exportReqVO 查询条件
      * @return 字典类型列表
      */
-    List<TestDemoDO> getTestDemoList(TestDemoExportReqVO exportReqVO);
+    List<TestDemoDO> getTestDemoList(AppTestDemoExportReqVO exportReqVO);
 
 }

+ 7 - 11
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/test/TestDemoServiceImpl.java

@@ -1,15 +1,11 @@
 package cn.iocoder.yudao.module.tool.service.test;
 
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoCreateReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoExportReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoPageReqVO;
-import cn.iocoder.yudao.module.tool.controller.admin.test.vo.TestDemoUpdateReqVO;
 import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.*;
-
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.*;
 import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
@@ -20,9 +16,9 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
 import static cn.iocoder.yudao.module.tool.enums.ErrorCodeConstants.*;
 
 /**
- * 测试示例 Service 实现类
+ * 字典类型 Service 实现类
  *
- * @author 芋
+ * @author 芋道源码
  */
 @Service
 @Validated
@@ -32,7 +28,7 @@ public class TestDemoServiceImpl implements TestDemoService {
     private TestDemoMapper testDemoMapper;
 
     @Override
-    public Long createTestDemo(TestDemoCreateReqVO createReqVO) {
+    public Long createTestDemo(AppTestDemoCreateReqVO createReqVO) {
         // 插入
         TestDemoDO testDemo = TestDemoConvert.INSTANCE.convert(createReqVO);
         testDemoMapper.insert(testDemo);
@@ -41,7 +37,7 @@ public class TestDemoServiceImpl implements TestDemoService {
     }
 
     @Override
-    public void updateTestDemo(TestDemoUpdateReqVO updateReqVO) {
+    public void updateTestDemo(AppTestDemoUpdateReqVO updateReqVO) {
         // 校验存在
         this.validateTestDemoExists(updateReqVO.getId());
         // 更新
@@ -74,12 +70,12 @@ public class TestDemoServiceImpl implements TestDemoService {
     }
 
     @Override
-    public PageResult<TestDemoDO> getTestDemoPage(TestDemoPageReqVO pageReqVO) {
+    public PageResult<TestDemoDO> getTestDemoPage(AppTestDemoPageReqVO pageReqVO) {
         return testDemoMapper.selectPage(pageReqVO);
     }
 
     @Override
-    public List<TestDemoDO> getTestDemoList(TestDemoExportReqVO exportReqVO) {
+    public List<TestDemoDO> getTestDemoList(AppTestDemoExportReqVO exportReqVO) {
         return testDemoMapper.selectList(exportReqVO);
     }
 

+ 19 - 19
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/controller.vm

@@ -1,9 +1,9 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName};
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
 
 import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.security.access.prepost.PreAuthorize;
+#if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end
 
 import io.swagger.annotations.*;
 
@@ -22,32 +22,32 @@ import ${ExcelUtilsClassName};
 import ${OperateLogClassName};
 import static ${OperateTypeEnumClassName}.*;
 
-import ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo.*;
+import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
 import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.${table.className}Service;
 
-@Api(tags = "${table.classComment}")
+@Api(tags = "${sceneEnum.name} - ${table.classComment}")
 @RestController
 ##二级的 businessName 暂时不算在 HTTP 路径上,可以根据需要写
 @RequestMapping("/${table.moduleName}/${simpleClassName_strikeCase}")
 @Validated
-public class ${table.className}Controller {
+public class ${sceneEnum.prefixClass}${table.className}Controller {
 
     @Resource
     private ${table.className}Service ${classNameVar}Service;
 
     @PostMapping("/create")
     @ApiOperation("创建${table.classComment}")
-    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
-    public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${table.className}CreateReqVO createReqVO) {
+#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")#end
+    public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
         return success(${classNameVar}Service.create${simpleClassName}(createReqVO));
     }
 
     @PutMapping("/update")
     @ApiOperation("更新${table.classComment}")
-    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
-    public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${table.className}UpdateReqVO updateReqVO) {
+#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")#end
+    public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
         ${classNameVar}Service.update${simpleClassName}(updateReqVO);
         return success(true);
     }
@@ -55,7 +55,7 @@ public class ${table.className}Controller {
     @DeleteMapping("/delete")
     @ApiOperation("删除${table.classComment}")
     @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = ${primaryColumn.javaType}.class)
-    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
+#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")#end
     public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
         ${classNameVar}Service.delete${simpleClassName}(id);
         return success(true);
@@ -65,7 +65,7 @@ public class ${table.className}Controller {
     @ApiOperation("获得${table.classComment}")
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = ${primaryColumn.javaType}.class)
     @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
-    public CommonResult<${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
+    public CommonResult<${sceneEnum.prefixClass}${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
         ${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
         return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
     }
@@ -73,30 +73,30 @@ public class ${table.className}Controller {
     @GetMapping("/list")
     @ApiOperation("获得${table.classComment}列表")
     @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
-    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
-    public CommonResult<List<${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
+#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
+    public CommonResult<List<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
         List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(ids);
         return success(${table.className}Convert.INSTANCE.convertList(list));
     }
 
     @GetMapping("/page")
     @ApiOperation("获得${table.classComment}分页")
-    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
-    public CommonResult<PageResult<${table.className}RespVO>> get${simpleClassName}Page(@Valid ${table.className}PageReqVO pageVO) {
+#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
+    public CommonResult<PageResult<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageVO) {
         PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(pageVO);
         return success(${table.className}Convert.INSTANCE.convertPage(pageResult));
     }
 
     @GetMapping("/export-excel")
     @ApiOperation("导出${table.classComment} Excel")
-    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")
+#if ($sceneEnum.scene == 1)    @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")#end
     @OperateLog(type = EXPORT)
-    public void export${simpleClassName}Excel(@Valid ${table.className}ExportReqVO exportReqVO,
+    public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO,
               HttpServletResponse response) throws IOException {
         List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(exportReqVO);
         // 导出 Excel
-        List<${table.className}ExcelVO> datas = ${table.className}Convert.INSTANCE.convertList02(list);
-        ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${table.className}ExcelVO.class, datas);
+        List<${sceneEnum.prefixClass}${table.className}ExcelVO> datas = ${table.className}Convert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${sceneEnum.prefixClass}${table.className}ExcelVO.class, datas);
     }
 
 }

+ 2 - 2
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/baseVO.vm

@@ -1,4 +1,4 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
@@ -20,7 +20,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
 */
 @Data
-public class ${table.className}BaseVO {
+public class ${sceneEnum.prefixClass}${table.className}BaseVO {
 
 #foreach ($column in $columns)
 #if (${column.createOperation} && ${column.updateOperation} && ${column.listOperationResult})##通用操作

+ 3 - 3
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/createReqVO.vm

@@ -1,4 +1,4 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
@@ -15,11 +15,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 #end
 #end
 
-@ApiModel("${table.classComment}创建 Request VO")
+@ApiModel("${sceneEnum.name} - ${table.classComment}创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class ${table.className}CreateReqVO extends ${table.className}BaseVO {
+public class ${sceneEnum.prefixClass}${table.className}CreateReqVO extends ${sceneEnum.prefixClass}${table.className}BaseVO {
 
 #foreach ($column in $columns)
 #if (${column.createOperation} && (!${column.updateOperation} || !${column.listOperationResult}))##不是通用字段

+ 2 - 2
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/excelVO.vm

@@ -1,4 +1,4 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
@@ -20,7 +20,7 @@ import ${DictConvertClassName};
  * @author ${table.author}
  */
 @Data
-public class ${table.className}ExcelVO {
+public class ${sceneEnum.prefixClass}${table.className}ExcelVO {
 
 #foreach ($column in $columns)
     #if (${column.listOperationResult})##返回字段

+ 3 - 3
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/exportReqVO.vm

@@ -1,4 +1,4 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
@@ -22,9 +22,9 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
     private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
 #end
 
-@ApiModel(value = "${table.classComment} Excel 导出 Request VO", description = "参数和 ${table.className}PageReqVO 是一致的")
+@ApiModel(value = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO", description = "参数和 ${table.className}PageReqVO 是一致的")
 @Data
-public class ${table.className}ExportReqVO {
+public class ${sceneEnum.prefixClass}${table.className}ExportReqVO {
 
 #foreach ($column in $columns)
 #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写

+ 3 - 3
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/pageReqVO.vm

@@ -1,4 +1,4 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
@@ -22,11 +22,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
     private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
 #end
 
-@ApiModel("${table.classComment}分页 Request VO")
+@ApiModel("${sceneEnum.name} - ${table.classComment}分页 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class ${table.className}PageReqVO extends PageParam {
+public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PageParam {
 
 #foreach ($column in $columns)
 #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写

+ 3 - 3
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/respVO.vm

@@ -1,14 +1,14 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
 import io.swagger.annotations.*;
 
-@ApiModel("${table.classComment} Response VO")
+@ApiModel("${sceneEnum.name} - ${table.classComment} Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class ${table.className}RespVO extends ${table.className}BaseVO {
+public class ${sceneEnum.prefixClass}${table.className}RespVO extends ${sceneEnum.prefixClass}${table.className}BaseVO {
 
 #foreach ($column in $columns)
 #if (${column.listOperationResult} && (!${column.createOperation} || !${column.updateOperation}))##不是通用字段

+ 3 - 3
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/controller/vo/updateReqVO.vm

@@ -1,4 +1,4 @@
-package ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo;
+package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
 
 import lombok.*;
 import java.util.*;
@@ -15,11 +15,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 #end
 #end
 
-@ApiModel("${table.classComment}更新 Request VO")
+@ApiModel("${sceneEnum.name} - ${table.classComment}更新 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class ${table.className}UpdateReqVO extends ${table.className}BaseVO {
+public class ${sceneEnum.prefixClass}${table.className}UpdateReqVO extends ${sceneEnum.prefixClass}${table.className}BaseVO {
 
 #foreach ($column in $columns)
 #if (${column.updateOperation} && (!${column.createOperation} || !${column.listOperationResult}))##不是通用字段

+ 7 - 7
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/convert/convert.vm

@@ -6,7 +6,7 @@ import ${PageResultClassName};
 
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
-import ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo.*;
+import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 
 /**
@@ -19,16 +19,16 @@ public interface ${table.className}Convert {
 
     ${table.className}Convert INSTANCE = Mappers.getMapper(${table.className}Convert.class);
 
-    ${table.className}DO convert(${table.className}CreateReqVO bean);
+    ${table.className}DO convert(${sceneEnum.prefixClass}${table.className}CreateReqVO bean);
 
-    ${table.className}DO convert(${table.className}UpdateReqVO bean);
+    ${table.className}DO convert(${sceneEnum.prefixClass}${table.className}UpdateReqVO bean);
 
-    ${table.className}RespVO convert(${table.className}DO bean);
+    ${sceneEnum.prefixClass}${table.className}RespVO convert(${table.className}DO bean);
 
-    List<${table.className}RespVO> convertList(List<${table.className}DO> list);
+    List<${sceneEnum.prefixClass}${table.className}RespVO> convertList(List<${table.className}DO> list);
 
-    PageResult<${table.className}RespVO> convertPage(PageResult<${table.className}DO> page);
+    PageResult<${sceneEnum.prefixClass}${table.className}RespVO> convertPage(PageResult<${table.className}DO> page);
 
-    List<${table.className}ExcelVO> convertList02(List<${table.className}DO> list);
+    List<${sceneEnum.prefixClass}${table.className}ExcelVO> convertList02(List<${table.className}DO> list);
 
 }

+ 17 - 17
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/mapper.vm

@@ -7,7 +7,7 @@ import ${QueryWrapperClassName};
 import ${BaseMapperClassName};
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import org.apache.ibatis.annotations.Mapper;
-import ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo.*;
+import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 
 ## 字段模板
 #macro(listCondition)
@@ -15,28 +15,28 @@ import ${basePackage}.module.${table.moduleName}.controller.${table.businessName
 #if (${column.listOperation})
 #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
 #if (${column.listOperationCondition} == "=")##情况一,= 的时候
-                .eqIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .eqIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == "!=")##情况二,!= 的时候
-                .neIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .neIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == ">")##情况三,> 的时候
-                .gtIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .gtIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == ">=")##情况四,>= 的时候
-                .geIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .geIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == "<")##情况五,< 的时候
-                .ltIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .ltIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == "<=")##情况五,<= 的时候
-                .leIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .leIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == "LIKE")##情况七,Like 的时候
-                .likeIfPresent("${column.columnName}", reqVO.get${JavaField}())
+                .likeIfPresent(${table.className}DO::get${JavaField}, reqVO.get${JavaField}())
 #end
 #if (${column.listOperationCondition} == "BETWEEN")##情况八,Between 的时候
-                .betweenIfPresent("${column.columnName}", reqVO.getBegin${JavaField}(), reqVO.getEnd${JavaField}())
+                .betweenIfPresent(${table.className}DO::get${JavaField}, reqVO.getBegin${JavaField}(), reqVO.getEnd${JavaField}())
 #end
 #end
 #end
@@ -49,18 +49,18 @@ import ${basePackage}.module.${table.moduleName}.controller.${table.businessName
 @Mapper
 public interface ${table.className}Mapper extends BaseMapperX<${table.className}DO> {
 
-    default PageResult<${table.className}DO> selectPage(${table.className}PageReqVO reqVO) {
-        return selectPage(reqVO, new QueryWrapperX<${table.className}DO>()
+    default PageResult<${table.className}DO> selectPage(${sceneEnum.prefixClass}${table.className}PageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<${table.className}DO>()
 			#listCondition()
-                .orderByDesc("id")## 大多数情况下,id 倒序
-        );
+                .orderByDesc(${table.className}DO::getId));## 大多数情况下,id 倒序
+
     }
 
-    default List<${table.className}DO> selectList(${table.className}ExportReqVO reqVO) {
-        return selectList(new QueryWrapperX<${table.className}DO>()
+    default List<${table.className}DO> selectList(${sceneEnum.prefixClass}${table.className}ExportReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<${table.className}DO>()
 			#listCondition()
-                .orderByDesc("id")## 大多数情况下,id 倒序
-        );
+                .orderByDesc(${table.className}DO::getId));## 大多数情况下,id 倒序
+
     }
 
 }

+ 1 - 0
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/enums/errorcode.vm

@@ -1,2 +1,3 @@
+// TODO 待办:请将下面的错误码复制到 yudao-module-${table.moduleName}-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
 // ========== ${table.classComment} TODO 补充编号 ==========
 ErrorCode ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS = new ErrorCode(TODO 补充编号, "${table.classComment}不存在");

+ 5 - 5
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/service/service.vm

@@ -2,7 +2,7 @@ package ${basePackage}.module.${table.moduleName}.service.${table.businessName};
 
 import java.util.*;
 import javax.validation.*;
-import ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo.*;
+import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import ${PageResultClassName};
 
@@ -19,14 +19,14 @@ public interface ${table.className}Service {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    ${primaryColumn.javaType} create${simpleClassName}(@Valid ${table.className}CreateReqVO createReqVO);
+    ${primaryColumn.javaType} create${simpleClassName}(@Valid ${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO);
 
     /**
      * 更新${table.classComment}
      *
      * @param updateReqVO 更新信息
      */
-    void update${simpleClassName}(@Valid ${table.className}UpdateReqVO updateReqVO);
+    void update${simpleClassName}(@Valid ${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO);
 
     /**
      * 删除${table.classComment}
@@ -57,7 +57,7 @@ public interface ${table.className}Service {
      * @param pageReqVO 分页查询
      * @return ${table.classComment}分页
      */
-    PageResult<${table.className}DO> get${simpleClassName}Page(${table.className}PageReqVO pageReqVO);
+    PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO);
 
     /**
      * 获得${table.classComment}列表, 用于 Excel 导出
@@ -65,6 +65,6 @@ public interface ${table.className}Service {
      * @param exportReqVO 查询条件
      * @return ${table.classComment}列表
      */
-    List<${table.className}DO> get${simpleClassName}List(${table.className}ExportReqVO exportReqVO);
+    List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO);
 
 }

+ 5 - 6
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/service/serviceImpl.vm

@@ -5,13 +5,12 @@ import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.*;
-import ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo.*;
+import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import ${PageResultClassName};
 
 import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
-import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.${table.className}Service;
 
 import static ${ServiceExceptionUtilClassName}.exception;
 import static ${basePackage}.module.${table.moduleName}.enums.ErrorCodeConstants.*;
@@ -29,7 +28,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
     private ${table.className}Mapper ${classNameVar}Mapper;
 
     @Override
-    public ${primaryColumn.javaType} create${simpleClassName}(${table.className}CreateReqVO createReqVO) {
+    public ${primaryColumn.javaType} create${simpleClassName}(${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
         // 插入
         ${table.className}DO ${classNameVar} = ${table.className}Convert.INSTANCE.convert(createReqVO);
         ${classNameVar}Mapper.insert(${classNameVar});
@@ -38,7 +37,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
     }
 
     @Override
-    public void update${simpleClassName}(${table.className}UpdateReqVO updateReqVO) {
+    public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
         // 校验存在
         this.validate${simpleClassName}Exists(updateReqVO.getId());
         // 更新
@@ -71,12 +70,12 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
     }
 
     @Override
-    public PageResult<${table.className}DO> get${simpleClassName}Page(${table.className}PageReqVO pageReqVO) {
+    public PageResult<${table.className}DO> get${simpleClassName}Page(${sceneEnum.prefixClass}${table.className}PageReqVO pageReqVO) {
         return ${classNameVar}Mapper.selectPage(pageReqVO);
     }
 
     @Override
-    public List<${table.className}DO> get${simpleClassName}List(${table.className}ExportReqVO exportReqVO) {
+    public List<${table.className}DO> get${simpleClassName}List(${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO) {
         return ${classNameVar}Mapper.selectList(exportReqVO);
     }
 

+ 8 - 8
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/test/serviceTest.vm

@@ -5,9 +5,9 @@ import org.springframework.boot.test.mock.mockito.MockBean;
 
 import javax.annotation.Resource;
 
-import ${basePackage}.BaseDbUnitTest;
-import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.impl.${table.className}ServiceImpl;
-import ${basePackage}.module.${table.moduleName}.controller.${table.businessName}.vo.*;
+import ${basePackage}.module.${table.moduleName}.test.BaseDbUnitTest;## 每个项目,默认有一个基础 DB Test 基类
+
+import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
 import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
 import ${basePackage}.module.${table.moduleName}.dal.mysql.${table.businessName}.${table.className}Mapper;
 import ${PageResultClassName};
@@ -45,7 +45,7 @@ import static org.mockito.Mockito.*;
        #end
        #end
        // 准备参数
-       ${table.className}${VO} reqVO = new ${table.className}${VO}();
+       ${sceneEnum.prefixClass}${table.className}${VO} reqVO = new ${sceneEnum.prefixClass}${table.className}${VO}();
        #foreach ($column in $columns)
        #if (${column.listOperation})
        #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写
@@ -64,7 +64,7 @@ import static org.mockito.Mockito.*;
 * @author ${table.author}
 */
 @Import(${table.className}ServiceImpl.class)
-public class ${table.className}ServiceTest extends BaseDbUnitTest {
+public class ${table.className}ServiceImplTest extends BaseDbUnitTest {
 
     @Resource
     private ${table.className}ServiceImpl ${classNameVar}Service;
@@ -75,7 +75,7 @@ public class ${table.className}ServiceTest extends BaseDbUnitTest {
     @Test
     public void testCreate${simpleClassName}_success() {
         // 准备参数
-        ${table.className}CreateReqVO reqVO = randomPojo(${table.className}CreateReqVO.class);
+        ${sceneEnum.prefixClass}${table.className}CreateReqVO reqVO = randomPojo(${sceneEnum.prefixClass}${table.className}CreateReqVO.class);
 
         // 调用
         ${primaryColumn.javaType} ${classNameVar}Id = ${classNameVar}Service.create${simpleClassName}(reqVO);
@@ -92,7 +92,7 @@ public class ${table.className}ServiceTest extends BaseDbUnitTest {
         ${table.className}DO db${simpleClassName} = randomPojo(${table.className}DO.class);
         ${classNameVar}Mapper.insert(db${simpleClassName});// @Sql: 先插入出一条存在的数据
         // 准备参数
-        ${table.className}UpdateReqVO reqVO = randomPojo(${table.className}UpdateReqVO.class, o -> {
+        ${sceneEnum.prefixClass}${table.className}UpdateReqVO reqVO = randomPojo(${sceneEnum.prefixClass}${table.className}UpdateReqVO.class, o -> {
             o.setId(db${simpleClassName}.getId()); // 设置更新的 ID
         });
 
@@ -106,7 +106,7 @@ public class ${table.className}ServiceTest extends BaseDbUnitTest {
     @Test
     public void testUpdate${simpleClassName}_notExists() {
         // 准备参数
-        ${table.className}UpdateReqVO reqVO = randomPojo(${table.className}UpdateReqVO.class);
+        ${sceneEnum.prefixClass}${table.className}UpdateReqVO reqVO = randomPojo(${sceneEnum.prefixClass}${table.className}UpdateReqVO.class);
 
         // 调用, 并断言异常
         assertServiceException(() -> ${classNameVar}Service.update${simpleClassName}(reqVO), ${simpleClassName_underlineCase.toUpperCase()}_NOT_EXISTS);

+ 1 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/service/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.module.tool.service;

+ 187 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/service/test/TestDemoServiceImplTest.java

@@ -0,0 +1,187 @@
+package cn.iocoder.yudao.module.tool.service.test;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+import javax.annotation.Resource;
+
+import cn.iocoder.yudao.module.tool.test.BaseDbUnitTest;
+import cn.iocoder.yudao.module.tool.controller.app.test.vo.*;
+import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
+import cn.iocoder.yudao.module.tool.dal.mysql.test.TestDemoMapper;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import javax.annotation.Resource;
+import org.springframework.context.annotation.Import;
+import java.util.*;
+
+import static cn.hutool.core.util.RandomUtil.*;
+import static cn.iocoder.yudao.module.tool.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+/**
+* {@link TestDemoServiceImpl} 的单元测试类
+*
+* @author 芋道源码
+*/
+@Import(TestDemoServiceImpl.class)
+public class TestDemoServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private TestDemoServiceImpl testDemoService;
+
+    @Resource
+    private TestDemoMapper testDemoMapper;
+
+    @Test
+    public void testCreateTestDemo_success() {
+        // 准备参数
+        AppTestDemoCreateReqVO reqVO = randomPojo(AppTestDemoCreateReqVO.class);
+
+        // 调用
+        Long testDemoId = testDemoService.createTestDemo(reqVO);
+        // 断言
+        assertNotNull(testDemoId);
+        // 校验记录的属性是否正确
+        TestDemoDO testDemo = testDemoMapper.selectById(testDemoId);
+        assertPojoEquals(reqVO, testDemo);
+    }
+
+    @Test
+    public void testUpdateTestDemo_success() {
+        // mock 数据
+        TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class);
+        testDemoMapper.insert(dbTestDemo);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        AppTestDemoUpdateReqVO reqVO = randomPojo(AppTestDemoUpdateReqVO.class, o -> {
+            o.setId(dbTestDemo.getId()); // 设置更新的 ID
+        });
+
+        // 调用
+        testDemoService.updateTestDemo(reqVO);
+        // 校验是否更新正确
+        TestDemoDO testDemo = testDemoMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, testDemo);
+    }
+
+    @Test
+    public void testUpdateTestDemo_notExists() {
+        // 准备参数
+        AppTestDemoUpdateReqVO reqVO = randomPojo(AppTestDemoUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> testDemoService.updateTestDemo(reqVO), TEST_DEMO_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteTestDemo_success() {
+        // mock 数据
+        TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class);
+        testDemoMapper.insert(dbTestDemo);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbTestDemo.getId();
+
+        // 调用
+        testDemoService.deleteTestDemo(id);
+       // 校验数据不存在了
+       assertNull(testDemoMapper.selectById(id));
+    }
+
+    @Test
+    public void testDeleteTestDemo_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> testDemoService.deleteTestDemo(id), TEST_DEMO_NOT_EXISTS);
+    }
+
+    @Test // TODO 请修改 null 为需要的值
+    public void testGetTestDemoPage() {
+       // mock 数据
+       TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class, o -> { // 等会查询到
+           o.setName(null);
+           o.setStatus(null);
+           o.setType(null);
+           o.setCategory(null);
+           o.setRemark(null);
+           o.setCreateTime(null);
+       });
+       testDemoMapper.insert(dbTestDemo);
+       // 测试 name 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setName(null)));
+       // 测试 status 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setStatus(null)));
+       // 测试 type 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setType(null)));
+       // 测试 category 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCategory(null)));
+       // 测试 remark 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setRemark(null)));
+       // 测试 createTime 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCreateTime(null)));
+       // 准备参数
+       AppTestDemoPageReqVO reqVO = new AppTestDemoPageReqVO();
+       reqVO.setName(null);
+       reqVO.setStatus(null);
+       reqVO.setType(null);
+       reqVO.setCategory(null);
+       reqVO.setRemark(null);
+       reqVO.setBeginCreateTime(null);
+       reqVO.setEndCreateTime(null);
+
+       // 调用
+       PageResult<TestDemoDO> pageResult = testDemoService.getTestDemoPage(reqVO);
+       // 断言
+       assertEquals(1, pageResult.getTotal());
+       assertEquals(1, pageResult.getList().size());
+       assertPojoEquals(dbTestDemo, pageResult.getList().get(0));
+    }
+
+    @Test // TODO 请修改 null 为需要的值
+    public void testGetTestDemoList() {
+       // mock 数据
+       TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class, o -> { // 等会查询到
+           o.setName(null);
+           o.setStatus(null);
+           o.setType(null);
+           o.setCategory(null);
+           o.setRemark(null);
+           o.setCreateTime(null);
+       });
+       testDemoMapper.insert(dbTestDemo);
+       // 测试 name 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setName(null)));
+       // 测试 status 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setStatus(null)));
+       // 测试 type 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setType(null)));
+       // 测试 category 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCategory(null)));
+       // 测试 remark 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setRemark(null)));
+       // 测试 createTime 不匹配
+       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCreateTime(null)));
+       // 准备参数
+       AppTestDemoExportReqVO reqVO = new AppTestDemoExportReqVO();
+       reqVO.setName(null);
+       reqVO.setStatus(null);
+       reqVO.setType(null);
+       reqVO.setCategory(null);
+       reqVO.setRemark(null);
+       reqVO.setBeginCreateTime(null);
+       reqVO.setEndCreateTime(null);
+
+       // 调用
+       List<TestDemoDO> list = testDemoService.getTestDemoList(reqVO);
+       // 断言
+       assertEquals(1, list.size());
+       assertPojoEquals(dbTestDemo, list.get(0));
+    }
+
+}

+ 39 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/test/BaseDbUnitTest.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.tool.test;
+
+import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
+import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.jdbc.Sql;
+
+/**
+ * 依赖内存 DB 的单元测试
+ *
+ * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
+ *
+ * @author 芋道源码
+ */
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
+@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
+@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
+public class BaseDbUnitTest {
+
+    @Import({
+            // DB 配置类
+            YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
+            DataSourceAutoConfiguration.class, // Spring DB 自动配置类
+            DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
+            DruidDataSourceAutoConfigure.class, // Druid 自动配置类
+            // MyBatis 配置类
+            YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
+            MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
+    })
+    public static class Application {
+    }
+
+}

+ 47 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/resources/application-unit-test.yaml

@@ -0,0 +1,47 @@
+spring:
+  main:
+    lazy-initialization: true # 开启懒加载,加快速度
+    banner-mode: off # 单元测试,禁用 Banner
+
+--- #################### 数据库相关配置 ####################
+
+spring:
+  # 数据源配置项
+  datasource:
+    name: ruoyi-vue-pro
+    url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
+    driver-class-name: org.h2.Driver
+    username: sa
+    password:
+    schema: classpath:sql/create_tables.sql # MySQL 转 H2 的语句,使用 https://www.jooq.org/translate/ 工具
+    druid:
+      async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
+      initial-size: 1 # 单元测试,配置为 1,提升启动速度
+
+  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
+  redis:
+    host: 127.0.0.1 # 地址
+    port: 16379 # 端口(单元测试,使用 16379 端口)
+    database: 0 # 数据库索引
+
+mybatis:
+  lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
+
+--- #################### 定时任务相关配置 ####################
+
+--- #################### 配置中心相关配置 ####################
+
+--- #################### 服务保障相关配置 ####################
+
+# Lock4j 配置项(单元测试,禁用 Lock4j)
+
+# Resilience4j 配置项
+
+--- #################### 监控相关配置 ####################
+
+--- #################### 芋道相关配置 ####################
+
+# 芋道配置项,设置当前项目所有自定义的配置
+yudao:
+  info:
+    base-package: cn.iocoder.yudao.module

+ 4 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/resources/logback.xml

@@ -0,0 +1,4 @@
+<configuration>
+    <!-- 引用 Spring Boot 的 logback 基础配置 -->
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+</configuration>

+ 0 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/resources/sql/clean.sql


+ 0 - 0
yudao-module-tool/yudao-module-tool-impl/src/test/resources/sql/create_tables.sql


+ 6 - 3
更新日志.md

@@ -10,6 +10,10 @@
 * 用户前台的社交登陆
 * 用户前台的修改手机、修改密码、忘记密码
 
+*【优化】操作日志新增用户类型,实现 APP 端的 API 的操作日志的记录
+*【修复】管理后台 UI 超时登录后,返回登陆界面时,由于未登陆加载不到字典数据,导致报错的问题
+
+
 ## [v1.4.0] 计划,预计 2022.02.28 发布
 
 ### ⚠️ Warning
@@ -18,9 +22,9 @@
 
 ### ⭐ New Features
 
-*【优化】操作日志新增用户类型,实现 APP 端的 API 的操作日志的记录
 *【重构】大模块按照多 Maven Module 的方式拆分,提升可维护性,为后续重构 onemall 提供基础
-*【重构】Spring Security 支持读取多种用户类型,从不同的数据库表,从而实现单项目提供管理后台、用户 APP 的不同 RESTful API 接口
+*【新增】Spring Security 支持读取多种用户类型,从不同的数据库表,从而实现单项目提供管理后台、用户 APP 的不同 RESTful API 接口
+*【新增】代码生成器支持多 Maven Module 的方式生成代码,支持管理后台、用户 APP 两种场景的 RESTful API 的生成
 *【重构】将数据库文档调整到 tool 模块,更加明确
 
 ### 🐞 Bug Fixes
@@ -28,7 +32,6 @@
 *【修复】用户无权限访问 指定 API 时,未返回 FORBIDDEN 结果码
 *【修复】定时任务刷新本地缓存时,无租户上线文,导致查询报错
 *【修复】配置中心只加载了删除的配置
-*【修复】管理后台 UI 超时登录后,返回登陆界面时,由于未登陆加载不到字典数据,导致报错的问题
 
 ### 🔨 Dependency Upgrades