소스 검색

更新 融合saas+oauth2
新增 逻辑删除回复基类 RecoverMapper
新增代码生成器

18339543638 2 년 전
부모
커밋
d4ea44c47e
46개의 변경된 파일1131개의 추가작업 그리고 149개의 파일을 삭제
  1. 1 1
      tr-dependencies/pom.xml
  2. 1 1
      tr-framework/src/main/java/cn/tr/core/annotation/TenantIgnore.java
  3. 1 2
      tr-framework/src/main/java/cn/tr/core/exception/TRExcCode.java
  4. 98 0
      tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/core/util/CommonServletUtil.java
  5. 1 2
      tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/basic/entity/CommonPageRequest.java
  6. 3 2
      tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/basic/enums/CommonSortOrderEnum.java
  7. 12 16
      tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/config/controller/GenConfigController.java
  8. 3 3
      tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/config/entity/GenConfig.java
  9. 4 0
      tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/config/mapper/GenConfigMapper.java
  10. 45 0
      tr-modules/tr-module-gen/src/main/resources/backend/AddParam.java.btl
  11. 125 0
      tr-modules/tr-module-gen/src/main/resources/backend/Controller.java.btl
  12. 45 0
      tr-modules/tr-module-gen/src/main/resources/backend/EditParam.java.btl
  13. 53 0
      tr-modules/tr-module-gen/src/main/resources/backend/Entity.java.btl
  14. 34 0
      tr-modules/tr-module-gen/src/main/resources/backend/Enum.java.btl
  15. 35 0
      tr-modules/tr-module-gen/src/main/resources/backend/IdParam.java.btl
  16. 25 0
      tr-modules/tr-module-gen/src/main/resources/backend/Mapper.java.btl
  17. 5 0
      tr-modules/tr-module-gen/src/main/resources/backend/Mapper.xml.btl
  18. 70 0
      tr-modules/tr-module-gen/src/main/resources/backend/PageParam.java.btl
  19. 80 0
      tr-modules/tr-module-gen/src/main/resources/backend/Service.java.btl
  20. 121 0
      tr-modules/tr-module-gen/src/main/resources/backend/ServiceImpl.java.btl
  21. 5 0
      tr-modules/tr-module-system/pom.xml
  22. 0 15
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/constant/OAuth2Constant.java
  23. 4 38
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/OAuth2ServerController.java
  24. 9 24
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/psw/operator/LoginOAuth2PswUserOperator.java
  25. 78 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysUserController.java
  26. 20 3
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserDTO.java
  27. 14 3
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysUserPO.java
  28. 10 3
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysUserRepository.java
  29. 2 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/ISysUserService.java
  30. 20 6
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysUserServiceImpl.java
  31. 13 0
      tr-modules/tr-module-system/src/main/resources/mapper/user/SysUserMapper.xml
  32. 1 0
      tr-plugins/tr-spring-boot-starter-plugin-biz-tenant/src/main/java/cn/tr/plugin/biz/tenant/config/aop/TenantIgnoreAspect.java
  33. 1 2
      tr-plugins/tr-spring-boot-starter-plugin-biz-tenant/src/main/java/cn/tr/plugin/biz/tenant/config/ignore/TenantIgnoreUrlConfig.java
  34. 5 0
      tr-plugins/tr-spring-boot-starter-plugin-doc/pom.xml
  35. 38 0
      tr-plugins/tr-spring-boot-starter-plugin-doc/src/main/java/cn/tr/plugin/doc/ModifyOkStatusCodeResponseMessageReader.java
  36. 11 0
      tr-plugins/tr-spring-boot-starter-plugin-doc/src/main/java/cn/tr/plugin/doc/TrDocAutoConfiguration.java
  37. 15 1
      tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/TrMybatisAutoConfiguration.java
  38. 22 0
      tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/base/RecoverMapper.java
  39. 35 0
      tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/config/logic/PteromysSqlInjector.java
  40. 50 0
      tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/config/logic/RecoverBatch.java
  41. 0 3
      tr-plugins/tr-spring-boot-starter-plugin-satoken/src/main/java/cn/tr/plugin/security/config/LoginUserStrategyConfig.java
  42. 1 7
      tr-plugins/tr-spring-boot-starter-plugin-satoken/src/main/java/cn/tr/plugin/security/config/TrSaTokenWebConfig.java
  43. 3 3
      tr-test/pom.xml
  44. 1 5
      tr-test/src/main/java/cn/tr/test/WebApplication.java
  45. 8 6
      tr-test/src/main/resources/application-doc.yml
  46. 3 1
      tr-test/src/main/resources/application.yml

+ 1 - 1
tr-dependencies/pom.xml

@@ -38,7 +38,7 @@
 
 
         <caffeine.version>2.6.2</caffeine.version>
         <caffeine.version>2.6.2</caffeine.version>
         <!--redission-->
         <!--redission-->
-        <redisson.version>3.19.0</redisson.version>
+        <redisson.version>3.17.7</redisson.version>
 
 
         <!--文件存储-->
         <!--文件存储-->
         <aliyun-oss.version>3.15.0</aliyun-oss.version>
         <aliyun-oss.version>3.15.0</aliyun-oss.version>

+ 1 - 1
tr-plugins/tr-spring-boot-starter-plugin-biz-tenant/src/main/java/cn/tr/plugin/biz/tenant/config/aop/TenantIgnore.java → tr-framework/src/main/java/cn/tr/core/annotation/TenantIgnore.java

@@ -1,4 +1,4 @@
-package cn.tr.plugin.biz.tenant.config.aop;
+package cn.tr.core.annotation;
 
 
 import java.lang.annotation.*;
 import java.lang.annotation.*;
 
 

+ 1 - 2
tr-framework/src/main/java/cn/tr/core/exception/TRExcCode.java

@@ -12,7 +12,7 @@ import lombok.Getter;
 @AllArgsConstructor
 @AllArgsConstructor
 @Getter
 @Getter
 public enum TRExcCode implements BaseCode {
 public enum TRExcCode implements BaseCode {
-    SUCCESS("00000", "成功"),
+        SUCCESS("00000", "成功"),
     USER_ERROR_0001("A0001", "用户端错误"),
     USER_ERROR_0001("A0001", "用户端错误"),
     USER_ERROR_A0100("A0100", "用户注册错误"),
     USER_ERROR_A0100("A0100", "用户注册错误"),
     USER_ERROR_A0101("A0101", "用户未同意隐私协议"),
     USER_ERROR_A0101("A0101", "用户未同意隐私协议"),
@@ -55,7 +55,6 @@ public enum TRExcCode implements BaseCode {
     USER_ERROR_A0242("A0242", "用户未登录"),
     USER_ERROR_A0242("A0242", "用户未登录"),
 
 
     USER_ERROR_A0243("A0243", "OAuth2 认证失败"),
     USER_ERROR_A0243("A0243", "OAuth2 认证失败"),
-    USER_ERROR_A0244("A0244", "用户尚未选择租户信息"),
     /**** 权限 **/
     /**** 权限 **/
     USER_ERROR_A0300("A0300", "访问权限异常"),
     USER_ERROR_A0300("A0300", "访问权限异常"),
     USER_ERROR_A0301("A0301", "访问未授权"),
     USER_ERROR_A0301("A0301", "访问未授权"),

+ 98 - 0
tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/core/util/CommonServletUtil.java

@@ -0,0 +1,98 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package cn.tr.module.gen.core.util;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.tr.core.exception.ServiceException;
+import cn.tr.core.exception.TRExcCode;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * HttpServlet工具类,获取当前request和response
+ *
+ * @author xuyuxiang
+ * @date 2020/3/30 15:09
+ */
+public class CommonServletUtil {
+
+    /**
+     * 从请求中中获取参数
+     *
+     * @author xuyuxiang
+     * @date 2021/10/14 10:44
+     **/
+    public static String getParamFromRequest(String paramName) {
+        HttpServletRequest request = getRequest();
+
+        // 1. 尝试从请求体里面读取
+        String paramValue = request.getParameter(paramName);
+
+        // 2. 尝试从header里读取
+        if (ObjectUtil.isEmpty(paramValue)) {
+            paramValue = request.getHeader(paramName);
+        }
+        // 3. 尝试从cookie里读取
+        if (ObjectUtil.isEmpty(paramValue)) {
+            Cookie[] cookies = request.getCookies();
+            if(ObjectUtil.isNotEmpty(cookies)) {
+                for (Cookie cookie : cookies) {
+                    String cookieName = cookie.getName();
+                    if (cookieName.equals(paramName)) {
+                        return cookie.getValue();
+                    }
+                }
+            }
+        }
+        // 4. 返回
+        return paramValue;
+    }
+
+    public static HttpServletRequest getRequest() {
+        ServletRequestAttributes servletRequestAttributes;
+        try {
+            servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"非Web上下文无法获取Request");
+        }
+        if (servletRequestAttributes == null) {
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"非Web上下文无法获取Request");
+        } else {
+            return servletRequestAttributes.getRequest();
+        }
+    }
+
+    public static HttpServletResponse getResponse() {
+        ServletRequestAttributes servletRequestAttributes;
+        try {
+            servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"非Web上下文无法获取Response");
+        }
+        if (servletRequestAttributes == null) {
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"非Web上下文无法获取Response");
+        } else {
+            return servletRequestAttributes.getResponse();
+        }
+    }
+
+    public static boolean isWeb() {
+        return RequestContextHolder.getRequestAttributes() != null;
+    }
+}

+ 1 - 2
tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/basic/entity/CommonPageRequest.java

@@ -14,10 +14,9 @@ package cn.tr.module.gen.modular.basic.entity;
 
 
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.tr.module.gen.core.util.CommonServletUtil;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import vip.xiaonuo.common.util.CommonServletUtil;
-
 import java.util.List;
 import java.util.List;
 
 
 /**
 /**

+ 3 - 2
tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/basic/enums/CommonSortOrderEnum.java

@@ -12,8 +12,9 @@
  */
  */
 package cn.tr.module.gen.modular.basic.enums;
 package cn.tr.module.gen.modular.basic.enums;
 
 
+import cn.tr.core.exception.ServiceException;
+import cn.tr.core.exception.TRExcCode;
 import lombok.Getter;
 import lombok.Getter;
-import vip.xiaonuo.common.exception.CommonException;
 
 
 /**
 /**
  * 通用排序方式枚举
  * 通用排序方式枚举
@@ -39,7 +40,7 @@ public enum CommonSortOrderEnum {
     public static void validate(String value) {
     public static void validate(String value) {
         boolean flag = ASC.getValue().toLowerCase().equals(value) || DESC.getValue().toLowerCase().equals(value);
         boolean flag = ASC.getValue().toLowerCase().equals(value) || DESC.getValue().toLowerCase().equals(value);
         if(!flag) {
         if(!flag) {
-            throw new CommonException("不支持该排序方式:{}", value);
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("不支持该排序方式:{%s}", value));
         }
         }
     }
     }
 }
 }

+ 12 - 16
tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/config/controller/GenConfigController.java

@@ -12,6 +12,13 @@
  */
  */
 package cn.tr.module.gen.modular.config.controller;
 package cn.tr.module.gen.modular.config.controller;
 
 
+import cn.tr.core.pojo.CommonResult;
+import cn.tr.module.gen.modular.basic.entity.CommonValidList;
+import cn.tr.module.gen.modular.config.entity.GenConfig;
+import cn.tr.module.gen.modular.config.param.GenConfigEditParam;
+import cn.tr.module.gen.modular.config.param.GenConfigIdParam;
+import cn.tr.module.gen.modular.config.param.GenConfigListParam;
+import cn.tr.module.gen.modular.config.service.GenConfigService;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
 import com.github.xiaoymin.knife4j.annotations.ApiSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
@@ -21,14 +28,6 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
-import vip.xiaonuo.common.annotation.CommonLog;
-import vip.xiaonuo.common.pojo.CommonResult;
-import vip.xiaonuo.common.pojo.CommonValidList;
-import vip.xiaonuo.gen.modular.config.entity.GenConfig;
-import vip.xiaonuo.gen.modular.config.param.GenConfigEditParam;
-import vip.xiaonuo.gen.modular.config.param.GenConfigIdParam;
-import vip.xiaonuo.gen.modular.config.param.GenConfigListParam;
-import vip.xiaonuo.gen.modular.config.service.GenConfigService;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.validation.Valid;
 import javax.validation.Valid;
@@ -60,7 +59,7 @@ public class GenConfigController {
     @ApiOperation("获取代码生成详细配置分页")
     @ApiOperation("获取代码生成详细配置分页")
     @GetMapping("/gen/config/list")
     @GetMapping("/gen/config/list")
     public CommonResult<List<GenConfig>> list(GenConfigListParam genConfigListParam) {
     public CommonResult<List<GenConfig>> list(GenConfigListParam genConfigListParam) {
-        return CommonResult.data(genConfigService.list(genConfigListParam));
+        return CommonResult.success(genConfigService.list(genConfigListParam));
     }
     }
 
 
     /**
     /**
@@ -71,11 +70,10 @@ public class GenConfigController {
      */
      */
     @ApiOperationSupport(order = 2)
     @ApiOperationSupport(order = 2)
     @ApiOperation("编辑代码生成详细配置")
     @ApiOperation("编辑代码生成详细配置")
-    @CommonLog("编辑代码生成详细配置")
     @PostMapping("/gen/config/edit")
     @PostMapping("/gen/config/edit")
     public CommonResult<String> edit(@RequestBody @Valid GenConfigEditParam genConfigEditParam) {
     public CommonResult<String> edit(@RequestBody @Valid GenConfigEditParam genConfigEditParam) {
         genConfigService.edit(genConfigEditParam);
         genConfigService.edit(genConfigEditParam);
-        return CommonResult.ok();
+        return CommonResult.success();
     }
     }
 
 
     /**
     /**
@@ -86,12 +84,11 @@ public class GenConfigController {
      */
      */
     @ApiOperationSupport(order = 3)
     @ApiOperationSupport(order = 3)
     @ApiOperation("删除代码生成详细配置")
     @ApiOperation("删除代码生成详细配置")
-    @CommonLog("删除代码生成详细配置")
     @PostMapping("/gen/config/delete")
     @PostMapping("/gen/config/delete")
     public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
     public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
                                                CommonValidList<GenConfigIdParam> genConfigIdParamList) {
                                                CommonValidList<GenConfigIdParam> genConfigIdParamList) {
         genConfigService.delete(genConfigIdParamList);
         genConfigService.delete(genConfigIdParamList);
-        return CommonResult.ok();
+        return CommonResult.success();
     }
     }
 
 
     /**
     /**
@@ -104,7 +101,7 @@ public class GenConfigController {
     @ApiOperation("获取代码生成详细配置详情")
     @ApiOperation("获取代码生成详细配置详情")
     @GetMapping("/gen/config/detail")
     @GetMapping("/gen/config/detail")
     public CommonResult<GenConfig> detail(@Valid GenConfigIdParam genConfigIdParam) {
     public CommonResult<GenConfig> detail(@Valid GenConfigIdParam genConfigIdParam) {
-        return CommonResult.data(genConfigService.detail(genConfigIdParam));
+        return CommonResult.success(genConfigService.detail(genConfigIdParam));
     }
     }
 
 
     /**
     /**
@@ -115,11 +112,10 @@ public class GenConfigController {
      */
      */
     @ApiOperationSupport(order = 5)
     @ApiOperationSupport(order = 5)
     @ApiOperation("批量编辑代码生成详细配置")
     @ApiOperation("批量编辑代码生成详细配置")
-    @CommonLog("批量编辑代码生成详细配置")
     @PostMapping("/gen/config/editBatch")
     @PostMapping("/gen/config/editBatch")
     public CommonResult<String> editBatch(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
     public CommonResult<String> editBatch(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
                                                       CommonValidList<GenConfigEditParam> genConfigEditParamList) {
                                                       CommonValidList<GenConfigEditParam> genConfigEditParamList) {
         genConfigService.editBatch(genConfigEditParamList);
         genConfigService.editBatch(genConfigEditParamList);
-        return CommonResult.ok();
+        return CommonResult.success();
     }
     }
 }
 }

+ 3 - 3
tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/config/entity/GenConfig.java

@@ -12,11 +12,11 @@
  */
  */
 package cn.tr.module.gen.modular.config.entity;
 package cn.tr.module.gen.modular.config.entity;
 
 
+import cn.tr.plugin.mybatis.pojo.BasePO;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.Setter;
-import vip.xiaonuo.common.pojo.CommonEntity;
 
 
 /**
 /**
  * 代码生成详细配置
  * 代码生成详细配置
@@ -26,8 +26,8 @@ import vip.xiaonuo.common.pojo.CommonEntity;
  **/
  **/
 @Getter
 @Getter
 @Setter
 @Setter
-@TableName("GEN_CONFIG")
-public class GenConfig extends CommonEntity {
+@TableName("gen_config")
+public class GenConfig extends BasePO {
 
 
     /** id */
     /** id */
     @ApiModelProperty(value = "id", position = 1)
     @ApiModelProperty(value = "id", position = 1)

+ 4 - 0
tr-modules/tr-module-gen/src/main/java/cn/tr/module/gen/modular/config/mapper/GenConfigMapper.java

@@ -14,6 +14,8 @@ package cn.tr.module.gen.modular.config.mapper;
 
 
 import cn.tr.module.gen.modular.config.entity.GenConfig;
 import cn.tr.module.gen.modular.config.entity.GenConfig;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
 
 
 /**
 /**
  * 代码生成详细配置Mapper接口
  * 代码生成详细配置Mapper接口
@@ -21,5 +23,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @author yubaoshan
  * @author yubaoshan
  * @date 2022/10/25 22:33
  * @date 2022/10/25 22:33
  **/
  **/
+@Mapper
+@Repository
 public interface GenConfigMapper extends BaseMapper<GenConfig> {
 public interface GenConfigMapper extends BaseMapper<GenConfig> {
 }
 }

+ 45 - 0
tr-modules/tr-module-gen/src/main/resources/backend/AddParam.java.btl

@@ -0,0 +1,45 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * ${functionName}添加参数
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Getter
+@Setter
+public class ${className}AddParam {
+
+    <% for(var i = 0; i < configList.~size; i++) { %>
+    <% if(configList[i].needAdd) { %>
+    /** ${configList[i].fieldRemark} */
+    @ApiModelProperty(value = "${configList[i].fieldRemark}",<% if(configList[i].required) { %> required = true,<% } %> position = ${i + 1})
+    <% if(configList[i].required) { %>
+    <% if(configList[i].fieldJavaType == 'String') { %>@NotBlank<% } else { %>@NotNull<% } %>(message = "${configList[i].fieldNameCamelCase}不能为空")
+    <% } else { %><% } %>
+    private ${configList[i].fieldJavaType} ${configList[i].fieldNameCamelCase};
+
+    <% } %>
+    <% } %>
+}

+ 125 - 0
tr-modules/tr-module-gen/src/main/resources/backend/Controller.java.btl

@@ -0,0 +1,125 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import ${packageName}.common.annotation.CommonLog;
+import ${packageName}.common.pojo.CommonResult;
+import ${packageName}.common.pojo.CommonValidList;
+import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}AddParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}EditParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}IdParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}PageParam;
+import ${packageName}.${moduleName}.modular.${busName}.service.${className}Service;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * ${functionName}控制器
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ */
+@Api(tags = "${functionName}控制器")
+@ApiSupport(author = "SNOWY_TEAM", order = 1)
+@RestController
+@Validated
+public class ${className}Controller {
+
+    @Resource
+    private ${className}Service ${classNameFirstLower}Service;
+
+    /**
+     * 获取${functionName}分页
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("获取${functionName}分页")
+    @GetMapping("/${moduleName}/${busName}/page")
+    public CommonResult<Page<${className}>> page(${className}PageParam ${classNameFirstLower}PageParam) {
+        return CommonResult.data(${classNameFirstLower}Service.page(${classNameFirstLower}PageParam));
+    }
+
+    /**
+     * 添加${functionName}
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    @ApiOperationSupport(order = 2)
+    @ApiOperation("添加${functionName}")
+    @CommonLog("添加${functionName}")
+    @PostMapping("/${moduleName}/${busName}/add")
+    public CommonResult<String> add(@RequestBody @Valid ${className}AddParam ${classNameFirstLower}AddParam) {
+        ${classNameFirstLower}Service.add(${classNameFirstLower}AddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑${functionName}
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    @ApiOperationSupport(order = 3)
+    @ApiOperation("编辑${functionName}")
+    @CommonLog("编辑${functionName}")
+    @PostMapping("/${moduleName}/${busName}/edit")
+    public CommonResult<String> edit(@RequestBody @Valid ${className}EditParam ${classNameFirstLower}EditParam) {
+        ${classNameFirstLower}Service.edit(${classNameFirstLower}EditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除${functionName}
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    @ApiOperationSupport(order = 4)
+    @ApiOperation("删除${functionName}")
+    @CommonLog("删除${functionName}")
+    @PostMapping("/${moduleName}/${busName}/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   CommonValidList<${className}IdParam> ${classNameFirstLower}IdParamList) {
+        ${classNameFirstLower}Service.delete(${classNameFirstLower}IdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取${functionName}详情
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    @ApiOperationSupport(order = 5)
+    @ApiOperation("获取${functionName}详情")
+    @GetMapping("/${moduleName}/${busName}/detail")
+    public CommonResult<${className}> detail(@Valid ${className}IdParam ${classNameFirstLower}IdParam) {
+        return CommonResult.data(${classNameFirstLower}Service.detail(${classNameFirstLower}IdParam));
+    }
+}

+ 45 - 0
tr-modules/tr-module-gen/src/main/resources/backend/EditParam.java.btl

@@ -0,0 +1,45 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * ${functionName}编辑参数
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Getter
+@Setter
+public class ${className}EditParam {
+
+    <% for(var i = 0; i < configList.~size; i++) { %>
+    <% if(configList[i].needEdit) { %>
+    /** ${configList[i].fieldRemark} */
+    @ApiModelProperty(value = "${configList[i].fieldRemark}",<% if(configList[i].required) { %> required = true,<% } %> position = ${i + 1})
+    <% if(configList[i].required) { %>
+    <% if(configList[i].fieldJavaType == 'String') { %>@NotBlank<% } else { %>@NotNull<% } %>(message = "${configList[i].fieldNameCamelCase}不能为空")
+    <% } else { %><% } %>
+    private ${configList[i].fieldJavaType} ${configList[i].fieldNameCamelCase};
+
+    <% } %>
+    <% } %>
+}

+ 53 - 0
tr-modules/tr-module-gen/src/main/resources/backend/Entity.java.btl

@@ -0,0 +1,53 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * ${functionName}实体
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Getter
+@Setter
+@TableName("${dbTable}")
+public class ${className} {
+
+    <% for(var i = 0; i < configList.~size; i++) { %>
+    /** ${configList[i].fieldRemark} */
+    <% if(configList[i].needTableId) { %>
+    @TableId
+    <% } else { %><% } %>
+    @ApiModelProperty(value = "${configList[i].fieldRemark}", position = ${i + 1})
+    <% if(configList[i].needAutoInsert) { %>
+    @TableField(fill = FieldFill.INSERT)
+    <% } else { %><% } %>
+    <% if(configList[i].needAutoUpdate) { %>
+    @TableField(fill = FieldFill.UPDATE)
+    <% } else { %><% } %>
+    private ${configList[i].fieldJavaType} ${configList[i].fieldNameCamelCase};
+    <% if(i == configList.~size - 1) { %><% } else { %>
+
+    <% } %>
+    <% } %>
+}

+ 34 - 0
tr-modules/tr-module-gen/src/main/resources/backend/Enum.java.btl

@@ -0,0 +1,34 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.enums;
+
+import lombok.Getter;
+
+/**
+ * ${functionName}枚举
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Getter
+public enum ${className}Enum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    ${className}Enum(String value) {
+        this.value = value;
+    }
+}

+ 35 - 0
tr-modules/tr-module-gen/src/main/resources/backend/IdParam.java.btl

@@ -0,0 +1,35 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * ${functionName}Id参数
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Getter
+@Setter
+public class ${className}IdParam {
+
+    /** ${dbTableKeyRemark} */
+    @ApiModelProperty(value = "${dbTableKeyRemark}", required = true)
+    @NotBlank(message = "${dbTableKeyCamelCase}不能为空")
+    private ${dbTableKeyJavaType} ${dbTableKeyCamelCase};
+}

+ 25 - 0
tr-modules/tr-module-gen/src/main/resources/backend/Mapper.java.btl

@@ -0,0 +1,25 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
+
+/**
+ * ${functionName}Mapper接口
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+public interface ${className}Mapper extends BaseMapper<${className}> {
+}

+ 5 - 0
tr-modules/tr-module-gen/src/main/resources/backend/Mapper.xml.btl

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="${packageName}.${moduleName}.modular.${busName}.mapper.${className}Mapper">
+
+</mapper>

+ 70 - 0
tr-modules/tr-module-gen/src/main/resources/backend/PageParam.java.btl

@@ -0,0 +1,70 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * ${functionName}查询参数
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Getter
+@Setter
+public class ${className}PageParam {
+
+    /** 当前页 */
+    @ApiModelProperty(value = "当前页码")
+    private Integer current;
+
+    /** 每页条数 */
+    @ApiModelProperty(value = "每页条数")
+    private Integer size;
+
+    /** 排序字段 */
+    @ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
+    private String sortField;
+
+    /** 排序方式 */
+    @ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
+    private String sortOrder;
+
+    /** 关键词 */
+    @ApiModelProperty(value = "关键词")
+    private String searchKey;
+
+    <% for(var i = 0; i < configList.~size; i++) { %>
+    <% if(configList[i].needPage) { %>
+    <% if(configList[i].effectType == 'datepicker') { %>
+    /** ${configList[i].fieldRemark}开始 */
+    @ApiModelProperty(value = "${configList[i].fieldRemark}开始")
+    private String start${configList[i].fieldNameCamelCaseFirstUpper};
+
+    /** ${configList[i].fieldRemark}结束 */
+    @ApiModelProperty(value = "${configList[i].fieldRemark}结束")
+    private String end${configList[i].fieldNameCamelCaseFirstUpper};
+
+    <% } else { %>
+    /** ${configList[i].fieldRemark} */
+    @ApiModelProperty(value = "${configList[i].fieldRemark}")
+    private ${configList[i].fieldJavaType} ${configList[i].fieldNameCamelCase};
+
+    <% } %>
+    <% } %>
+    <% } %>
+}

+ 80 - 0
tr-modules/tr-module-gen/src/main/resources/backend/Service.java.btl

@@ -0,0 +1,80 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}AddParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}EditParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}IdParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}PageParam;
+
+import java.util.List;
+
+/**
+ * ${functionName}Service接口
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+public interface ${className}Service extends IService<${className}> {
+
+    /**
+     * 获取${functionName}分页
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    Page<${className}> page(${className}PageParam ${classNameFirstLower}PageParam);
+
+    /**
+     * 添加${functionName}
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    void add(${className}AddParam ${classNameFirstLower}AddParam);
+
+    /**
+     * 编辑${functionName}
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    void edit(${className}EditParam ${classNameFirstLower}EditParam);
+
+    /**
+     * 删除${functionName}
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    void delete(List<${className}IdParam> ${classNameFirstLower}IdParamList);
+
+    /**
+     * 获取${functionName}详情
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     */
+    ${className} detail(${className}IdParam ${classNameFirstLower}IdParam);
+
+    /**
+     * 获取${functionName}详情
+     *
+     * @author ${authorName}
+     * @date ${genTime}
+     **/
+    ${className} queryEntity(String id);
+}

+ 121 - 0
tr-modules/tr-module-gen/src/main/resources/backend/ServiceImpl.java.btl

@@ -0,0 +1,121 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package ${packageName}.${moduleName}.modular.${busName}.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import ${packageName}.common.enums.CommonSortOrderEnum;
+import ${packageName}.common.exception.CommonException;
+import ${packageName}.common.page.CommonPageRequest;
+import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
+import ${packageName}.${moduleName}.modular.${busName}.mapper.${className}Mapper;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}AddParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}EditParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}IdParam;
+import ${packageName}.${moduleName}.modular.${busName}.param.${className}PageParam;
+import ${packageName}.${moduleName}.modular.${busName}.service.${className}Service;
+
+import java.util.List;
+
+/**
+ * ${functionName}Service接口实现类
+ *
+ * @author ${authorName}
+ * @date ${genTime}
+ **/
+@Service
+public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${className}> implements ${className}Service {
+
+    @Override
+    public Page<${className}> page(${className}PageParam ${classNameFirstLower}PageParam) {
+        QueryWrapper<${className}> queryWrapper = new QueryWrapper<>();
+        <% for(var i = 0; i < configList.~size; i++) { %>
+        <% if(configList[i].needPage) { %>
+        <% if(configList[i].effectType == 'datepicker') { %>
+        if(ObjectUtil.isNotEmpty(${classNameFirstLower}PageParam.getStart${configList[i].fieldNameCamelCaseFirstUpper}()) && ObjectUtil.isNotEmpty(${classNameFirstLower}PageParam.getEnd${configList[i].fieldNameCamelCaseFirstUpper}())) {
+            queryWrapper.lambda().between(${className}::get${configList[i].fieldNameCamelCaseFirstUpper}, ${classNameFirstLower}PageParam.getStart${configList[i].fieldNameCamelCaseFirstUpper}(), ${classNameFirstLower}PageParam.getEnd${configList[i].fieldNameCamelCaseFirstUpper}());
+        }
+        <% } else { %>
+        if(ObjectUtil.isNotEmpty(${classNameFirstLower}PageParam.get${configList[i].fieldNameCamelCaseFirstUpper}())) {
+            queryWrapper.lambda().${configList[i].needPageType}(${className}::get${configList[i].fieldNameCamelCaseFirstUpper}, ${classNameFirstLower}PageParam.get${configList[i].fieldNameCamelCaseFirstUpper}());
+        }
+        <% } %>
+        <% } %>
+        <% } %>
+        if(ObjectUtil.isAllNotEmpty(${classNameFirstLower}PageParam.getSortField(), ${classNameFirstLower}PageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(${classNameFirstLower}PageParam.getSortOrder());
+            queryWrapper.orderBy(true, ${classNameFirstLower}PageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(${classNameFirstLower}PageParam.getSortField()));
+        } else {
+            <% if(hasSortCodeField) { %>
+            queryWrapper.lambda().orderByAsc(${className}::getSortCode);
+            <% } else { %>
+            queryWrapper.lambda().orderByAsc(${className}::get${dbTableKeyFirstUpper});
+            <% } %>
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Override
+    public void add(${className}AddParam ${classNameFirstLower}AddParam) {
+        ${className} ${classNameFirstLower} = BeanUtil.toBean(${classNameFirstLower}AddParam, ${className}.class);
+        this.save(${classNameFirstLower});
+    }
+
+    @Override
+    public void edit(${className}EditParam ${classNameFirstLower}EditParam) {
+        <% for(var i = 0; i < configList.~size; i++) { %>
+        <% if(configList[i].needTableId) { %>
+        ${className} ${classNameFirstLower} = this.queryEntity(${classNameFirstLower}EditParam.get${configList[i].fieldNameCamelCaseFirstUpper}());
+        <% } %>
+        <% } %>
+        BeanUtil.copyProperties(${classNameFirstLower}EditParam, ${classNameFirstLower});
+        this.updateById(${classNameFirstLower});
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<${className}IdParam> ${classNameFirstLower}IdParamList) {
+        // 执行删除
+        <% for(var i = 0; i < configList.~size; i++) { %>
+        <% if(configList[i].needTableId) { %>
+        this.removeBatchByIds(CollStreamUtil.toList(${classNameFirstLower}IdParamList, ${className}IdParam::get${configList[i].fieldNameCamelCaseFirstUpper}));
+        <% } %>
+        <% } %>
+    }
+
+    @Override
+    public ${className} detail(${className}IdParam ${classNameFirstLower}IdParam) {
+        <% for(var i = 0; i < configList.~size; i++) { %>
+        <% if(configList[i].needTableId) { %>
+        return this.queryEntity(${classNameFirstLower}IdParam.get${configList[i].fieldNameCamelCaseFirstUpper}());
+        <% } %>
+        <% } %>
+    }
+
+    @Override
+    public ${className} queryEntity(String id) {
+        ${className} ${classNameFirstLower} = this.getById(id);
+        if(ObjectUtil.isEmpty(${classNameFirstLower})) {
+            throw new CommonException("${functionName}不存在,id值为:{}", id);
+        }
+        return ${classNameFirstLower};
+    }
+}

+ 5 - 0
tr-modules/tr-module-system/pom.xml

@@ -28,6 +28,11 @@
             <artifactId>tr-spring-boot-starter-plugin-mybatis</artifactId>
             <artifactId>tr-spring-boot-starter-plugin-mybatis</artifactId>
         </dependency>
         </dependency>
 
 
+        <dependency>
+            <groupId>cn.tr</groupId>
+            <artifactId>tr-spring-boot-starter-plugin-biz-excel</artifactId>
+        </dependency>
+        
         <dependency>
         <dependency>
             <groupId>cn.tr</groupId>
             <groupId>cn.tr</groupId>
             <artifactId>tr-spring-boot-starter-plugin-satoken</artifactId>
             <artifactId>tr-spring-boot-starter-plugin-satoken</artifactId>

+ 0 - 15
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/constant/OAuth2Constant.java

@@ -1,15 +0,0 @@
-package cn.tr.module.sys.oauth2.constant;
-
-/**
- * @Interface : OAuth2Constant
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-
-public interface OAuth2Constant {
-    /**
-     * 当前token所绑定得到租户用户列表
-     */
-    String tenantUsers="Tenant_users";
-}

+ 4 - 38
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/OAuth2ServerController.java

@@ -10,27 +10,19 @@ import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
 import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
 import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
 import cn.dev33.satoken.oauth2.model.SaClientModel;
 import cn.dev33.satoken.oauth2.model.SaClientModel;
 import cn.dev33.satoken.util.SaResult;
 import cn.dev33.satoken.util.SaResult;
-import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.tr.core.exception.ServiceException;
 import cn.tr.core.exception.ServiceException;
 import cn.tr.core.exception.TRExcCode;
 import cn.tr.core.exception.TRExcCode;
 import cn.tr.core.pojo.CommonResult;
 import cn.tr.core.pojo.CommonResult;
-import cn.tr.module.sys.mapper.oauth2.UserLoginInfoMapper;
 import cn.tr.module.sys.oauth2.dto.OAuth2UpdatePswDTO;
 import cn.tr.module.sys.oauth2.dto.OAuth2UpdatePswDTO;
 import cn.tr.module.sys.oauth2.psw.operator.LoginOAuth2PswUserOperator;
 import cn.tr.module.sys.oauth2.psw.operator.LoginOAuth2PswUserOperator;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
-import cn.tr.module.sys.oauth2.constant.OAuth2Constant;
-import cn.tr.module.sys.oauth2.controller.vo.SwitchTenantUserVO;
 import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
 import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
 import cn.tr.module.sys.oauth2.dto.OAuth2RefreshDTO;
 import cn.tr.module.sys.oauth2.dto.OAuth2RefreshDTO;
-import cn.tr.module.sys.user.enums.UserStatusEnum;
-import cn.tr.plugin.security.constant.SecurityConstant;
 import cn.tr.plugin.security.context.LoginUserContextHolder;
 import cn.tr.plugin.security.context.LoginUserContextHolder;
 import cn.tr.plugin.security.utils.SaTokenUtils;
 import cn.tr.plugin.security.utils.SaTokenUtils;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
@@ -108,36 +100,10 @@ public class OAuth2ServerController {
     }
     }
 
 
     @ApiOperationSupport(author = "lf")
     @ApiOperationSupport(author = "lf")
-    @ApiOperation("多租户模式下,获取当前username所对应的所有租户用户列表")
-    @GetMapping("/list/tenant-user")
-    @SaIgnore
-    public CommonResult<List<SwitchTenantUserVO>> tenantUsers(){
-        List<UserLoginInfoBO> infos = SaTokenUtils.getList(OAuth2Constant.tenantUsers, UserLoginInfoBO.class);
-        return CommonResult.success(UserLoginInfoMapper.INSTANCE.toSwtichTenantUserList(infos));
-    }
-
-    @ApiOperationSupport(author = "lf")
-    @ApiOperation("多租户模式下,选择当前username所登陆的租户用户")
-    @GetMapping("/login/{userId}")
-    @SaIgnore
-    public CommonResult<Boolean> switchUser(@ApiParam("租户用户id") @PathVariable("userId") String userId){
-        List<UserLoginInfoBO> infos = SaTokenUtils.getList(OAuth2Constant.tenantUsers, UserLoginInfoBO.class);
-        if(CollectionUtil.isEmpty(infos)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"所选用户不存在,请刷新后重试");
-        }
-        Optional<UserLoginInfoBO> optional = infos.stream()
-                .filter(info -> StrUtil.equals(info.getUserId(), userId))
-                .findFirst();
-        if(!optional.isPresent()){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"所选用户不存在,请刷新后重试");
-        }
-        UserLoginInfoBO loginInfo = optional.get();
-        if(!StrUtil.equals(loginInfo.getStatus(), UserStatusEnum.normal.getValue())){
-            //用户都被禁用
-            throw new ServiceException(TRExcCode.USER_ERROR_A0202);
-        }
-        SaTokenUtils.set(SecurityConstant.LOGIN_USER,loginInfo);
+    @ApiOperation("退出登录")
+    @PostMapping("/logout")
+    public CommonResult<Boolean> logout(){
+        SaTokenUtils.logout();
         return CommonResult.success(true);
         return CommonResult.success(true);
     }
     }
-
 }
 }

+ 9 - 24
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/psw/operator/LoginOAuth2PswUserOperator.java

@@ -2,15 +2,13 @@ package cn.tr.module.sys.oauth2.psw.operator;
 
 
 import cn.dev33.satoken.stp.StpLogic;
 import cn.dev33.satoken.stp.StpLogic;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.tr.core.exception.ServiceException;
 import cn.tr.core.exception.ServiceException;
 import cn.tr.core.exception.TRExcCode;
 import cn.tr.core.exception.TRExcCode;
 import cn.tr.core.strategy.LoginUserStrategy;
 import cn.tr.core.strategy.LoginUserStrategy;
 import cn.tr.core.utils.PswUtils;
 import cn.tr.core.utils.PswUtils;
 import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
 import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
-import cn.tr.module.sys.oauth2.constant.OAuth2Constant;
+import cn.tr.module.sys.user.dto.SysUserDTO;
 import cn.tr.module.sys.user.enums.UserStatusEnum;
 import cn.tr.module.sys.user.enums.UserStatusEnum;
 import cn.tr.module.sys.user.service.ISysUserService;
 import cn.tr.module.sys.user.service.ISysUserService;
 import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
 import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
@@ -18,9 +16,6 @@ import cn.tr.plugin.security.utils.SaTokenUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
-import java.util.List;
-import java.util.stream.Collectors;
-
 /**
 /**
  * @ClassName : LoginOauth2PswUserOperator
  * @ClassName : LoginOauth2PswUserOperator
  * @Description : 默认账号体系登录操作
  * @Description : 默认账号体系登录操作
@@ -37,33 +32,23 @@ public class LoginOAuth2PswUserOperator extends AbstractOAuth2PswUserOperator{
         String psw = source.getPassword();
         String psw = source.getPassword();
         TenantContextHolder.setIgnore(true);
         TenantContextHolder.setIgnore(true);
         //对账号进行校验
         //对账号进行校验
-        List<UserLoginInfoBO> users = sysUserService.findByUsernameWhenLoginNoTenant(username);
-        if(CollectionUtil.isEmpty(users)){
+        SysUserDTO user = sysUserService.selectUserByUsername(username);
+        if(user==null){
             //账户不存在
             //账户不存在
             throw new ServiceException(TRExcCode.USER_ERROR_A0201);
             throw new ServiceException(TRExcCode.USER_ERROR_A0201);
         }
         }
-        //对密码进行校验找到匹配的用户
-        List<UserLoginInfoBO> matchUsers = users.stream()
-                .filter(user -> PswUtils.matchesPassword(psw, user.getPassword()))
-                .collect(Collectors.toList());
-        if(CollectionUtil.isEmpty(matchUsers)){
-            //密码错误
+        //对密码进行校验
+        if(!PswUtils.matchesPassword(psw, user.getPassword())){
             throw new ServiceException(TRExcCode.USER_ERROR_A0210);
             throw new ServiceException(TRExcCode.USER_ERROR_A0210);
         }
         }
-        //查看所有用户是否被禁用
-        List<UserLoginInfoBO> normalUsers = matchUsers.stream()
-                .filter(user -> StrUtil.equals(UserStatusEnum.normal.getValue(), user.getStatus()))
-                .collect(Collectors.toList());
-        if(CollectionUtil.isEmpty(normalUsers)){
+        //查看用户是否被禁用
+        if(!StrUtil.equals(UserStatusEnum.normal.getValue(), user.getStatus())){
             //用户都被禁用
             //用户都被禁用
             throw new ServiceException(TRExcCode.USER_ERROR_A0202);
             throw new ServiceException(TRExcCode.USER_ERROR_A0202);
         }
         }
         StpLogic stpUtil = SaTokenUtils.getStpUtil();
         StpLogic stpUtil = SaTokenUtils.getStpUtil();
-        stpUtil.login(username);
-        //如果只有一个用户,则默认登录该用户,若绑定多个用户,在选择完成用户后进行token的绑定,多租户模式下先使用username进行登录
-        String tokenValue =stpUtil.getTokenValue();
-        SaTokenUtils.setList(OAuth2Constant.tenantUsers,matchUsers);
-        return tokenValue;
+        stpUtil.login(user.getUserId());
+        return stpUtil.getTokenValue();
     }
     }
 
 
     @Override
     @Override

+ 78 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysUserController.java

@@ -0,0 +1,78 @@
+package cn.tr.module.sys.user.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.tr.core.pojo.CommonResult;
+import cn.tr.core.pojo.TableDataInfo;
+import cn.tr.core.validation.Insert;
+import cn.tr.core.validation.Update;
+import cn.tr.module.sys.user.dto.SysUserDTO;
+import cn.tr.module.sys.user.dto.SysUserQueryDTO;
+import cn.tr.module.sys.user.service.ISysUserService;
+import cn.tr.plugin.mybatis.base.BaseController;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+
+/**
+ * @ClassName : SysUserController
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年03月24日
+ */
+@RestController
+@RequestMapping("/sys/user")
+@Api(tags = "用户")
+@AllArgsConstructor
+public class SysUserController extends BaseController {
+    private final ISysUserService userService;
+
+    @PostMapping("/query/page")
+    @ApiOperationSupport(author = "lf")
+    @ApiOperation(value = "根据条件查询用户",notes = "权限: sys:user:query")
+    @SaCheckPermission("sys:user:query")
+    public TableDataInfo<SysUserDTO> selectList(@RequestBody SysUserQueryDTO query){
+        startPage();
+        return getDataTable(userService.selectSysUserList(query));
+    }
+
+    @GetMapping("/detail/{id}")
+    @ApiOperationSupport(author = "lf")
+    @ApiOperation(value = "根据id查询用户",notes = "权限: sys:user:query")
+    @SaCheckPermission("sys:user:query")
+    public CommonResult<SysUserDTO> findById(@PathVariable("id") String id){
+        return CommonResult.success(userService.selectSysUserById(id));
+    }
+
+    @PostMapping("/edit")
+    @ApiOperationSupport(author = "lf")
+    @SaCheckPermission("sys:user:edit")
+    @ApiOperation(value = "根据id更新用户",notes = "权限: sys:user:edit")
+    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysUserDTO source){
+        return CommonResult.success(userService.updateSysUserById(source));
+    }
+
+    @PostMapping("/add")
+    @ApiOperationSupport(author = "lf")
+    @SaCheckPermission("sys:user:add")
+    @ApiOperation(value = "新增用户",notes = "权限: sys:user:add")
+    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysUserDTO source){
+        return CommonResult.success(userService.insertSysUser(source));
+    }
+    
+    @PostMapping("/deleteByIds")
+    @ApiOperationSupport(author = "lf")
+    @ApiOperation(value = "删除用户",notes = "权限: sys:user:del")
+    @SaCheckPermission("sys:user:del")
+    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
+        return CommonResult.success(userService.deleteSysUserByIds(ids));
+    }
+    
+
+    //todo 导出
+
+}

+ 20 - 3
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserDTO.java

@@ -1,8 +1,9 @@
 package cn.tr.module.sys.user.dto;
 package cn.tr.module.sys.user.dto;
 
 
+import cn.hutool.core.date.DatePattern;
+import cn.tr.plugin.excel.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import lombok.Data;
 import lombok.Data;
-
-import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.Date;
 
 
 /**
 /**
@@ -21,16 +22,25 @@ public class SysUserDTO {
     /**
     /**
      * 用户名
      * 用户名
      */
      */
+    @Excel(name = "用户名")
     private String username;
     private String username;
 
 
     /**
     /**
      * 昵称
      * 昵称
      */
      */
+    @Excel(name = "昵称")
     private String nickname;
     private String nickname;
 
 
+    /**
+     * 密码
+     */
+    @JsonIgnoreProperties(allowSetters = true)
+    private String password;
+
     /**
     /**
      * 性别
      * 性别
      */
      */
+    @Excel(name = "性别",dictCode = "gender")
     private String gender;
     private String gender;
 
 
     /**
     /**
@@ -41,16 +51,19 @@ public class SysUserDTO {
     /**
     /**
      * 手机号
      * 手机号
      */
      */
+    @Excel(name = "手机号")
     private String phone;
     private String phone;
 
 
     /**
     /**
      * 邮箱地址
      * 邮箱地址
      */
      */
+    @Excel(name = "邮箱")
     private String email;
     private String email;
 
 
     /**
     /**
      * 出生日期
      * 出生日期
      */
      */
+    @Excel(name = "出生日期",dateFormat = DatePattern.CHINESE_DATE_TIME_PATTERN)
     private Date birthday;
     private Date birthday;
 
 
     /**
     /**
@@ -61,6 +74,7 @@ public class SysUserDTO {
     /**
     /**
      * 用户头像
      * 用户头像
      */
      */
+    @Excel(name = "用户头像")
     private String avatar;
     private String avatar;
 
 
     /**
     /**
@@ -71,16 +85,19 @@ public class SysUserDTO {
     /**
     /**
      * 最后登录IP
      * 最后登录IP
      */
      */
+    @Excel(name = "最后登录IP")
     private String loginIp;
     private String loginIp;
 
 
     /**
     /**
      * 最后登录时间
      * 最后登录时间
      */
      */
-    private LocalDateTime loginDate;
+    @Excel(name = "最后登录时间",dateFormat = DatePattern.CHINESE_DATE_TIME_PATTERN)
+    private Date loginDate;
 
 
     /**
     /**
      * 备注
      * 备注
      */
      */
+    @Excel(name = "备注")
     private String remark;
     private String remark;
 
 
 }
 }

+ 14 - 3
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysUserPO.java

@@ -1,12 +1,13 @@
 package cn.tr.module.sys.user.po;
 package cn.tr.module.sys.user.po;
 
 
+import cn.tr.core.annotation.ColumnDefaultValue;
+import cn.tr.core.annotation.Comment;
 import cn.tr.module.sys.user.enums.UserStatusEnum;
 import cn.tr.module.sys.user.enums.UserStatusEnum;
-import cn.tr.plugin.mybatis.pojo.BasePO;
 import cn.tr.plugin.mybatis.pojo.TenantPO;
 import cn.tr.plugin.mybatis.pojo.TenantPO;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.*;
 import com.gitee.sunchenbin.mybatis.actable.annotation.ColumnComment;
 import com.gitee.sunchenbin.mybatis.actable.annotation.ColumnComment;
 import lombok.Data;
 import lombok.Data;
+import org.apache.ibatis.type.JdbcType;
 
 
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.Date;
@@ -25,6 +26,7 @@ public class SysUserPO extends TenantPO {
     private String userId;
     private String userId;
 
 
     @ColumnComment("用户名")
     @ColumnComment("用户名")
+    @TableField(updateStrategy = FieldStrategy.NEVER)
     private String username;
     private String username;
 
 
     /**
     /**
@@ -73,4 +75,13 @@ public class SysUserPO extends TenantPO {
     @ColumnComment("备注")
     @ColumnComment("备注")
     private String remark;
     private String remark;
 
 
+        /**
+     * 是否删除
+     */
+    @Comment("删除标记")
+    @ColumnDefaultValue("0")
+    @TableLogic
+    @TableField(jdbcType = JdbcType.TINYINT)
+    private Boolean deleted;
+
 }
 }

+ 10 - 3
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysUserRepository.java

@@ -1,10 +1,10 @@
 package cn.tr.module.sys.user.repository;
 package cn.tr.module.sys.user.repository;
 
 
 import cn.tr.module.sys.user.po.SysUserPO;
 import cn.tr.module.sys.user.po.SysUserPO;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import cn.tr.plugin.mybatis.base.RecoverMapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 import org.springframework.stereotype.Repository;
-
 /**
 /**
  * @ClassName : SysUserRepository
  * @ClassName : SysUserRepository
  * @Description :
  * @Description :
@@ -13,5 +13,12 @@ import org.springframework.stereotype.Repository;
  */
  */
 @Mapper
 @Mapper
 @Repository
 @Repository
-public interface SysUserRepository extends BaseMapper<SysUserPO> {
+public interface SysUserRepository extends RecoverMapper<SysUserPO> {
+
+    /**
+     * 无视逻辑删除进行查询
+     * @param username 用户名
+     * @return
+     */
+    SysUserPO selectUserIgnoreDelByUsername(@Param("username") String username);
 }
 }

+ 2 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/ISysUserService.java

@@ -34,11 +34,11 @@ public interface ISysUserService {
     boolean updateSysUserById(SysUserDTO source);
     boolean updateSysUserById(SysUserDTO source);
 
 
     /**
     /**
-     * 无租户登录时根据用户名查询用户
+     * 根据用户名查询
      * @param username 用户名
      * @param username 用户名
      * @return
      * @return
      */
      */
-    List<UserLoginInfoBO> findByUsernameWhenLoginNoTenant(String username);
+    SysUserDTO selectUserByUsername(String username);
 
 
     /**
     /**
      * 更新密码
      * 更新密码

+ 20 - 6
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysUserServiceImpl.java

@@ -7,13 +7,13 @@ import cn.tr.module.sys.mapper.user.SysUserMapper;
 import cn.tr.module.sys.user.dto.SysUserDTO;
 import cn.tr.module.sys.user.dto.SysUserDTO;
 import cn.tr.module.sys.user.dto.SysUserQueryDTO;
 import cn.tr.module.sys.user.dto.SysUserQueryDTO;
 import cn.tr.module.sys.user.service.ISysUserService;
 import cn.tr.module.sys.user.service.ISysUserService;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
 import cn.tr.module.sys.user.po.SysUserPO;
 import cn.tr.module.sys.user.po.SysUserPO;
 import cn.tr.module.sys.user.repository.SysUserRepository;
 import cn.tr.module.sys.user.repository.SysUserRepository;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
-
+import org.springframework.transaction.annotation.Transactional;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.List;
 import java.util.List;
 
 
@@ -38,17 +38,20 @@ public class SysUserServiceImpl implements ISysUserService {
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean updateSysUserById(SysUserDTO source) {
     public boolean updateSysUserById(SysUserDTO source) {
         return userRepository.updateById(SysUserMapper.INSTANCE.toUserPO(source))!=0;
         return userRepository.updateById(SysUserMapper.INSTANCE.toUserPO(source))!=0;
     }
     }
 
 
     @Override
     @Override
-    public List<UserLoginInfoBO> findByUsernameWhenLoginNoTenant(String username) {
-        return SysUserMapper.INSTANCE.toUserLoginInfoDTOList(userRepository.selectList(new LambdaQueryWrapper<SysUserPO>()
-                .eq(SysUserPO::getUsername,username)));
+    public SysUserDTO selectUserByUsername(String username) {
+        return SysUserMapper.INSTANCE.toUserDTO(userRepository.selectOne(new LambdaQueryWrapper<SysUserPO>()
+                .eq(SysUserPO::getUsername,username)
+                .last("limit 1")));
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean updatePsw(String username, String oldPsw, String newPsw) {
     public boolean updatePsw(String username, String oldPsw, String newPsw) {
         SysUserPO user = userRepository.selectOne(new LambdaQueryWrapper<SysUserPO>()
         SysUserPO user = userRepository.selectOne(new LambdaQueryWrapper<SysUserPO>()
                 .eq(SysUserPO::getUsername, username)
                 .eq(SysUserPO::getUsername, username)
@@ -66,11 +69,22 @@ public class SysUserServiceImpl implements ISysUserService {
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean insertSysUser(SysUserDTO source) {
     public boolean insertSysUser(SysUserDTO source) {
-        return false;
+        SysUserPO user = userRepository.selectUserIgnoreDelByUsername(source.getUsername());
+        if(user==null){
+            return userRepository.insert(user)!=0;
+        }
+        if(Boolean.TRUE.equals(user.getDeleted())){
+            userRepository.recoverBatch(Arrays.asList(user));
+            return userRepository.updateById(user)!=0;
+        }else {
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("账户{%s}已存在,不可重复添加",source.getUsername()));
+        }
     }
     }
 
 
     @Override
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int deleteSysUserByIds(Collection<String> ids) {
     public int deleteSysUserByIds(Collection<String> ids) {
         return userRepository.deleteBatchIds(ids);
         return userRepository.deleteBatchIds(ids);
     }
     }

+ 13 - 0
tr-modules/tr-module-system/src/main/resources/mapper/user/SysUserMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.tr.module.sys.user.repository.SysUserRepository">
+
+
+    <select id="selectUserIgnoreDelByUsername" resultType="cn.tr.module.sys.user.po.SysUserPO">
+        select * from sys_user where username=#{username}
+    </select>
+
+
+</mapper>

+ 1 - 0
tr-plugins/tr-spring-boot-starter-plugin-biz-tenant/src/main/java/cn/tr/plugin/biz/tenant/config/aop/TenantIgnoreAspect.java

@@ -1,5 +1,6 @@
 package cn.tr.plugin.biz.tenant.config.aop;
 package cn.tr.plugin.biz.tenant.config.aop;
 
 
+import cn.tr.core.annotation.TenantIgnore;
 import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
 import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;

+ 1 - 2
tr-plugins/tr-spring-boot-starter-plugin-biz-tenant/src/main/java/cn/tr/plugin/biz/tenant/config/ignore/TenantIgnoreUrlConfig.java

@@ -1,11 +1,10 @@
 package cn.tr.plugin.biz.tenant.config.ignore;
 package cn.tr.plugin.biz.tenant.config.ignore;
 
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.collection.CollectionUtil;
-import cn.tr.plugin.biz.tenant.config.aop.TenantIgnore;
+import cn.tr.core.annotation.TenantIgnore;
 import cn.tr.plugin.biz.tenant.properties.TenantProperties;
 import cn.tr.plugin.biz.tenant.properties.TenantProperties;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.CommandLineRunner;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
 import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfo;

+ 5 - 0
tr-plugins/tr-spring-boot-starter-plugin-doc/pom.xml

@@ -13,6 +13,11 @@
 
 
 
 
     <dependencies>
     <dependencies>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
         <dependency>
         <dependency>
             <groupId>com.github.xiaoymin</groupId>
             <groupId>com.github.xiaoymin</groupId>
             <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
             <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>

+ 38 - 0
tr-plugins/tr-spring-boot-starter-plugin-doc/src/main/java/cn/tr/plugin/doc/ModifyOkStatusCodeResponseMessageReader.java

@@ -0,0 +1,38 @@
+package cn.tr.plugin.doc;
+
+import cn.hutool.core.util.ReflectUtil;
+import lombok.NonNull;
+import org.springframework.http.HttpStatus;
+import springfox.documentation.builders.OperationBuilder;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ResponseMessage;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.OperationBuilderPlugin;
+import springfox.documentation.spi.service.contexts.OperationContext;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * 改变swagger中默认的200状态码
+ *
+ * @author GeNing
+ * @version 1.0
+ * @since 2022/5/25 17:41
+ */
+public class ModifyOkStatusCodeResponseMessageReader implements OperationBuilderPlugin {
+
+    @Override
+    public void apply(OperationContext operationContext) {
+        // 获取Builder
+        // 获取Response集合(这里是通过流重新生成了集合,而跟builder中的responses属性不属于同一个引用)
+        // 重新赋值response,注意这里的responses()方法里是循环当前传入参数,再add。所以必须通过反射先清空私有属性
+        operationContext.operationBuilder().responseMessages(Collections.emptySet());
+    }
+
+    @Override
+    public boolean supports(@NonNull DocumentationType documentationType) {
+        return true;
+    }
+}

+ 11 - 0
tr-plugins/tr-spring-boot-starter-plugin-doc/src/main/java/cn/tr/plugin/doc/TrDocAutoConfiguration.java

@@ -5,12 +5,17 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Import;
 import org.springframework.util.ReflectionUtils;
 import org.springframework.util.ReflectionUtils;
+import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
 import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
 import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
+import springfox.documentation.spi.service.OperationBuilderPlugin;
+import springfox.documentation.spring.web.plugins.Docket;
 import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
 import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
 import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
 import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
 
 
+import javax.print.Doc;
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
+import java.util.Collections;
 import java.util.List;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
@@ -32,6 +37,12 @@ public class TrDocAutoConfiguration {
                 if (bean instanceof WebMvcRequestHandlerProvider) {
                 if (bean instanceof WebMvcRequestHandlerProvider) {
                     customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                     customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                 }
                 }
+                if(bean instanceof Docket){
+                    Docket docket= (Docket) bean;
+                    docket.useDefaultResponseMessages(false)
+                    .globalResponseMessage(RequestMethod.GET, Collections.emptyList())
+                    .globalResponseMessage(RequestMethod.POST,Collections.emptyList());
+                }
                 return bean;
                 return bean;
             }
             }
 
 

+ 15 - 1
tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/TrMybatisAutoConfiguration.java

@@ -2,9 +2,12 @@ package cn.tr.plugin.mybatis;
 
 
 import cn.tr.plugin.mybatis.config.filter.DruidAdRemoveFilter;
 import cn.tr.plugin.mybatis.config.filter.DruidAdRemoveFilter;
 import cn.tr.plugin.mybatis.config.handler.CreateAndUpdateMetaObjectHandler;
 import cn.tr.plugin.mybatis.config.handler.CreateAndUpdateMetaObjectHandler;
+import cn.tr.plugin.mybatis.config.logic.PteromysSqlInjector;
 import cn.tr.plugin.mybatis.config.page.PageConfig;
 import cn.tr.plugin.mybatis.config.page.PageConfig;
 import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
 import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.injector.ISqlInjector;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
@@ -14,6 +17,8 @@ import java.util.*;
 import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
 import com.github.pagehelper.PageInterceptor;
 import com.github.pagehelper.PageInterceptor;
 import org.apache.ibatis.plugin.Interceptor;
 import org.apache.ibatis.plugin.Interceptor;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
@@ -24,8 +29,17 @@ import org.springframework.context.annotation.Bean;
  * @Author : LF
  * @Author : LF
  * @Date: 2023年02月21日
  * @Date: 2023年02月21日
  */
  */
-public class TrMybatisAutoConfiguration {
+public class TrMybatisAutoConfiguration implements BeanPostProcessor {
 
 
+    @Override
+    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+        return bean;
+    }
+
+    @Bean
+    public ISqlInjector sqlInjector(){
+        return new PteromysSqlInjector();
+    }
 
 
     @Bean
     @Bean
     public PageConfig pageConfig(){
     public PageConfig pageConfig(){

+ 22 - 0
tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/base/RecoverMapper.java

@@ -0,0 +1,22 @@
+package cn.tr.plugin.mybatis.base;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import java.util.*;
+/**
+ * @ClassName : RecoverMapper
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年04月03日
+ */
+
+public interface RecoverMapper<T> extends BaseMapper<T> {
+
+
+    /**
+     * 批量恢复
+     * @param batchList
+     * @return
+     */
+    int recoverBatch(@Param("list") List<T> batchList);
+}

+ 35 - 0
tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/config/logic/PteromysSqlInjector.java

@@ -0,0 +1,35 @@
+package cn.tr.plugin.mybatis.config.logic;
+
+import java.util.List;
+ 
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+ 
+ 
+ 
+/**
+ * 自定义 SqlInjector
+ *
+ * @author miemie
+ * @since 2018-08-13
+ */
+public class PteromysSqlInjector extends DefaultSqlInjector {
+ 
+    /**
+     * 如果只需增加方法,保留MP自带方法
+     * 可以super.getMethodList() 再add
+     * @return
+     */
+    @Override
+    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
+        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
+        try {
+            tableInfo.getLogicDeleteFieldInfo().getColumn();
+            methodList.add(new RecoverBatch());
+        }catch (Exception e){
+
+        }
+        return methodList;
+    }
+}

+ 50 - 0
tr-plugins/tr-spring-boot-starter-plugin-mybatis/src/main/java/cn/tr/plugin/mybatis/config/logic/RecoverBatch.java

@@ -0,0 +1,50 @@
+package cn.tr.plugin.mybatis.config.logic;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import org.apache.ibatis.executor.keygen.NoKeyGenerator;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+
+/**
+ * <p>
+ * </p>
+ *
+ * @author L
+ * @date 2019/6/14
+ */
+public class RecoverBatch extends AbstractMethod {
+
+    protected RecoverBatch() {
+        super("recoverBatch");
+    }
+
+    @Override
+    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
+        final String sql = "<script>update %s set %s where %s</script>";
+        final String fieldSql = prepareFieldSql(tableInfo);
+        final String whereSql = prepareWhereSqlForMysqlBatch(tableInfo);
+        final String sqlResult = String.format(sql, tableInfo.getTableName(), fieldSql, whereSql);
+        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
+        return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource,new NoKeyGenerator(),null,null);
+    }
+
+    private String prepareFieldSql(TableInfo tableInfo) {
+        final StringBuilder valueSql = new StringBuilder();
+        final TableFieldInfo logicDeleteFieldInfo = tableInfo.getLogicDeleteFieldInfo();
+        final String logicDeleteColum = logicDeleteFieldInfo.getColumn();
+        final String logicNotDeleteValue = logicDeleteFieldInfo.getLogicNotDeleteValue();
+        valueSql.append(logicDeleteColum).append("=").append(logicNotDeleteValue);
+        return valueSql.toString();
+    }
+
+    private String prepareWhereSqlForMysqlBatch(TableInfo tableInfo) {
+        final StringBuilder whereSql = new StringBuilder();
+        whereSql.append(tableInfo.getKeyColumn()).append(" ").append("in").append(" ");
+        whereSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\",\" close=\")\">");
+        whereSql.append("#{item.").append(tableInfo.getKeyProperty()).append("}");
+        whereSql.append("</foreach>");
+        return whereSql.toString();
+    }
+}

+ 0 - 3
tr-plugins/tr-spring-boot-starter-plugin-satoken/src/main/java/cn/tr/plugin/security/config/LoginUserStrategyConfig.java

@@ -24,9 +24,6 @@ public class LoginUserStrategyConfig {
             UserLoginInfoBO user = LoginUserContextHolder.getUser();
             UserLoginInfoBO user = LoginUserContextHolder.getUser();
             if(user==null){
             if(user==null){
                 user = SaTokenUtils.getValue(SecurityConstant.LOGIN_USER, UserLoginInfoBO.class);
                 user = SaTokenUtils.getValue(SecurityConstant.LOGIN_USER, UserLoginInfoBO.class);
-                if(user==null){
-                    throw new ServiceException(TRExcCode.USER_ERROR_A0244);
-                }
             }
             }
             UserLoginInfoBO finalUser = user;
             UserLoginInfoBO finalUser = user;
             return new ILoginUser() {
             return new ILoginUser() {

+ 1 - 7
tr-plugins/tr-spring-boot-starter-plugin-satoken/src/main/java/cn/tr/plugin/security/config/TrSaTokenWebConfig.java

@@ -69,13 +69,7 @@ public class TrSaTokenWebConfig implements WebMvcConfigurer {
                     SaRouter
                     SaRouter
                             .match("/**")    // 拦截的 path 列表,可以写多个 */
                             .match("/**")    // 拦截的 path 列表,可以写多个 */
                             .notMatch(IGNORE_URL)        // 排除掉的 path 列表,可以写多个
                             .notMatch(IGNORE_URL)        // 排除掉的 path 列表,可以写多个
-                            .check(r -> {
-                                SaTokenUtils.checkout();
-                                UserLoginInfoBO loginInfo = SaTokenUtils.getValue(SecurityConstant.LOGIN_USER, UserLoginInfoBO.class);
-                                if(loginInfo==null){
-                                    throw new ServiceException(TRExcCode.USER_ERROR_A0244);
-                                }
-                            }));
+                            .check(r -> SaTokenUtils.checkout()));
         }
         }
 
 
         @Override
         @Override

+ 3 - 3
tr-test/pom.xml

@@ -92,9 +92,9 @@
         </dependency>
         </dependency>
 
 
         <dependency>
         <dependency>
-            <groupId></groupId>
-            <artifactId>
-            </artifactId>
+            <groupId>cn.tr</groupId>
+            <artifactId>tr-module-gen</artifactId>
+            <version>0.0.9</version>
         </dependency>
         </dependency>
 
 
         <dependency>
         <dependency>

+ 1 - 5
tr-test/src/main/java/cn/tr/test/WebApplication.java

@@ -1,14 +1,10 @@
 package cn.tr.test;
 package cn.tr.test;
 
 
-import cn.dev33.satoken.SaManager;
-import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.strategy.SaStrategy;
 import cn.dev33.satoken.strategy.SaStrategy;
 import org.mybatis.spring.annotation.MapperScan;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 
-import javax.annotation.PostConstruct;
-
 /**
 /**
  * @ClassName : WebApplication
  * @ClassName : WebApplication
  * @Description :
  * @Description :
@@ -16,7 +12,7 @@ import javax.annotation.PostConstruct;
  * @Date: 2023年02月22日
  * @Date: 2023年02月22日
  */
  */
 @SpringBootApplication(scanBasePackages = "cn.tr.module.*")
 @SpringBootApplication(scanBasePackages = "cn.tr.module.*")
-@MapperScan("cn.tr.module.sys.*.repository")
+@MapperScan({"cn.tr.module.sys.*.repository","cn.tr.module.gen.modular.*.mapper"})
 public class WebApplication {
 public class WebApplication {
     public static void main(String[] args) {
     public static void main(String[] args) {
         SaStrategy.me.checkElementAnnotation=c->{};
         SaStrategy.me.checkElementAnnotation=c->{};

+ 8 - 6
tr-test/src/main/resources/application-doc.yml

@@ -8,17 +8,19 @@ knife4j:
     version: V0.9
     version: V0.9
     license: Apache 2.0
     license: Apache 2.0
     group:
     group:
-      auth:
-        group-name: 认证授权
-        api-rule: package
-        api-rule-resources:
-          - cn.tr.module.auth
       sys:
       sys:
         group-name: 系统管理
         group-name: 系统管理
         api-rule: package
         api-rule: package
         api-rule-resources:
         api-rule-resources:
           - cn.tr.module.sys
           - cn.tr.module.sys
+      gen:
+        group-name: 代码生成器
+        api-rule: package
+        api-rule-resources:
+          - cn.tr.module.gen.modular.basic
+          - cn.tr.module.gen.modular.config
   setting:
   setting:
     enable-footer: false
     enable-footer: false
     enable-footer-custom: true
     enable-footer-custom: true
-    footer-custom-content: Apache License 2.0 | Copyright  2019-[驼人控股集团](https://www.tuoren.com/about/index.html)
+    footer-custom-content: Apache License 2.0 | Copyright  2019-[驼人控股集团](https://www.tuoren.com/about/index.html)
+    enable-response-code: false

+ 3 - 1
tr-test/src/main/resources/application.yml

@@ -60,12 +60,14 @@ tr:
       - /v2/api-docs/*
       - /v2/api-docs/*
       - /v2/api-docs
       - /v2/api-docs
       - /webjars/**
       - /webjars/**
+      - /oauth2/psw/**
   tenant:
   tenant:
     ignore-tables:
     ignore-tables:
       - sys_menu
       - sys_menu
       - gen_basic
       - gen_basic
       - sys_dict
       - sys_dict
-      - sys_dict_detail
+      - sys_dict_item
+      - gen_config
 
 
 sa-token:
 sa-token:
   is-read-header: true
   is-read-header: true