Explorar o código

Merge remote-tracking branch 'master/master'

# Conflicts:
#	logs/2026-01/hdis-2026-01-14-1.log.gz
#	logs/2026-01/hdis-2026-01-15-1.log.gz
G hai 1 semana
pai
achega
4756dd2ca5
Modificáronse 100 ficheiros con 6850 adicións e 2486 borrados
  1. BIN=BIN
      logs/2026-01/hdis-2026-01-08-1.log.gz
  2. BIN=BIN
      logs/2026-01/hdis-2026-01-14-1.log.gz
  3. BIN=BIN
      logs/2026-01/hdis-2026-01-15-1.log.gz
  4. BIN=BIN
      logs/2026-01/hdis-2026-01-16-1.log.gz
  5. BIN=BIN
      logs/2026-01/hdis-2026-01-19-1.log.gz
  6. 5 1
      tr-framework/src/main/java/cn/tr/core/utils/PswUtils.java
  7. 0 0
      tr-modules/tr-module-platform/src/main/resources/mapper/platform/SysUserPostRepository.xml
  8. 6 0
      tr-modules/tr-module-system/pom.xml
  9. 185 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/SimpleValue.java
  10. 44 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/Value.java
  11. 22 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/annotation/ExcelDict.java
  12. 24 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/annotation/Log.java
  13. 17 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/bo/DictModel.java
  14. 94 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/ClusterConfigStorage.java
  15. 30 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/ConfigStorage.java
  16. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/manager/ConfigStorageManager.java
  17. 50 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/convert/ExcelDictConverter.java
  18. 30 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/Entity.java
  19. 48 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/GenericEntity.java
  20. 25 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/RecordCreationEntity.java
  21. 28 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/RecordModifierEntity.java
  22. 26 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/TenantGenericEntity.java
  23. 20 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/exception/CustomException.java
  24. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/BizEnum.java
  25. 28 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/DelFlagEnum.java
  26. 28 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/LinkExternalEnum.java
  27. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/MenuTypeEnum.java
  28. 34 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/SexEnum.java
  29. 29 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/StatusEnum.java
  30. 36 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/UserPlatformEnum.java
  31. 26 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/YesNoEnum.java
  32. 50 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/handler/IntegerStringTypeHandler.java
  33. 61 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/handler/TenantNameHandler.java
  34. 12 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/interceptor/GetNameInterface.java
  35. 53 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/properties/AppProperties.java
  36. 52 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedisConfig.java
  37. 587 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedisUtils.java
  38. 113 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedissonClientAutoConfiguration.java
  39. 42 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/Constants.java
  40. 68 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/DictUtil.java
  41. 70 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/ExcelUtil.java
  42. 139 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/SecurityUtil.java
  43. 19 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/TenantUtil.java
  44. 20 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/exception/CustomException.java
  45. 38 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/AuthInfo.java
  46. 101 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/LoginUser.java
  47. 40 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/SysRoleInfo.java
  48. 42 42
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/config/StdStpInterface.java
  49. 93 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/AuthController.java
  50. 46 46
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/CaptchaController.java
  51. 121 121
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/CurrentUserController.java
  52. 100 100
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/OAuth2ServerController.java
  53. 51 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/enums/GrantTypeEnum.java
  54. 27 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/enums/StpTypeEnum.java
  55. 68 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/IAccountOperator.java
  56. 70 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/IAuthGranter.java
  57. 45 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/TokenParameter.java
  58. 269 270
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/psw/operator/LoginOAuth2PswUserOperator.java
  59. 127 128
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/psw/operator/LoginWxUserOperator.java
  60. 170 170
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/service/CurrentUserService.java
  61. 51 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/AddressUtil.java
  62. 53 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/IpUtil.java
  63. 140 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/SecurityUtil.java
  64. 21 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/vo/RoleInfoVO.java
  65. 41 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/vo/UserInfoVO.java
  66. 1 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/sms/service/impl/SmsSendServiceImpl.java
  67. 93 93
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantController.java
  68. 104 105
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantPackageController.java
  69. 49 50
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/ISysTenantPackageMenuService.java
  70. 53 53
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/ISysTenantPackageService.java
  71. 81 82
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/ISysTenantService.java
  72. 148 149
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantPackageMenuServiceImpl.java
  73. 118 118
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantPackageServiceImpl.java
  74. 217 217
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantServiceImpl.java
  75. 114 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysDeptController.java
  76. 85 86
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysMenuController.java
  77. 98 98
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysOrgController.java
  78. 101 101
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPortalController.java
  79. 0 82
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPositionController.java
  80. 119 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPostController.java
  81. 122 74
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysRoleController.java
  82. 88 81
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysUserController.java
  83. 102 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptAddDTO.java
  84. 104 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptEditDTO.java
  85. 80 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptQueryDTO.java
  86. 119 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuAddDTO.java
  87. 96 98
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuDTO.java
  88. 119 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuEditDTO.java
  89. 1 9
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuQueryDTO.java
  90. 0 1
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysOrgDTO.java
  91. 60 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostAddDTO.java
  92. 62 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostEditDTO.java
  93. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostQueryDTO.java
  94. 72 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleAddDTO.java
  95. 33 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleAssignMenuDTO.java
  96. 73 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleEditDTO.java
  97. 0 6
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleQueryDTO.java
  98. 138 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserAddDTO.java
  99. 140 55
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserDTO.java
  100. 101 48
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserEditDTO.java

BIN=BIN
logs/2026-01/hdis-2026-01-08-1.log.gz


BIN=BIN
logs/2026-01/hdis-2026-01-14-1.log.gz


BIN=BIN
logs/2026-01/hdis-2026-01-15-1.log.gz


BIN=BIN
logs/2026-01/hdis-2026-01-16-1.log.gz


BIN=BIN
logs/2026-01/hdis-2026-01-19-1.log.gz


+ 5 - 1
tr-framework/src/main/java/cn/tr/core/utils/PswUtils.java

@@ -37,13 +37,17 @@ public class PswUtils {
      * 校验密码
      *
      * @param password 密码
+     * @return
      */
-    public static void validatePsw(String password) {
+    public static boolean validatePsw(String password) {
         if(StrUtil.length(password)<6){
             throw new UnsupportedOperationException("密码长度不得少于6位");
         }
+        return false;
     }
 
+
+
     /**
      * 校验密码强度
      * 密码必须不少于8位,且必须包含字母、数字和特殊符号

+ 0 - 0
tr-modules/tr-module-platform/src/main/resources/mapper/platform/BizWechatMapper.xml → tr-modules/tr-module-platform/src/main/resources/mapper/platform/SysUserPostRepository.xml


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

@@ -13,6 +13,12 @@
     <version>${revision}</version>
 
     <dependencies>
+        <!-- 添加Redisson依赖 -->
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>cn.tr</groupId>
             <artifactId>tr-spring-boot-starter-plugin-quartz</artifactId>

+ 185 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/SimpleValue.java

@@ -0,0 +1,185 @@
+package cn.tr.module.common;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.annotation.IEnum;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+@Slf4j
+public class SimpleValue implements Value {
+
+    public static SimpleValue of(Object nativeValue){
+        SimpleValue simpleValue = new SimpleValue();
+        simpleValue.nativeValue=nativeValue;
+        return simpleValue;
+    }
+    @Getter
+    private Object nativeValue;
+
+    @Override
+    public Object get() {
+        return nativeValue;
+    }
+
+    @Override
+    public <T> T as(Class<T> type) {
+        if (nativeValue == null) {
+            return null;
+        }
+        if(type.isInstance(nativeValue)){
+            return (T)nativeValue;
+        }
+        return convert(nativeValue, type, new Class[0]);
+    }
+
+    public <T> T convert(Object source, Class<T> targetClass, Class[] genericType) {
+        if (source == null) {
+            return null;
+        }
+        if (targetClass == String.class) {
+            if (source instanceof Date) {
+                return (T) DateUtil.parse(String.valueOf(source));
+            }
+            return (T) String.valueOf(source);
+        }
+        if (targetClass == Object.class) {
+            return (T) source;
+        }
+        if (targetClass == Date.class) {
+            if (source instanceof String) {
+                return (T) DateUtil.parse(String.valueOf(source));
+            }
+            if (source instanceof Number) {
+                return (T) new Date(((Number) source).longValue());
+            }
+            if (source instanceof Date) {
+                return (T) source;
+            }
+        }
+        if(IEnum.class.isAssignableFrom(targetClass)){
+            if (targetClass.isEnum()) {
+                T[] enumConstants = targetClass.getEnumConstants();
+                for (T enumConstant : enumConstants) {
+                    try {
+                        Field value = enumConstant.getClass().getDeclaredField("value");
+                        value.setAccessible(true);
+                        try {
+                            if(ObjectUtil.equal(String.valueOf(value.get(enumConstant)),String.valueOf(source))){
+                                return enumConstant;
+                            }
+                        } catch (IllegalAccessException e) {
+                            log.error("枚举类转换失败,[value]值无法获取,{}",targetClass.getName());
+                            return null;
+                        }
+                    } catch (NoSuchFieldException e) {
+                        log.error("枚举类转换失败,不存在[value]值,{}",targetClass.getName());
+                        return null;
+                    }
+                }
+            }else {
+                return null;
+            }
+        }
+        if (Collection.class.isAssignableFrom(targetClass)) {
+            Collection collection = newCollection(targetClass);
+            Collection sourceCollection;
+            if(source instanceof Map){
+                Map map= (Map) source;
+                if(CollectionUtil.size(map)==1&&map.containsKey("nativeValue")){
+                    source=map.get("nativeValue");
+                }
+            }
+            if (source instanceof Collection) {
+                sourceCollection = (Collection) source;
+            } else if (source instanceof Object[]) {
+                sourceCollection = Arrays.asList((Object[]) source);
+            } else {
+                if (source instanceof String) {
+                    String stringValue = ((String) source);
+                    sourceCollection = Arrays.asList(stringValue.split("[,]"));
+                } else {
+                    sourceCollection = Arrays.asList(source);
+                }
+            }
+            //转换泛型
+            if (genericType != null && genericType.length > 0 && genericType[0] != Object.class) {
+                for (Object sourceObj : sourceCollection) {
+                    collection.add(convert(sourceObj, genericType[0], null));
+                }
+            } else {
+                collection.addAll(sourceCollection);
+            }
+            return (T) collection;
+        }
+
+        if (targetClass.isEnum()) {
+            if (Enum.class.isAssignableFrom(targetClass)) {
+                String strVal = String.valueOf(source);
+                T[] enumConstants = targetClass.getEnumConstants();
+                for (T enumConstant : enumConstants) {
+                    if (String.valueOf(source).equals(( (Enum)enumConstant).ordinal())
+                            ||String.valueOf(source).equals(( (Enum)enumConstant).name())) {
+                        return enumConstant;
+                    }
+                }
+                return null;
+            }
+            String strSource=String.valueOf(source);
+            for (T t : targetClass.getEnumConstants()) {
+                if (((Enum) t).name().equalsIgnoreCase(strSource)
+                        || Objects.equals(String.valueOf(((Enum<?>) t).ordinal()),strSource)) {
+                    return t;
+                }
+            }
+
+            log.warn("无法将:{}转为枚举:{}", source, targetClass);
+            return null;
+        }
+        //转换为数组
+        if (targetClass.isArray()) {
+            Class<?> componentType = targetClass.getComponentType();
+            List<?> val = convert(source, List.class, new Class[]{componentType});
+            return (T) val.toArray((Object[]) Array.newInstance(componentType, val.size()));
+        }
+        if (targetClass.getSuperclass().equals(Number.class)) {
+            try {
+                return ReflectUtil.getConstructor(targetClass,source.getClass()).newInstance(source);
+            } catch (InstantiationException e) {
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            } catch (InvocationTargetException e) {
+                e.printStackTrace();
+            }
+        }
+        return JSONUtil.toBean(JSONUtil.parseObj(source),targetClass);
+    }
+
+    private Collection<?> newCollection(Class<?> targetClass) {
+
+        if (targetClass == List.class) {
+            return new ArrayList<>();
+        } else if (targetClass == Set.class) {
+            return new HashSet<>();
+        } else if (targetClass == Queue.class) {
+            return new LinkedList<>();
+        } else {
+            try {
+                return (Collection<?>) targetClass.newInstance();
+            } catch (Exception e) {
+                throw new UnsupportedOperationException("不支持的类型:" + targetClass, e);
+            }
+        }
+    }
+
+
+}

+ 44 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/Value.java

@@ -0,0 +1,44 @@
+package cn.tr.module.common;
+
+import cn.hutool.core.util.ObjectUtil;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public interface Value extends Serializable {
+    default String asString() {
+        if(ObjectUtil.isNull(get())){
+            return null;
+        }
+        return String.valueOf(get());
+    }
+
+    default int asInt() {
+        return as(Integer.class);
+    }
+
+    default long asLong() {
+        return as(Long.class);
+    }
+
+    default boolean asBoolean() {
+        return Boolean.TRUE.equals(get())
+                || "true".equals(get())||"1".equals(String.valueOf(get()));
+    }
+
+    default Number asNumber() {
+        return as(Number.class);
+    }
+
+    default Date asDate() {
+        return as(Date.class);
+    }
+
+    Object get();
+
+    <T> T as(Class<T> type);
+
+    static Value simple(Object value) {
+        return SimpleValue.of(value);
+    }
+}

+ 22 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/annotation/ExcelDict.java

@@ -0,0 +1,22 @@
+package cn.tr.module.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 数据字典注解
+ *
+ * @author Kevin
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface ExcelDict {
+
+    /**
+     * 字典编码
+     *
+     * @return
+     */
+    String value() default "";
+
+}

+ 24 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/annotation/Log.java

@@ -0,0 +1,24 @@
+package cn.tr.module.common.annotation;
+
+
+import cn.tr.module.common.menus.UserPlatformEnum;
+
+import java.lang.annotation.*;
+
+/**
+ * 日志注解
+ *
+ * @author Kevin
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Log {
+    String title() default "";
+
+    /**
+     * 用户平台
+     */
+    UserPlatformEnum userPlatform() default UserPlatformEnum.WEB;
+
+}

+ 17 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/bo/DictModel.java

@@ -0,0 +1,17 @@
+package cn.tr.module.common.bo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 字典模型
+ *
+ * @author Kevin
+ */
+@Data
+public class DictModel implements Serializable {
+
+    String label;
+    String value;
+}

+ 94 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/ClusterConfigStorage.java

@@ -0,0 +1,94 @@
+package cn.tr.module.common.cache;
+
+import cn.hutool.core.util.StrUtil;
+import cn.tr.module.common.Value;
+import com.baomidou.mybatisplus.annotation.IEnum;
+import org.springframework.data.redis.core.BoundHashOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClusterConfigStorage implements ConfigStorage {
+    private  BoundHashOperations boundHashOperations;
+    public ClusterConfigStorage(RedisTemplate redisTemplate,String name){
+        boundHashOperations = redisTemplate.opsForSet().getOperations().boundHashOps(name);
+    }
+
+    @Override
+    public Value getConfig(String key) {
+        if (StrUtil.isEmpty(key)) {
+            return null;
+        }
+        return Value.simple(boundHashOperations.get(key));
+    }
+
+    @Override
+    public Boolean setConfigs(Map<String, Object> values) {
+        if (CollectionUtils.isEmpty(values)) {
+            return true;
+        }
+        HashMap<String, Object> map = new HashMap<>();
+        values.forEach((k,v)->{
+            if(v instanceof IEnum){
+                map.put(k,((IEnum) v).getValue());
+            }else {
+                map.put(k,v);
+            }
+        });
+        boundHashOperations.putAll(map);
+        return true;
+    }
+
+    @Override
+    public Boolean setConfig(String key, Object value) {
+        if (key == null) {
+            return true;
+        }
+        if(value==null){
+            boundHashOperations.delete(key);
+        }else {
+            if(value instanceof IEnum){
+                value=((IEnum) value).getValue();
+            }
+            boundHashOperations.put(key,value);
+        }
+        return true;
+    }
+
+    @Override
+    public Value getAndRemove(String key) {
+        Value value = Value.simple(boundHashOperations.get(key));
+        boundHashOperations.delete(key);
+        return value;
+    }
+
+    @Override
+    public Boolean remove(String key) {
+        boundHashOperations.delete(key);
+        return true;
+    }
+
+    @Override
+    public Boolean remove(Collection<String> key) {
+        boundHashOperations.delete(key);
+        return true;
+    }
+
+    @Override
+    public Boolean clear() {
+        boundHashOperations.delete(boundHashOperations.keys());
+        return true;
+    }
+
+    @Override
+    public Map<String, Value> getKeys(Collection<String> keys) {
+        Map<String, Value> result = new HashMap<>();
+        keys.parallelStream().forEach(key->{
+            result.put(key,getConfig(key));
+        });
+        return result;
+    }
+}

+ 30 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/ConfigStorage.java

@@ -0,0 +1,30 @@
+package cn.tr.module.common.cache;
+
+
+
+import cn.tr.module.common.Value;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 配置存储
+ */
+public interface ConfigStorage {
+
+    Value getConfig(String key);
+
+    Boolean setConfigs(Map<String, Object> values);
+
+    Boolean setConfig(String key, Object value);
+
+    Boolean remove(String key);
+
+    Value getAndRemove(String key);
+
+    Boolean remove(Collection<String> key);
+
+    Boolean clear();
+
+    Map<String,Value> getKeys(Collection<String> keys);
+}

+ 31 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/manager/ConfigStorageManager.java

@@ -0,0 +1,31 @@
+package cn.tr.module.common.cache.manager;
+
+import cn.tr.module.common.cache.ClusterConfigStorage;
+import cn.tr.module.common.cache.ConfigStorage;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+/**
+ * 配置存储管理器
+ * 用于管理各种配置存储实例
+ *
+ * @author tr
+ * @since 2026-01-19
+ */
+@Component
+public class ConfigStorageManager {
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 获取指定名称的配置存储实例
+     *
+     * @param name 存储名称
+     * @return 配置存储实例
+     */
+    public ConfigStorage getStorage(String name) {
+        return new ClusterConfigStorage(redisTemplate, name);
+    }
+}

+ 50 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/convert/ExcelDictConverter.java

@@ -0,0 +1,50 @@
+package cn.tr.module.common.convert;
+
+import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.tr.module.common.annotation.ExcelDict;
+import cn.tr.module.common.utils.DictUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+
+import java.lang.reflect.Field;
+
+/**
+ * Excel数据字典转换器
+ *
+ * @author Kevin
+ */
+public class ExcelDictConverter implements Converter<String> {
+
+    @Override
+    public Class supportJavaTypeKey() {
+        return String.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public String convertToJavaData(ReadCellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        Field field = excelContentProperty.getField();
+        String dictCode = AnnotationUtil.getAnnotationValue(field, ExcelDict.class);
+        String dictValue = DictUtil.getDictValue(dictCode, cellData.getStringValue());
+        return StrUtil.isBlank(dictValue) ? cellData.getStringValue() : dictValue;
+    }
+
+    @Override
+    public WriteCellData convertToExcelData(String s, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        Field field = excelContentProperty.getField();
+        String dictCode = AnnotationUtil.getAnnotationValue(field, ExcelDict.class);
+        String dictLabel = DictUtil.getDictLabel(dictCode, s);
+        return new WriteCellData(StrUtil.isBlank(dictLabel) ? s : dictLabel);
+    }
+
+}

+ 30 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/Entity.java

@@ -0,0 +1,30 @@
+package cn.tr.module.common.entity;
+
+import cn.hutool.core.bean.BeanUtil;
+
+import java.io.Serializable;
+import java.util.function.Predicate;
+
+
+public interface Entity extends Serializable {
+    long serialVersionUID = 1L;
+
+    default boolean tryValidate(Predicate<? super Entity> predicate) {
+        return predicate.test(this);
+    }
+
+    default <T> T copyTo(Class<T> target, String... ignoreProperties) {
+        return BeanUtil.copyProperties(this, target, ignoreProperties);
+    }
+
+    default <T> T copyTo(T target, String... ignoreProperties) {
+        BeanUtil.copyProperties(this, target, ignoreProperties);
+        return target;
+    }
+
+
+    default Entity copyFrom(Object target, String... ignoreProperties) {
+        BeanUtil.copyProperties(target, this, ignoreProperties);
+        return this;
+    }
+}

+ 48 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/GenericEntity.java

@@ -0,0 +1,48 @@
+package cn.tr.module.common.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import jakarta.validation.constraints.NotNull;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public abstract class GenericEntity<PK> implements Entity,RecordModifierEntity,RecordCreationEntity, Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.ASSIGN_ID)
+    @Schema(description = "id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @NotNull(groups = Update.class,message = "id不可为空")
+    private PK id;
+
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "创建时间",readOnly = true)
+    private Date createTime;
+
+    @TableField(fill = FieldFill.INSERT)
+    @Schema(description = "创建人",readOnly = true)
+    private String createBy;
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @Schema(description = "修改人",readOnly = true)
+    private String updateBy;
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @Schema(description = "修改时间",readOnly = true)
+    private Date updateTime;
+
+    /* 分组校验 */
+    public static @interface Update {
+    }
+
+    public static @interface Insert {
+    }
+}

+ 25 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/RecordCreationEntity.java

@@ -0,0 +1,25 @@
+package cn.tr.module.common.entity;
+
+import java.util.Date;
+
+/**
+ * @Author lifang
+ * @Date 13:54 2022/3/12
+ * @Description 创建字段
+ **/
+
+public interface RecordCreationEntity extends Entity {
+
+    String getCreateBy();
+
+    void setCreateBy(String createBy);
+
+    Date getCreateTime();
+
+    void setCreateTime(Date createTime);
+
+
+    default void setCreateTimeNow() {
+        setCreateTime(new Date());
+    }
+}

+ 28 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/RecordModifierEntity.java

@@ -0,0 +1,28 @@
+package cn.tr.module.common.entity;
+
+import java.util.Date;
+
+
+/**
+ * @Author lifang
+ * @Date 13:54 2022/3/12
+ * @Description 修改字段
+ **/
+
+public interface RecordModifierEntity extends Entity {
+
+    String getUpdateBy();
+
+    void setUpdateBy(String updateBy);
+
+    Date getUpdateTime();
+
+    void setUpdateTime(Date updateTime);
+
+
+
+    default void setModifyTimeNow() {
+        setUpdateTime(new Date());
+    }
+
+}

+ 26 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/TenantGenericEntity.java

@@ -0,0 +1,26 @@
+package cn.tr.module.common.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName TenetGenericEntity.java
+ * @Description 多租户父类
+ * @createTime 2022年03月15日 17:02:00
+ */
+public abstract class TenantGenericEntity<K,T> extends GenericEntity<K> {
+
+    private static final long serialVersionUID = 1L;
+
+    @Getter
+    @TableField(value = "tenant_id",fill = FieldFill.INSERT)
+    @Setter
+    @JsonSerialize(using = ToStringSerializer.class)
+    private T tenantId;
+}

+ 20 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/exception/CustomException.java

@@ -0,0 +1,20 @@
+package cn.tr.module.common.exception;
+
+import lombok.Data;
+
+/**
+ * 自定义异常
+ *
+ * @author Kevin
+ */
+@Data
+public class CustomException extends RuntimeException {
+
+    private Integer code;
+
+    private String message;
+
+    public CustomException(String message) {
+        this.message = message;
+    }
+}

+ 31 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/BizEnum.java

@@ -0,0 +1,31 @@
+package cn.tr.module.common.menus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * 业务类型
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum BizEnum {
+    /**
+     * 临时文件
+     */
+    TEMP("temp", "临时文件"),
+    /**
+     * 图片
+     */
+    IMAGE("image", "图片"),
+    /**
+     * Excel
+     */
+    EXCEL("excel", "Excel");
+
+    private String code;
+    private String desc;
+
+}

+ 28 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/DelFlagEnum.java

@@ -0,0 +1,28 @@
+package cn.tr.module.common.menus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * 删除标记
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum DelFlagEnum {
+
+    /**
+     * 存在
+     */
+    NO("0", "存在"),
+    /**
+     * 删除
+     */
+    YES("1", "删除");
+
+    private String code;
+    private String desc;
+
+}

+ 28 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/LinkExternalEnum.java

@@ -0,0 +1,28 @@
+package cn.tr.module.common.menus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * 是否外链
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum LinkExternalEnum {
+
+    /**
+     * 是
+     */
+    YES("0", "是"),
+    /**
+     * 否
+     */
+    NO("1", "否");
+
+    private String code;
+    private String desc;
+
+}

+ 31 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/MenuTypeEnum.java

@@ -0,0 +1,31 @@
+package cn.tr.module.common.menus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 菜单类型
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum MenuTypeEnum {
+
+    /**
+     * 目录
+     */
+    DIR("dir", "目录"),
+    /**
+     * 菜单
+     */
+    MENU("menu", "菜单"),
+    /**
+     * 按钮
+     */
+    BUTTON("button", "按钮");
+
+    private String code;
+    private String desc;
+
+}

+ 34 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/SexEnum.java

@@ -0,0 +1,34 @@
+package cn.tr.module.common.menus;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * 性别
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum SexEnum implements IEnum<Integer> {
+
+    /**
+     * 男
+     */
+    MAN(1,"男"),
+    /**
+     * 女
+     */
+    WOMAN(2, "女"),
+    /**
+     * 未知
+     */
+    UNKNOW(3, "未知");
+
+    private Integer value;
+    private String text;
+}

+ 29 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/StatusEnum.java

@@ -0,0 +1,29 @@
+package cn.tr.module.common.menus;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 状态
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum StatusEnum implements IEnum<Integer> {
+    /**
+     * 正常
+     */
+    YES(0, "正常"),
+    /**
+     * 停用
+     */
+    NO(1, "停用");
+
+    private Integer value;
+    private String text;
+
+}

+ 36 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/UserPlatformEnum.java

@@ -0,0 +1,36 @@
+package cn.tr.module.common.menus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * 用户平台
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum UserPlatformEnum {
+
+    /**
+     * web管理后台
+     */
+    WEB("WEB", "web管理后台"),
+    /**
+     * 前端用户平台
+     */
+    APP("APP", "前端用户平台"),
+    /**
+     * 第三方应用
+     */
+    OPENAPI("API", "第三方应用"),
+
+    APP_DOCTOR("DOCTOR","app医生端"),
+
+    APP_ASSIST("ASSIST","疼痛小助手");
+
+    private String code;
+    private String desc;
+
+}

+ 26 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/YesNoEnum.java

@@ -0,0 +1,26 @@
+package cn.tr.module.common.menus;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 是否
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum YesNoEnum {
+    /**
+     * 否
+     */
+    NO("0", "否"),
+    /**
+     * 是
+     */
+    YES("1", "是");
+
+    private String code;
+    private String desc;
+
+}

+ 50 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/handler/IntegerStringTypeHandler.java

@@ -0,0 +1,50 @@
+package cn.tr.module.common.mybatisplus.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 处理Integer类型与String类型(0/1转"0"/"1")之间的转换
+ * 用于解决PostgreSQL中integer字段与Java中String类型的映射问题
+ *
+ * @author tr
+ * @since 2026-01-19
+ */
+@MappedTypes(String.class)
+@MappedJdbcTypes({JdbcType.INTEGER, JdbcType.SMALLINT, JdbcType.TINYINT})
+public class IntegerStringTypeHandler extends BaseTypeHandler<String> {
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
+        if (parameter != null) {
+            ps.setInt(i, Integer.parseInt(parameter));
+        } else {
+            ps.setNull(i, java.sql.Types.INTEGER);
+        }
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        int value = rs.getInt(columnName);
+        return rs.wasNull() ? null : String.valueOf(value);
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        int value = rs.getInt(columnIndex);
+        return rs.wasNull() ? null : String.valueOf(value);
+    }
+
+    @Override
+    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        int value = cs.getInt(columnIndex);
+        return cs.wasNull() ? null : String.valueOf(value);
+    }
+}

+ 61 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/handler/TenantNameHandler.java

@@ -0,0 +1,61 @@
+package cn.tr.module.common.mybatisplus.handler;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.tr.module.common.mybatisplus.interceptor.GetNameInterface;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+import org.apache.ibatis.type.TypeHandler;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DateToBigIntHandler.java
+ * @Description TODO
+ * @createTime 2022年03月21日 09:58:00
+ */
+@MappedTypes(String.class)
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public class TenantNameHandler implements TypeHandler<String> {
+
+    private GetNameInterface<String,String> getHospitalName;
+
+    @Override
+    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) {
+
+    }
+
+    @Override
+    public String getResult(ResultSet rs, String columnName) throws SQLException {
+        if(getHospitalName==null){
+            getHospitalName= SpringUtil.getBean(GetNameInterface.class);
+        }
+        if (CharSequenceUtil.isNotBlank(rs.getString(columnName))) {
+            return getHospitalName.getName( rs.getString(columnName));
+        }
+        return null;
+    }
+
+    @Override
+    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
+        if(getHospitalName==null){
+            getHospitalName= SpringUtil.getBean(GetNameInterface.class);
+        }
+        return getHospitalName.getName( rs.getString(columnIndex));
+    }
+
+    @Override
+    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
+        if(getHospitalName==null){
+            getHospitalName= SpringUtil.getBean(GetNameInterface.class);
+        }
+        return getHospitalName.getName( cs.getString(columnIndex));
+    }
+}

+ 12 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/interceptor/GetNameInterface.java

@@ -0,0 +1,12 @@
+package cn.tr.module.common.mybatisplus.interceptor;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName GetNameInterface.java
+ * @Description TODO
+ * @createTime 2022年03月22日 17:22:00
+ */
+public interface GetNameInterface<PK,T> {
+    T getName(PK id);
+}

+ 53 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/properties/AppProperties.java

@@ -0,0 +1,53 @@
+package cn.tr.module.common.properties;
+
+import lombok.Data;
+import lombok.Getter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 读取项目相关配置
+ *
+ * @author Kevin
+ */
+@Component
+@ConfigurationProperties(prefix = "app")
+@Data
+public class AppProperties {
+
+    /**
+     * 项目名称
+     */
+    @Getter
+    private String name;
+
+    /**
+     * 实例演示开关
+     */
+//    @Getter
+//    private static boolean demoEnabled = false;
+
+    /**
+     * 获取地址开关
+     */
+    @Getter
+    private boolean addressEnabled = false;
+
+    /**
+     * 上传目录
+     */
+    @Getter
+    private String uploadType;
+
+    /**
+     * 上传目录
+     */
+    @Getter
+    private String uploadDir;
+
+    /**
+     * 缓存前缀
+     */
+    @Getter
+    private String cachePrefix;
+}

+ 52 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedisConfig.java

@@ -0,0 +1,52 @@
+package cn.tr.module.common.redis;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+
+
+/**
+ * redis基础配置
+ *
+ * @author Kevin
+ */
+@Configuration
+@Slf4j
+@AllArgsConstructor
+@ConditionalOnProperty(name = "spring.data.redis.host")
+public class RedisConfig  {
+
+
+    @Bean(name = "redisTemplate")
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+//        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+//
+//        // 设置序列化方式
+//        redisTemplate.setKeySerializer(new StringRedisSerializer());
+//        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
+//
+//        // 设置连接工厂
+//        redisTemplate.setConnectionFactory(connectionFactory);
+//
+//        return redisTemplate;
+
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用JSON序列化,避免循环引用
+        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
+
+        return template;
+    }
+    
+}

+ 587 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedisUtils.java

@@ -0,0 +1,587 @@
+package cn.tr.module.common.redis;
+
+import cn.hutool.core.collection.CollectionUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 基于spring和redis的redisTemplate工具类
+ * 针对所有的hash  都是以h开头的方法
+ * 针对所有的Set  都是以s开头的方法
+ * 针对所有的List  都是以l开头的方法
+ *
+ * @author Kevin
+ */
+@Component
+public class RedisUtils {
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 指定缓存失效时间
+     *
+     * @param key  键
+     * @param time 时间(秒)
+     * @return
+     */
+    public boolean expire(String key, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.expire(key, time, TimeUnit.SECONDS);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据key  获取过期时间
+     *
+     * @param key 键  不能为null
+     * @return 时间(秒)  返回0代表为永久有效
+     */
+    public long getExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 判断key是否存在
+     *
+     * @param key 键
+     * @return true  存在  false不存在
+     */
+    public boolean hasKey(String key) {
+        try {
+            return redisTemplate.hasKey(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 删除缓存
+     *
+     * @param key 可以传一个值  或多个
+     */
+    @SuppressWarnings("unchecked")
+    public Boolean del(String... key) {
+        if (key != null && key.length > 0) {
+            if (key.length == 1) {
+                return redisTemplate.delete(key[0]);
+            } else {
+                List<?> objects = CollectionUtils.arrayToList(key);
+                return  redisTemplate.delete((Collection<String>) objects)== CollectionUtil.size(objects);
+            }
+        }
+        return true;
+    }
+
+    //============================String=============================
+
+    /**
+     * 普通缓存获取
+     *
+     * @param key 键
+     * @return 值
+     */
+    public Object get(String key) {
+        return key == null ? null : redisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 普通缓存放入
+     *
+     * @param key   键
+     * @param value 值
+     * @return true成功  false失败
+     */
+    public boolean set(String key, Object value) {
+        try {
+            redisTemplate.opsForValue().set(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+
+    }
+
+    /**
+     * 普通缓存放入并设置时间
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)  time要大于0  如果time小于等于0  将设置无限期
+     * @return true成功  false  失败
+     */
+    public boolean set(String key, Object value, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+            } else {
+                set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 递增
+     *
+     * @param key   键
+     * @param delta 要增加几(大于0)
+     * @return
+     */
+    public long incr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递增因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+
+    /**
+     * 递减
+     *
+     * @param key   键
+     * @param delta 要减少几(小于0)
+     * @return
+     */
+    public long decr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递减因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, -delta);
+    }
+
+    //================================Map=================================
+
+    /**
+     * HashGet
+     *
+     * @param key  键  不能为null
+     * @param item 项  不能为null
+     * @return 值
+     */
+    public Object hget(String key, String item) {
+        return redisTemplate.opsForHash().get(key, item);
+    }
+
+    /**
+     * 获取hashKey对应的所有键值
+     *
+     * @param key 键
+     * @return 对应的多个键值
+     */
+    public Map<Object, Object> hmget(String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * HashSet
+     *
+     * @param key 键
+     * @param map 对应多个键值
+     * @return true  成功  false  失败
+     */
+    public boolean hmset(String key, Map<String, Object> map) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * HashSet  并设置时间
+     *
+     * @param key  键
+     * @param map  对应多个键值
+     * @param time 时间(秒)
+     * @return true成功  false失败
+     */
+    public boolean hmset(String key, Map<String, Object> map, long time) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @return true  成功  false失败
+     */
+    public boolean hset(String key, String item, Object value) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @param time  时间(秒)注意:如果已存在的hash表有时间,这里将会替换原有的时间
+     * @return true  成功  false失败
+     */
+    public boolean hset(String key, String item, Object value, long time) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 删除hash表中的值
+     *
+     * @param key  键  不能为null
+     * @param item 项  可以使多个  不能为null
+     */
+    public void hdel(String key, Object... item) {
+        redisTemplate.opsForHash().delete(key, item);
+    }
+
+    /**
+     * 判断hash表中是否有该项的值
+     *
+     * @param key  键  不能为null
+     * @param item 项  不能为null
+     * @return true  存在  false不存在
+     */
+    public boolean hHasKey(String key, String item) {
+        return redisTemplate.opsForHash().hasKey(key, item);
+    }
+
+    /**
+     * hash递增  如果不存在,就会创建一个  并把新增后的值返回
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要增加几(大于0)
+     * @return
+     */
+    public double hincr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, by);
+    }
+
+    /**
+     * hash递减
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要减少记(小于0)
+     * @return
+     */
+    public double hdecr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, -by);
+    }
+
+    //============================set=============================
+
+    /**
+     * 根据key获取Set中的所有值
+     *
+     * @param key 键
+     * @return
+     */
+    public Set<Object> sGet(String key) {
+        try {
+            return redisTemplate.opsForSet().members(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 根据value从一个set中查询,是否存在
+     *
+     * @param key   键
+     * @param value 值
+     * @return true  存在  false不存在
+     */
+    public boolean sHasKey(String key, Object value) {
+        try {
+            return redisTemplate.opsForSet().isMember(key, value);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将数据放入set缓存
+     *
+     * @param key    键
+     * @param values 值  可以是多个
+     * @return 成功个数
+     */
+    public long sSet(String key, Object... values) {
+        try {
+            return redisTemplate.opsForSet().add(key, values);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 将set数据放入缓存
+     *
+     * @param key    键
+     * @param time   时间(秒)
+     * @param values 值  可以是多个
+     * @return 成功个数
+     */
+    public long sSetAndTime(String key, long time, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().add(key, values);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 获取set缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long sGetSetSize(String key) {
+        try {
+            return redisTemplate.opsForSet().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 移除值为value的
+     *
+     * @param key    键
+     * @param values 值  可以是多个
+     * @return 移除的个数
+     */
+    public long setRemove(String key, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().remove(key, values);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    //===============================list=================================
+
+    /**
+     * 获取list缓存的内容
+     *
+     * @param key   键
+     * @param start 开始
+     * @param end   结束0  到  -1代表所有值
+     * @return
+     */
+    public List<Object> lGet(String key, long start, long end) {
+        try {
+            return redisTemplate.opsForList().range(key, start, end);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 获取list缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long lGetListSize(String key) {
+        try {
+            return redisTemplate.opsForList().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 通过索引  获取list中的值
+     *
+     * @param key   键
+     * @param index 索引index>=0时,  0  表头,1  第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+     * @return
+     */
+    public Object lGetIndex(String key, long index) {
+        try {
+            return redisTemplate.opsForList().index(key, index);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean lSet(String key, Object value) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean lSet(String key, Object value, long time) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean lSet(String key, List<Object> value) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean lSet(String key, List<Object> value, long time) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据索引修改list中的某条数据
+     *
+     * @param key   键
+     * @param index 索引
+     * @param value 值
+     * @return
+     */
+    public boolean lUpdateIndex(String key, long index, Object value) {
+        try {
+            redisTemplate.opsForList().set(key, index, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 移除N个值为value
+     *
+     * @param key   键
+     * @param count 移除多少个
+     * @param value 值
+     * @return 移除的个数
+     */
+    public long lRemove(String key, long count, Object value) {
+        try {
+            Long remove = redisTemplate.opsForList().remove(key, count, value);
+            return remove;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    public Collection<String> keys(final String pattern) {
+        return redisTemplate.keys(pattern);
+    }
+
+
+}

+ 113 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedissonClientAutoConfiguration.java

@@ -0,0 +1,113 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package cn.tr.module.common.redis;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.codec.SerializationCodec;
+import org.redisson.config.Config;
+import org.redisson.config.SingleServerConfig;
+import org.redisson.config.TransportMode;
+import org.redisson.connection.ConnectionListener;
+import org.redisson.spring.starter.RedissonProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+// 注意:移除了 @Primary 注解,避免与Spring Data Redis冲突
+import org.springframework.data.redis.core.RedisOperations;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+
+import java.net.InetSocketAddress;
+import java.time.Duration;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redisson客户端自动配置类
+ * 配置Redisson客户端连接,避免与Spring Data Redis冲突
+ */
+@Configuration
+@ConditionalOnClass({Redisson.class, RedisOperations.class})
+@AutoConfigureAfter({RedisAutoConfiguration.class, RedisConfig.class}) // 改为After,让Spring Data Redis先加载
+@EnableConfigurationProperties({RedissonProperties.class, RedisProperties.class})
+@Slf4j
+public class RedissonClientAutoConfiguration {
+
+    @Autowired
+    private RedisProperties redisProperties;
+
+    // 注入Spring的ObjectMapper,统一序列化
+    @Autowired(required = false)
+    private ObjectMapper objectMapper;
+
+    public RedissonClientAutoConfiguration() {
+    }
+
+    @Bean(
+            destroyMethod = "shutdown"
+    )
+    // 移除了 @Primary 注解,避免与Spring Data Redis的RedisTemplate冲突
+    public RedissonClient redissonClient() {
+        Config config = new Config();
+        SingleServerConfig singleServerConfig= config.useSingleServer();
+        singleServerConfig.setDatabase(redisProperties.getDatabase());
+        singleServerConfig.setPassword(redisProperties.getPassword());
+        singleServerConfig.setAddress("redis://"+redisProperties.getHost()+":"+redisProperties.getPort());
+        singleServerConfig.setPingConnectionInterval(0);
+        //  如果当前连接池里的连接数量超过了最小空闲连接数,而同时有连接空闲时间超过了该数值,那么这些连接将会自动被关闭,并从连接池里去掉。时间单位是毫秒。默认10000
+        singleServerConfig.setIdleConnectionTimeout(30000);
+        //建立连接时的等待超时。时间单位是毫秒。默认10000
+        singleServerConfig.setConnectTimeout(Long.valueOf(Optional.ofNullable(redisProperties.getConnectTimeout()).orElse(Duration.ofSeconds(3)).toMillis()).intValue());
+        //等待节点回复命令的时间。该时间从命令发送成功时开始计时。默认3000
+        singleServerConfig.setTimeout(Long.valueOf(Optional.ofNullable(redisProperties.getTimeout()).orElse(Duration.ofSeconds(3)).toMillis()).intValue());
+        //命令失败重试次数,如果尝试达到 retryAttempts(命令失败重试次数) 仍然不能将命令发送至某个指定的节点时,将抛出错误,如果尝试在此限制之内发送成功,则开始启用 timeout(命令等待超时) 计时。
+        singleServerConfig.setRetryAttempts(3);
+        //在一条命令发送失败以后,等待重试发送的时间间隔。时间单位是毫秒。默认1500
+        singleServerConfig.setRetryInterval(1500);
+        //每个连接的最大订阅数量。默认5
+        singleServerConfig.setSubscriptionsPerConnection(5000);
+        //在Redis节点里显示的客户端名称。默认null
+        singleServerConfig.setClientName("nb");
+        //用于发布和订阅连接的最小保持连接数(长连接)。Redisson内部经常通过发布和订阅来实现许多功能,长期保持一定数量的发布订阅连接是必须的。默认1
+        singleServerConfig.setSubscriptionConnectionMinimumIdleSize(1);
+        //多从节点的环境里,每个从服务节点里用于发布和订阅连接的连接池最大容量。连接池的连接数量自动弹性伸缩。默认50
+        singleServerConfig.setSubscriptionConnectionPoolSize(500);
+        //是否保持连接
+        singleServerConfig.setKeepAlive(false);
+        //这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。默认当前处理核数量 * 2
+        config.setThreads(Runtime.getRuntime().availableProcessors()*2);
+        // 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
+        config.setThreads(Runtime.getRuntime().availableProcessors()*2);
+        config.setTransportMode(TransportMode.NIO);
+        config.setCodec(new SerializationCodec());
+        config.setConnectionListener(new ConnectionListener() {
+            @Override
+            public void onConnect(InetSocketAddress addr) {
+                if(log.isDebugEnabled()){
+                    log.debug("redisson client connect success, addr : {}",addr.toString());
+                }
+            }
+
+            @Override
+            public void onDisconnect(InetSocketAddress addr) {
+                if(log.isDebugEnabled()){
+                    log.debug("redisson client disconnect success, addr : {}",addr.toString());
+                }
+            }
+        });
+        return Redisson.create(config);
+    }
+}

+ 42 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/Constants.java

@@ -0,0 +1,42 @@
+package cn.tr.module.common.utils;
+
+/**
+ * 常量类
+ *
+ * @author Kevin
+ */
+public class Constants {
+
+    /**
+     * header token
+     */
+    public static final String HEADER_TOKEN = "Authorization";
+
+    /**
+     * sa token, token session, user key
+     */
+    public static final String LOGIN_USER_KEY = "loginUser";
+
+    public static final String HOSPITAL_ID = "hospital_id";
+
+    /**
+     * redis缓存,系统字典缓存模板
+     */
+    public static final String SYS_DICT_TPL = "sys_dict:%s";
+    /**
+     * redis缓存,系统参数缓存模板
+     */
+    public static final String SYS_CONFIG_TPL = "sys_config:%s";
+
+    /**
+     * 所有权限常量
+     */
+    public static final String ALL_PERMISSION = "*:*:*";
+
+    /**
+     * 默认短信验证码
+     */
+    public static final String DEFAULT_SMS_CODE = "000000";
+
+
+}

+ 68 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/DictUtil.java

@@ -0,0 +1,68 @@
+package cn.tr.module.common.utils;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+
+import cn.tr.module.common.bo.DictModel;
+import cn.tr.module.common.redis.RedisUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 字典缓存工具类
+ *
+ * @author Kevin
+ */
+@Component
+public class DictUtil {
+
+
+    public static String getCacheKey(String key) {
+        return String.format(Constants.SYS_DICT_TPL, key);
+    }
+
+    public static List<DictModel> getDictList(String dictCode) {
+        Object obj = SpringUtil.getBean(RedisUtils.class).get(getCacheKey(dictCode));
+        return Objects.nonNull(obj) ? (List<DictModel>) obj : new ArrayList<>();
+    }
+
+
+    public static void clearDict(String dictCode) {
+         SpringUtil.getBean(RedisUtils.class).del(getCacheKey(dictCode));
+    }
+
+    public static String getDictLabel(String dictCode, String dictValue) {
+        if (StrUtil.isBlank(dictCode) || StrUtil.isBlank(dictValue)) {
+            return "";
+        }
+        List<DictModel> dictModelList = getDictList(dictCode);
+        DictModel dictModel = dictModelList.stream().filter(x -> x.getValue().equals(dictValue)).findFirst().orElse(null);
+        return Objects.nonNull(dictModel) ? dictModel.getLabel() : "";
+    }
+
+    public static String getDictValue(String dictCode, String dictLabel) {
+        if (StrUtil.isBlank(dictCode) || StrUtil.isBlank(dictLabel)) {
+            return "";
+        }
+        List<DictModel> dictModelList = getDictList(dictCode);
+        DictModel dictModel = dictModelList.stream().filter(x -> x.getLabel().equals(dictLabel)).findFirst().orElse(null);
+        return Objects.nonNull(dictModel) ? dictModel.getValue() : "";
+    }
+
+    public static void setDictCache(String dictCode, List<DictModel> dictModelList) {
+        if (StrUtil.isBlank(dictCode) || Objects.isNull(dictModelList) || dictModelList.isEmpty()) {
+            return;
+        }
+        SpringUtil.getBean(RedisUtils.class).set(getCacheKey(dictCode), dictModelList);
+    }
+
+    public static void clearDictCache() {
+        Collection<String> keys = SpringUtil.getBean(RedisUtils.class).keys(getCacheKey("*"));
+        SpringUtil.getBean(RedisUtils.class).del(keys.toArray(new String[0]));
+    }
+
+}

+ 70 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/ExcelUtil.java

@@ -0,0 +1,70 @@
+package cn.tr.module.common.utils;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.tr.module.common.menus.BizEnum;
+import cn.tr.module.common.properties.AppProperties;
+import cn.tr.module.excel.core.handler.write.CustomHorizontalCellStyleStrategy;
+import cn.tr.module.excel.core.utils.StyleUtils;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
+import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
+
+import lombok.extern.slf4j.Slf4j;
+
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Excel工具类
+ *
+ * @author Kevin
+ */
+@Slf4j
+public class ExcelUtil {
+    private static HorizontalCellStyleStrategy horizontalCellStyleStrategy =
+            new CustomHorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
+
+    public static String export(String filename, Class clazz, List list) {
+        return export(filename, clazz, list, filename);
+    }
+
+    public static String export(String filename, Class clazz, List list, String sheetName) {
+        filename = filename + "_" + IdUtil.fastSimpleUUID() + ".xlsx";
+        String filepath = "/" + BizEnum.TEMP.getCode() + "/" + DateUtil.today() + "/" + filename;
+        String absoluteFilepath = SpringUtil.getBean(AppProperties.class).getUploadDir() + filepath;
+        log.info("导出文件路径,{}", absoluteFilepath);
+        FileUtil.touch(absoluteFilepath);
+        EasyExcel.write(absoluteFilepath, clazz).head(clazz).sheet(sheetName).doWrite(list);
+        return filepath;
+    }
+
+    public static void exportResponse(HttpServletResponse response, String filename, Class clazz, List list) throws IOException {
+        ServletOutputStream outputStream = response.getOutputStream();
+        response.setHeader("content-type", "application/octet-stream;charset=UTF-8");
+        response.setContentType("application/octet-stream;charset=UTF-8");
+        ExcelWriter write = EasyExcel.write(outputStream, clazz).build();
+        createSheet(write,0,"全部数据",clazz,list);
+        IoUtil.flush(outputStream);
+        write.finish();
+        IoUtil.close(outputStream);
+    }
+
+    private static <T> void createSheet(ExcelWriter excelWriter, int sheetNo, String sheetName, Class<T> aClass, Collection<T> data){
+        WriteSheet writeSheet = EasyExcel.writerSheet(sheetNo, sheetName)
+                .registerWriteHandler(horizontalCellStyleStrategy)
+                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(13))
+                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 20))
+                .head(aClass).build();
+        excelWriter.write(data,writeSheet);
+    }
+}

+ 139 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/SecurityUtil.java

@@ -0,0 +1,139 @@
+package cn.tr.module.common.utils;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.secure.BCrypt;
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.hutool.core.util.StrUtil;
+
+import cn.tr.module.sys.oauth2.bean.LoginUser;
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+/**
+ * 安全服务工具类
+ *
+ * @author Kevin
+ */
+public class SecurityUtil {
+    public static final String LOGIN_USER_KEY="loginUser";
+    /**
+     * 获取用户账户
+     **/
+    public static String getUsername() {
+        return getLoginUser().getUsername();
+    }
+
+
+    /**
+     * 获取用户
+     **/
+    public static LoginUser getLoginUser(String authorization) {
+        try {
+            return (LoginUser) getStpLogic().getTokenSessionByToken(authorization).get(LOGIN_USER_KEY);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    /**
+     * 获取用户
+     **/
+    public static LoginUser getLoginUser() {
+        try {
+
+            return (LoginUser) getStpLogic().getTokenSession().get(LOGIN_USER_KEY);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    /**
+     * 获取用户
+     **/
+    public static void  setLogin(LoginUser loginUser) {
+        getStpLogic().getTokenSession().set(LOGIN_USER_KEY,loginUser);
+    }
+
+    public static boolean isSys(){
+        LoginUser loginUser = getLoginUser();
+        if(loginUser==null){
+            return false;
+        }
+        GrantTypeEnum grantType = loginUser.getGrantType();
+        if (GrantTypeEnum.APPKEY_APPSECRET.equals(grantType)) {
+            return false;
+        }
+        return Boolean.TRUE.equals(loginUser.isSys());
+    }
+
+    public static String getTenantId(){
+        return String.valueOf(SpringMVCUtil.getRequest().getAttribute("tenantId"));
+    }
+    /**
+     * 是否是超级管理员
+     **/
+    public static Boolean isSuperAdmin() {
+        return getLoginUser().isSuperAdmin();
+//        LoginUser loginUser = getLoginUser();
+//        String grantType = getLoginUser().getGrantType();
+//        if (GrantTypeEnum.APPKEY_APPSECRET.getValue().equalsIgnoreCase(grantType)) {
+//            return false;
+//        }
+//        List<SysRoleBO> roles = getSysUser().getRoles();
+//        if(CollUtil.isEmpty(roles)){
+//            return false;
+//        }
+//        return roles.stream().filter(role-> StrUtil.isNotBlank(role.getRoleCode()))
+//                .map(SysRoleBO::getRoleCode)
+//                .collect(Collectors.toSet())
+//                .contains("admin");
+    }
+
+    /**
+     * 是否是超级管理员
+     **/
+    public static Boolean isSysSuperAdmin(Long userId) {
+        return Objects.nonNull(userId) && userId == 1L;
+    }
+
+    /**
+     * 生成BCryptPasswordEncoder密码
+     *
+     * @param password 密码
+     * @return 加密字符串
+     */
+    public static String encryptPassword(String password) {
+        return BCrypt.hashpw(password);
+    }
+
+    /**
+     * 判断密码是否相同
+     *
+     * @param rawPassword     真实密码
+     * @param encodedPassword 加密后字符
+     * @return 结果
+     */
+    public static boolean matchesPassword(String rawPassword, String encodedPassword) {
+        return BCrypt.checkpw(rawPassword, encodedPassword);
+    }
+
+    public static Object getId() {
+        return getLoginUser().getId();
+    }
+
+
+    public static StpLogic getStpLogic(){
+        HttpServletRequest request = SpringMVCUtil.getRequest();
+        return getStpLogic(request.getHeader("Login-Type"));
+    }
+
+    public static StpLogic getStpLogic(String loginType){
+        String header ="";
+        if(!StrUtil.isNullOrUndefined(loginType)){
+            header=loginType;
+        };
+        return SaManager.getStpLogic(header);
+    }
+}

+ 19 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/TenantUtil.java

@@ -0,0 +1,19 @@
+package cn.tr.module.common.utils;
+
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.hutool.core.util.ObjectUtil;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName TeantUtil.java
+ * @Description TODO
+ * @createTime 2022年07月06日 13:59:00
+ */
+public class TenantUtil {
+    public static boolean isTuoRen(){
+        Object tenantId = SpringMVCUtil.getRequest().getAttribute("tenantId");
+        return ObjectUtil.equals(tenantId,"1");
+    }
+
+}

+ 20 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/exception/CustomException.java

@@ -0,0 +1,20 @@
+package cn.tr.module.sys.exception;
+
+import lombok.Data;
+
+/**
+ * 自定义异常
+ *
+ * @author Kevin
+ */
+@Data
+public class CustomException extends RuntimeException {
+
+    private Integer code;
+
+    private String message;
+
+    public CustomException(String message) {
+        this.message = message;
+    }
+}

+ 38 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/AuthInfo.java

@@ -0,0 +1,38 @@
+package cn.tr.module.sys.oauth2.bean;
+
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AuthInfo.java
+ * @Description TODO
+ * @createTime 2022年08月01日 14:28:00
+ */
+@Data
+@Tag(name = "授权结果")
+@Builder
+public class AuthInfo {
+
+    @Schema(description = "令牌")
+    private String token;
+    @Schema(description = "令牌在请求头中名称")
+    private String tokenName;
+    @Schema(description = "授权类型")
+    private GrantTypeEnum grantType;
+//    @Schema(description = "令牌失效时间")
+//    private long activityTimeout;
+    @Schema(description = "权限体系名称")
+    private String loginType;
+
+    private Date lastModifyPswTime;
+
+    @Schema(description = "是否需要修改密码")
+    private Boolean pswNeedReset;
+}

+ 101 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/LoginUser.java

@@ -0,0 +1,101 @@
+package cn.tr.module.sys.oauth2.bean;
+
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 登录用户
+ *
+ * @author Kevin
+ */
+@Data
+public class LoginUser<T> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private T Id;
+    /**
+     * token
+     */
+    private String token;
+
+    /**
+     * 用户平台
+     */
+    private String userPlatform;
+
+    /**
+     * 授权类型
+     */
+    private GrantTypeEnum grantType;
+
+    /**
+     * 用户名 或者 appkey
+     */
+    private String username;
+
+    private String nickName;
+    /**
+     * 登录时间
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date loginTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipAddress;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+    /**
+     * 权限列表
+     */
+    private Set<String> permissions;
+
+    /**
+     * 角色列表
+     */
+    private List<SysRoleInfo> roles;
+
+    @Schema(defaultValue = "权限体系名称")
+    private String loginType;
+
+    private T tenantId;
+
+    /**
+     * 是否为系统级别用户
+     *
+     **/
+    private boolean isSys;
+
+    /**
+     * 是否为超级管理员
+     */
+    private boolean isSuperAdmin;
+
+    private Boolean pswNeedReset=false;
+
+    private Date lastModifyPswTime;
+}

+ 40 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/SysRoleInfo.java

@@ -0,0 +1,40 @@
+package cn.tr.module.sys.oauth2.bean;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 角色
+ *
+ * @author Kevin
+ */
+@Data
+public class SysRoleInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    /**
+     * 角色编码
+     */
+    private String code;
+
+    /**
+     * 角色名称
+     */
+    private String name;
+
+    /**
+     * 数据范围 1全部数据权限;2自定数据权限;3本部门数据权限;4本部门及以下数据权限
+     */
+    private String dataScope;
+
+}

+ 42 - 42
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/config/StdStpInterface.java

@@ -1,42 +1,42 @@
-package cn.tr.module.sys.oauth2.config;
-
-import cn.dev33.satoken.SaManager;
-import cn.dev33.satoken.stp.StpInterface;
-import cn.tr.module.sys.oauth2.service.CurrentUserService;
-import jakarta.annotation.PostConstruct;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @ClassName : StdStpInterface
- * @Description :
- * @Author : LF
- * @Date: 2023年05月30日
- */
-@Component
-public class StdStpInterface implements StpInterface {
-    @Autowired
-    private CurrentUserService currentUserService;
-    @Autowired
-    @Lazy
-    private StdStpInterface self;
-
-    @PostConstruct
-    public void init(){
-        SaManager.setStpInterface(self);
-    }
-
-    @Override
-    public List<String> getPermissionList(Object loginId, String loginType) {
-        return new ArrayList<>(currentUserService.currentUserPermission(String.valueOf(loginId)));
-    }
-
-    @Override
-    public List<String> getRoleList(Object loginId, String loginType) {
-        return new ArrayList<>(currentUserService.currentUserRoleCode());
-    }
-}
+//package cn.tr.module.sys.oauth2.config;
+//
+//import cn.dev33.satoken.SaManager;
+//import cn.dev33.satoken.stp.StpInterface;
+//import cn.tr.module.sys.oauth2.service.CurrentUserService;
+//import jakarta.annotation.PostConstruct;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Lazy;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+///**
+// * @ClassName : StdStpInterface
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年05月30日
+// */
+//@Component
+//public class StdStpInterface implements StpInterface {
+//    @Autowired
+//    private CurrentUserService currentUserService;
+//    @Autowired
+//    @Lazy
+//    private StdStpInterface self;
+//
+//    @PostConstruct
+//    public void init(){
+//        SaManager.setStpInterface(self);
+//    }
+//
+//    @Override
+//    public List<String> getPermissionList(Object loginId, String loginType) {
+//        return new ArrayList<>(currentUserService.currentUserPermission(String.valueOf(loginId)));
+//    }
+//
+//    @Override
+//    public List<String> getRoleList(Object loginId, String loginType) {
+//        return new ArrayList<>(currentUserService.currentUserRoleCode());
+//    }
+//}

+ 93 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/AuthController.java

@@ -0,0 +1,93 @@
+package cn.tr.module.sys.oauth2.controller;
+
+import cn.tr.core.pojo.CommonResult;
+import cn.tr.module.common.annotation.Log;
+import cn.tr.module.common.exception.CustomException;
+import cn.tr.module.sys.oauth2.bean.AuthInfo;
+import cn.tr.module.sys.oauth2.bean.LoginUser;
+import cn.tr.module.sys.oauth2.granter.IAuthGranter;
+import cn.tr.module.sys.oauth2.granter.TokenParameter;
+import cn.tr.module.sys.oauth2.utils.SecurityUtil;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AutController.java
+ * @Description 授权接口
+ * @createTime 2022年08月01日 13:33:00
+ */
+@RestController
+@Tag(name = "登录、授权接口")
+public class AuthController {
+
+    private final List<IAuthGranter> tokenGranter;
+
+    public AuthController(List<IAuthGranter> tokenGranter) {
+        this.tokenGranter = tokenGranter;
+    }
+
+    @Value("${sa-token.token-name}")
+    private String tokenName;
+
+//    @Value("${sa-token.activity-timeout}")
+//    private Long activityTimeout;
+
+    @PostMapping({"/login","/token"})
+    @Operation(summary = "登录")
+    public CommonResult<AuthInfo> login(@Validated @RequestBody TokenParameter req) {
+        if(req.getGrantType()==null){
+            throw new CustomException("授权类型不能为空");
+        }
+        Optional<IAuthGranter> granter = tokenGranter.stream().filter(grant -> req.getGrantType().equals(grant.getType()))
+                .findFirst();
+        if(!granter.isPresent()){
+            throw new CustomException("暂不支持该登录方式");
+        }
+        //对应web还是APP的登录方式
+        LoginUser grant = granter.get().grant(req);
+        return CommonResult.success(AuthInfo.builder()
+//                .activityTimeout(activityTimeout)
+                .grantType(req.getGrantType())//登录类型
+                .loginType(grant.getLoginType())//权限体系名称StpTypeEnum.DEFAULT.getText()
+                .token(grant.getToken())//toaken
+                .pswNeedReset(grant.getPswNeedReset())//密码是否重置
+                .lastModifyPswTime(grant.getLastModifyPswTime())//获取最后修改密码时间
+                .build());
+    }
+
+//    /*
+//     * 根据键值,获取value
+//     */
+//    @ApiOperation("刷新token时间")
+//    @GetMapping("/refresh")
+//    public R getTime() {
+//        if (SecurityUtil.getStpLogic().isLogin()) {
+//            try {
+//                SecurityUtil.getStpLogic().checkActivityTimeout();
+//                //手动续签
+//                SecurityUtil.getStpLogic().updateLastActivityToNow();
+//            }catch (Exception e){
+//
+//            }
+//        }
+//        return R.success();
+//    }
+
+    @Log(title = "退出")
+    @Operation(summary = "用户登出")
+    @PostMapping("/logout")
+    public CommonResult logout() {
+        SecurityUtil.getStpLogic().logout();
+        return CommonResult.success();
+    }
+}

+ 46 - 46
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/CaptchaController.java

@@ -1,46 +1,46 @@
-package cn.tr.module.sys.oauth2.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.module.sys.oauth2.config.CaptchaOperator;
-import com.wf.captcha.ArithmeticCaptcha;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
-import org.springframework.web.bind.annotation.*;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import java.awt.*;
-import java.io.IOException;
-
-/**
- * 验证码
- *
- * @author tr
- */
-@Tag(name = "验证码")
-@RestController
-@RequestMapping("/auth/captcha")
-@AllArgsConstructor
-public class CaptchaController {
-
-    private final CaptchaOperator captchaTool;
-
-    @GetMapping
-    @SaIgnore
-    @Operation(summary = "获取验证码", description = "生成并返回算术验证码图片")
-    public void get(@Parameter(description = "验证码key") @RequestParam("key") String key,
-                    HttpServletRequest request, HttpServletResponse response) {
-        // 算术类型
-        ArithmeticCaptcha captcha = new ArithmeticCaptcha(140, 38);
-        // 设置字体
-        captcha.setFont(new Font("Verdana", Font.PLAIN, 32));
-        try {
-            captchaTool.out(key, captcha, response);
-        } catch (IOException e) {
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001, "系统繁忙,请稍后再试");
-        }
-    }
-}
+//package cn.tr.module.sys.oauth2.controller;
+//
+//import cn.dev33.satoken.annotation.SaIgnore;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.module.sys.oauth2.config.CaptchaOperator;
+//import com.wf.captcha.ArithmeticCaptcha;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//import lombok.AllArgsConstructor;
+//import org.springframework.web.bind.annotation.*;
+//import jakarta.servlet.http.HttpServletRequest;
+//import jakarta.servlet.http.HttpServletResponse;
+//import java.awt.*;
+//import java.io.IOException;
+//
+///**
+// * 验证码
+// *
+// * @author tr
+// */
+//@Tag(name = "验证码")
+//@RestController
+//@RequestMapping("/auth/captcha")
+//@AllArgsConstructor
+//public class CaptchaController {
+//
+//    private final CaptchaOperator captchaTool;
+//
+//    @GetMapping
+//    @SaIgnore
+//    @Operation(summary = "获取验证码", description = "生成并返回算术验证码图片")
+//    public void get(@Parameter(description = "验证码key") @RequestParam("key") String key,
+//                    HttpServletRequest request, HttpServletResponse response) {
+//        // 算术类型
+//        ArithmeticCaptcha captcha = new ArithmeticCaptcha(140, 38);
+//        // 设置字体
+//        captcha.setFont(new Font("Verdana", Font.PLAIN, 32));
+//        try {
+//            captchaTool.out(key, captcha, response);
+//        } catch (IOException e) {
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001, "系统繁忙,请稍后再试");
+//        }
+//    }
+//}

+ 121 - 121
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/CurrentUserController.java

@@ -1,122 +1,122 @@
-package cn.tr.module.sys.oauth2.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.pojo.CommonResult;
-import cn.tr.core.tree.TreeBuilder;
-import cn.tr.module.sys.oauth2.dto.AccountUserInfoEditDTO;
-import cn.tr.module.sys.oauth2.psw.operator.AbstractOAuth2PswUserOperator;
-import cn.tr.module.sys.oauth2.psw.operator.OAuth2PswUserOperatorManager;
-import cn.tr.module.sys.oauth2.service.CurrentUserService;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
-import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
-import cn.tr.module.sys.user.enums.MenuEnum;
-import cn.tr.module.sys.user.service.ISysMenuService;
-import cn.tr.module.sys.user.vo.RouteItemVO;
-import cn.tr.plugin.security.context.LoginUserContextHolder;
-import cn.tr.plugin.security.utils.SaTokenUtils;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName : CurrentUserController
- * @Description :
- * @Author : LF
- * @Date: 2023年04月01日
- */
-@RestController
-@RequestMapping("/user")
-@Tag(name = "当前账号用户操作")
-@AllArgsConstructor
-public class CurrentUserController {
-    private final OAuth2PswUserOperatorManager pswUserOperatorManager;
-    private final CurrentUserService currentUserService;
-    private final ISysMenuService menuService;
-
-    @Operation(summary = "当前用户的登陆信息", description = "获取当前登录用户的基本信息")
-    @GetMapping("/loginInfo")
-    public CommonResult loginInfo(){
-        SaTokenUtils.getStpUtil().checkLogin();
-        String stpType = LoginUserContextHolder.getStpType();
-        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
-        if(operator==null){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
-        }
-        return CommonResult.success(operator.getUserLoginInfo());
-    }
-
-    @Operation(summary = "获取登录用户的权限信息", description = "获取当前登录用户的所有权限标识集合")
-    @GetMapping("/getPermissionInfo")
-    public CommonResult<Collection<String>> getPermissionInfo() {
-        SaTokenUtils.getStpUtil().checkLogin();
-        return CommonResult.success(currentUserService.currentUserPermission(String.valueOf(SaTokenUtils.getStpUtil().getLoginId())));
-    }
-
-    @Operation(summary = "获得登录用户的菜单列表", description = "根据门户ID获取当前登录用户的菜单路由信息")
-    @GetMapping("/listMenus-{portalId}")
-    public CommonResult<List<RouteItemVO>> getMenus(@Parameter(description = "门户ID") @PathVariable(value = "portalId",required = false) String portalId) {
-        return CommonResult.success(TreeBuilder.buildTree(currentUserService.currentUserMenus(portalId)));
-    }
-
-    //C端程序无用
-//    @Operation(summary = "查询匿名菜单树", description = "查询匿名菜单树")
-//    @PostMapping("/listAnonymousMenus")
-//    @SaIgnore
-//    public CommonResult<List<RouteItemVO>> getListAnonymousMenus() {
-//        List<SysMenuDTO> anonymousMenus = menuService.findAnonymousMenus();
-//        return CommonResult.success(TreeBuilder.buildTree(anonymousMenus
-//                .stream()
-//                .collect(Collectors.groupingBy(SysMenuDTO::getId, Collectors.collectingAndThen(Collectors.toList(), CollUtil::getFirst)))
-//                //未重复的菜单
-//                .values()
-//                .stream()
-//                .filter(menu -> !StrUtil.equals(MenuEnum.button.name(), menu.getMenuType()))
-//                .filter(menu-> Boolean.TRUE.equals(menu.getVisible()))
-//                .map(menuService::convertToRoute)
-//                .collect(Collectors.toList())));
+//package cn.tr.module.sys.oauth2.controller;
+//
+//import cn.dev33.satoken.annotation.SaIgnore;
+//import cn.hutool.core.collection.CollUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.core.pojo.CommonResult;
+//import cn.tr.core.tree.TreeBuilder;
+//import cn.tr.module.sys.oauth2.dto.AccountUserInfoEditDTO;
+//import cn.tr.module.sys.oauth2.psw.operator.AbstractOAuth2PswUserOperator;
+//import cn.tr.module.sys.oauth2.psw.operator.OAuth2PswUserOperatorManager;
+//import cn.tr.module.sys.oauth2.service.CurrentUserService;
+//import cn.tr.module.sys.user.dto.SysMenuDTO;
+//import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
+//import cn.tr.module.sys.user.enums.MenuEnum;
+//import cn.tr.module.sys.user.service.ISysMenuService;
+//import cn.tr.module.sys.user.vo.RouteItemVO;
+//import cn.tr.plugin.security.context.LoginUserContextHolder;
+//import cn.tr.plugin.security.utils.SaTokenUtils;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//import lombok.AllArgsConstructor;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.*;
+//
+//import java.util.Collection;
+//import java.util.List;
+//import java.util.stream.Collectors;
+//
+///**
+// * @ClassName : CurrentUserController
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月01日
+// */
+//@RestController
+//@RequestMapping("/user")
+//@Tag(name = "当前账号用户操作")
+//@AllArgsConstructor
+//public class CurrentUserController {
+//    private final OAuth2PswUserOperatorManager pswUserOperatorManager;
+//    private final CurrentUserService currentUserService;
+//    private final ISysMenuService menuService;
+//
+//    @Operation(summary = "当前用户的登陆信息", description = "获取当前登录用户的基本信息")
+//    @GetMapping("/loginInfo")
+//    public CommonResult loginInfo(){
+//        SaTokenUtils.getStpUtil().checkLogin();
+//        String stpType = LoginUserContextHolder.getStpType();
+//        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
+//        if(operator==null){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
+//        }
+//        return CommonResult.success(operator.getUserLoginInfo());
 //    }
-
-    @Operation(summary = "获取登录用户的门户列表", description = "获取当前登录用户可访问的所有门户信息")
-    @GetMapping("/listPortal")
-    public CommonResult<List<SysUserPortalListDTO>> getPortals() {
-        SaTokenUtils.getStpUtil().checkLogin();
-        return CommonResult.success(currentUserService.currentUserPortals());
-    }
-
-    @Operation(summary = "当前用户的个人账户中心信息", description = "获取当前登录用户的个人账户详细信息")
-    @GetMapping("/accountInfo")
-    public CommonResult accountInfo(){
-        SaTokenUtils.getStpUtil().checkLogin();
-        String stpType = LoginUserContextHolder.getStpType();
-        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
-        if(operator==null){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
-        }
-        return CommonResult.success(operator.getAccountInfo());
-    }
-
-    @Operation(summary = "更新用户的个人账户中心信息", description = "更新当前登录用户的个人账户信息")
-    @PostMapping("/updateAccountInfo")
-    public CommonResult<Boolean> updateAccountInfo(@Parameter(description = "账户信息编辑DTO") @RequestBody AccountUserInfoEditDTO source){
-        SaTokenUtils.getStpUtil().checkLogin();
-        String stpType = LoginUserContextHolder.getStpType();
-        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
-        if(operator==null){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
-        }
-        operator.updateAccountUserInfo(LoginUserContextHolder.getUser().getUserId(),source);
-        return CommonResult.success(true);
-    }
-
-}
+//
+//    @Operation(summary = "获取登录用户的权限信息", description = "获取当前登录用户的所有权限标识集合")
+//    @GetMapping("/getPermissionInfo")
+//    public CommonResult<Collection<String>> getPermissionInfo() {
+//        SaTokenUtils.getStpUtil().checkLogin();
+//        return CommonResult.success(currentUserService.currentUserPermission(String.valueOf(SaTokenUtils.getStpUtil().getLoginId())));
+//    }
+//
+//    @Operation(summary = "获得登录用户的菜单列表", description = "根据门户ID获取当前登录用户的菜单路由信息")
+//    @GetMapping("/listMenus-{portalId}")
+//    public CommonResult<List<RouteItemVO>> getMenus(@Parameter(description = "门户ID") @PathVariable(value = "portalId",required = false) String portalId) {
+//        return CommonResult.success(TreeBuilder.buildTree(currentUserService.currentUserMenus(portalId)));
+//    }
+//
+//    //C端程序无用
+////    @Operation(summary = "查询匿名菜单树", description = "查询匿名菜单树")
+////    @PostMapping("/listAnonymousMenus")
+////    @SaIgnore
+////    public CommonResult<List<RouteItemVO>> getListAnonymousMenus() {
+////        List<SysMenuDTO> anonymousMenus = menuService.findAnonymousMenus();
+////        return CommonResult.success(TreeBuilder.buildTree(anonymousMenus
+////                .stream()
+////                .collect(Collectors.groupingBy(SysMenuDTO::getId, Collectors.collectingAndThen(Collectors.toList(), CollUtil::getFirst)))
+////                //未重复的菜单
+////                .values()
+////                .stream()
+////                .filter(menu -> !StrUtil.equals(MenuEnum.button.name(), menu.getMenuType()))
+////                .filter(menu-> Boolean.TRUE.equals(menu.getVisible()))
+////                .map(menuService::convertToRoute)
+////                .collect(Collectors.toList())));
+////    }
+//
+//    @Operation(summary = "获取登录用户的门户列表", description = "获取当前登录用户可访问的所有门户信息")
+//    @GetMapping("/listPortal")
+//    public CommonResult<List<SysUserPortalListDTO>> getPortals() {
+//        SaTokenUtils.getStpUtil().checkLogin();
+//        return CommonResult.success(currentUserService.currentUserPortals());
+//    }
+//
+//    @Operation(summary = "当前用户的个人账户中心信息", description = "获取当前登录用户的个人账户详细信息")
+//    @GetMapping("/accountInfo")
+//    public CommonResult accountInfo(){
+//        SaTokenUtils.getStpUtil().checkLogin();
+//        String stpType = LoginUserContextHolder.getStpType();
+//        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
+//        if(operator==null){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
+//        }
+//        return CommonResult.success(operator.getAccountInfo());
+//    }
+//
+//    @Operation(summary = "更新用户的个人账户中心信息", description = "更新当前登录用户的个人账户信息")
+//    @PostMapping("/updateAccountInfo")
+//    public CommonResult<Boolean> updateAccountInfo(@Parameter(description = "账户信息编辑DTO") @RequestBody AccountUserInfoEditDTO source){
+//        SaTokenUtils.getStpUtil().checkLogin();
+//        String stpType = LoginUserContextHolder.getStpType();
+//        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
+//        if(operator==null){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
+//        }
+//        operator.updateAccountUserInfo(LoginUserContextHolder.getUser().getUserId(),source);
+//        return CommonResult.success(true);
+//    }
+//
+//}

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

@@ -1,100 +1,100 @@
-package cn.tr.module.sys.oauth2.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.enums.LoginScopeType;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.pojo.CommonResult;
-import cn.tr.core.utils.PswUtils;
-import cn.tr.module.sys.oauth2.dto.OAuth2UpdatePswDTO;
-import cn.tr.module.sys.oauth2.psw.operator.AbstractOAuth2PswUserOperator;
-import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
-import cn.tr.module.sys.oauth2.psw.operator.OAuth2PswUserOperatorManager;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import cn.tr.module.api.sys.log.enums.LoginType;
-import cn.tr.plugin.security.context.LoginUserContextHolder;
-import cn.tr.plugin.security.utils.SaTokenUtils;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * @ClassName : OAuth2ServerController
- * @Description : oauth2接口
- * @Author : LF
- * @Date: 2023年03月31日
- */
-@RestController
-@RequestMapping("/login")
-@Tag(name = "密码登录")
-@AllArgsConstructor
-public class OAuth2ServerController {
-    private final OAuth2PswUserOperatorManager pswUserOperatorManager;
-
-    @Operation(summary = "账号密码登录", description = "通过用户名和密码获取token")
-    @ApiOperationSupport(author = "lf")
-    @PostMapping({"/token","psw"})
-    @OperateLog(loginType = LoginType.login,logArgs = false,logResultData = false)
-    @SaIgnore
-    public CommonResult<Object> pswLogin(@RequestBody OAuth2PswReqDTO source) {
-        AbstractOAuth2PswUserOperator abstractOAuth2PswUserOperator = pswUserOperatorManager.matchLoginType(LoginScopeType.LOGIN_SCOPE_TYPE_NORMAL);
-        if(abstractOAuth2PswUserOperator==null){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,"登录失败");
-        }
-        return CommonResult.success(abstractOAuth2PswUserOperator.auth(source));
-    }
-
-    @Operation(summary = "微信登录", description = "微信登录获取token")
-    @ApiOperationSupport(author = "lf")
-    @PostMapping("/wx")
-    @OperateLog(loginType = LoginType.login,logArgs = false,logResultData = false)
-    @SaIgnore
-    public CommonResult<Object> wxLogin(@RequestBody OAuth2PswReqDTO source) {
-        AbstractOAuth2PswUserOperator abstractOAuth2PswUserOperator = pswUserOperatorManager.matchLoginType(LoginScopeType.LOGIN_SCOPE_TYPE_WX);
-        if(abstractOAuth2PswUserOperator==null){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,"登录失败");
-        }
-        return CommonResult.success(abstractOAuth2PswUserOperator.auth(source));
-    }
-
-
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "更新当前用户密码", description = "修改当前登录用户的密码")
-    @PostMapping("/updatePsw")
-    @SaIgnore
-    public CommonResult<Boolean> updatePsw(@Parameter(description = "密码更新参数") @RequestBody @Validated OAuth2UpdatePswDTO source){
-        String stpType = LoginUserContextHolder.getStpType();
-        if (StrUtil.isEmpty(stpType)) {
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,"账号体系不能为空");
-        }
-        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
-        if(operator==null){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
-        }
-        String confirmPsw = source.getConfirmPsw();
-        String newPsw = source.getNewPsw();
-        PswUtils.validatePsw(newPsw);
-        if(!StrUtil.equals(confirmPsw,newPsw)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"新密码与确认密码不相同,修改密码失败");
-        }
-        if(StrUtil.equals(source.getOldPsw(),newPsw)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"旧密码与新密码不能一样");
-        }
-        return CommonResult.success(operator
-                .updatePsw(source.getOldPsw(),source.getNewPsw()));
-    }
-
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "退出登录", description = "注销当前用户的登录状态")
-    @PostMapping("/logout")
-    @OperateLog(loginType = LoginType.logout,logResultData = false,logArgs = false)
-    public CommonResult<Boolean> logout(){
-        SaTokenUtils.logout();
-        return CommonResult.success(true);
-    }
-}
+//package cn.tr.module.sys.oauth2.controller;
+//
+//import cn.dev33.satoken.annotation.SaIgnore;
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.core.enums.LoginScopeType;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.core.pojo.CommonResult;
+//import cn.tr.core.utils.PswUtils;
+//import cn.tr.module.sys.oauth2.dto.OAuth2UpdatePswDTO;
+//import cn.tr.module.sys.oauth2.psw.operator.AbstractOAuth2PswUserOperator;
+//import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
+//import cn.tr.module.sys.oauth2.psw.operator.OAuth2PswUserOperatorManager;
+//import cn.tr.module.api.sys.log.annotation.OperateLog;
+//import cn.tr.module.api.sys.log.enums.LoginType;
+//import cn.tr.plugin.security.context.LoginUserContextHolder;
+//import cn.tr.plugin.security.utils.SaTokenUtils;
+//import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//import lombok.AllArgsConstructor;
+//import org.springframework.validation.annotation.Validated;
+//import org.springframework.web.bind.annotation.*;
+//
+///**
+// * @ClassName : OAuth2ServerController
+// * @Description : oauth2接口
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//@RestController
+//@RequestMapping("/login")
+//@Tag(name = "密码登录")
+//@AllArgsConstructor
+//public class OAuth2ServerController {
+//    private final OAuth2PswUserOperatorManager pswUserOperatorManager;
+//
+//    @Operation(summary = "账号密码登录", description = "通过用户名和密码获取token")
+//    @ApiOperationSupport(author = "lf")
+//    @PostMapping({"/token","psw"})
+//    @OperateLog(loginType = LoginType.login,logArgs = false,logResultData = false)
+//    @SaIgnore
+//    public CommonResult<Object> pswLogin(@RequestBody OAuth2PswReqDTO source) {
+//        AbstractOAuth2PswUserOperator abstractOAuth2PswUserOperator = pswUserOperatorManager.matchLoginType(LoginScopeType.LOGIN_SCOPE_TYPE_NORMAL);
+//        if(abstractOAuth2PswUserOperator==null){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,"登录失败");
+//        }
+//        return CommonResult.success(abstractOAuth2PswUserOperator.auth(source));
+//    }
+//
+//    @Operation(summary = "微信登录", description = "微信登录获取token")
+//    @ApiOperationSupport(author = "lf")
+//    @PostMapping("/wx")
+//    @OperateLog(loginType = LoginType.login,logArgs = false,logResultData = false)
+//    @SaIgnore
+//    public CommonResult<Object> wxLogin(@RequestBody OAuth2PswReqDTO source) {
+//        AbstractOAuth2PswUserOperator abstractOAuth2PswUserOperator = pswUserOperatorManager.matchLoginType(LoginScopeType.LOGIN_SCOPE_TYPE_WX);
+//        if(abstractOAuth2PswUserOperator==null){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,"登录失败");
+//        }
+//        return CommonResult.success(abstractOAuth2PswUserOperator.auth(source));
+//    }
+//
+//
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "更新当前用户密码", description = "修改当前登录用户的密码")
+//    @PostMapping("/updatePsw")
+//    @SaIgnore
+//    public CommonResult<Boolean> updatePsw(@Parameter(description = "密码更新参数") @RequestBody @Validated OAuth2UpdatePswDTO source){
+//        String stpType = LoginUserContextHolder.getStpType();
+//        if (StrUtil.isEmpty(stpType)) {
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,"账号体系不能为空");
+//        }
+//        AbstractOAuth2PswUserOperator operator = pswUserOperatorManager.matchLoginType(stpType);
+//        if(operator==null){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0200,String.format("账号体系[{%s}]不存在",stpType));
+//        }
+//        String confirmPsw = source.getConfirmPsw();
+//        String newPsw = source.getNewPsw();
+//        PswUtils.validatePsw(newPsw);
+//        if(!StrUtil.equals(confirmPsw,newPsw)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"新密码与确认密码不相同,修改密码失败");
+//        }
+//        if(StrUtil.equals(source.getOldPsw(),newPsw)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"旧密码与新密码不能一样");
+//        }
+//        return CommonResult.success(operator
+//                .updatePsw(source.getOldPsw(),source.getNewPsw()));
+//    }
+//
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "退出登录", description = "注销当前用户的登录状态")
+//    @PostMapping("/logout")
+//    @OperateLog(loginType = LoginType.logout,logResultData = false,logArgs = false)
+//    public CommonResult<Boolean> logout(){
+//        SaTokenUtils.logout();
+//        return CommonResult.success(true);
+//    }
+//}

+ 51 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/enums/GrantTypeEnum.java

@@ -0,0 +1,51 @@
+package cn.tr.module.sys.oauth2.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+/**
+ * 授权类型
+ *
+ * @author Kevin
+ */
+@Getter
+@AllArgsConstructor
+public enum GrantTypeEnum{
+
+    /**
+     * 网页端用户名密码模式
+     */
+    WEB_USERNAME_PASSWORD("1", "用户名密码模式"),
+    /**
+     * 手机号短信模式
+     */
+    MOBILE_CODE("2", "手机号短信模式"),
+
+    /**
+     * appkey、appSecret模式
+     */
+    APPKEY_APPSECRET("3", "第三方应用登录"),
+
+    /**
+     * appkey、appSecret模式
+     */
+    APP_DOCTOR("4", "app医生登录");
+
+
+    private String code;
+    private String desc;
+
+
+    public static Boolean contains(String code) {
+        return Arrays.stream(GrantTypeEnum.values()).anyMatch(temp -> temp.getCode().equals(code));
+    }
+
+    public static GrantTypeEnum valueOfCode(String code) {
+        Optional<GrantTypeEnum> first = Arrays.stream(GrantTypeEnum.values()).filter(temp -> temp.getCode().equals(code)).findFirst();
+        return
+                first.isPresent()?first.get():null;
+    }
+}

+ 27 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/enums/StpTypeEnum.java

@@ -0,0 +1,27 @@
+package cn.tr.module.sys.oauth2.enums;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName StpConstant.java
+ * @Description TODO
+ * @createTime 2022年08月09日 22:00:00
+ */
+@Getter
+@AllArgsConstructor
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum  StpTypeEnum implements IEnum<Integer> {
+    DEFAULT(1,"默认登录体系","login"),
+    APP_DOCTOR(2,"app医生端登录体系","app_doctor")
+    ;
+
+    private Integer value;
+    private String desc;
+    private String text;
+}
+

+ 68 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/IAccountOperator.java

@@ -0,0 +1,68 @@
+package cn.tr.module.sys.oauth2.granter;
+
+
+
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+import cn.tr.module.sys.oauth2.vo.UserInfoVO;
+import cn.tr.module.sys.user.vo.RouteItemVO;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName IAccountOperator.java
+ * @Description 账户操作符
+ * @createTime 2022年08月01日 14:45:00
+ */
+public interface IAccountOperator<T> {
+
+    /**
+     * 描述: 匹配登录方式
+     * @author lifang
+     * @date 2022/8/9 22:08
+     * @param type
+     * @return boolean
+     */
+    boolean matchGrantType(GrantTypeEnum type);
+
+    /**
+     * 描述: 获取当前用户信息
+     * @author lifang
+     * @date 2022/8/1 14:39
+     * @param
+     * @return UserInfoVO
+     */
+    UserInfoVO getUserInfo();
+
+    /**
+     * 描述: 获取当前用户权限标识
+     * @author lifang
+     * @date 2022/8/1 14:39
+     * @return Set<String>
+     */
+    Set<String> getPermCode();
+
+    /**
+     * 描述: 获取当前用户菜单列表
+     * @author lifang
+     * @date 2022/8/1 14:39
+     * @return Set<String>
+     */
+    List<RouteItemVO> getMenuList();
+
+
+//    AccountInfoVO<T> getAccountInfo();
+
+    /**
+     * 描述: 设置当前用户账户信息
+     * @author lifang
+     * @date 2022/8/1 14:39
+     * @param req 账户信息
+     * @return Set<String>
+     */
+//    void saveAccountInfo(AccountInfoVO<T> req);
+
+    boolean updatePass(String oldPass, String newPass);
+}

+ 70 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/IAuthGranter.java

@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.tr.module.sys.oauth2.granter;
+
+
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import cn.tr.module.sys.oauth2.bean.LoginUser;
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+
+
+import cn.tr.module.sys.oauth2.utils.AddressUtil;
+import cn.tr.module.sys.oauth2.utils.IpUtil;
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+/**
+ * 授权认证统一接口.
+ *IAuthGranter
+ * @author Chill
+ */
+public interface IAuthGranter {
+
+	/**
+	 * 描述: 授权类型
+	 * @author lifang
+	 * @date 2022/8/1 14:46
+	 * @param
+	 */
+	GrantTypeEnum getType();
+	/**
+	 * 获取用户信息
+	 *
+	 * @param source 授权参数
+	 * @return UserInfo
+	 */
+	LoginUser grant(TokenParameter source);
+
+	/**
+	 * 描述: 填充用户登录信息
+	 * @author lifang
+	 * @date 2022/8/1 15:22
+	 * @param loginUser
+	 * @return void
+	 */
+	default void fillUserAgentInfo(LoginUser loginUser){
+		HttpServletRequest request = SpringMVCUtil.getRequest();
+		UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
+		String ipAddress = IpUtil.getClientIp(request);
+		loginUser.setIpAddress(ipAddress);
+		loginUser.setLoginLocation(AddressUtil.getRealAddressByIp(ipAddress));
+		loginUser.setBrowser(userAgent.getBrowser().getName());
+		loginUser.setOs(userAgent.getOs().getName());
+		loginUser.setLoginTime(new Date());
+	};
+}

+ 45 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/TokenParameter.java

@@ -0,0 +1,45 @@
+package cn.tr.module.sys.oauth2.granter;
+
+
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 登录实体类
+ *
+ * @author Kevin
+ */
+@Data
+public class TokenParameter implements Serializable {
+
+    @Schema(description = "授权方式 ",allowableValues = "1(web账密登录), 2 (手机短信登录),3(第三方应用登陆), 4(app医生登录), 5(疼痛小管家手机账密登录)6(疼痛小管家手机一键登录)")
+    GrantTypeEnum grantType;
+
+    @Schema(description = "用户名 账密登录、app医生登录、疼痛小管家账密(此处用户名即为用户的手机号)登录时使用")
+    String username;
+
+    @Schema(description = "密码  账密登录、app医生登录、疼痛小管家账密登录时使用")
+    String password;
+
+    @Schema(description = "验证码,web账密登录、疼痛小管家手机验证码时使用")
+    String code;
+
+    @Schema(description = "验证码key,web账密登录时使用")
+    String codeKey;
+
+    @Schema(description = "第三方应用登陆时使用")
+    String appKey;
+
+    @Schema(description = "第三方应用登录时使用时的签名")
+    String sign;
+
+    @Schema(description = "第三方应用登录时使用的时间戳,用来获取签名")
+    String timestamp;
+
+    public void setGrantType(String grantType) {
+        this.grantType = GrantTypeEnum.valueOfCode(grantType);
+    }
+}

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

@@ -1,270 +1,269 @@
-package cn.tr.module.sys.oauth2.psw.operator;
-
-import cn.dev33.satoken.stp.StpLogic;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.useragent.UserAgent;
-import cn.hutool.http.useragent.UserAgentUtil;
-import cn.tr.core.annotation.TenantIgnore;
-import cn.tr.core.enums.LoginScopeType;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.utils.IpUtil;
-import cn.tr.core.utils.PswUtils;
-import cn.tr.core.utils.ServletUtils;
-import cn.tr.module.api.sys.log.enums.LoginType;
-import cn.tr.module.sys.config.SysConfigManager;
-import cn.tr.module.sys.config.SysConfigProperties;
-import cn.tr.module.sys.oauth2.config.CaptchaOperator;
-import cn.tr.module.sys.oauth2.dto.AccountUserInfoDTO;
-import cn.tr.module.sys.oauth2.dto.AccountUserInfoEditDTO;
-import cn.tr.module.sys.oauth2.mapper.OAuth2Mapper;
-import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
-import cn.tr.module.sys.tenant.service.ISysTenantService;
-import cn.tr.module.sys.user.dto.SysOrgDTO;
-import cn.tr.module.sys.user.dto.SysPositionDTO;
-import cn.tr.module.sys.user.dto.SysRoleDTO;
-import cn.tr.module.sys.user.dto.SysUserDTO;
-import cn.tr.module.sys.user.enums.UserStatusEnum;
-import cn.tr.module.sys.user.mapper.SysOrgMapper;
-import cn.tr.module.sys.user.mapper.SysPositionMapper;
-import cn.tr.module.sys.user.mapper.SysRoleMapper;
-import cn.tr.module.sys.user.po.SysUserPO;
-import cn.tr.module.sys.user.repository.SysUserRepository;
-import cn.tr.module.sys.user.service.ISysOrgService;
-import cn.tr.module.sys.user.service.ISysPositionService;
-import cn.tr.module.sys.user.service.ISysRoleService;
-import cn.tr.module.sys.user.service.ISysUserService;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
-import cn.tr.plugin.security.constant.SecurityConstant;
-import cn.tr.plugin.security.context.LoginUserContextHolder;
-import cn.tr.plugin.security.utils.SaTokenUtils;
-import jakarta.annotation.Resource;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-import java.util.Date;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * 默认账号体系登录操作
- *
- * @author lf
- * @date  2023/11/06 10:12
- */
-@Component
-public class LoginOAuth2PswUserOperator extends AbstractOAuth2PswUserOperator{
-    @Resource
-    @Lazy
-    private LoginOAuth2PswUserOperator self;
-    @Resource
-    private ISysUserService sysUserService;
-
-    @Resource
-    private SysUserRepository sysUserRepository;
-
-    @Resource
-    private ISysTenantService tenantService;
-
-    @Resource
-    private SysConfigManager configManager;
-
-    @Resource
-    private CaptchaOperator captchaOperator;
-
-    @Resource
-    private ISysOrgService orgService;
-
-    @Resource
-    private ISysRoleService roleService;
-
-    @Resource
-    private ISysPositionService positionService;
-
-    @Value("${tr.tenant.enable}")
-    private Boolean tenantEnable;
-
-    @Override
-    @TenantIgnore
-    public String auth(OAuth2PswReqDTO source) {
-        validate(source);
-        String username = source.getUsername();
-        String psw = source.getPassword();
-        //对账号进行校验
-        SysUserDTO user = sysUserService.selectUserByUsername(username);
-        if(user==null){
-            //账户不存在
-            throw new ServiceException(TRExcCode.USER_ERROR_A0201);
-        }
-        //对密码进行校验
-        if(!PswUtils.matchesPassword(psw, user.getPassword())){
-            throw new ServiceException(TRExcCode.USER_ERROR_A0210);
-        }
-        //查看用户是否被禁用
-        if(!StrUtil.equals(UserStatusEnum.normal.getValue(), user.getStatus())){
-            //用户都被禁用
-            throw new ServiceException(TRExcCode.USER_ERROR_A0202);
-        }
-        if(Boolean.TRUE.equals(tenantEnable)){
-            //查看租户是否被禁用
-            String tenantId = user.getTenantId();
-            SysTenantCommonDTO tenant = tenantService.selectSysTenantById(tenantId);
-            if(tenant==null){
-                throw new ServiceException(TRExcCode.USER_ERROR_A0205);
-            }
-            if (Boolean.TRUE.equals(tenant.getDisable())) {
-                throw new ServiceException(TRExcCode.USER_ERROR_A0204);
-            }
-        }
-        //验证码校验
-        SysConfigProperties current = configManager.getCurrent();
-        if (Boolean.TRUE.equals(current.getCaptchaOpen())) {
-            String captchaCode = source.getCaptchaCode();
-            if(StrUtil.isEmpty(captchaCode)){
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"验证码不能为空");
-            }
-            if(!captchaOperator.ver(source.getCaptchaKey(),source.getCaptchaCode())){
-                throw new ServiceException(TRExcCode.USER_ERROR_A0240);
-            }
-        }
-        StpLogic stpUtil = SaTokenUtils.getStpUtil();
-        stpUtil.login(user.getId());
-        String tokenValue = stpUtil.getTokenValue();
-        Date loginTime = new Date();
-        //更新最后登录信息
-        String ip = ServletUtils.getClientIP();
-        String cityInfo = IpUtil.getCityInfo(ip);
-        SysUserDTO updateUser = new SysUserDTO();
-        updateUser.setId(user.getId());
-        updateUser.setLastLoginDate(loginTime);
-        updateUser.setLastLoginIp(ip);
-        updateUser.setLastLoginAddress(cityInfo);
-        sysUserService.updateLastLoginInfo(user.getId(),loginTime,ip,cityInfo);
-        //清除缓存
-        self.delUserLoginInfoCache(user.getId());
-
-        UserAgent userAgent = Optional.ofNullable(UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"))).orElse(new UserAgent());
-        String browser = ObjectUtil.isEmpty(userAgent.getBrowser()) ? "未知" : userAgent.getBrowser().getName();
-        String os = ObjectUtil.isEmpty(userAgent.getOs()) ? "未知" : userAgent.getOs().getName();
-
-        UserLoginInfoBO loginInfo = UserLoginInfoBO.builder()
-                .userId(user.getId())
-                .nickname(user.getNickname())
-                .username(username)
-                .tenantId(user.getTenantId())
-                .token(tokenValue)
-                .loginType(StpUtil.TYPE)
-                .loginIp(updateUser.getLastLoginIp())
-                .loginLocation(cityInfo)
-                .loginTime(loginTime)
-                .browser(browser)
-                .os(os)
-                .signature(user.getSignature())
-                .build();
-        setSessionUser(tokenValue,loginInfo);
-        return tokenValue;
-    }
-
-    @Override
-    public boolean updatePsw(String oldPsw, String newPsw) {
-        return  sysUserService.updatePsw(LoginUserContextHolder.getUser().getUserId(),oldPsw,newPsw);
-    }
-
-    @Override
-    public Object getUserLoginInfo() {
-        String loginId =String.valueOf( SaTokenUtils.getStpUtil().getLoginId());
-        return OAuth2Mapper.INSTANCE.toPswLoginInfo(sysUserService.selectSysUserById(loginId));
-    }
-
-    @Override
-    public AccountUserInfoDTO getAccountInfo() {
-        AccountUserInfoDTO result = new AccountUserInfoDTO();
-        String loginId =String.valueOf( SaTokenUtils.getStpUtil().getLoginId());
-        SysUserDTO user = sysUserService.selectSysUserById(loginId);
-
-        AccountUserInfoDTO.BasicInfo basicInfo = AccountUserInfoDTO.BasicInfo.builder()
-                .userId(user.getId())
-                .avatar(user.getAvatar())
-                .username(user.getUsername())
-                .nickname(user.getNickname())
-                .gender(user.getGender())
-                .phone(user.getPhone())
-                .email(user.getEmail())
-                .createTime(user.getCreateTime())
-                .lastLoginIp(user.getLastLoginIp())
-                .lastLoginAddress(user.getLastLoginAddress())
-                .lastLoginDate(user.getLastLoginDate())
-                .signature(user.getSignature())
-                .build();
-        //填充角色信息
-        List<SysRoleDTO> roles = roleService.selectSysRoleByIds(user.getRoleIds());
-        basicInfo.setRoles(SysRoleMapper.INSTANCE.convertSmallList(roles));
-        //填充岗位信息
-        List<SysPositionDTO> positions = positionService.selectSysPositionByIds(user.getPostIds());
-        basicInfo.setPositions(SysPositionMapper.INSTANCE.convertSmallList(positions));
-        //填充机构信息
-        SysOrgDTO sysOrgDTO = orgService.selectSysOrgById(user.getOrgId());
-        basicInfo.setOrg(SysOrgMapper.INSTANCE.convertSmall(sysOrgDTO));
-        result.setBasicInfo(basicInfo);
-        return result;
-    }
-
-    @Override
-    public void updateAccountUserInfo(String userId, AccountUserInfoEditDTO source) {
-        if(StrUtil.isBlank(source.getAvatar())
-                &&StrUtil.isBlank(source.getNickname())
-                &&StrUtil.isBlank(source.getGender())
-                &&StrUtil.isBlank(source.getPhone())
-                &&StrUtil.isBlank(source.getEmail())
-                &&StrUtil.isBlank(source.getSignature())){
-            return;
-        }
-
-        SysUserPO sysUserPO = OAuth2Mapper.INSTANCE.toSysUser(source);
-        sysUserPO.setId(userId);
-        UserLoginInfoBO user = LoginUserContextHolder.getUser();
-        user.setAvatar(source.getAvatar());
-        user.setNickname(source.getNickname());
-        user.setSignature(source.getSignature());
-        sysUserRepository.updateById(sysUserPO);
-        sysUserService.delUserIdAndNickNameCache();
-        SaTokenUtils.set(SecurityConstant.LOGIN_USER,user);
-    }
-
-    @Override
-    public String matchLoginType() {
-        return LoginScopeType.LOGIN_SCOPE_TYPE_NORMAL;
-    }
-
-
-    /**
-     * 验证用户名和密码的有效性
-     * @throws IllegalArgumentException 当验证失败时抛出
-     */
-    public void validate(OAuth2PswReqDTO source) throws IllegalArgumentException {
-        // 验证用户名
-        if (source.getUsername() == null || source.getUsername() .trim().isEmpty()) {
-            throw new IllegalArgumentException("账号不能为空");
-        }
-
-        if (source.getUsername() .length() < 4 || source.getUsername() .length() > 16) {
-            throw new IllegalArgumentException("账号长度为 4-16 位");
-        }
-
-        if (!source.getUsername() .matches("^[A-Za-z0-9]+$")) {
-            throw new IllegalArgumentException("账号格式为数字以及字母");
-        }
-
-        // 验证密码
-        if (source.getPassword() == null || source.getPassword().trim().isEmpty()) {
-            throw new IllegalArgumentException("密码不能为空");
-        }
-
-        if (source.getPassword().length() < 4 || source.getPassword().length() > 16) {
-            throw new IllegalArgumentException("密码长度为 4-16 位");
-        }
-    }
-}
+//package cn.tr.module.sys.oauth2.psw.operator;
+//
+//import cn.dev33.satoken.stp.StpLogic;
+//import cn.dev33.satoken.stp.StpUtil;
+//import cn.hutool.core.util.ObjectUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.hutool.http.useragent.UserAgent;
+//import cn.hutool.http.useragent.UserAgentUtil;
+//import cn.tr.core.annotation.TenantIgnore;
+//import cn.tr.core.enums.LoginScopeType;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.core.utils.IpUtil;
+//import cn.tr.core.utils.PswUtils;
+//import cn.tr.core.utils.ServletUtils;
+//import cn.tr.module.sys.config.SysConfigManager;
+//import cn.tr.module.sys.config.SysConfigProperties;
+//import cn.tr.module.sys.oauth2.config.CaptchaOperator;
+//import cn.tr.module.sys.oauth2.dto.AccountUserInfoDTO;
+//import cn.tr.module.sys.oauth2.dto.AccountUserInfoEditDTO;
+//import cn.tr.module.sys.oauth2.mapper.OAuth2Mapper;
+//import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
+//import cn.tr.module.sys.tenant.service.ISysTenantService;
+//import cn.tr.module.sys.user.dto.SysOrgDTO;
+//import cn.tr.module.sys.user.dto.SysPositionDTO;
+//import cn.tr.module.sys.user.dto.SysRoleDTO;
+//import cn.tr.module.sys.user.dto.SysUserDTO;
+//import cn.tr.module.sys.user.enums.UserStatusEnum;
+//import cn.tr.module.sys.user.mapper.SysOrgMapper;
+//import cn.tr.module.sys.user.mapper.SysPositionMapper;
+//import cn.tr.module.sys.user.mapper.SysRoleMapper;
+//import cn.tr.module.sys.user.po.SysUserPO;
+//import cn.tr.module.sys.user.repository.SysUserRepository;
+//import cn.tr.module.sys.user.service.ISysOrgService;
+//import cn.tr.module.sys.user.service.ISysPositionService;
+//import cn.tr.module.sys.user.service.ISysRoleService;
+//import cn.tr.module.sys.user.service.ISysUserService;
+//import cn.tr.plugin.security.bo.UserLoginInfoBO;
+//import cn.tr.plugin.security.constant.SecurityConstant;
+//import cn.tr.plugin.security.context.LoginUserContextHolder;
+//import cn.tr.plugin.security.utils.SaTokenUtils;
+//import jakarta.annotation.Resource;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.context.annotation.Lazy;
+//import org.springframework.stereotype.Component;
+//import java.util.Date;
+//import java.util.List;
+//import java.util.Optional;
+//
+///**
+// * 默认账号体系登录操作
+// *
+// * @author lf
+// * @date  2023/11/06 10:12
+// */
+//@Component
+//public class LoginOAuth2PswUserOperator extends AbstractOAuth2PswUserOperator{
+//    @Resource
+//    @Lazy
+//    private LoginOAuth2PswUserOperator self;
+//    @Resource
+//    private ISysUserService sysUserService;
+//
+//    @Resource
+//    private SysUserRepository sysUserRepository;
+//
+//    @Resource
+//    private ISysTenantService tenantService;
+//
+//    @Resource
+//    private SysConfigManager configManager;
+//
+//    @Resource
+//    private CaptchaOperator captchaOperator;
+//
+//    @Resource
+//    private ISysOrgService orgService;
+//
+//    @Resource
+//    private ISysRoleService roleService;
+//
+//    @Resource
+//    private ISysPositionService positionService;
+//
+//    @Value("${tr.tenant.enable}")
+//    private Boolean tenantEnable;
+//
+//    @Override
+//    @TenantIgnore
+//    public String auth(OAuth2PswReqDTO source) {
+//        validate(source);
+//        String username = source.getUsername();
+//        String psw = source.getPassword();
+//        //对账号进行校验
+//        SysUserDTO user = sysUserService.selectUserByUsername(username);
+//        if(user==null){
+//            //账户不存在
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0201);
+//        }
+//        //对密码进行校验
+//        if(!PswUtils.matchesPassword(psw, user.getPassword())){
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0210);
+//        }
+//        //查看用户是否被禁用
+//        if(!StrUtil.equals(UserStatusEnum.normal.getValue(), user.getStatus())){
+//            //用户都被禁用
+//            throw new ServiceException(TRExcCode.USER_ERROR_A0202);
+//        }
+//        if(Boolean.TRUE.equals(tenantEnable)){
+//            //查看租户是否被禁用
+//            String tenantId = user.getTenantId();
+//            SysTenantCommonDTO tenant = tenantService.selectSysTenantById(tenantId);
+//            if(tenant==null){
+//                throw new ServiceException(TRExcCode.USER_ERROR_A0205);
+//            }
+//            if (Boolean.TRUE.equals(tenant.getDisable())) {
+//                throw new ServiceException(TRExcCode.USER_ERROR_A0204);
+//            }
+//        }
+//        //验证码校验
+//        SysConfigProperties current = configManager.getCurrent();
+//        if (Boolean.TRUE.equals(current.getCaptchaOpen())) {
+//            String captchaCode = source.getCaptchaCode();
+//            if(StrUtil.isEmpty(captchaCode)){
+//                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"验证码不能为空");
+//            }
+//            if(!captchaOperator.ver(source.getCaptchaKey(),source.getCaptchaCode())){
+//                throw new ServiceException(TRExcCode.USER_ERROR_A0240);
+//            }
+//        }
+//        StpLogic stpUtil = SaTokenUtils.getStpUtil();
+//        stpUtil.login(user.getId());
+//        String tokenValue = stpUtil.getTokenValue();
+//        Date loginTime = new Date();
+//        //更新最后登录信息
+//        String ip = ServletUtils.getClientIP();
+//        String cityInfo = IpUtil.getCityInfo(ip);
+//        SysUserDTO updateUser = new SysUserDTO();
+//        updateUser.setId(user.getId());
+//        updateUser.setLastLoginDate(loginTime);
+//        updateUser.setLastLoginIp(ip);
+//        updateUser.setLastLoginAddress(cityInfo);
+//        sysUserService.updateLastLoginInfo(user.getId(),loginTime,ip,cityInfo);
+//        //清除缓存
+//        self.delUserLoginInfoCache(user.getId());
+//
+//        UserAgent userAgent = Optional.ofNullable(UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"))).orElse(new UserAgent());
+//        String browser = ObjectUtil.isEmpty(userAgent.getBrowser()) ? "未知" : userAgent.getBrowser().getName();
+//        String os = ObjectUtil.isEmpty(userAgent.getOs()) ? "未知" : userAgent.getOs().getName();
+//
+//        UserLoginInfoBO loginInfo = UserLoginInfoBO.builder()
+//                .userId(user.getId())
+//                .nickname(user.getNickname())
+//                .username(username)
+//                .tenantId(user.getTenantId())
+//                .token(tokenValue)
+//                .loginType(StpUtil.TYPE)
+//                .loginIp(updateUser.getLastLoginIp())
+//                .loginLocation(cityInfo)
+//                .loginTime(loginTime)
+//                .browser(browser)
+//                .os(os)
+//                .signature(user.getSignature())
+//                .build();
+//        setSessionUser(tokenValue,loginInfo);
+//        return tokenValue;
+//    }
+//
+//    @Override
+//    public boolean updatePsw(String oldPsw, String newPsw) {
+//        return  sysUserService.updatePsw(LoginUserContextHolder.getUser().getUserId(),oldPsw,newPsw);
+//    }
+//
+//    @Override
+//    public Object getUserLoginInfo() {
+//        String loginId =String.valueOf( SaTokenUtils.getStpUtil().getLoginId());
+//        return OAuth2Mapper.INSTANCE.toPswLoginInfo(sysUserService.selectSysUserById(loginId));
+//    }
+//
+//    @Override
+//    public AccountUserInfoDTO getAccountInfo() {
+//        AccountUserInfoDTO result = new AccountUserInfoDTO();
+//        String loginId =String.valueOf( SaTokenUtils.getStpUtil().getLoginId());
+//        SysUserDTO user = sysUserService.selectSysUserById(loginId);
+//
+//        AccountUserInfoDTO.BasicInfo basicInfo = AccountUserInfoDTO.BasicInfo.builder()
+//                .userId(user.getId())
+//                .avatar(user.getAvatar())
+//                .username(user.getUsername())
+//                .nickname(user.getNickname())
+//                .gender(user.getGender())
+//                .phone(user.getPhone())
+//                .email(user.getEmail())
+//                .createTime(user.getCreateTime())
+//                .lastLoginIp(user.getLastLoginIp())
+//                .lastLoginAddress(user.getLastLoginAddress())
+//                .lastLoginDate(user.getLastLoginDate())
+//                .signature(user.getSignature())
+//                .build();
+//        //填充角色信息
+//        List<SysRoleDTO> roles = roleService.selectSysRoleByIds(user.getRoleIds());
+//        basicInfo.setRoles(SysRoleMapper.INSTANCE.convertSmallList(roles));
+//        //填充岗位信息
+//        List<SysPositionDTO> positions = positionService.selectSysPositionByIds(user.getPostIds());
+//        basicInfo.setPositions(SysPositionMapper.INSTANCE.convertSmallList(positions));
+//        //填充机构信息
+//        SysOrgDTO sysOrgDTO = orgService.selectSysOrgById(user.getOrgId());
+//        basicInfo.setOrg(SysOrgMapper.INSTANCE.convertSmall(sysOrgDTO));
+//        result.setBasicInfo(basicInfo);
+//        return result;
+//    }
+//
+//    @Override
+//    public void updateAccountUserInfo(String userId, AccountUserInfoEditDTO source) {
+//        if(StrUtil.isBlank(source.getAvatar())
+//                &&StrUtil.isBlank(source.getNickname())
+//                &&StrUtil.isBlank(source.getGender())
+//                &&StrUtil.isBlank(source.getPhone())
+//                &&StrUtil.isBlank(source.getEmail())
+//                &&StrUtil.isBlank(source.getSignature())){
+//            return;
+//        }
+//
+//        SysUserPO sysUserPO = OAuth2Mapper.INSTANCE.toSysUser(source);
+//        sysUserPO.setId(userId);
+//        UserLoginInfoBO user = LoginUserContextHolder.getUser();
+//        user.setAvatar(source.getAvatar());
+//        user.setNickname(source.getNickname());
+//        user.setSignature(source.getSignature());
+//        sysUserRepository.updateById(sysUserPO);
+//        sysUserService.delUserIdAndNickNameCache();
+//        SaTokenUtils.set(SecurityConstant.LOGIN_USER,user);
+//    }
+//
+//    @Override
+//    public String matchLoginType() {
+//        return LoginScopeType.LOGIN_SCOPE_TYPE_NORMAL;
+//    }
+//
+//
+//    /**
+//     * 验证用户名和密码的有效性
+//     * @throws IllegalArgumentException 当验证失败时抛出
+//     */
+//    public void validate(OAuth2PswReqDTO source) throws IllegalArgumentException {
+//        // 验证用户名
+//        if (source.getUsername() == null || source.getUsername() .trim().isEmpty()) {
+//            throw new IllegalArgumentException("账号不能为空");
+//        }
+//
+//        if (source.getUsername() .length() < 4 || source.getUsername() .length() > 16) {
+//            throw new IllegalArgumentException("账号长度为 4-16 位");
+//        }
+//
+//        if (!source.getUsername() .matches("^[A-Za-z0-9]+$")) {
+//            throw new IllegalArgumentException("账号格式为数字以及字母");
+//        }
+//
+//        // 验证密码
+//        if (source.getPassword() == null || source.getPassword().trim().isEmpty()) {
+//            throw new IllegalArgumentException("密码不能为空");
+//        }
+//
+//        if (source.getPassword().length() < 4 || source.getPassword().length() > 16) {
+//            throw new IllegalArgumentException("密码长度为 4-16 位");
+//        }
+//    }
+//}

+ 127 - 128
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/psw/operator/LoginWxUserOperator.java

@@ -1,128 +1,127 @@
-package cn.tr.module.sys.oauth2.psw.operator;
-
-import cn.binarywang.wx.miniapp.api.WxMaService;
-import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
-import cn.dev33.satoken.stp.StpLogic;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.useragent.UserAgent;
-import cn.hutool.http.useragent.UserAgentUtil;
-import cn.tr.core.annotation.TenantIgnore;
-import cn.tr.core.enums.LoginScopeType;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.utils.IpUtil;
-import cn.tr.core.utils.ServletUtils;
-import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
-import cn.tr.module.sys.user.constant.UserType;
-import cn.tr.module.sys.user.po.SysUserPO;
-import cn.tr.module.sys.user.repository.SysUserRepository;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
-import cn.tr.plugin.security.utils.SaTokenUtils;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-
-import java.util.Date;
-import java.util.Optional;
-
-/**
- * @ClassName : LoginWxUserOperator
- * @Description : 微信登录体系操作
- * @Author : LF
- * @Date: 2023年03月31日
- */
-@Slf4j
-@Component
-@ConditionalOnBean(WxMaService.class)
-public class LoginWxUserOperator extends LoginOAuth2PswUserOperator{
-    @Resource
-    @Lazy
-    private LoginWxUserOperator self;
-
-    @Resource
-    private WxMaService wxMaService;
-
-    @Resource
-    private SysUserRepository sysUserRepository;
-
-    @Override
-    @TenantIgnore
-    public String auth(OAuth2PswReqDTO source) {
-        String wxAppletCode = source.getWxAppletCode();
-        String username = source.getUsername();
-        Date loginTime = new Date();
-        //获取Request对象
-        HttpServletRequest request = ServletUtils.getRequest();
-        String ip = ServletUtils.getClientIP(request);
-        String cityInfo = IpUtil.getCityInfo(ip);
-
-        if (StrUtil.isEmpty(wxAppletCode)) {
-            throw new IllegalArgumentException("微信登陆码不能为空");
-        }
-        WxMaJscode2SessionResult sessionInfo;
-        try {
-            sessionInfo = wxMaService.getUserService().getSessionInfo(wxAppletCode);
-        } catch (Exception e) {
-            log.error("微信服务调用失败 |  code:{} | 错误:{}",
-                     source.getWxAppletCode(), e.getMessage(), e);
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001, "微信授权失败: " + e.getMessage());
-        }
-
-        String openid = sessionInfo.getOpenid();
-        String unionid = sessionInfo.getUnionid();
-        SysUserPO wxUser = sysUserRepository.selectOne(new LambdaQueryWrapper<SysUserPO>()
-                .eq(SysUserPO::getOpenId, openid)
-                .last("limit 1"));
-        //根据openid查询用户信息 (通过数据库进行查询)
-        if (wxUser == null) {
-            wxUser = new SysUserPO();
-            wxUser.setOpenId(openid);
-            wxUser.setType(UserType.NORMAL);
-            wxUser.setUnionId(unionid);
-            wxUser.setLastLoginIp(ip);
-            wxUser.setLastLoginDate(new Date());
-            wxUser.setLastLoginAddress(cityInfo);
-            if (StrUtil.isNotBlank(sessionInfo.getUnionid())) {
-                wxUser.setUnionId(sessionInfo.getUnionid());
-            }
-            sysUserRepository.insert(wxUser);
-        } else {
-            wxUser.setUnionId(unionid);
-            wxUser.setLastLoginIp(ip);
-            wxUser.setLastLoginAddress(cityInfo);
-            wxUser.setLastLoginDate(new Date());
-            sysUserRepository.updateById(wxUser);
-        }
-        StpLogic stpUtil = SaTokenUtils.getStpUtil();
-        stpUtil.login(wxUser.getId());
-        String tokenValue = stpUtil.getTokenValue();
-        //清除缓存
-        self.delUserLoginInfoCache(wxUser.getId());
-        UserAgent userAgent = Optional.ofNullable(UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"))).orElse(new UserAgent());
-        String browser = ObjectUtil.isEmpty(userAgent.getBrowser()) ? "未知" : userAgent.getBrowser().getName();
-        String os = ObjectUtil.isEmpty(userAgent.getOs()) ? "未知" : userAgent.getOs().getName();
-        UserLoginInfoBO loginInfo = UserLoginInfoBO.builder()
-                .userId(wxUser.getId())
-                .nickname(wxUser.getNickname())
-                .username(username)
-                .token(tokenValue)
-                .loginIp(wxUser.getLastLoginIp())
-                .loginLocation(cityInfo)
-                .loginTime(loginTime)
-                .browser(browser)
-                .os(os)
-                .build();
-        setSessionUser(tokenValue, loginInfo);
-        return tokenValue;
-    }
-
-    @Override
-    public String matchLoginType() {
-        return LoginScopeType.LOGIN_SCOPE_TYPE_WX;
-    }
-}
+//package cn.tr.module.sys.oauth2.psw.operator;
+//
+//import cn.binarywang.wx.miniapp.api.WxMaService;
+//import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+//import cn.dev33.satoken.stp.StpLogic;
+//import cn.hutool.core.util.ObjectUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.hutool.http.useragent.UserAgent;
+//import cn.hutool.http.useragent.UserAgentUtil;
+//import cn.tr.core.annotation.TenantIgnore;
+//import cn.tr.core.enums.LoginScopeType;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.core.utils.IpUtil;
+//import cn.tr.core.utils.ServletUtils;
+//import cn.tr.module.sys.oauth2.dto.OAuth2PswReqDTO;
+//import cn.tr.module.sys.user.constant.UserType;
+//import cn.tr.module.sys.user.repository.SysUserRepository;
+//import cn.tr.plugin.security.bo.UserLoginInfoBO;
+//import cn.tr.plugin.security.utils.SaTokenUtils;
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import jakarta.annotation.Resource;
+//import jakarta.servlet.http.HttpServletRequest;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+//import org.springframework.context.annotation.Lazy;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.Date;
+//import java.util.Optional;
+//
+///**
+// * @ClassName : LoginWxUserOperator
+// * @Description : 微信登录体系操作
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//@Slf4j
+//@Component
+//@ConditionalOnBean(WxMaService.class)
+//public class LoginWxUserOperator extends LoginOAuth2PswUserOperator{
+//    @Resource
+//    @Lazy
+//    private LoginWxUserOperator self;
+//
+//    @Resource
+//    private WxMaService wxMaService;
+//
+//    @Resource
+//    private SysUserRepository sysUserRepository;
+//
+//    @Override
+//    @TenantIgnore
+//    public String auth(OAuth2PswReqDTO source) {
+//        String wxAppletCode = source.getWxAppletCode();
+//        String username = source.getUsername();
+//        Date loginTime = new Date();
+//        //获取Request对象
+//        HttpServletRequest request = ServletUtils.getRequest();
+//        String ip = ServletUtils.getClientIP(request);
+//        String cityInfo = IpUtil.getCityInfo(ip);
+//
+//        if (StrUtil.isEmpty(wxAppletCode)) {
+//            throw new IllegalArgumentException("微信登陆码不能为空");
+//        }
+//        WxMaJscode2SessionResult sessionInfo;
+//        try {
+//            sessionInfo = wxMaService.getUserService().getSessionInfo(wxAppletCode);
+//        } catch (Exception e) {
+//            log.error("微信服务调用失败 |  code:{} | 错误:{}",
+//                     source.getWxAppletCode(), e.getMessage(), e);
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001, "微信授权失败: " + e.getMessage());
+//        }
+//
+//        String openid = sessionInfo.getOpenid();
+//        String unionid = sessionInfo.getUnionid();
+//        SysUserPO wxUser = sysUserRepository.selectOne(new LambdaQueryWrapper<SysUserPO>()
+//                .eq(SysUserPO::getOpenId, openid)
+//                .last("limit 1"));
+//        //根据openid查询用户信息 (通过数据库进行查询)
+//        if (wxUser == null) {
+//            wxUser = new SysUserPO();
+//            wxUser.setOpenId(openid);
+//            wxUser.setType(UserType.NORMAL);
+//            wxUser.setUnionId(unionid);
+//            wxUser.setLastLoginIp(ip);
+//            wxUser.setLastLoginDate(new Date());
+//            wxUser.setLastLoginAddress(cityInfo);
+//            if (StrUtil.isNotBlank(sessionInfo.getUnionid())) {
+//                wxUser.setUnionId(sessionInfo.getUnionid());
+//            }
+//            sysUserRepository.insert(wxUser);
+//        } else {
+//            wxUser.setUnionId(unionid);
+//            wxUser.setLastLoginIp(ip);
+//            wxUser.setLastLoginAddress(cityInfo);
+//            wxUser.setLastLoginDate(new Date());
+//            sysUserRepository.updateById(wxUser);
+//        }
+//        StpLogic stpUtil = SaTokenUtils.getStpUtil();
+//        stpUtil.login(wxUser.getId());
+//        String tokenValue = stpUtil.getTokenValue();
+//        //清除缓存
+//        self.delUserLoginInfoCache(wxUser.getId());
+//        UserAgent userAgent = Optional.ofNullable(UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"))).orElse(new UserAgent());
+//        String browser = ObjectUtil.isEmpty(userAgent.getBrowser()) ? "未知" : userAgent.getBrowser().getName();
+//        String os = ObjectUtil.isEmpty(userAgent.getOs()) ? "未知" : userAgent.getOs().getName();
+//        UserLoginInfoBO loginInfo = UserLoginInfoBO.builder()
+//                .userId(wxUser.getId())
+//                .nickname(wxUser.getNickname())
+//                .username(username)
+//                .token(tokenValue)
+//                .loginIp(wxUser.getLastLoginIp())
+//                .loginLocation(cityInfo)
+//                .loginTime(loginTime)
+//                .browser(browser)
+//                .os(os)
+//                .build();
+//        setSessionUser(tokenValue, loginInfo);
+//        return tokenValue;
+//    }
+//
+//    @Override
+//    public String matchLoginType() {
+//        return LoginScopeType.LOGIN_SCOPE_TYPE_WX;
+//    }
+//}

+ 170 - 170
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/service/CurrentUserService.java

@@ -1,171 +1,171 @@
-package cn.tr.module.sys.oauth2.service;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.module.sys.tenant.service.ISysTenantService;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
-import cn.tr.module.sys.user.dto.SysRoleDTO;
-import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
-import cn.tr.module.sys.user.enums.MenuEnum;
-import cn.tr.module.sys.user.service.ISysMenuService;
-import cn.tr.module.sys.user.service.ISysPortalMenuService;
-import cn.tr.module.sys.user.service.ISysUserPortalService;
-import cn.tr.module.sys.user.service.ISysUserRoleService;
-import cn.tr.module.sys.user.vo.RouteItemVO;
-import cn.tr.plugin.security.utils.SaTokenUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName : CurrentUserService
- * @Description :
- * @Author : LF
- * @Date: 2023年04月07日
- */
-
-@Component
-public class CurrentUserService {
-    @Autowired
-    private  ISysTenantService tenantService;
-    @Autowired
-    private  ISysMenuService menuService;
-    @Autowired
-    private  ISysPortalMenuService portalMenuService;
-    @Autowired
-    private  ISysUserPortalService userPortalService;
-    @Autowired
-    private  ISysUserRoleService userRoleService;
-
-    @Value("${tr.tenant.enable}")
-    private Boolean tenantEnable;
-    /**
-     * 获取当前用户权限
-     * @return
-     */
-    public Collection<String> currentUserPermission(String userId){
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            //用户所在租户拥有的权限
-            Set<String> tenantPermissions = tenantService.findTenantPermission();
-            ;
-            //用户角色所拥有的权限
-            Set<String> rolePermissions = menuService.findUserPermission(userId);
-
-            return CollectionUtil.intersection(tenantPermissions,rolePermissions);
-        }else {
-            return menuService.findUserPermission(userId);
-        }
-
-    };
-
-    public Collection<String> currentUserRoleCode(){
-        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
-        List<SysRoleDTO> roles = userRoleService.findAllRolesByUserId(currentUserId);
-        return roles.stream().
-                map(SysRoleDTO::getCode)
-                .collect(Collectors.toList());
-    }
-
-    /**
-     * 获取当前用户菜单
-     * @return
-     */
-    public List<RouteItemVO> currentUserMenus(String portalId){
-        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
-        Set<SysMenuDTO> tenantMenus =null;
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            tenantMenus = tenantService.currentTenantMenus();
-        }
-        //查询所有可匿名访问的菜单
-//        List<SysMenuDTO> anonymousMenus = menuService.findAnonymousMenus();
-        Set<SysMenuDTO> roleMenus = menuService.findUserMenus(currentUserId);
-        //当未传门户id时,使用默认门户
-        if(StrUtil.isEmpty(portalId)){
-            List<SysUserPortalListDTO> portalList = currentUserPortals();
-            if (CollectionUtil.isNotEmpty(portalList)) {
-                portalId=portalList.stream()
-                        .filter(portal->Boolean.TRUE.equals(portal.getIsDefault()))
-                        .map(SysUserPortalListDTO::getId)
-                        .findFirst()
-                        .orElse(CollectionUtil.getFirst(portalList).getId());
-            }
-        }
-        Set<SysMenuDTO> portalMenus =StrUtil.isEmpty(portalId)?Collections.emptySet():new HashSet<>(portalMenuService.findAllMenusByPortalId(portalId));
-        // 交集(门面菜单,租户菜单,角色菜单)
-        Collection<SysMenuDTO> allMenus=new ArrayList<>();
-        if(Boolean.TRUE.equals(tenantEnable)){
-            allMenus = CollectionUtil.intersection(tenantMenus, roleMenus,portalMenus);
-        }else if(CollectionUtil.isNotEmpty(portalMenus)){
-            allMenus = CollectionUtil.intersection(roleMenus,portalMenus);
-        }else {
-            allMenus=roleMenus;
-        }
-//        if(CollectionUtil.isNotEmpty(anonymousMenus)){
-//            allMenus.addAll(anonymousMenus);
+//package cn.tr.module.sys.oauth2.service;
+//
+//import cn.hutool.core.collection.CollUtil;
+//import cn.hutool.core.collection.CollectionUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.module.sys.tenant.service.ISysTenantService;
+//import cn.tr.module.sys.user.dto.SysMenuDTO;
+//import cn.tr.module.sys.user.dto.SysRoleDTO;
+//import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
+//import cn.tr.module.sys.user.enums.MenuEnum;
+//import cn.tr.module.sys.user.service.ISysMenuService;
+//import cn.tr.module.sys.user.service.ISysPortalMenuService;
+//import cn.tr.module.sys.user.service.ISysUserPortalService;
+//import cn.tr.module.sys.user.service.ISysUserRoleService;
+//import cn.tr.module.sys.user.vo.RouteItemVO;
+//import cn.tr.plugin.security.utils.SaTokenUtils;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * @ClassName : CurrentUserService
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月07日
+// */
+//
+//@Component
+//public class CurrentUserService {
+//    @Autowired
+//    private  ISysTenantService tenantService;
+//    @Autowired
+//    private  ISysMenuService menuService;
+//    @Autowired
+//    private  ISysPortalMenuService portalMenuService;
+//    @Autowired
+//    private  ISysUserPortalService userPortalService;
+//    @Autowired
+//    private  ISysUserRoleService userRoleService;
+//
+//    @Value("${tr.tenant.enable}")
+//    private Boolean tenantEnable;
+//    /**
+//     * 获取当前用户权限
+//     * @return
+//     */
+//    public Collection<String> currentUserPermission(String userId){
+//        if (Boolean.TRUE.equals(tenantEnable)) {
+//            //用户所在租户拥有的权限
+//            Set<String> tenantPermissions = tenantService.findTenantPermission();
+//            ;
+//            //用户角色所拥有的权限
+//            Set<String> rolePermissions = menuService.findUserPermission(userId);
+//
+//            return CollectionUtil.intersection(tenantPermissions,rolePermissions);
+//        }else {
+//            return menuService.findUserPermission(userId);
 //        }
-        if(CollectionUtil.isEmpty(allMenus)){
-            return new ArrayList<>();
-        }
-        return allMenus
-                .stream()
-                .collect(Collectors.groupingBy(SysMenuDTO::getId, Collectors.collectingAndThen(Collectors.toList(), CollUtil::getFirst)))
-                //未重复的菜单
-                .values()
-                .stream()
-                .filter(menu -> !StrUtil.equals(MenuEnum.button.name(), menu.getMenuType()))
-                .filter(menu-> Boolean.TRUE.equals(menu.getVisible()))
-                .map(menuService::convertToRoute)
-                .collect(Collectors.toList());
-    }
-
-    public List<SysUserPortalListDTO> currentUserPortals(){
-        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
-        List<SysUserPortalListDTO> portals = userPortalService.findPortalsByUserId(currentUserId);
-        if (CollectionUtil.size(portals)==0) {
-            if (Boolean.TRUE.equals(tenantEnable)) {
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"当前用户未设置门户信息");
-            }else {
-                return new ArrayList<>();
-            }
-
-        }
-        return portals;
-    }
-
-    /**
-     * 获取当前用户菜单
-     * @auth: lisen
-     * @return List<SysMenuDTO>
-     */
-    public Collection<SysMenuDTO> currentUserAllMenus(String portalId){
-        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
-        Set<SysMenuDTO> tenantMenus =null;
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            tenantMenus = tenantService.currentTenantMenus();
-        }
-        Set<SysMenuDTO> roleMenus = menuService.findUserMenus(currentUserId);
-        //当未传门户id时,使用默认门户
-        if(StrUtil.isEmpty(portalId)){
-            List<SysUserPortalListDTO> portalList = currentUserPortals();
-            if (CollectionUtil.isNotEmpty(portalList)) {
-                portalId=portalList.stream()
-                        .filter(portal->Boolean.TRUE.equals(portal.getIsDefault()))
-                        .map(SysUserPortalListDTO::getId)
-                        .findFirst()
-                        .orElse(CollectionUtil.getFirst(portalList).getId());
-            }
-        }
-        Set<SysMenuDTO> portalMenus =StrUtil.isEmpty(portalId)?Collections.emptySet():new HashSet<>(portalMenuService.findAllMenusByPortalId(portalId));
-        // 交集(门面菜单,租户菜单,角色菜单)
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            return CollectionUtil.intersection(tenantMenus, roleMenus,portalMenus);
-        }
-        return CollectionUtil.intersection(roleMenus,portalMenus);
-    }
-}
+//
+//    };
+//
+//    public Collection<String> currentUserRoleCode(){
+//        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
+//        List<SysRoleDTO> roles = userRoleService.findAllRolesByUserId(currentUserId);
+//        return roles.stream().
+//                map(SysRoleDTO::getCode)
+//                .collect(Collectors.toList());
+//    }
+//
+//    /**
+//     * 获取当前用户菜单
+//     * @return
+//     */
+//    public List<RouteItemVO> currentUserMenus(String portalId){
+//        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
+//        Set<SysMenuDTO> tenantMenus =null;
+//        if (Boolean.TRUE.equals(tenantEnable)) {
+//            tenantMenus = tenantService.currentTenantMenus();
+//        }
+//        //查询所有可匿名访问的菜单
+////        List<SysMenuDTO> anonymousMenus = menuService.findAnonymousMenus();
+//        Set<SysMenuDTO> roleMenus = menuService.findUserMenus(currentUserId);
+//        //当未传门户id时,使用默认门户
+//        if(StrUtil.isEmpty(portalId)){
+//            List<SysUserPortalListDTO> portalList = currentUserPortals();
+//            if (CollectionUtil.isNotEmpty(portalList)) {
+//                portalId=portalList.stream()
+//                        .filter(portal->Boolean.TRUE.equals(portal.getIsDefault()))
+//                        .map(SysUserPortalListDTO::getId)
+//                        .findFirst()
+//                        .orElse(CollectionUtil.getFirst(portalList).getId());
+//            }
+//        }
+//        Set<SysMenuDTO> portalMenus =StrUtil.isEmpty(portalId)?Collections.emptySet():new HashSet<>(portalMenuService.findAllMenusByPortalId(portalId));
+//        // 交集(门面菜单,租户菜单,角色菜单)
+//        Collection<SysMenuDTO> allMenus=new ArrayList<>();
+//        if(Boolean.TRUE.equals(tenantEnable)){
+//            allMenus = CollectionUtil.intersection(tenantMenus, roleMenus,portalMenus);
+//        }else if(CollectionUtil.isNotEmpty(portalMenus)){
+//            allMenus = CollectionUtil.intersection(roleMenus,portalMenus);
+//        }else {
+//            allMenus=roleMenus;
+//        }
+////        if(CollectionUtil.isNotEmpty(anonymousMenus)){
+////            allMenus.addAll(anonymousMenus);
+////        }
+//        if(CollectionUtil.isEmpty(allMenus)){
+//            return new ArrayList<>();
+//        }
+//        return allMenus
+//                .stream()
+//                .collect(Collectors.groupingBy(SysMenuDTO::getId, Collectors.collectingAndThen(Collectors.toList(), CollUtil::getFirst)))
+//                //未重复的菜单
+//                .values()
+//                .stream()
+//                .filter(menu -> !StrUtil.equals(MenuEnum.button.name(), menu.getMenuType()))
+//                .filter(menu-> Boolean.TRUE.equals(menu.getVisible()))
+//                .map(menuService::convertToRoute)
+//                .collect(Collectors.toList());
+//    }
+//
+//    public List<SysUserPortalListDTO> currentUserPortals(){
+//        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
+//        List<SysUserPortalListDTO> portals = userPortalService.findPortalsByUserId(currentUserId);
+//        if (CollectionUtil.size(portals)==0) {
+//            if (Boolean.TRUE.equals(tenantEnable)) {
+//                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"当前用户未设置门户信息");
+//            }else {
+//                return new ArrayList<>();
+//            }
+//
+//        }
+//        return portals;
+//    }
+//
+//    /**
+//     * 获取当前用户菜单
+//     * @auth: lisen
+//     * @return List<SysMenuDTO>
+//     */
+//    public Collection<SysMenuDTO> currentUserAllMenus(String portalId){
+//        String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
+//        Set<SysMenuDTO> tenantMenus =null;
+//        if (Boolean.TRUE.equals(tenantEnable)) {
+//            tenantMenus = tenantService.currentTenantMenus();
+//        }
+//        Set<SysMenuDTO> roleMenus = menuService.findUserMenus(currentUserId);
+//        //当未传门户id时,使用默认门户
+//        if(StrUtil.isEmpty(portalId)){
+//            List<SysUserPortalListDTO> portalList = currentUserPortals();
+//            if (CollectionUtil.isNotEmpty(portalList)) {
+//                portalId=portalList.stream()
+//                        .filter(portal->Boolean.TRUE.equals(portal.getIsDefault()))
+//                        .map(SysUserPortalListDTO::getId)
+//                        .findFirst()
+//                        .orElse(CollectionUtil.getFirst(portalList).getId());
+//            }
+//        }
+//        Set<SysMenuDTO> portalMenus =StrUtil.isEmpty(portalId)?Collections.emptySet():new HashSet<>(portalMenuService.findAllMenusByPortalId(portalId));
+//        // 交集(门面菜单,租户菜单,角色菜单)
+//        if (Boolean.TRUE.equals(tenantEnable)) {
+//            return CollectionUtil.intersection(tenantMenus, roleMenus,portalMenus);
+//        }
+//        return CollectionUtil.intersection(roleMenus,portalMenus);
+//    }
+//}

+ 51 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/AddressUtil.java

@@ -0,0 +1,51 @@
+package cn.tr.module.sys.oauth2.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 获取地址类
+ *
+ * @author Kevin
+ */
+@Slf4j
+public class AddressUtil {
+    /**
+     * IP地址查询
+     */
+    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
+
+    /**
+     * 未知地址
+     */
+    public static final String UNKNOWN = "XX XX";
+
+    public static String getRealAddressByIp(String ip) {
+        String address = UNKNOWN;
+        // 内网不查询
+//        try {
+//            if (NetUtil.isInnerIP(ip)) {
+//                return "内网IP";
+//            }
+//            if (AppConfig.isAddressEnabled()) {
+//                try {
+//                    String rspStr = HttpUtil.get(IP_URL + "?ip=" + ip + "&json=true", CharsetUtil.CHARSET_GBK);
+//                    if (CharSequenceUtil.isEmpty(rspStr)) {
+//                        log.error("获取地理位置异常 {}", ip);
+//                        return UNKNOWN;
+//                    }
+//                    JSONObject obj = JSONUtil.parseObj(rspStr);
+//                    String region = obj.getStr("pro");
+//                    String city = obj.getStr("city");
+//                    return String.format("%s %s", region, city);
+//                } catch (Exception e) {
+//                    log.error("获取地理位置异常 {}", ip);
+//                }
+//            }
+//            return address;
+//        }catch (Exception e){
+//            return UNKNOWN;
+//        }
+        return address;
+
+    }
+}

+ 53 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/IpUtil.java

@@ -0,0 +1,53 @@
+package cn.tr.module.sys.oauth2.utils;
+
+import cn.hutool.core.util.StrUtil;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+/**
+ * IP获取工具
+ *
+ * @author Kevin
+ */
+public class IpUtil {
+
+    public static String getClientIp(HttpServletRequest request) {
+//        // natapp穿透工具搭建的环境,通过header,X-Natapp-Ip,获取
+//        String ipAddress = ServletUtil.getClientIPByHeader(request, "X-Natapp-Ip");
+//        if (StrUtil.isBlank(ipAddress)) {
+//            ipAddress = ServletUtil.getClientIP(request);
+//        }
+//        // 本地开发,客户端和服务器在同一台机器,获取到是0:0:0:0:0:0:0:1,ip6地址,需要进行转换
+//        ipAddress = "0:0:0:0:0:0:0:1".equals(ipAddress) ? "127.0.0.1" : ipAddress;
+        return getIpAddress(request);
+    }
+
+    public static String getIpAddress(HttpServletRequest request) {
+
+        String sourceIp = null;
+
+        String ipAddresses = request.getHeader("x-forwarded-for");
+
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            ipAddresses = request.getHeader("Proxy-Client-IP");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            ipAddresses = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            ipAddresses = request.getRemoteAddr();
+        }
+        if (!StrUtil.isEmpty(ipAddresses)) {
+            sourceIp = ipAddresses.split(",")[0];
+        }
+
+        return sourceIp;
+    }
+
+}

+ 140 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/SecurityUtil.java

@@ -0,0 +1,140 @@
+package cn.tr.module.sys.oauth2.utils;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.secure.BCrypt;
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.hutool.core.util.StrUtil;
+import cn.tr.module.sys.oauth2.bean.LoginUser;
+import cn.tr.module.sys.oauth2.enums.GrantTypeEnum;
+
+
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+/**
+ * 安全服务工具类
+ *
+ * @author Kevin
+ */
+public class SecurityUtil {
+    public static final String LOGIN_USER_KEY="loginUser";
+    /**
+     * 获取用户账户
+     **/
+    public static String getUsername() {
+        return getLoginUser().getUsername();
+    }
+
+
+    /**
+     * 获取用户
+     **/
+    public static LoginUser getLoginUser(String authorization) {
+        try {
+            return (LoginUser) getStpLogic().getTokenSessionByToken(authorization).get(LOGIN_USER_KEY);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    /**
+     * 获取用户
+     **/
+    public static LoginUser getLoginUser() {
+        try {
+
+            return (LoginUser) getStpLogic().getTokenSession().get(LOGIN_USER_KEY);
+        } catch (Exception ex) {
+            return null;
+        }
+    }
+
+    /**
+     * 获取用户
+     **/
+    public static void  setLogin(LoginUser loginUser) {
+        getStpLogic().getTokenSession().set(LOGIN_USER_KEY,loginUser);
+    }
+
+    public static boolean isSys(){
+        LoginUser loginUser = getLoginUser();
+        if(loginUser==null){
+            return false;
+        }
+        GrantTypeEnum grantType = loginUser.getGrantType();
+        if (GrantTypeEnum.APPKEY_APPSECRET.equals(grantType)) {
+            return false;
+        }
+        return Boolean.TRUE.equals(loginUser.isSys());
+    }
+
+    public static String getTenantId(){
+        return String.valueOf(SpringMVCUtil.getRequest().getAttribute("tenantId"));
+    }
+    /**
+     * 是否是超级管理员
+     **/
+    public static Boolean isSuperAdmin() {
+        return getLoginUser().isSuperAdmin();
+//        LoginUser loginUser = getLoginUser();
+//        String grantType = getLoginUser().getGrantType();
+//        if (GrantTypeEnum.APPKEY_APPSECRET.getValue().equalsIgnoreCase(grantType)) {
+//            return false;
+//        }
+//        List<SysRoleBO> roles = getSysUser().getRoles();
+//        if(CollUtil.isEmpty(roles)){
+//            return false;
+//        }
+//        return roles.stream().filter(role-> StrUtil.isNotBlank(role.getRoleCode()))
+//                .map(SysRoleBO::getRoleCode)
+//                .collect(Collectors.toSet())
+//                .contains("admin");
+    }
+
+    /**
+     * 是否是超级管理员
+     **/
+    public static Boolean isSysSuperAdmin(Long userId) {
+        return Objects.nonNull(userId) && userId == 1L;
+    }
+
+    /**
+     * 生成BCryptPasswordEncoder密码
+     *
+     * @param password 密码
+     * @return 加密字符串
+     */
+    public static String encryptPassword(String password) {
+        return BCrypt.hashpw(password);
+    }
+
+    /**
+     * 判断密码是否相同
+     *
+     * @param rawPassword     真实密码
+     * @param encodedPassword 加密后字符
+     * @return 结果
+     */
+    public static boolean matchesPassword(String rawPassword, String encodedPassword) {
+        return BCrypt.checkpw(rawPassword, encodedPassword);
+    }
+
+    public static Object getId() {
+        return getLoginUser().getId();
+    }
+
+
+    public static StpLogic getStpLogic(){
+        HttpServletRequest request = SpringMVCUtil.getRequest();
+        return getStpLogic(request.getHeader("Login-Type"));
+    }
+
+    public static StpLogic getStpLogic(String loginType){
+        String header ="";
+        if(!StrUtil.isNullOrUndefined(loginType)){
+            header=loginType;
+        };
+        return SaManager.getStpLogic(header);
+    }
+}

+ 21 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/vo/RoleInfoVO.java

@@ -0,0 +1,21 @@
+package cn.tr.module.sys.oauth2.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 角色VO
+ *
+ * @author Kevin
+ */
+@Data
+public class RoleInfoVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String roleName;
+
+    private String value;
+
+}

+ 41 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/vo/UserInfoVO.java

@@ -0,0 +1,41 @@
+package cn.tr.module.sys.oauth2.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 用户信息VO
+ *
+ * @author Kevin
+ */
+@Data
+public class UserInfoVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String userId;
+
+    private String username;
+
+    private String realName;
+
+    private String nickname;
+
+    private String avatar;
+
+    private String desc;
+
+    private String tenantId;
+
+    private String tenantName;
+
+    private List<RoleInfoVO> roles;
+
+    private Boolean isSys;
+
+    private Integer isEdit;
+
+    private Boolean pswNeedReset;
+}

+ 1 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/sms/service/impl/SmsSendServiceImpl.java

@@ -7,7 +7,6 @@ import cn.tr.core.enums.UserTypeEnum;
 import cn.tr.core.exception.ServiceException;
 import cn.tr.core.exception.TRExcCode;
 import cn.tr.core.pojo.KeyValue;
-import cn.tr.core.utils.JsonUtils;
 import cn.tr.module.sys.sms.dto.SmsSendMessageDTO;
 import cn.tr.module.sys.sms.dto.SysSmsChannelDTO;
 import cn.tr.module.sys.sms.dto.SysSmsTempDTO;
@@ -16,7 +15,7 @@ import cn.tr.module.sys.sms.service.ISysSmsChannelService;
 import cn.tr.module.sys.sms.service.ISysSmsLogService;
 import cn.tr.module.sys.sms.service.ISysSmsTempService;
 import cn.tr.module.sys.user.dto.SysUserDTO;
-import cn.tr.module.sys.user.service.ISysUserService;
+import cn.tr.module.sys.user.service.impl.ISysUserService;
 import cn.tr.plugin.sms.bo.SmsCommonResult;
 import cn.tr.plugin.sms.bo.SmsReceiveRespBO;
 import cn.tr.plugin.sms.bo.SmsSendRespBO;

+ 93 - 93
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantController.java

@@ -1,93 +1,93 @@
-package cn.tr.module.sys.tenant.controller;
-
-import cn.tr.core.strategy.LoginUserStrategy;
-import cn.tr.module.sys.tenant.dto.SysTenantAddDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.tr.core.validation.Insert;
-import cn.tr.core.validation.Update;
-import cn.tr.core.pojo.CommonResult;
-import lombok.AllArgsConstructor;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-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 cn.tr.module.sys.tenant.service.ISysTenantService;
-import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
-import java.util.*;
-import cn.tr.core.context.BaseController;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 租户列表控制器
- *
- * @author lf
- * @date  2023/04/15 15:27
- */
-@Tag(name = "租户列表")
-@RestController
-@RequestMapping("/sys/tenant")
-@AllArgsConstructor
-public class SysTenantController extends BaseController{
-
-    private final ISysTenantService sysTenantService;
-
-    @ApiOperationSupport(author = "lf",order = 1)
-    @Operation(summary = "根据条件查询租户列表", description = "权限: 无")
-    @PostMapping("/query/page")
-    public CommonResult<List<SysTenantCommonDTO>> selectList(@RequestBody SysTenantQueryDTO query) {
-        startPage();
-        return CommonResult.success(sysTenantService.selectSysTenantList(query));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 2)
-    @Operation(summary = "根据id查询租户列表", description = "权限: sys:tenant:query")
-    @GetMapping("/detail/{id}")
-    @Parameter(name = "id", description = "租户ID", required = true)
-    @SaCheckPermission("sys:tenant:query")
-    public CommonResult<SysTenantCommonDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(sysTenantService.selectSysTenantById(id));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 3)
-    @Operation(summary = "添加租户列表", description = "权限: sys:tenant:add")
-    @PostMapping("/add")
-    @SaCheckPermission("sys:tenant:add")
-    @OperateLog
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysTenantAddDTO source) {
-        source.setType(CreateEnum.custom.name());
-        return CommonResult.success(sysTenantService.insertSysTenant(source));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 4)
-    @Operation(summary = "通过主键id编辑租户列表", description = "权限: sys:tenant:edit")
-    @PostMapping("/edit")
-    @SaCheckPermission("sys:tenant:edit")
-    @OperateLog
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysTenantCommonDTO source) {
-        return CommonResult.success(sysTenantService.updateSysTenantById(source));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 5)
-    @Operation(summary = "删除租户列表", description = "权限: sys:tenant:remove")
-    @PostMapping("/removeByIds")
-    @SaCheckPermission("sys:tenant:remove")
-    @OperateLog
-    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
-        return CommonResult.success(sysTenantService.removeSysTenantByIds(ids));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 6)
-    @Operation(summary = "查询当前用户的租户信息", description = "权限: 无")
-    @PostMapping("/query/current")
-    public CommonResult<SysTenantCommonDTO> selectList() {
-        return CommonResult.success(sysTenantService.selectSysTenantById(LoginUserStrategy.tr.getTenantId()));
-    }
-}
+//package cn.tr.module.sys.tenant.controller;
+//
+//import cn.tr.core.strategy.LoginUserStrategy;
+//import cn.tr.module.sys.tenant.dto.SysTenantAddDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
+//import cn.tr.core.enums.CreateEnum;
+//import cn.tr.module.api.sys.log.annotation.OperateLog;
+//import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+//import cn.dev33.satoken.annotation.SaCheckPermission;
+//import cn.tr.core.validation.Insert;
+//import cn.tr.core.validation.Update;
+//import cn.tr.core.pojo.CommonResult;
+//import lombok.AllArgsConstructor;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//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 cn.tr.module.sys.tenant.service.ISysTenantService;
+//import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
+//import java.util.*;
+//import cn.tr.core.context.BaseController;
+//import org.springframework.web.bind.annotation.*;
+//
+///**
+// * 租户列表控制器
+// *
+// * @author lf
+// * @date  2023/04/15 15:27
+// */
+//@Tag(name = "租户列表")
+//@RestController
+//@RequestMapping("/sys/tenant")
+//@AllArgsConstructor
+//public class SysTenantController extends BaseController{
+//
+//    private final ISysTenantService sysTenantService;
+//
+//    @ApiOperationSupport(author = "lf",order = 1)
+//    @Operation(summary = "根据条件查询租户列表", description = "权限: 无")
+//    @PostMapping("/query/page")
+//    public CommonResult<List<SysTenantCommonDTO>> selectList(@RequestBody SysTenantQueryDTO query) {
+//        startPage();
+//        return CommonResult.success(sysTenantService.selectSysTenantList(query));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 2)
+//    @Operation(summary = "根据id查询租户列表", description = "权限: sys:tenant:query")
+//    @GetMapping("/detail/{id}")
+//    @Parameter(name = "id", description = "租户ID", required = true)
+//    @SaCheckPermission("sys:tenant:query")
+//    public CommonResult<SysTenantCommonDTO> findById(@PathVariable("id") String id){
+//        return CommonResult.success(sysTenantService.selectSysTenantById(id));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 3)
+//    @Operation(summary = "添加租户列表", description = "权限: sys:tenant:add")
+//    @PostMapping("/add")
+//    @SaCheckPermission("sys:tenant:add")
+//    @OperateLog
+//    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysTenantAddDTO source) {
+//        source.setType(CreateEnum.custom.name());
+//        return CommonResult.success(sysTenantService.insertSysTenant(source));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 4)
+//    @Operation(summary = "通过主键id编辑租户列表", description = "权限: sys:tenant:edit")
+//    @PostMapping("/edit")
+//    @SaCheckPermission("sys:tenant:edit")
+//    @OperateLog
+//    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysTenantCommonDTO source) {
+//        return CommonResult.success(sysTenantService.updateSysTenantById(source));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 5)
+//    @Operation(summary = "删除租户列表", description = "权限: sys:tenant:remove")
+//    @PostMapping("/removeByIds")
+//    @SaCheckPermission("sys:tenant:remove")
+//    @OperateLog
+//    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
+//        return CommonResult.success(sysTenantService.removeSysTenantByIds(ids));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 6)
+//    @Operation(summary = "查询当前用户的租户信息", description = "权限: 无")
+//    @PostMapping("/query/current")
+//    public CommonResult<SysTenantCommonDTO> selectList() {
+//        return CommonResult.success(sysTenantService.selectSysTenantById(LoginUserStrategy.tr.getTenantId()));
+//    }
+//}

+ 104 - 105
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantPackageController.java

@@ -1,105 +1,104 @@
-package cn.tr.module.sys.tenant.controller;
-
-import cn.tr.core.pojo.TableDataInfo;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageMenuAssignDTO;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.tr.core.validation.Insert;
-import cn.tr.core.validation.Update;
-import cn.tr.core.pojo.CommonResult;
-import lombok.AllArgsConstructor;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-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 cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
-import java.util.*;
-import cn.tr.core.context.BaseController;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 租户套餐控制器
- *
- * @author lf
- * @date  2023/04/15 15:28
- */
-@Tag(name = "租户套餐")
-@RestController
-@RequestMapping("/sys/tenantPackage")
-@AllArgsConstructor
-public class SysTenantPackageController extends BaseController{
-
-    private final ISysTenantPackageService sysTenantPackageService;
-    private final ISysTenantPackageMenuService sysTenantPackageMenuService;
-
-    @GetMapping("/menu/list/{packageId}")
-    @Operation(summary = "查询套餐下的权限信息", description = "权限: 无")
-    public CommonResult<Set<SysMenuDTO>> listMenu(@Parameter(description = "套餐ID") @PathVariable("packageId") String packageId) {
-        return CommonResult.success(sysTenantPackageMenuService.findMenuIdByPackageId(packageId));
-    }
-
-    @PostMapping("/assign")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "为套餐分配权限", description = "权限: sys:tenantPackage:assign")
-    @SaCheckPermission("sys:tenantPackage:assign")
-    @OperateLog
-    public CommonResult<Boolean> selectList(@RequestBody@Validated SysTenantPackageMenuAssignDTO source){
-        sysTenantPackageMenuService.assignPackageMenu(source.getPackageId(),source.getMenuIds());
-        return CommonResult.success(true);
-    }
-
-    @ApiOperationSupport(author = "lf",order = 1)
-    @Operation(summary = "根据条件查询租户套餐", description = "权限:无")
-    @PostMapping("/query/page")
-    public TableDataInfo<SysTenantPackageDTO> selectPage(@RequestBody SysTenantPackageQueryDTO query) {
-        startPage();
-        return getDataTable(sysTenantPackageService.selectSysTenantPackageList(query));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 2)
-    @Operation(summary = "根据id查询租户套餐", description = "权限: sys:tenantPackage:query")
-    @GetMapping("/detail/{id}")
-    @Parameter(name = "id", description = "套餐ID", required = true)
-    @SaCheckPermission("sys:tenantPackage:query")
-    public CommonResult<SysTenantPackageDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(sysTenantPackageService.selectSysTenantPackageById(id));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 3)
-    @Operation(summary = "添加租户套餐", description = "权限: sys:tenantPackage:add")
-    @PostMapping("/add")
-    @SaCheckPermission("sys:tenantPackage:add")
-    @OperateLog
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysTenantPackageDTO source) {
-        source.setType(CreateEnum.custom.name());
-        return CommonResult.success(sysTenantPackageService.insertSysTenantPackage(source));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 4)
-    @Operation(summary = "通过主键id编辑租户套餐", description = "权限: sys:tenantPackage:edit")
-    @PostMapping("/edit")
-    @SaCheckPermission("sys:tenantPackage:edit")
-    @OperateLog
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysTenantPackageDTO source) {
-        return CommonResult.success(sysTenantPackageService.updateSysTenantPackageById(source));
-    }
-
-    @ApiOperationSupport(author = "lf",order = 5)
-    @Operation(summary = "删除租户套餐", description = "权限: sys:tenantPackage:remove")
-    @PostMapping("/removeByIds")
-    @SaCheckPermission("sys:tenantPackage:remove")
-    @OperateLog
-    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
-        return CommonResult.success(sysTenantPackageService.removeSysTenantPackageByIds(ids));
-    }
-}
+//package cn.tr.module.sys.tenant.controller;
+//
+//import cn.tr.core.pojo.TableDataInfo;
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageMenuAssignDTO;
+//import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
+//import cn.tr.core.enums.CreateEnum;
+//import cn.tr.module.api.sys.log.annotation.OperateLog;
+//import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+//import cn.dev33.satoken.annotation.SaCheckPermission;
+//import cn.tr.core.validation.Insert;
+//import cn.tr.core.validation.Update;
+//import cn.tr.core.pojo.CommonResult;
+//import lombok.AllArgsConstructor;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//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 cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
+//import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
+//import java.util.*;
+//import cn.tr.core.context.BaseController;
+//import org.springframework.web.bind.annotation.*;
+//
+///**
+// * 租户套餐控制器
+// *
+// * @author lf
+// * @date  2023/04/15 15:28
+// */
+//@Tag(name = "租户套餐")
+//@RestController
+//@RequestMapping("/sys/tenantPackage")
+//@AllArgsConstructor
+//public class SysTenantPackageController extends BaseController{
+//
+//    private final ISysTenantPackageService sysTenantPackageService;
+//    private final ISysTenantPackageMenuService sysTenantPackageMenuService;
+//
+//    @GetMapping("/menu/list/{packageId}")
+//    @Operation(summary = "查询套餐下的权限信息", description = "权限: 无")
+//    public CommonResult<Set<SysMenuDTO>> listMenu(@Parameter(description = "套餐ID") @PathVariable("packageId") String packageId) {
+//        return CommonResult.success(sysTenantPackageMenuService.findMenuIdByPackageId(packageId));
+//    }
+//
+//    @PostMapping("/assign")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "为套餐分配权限", description = "权限: sys:tenantPackage:assign")
+//    @SaCheckPermission("sys:tenantPackage:assign")
+//    @OperateLog
+//    public CommonResult<Boolean> selectList(@RequestBody@Validated SysTenantPackageMenuAssignDTO source){
+//        sysTenantPackageMenuService.assignPackageMenu(source.getPackageId(),source.getMenuIds());
+//        return CommonResult.success(true);
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 1)
+//    @Operation(summary = "根据条件查询租户套餐", description = "权限:无")
+//    @PostMapping("/query/page")
+//    public TableDataInfo<SysTenantPackageDTO> selectPage(@RequestBody SysTenantPackageQueryDTO query) {
+//        startPage();
+//        return getDataTable(sysTenantPackageService.selectSysTenantPackageList(query));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 2)
+//    @Operation(summary = "根据id查询租户套餐", description = "权限: sys:tenantPackage:query")
+//    @GetMapping("/detail/{id}")
+//    @Parameter(name = "id", description = "套餐ID", required = true)
+//    @SaCheckPermission("sys:tenantPackage:query")
+//    public CommonResult<SysTenantPackageDTO> findById(@PathVariable("id") String id){
+//        return CommonResult.success(sysTenantPackageService.selectSysTenantPackageById(id));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 3)
+//    @Operation(summary = "添加租户套餐", description = "权限: sys:tenantPackage:add")
+//    @PostMapping("/add")
+//    @SaCheckPermission("sys:tenantPackage:add")
+//    @OperateLog
+//    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysTenantPackageDTO source) {
+//        source.setType(CreateEnum.custom.name());
+//        return CommonResult.success(sysTenantPackageService.insertSysTenantPackage(source));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 4)
+//    @Operation(summary = "通过主键id编辑租户套餐", description = "权限: sys:tenantPackage:edit")
+//    @PostMapping("/edit")
+//    @SaCheckPermission("sys:tenantPackage:edit")
+//    @OperateLog
+//    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysTenantPackageDTO source) {
+//        return CommonResult.success(sysTenantPackageService.updateSysTenantPackageById(source));
+//    }
+//
+//    @ApiOperationSupport(author = "lf",order = 5)
+//    @Operation(summary = "删除租户套餐", description = "权限: sys:tenantPackage:remove")
+//    @PostMapping("/removeByIds")
+//    @SaCheckPermission("sys:tenantPackage:remove")
+//    @OperateLog
+//    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
+//        return CommonResult.success(sysTenantPackageService.removeSysTenantPackageByIds(ids));
+//    }
+//}

+ 49 - 50
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/ISysTenantPackageMenuService.java

@@ -1,50 +1,49 @@
-package cn.tr.module.sys.tenant.service;
-
-import cn.tr.module.sys.user.dto.SysMenuDTO;
-import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
-
-import java.util.*;
-/**
- * @ClassName : ISysTenantPackageMenuService
- * @Description :
- * @Author : LF
- * @Date: 2023年04月07日
- */
-
-public interface ISysTenantPackageMenuService {
-    /**
-     * 为租户套餐分配菜单
-     * @param packageId 套餐id
-     * @param
-     * @return
-     */
-    void assignPackageMenu(String packageId,List<String> menuIds);
-
-    /**
-     * 通过菜单id找到所有持有该菜单的套餐
-     * @param menuIds
-     * @param containsSys 是否包含系统套餐
-     * @return
-     */
-    Set<String> findPackageIdByMenuId(Collection<String> menuIds,boolean containsSys);
-
-    /**
-     * 删除套餐缓存
-     * {@link ISysTenantPackageMenuService#assignPackageMenu(String,List)}
-     * {@link cn.tr.module.sys.user.service.ISysMenuService#deleteSysMenuByIds(Collection)}
-     * {@link cn.tr.module.sys.user.service.ISysMenuService#updateSysMenuById(SysMenuDTO)}
-     * @param packageId
-     */
-    @CacheEvict(value = "global:menu:package",key = "#packageId")
-    default void delCacheMenuIdByPackageId(String packageId){
-
-    }
-    /**
-     * 找到套餐下所有的菜单id
-     * @param packageId
-     * @return
-     */
-    @Cacheable(value = "global:menu:package",key = "#packageId")
-    Set<SysMenuDTO> findMenuIdByPackageId(String packageId);
-}
+//package cn.tr.module.sys.tenant.service;
+//
+//import org.springframework.cache.annotation.CacheEvict;
+//import org.springframework.cache.annotation.Cacheable;
+//
+//import java.util.*;
+///**
+// * @ClassName : ISysTenantPackageMenuService
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月07日
+// */
+//
+//public interface ISysTenantPackageMenuService {
+//    /**
+//     * 为租户套餐分配菜单
+//     * @param packageId 套餐id
+//     * @param
+//     * @return
+//     */
+//    void assignPackageMenu(String packageId,List<String> menuIds);
+//
+//    /**
+//     * 通过菜单id找到所有持有该菜单的套餐
+//     * @param menuIds
+//     * @param containsSys 是否包含系统套餐
+//     * @return
+//     */
+//    Set<String> findPackageIdByMenuId(Collection<String> menuIds,boolean containsSys);
+//
+//    /**
+//     * 删除套餐缓存
+//     * {@link ISysTenantPackageMenuService#assignPackageMenu(String,List)}
+//     * {@link cn.tr.module.sys.user.service.ISysMenuService#deleteSysMenuByIds(Collection)}
+//     * {@link cn.tr.module.sys.user.service.ISysMenuService#updateSysMenuById(SysMenuDTO)}
+//     * @param packageId
+//     */
+//    @CacheEvict(value = "global:menu:package",key = "#packageId")
+//    default void delCacheMenuIdByPackageId(String packageId){
+//
+//    }
+//    /**
+//     * 找到套餐下所有的菜单id
+//     * @param packageId
+//     * @return
+//     */
+//    @Cacheable(value = "global:menu:package",key = "#packageId")
+//    Set<SysMenuDTO> findMenuIdByPackageId(String packageId);
+//}

+ 53 - 53
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/ISysTenantPackageService.java

@@ -1,53 +1,53 @@
-package cn.tr.module.sys.tenant.service;
-
-import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @ClassName : ISysTenantPackageService
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-public interface ISysTenantPackageService {
-
-    /**
-     * 根据条件查询
-     * @param query 查询参数
-     * @return
-     */
-    List<SysTenantPackageDTO> selectSysTenantPackageList(SysTenantPackageQueryDTO query);
-
-    /**
-     * 根据id查询操作租户套餐
-     * @param id 租户套餐id
-     * @return 租户套餐
-     */
-    SysTenantPackageDTO selectSysTenantPackageById(String id);
-
-    /**
-     * 更新租户套餐
-     * @param source 更新租户套餐
-     * @return true:更新成功
-     */
-    boolean updateSysTenantPackageById(SysTenantPackageDTO source);
-
-    /**
-     * 新增租户套餐
-     * @param source 新增租户套餐
-     * @return true:新增成功
-     */
-    boolean insertSysTenantPackage(SysTenantPackageDTO source);
-
-    /**
-     * 根据id删除租户套餐
-     * @param ids 租户套餐id
-     * @return 删除数量
-     */
-    int removeSysTenantPackageByIds(Collection<String> ids);
-
-    Collection<SysTenantPackageDTO> findAllSysPackages();
-}
+//package cn.tr.module.sys.tenant.service;
+//
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
+//
+//import java.util.Collection;
+//import java.util.List;
+//
+///**
+// * @ClassName : ISysTenantPackageService
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//public interface ISysTenantPackageService {
+//
+//    /**
+//     * 根据条件查询
+//     * @param query 查询参数
+//     * @return
+//     */
+//    List<SysTenantPackageDTO> selectSysTenantPackageList(SysTenantPackageQueryDTO query);
+//
+//    /**
+//     * 根据id查询操作租户套餐
+//     * @param id 租户套餐id
+//     * @return 租户套餐
+//     */
+//    SysTenantPackageDTO selectSysTenantPackageById(String id);
+//
+//    /**
+//     * 更新租户套餐
+//     * @param source 更新租户套餐
+//     * @return true:更新成功
+//     */
+//    boolean updateSysTenantPackageById(SysTenantPackageDTO source);
+//
+//    /**
+//     * 新增租户套餐
+//     * @param source 新增租户套餐
+//     * @return true:新增成功
+//     */
+//    boolean insertSysTenantPackage(SysTenantPackageDTO source);
+//
+//    /**
+//     * 根据id删除租户套餐
+//     * @param ids 租户套餐id
+//     * @return 删除数量
+//     */
+//    int removeSysTenantPackageByIds(Collection<String> ids);
+//
+//    Collection<SysTenantPackageDTO> findAllSysPackages();
+//}

+ 81 - 82
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/ISysTenantService.java

@@ -1,82 +1,81 @@
-package cn.tr.module.sys.tenant.service;
-
-import cn.hutool.core.util.StrUtil;
-import cn.tr.module.sys.tenant.dto.SysTenantAddDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
-import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName : ISysTenantService
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-
-public interface ISysTenantService {
-    /**
-     * 根据条件查询
-     * @param query 查询参数
-     * @return
-     */
-    List<SysTenantCommonDTO> selectSysTenantList(SysTenantQueryDTO query);
-
-    /**
-     * 根据id查询操作租户
-     * @param id 租户id
-     * @return 租户
-     */
-    SysTenantCommonDTO selectSysTenantById(String id);
-
-    /**
-     * 更新租户
-     * @param source 更新租户
-     * @return true:更新成功
-     */
-    boolean updateSysTenantById(SysTenantCommonDTO source);
-
-    /**
-     * 新增租户
-     * @param source 新增租户
-     * @return true:新增成功
-     */
-    boolean insertSysTenant(SysTenantAddDTO source);
-
-    /**
-     * 根据id删除租户
-     * @param ids 租户id
-     * @return 删除数量
-     */
-    int removeSysTenantByIds(Collection<String> ids);
-    /**
-     * 获取当前租户的菜单id
-     * @return
-     */
-
-    /**
-     * 查询租户的权限
-     * @return
-     */
-    default Set<String>  findTenantPermission(){
-        return currentTenantMenus()
-                .stream()
-                .filter(Objects::nonNull)
-                .filter(menu->Boolean.FALSE.equals(menu.getDisable()))
-                .map(SysMenuDTO::getPermission)
-                .filter(StrUtil::isNotEmpty)
-                .collect(Collectors.toSet());
-    };
-
-    default Set<SysMenuDTO> currentTenantMenus(){
-        return getTenantMenus(TenantContextHolder.getTenantId());
-    };
-
-    Set<SysMenuDTO> getTenantMenus(String tenantId);
-}
+//package cn.tr.module.sys.tenant.service;
+//
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.module.sys.tenant.dto.SysTenantAddDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
+//import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
+//
+//import java.util.Collection;
+//import java.util.List;
+//import java.util.Objects;
+//import java.util.Set;
+//import java.util.stream.Collectors;
+//
+///**
+// * @ClassName : ISysTenantService
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//
+//public interface ISysTenantService {
+//    /**
+//     * 根据条件查询
+//     * @param query 查询参数
+//     * @return
+//     */
+//    List<SysTenantCommonDTO> selectSysTenantList(SysTenantQueryDTO query);
+//
+//    /**
+//     * 根据id查询操作租户
+//     * @param id 租户id
+//     * @return 租户
+//     */
+//    SysTenantCommonDTO selectSysTenantById(String id);
+//
+//    /**
+//     * 更新租户
+//     * @param source 更新租户
+//     * @return true:更新成功
+//     */
+//    boolean updateSysTenantById(SysTenantCommonDTO source);
+//
+//    /**
+//     * 新增租户
+//     * @param source 新增租户
+//     * @return true:新增成功
+//     */
+//    boolean insertSysTenant(SysTenantAddDTO source);
+//
+//    /**
+//     * 根据id删除租户
+//     * @param ids 租户id
+//     * @return 删除数量
+//     */
+//    int removeSysTenantByIds(Collection<String> ids);
+//    /**
+//     * 获取当前租户的菜单id
+//     * @return
+//     */
+//
+//    /**
+//     * 查询租户的权限
+//     * @return
+//     */
+//    default Set<String>  findTenantPermission(){
+//        return currentTenantMenus()
+//                .stream()
+//                .filter(Objects::nonNull)
+//                .filter(menu->Boolean.FALSE.equals(menu.getDisable()))
+//                .map(SysMenuDTO::getPermission)
+//                .filter(StrUtil::isNotEmpty)
+//                .collect(Collectors.toSet());
+//    };
+//
+//    default Set<SysMenuDTO> currentTenantMenus(){
+//        return getTenantMenus(TenantContextHolder.getTenantId());
+//    };
+//
+//    Set<SysMenuDTO> getTenantMenus(String tenantId);
+//}

+ 148 - 149
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantPackageMenuServiceImpl.java

@@ -1,149 +1,148 @@
-package cn.tr.module.sys.tenant.service.impl;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
-import cn.tr.module.sys.tenant.enums.PackageEnum;
-import cn.tr.module.sys.tenant.po.SysTenantPackageMenuPO;
-import cn.tr.module.sys.tenant.repository.SysTenantPackageMenuRepository;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
-import cn.tr.module.sys.tenant.service.ISysTenantService;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
-import cn.tr.module.sys.user.dto.SysPortalDTO;
-import cn.tr.module.sys.user.dto.SysRoleDTO;
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.module.sys.user.service.ISysMenuService;
-import cn.tr.module.sys.user.service.ISysPortalMenuService;
-import cn.tr.module.sys.user.service.ISysPortalService;
-import cn.tr.module.sys.user.service.ISysRoleService;
-import cn.tr.plugin.biz.tenant.utils.TenantUtils;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName : SysTenantPackageMenuServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年04月07日
- */
-@Service
-public class SysTenantPackageMenuServiceImpl  extends ServiceImpl<SysTenantPackageMenuRepository, SysTenantPackageMenuPO>  implements ISysTenantPackageMenuService {
-    @Autowired
-    @Lazy
-    private ISysTenantPackageService tenantPackageService;
-    @Autowired
-    @Lazy
-    private ISysTenantPackageMenuService self;
-    @Autowired
-    @Lazy
-    private ISysRoleService roleService;
-
-    @Autowired
-    @Lazy
-    private ISysMenuService menuService;
-
-    @Autowired
-    @Lazy
-    private ISysPortalMenuService portalMenuService;
-
-    @Autowired
-    @Lazy
-    private ISysPortalService portalService;
-
-    @Autowired
-    @Lazy
-    private ISysTenantService tenantService;
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void assignPackageMenu(String packageId,List<String> menuIds) {
-        SysTenantPackageDTO tenantPackage = tenantPackageService.selectSysTenantPackageById(packageId);
-        if(StrUtil.equals(tenantPackage.getType(), CreateEnum.sys.name())){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统套餐进行操作");
-        }
-
-        baseMapper.delete(
-                new LambdaQueryWrapper<SysTenantPackageMenuPO>().eq(SysTenantPackageMenuPO::getPackageId,packageId)
-        );
-        if(CollectionUtil.isNotEmpty(menuIds)){
-            List<SysTenantPackageMenuPO> packageMenus = menuIds
-                    .stream()
-                    .distinct()
-                    .map(menuId -> {
-                        SysTenantPackageMenuPO result = new SysTenantPackageMenuPO();
-                        result.setMenuId(menuId);
-                        result.setPackageId(packageId);
-                        return result;
-                    })
-                    .collect(Collectors.toList());
-            this.saveBatch(packageMenus);
-        }
-        self.delCacheMenuIdByPackageId(packageId);
-
-
-        //对套餐绑定的租户进行操作
-        SysTenantQueryDTO query = new SysTenantQueryDTO();
-        query.setPackageId(packageId);
-        List<SysTenantCommonDTO> tenants = tenantService.selectSysTenantList(query);
-        if (CollectionUtil.isNotEmpty(tenants)) {
-            for (SysTenantCommonDTO tenant : tenants) {
-                TenantUtils.execute(tenant.getId(),()->{
-                    Collection<SysRoleDTO> sysRoles = roleService.findAllSysRoles();
-                    Collection<SysPortalDTO> sysPortals = portalService.findAllSysPortals();
-
-                    sysRoles.forEach(role->menuService.delRoleMenusCache(role.getId()));
-                    sysPortals.forEach(portal->portalMenuService.delCacheMenusByPortalId(portal.getId()));
-                });
-            }
-        }
-    }
-
-    @Override
-    public Set<String> findPackageIdByMenuId(Collection<String> menuIds,boolean containsSys) {
-        Set<String> packageIds = this.list(new LambdaQueryWrapper<SysTenantPackageMenuPO>()
-                .in(SysTenantPackageMenuPO::getMenuId, menuIds))
-                .stream()
-                .map(SysTenantPackageMenuPO::getPackageId)
-                .collect(Collectors.toSet());
-        Set<String> sysPackageIds=new HashSet<>();
-        if(containsSys){
-            sysPackageIds = tenantPackageService.findAllSysPackages().stream()
-                    .map(SysTenantPackageDTO::getId)
-                    .collect(Collectors.toSet());
-
-        }
-        sysPackageIds.addAll(packageIds);
-        return sysPackageIds;
-    }
-
-    @Override
-    public Set<SysMenuDTO> findMenuIdByPackageId(String packageId) {
-        SysTenantPackageDTO packageDTO = tenantPackageService.selectSysTenantPackageById(packageId);
-        if(packageDTO!=null&&StrUtil.equals(packageDTO.getType(), PackageEnum.sys.name())){
-            //所有目录id
-            return new HashSet<>(menuService.findAllMenu());
-        }
-        Set<SysMenuDTO> result = new HashSet<>();
-        Set<String> menuIds = this.list(new LambdaQueryWrapper<SysTenantPackageMenuPO>().eq(SysTenantPackageMenuPO::getPackageId, packageId))
-                .stream()
-                .map(SysTenantPackageMenuPO::getMenuId)
-                .collect(Collectors.toSet());
-        if(CollectionUtil.isNotEmpty(menuIds)){
-            List<SysMenuDTO> menus = menuService.selectBatchIds(menuIds);
-            result.addAll(menus);
-        }
-        return result;
-    }
-}
+//package cn.tr.module.sys.tenant.service.impl;
+//
+//import cn.hutool.core.collection.CollectionUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
+//import cn.tr.module.sys.tenant.enums.PackageEnum;
+//import cn.tr.module.sys.tenant.po.SysTenantPackageMenuPO;
+//import cn.tr.module.sys.tenant.repository.SysTenantPackageMenuRepository;
+//import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
+//import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
+//import cn.tr.module.sys.tenant.service.ISysTenantService;
+//import cn.tr.module.sys.user.dto.SysPortalDTO;
+//import cn.tr.module.sys.user.dto.SysRoleDTO;
+//import cn.tr.core.enums.CreateEnum;
+//import cn.tr.module.sys.user.service.ISysMenuService;
+//import cn.tr.module.sys.user.service.ISysPortalMenuService;
+//import cn.tr.module.sys.user.service.ISysPortalService;
+//import cn.tr.module.sys.user.service.ISysRoleService;
+//import cn.tr.plugin.biz.tenant.utils.TenantUtils;
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Lazy;
+//import org.springframework.stereotype.Service;
+//import org.springframework.transaction.annotation.Transactional;
+//
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * @ClassName : SysTenantPackageMenuServiceImpl
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月07日
+// */
+//@Service
+//public class SysTenantPackageMenuServiceImpl  extends ServiceImpl<SysTenantPackageMenuRepository, SysTenantPackageMenuPO>  implements ISysTenantPackageMenuService {
+//    @Autowired
+//    @Lazy
+//    private ISysTenantPackageService tenantPackageService;
+//    @Autowired
+//    @Lazy
+//    private ISysTenantPackageMenuService self;
+//    @Autowired
+//    @Lazy
+//    private ISysRoleService roleService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysMenuService menuService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysPortalMenuService portalMenuService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysPortalService portalService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysTenantService tenantService;
+//
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public void assignPackageMenu(String packageId,List<String> menuIds) {
+//        SysTenantPackageDTO tenantPackage = tenantPackageService.selectSysTenantPackageById(packageId);
+//        if(StrUtil.equals(tenantPackage.getType(), CreateEnum.sys.name())){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统套餐进行操作");
+//        }
+//
+//        baseMapper.delete(
+//                new LambdaQueryWrapper<SysTenantPackageMenuPO>().eq(SysTenantPackageMenuPO::getPackageId,packageId)
+//        );
+//        if(CollectionUtil.isNotEmpty(menuIds)){
+//            List<SysTenantPackageMenuPO> packageMenus = menuIds
+//                    .stream()
+//                    .distinct()
+//                    .map(menuId -> {
+//                        SysTenantPackageMenuPO result = new SysTenantPackageMenuPO();
+//                        result.setMenuId(menuId);
+//                        result.setPackageId(packageId);
+//                        return result;
+//                    })
+//                    .collect(Collectors.toList());
+//            this.saveBatch(packageMenus);
+//        }
+//        self.delCacheMenuIdByPackageId(packageId);
+//
+//
+//        //对套餐绑定的租户进行操作
+//        SysTenantQueryDTO query = new SysTenantQueryDTO();
+//        query.setPackageId(packageId);
+//        List<SysTenantCommonDTO> tenants = tenantService.selectSysTenantList(query);
+//        if (CollectionUtil.isNotEmpty(tenants)) {
+//            for (SysTenantCommonDTO tenant : tenants) {
+//                TenantUtils.execute(tenant.getId(),()->{
+//                    Collection<SysRoleDTO> sysRoles = roleService.findAllSysRoles();
+//                    Collection<SysPortalDTO> sysPortals = portalService.findAllSysPortals();
+//
+//                    sysRoles.forEach(role->menuService.delRoleMenusCache(role.getId()));
+//                    sysPortals.forEach(portal->portalMenuService.delCacheMenusByPortalId(portal.getId()));
+//                });
+//            }
+//        }
+//    }
+//
+//    @Override
+//    public Set<String> findPackageIdByMenuId(Collection<String> menuIds,boolean containsSys) {
+//        Set<String> packageIds = this.list(new LambdaQueryWrapper<SysTenantPackageMenuPO>()
+//                .in(SysTenantPackageMenuPO::getMenuId, menuIds))
+//                .stream()
+//                .map(SysTenantPackageMenuPO::getPackageId)
+//                .collect(Collectors.toSet());
+//        Set<String> sysPackageIds=new HashSet<>();
+//        if(containsSys){
+//            sysPackageIds = tenantPackageService.findAllSysPackages().stream()
+//                    .map(SysTenantPackageDTO::getId)
+//                    .collect(Collectors.toSet());
+//
+//        }
+//        sysPackageIds.addAll(packageIds);
+//        return sysPackageIds;
+//    }
+//
+//    @Override
+//    public Set<SysMenuDTO> findMenuIdByPackageId(String packageId) {
+//        SysTenantPackageDTO packageDTO = tenantPackageService.selectSysTenantPackageById(packageId);
+//        if(packageDTO!=null&&StrUtil.equals(packageDTO.getType(), PackageEnum.sys.name())){
+//            //所有目录id
+//            return new HashSet<>(menuService.findAllMenu());
+//        }
+//        Set<SysMenuDTO> result = new HashSet<>();
+//        Set<String> menuIds = this.list(new LambdaQueryWrapper<SysTenantPackageMenuPO>().eq(SysTenantPackageMenuPO::getPackageId, packageId))
+//                .stream()
+//                .map(SysTenantPackageMenuPO::getMenuId)
+//                .collect(Collectors.toSet());
+//        if(CollectionUtil.isNotEmpty(menuIds)){
+//            List<SysMenuDTO> menus = menuService.selectBatchIds(menuIds);
+//            result.addAll(menus);
+//        }
+//        return result;
+//    }
+//}

+ 118 - 118
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantPackageServiceImpl.java

@@ -1,118 +1,118 @@
-package cn.tr.module.sys.tenant.service.impl;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.utils.JsonUtils;
-import cn.tr.module.sys.tenant.mapper.SysTenantPackageMapper;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
-import cn.tr.module.sys.tenant.enums.PackageEnum;
-import cn.tr.module.sys.tenant.po.SysTenantPO;
-import cn.tr.module.sys.tenant.po.SysTenantPackagePO;
-import cn.tr.module.sys.tenant.repository.SysTenantPackageRepository;
-import cn.tr.module.sys.tenant.repository.SysTenantRepository;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName : SysTenantPackageServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年04月07日
- */
-@Service
-public class SysTenantPackageServiceImpl implements ISysTenantPackageService {
-    @Autowired
-    private SysTenantPackageRepository tenantPackageRepository;
-
-    @Autowired
-    private SysTenantRepository tenantRepository;
-
-    @Override
-    public List<SysTenantPackageDTO> selectSysTenantPackageList(SysTenantPackageQueryDTO query) {
-        return SysTenantPackageMapper.INSTANCE.toDTOList(
-                tenantPackageRepository.selectList(new LambdaQueryWrapper<SysTenantPackagePO>()
-                        .like(StrUtil.isNotEmpty(query.getPackageCode()),SysTenantPackagePO::getPackageCode,query.getPackageCode())
-                        .like(StrUtil.isNotEmpty(query.getPackageName()),SysTenantPackagePO::getPackageName,query.getPackageName())
-                ));
-    }
-
-    @Override
-    public SysTenantPackageDTO selectSysTenantPackageById(String id) {
-        return SysTenantPackageMapper.INSTANCE.toDTO(tenantPackageRepository.selectById(id));
-    }
-
-    @Override
-    public boolean updateSysTenantPackageById(SysTenantPackageDTO source) {
-        validatePackageSource(Collections.singleton(source.getId()));
-        validateSource(source);
-        return tenantPackageRepository.updateById(SysTenantPackageMapper.INSTANCE.toPO(source))!=0;
-    }
-
-    @Override
-    public boolean insertSysTenantPackage(SysTenantPackageDTO source) {
-        validateSource(source);
-        return tenantPackageRepository.insert(SysTenantPackageMapper.INSTANCE.toPO(source))!=0;
-    }
-
-    @Override
-    public int removeSysTenantPackageByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
-        }
-        validatePackageSource(ids);
-        List<SysTenantPO> tenants = tenantRepository.selectList(new LambdaQueryWrapper<SysTenantPO>()
-                .in(SysTenantPO::getPackageId, ids));
-        if(CollectionUtil.isNotEmpty(tenants)){
-            Set<String> packageIds = tenants.stream().map(SysTenantPO::getPackageId).collect(Collectors.toSet());
-            if(CollectionUtil.isNotEmpty(packageIds)){
-                List<SysTenantPackagePO> packages = tenantPackageRepository.selectBatchIds(packageIds);
-                if(CollectionUtil.isNotEmpty(packages)){
-                    Set<String> packageNames = packages.stream().map(SysTenantPackagePO::getPackageName).collect(Collectors.toSet());
-                    throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("租户套餐 %s 正在被使用,无法删除", JsonUtils.toJsonString(packageNames)));
-                }
-            }
-        }
-        return tenantPackageRepository.deleteBatchIds(ids);
-    }
-
-    @Override
-    public Collection<SysTenantPackageDTO> findAllSysPackages() {
-        return SysTenantPackageMapper.INSTANCE.toDTOList(tenantPackageRepository.selectList(new LambdaQueryWrapper<SysTenantPackagePO>()
-                .eq(SysTenantPackagePO::getType, PackageEnum.sys.name())));
-    }
-
-    private void validateSource(SysTenantPackageDTO source){
-        SysTenantPackagePO sysTenantPackagePO = tenantPackageRepository.selectOne(new LambdaQueryWrapper<SysTenantPackagePO>()
-                .ne(StrUtil.isNotEmpty(source.getId()), SysTenantPackagePO::getId, source.getId())
-                .nested(t->{
-                    t.or()
-                            .eq(SysTenantPackagePO::getPackageCode, source.getPackageCode())
-                            .or()
-                            .eq(SysTenantPackagePO::getPackageName, source.getPackageName());
-                })
-
-                .last("limit 1"));
-        if(ObjectUtil.isNotNull(sysTenantPackagePO)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"租户套餐的名称、编码不能重复");
-        }
-    }
-
-    private void validatePackageSource(Collection<String> packageIds){
-        List<SysTenantPackagePO> packages = tenantPackageRepository.selectList(new LambdaQueryWrapper<SysTenantPackagePO>()
-                .in(SysTenantPackagePO::getId, packageIds));
-        for (SysTenantPackagePO aPackage : packages) {
-            if(StrUtil.equals(aPackage.getType(),PackageEnum.sys.name())){
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统级别套餐进行操作");
-            }
-        }
-    }
-}
+//package cn.tr.module.sys.tenant.service.impl;
+//
+//import cn.hutool.core.collection.CollectionUtil;
+//import cn.hutool.core.util.ObjectUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.core.utils.JsonUtils;
+//import cn.tr.module.sys.tenant.mapper.SysTenantPackageMapper;
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
+//import cn.tr.module.sys.tenant.enums.PackageEnum;
+//import cn.tr.module.sys.tenant.po.SysTenantPO;
+//import cn.tr.module.sys.tenant.po.SysTenantPackagePO;
+//import cn.tr.module.sys.tenant.repository.SysTenantPackageRepository;
+//import cn.tr.module.sys.tenant.repository.SysTenantRepository;
+//import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Service;
+//
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * @ClassName : SysTenantPackageServiceImpl
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月07日
+// */
+//@Service
+//public class SysTenantPackageServiceImpl implements ISysTenantPackageService {
+//    @Autowired
+//    private SysTenantPackageRepository tenantPackageRepository;
+//
+//    @Autowired
+//    private SysTenantRepository tenantRepository;
+//
+//    @Override
+//    public List<SysTenantPackageDTO> selectSysTenantPackageList(SysTenantPackageQueryDTO query) {
+//        return SysTenantPackageMapper.INSTANCE.toDTOList(
+//                tenantPackageRepository.selectList(new LambdaQueryWrapper<SysTenantPackagePO>()
+//                        .like(StrUtil.isNotEmpty(query.getPackageCode()),SysTenantPackagePO::getPackageCode,query.getPackageCode())
+//                        .like(StrUtil.isNotEmpty(query.getPackageName()),SysTenantPackagePO::getPackageName,query.getPackageName())
+//                ));
+//    }
+//
+//    @Override
+//    public SysTenantPackageDTO selectSysTenantPackageById(String id) {
+//        return SysTenantPackageMapper.INSTANCE.toDTO(tenantPackageRepository.selectById(id));
+//    }
+//
+//    @Override
+//    public boolean updateSysTenantPackageById(SysTenantPackageDTO source) {
+//        validatePackageSource(Collections.singleton(source.getId()));
+//        validateSource(source);
+//        return tenantPackageRepository.updateById(SysTenantPackageMapper.INSTANCE.toPO(source))!=0;
+//    }
+//
+//    @Override
+//    public boolean insertSysTenantPackage(SysTenantPackageDTO source) {
+//        validateSource(source);
+//        return tenantPackageRepository.insert(SysTenantPackageMapper.INSTANCE.toPO(source))!=0;
+//    }
+//
+//    @Override
+//    public int removeSysTenantPackageByIds(Collection<String> ids) {
+//        if(CollectionUtil.isEmpty(ids)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+//        }
+//        validatePackageSource(ids);
+//        List<SysTenantPO> tenants = tenantRepository.selectList(new LambdaQueryWrapper<SysTenantPO>()
+//                .in(SysTenantPO::getPackageId, ids));
+//        if(CollectionUtil.isNotEmpty(tenants)){
+//            Set<String> packageIds = tenants.stream().map(SysTenantPO::getPackageId).collect(Collectors.toSet());
+//            if(CollectionUtil.isNotEmpty(packageIds)){
+//                List<SysTenantPackagePO> packages = tenantPackageRepository.selectBatchIds(packageIds);
+//                if(CollectionUtil.isNotEmpty(packages)){
+//                    Set<String> packageNames = packages.stream().map(SysTenantPackagePO::getPackageName).collect(Collectors.toSet());
+//                    throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("租户套餐 %s 正在被使用,无法删除", JsonUtils.toJsonString(packageNames)));
+//                }
+//            }
+//        }
+//        return tenantPackageRepository.deleteBatchIds(ids);
+//    }
+//
+//    @Override
+//    public Collection<SysTenantPackageDTO> findAllSysPackages() {
+//        return SysTenantPackageMapper.INSTANCE.toDTOList(tenantPackageRepository.selectList(new LambdaQueryWrapper<SysTenantPackagePO>()
+//                .eq(SysTenantPackagePO::getType, PackageEnum.sys.name())));
+//    }
+//
+//    private void validateSource(SysTenantPackageDTO source){
+//        SysTenantPackagePO sysTenantPackagePO = tenantPackageRepository.selectOne(new LambdaQueryWrapper<SysTenantPackagePO>()
+//                .ne(StrUtil.isNotEmpty(source.getId()), SysTenantPackagePO::getId, source.getId())
+//                .nested(t->{
+//                    t.or()
+//                            .eq(SysTenantPackagePO::getPackageCode, source.getPackageCode())
+//                            .or()
+//                            .eq(SysTenantPackagePO::getPackageName, source.getPackageName());
+//                })
+//
+//                .last("limit 1"));
+//        if(ObjectUtil.isNotNull(sysTenantPackagePO)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"租户套餐的名称、编码不能重复");
+//        }
+//    }
+//
+//    private void validatePackageSource(Collection<String> packageIds){
+//        List<SysTenantPackagePO> packages = tenantPackageRepository.selectList(new LambdaQueryWrapper<SysTenantPackagePO>()
+//                .in(SysTenantPackagePO::getId, packageIds));
+//        for (SysTenantPackagePO aPackage : packages) {
+//            if(StrUtil.equals(aPackage.getType(),PackageEnum.sys.name())){
+//                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统级别套餐进行操作");
+//            }
+//        }
+//    }
+//}

+ 217 - 217
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantServiceImpl.java

@@ -1,217 +1,217 @@
-package cn.tr.module.sys.tenant.service.impl;
-
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.annotation.TenantIgnore;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.module.sys.config.SysConfigManager;
-import cn.tr.module.sys.tenant.mapper.SysTenantMapper;
-import cn.tr.module.sys.tenant.dto.SysTenantAddDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
-import cn.tr.module.sys.user.dto.*;
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.module.sys.user.enums.UserStatusEnum;
-import cn.tr.module.sys.tenant.po.SysTenantPO;
-import cn.tr.module.sys.tenant.repository.SysTenantRepository;
-import cn.tr.module.sys.user.service.*;
-import cn.tr.module.sys.tenant.service.ISysTenantService;
-import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
-import cn.tr.plugin.biz.tenant.utils.TenantUtils;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.IdWorker;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.*;
-
-/**
- * @ClassName : SysTenantServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年04月05日
- */
-@Service
-public class SysTenantServiceImpl implements ISysTenantService {
-    @Autowired
-    private SysTenantRepository tenantRepository;
-
-    @Autowired
-    @Lazy
-    private ISysPortalService portalService;
-
-    @Autowired
-    @Lazy
-    private ISysUserService userService;
-
-    @Autowired
-    @Lazy
-    private ISysUserPortalService userPortalService;
-
-    @Autowired
-    @Lazy
-    private ISysOrgService orgService;
-
-    @Autowired
-    @Lazy
-    private ISysRoleService roleService;
-
-    @Autowired
-    @Lazy
-    private SysConfigManager configManager;
-
-    @Autowired
-    @Lazy
-    private ISysTenantPackageMenuService tenantPackageMenuService;
-
-    @Override
-    @TenantIgnore
-    public List<SysTenantCommonDTO> selectSysTenantList(SysTenantQueryDTO query) {
-        return tenantRepository.stdSelectList(query);
-    }
-
-    @Override
-    @TenantIgnore
-    public SysTenantCommonDTO selectSysTenantById(String id) {
-        return tenantRepository.stdSelectById(id);
-    }
-
-    @Override
-    public boolean updateSysTenantById(SysTenantCommonDTO source) {
-        validateSource(source);
-        return tenantRepository.updateById(SysTenantMapper.INSTANCE.toPO(source))!=0;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean insertSysTenant(SysTenantAddDTO source) {
-        validateSource(source);
-        String orgId= IdWorker.getIdStr();
-        String userId= IdWorker.getIdStr();
-        String roleId= IdWorker.getIdStr();
-        String portalId= IdWorker.getIdStr();
-        SysTenantPO tenant = SysTenantMapper.INSTANCE.toPO(source);
-        tenant.setTenantUserId(userId);
-        boolean result = tenantRepository.insert(tenant) != 0;
-        if(!result){
-            return false;
-        }
-        String tenantId = tenant.getId();
-        TenantUtils.execute(tenantId,()->{
-            //创建门面
-            portalService.insertInnerSysPortal(buildPortal(portalId));
-            //创建部门
-            orgService.insertSysOrg(buildOrg(orgId,source.getName()));
-            //创建角色
-            roleService.insertInnerSysRole(buildRole(roleId));
-            //创建租户用户
-            userService.insertSysUser(buildUser(userId,portalId,roleId,orgId,source.
-                    getUsername(),configManager.getCurrent().getDefaultPsw(),source.getName()));
-            //关联用户和门户
-            userPortalService.assignUserPortal(userId,Collections.singleton(portalId));
-        });
-        return result;
-    }
-
-    private List<SysUserPortalDTO> buildUserPortal(String userId, String portalId) {
-        ArrayList<SysUserPortalDTO> result = new ArrayList<>();
-        SysUserPortalDTO userPortalDTO = new SysUserPortalDTO();
-        userPortalDTO.setIsDefault(true);
-        userPortalDTO.setUserId(userId);
-        userPortalDTO.setPortalId(portalId);
-        result.add(userPortalDTO);
-        return result;
-    }
-
-    @Override
-    public int removeSysTenantByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
-        }
-        String tenantId = TenantContextHolder.getTenantId();
-        List<SysTenantPO> tenants = tenantRepository.selectBatchIds(ids);
-        for (SysTenantPO tenant : tenants) {
-            if (StrUtil.equals(tenant.getType(), CreateEnum.sys.name())) {
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统租户进行操作");
-            }
-            if(StrUtil.equals(tenantId,tenant.getId())){
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法删除自身的租户信息");
-            }
-        }
-        return tenantRepository.deleteBatchIds(ids);
-    }
-
-    @Override
-    public Set<SysMenuDTO> getTenantMenus(String tenantId) {
-        SysTenantPO tenant = tenantRepository.selectById(tenantId);
-        return  tenantPackageMenuService.findMenuIdByPackageId(tenant.getPackageId());
-    }
-
-    private void validateSource(SysTenantAddDTO source){
-        SysTenantPO sysTenantPO = tenantRepository.selectOne(new LambdaQueryWrapper<SysTenantPO>()
-                .eq(SysTenantPO::getName, source.getName()));
-        if(ObjectUtil.isNotNull(sysTenantPO)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"租户名称不能重复");
-        }
-    }
-
-    private void validateSource(SysTenantCommonDTO source){
-        SysTenantPO sysTenantPO = tenantRepository.selectOne(new LambdaQueryWrapper<SysTenantPO>()
-                .ne(StrUtil.isNotEmpty(source.getId()),SysTenantPO::getId,source.getId())
-                .eq(SysTenantPO::getName, source.getName()));
-        if(ObjectUtil.isNotNull(sysTenantPO)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"租户名称不能重复");
-        }
-    }
-    private SysPortalDTO buildPortal(String portalId){
-        SysPortalDTO org = new SysPortalDTO();
-        org.setId(portalId);
-        org.setCode("admin");
-        org.setName("系统管理员工作台");
-        org.setType(CreateEnum.sys.name());
-        return org;
-    }
-
-    private SysOrgDTO buildOrg(String orgId,String tenantName){
-        SysOrgDTO org = new SysOrgDTO();
-        org.setId(orgId);
-        org.setParentId("0");
-        org.setSort(1);
-        org.setName(tenantName);
-        org.setDisable(false);
-        return org;
-    }
-
-    private SysRoleDTO buildRole(String roleId){
-        SysRoleDTO role = new SysRoleDTO();
-        role.setId(roleId);
-        role.setDataScope("1");
-        role.setCode("admin");
-        role.setName("超级管理员");
-        role.setRemark("系统角色");
-        role.setDisable(false);
-        role.setSort(1);
-        role.setType(CreateEnum.sys.name());
-        return role;
-    }
-
-    private SysUserDTO buildUser(String userId,String portalId,String roleId,String orgId,String username,String password,String tenantName){
-        SysUserDTO user = new SysUserDTO();
-        user.setId(userId);
-        user.setOrgId(orgId);
-        user.setPortalIds(Collections.singleton(portalId));
-        user.setUsername(username);
-        user.setPassword(password);
-        user.setNickname(tenantName);
-        user.setRoleIds(Collections.singleton(roleId));
-        user.setStatus(UserStatusEnum.normal.getValue());
-
-        return user;
-    }
-}
+//package cn.tr.module.sys.tenant.service.impl;
+//
+//
+//import cn.hutool.core.collection.CollectionUtil;
+//import cn.hutool.core.util.ObjectUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.tr.core.annotation.TenantIgnore;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.module.sys.config.SysConfigManager;
+//import cn.tr.module.sys.tenant.mapper.SysTenantMapper;
+//import cn.tr.module.sys.tenant.dto.SysTenantAddDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantCommonDTO;
+//import cn.tr.module.sys.tenant.dto.SysTenantQueryDTO;
+//import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
+//import cn.tr.module.sys.user.dto.*;
+//import cn.tr.core.enums.CreateEnum;
+//import cn.tr.module.sys.user.enums.UserStatusEnum;
+//import cn.tr.module.sys.tenant.po.SysTenantPO;
+//import cn.tr.module.sys.tenant.repository.SysTenantRepository;
+//import cn.tr.module.sys.user.service.*;
+//import cn.tr.module.sys.tenant.service.ISysTenantService;
+//import cn.tr.plugin.biz.tenant.context.TenantContextHolder;
+//import cn.tr.plugin.biz.tenant.utils.TenantUtils;
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Lazy;
+//import org.springframework.stereotype.Service;
+//import org.springframework.transaction.annotation.Transactional;
+//
+//import java.util.*;
+//
+///**
+// * @ClassName : SysTenantServiceImpl
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月05日
+// */
+//@Service
+//public class SysTenantServiceImpl implements ISysTenantService {
+//    @Autowired
+//    private SysTenantRepository tenantRepository;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysPortalService portalService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysUserService userService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysUserPortalService userPortalService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysOrgService orgService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysRoleService roleService;
+//
+//    @Autowired
+//    @Lazy
+//    private SysConfigManager configManager;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysTenantPackageMenuService tenantPackageMenuService;
+//
+//    @Override
+//    @TenantIgnore
+//    public List<SysTenantCommonDTO> selectSysTenantList(SysTenantQueryDTO query) {
+//        return tenantRepository.stdSelectList(query);
+//    }
+//
+//    @Override
+//    @TenantIgnore
+//    public SysTenantCommonDTO selectSysTenantById(String id) {
+//        return tenantRepository.stdSelectById(id);
+//    }
+//
+//    @Override
+//    public boolean updateSysTenantById(SysTenantCommonDTO source) {
+//        validateSource(source);
+//        return tenantRepository.updateById(SysTenantMapper.INSTANCE.toPO(source))!=0;
+//    }
+//
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public boolean insertSysTenant(SysTenantAddDTO source) {
+//        validateSource(source);
+//        String orgId= IdWorker.getIdStr();
+//        String userId= IdWorker.getIdStr();
+//        String roleId= IdWorker.getIdStr();
+//        String portalId= IdWorker.getIdStr();
+//        SysTenantPO tenant = SysTenantMapper.INSTANCE.toPO(source);
+//        tenant.setTenantUserId(userId);
+//        boolean result = tenantRepository.insert(tenant) != 0;
+//        if(!result){
+//            return false;
+//        }
+//        String tenantId = tenant.getId();
+//        TenantUtils.execute(tenantId,()->{
+//            //创建门面
+//            portalService.insertInnerSysPortal(buildPortal(portalId));
+//            //创建部门
+//            orgService.insertSysOrg(buildOrg(orgId,source.getName()));
+//            //创建角色
+//            roleService.insertInnerSysRole(buildRole(roleId));
+//            //创建租户用户
+//            userService.insertSysUser(buildUser(userId,portalId,roleId,orgId,source.
+//                    getUsername(),configManager.getCurrent().getDefaultPsw(),source.getName()));
+//            //关联用户和门户
+//            userPortalService.assignUserPortal(userId,Collections.singleton(portalId));
+//        });
+//        return result;
+//    }
+//
+//    private List<SysUserPortalDTO> buildUserPortal(String userId, String portalId) {
+//        ArrayList<SysUserPortalDTO> result = new ArrayList<>();
+//        SysUserPortalDTO userPortalDTO = new SysUserPortalDTO();
+//        userPortalDTO.setIsDefault(true);
+//        userPortalDTO.setUserId(userId);
+//        userPortalDTO.setPortalId(portalId);
+//        result.add(userPortalDTO);
+//        return result;
+//    }
+//
+//    @Override
+//    public int removeSysTenantByIds(Collection<String> ids) {
+//        if(CollectionUtil.isEmpty(ids)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+//        }
+//        String tenantId = TenantContextHolder.getTenantId();
+//        List<SysTenantPO> tenants = tenantRepository.selectBatchIds(ids);
+//        for (SysTenantPO tenant : tenants) {
+//            if (StrUtil.equals(tenant.getType(), CreateEnum.sys.name())) {
+//                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统租户进行操作");
+//            }
+//            if(StrUtil.equals(tenantId,tenant.getId())){
+//                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法删除自身的租户信息");
+//            }
+//        }
+//        return tenantRepository.deleteBatchIds(ids);
+//    }
+//
+//    @Override
+//    public Set<SysMenuDTO> getTenantMenus(String tenantId) {
+//        SysTenantPO tenant = tenantRepository.selectById(tenantId);
+//        return  tenantPackageMenuService.findMenuIdByPackageId(tenant.getPackageId());
+//    }
+//
+//    private void validateSource(SysTenantAddDTO source){
+//        SysTenantPO sysTenantPO = tenantRepository.selectOne(new LambdaQueryWrapper<SysTenantPO>()
+//                .eq(SysTenantPO::getName, source.getName()));
+//        if(ObjectUtil.isNotNull(sysTenantPO)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"租户名称不能重复");
+//        }
+//    }
+//
+//    private void validateSource(SysTenantCommonDTO source){
+//        SysTenantPO sysTenantPO = tenantRepository.selectOne(new LambdaQueryWrapper<SysTenantPO>()
+//                .ne(StrUtil.isNotEmpty(source.getId()),SysTenantPO::getId,source.getId())
+//                .eq(SysTenantPO::getName, source.getName()));
+//        if(ObjectUtil.isNotNull(sysTenantPO)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"租户名称不能重复");
+//        }
+//    }
+//    private SysPortalDTO buildPortal(String portalId){
+//        SysPortalDTO org = new SysPortalDTO();
+//        org.setId(portalId);
+//        org.setCode("admin");
+//        org.setName("系统管理员工作台");
+//        org.setType(CreateEnum.sys.name());
+//        return org;
+//    }
+//
+//    private SysOrgDTO buildOrg(String orgId,String tenantName){
+//        SysOrgDTO org = new SysOrgDTO();
+//        org.setId(orgId);
+//        org.setParentId("0");
+//        org.setSort(1);
+//        org.setName(tenantName);
+//        org.setDisable(false);
+//        return org;
+//    }
+//
+//    private SysRoleDTO buildRole(String roleId){
+//        SysRoleDTO role = new SysRoleDTO();
+//        role.setId(roleId);
+//        role.setDataScope("1");
+//        role.setCode("admin");
+//        role.setName("超级管理员");
+//        role.setRemark("系统角色");
+//        role.setDisable(false);
+//        role.setSort(1);
+//        role.setType(CreateEnum.sys.name());
+//        return role;
+//    }
+//
+//    private SysUserDTO buildUser(String userId,String portalId,String roleId,String orgId,String username,String password,String tenantName){
+//        SysUserDTO user = new SysUserDTO();
+//        user.setId(userId);
+//        user.setOrgId(orgId);
+//        user.setPortalIds(Collections.singleton(portalId));
+//        user.setUsername(username);
+//        user.setPassword(password);
+//        user.setNickname(tenantName);
+//        user.setRoleIds(Collections.singleton(roleId));
+//        user.setStatus(UserStatusEnum.normal.getValue());
+//
+//        return user;
+//    }
+//}

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

@@ -0,0 +1,114 @@
+package cn.tr.module.sys.user.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.tr.core.pojo.CommonResult;
+import cn.tr.module.sys.user.dto.SysDeptAddDTO;
+import cn.tr.module.sys.user.dto.SysDeptEditDTO;
+import cn.tr.module.sys.user.dto.SysDeptQueryDTO;
+import cn.tr.module.sys.user.service.ISysDeptService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import cn.tr.module.common.annotation.Log;
+import jakarta.annotation.Resource;
+
+/**
+ * <p>
+ * 部门表 前端控制器
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Tag(name = "部门管理")
+@RestController
+@RequestMapping("/sys/dept")
+public class SysDeptController {
+
+    @Resource
+    private ISysDeptService sysDeptService;
+
+    /**
+     * 分页查询
+     */
+    @Operation(summary = "部门管理分页查询")
+    @GetMapping("/page")
+    @SaCheckPermission("system:sysDept:page")
+    public CommonResult page(Page reqPage, SysDeptQueryDTO req) {
+        return CommonResult.success(sysDeptService.page(reqPage, req));
+    }
+
+    /**
+     * 新增
+     */
+    @Operation(summary = "部门管理新增")
+    @PostMapping("/add")
+    @SaCheckPermission("system:sysDept:add")
+    public CommonResult add(@Validated @RequestBody SysDeptAddDTO req) {
+        sysDeptService.add(req);
+        return CommonResult.success();
+    }
+
+    /**
+     * 修改
+     */
+    @Operation(summary = "部门管理修改")
+    @PostMapping("/edit")
+    @SaCheckPermission("system:sysDept:edit")
+    public CommonResult edit(@Validated @RequestBody SysDeptEditDTO req) {
+        sysDeptService.edit(req);
+        return CommonResult.success();
+    }
+
+    /**
+     * 删除
+     */
+    @Operation(summary = "部门管理删除")
+    @PostMapping("/remove")
+    @SaCheckPermission("system:sysDept:remove")
+    public CommonResult remove(@RequestParam String ids) {
+        sysDeptService.remove(ids);
+        return CommonResult.success();
+    }
+
+    /**
+     * 查看
+     */
+    @Operation(summary = "部门管理查看")
+    @GetMapping("/view")
+    @SaCheckPermission("system:sysDept:view")
+    public CommonResult view(@RequestParam String id) {
+        return CommonResult.success(sysDeptService.view(id));
+    }
+
+    /**
+     * 查询部门树
+     */
+    @Operation(summary = "查询部门树")
+    @GetMapping("/listDeptTree")
+    public CommonResult listDeptTree() {
+        return CommonResult.success(sysDeptService.listDeptTree());
+    }
+
+    /**
+     * 查询下拉部门树,排除当前节点以及子节点
+     */
+    @Operation(summary = "查询下拉部门树,排除当前节点以及子节点")
+    @GetMapping("/selectDeptTreeAndExcludeNode")
+    public CommonResult selectTreeAndExcludeNode(@RequestParam(required = false) String nodeId) {
+        return CommonResult.success(sysDeptService.selectDeptTreeAndExcludeNode(nodeId));
+    }
+
+    /**
+     * 查询下拉部门树
+     */
+    @Operation(summary = "查询下拉部门树")
+    @GetMapping("/selectDeptTree")
+    public CommonResult selectTree() {
+        return CommonResult.success(sysDeptService.selectDeptTree());
+    }
+
+}
+

+ 85 - 86
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysMenuController.java

@@ -2,115 +2,114 @@ 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.tenant.service.ISysTenantService;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
+import cn.tr.module.sys.user.dto.SysMenuAddDTO;
+import cn.tr.module.sys.user.dto.SysMenuEditDTO;
 import cn.tr.module.sys.user.dto.SysMenuQueryDTO;
 import cn.tr.module.sys.user.service.ISysMenuService;
-import cn.tr.core.context.BaseController;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
 import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-
-import java.util.Collection;
-import java.util.*;
-import java.util.stream.Collectors;
+import cn.tr.module.common.annotation.Log;
+import jakarta.annotation.Resource;
 
 /**
- * @ClassName : SysMenuController
- * @Description :
- * @Author : LF
- * @Date: 2023年03月24日
+ * <p>
+ * 菜单表  前端控制器
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-19
  */
+@Tag(name = "目录管理")
 @RestController
 @RequestMapping("/sys/menu")
-@Tag(name = "菜单")
-public class SysMenuController extends BaseController {
-    @Autowired
-    private ISysMenuService menuService;
-    @Autowired
-    private ISysTenantService tenantService;
-    @Value("${tr.tenant.enable}")
-    private Boolean tenantEnable;
+public class SysMenuController {
 
-    @PostMapping("/query/tree")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "菜单树", description = "权限: 无")
-    public CommonResult<List<SysMenuDTO>> selectTree(@RequestBody SysMenuQueryDTO query){
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            query.setTenantMenuIds(tenantService.currentTenantMenus()
-                    .stream()
-                    .map(SysMenuDTO::getId)
-                    .collect(Collectors.toSet()));
-        }
-        return CommonResult.success(menuService.selectSysMenuTree(query));
-    }
+    @Resource
+    private ISysMenuService sysMenuService;
 
-    @PostMapping("/query/page")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询菜单", description = "权限: 无")
-    public TableDataInfo<SysMenuDTO> selectPage(@RequestBody SysMenuQueryDTO query){
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            query.setTenantMenuIds(tenantService.currentTenantMenus()
-                    .stream()
-                    .map(SysMenuDTO::getId)
-                    .collect(Collectors.toSet()));
-        }
-        startPage();
-        return getDataTable(menuService.selectSysMenuList(query));
+    /**
+     * 分页查询
+     */
+    @Operation(summary = "菜单管理分页查询")
+    @GetMapping("/page")
+    @SaCheckPermission("system:sysMenu:page")
+    public CommonResult page(Page reqPage, SysMenuQueryDTO req) {
+        return CommonResult.success(sysMenuService.page(reqPage, req));
     }
 
-    @GetMapping("/detail/{id}")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据id查询菜单", description = "权限: sys:menu:query")
-    @Parameter(name = "id", description = "菜单ID", required = true)
-    @SaCheckPermission("sys:menu:query")
-    public CommonResult<SysMenuDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(menuService.selectSysMenuById(id));
+    /**
+     * 新增
+     */
+    @Operation(summary = "菜单管理新增")
+    @PostMapping("/add")
+    @SaCheckPermission("system:sysMenu:add")
+    public CommonResult add(@Validated @RequestBody SysMenuAddDTO req) {
+        sysMenuService.add(req);
+        return CommonResult.success();
     }
 
+    /**
+     * 修改
+     */
+    @Operation(summary = "菜单管理修改")
     @PostMapping("/edit")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:menu:edit")
-    @Operation(summary = "根据id更新菜单", description = "权限: sys:menu:edit")
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysMenuDTO source){
-        return CommonResult.success(menuService.updateSysMenuById(source));
+    @SaCheckPermission("system:sysMenu:edit")
+    public CommonResult edit(@Validated @RequestBody SysMenuEditDTO req) {
+        sysMenuService.edit(req);
+        return CommonResult.success();
     }
 
-    @PostMapping("/add")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:menu:add")
-    @Operation(summary = "新增菜单", description = "权限: sys:menu:add")
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysMenuDTO source){
-        return CommonResult.success(menuService.insertSysMenu(source));
+    /**
+     * 删除
+     */
+    @Operation(summary = "菜单管理删除")
+    @PostMapping("/remove")
+    @SaCheckPermission("system:sysMenu:remove")
+    public CommonResult remove(@RequestParam String ids) {
+        sysMenuService.remove(ids);
+        return CommonResult.success();
+    }
+
+    /**
+     * 查看
+     */
+    @Operation(summary = "菜单管理查看")
+    @GetMapping("/view")
+    @SaCheckPermission("system:sysMenu:view")
+    public CommonResult view(@RequestParam String id) {
+        return CommonResult.success(sysMenuService.view(id));
     }
 
-    @PostMapping("/deleteByIds")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "删除菜单", description = "权限: sys:menu:remove")
-    @SaCheckPermission("sys:menu:remove")
-    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
-        return CommonResult.success(menuService.deleteSysMenuByIds(ids));
+    /**
+     * 查询菜单树
+     */
+    @Operation(summary = "查询菜单树")
+    @GetMapping("/listMenuTree")
+    public CommonResult listMenuTree() {
+        return CommonResult.success(sysMenuService.listMenuTree());
     }
 
+    /**
+     * 查询下拉菜单树,排除当前节点以及子节点
+     */
+    @Operation(summary = "询下拉菜单树,排除当前节点以及子节点")
+    @GetMapping("/selectMenuTreeAndExcludeNode")
+    public CommonResult selectMenuTreeAndExcludeNode(@RequestParam(required = false) String nodeId) {
+        return CommonResult.success(sysMenuService.selectMenuTreeAndExcludeNode(nodeId));
+    }
 
-    @PostMapping("/query/list")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询菜单(不分页)", description = "权限: 无")
-    public CommonResult<List<SysMenuDTO>> selectList(@RequestBody SysMenuQueryDTO query){
-        if (Boolean.TRUE.equals(tenantEnable)) {
-            query.setTenantMenuIds(tenantService.currentTenantMenus()
-                    .stream()
-                    .map(SysMenuDTO::getId)
-                    .collect(Collectors.toSet()));
-        }
-        return CommonResult.success(menuService.selectSysMenuList(query));
+    /**
+     * 查询下拉菜单树
+     */
+    @Operation(summary = "查询下拉菜单树")
+    @GetMapping("/selectMenuTree")
+    public CommonResult selectMenuTree() {
+        return CommonResult.success(sysMenuService.selectMenuTree());
     }
+
 }
+

+ 98 - 98
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysOrgController.java

@@ -1,98 +1,98 @@
-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.SysOrgDTO;
-import cn.tr.module.sys.user.dto.SysOrgQueryDTO;
-import cn.tr.module.sys.user.dto.SysOrgTreeDTO;
-import cn.tr.module.sys.user.service.ISysOrgService;
-import cn.tr.core.context.BaseController;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.*;
-
-/**
- * @ClassName : SysOrgController
- * @Description :
- * @Author : LF
- * @Date: 2023年03月24日
- */
-@RestController
-@RequestMapping("/sys/org")
-@Tag(name = "组织")
-@AllArgsConstructor
-public class SysOrgController extends BaseController {
-    private final ISysOrgService orgService;
-
-    @PostMapping("/tree")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "组织树", description = "权限: 无")
-    public CommonResult<List<SysOrgTreeDTO>> selectTree(){
-        return CommonResult.success(orgService.selectSysOrgTree());
-    }
-
-    @PostMapping("/query/page")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询组织(分页)", description = "权限: 无")
-    public TableDataInfo<SysOrgDTO> selectPage(@RequestBody SysOrgQueryDTO query){
-        startPage();
-        return getDataTable(orgService.selectSysOrgList(query));
-    }
-
-    @PostMapping("/query/list")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询组织(不分页)", description = "权限: 无")
-    public CommonResult<List<SysOrgDTO>> selectList(@RequestBody SysOrgQueryDTO query){
-        query.setDisable(false);
-        return CommonResult.success(orgService.selectSysOrgList(query));
-    }
-
-    @GetMapping("/detail/{id}")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据id查询组织", description = "权限: sys:org:query")
-    @Parameter(name = "id", description = "组织ID", required = true)
-    @SaCheckPermission("sys:org:query")
-    public CommonResult<SysOrgDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(orgService.selectSysOrgById(id));
-    }
-
-    @PostMapping("/edit")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:org:edit")
-    @Operation(summary = "根据id更新组织", description = "权限: sys:org:edit")
-    @OperateLog
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysOrgDTO source){
-        return CommonResult.success(orgService.updateSysOrgById(source));
-    }
-
-    @PostMapping("/add")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:org:add")
-    @Operation(summary = "新增组织", description = "权限: sys:org:add")
-    @OperateLog
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysOrgDTO source){
-        return CommonResult.success(orgService.insertSysOrg(source));
-    }
-
-    @PostMapping("/deleteByIds")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "删除组织", description = "权限: sys:org:remove")
-    @SaCheckPermission("sys:org:remove")
-    @OperateLog
-    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
-        return CommonResult.success(orgService.deleteSysOrgByIds(ids));
-    }
-
-    //todo 导出
-
-}
+//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.SysOrgDTO;
+//import cn.tr.module.sys.user.dto.SysOrgQueryDTO;
+//import cn.tr.module.sys.user.dto.SysOrgTreeDTO;
+//import cn.tr.module.sys.user.service.ISysOrgService;
+//import cn.tr.core.context.BaseController;
+//import cn.tr.module.api.sys.log.annotation.OperateLog;
+//import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//import lombok.AllArgsConstructor;
+//import org.springframework.validation.annotation.Validated;
+//import org.springframework.web.bind.annotation.*;
+//
+//import java.util.*;
+//
+///**
+// * @ClassName : SysOrgController
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月24日
+// */
+//@RestController
+//@RequestMapping("/sys/org")
+//@Tag(name = "组织")
+//@AllArgsConstructor
+//public class SysOrgController extends BaseController {
+//    private final ISysOrgService orgService;
+//
+//    @PostMapping("/tree")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "组织树", description = "权限: 无")
+//    public CommonResult<List<SysOrgTreeDTO>> selectTree(){
+//        return CommonResult.success(orgService.selectSysOrgTree());
+//    }
+//
+//    @PostMapping("/query/page")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "根据条件查询组织(分页)", description = "权限: 无")
+//    public TableDataInfo<SysOrgDTO> selectPage(@RequestBody SysOrgQueryDTO query){
+//        startPage();
+//        return getDataTable(orgService.selectSysOrgList(query));
+//    }
+//
+//    @PostMapping("/query/list")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "根据条件查询组织(不分页)", description = "权限: 无")
+//    public CommonResult<List<SysOrgDTO>> selectList(@RequestBody SysOrgQueryDTO query){
+//        query.setDisable(false);
+//        return CommonResult.success(orgService.selectSysOrgList(query));
+//    }
+//
+//    @GetMapping("/detail/{id}")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "根据id查询组织", description = "权限: sys:org:query")
+//    @Parameter(name = "id", description = "组织ID", required = true)
+//    @SaCheckPermission("sys:org:query")
+//    public CommonResult<SysOrgDTO> findById(@PathVariable("id") String id){
+//        return CommonResult.success(orgService.selectSysOrgById(id));
+//    }
+//
+//    @PostMapping("/edit")
+//    @ApiOperationSupport(author = "lf")
+//    @SaCheckPermission("sys:org:edit")
+//    @Operation(summary = "根据id更新组织", description = "权限: sys:org:edit")
+//    @OperateLog
+//    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysOrgDTO source){
+//        return CommonResult.success(orgService.updateSysOrgById(source));
+//    }
+//
+//    @PostMapping("/add")
+//    @ApiOperationSupport(author = "lf")
+//    @SaCheckPermission("sys:org:add")
+//    @Operation(summary = "新增组织", description = "权限: sys:org:add")
+//    @OperateLog
+//    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysOrgDTO source){
+//        return CommonResult.success(orgService.insertSysOrg(source));
+//    }
+//
+//    @PostMapping("/deleteByIds")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "删除组织", description = "权限: sys:org:remove")
+//    @SaCheckPermission("sys:org:remove")
+//    @OperateLog
+//    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
+//        return CommonResult.success(orgService.deleteSysOrgByIds(ids));
+//    }
+//
+//    //todo 导出
+//
+//}

+ 101 - 101
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPortalController.java

@@ -1,101 +1,101 @@
-package cn.tr.module.sys.user.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.tr.core.enums.CreateEnum;
-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.*;
-import cn.tr.module.sys.user.service.ISysPortalMenuService;
-import cn.tr.module.sys.user.service.ISysPortalService;
-import cn.tr.core.context.BaseController;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.*;
-
-/**
- * @ClassName : SysPortalController
- * @Description :
- * @Author : LF
- * @Date: 2023年03月24日
- */
-@RestController
-@RequestMapping("/sys/portal")
-@Tag(name = "门户")
-@AllArgsConstructor
-public class SysPortalController extends BaseController {
-    private final ISysPortalService portalService;
-    private final ISysPortalMenuService portalMenuService;
-
-    @GetMapping("/menu/list/{portalId}")
-    @Operation(summary = "查询门户下的权限信息", description = "权限: 无")
-    public CommonResult<List<SysMenuDTO>> listMenu(@Parameter(description = "门户ID") @PathVariable("portalId") String portalId) {
-        return CommonResult.success(portalMenuService.findAllMenusByPortalId(portalId));
-    }
-
-    @PostMapping("/assign")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "为门户分配菜单", description = "权限: sys:portal:assign")
-    @SaCheckPermission("sys:portal:assign")
-    public CommonResult<Boolean> selectList(@RequestBody@Validated SysPortalMenuAssignDTO source){
-        portalMenuService.assignPortalMenu(source.getPortalId(),source.getMenuIds());
-        return CommonResult.success(true);
-    }
-
-    @PostMapping("/query/page")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询门户", description = "权限: 无")
-    public TableDataInfo<SysPortalDTO> selectList(@RequestBody SysPortalQueryDTO query){
-        startPage();
-        return getDataTable(portalService.selectSysPortalList(query));
-    }
-
-    @GetMapping("/detail/{id}")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据id查询门户", description = "权限: sys:portal:query")
-    @Parameter(name = "id", description = "门户ID", required = true)
-    @SaCheckPermission("sys:portal:query")
-    @OperateLog
-    public CommonResult<SysPortalDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(portalService.selectSysPortalById(id));
-    }
-
-    @PostMapping("/edit")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:portal:edit")
-    @Operation(summary = "根据id更新门户", description = "权限: sys:portal:edit")
-    @OperateLog
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysPortalDTO source){
-        return CommonResult.success(portalService.updateSysPortalById(source));
-    }
-
-    @PostMapping("/add")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:portal:add")
-    @Operation(summary = "新增门户", description = "权限: sys:portal:add")
-    @OperateLog
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysPortalDTO source){
-        source.setType(CreateEnum.custom.name());
-        return CommonResult.success(portalService.insertSysPortal(source));
-    }
-
-    @PostMapping("/removeByIds")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "删除门户", description = "权限: sys:portal:remove")
-    @SaCheckPermission("sys:portal:remove")
-    @OperateLog
-    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
-        return CommonResult.success(portalService.deleteSysPortalByIds(ids));
-    }
-
-    //todo 导出
-
-}
+//package cn.tr.module.sys.user.controller;
+//
+//import cn.dev33.satoken.annotation.SaCheckPermission;
+//import cn.tr.core.enums.CreateEnum;
+//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.*;
+//import cn.tr.module.sys.user.service.ISysPortalMenuService;
+//import cn.tr.module.sys.user.service.ISysPortalService;
+//import cn.tr.core.context.BaseController;
+//import cn.tr.module.api.sys.log.annotation.OperateLog;
+//import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+//import io.swagger.v3.oas.annotations.tags.Tag;
+//import io.swagger.v3.oas.annotations.Operation;
+//import io.swagger.v3.oas.annotations.Parameter;
+//import lombok.AllArgsConstructor;
+//import org.springframework.validation.annotation.Validated;
+//import org.springframework.web.bind.annotation.*;
+//
+//import java.util.*;
+//
+///**
+// * @ClassName : SysPortalController
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月24日
+// */
+//@RestController
+//@RequestMapping("/sys/portal")
+//@Tag(name = "门户")
+//@AllArgsConstructor
+//public class SysPortalController extends BaseController {
+//    private final ISysPortalService portalService;
+//    private final ISysPortalMenuService portalMenuService;
+//
+//    @GetMapping("/menu/list/{portalId}")
+//    @Operation(summary = "查询门户下的权限信息", description = "权限: 无")
+//    public CommonResult<List<SysMenuDTO>> listMenu(@Parameter(description = "门户ID") @PathVariable("portalId") String portalId) {
+//        return CommonResult.success(portalMenuService.findAllMenusByPortalId(portalId));
+//    }
+//
+//    @PostMapping("/assign")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "为门户分配菜单", description = "权限: sys:portal:assign")
+//    @SaCheckPermission("sys:portal:assign")
+//    public CommonResult<Boolean> selectList(@RequestBody@Validated SysPortalMenuAssignDTO source){
+//        portalMenuService.assignPortalMenu(source.getPortalId(),source.getMenuIds());
+//        return CommonResult.success(true);
+//    }
+//
+//    @PostMapping("/query/page")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "根据条件查询门户", description = "权限: 无")
+//    public TableDataInfo<SysPortalDTO> selectList(@RequestBody SysPortalQueryDTO query){
+//        startPage();
+//        return getDataTable(portalService.selectSysPortalList(query));
+//    }
+//
+//    @GetMapping("/detail/{id}")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "根据id查询门户", description = "权限: sys:portal:query")
+//    @Parameter(name = "id", description = "门户ID", required = true)
+//    @SaCheckPermission("sys:portal:query")
+//    @OperateLog
+//    public CommonResult<SysPortalDTO> findById(@PathVariable("id") String id){
+//        return CommonResult.success(portalService.selectSysPortalById(id));
+//    }
+//
+//    @PostMapping("/edit")
+//    @ApiOperationSupport(author = "lf")
+//    @SaCheckPermission("sys:portal:edit")
+//    @Operation(summary = "根据id更新门户", description = "权限: sys:portal:edit")
+//    @OperateLog
+//    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysPortalDTO source){
+//        return CommonResult.success(portalService.updateSysPortalById(source));
+//    }
+//
+//    @PostMapping("/add")
+//    @ApiOperationSupport(author = "lf")
+//    @SaCheckPermission("sys:portal:add")
+//    @Operation(summary = "新增门户", description = "权限: sys:portal:add")
+//    @OperateLog
+//    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysPortalDTO source){
+//        source.setType(CreateEnum.custom.name());
+//        return CommonResult.success(portalService.insertSysPortal(source));
+//    }
+//
+//    @PostMapping("/removeByIds")
+//    @ApiOperationSupport(author = "lf")
+//    @Operation(summary = "删除门户", description = "权限: sys:portal:remove")
+//    @SaCheckPermission("sys:portal:remove")
+//    @OperateLog
+//    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
+//        return CommonResult.success(portalService.deleteSysPortalByIds(ids));
+//    }
+//
+//    //todo 导出
+//
+//}

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

@@ -1,82 +0,0 @@
-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.SysPositionDTO;
-import cn.tr.module.sys.user.dto.SysPositionQueryDTO;
-import cn.tr.module.sys.user.service.ISysPositionService;
-import cn.tr.core.context.BaseController;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Collection;
-
-/**
- * @ClassName : SysPositionController
- * @Description :
- * @Author : LF
- * @Date: 2023年03月24日
- */
-@RestController
-@RequestMapping("/sys/pos")
-@Tag(name = "岗位")
-@AllArgsConstructor
-public class SysPositionController extends BaseController {
-    private final ISysPositionService positionService;
-
-    @PostMapping("/query/page")
-    @ApiOperationSupport(author = "lf",order = 1)
-    @Operation(summary = "根据条件查询岗位", description = "权限:无")
-    public TableDataInfo<SysPositionDTO> selectList(@RequestBody SysPositionQueryDTO query){
-        startPage();
-        return getDataTable(positionService.selectSysPositionList(query));
-    }
-
-    @GetMapping("/detail/{id}")
-    @ApiOperationSupport(author = "lf",order = 2)
-    @Operation(summary = "根据id查询岗位", description = "权限: sys:pos:query")
-    @Parameter(name = "id", description = "岗位ID", required = true)
-    @SaCheckPermission("sys:pos:query")
-    public CommonResult<SysPositionDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(positionService.selectSysPositionById(id));
-    }
-
-    @PostMapping("/edit")
-    @ApiOperationSupport(author = "lf",order = 3)
-    @SaCheckPermission("sys:pos:edit")
-    @Operation(summary = "根据id更新岗位", description = "权限: sys:pos:edit")
-    @OperateLog
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysPositionDTO source){
-        return CommonResult.success(positionService.updateSysPositionById(source));
-    }
-
-    @PostMapping("/add")
-    @ApiOperationSupport(author = "lf",order = 4)
-    @SaCheckPermission("sys:pos:add")
-    @Operation(summary = "新增岗位", description = "权限: sys:pos:add")
-    @OperateLog
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysPositionDTO source){
-        return CommonResult.success(positionService.insertSysPosition(source));
-    }
-
-    @PostMapping("/removeByIds")
-    @ApiOperationSupport(author = "lf",order = 5)
-    @Operation(summary = "删除岗位", description = "权限: sys:pos:remove")
-    @SaCheckPermission("sys:pos:remove")
-    @OperateLog
-    public CommonResult<Integer> removeByIds(@RequestBody Collection<String> ids){
-        return CommonResult.success(positionService.deleteSysPositionByIds(ids));
-    }
-
-    //todo 导出
-
-}

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

@@ -0,0 +1,119 @@
+package cn.tr.module.sys.user.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.tr.core.pojo.CommonResult;
+import cn.tr.module.common.utils.ExcelUtil;
+import cn.tr.module.sys.user.dto.SysPostAddDTO;
+import cn.tr.module.sys.user.dto.SysPostEditDTO;
+import cn.tr.module.sys.user.dto.SysPostQueryDTO;
+import cn.tr.module.sys.user.po.SysPostPO;
+import cn.tr.module.sys.user.service.ISysPostService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import cn.tr.module.common.annotation.Log;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.annotation.Resource;
+
+/**
+ * <p>
+ * 岗位表 前端控制器
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+@Tag(name = "岗位管理")
+@RestController
+@RequestMapping("/system/sysPost")
+public class SysPostController {
+
+    @Resource
+    private ISysPostService sysPostService;
+
+    /**
+     * 分页查询
+     */
+    @Operation(summary = "岗位管理分页查询")
+    @GetMapping("/page")
+    @SaCheckPermission("system:sysPost:page")
+    public CommonResult page(Page reqPage, SysPostQueryDTO req) {
+        return CommonResult.success(sysPostService.page(reqPage, req));
+    }
+
+    /**
+     * 新增
+     */
+    @Operation(summary = "岗位管理新增")
+    @PostMapping("/add")
+    @SaCheckPermission("system:sysPost:add")
+    public CommonResult add(@Validated @RequestBody SysPostAddDTO req) {
+        sysPostService.add(req);
+        return CommonResult.success();
+    }
+
+    /**
+     * 修改
+     */
+    @Operation(summary = "岗位管理修改")
+    @PostMapping("/edit")
+    @SaCheckPermission("system:sysPost:edit")
+    public CommonResult edit(@Validated @RequestBody SysPostEditDTO req) {
+        sysPostService.edit(req);
+        return CommonResult.success();
+    }
+
+    /**
+     * 删除
+     */
+    @Operation(summary = "岗位管理删除")
+    @PostMapping("/remove")
+    @SaCheckPermission("system:sysPost:remove")
+    public CommonResult remove(@RequestParam String ids) {
+        sysPostService.remove(ids);
+        return CommonResult.success();
+    }
+
+    /**
+     * 查看
+     */
+    @Operation(summary = "岗位管理查看")
+    @GetMapping("/view")
+    @SaCheckPermission("system:sysPost:view")
+    public CommonResult view(@RequestParam String id) {
+        return CommonResult.success(sysPostService.view(id));
+    }
+
+    /**
+     * 导出
+     */
+    @Operation(summary = "岗位管理导出")
+    @GetMapping("/export")
+    @SaCheckPermission("system:sysPost:export")
+    public CommonResult export(SysPostQueryDTO req) {
+        String filepath = ExcelUtil.export("岗位列表", SysPostPO.class, sysPostService.list(req));
+        return CommonResult.success(filepath);
+    }
+
+    /**
+     * 查询下拉框列表
+     */
+    @Operation(summary = "查询下拉框列表")
+    @GetMapping("/listOptions")
+    public CommonResult listOptions() {
+        return CommonResult.success(sysPostService.listOptions());
+    }
+
+    /**
+     * 下拉列表
+     */
+    @Operation(summary = "下拉列表")
+    @GetMapping("/selectOptions")
+    public CommonResult selectOptions() {
+        return CommonResult.success(sysPostService.selectOptions());
+    }
+
+}
+

+ 122 - 74
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysRoleController.java

@@ -2,100 +2,148 @@ 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.*;
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.module.sys.user.service.ISysRoleMenuService;
+import cn.tr.module.common.utils.ExcelUtil;
+import cn.tr.module.sys.user.dto.SysRoleAddDTO;
+import cn.tr.module.sys.user.dto.SysRoleAssignMenuDTO;
+import cn.tr.module.sys.user.dto.SysRoleEditDTO;
+import cn.tr.module.sys.user.dto.SysRoleQueryDTO;
+import cn.tr.module.sys.user.po.SysRolePO;
 import cn.tr.module.sys.user.service.ISysRoleService;
-import cn.tr.core.context.BaseController;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import cn.tr.module.common.annotation.Log;
 import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import lombok.AllArgsConstructor;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.Collection;
-import java.util.List;
+import jakarta.annotation.Resource;
 
 /**
- * @ClassName : SysRoleController
- * @Description :
- * @Author : LF
- * @Date: 2023年03月24日
+ * <p>
+ * 角色表 前端控制器
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
+@Tag(name = "角色管理")
 @RestController
 @RequestMapping("/sys/role")
-@Tag(name = "角色")
-@AllArgsConstructor
-public class SysRoleController extends BaseController {
-    private final ISysRoleService roleService;
-    private final ISysRoleMenuService roleMenuService;
-
-    @GetMapping("/menu/list/{roleId}")
-    @Operation(summary = "查询角色下的权限信息", description = "权限: 无")
-    public CommonResult<List<SysMenuDTO>> listMenu(@Parameter(description = "角色ID") @PathVariable("roleId") String roleId) {
-        return CommonResult.success(roleMenuService.findAllMenuByRoleId(roleId));
+public class SysRoleController {
+
+    @Resource
+    private ISysRoleService sysRoleService;
+
+    /**
+     * 分页查询
+     */
+    @Operation(summary = "角色管理分页查询")
+    @GetMapping("/page")
+    @SaCheckPermission("system:sysRole:page")
+    public CommonResult page(Page reqPage, SysRoleQueryDTO req) {
+        return CommonResult.success(sysRoleService.page(reqPage, req));
     }
 
-    @PostMapping("/query/page")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询角色", description = "权限: 无")
-    public TableDataInfo<SysRoleDTO> selectList(@RequestBody SysRoleQueryDTO query){
-        startPage();
-        return getDataTable(roleService.selectSysRoleList(query));
+    /**
+     * 新增
+     */
+    @Operation(summary = "角色管理新增")
+    @PostMapping("/add")
+    @SaCheckPermission("system:sysRole:add")
+    public CommonResult add(@Validated @RequestBody SysRoleAddDTO req) {
+        sysRoleService.add(req);
+        return CommonResult.success();
     }
 
-    @PostMapping("/assign")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "为角色分配权限", description = "权限: sys:role:assign")
-    @SaCheckPermission("sys:role:assign")
-    @OperateLog
-    public CommonResult<Boolean> selectList(@RequestBody@Validated SysRoleMenuAssignDTO source){
-        roleMenuService.assignRoleMenu(source.getRoleId(),source.getMenuIds());
-        return CommonResult.success(true);
+    /**
+     * 修改
+     */
+    @Operation(summary = "角色管理修改")
+    @PostMapping("/edit")
+    @SaCheckPermission("system:sysRole:edit")
+    public CommonResult edit(@Validated @RequestBody SysRoleEditDTO req) {
+        sysRoleService.edit(req);
+        return CommonResult.success();
     }
 
-    @GetMapping("/detail/{id}")
-    @ApiOperationSupport(author = "lf")
-    @OperateLog
-    @Operation(summary = "根据id查询角色", description = "权限: sys:role:query")
-    @Parameter(name = "id", description = "角色ID", required = true)
-    @SaCheckPermission("sys:role:query")
-    public CommonResult<SysRoleDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(roleService.selectSysRoleById(id));
+    /**
+     * 删除
+     */
+    @Operation(summary = "角色管理删除")
+    @PostMapping("/remove")
+    @SaCheckPermission("system:sysRole:remove")
+    public CommonResult remove(@RequestParam("ids") Long id) {
+        sysRoleService.remove(id);
+        return CommonResult.success();
     }
 
-    @PostMapping("/edit")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:role:edit")
-    @Operation(summary = "根据id更新角色", description = "权限: sys:role:edit")
-    @OperateLog
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysRoleDTO source){
-        source.setType(CreateEnum.custom.name());
-        return CommonResult.success(roleService.updateSysRoleById(source));
+    /**
+     * 查看
+     */
+    @Operation(summary = "角色管理查看")
+    @GetMapping("/view")
+    @SaCheckPermission("system:sysRole:view")
+    public CommonResult view(@RequestParam String id) {
+        return CommonResult.success(sysRoleService.view(id));
     }
 
-    @PostMapping("/add")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:role:add")
-    @OperateLog
-    @Operation(summary = "新增角色", description = "权限: sys:role:add")
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysRoleDTO source){
-        source.setType(CreateEnum.custom.name());
-        return CommonResult.success(roleService.insertSysRole(source));
+    /**
+     * 导出
+     */
+    @Operation(summary = "角色管理导出")
+    @GetMapping("/export")
+    @SaCheckPermission("system:sysRole:export")
+    public CommonResult export(SysRoleQueryDTO req) {
+        String filepath = ExcelUtil.export("角色列表", SysRolePO.class, sysRoleService.list(req));
+        return CommonResult.success(filepath);
+    }
+
+    /**
+     * 查询下拉框列表
+     */
+    @Operation(summary = "查询下拉框列表")
+    @GetMapping("/listOptions")
+    public CommonResult listOptions() {
+        return CommonResult.success(sysRoleService.listOptions());
+    }
+
+    /**
+     * 分配菜单
+     */
+    @Operation(summary = "角色管理分配菜单")
+    @PostMapping("/assignMenu")
+    @SaCheckPermission("system:sysRole:assignMenu")
+    public CommonResult assignMenu(@Validated @RequestBody SysRoleAssignMenuDTO req) {
+        sysRoleService.assignMenu(req);
+        return CommonResult.success();
+    }
+
+    /**
+     * 查询角色关联的菜单
+     */
+    @Operation(summary = "查询角色关联的菜单")
+    @GetMapping("/listRoleMenus")
+    public CommonResult listRoleMenus(@RequestParam String roleId) {
+        return CommonResult.success(sysRoleService.listRoleMenus(roleId));
     }
 
-    @PostMapping("/deleteByIds")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "删除角色", description = "权限: sys:role:remove")
-    @SaCheckPermission("sys:role:remove")
-    @OperateLog
-    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
-        return CommonResult.success(roleService.deleteSysRoleByIds(ids));
+    /**
+     * 查询角色关联的部门
+     */
+    @Operation(summary = "查询角色关联的部门")
+    @GetMapping("/listRoleDepts")
+    public CommonResult listRoleDepts(@RequestParam String roleId) {
+        return CommonResult.success(sysRoleService.listRoleDepts(roleId));
     }
-}
+
+    /**
+     * 下拉列表
+     */
+    @Operation(summary = "下拉列表")
+    @GetMapping("/selectOptions")
+    public CommonResult selectOptions() {
+        return CommonResult.success(sysRoleService.selectOptions());
+    }
+
+}
+

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

@@ -2,110 +2,117 @@ 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.*;
-import cn.tr.module.sys.user.enums.UserStatusEnum;
-import cn.tr.module.sys.user.mapper.SysUserMapper;
-import cn.tr.module.sys.user.service.ISysUserService;
-import cn.tr.core.context.BaseController;
-import cn.tr.module.api.sys.log.annotation.OperateLog;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.v3.oas.annotations.tags.Tag;
+import cn.tr.module.common.utils.ExcelUtil;
+import cn.tr.module.sys.exception.CustomException;
+import cn.tr.module.sys.oauth2.utils.SecurityUtil;
+import cn.tr.module.sys.user.dto.SysUserAddDTO;
+import cn.tr.module.sys.user.dto.SysUserEditDTO;
+import cn.tr.module.sys.user.dto.SysUserQueryDTO;
+import cn.tr.module.sys.user.dto.SysUserResetPwdDTO;
+import cn.tr.module.sys.user.po.SysUserPO;
+import cn.tr.module.sys.user.service.impl.ISysUserService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-import lombok.AllArgsConstructor;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import cn.tr.module.common.annotation.Log;
 
-import java.util.*;
+import jakarta.annotation.Resource;
 
 /**
- * @ClassName : SysUserController
- * @Description :
- * @Author : LF
- * @Date: 2023年03月24日
+ * <p>
+ * 用户表 前端控制器
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
+@Tag(name = "用户管理")
 @RestController
 @RequestMapping("/sys/user")
-@Tag(name = "用户")
-@AllArgsConstructor
-public class SysUserController extends BaseController {
-    private final ISysUserService userService;
+public class SysUserController {
 
-    @PostMapping("/reset/psw")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "重置密码", description = "权限: sys:user:reset")
-    @SaCheckPermission("sys:user:reset")
-    public CommonResult<Boolean> valid(@RequestBody Set<String> userIds){
-        return CommonResult.success(userService.resetPsw(userIds));
-    }
+    @Resource
+    private ISysUserService sysUserService;
 
-    @PostMapping("/username/valid")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "校验用户名是否重复", description = "权限: sys:user:query")
-    @ApiResponses(
-            @ApiResponse(responseCode = "200", description = "1 用户名可用")
-    )
-    @SaCheckPermission("sys:user:query")
-    public CommonResult<Boolean> valid(@RequestBody@Validated SysValidateUsernameDTO source){
-        return CommonResult.success(userService.isValidUsername(source.getUserId(),source.getUsername()));
+    /**
+     * 分页查询
+     */
+    @Operation(summary = "用户管理分页查询")
+    @GetMapping("/page")
+    @SaCheckPermission("system:sysUser:page")
+    public CommonResult page(Page reqPage, SysUserQueryDTO req) {
+        return CommonResult.success(sysUserService.page(reqPage, req));
     }
 
-    @PostMapping("/query/page")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询用户(分页)", description = "权限: 无")
-    public TableDataInfo<SysUserDTO> selectPage(@RequestBody SysUserQueryDTO query){
-        startPage();
-        return getDataTable(userService.selectSysUserList(query));
+    /**
+     * 新增
+     */
+    @Operation(summary = "用户管理新增")
+    @PostMapping("/add")
+    @SaCheckPermission("system:sysUser:add")
+    public CommonResult add(@Validated @RequestBody SysUserAddDTO req) {
+            sysUserService.add(req);
+            return CommonResult.success();
     }
 
-    @PostMapping("/query/list")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据条件查询用户(不分页)", description = "权限: 无")
-    public CommonResult<List<SysUserSmallDTO>> selectList(@RequestBody SysUserQueryDTO query){
-        query.setStatus(UserStatusEnum.normal.getValue());
-        return CommonResult.success(SysUserMapper.INSTANCE.toUserSmallDTOList(userService.selectSysUserList(query)));
+    /**
+     * 修改
+     */
+    @Operation(summary = "用户管理修改")
+    @PostMapping("/edit")
+    @SaCheckPermission("system:sysUser:edit")
+    public CommonResult edit(@Validated @RequestBody SysUserEditDTO req) {
+        sysUserService.edit(req);
+        return CommonResult.success();
     }
 
-    @GetMapping("/detail/{id}")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "根据id查询用户", description = "权限: sys:user:query")
-    @Parameter(name = "id", description = "用户ID", required = true)
-    @SaCheckPermission("sys:user:query")
-    public CommonResult<SysUserDTO> findById(@PathVariable("id") String id){
-        return CommonResult.success(userService.selectSysUserById(id));
+    /**
+     * 删除
+     */
+    @Operation(summary = "用户管理删除")
+    @PostMapping("/remove")
+    @SaCheckPermission("system:sysUser:remove")
+    public CommonResult remove(@RequestParam("ids") Long id) {
+        sysUserService.remove(id);
+        return CommonResult.success();
     }
 
-    @PostMapping("/edit")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:user:edit")
-    @Operation(summary = "根据id更新用户", description = "权限: sys:user:edit")
-    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysUserEditDTO source){
-        return CommonResult.success(userService.updateSysUserById(source));
+    /**
+     * 查看
+     */
+    @Operation(summary = "用户管理查看")
+    @GetMapping("/view")
+    @SaCheckPermission("system:sysUser:page")
+    public CommonResult view(@RequestParam String id) {
+        return CommonResult.success(sysUserService.view(id));
     }
 
-    @PostMapping("/add")
-    @ApiOperationSupport(author = "lf")
-    @SaCheckPermission("sys:user:add")
-    @Operation(summary = "新增用户", description = "权限: sys:user:add")
-    @OperateLog
-    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysUserDTO source){
-        return CommonResult.success(userService.insertSysUser(source));
+    /**
+     * 导出
+     */
+    @Operation(summary = "用户管理导出")
+    @GetMapping("/export")
+    @SaCheckPermission("system:sysUser:export")
+    public CommonResult export(SysUserQueryDTO req) {
+        String filepath = ExcelUtil.export("用户列表", SysUserPO.class, sysUserService.list(req));
+        return CommonResult.success(filepath);
     }
 
-    @PostMapping("/deleteByIds")
-    @ApiOperationSupport(author = "lf")
-    @Operation(summary = "删除用户", description = "权限: sys:user:remove")
-    @SaCheckPermission("sys:user:remove")
-    @OperateLog
-    public CommonResult<Integer> deleteByIds(@RequestBody Collection<String> ids){
-        return CommonResult.success(userService.deleteSysUserByIds(ids));
+    /**
+     * 重置密码
+     */
+    @Operation(summary = "重置密码")
+    @PostMapping("/resetPwd")
+    @SaCheckPermission("system:sysUser:resetPwd")
+    public CommonResult resetPwd(@Validated @RequestBody SysUserResetPwdDTO<Long> req) {
+        if (SecurityUtil.getId().equals(req.getId())) {
+            throw new CustomException("不可重置当前用户密码,请前往【账户设置】中修改");
+        }
+        sysUserService.resetPwd(req);
+        return CommonResult.success();
     }
 
-    //todo 导出
-
 }
+

+ 102 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptAddDTO.java

@@ -0,0 +1,102 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 部门表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysDeptAddDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 父部门ID
+     */
+    private Long parentId;
+
+    /**
+     * 部门名称
+     */
+    @NotBlank(message = "部门名称不能为空")
+    private String deptName;
+
+    /**
+     * 部门全名
+     */
+    @NotBlank(message = "部门全名不能为空")
+    private String deptFullname;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 机构类型 1公司;2部门;3小组;4其他
+     */
+    @NotBlank(message = "机构类型 1公司;2部门;3小组;4其他不能为空")
+    private String orgType;
+
+    /**
+     * 负责人
+     */
+    private String leader;
+
+    /**
+     * 负责人电话
+     */
+    private String leaderPhone;
+
+    /**
+     * 办公电话
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 邮政编码
+     */
+    private String postCode;
+
+    /**
+     * 联系地址
+     */
+    private String address;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态 0正常;1停用不能为空")
+    private String status;
+
+}

+ 104 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptEditDTO.java

@@ -0,0 +1,104 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 部门表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysDeptEditDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @NotNull(message = "主键不能为空")
+    private Long id;
+
+    /**
+     * 父部门ID
+     */
+    private Long parentId;
+
+    /**
+     * 部门名称
+     */
+    @NotBlank(message = "部门名称不能为空")
+    private String deptName;
+
+    /**
+     * 部门全名
+     */
+    @NotBlank(message = "部门全名不能为空")
+    private String deptFullname;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 机构类型 1公司;2部门;3小组;4其他
+     */
+    @NotBlank(message = "机构类型 1公司;2部门;3小组;4其他不能为空")
+    private String orgType;
+
+    /**
+     * 负责人
+     */
+    private String leader;
+
+    /**
+     * 负责人电话
+     */
+    private String leaderPhone;
+
+    /**
+     * 办公电话
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 邮政编码
+     */
+    private String postCode;
+
+    /**
+     * 联系地址
+     */
+    private String address;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态 0正常;1停用不能为空")
+    private String status;
+
+
+}

+ 80 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptQueryDTO.java

@@ -0,0 +1,80 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 部门表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysDeptQueryDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 父部门ID
+     */
+    private Long parentId;
+
+    /**
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 部门全名
+     */
+    private String deptFullname;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 机构类型 1公司;2部门;3小组;4其他
+     */
+    private String orgType;
+
+    /**
+     * 负责人
+     */
+    private String leader;
+
+    /**
+     * 负责人电话
+     */
+    private String leaderPhone;
+
+    /**
+     * 办公电话
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 邮政编码
+     */
+    private String postCode;
+
+    /**
+     * 联系地址
+     */
+    private String address;
+
+}

+ 119 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuAddDTO.java

@@ -0,0 +1,119 @@
+package cn.tr.module.sys.user.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 菜单表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-19
+ */
+@Data
+public class SysMenuAddDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 菜单类型 dir目录;menu菜单;button按钮
+     */
+    @NotBlank(message = "菜单类型")
+    @Size(max = 30, message = "菜单类型长度不能超过30个字符")
+    private String menuType;
+
+    /**
+     * 菜单名称
+     */
+    @NotBlank(message = "菜单名称不能为空")
+    @Size(max = 100, message = "菜单名称长度不能超过100个字符")
+    private String menuName;
+
+    /**
+     * 上级菜单
+     */
+    private Long parentId;
+
+    /**
+     * 路由地址
+     */
+    @Size(max = 500, message = "路由地址长度不能超过500个字符")
+    private String routePath;
+
+    /**
+     * 组件路径
+     */
+    @Size(max = 500, message = "组件路径长度不能超过500个字符")
+    private String component;
+
+    /**
+     * 权限标识
+     */
+    @Size(max = 100, message = "权限标识长度不能超过100个字符")
+    private String permission;
+
+    /**
+     * 图标
+     */
+    @Size(max = 100, message = "图标长度不能超过100个字符")
+    private String icon;
+
+    @Schema(description = "是否为租户菜单, 0、否(租户不可见) 1、是(租户可见)")
+    private Boolean tenantMenu;
+    /**
+     * 是否缓存 0缓存;1不缓存
+     */
+    private String keepalive;
+
+    /**
+     * 是否外链 0是;1否
+     */
+    private String linkExternal;
+
+    /**
+     * 是否显示 0显示;1隐藏
+     */
+    private String visible;
+
+    /**
+     * 是否内嵌 0内嵌;1不内嵌
+     */
+    private String frame;
+
+    /**
+     * 外部链接
+     */
+    @Size(max = 500, message = "外部链接长度不能超过500个字符")
+    private String linkUrl;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+    private String tenantId;
+}

+ 96 - 98
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuDTO.java

@@ -1,148 +1,146 @@
 package cn.tr.module.sys.user.dto;
 
-import cn.tr.core.tree.TreeNode;
-import cn.tr.core.validation.Insert;
-import cn.tr.core.validation.Update;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
 import lombok.Data;
-import lombok.ToString;
 
-import java.io.Serial;
+import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
-import java.util.Objects;
 
 /**
- * 菜单对象 sys_menu
+ * <p>
+ * 菜单表
+ * </p>
  *
- * @author tr
- * @date 2022-11-23 15:34:37
+ * @author Kevin
+ * @since 2021-06-19
  */
 @Data
-@ToString
-@Schema(description = "菜单对象")
-public class SysMenuDTO extends TreeNode<SysMenuDTO,String> {
+public class SysMenuDTO implements Serializable {
 
-    @Serial
     private static final long serialVersionUID = 1L;
 
-    @Schema(description = "主键")
-    @NotBlank(message = "菜单主键不能为空",groups = Update.class)
-    private String id;
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
 
     /**
-     * {@link cn.tr.module.sys.user.enums.MenuEnum}
+     * 菜单类型 dir目录;menu菜单;button按钮
      */
-    @Schema(description = "菜单类型 dir目录;menu菜单;button按钮", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "菜单类型不能为空",groups = {Update.class, Insert.class})
     private String menuType;
 
+    /**
+     * 菜单名称
+     */
+    private String menuName;
 
-    @Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "菜单名称不能为空",groups = {Update.class, Insert.class})
-    private String name;
+    /**
+     * 上级菜单
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long parentId;
 
-    @Schema(description = "路由地址")
-    private String routePath;
+    @TableField(exist = false)
+    private String parentName;
 
+    /**
+     * 路由地址
+     */
+    private String routePath;
 
-    @Schema(description = "组件路径")
+    /**
+     * 组件路径
+     */
     private String component;
 
-
-    @Schema(description = "权限标识")
+    /**
+     * 权限标识
+     */
     private String permission;
 
-
-    @Schema(description = "图标")
+    /**
+     * 图标
+     */
+    @TableField(updateStrategy = FieldStrategy.NEVER)
     private String icon;
 
-    @Schema(description = "是否缓存 0不缓存;1缓存", requiredMode = Schema.RequiredMode.REQUIRED)
-    private Boolean keepalive;
-
-
-    @Schema(description = "是否外链 0否;1是", requiredMode = Schema.RequiredMode.REQUIRED)
-    private Boolean linkExternal;
+    /**
+     * 是否缓存 0缓存;1不缓存
+     */
+    private String keepalive;
 
+    /**
+     * 是否外链 0是;1否
+     */
+    private String linkExternal;
 
-    @Schema(description = "是否显示 0隐藏;1显示", requiredMode = Schema.RequiredMode.REQUIRED)
-    private Boolean visible;
+    /**
+     * 是否显示 0显示;1隐藏
+     */
+    private String visible;
 
+    @Schema(description = "是否为租户菜单, 0、否(租户不可见) 1、是(租户可见)")
+    private Boolean tenantMenu;
 
-    @Schema(description = "是否内嵌 0不内嵌;1、内嵌", requiredMode = Schema.RequiredMode.REQUIRED)
-    private Boolean frame;
+    /**
+     * 是否内嵌 0内嵌;1不内嵌
+     */
+    private String frame;
 
-    @Schema(description = "外部链接", requiredMode = Schema.RequiredMode.REQUIRED)
+    /**
+     * 外部链接
+     */
     private String linkUrl;
 
+    /**
+     * 排序
+     */
+    private Integer sort;
 
-    @Schema(description = "备注")
-    private String remark;
-
-    @Schema(description = "状态 0正常;1停用", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "菜单状态不能为空",groups = {Update.class, Insert.class})
-    private Boolean disable;
-
-    // 新增字段
-    private List<String> authority;
-
-    private Boolean noBasicLayout;
-
-    private Integer order;
-
-    private String badge;
-
-    private String badgeType;
-
-    private String badgeVariants;
-
-//    /**
-//     * 菜单是否可以匿名访问
-//     */
-//    private Boolean anonymous;
-
-//    private Boolean hideChildrenInMenu;
-//
-//    private Boolean  hideInMenu;
-
+    /**
+     * 备注
+     */
+    private String remarks;
 
-    @Schema(description = "0非快捷菜单;1快捷菜单")
-    private Integer quickMenu;
+    /**
+     * 状态 0正常;1停用
+     */
+    private String status;
 
-    @Schema(description = "快捷菜单排序")
-    private String quickMenuSort;
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
 
-    @Schema(description = "快捷菜单图标")
-    private String quickMenuIcon;
     /**
      * 创建时间
      */
-    @JsonIgnoreProperties(allowGetters = true)
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     /**
-     * 最后更新时间
+     * 更新人
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+    /**
+     * 更新时间
      */
-    @JsonIgnoreProperties(allowGetters = true)
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updateTime;
 
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        SysMenuDTO that = (SysMenuDTO) o;
-        return Objects.equals(getId(), that.getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(getId());
-    }
-}
+    @TableField(exist = false)
+    private List<SysMenuDTO> children;
+}

+ 119 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuEditDTO.java

@@ -0,0 +1,119 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 菜单表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-19
+ */
+@Data
+public class SysMenuEditDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @NotNull(message = "主键不能为空")
+    private Long id;
+
+    /**
+     * 菜单类型 dir目录;menu菜单;button按钮
+     */
+    @NotBlank(message = "菜单类型")
+    @Size(max = 30, message = "菜单类型长度不能超过30个字符")
+    private String menuType;
+
+    /**
+     * 菜单名称
+     */
+    @NotBlank(message = "菜单名称不能为空")
+    @Size(max = 100, message = "菜单名称长度不能超过100个字符")
+    private String menuName;
+
+    /**
+     * 上级菜单
+     */
+    private Long parentId;
+
+    /**
+     * 路由地址
+     */
+    @Size(max = 500, message = "路由地址长度不能超过500个字符")
+    private String routePath;
+
+    /**
+     * 组件路径
+     */
+    @Size(max = 500, message = "组件路径长度不能超过500个字符")
+    private String component;
+
+    /**
+     * 权限标识
+     */
+    @Size(max = 100, message = "权限标识长度不能超过100个字符")
+    private String permission;
+
+    /**
+     * 图标
+     */
+    @Size(max = 100, message = "图标长度不能超过100个字符")
+    private String icon;
+
+    private Boolean tenantMenu;
+    /**
+     * 是否缓存 0缓存;1不缓存
+     */
+    private String keepalive;
+
+    /**
+     * 是否外链 0是;1否
+     */
+    private String linkExternal;
+
+    /**
+     * 是否显示 0显示;1隐藏
+     */
+    private String visible;
+
+    /**
+     * 是否内嵌 0内嵌;1不内嵌
+     */
+    private String frame;
+
+    /**
+     * 外部链接
+     */
+    @Size(max = 500, message = "外部链接长度不能超过500个字符")
+    private String linkUrl;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+    private String tenantId;
+
+}

+ 1 - 9
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuQueryDTO.java

@@ -23,14 +23,6 @@ public class SysMenuQueryDTO implements Serializable {
     private String parentId;
 
     @Schema(description = "菜单名称")
-    private String name;
+    private String menuName;
 
-    @Schema(description = "菜单类型")
-    private Set<String> menuType;
-
-    @Schema(description = "菜单状态")
-    private Boolean disable;
-
-    @Schema(description = "租户菜单id", hidden = true)
-    private Set<String> tenantMenuIds;
 }

+ 0 - 1
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysOrgDTO.java

@@ -12,7 +12,6 @@ import lombok.Data;
 import java.util.Date;
 
 /**
- * 部门对象 sys_menu
  *
  * @author tr
  * @date 2022-11-23 15:34:37

+ 60 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostAddDTO.java

@@ -0,0 +1,60 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 岗位表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+@Data
+public class SysPostAddDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 岗位编码
+     */
+    @NotBlank(message = "岗位编码不能为空")
+    @Size(max = 100, message = "岗位编码长度不能超过100个字符")
+    private String postCode;
+
+    /**
+     * 岗位名称
+     */
+    @NotBlank(message = "岗位名称不能为空")
+    @Size(max = 100, message = "岗位名称长度不能超过100个字符")
+    private String postName;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+}

+ 62 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostEditDTO.java

@@ -0,0 +1,62 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 岗位表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+@Data
+public class SysPostEditDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @NotNull(message = "主键不能为空")
+    private Long id;
+
+    /**
+     * 岗位编码
+     */
+    @NotBlank(message = "岗位编码不能为空")
+    @Size(max = 100, message = "岗位编码长度不能超过100个字符")
+    private String postCode;
+
+    /**
+     * 岗位名称
+     */
+    @NotBlank(message = "岗位名称不能为空")
+    @Size(max = 100, message = "岗位名称长度不能超过100个字符")
+    private String postName;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+
+}

+ 31 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostQueryDTO.java

@@ -0,0 +1,31 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 岗位表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+@Data
+public class SysPostQueryDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 岗位编码
+     */
+    private String postCode;
+
+    /**
+     * 岗位名称
+     */
+    private String postName;
+
+
+}

+ 72 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleAddDTO.java

@@ -0,0 +1,72 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysRoleAddDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 角色编码
+     */
+    @NotBlank(message = "角色编码不能为空")
+    @Size(max = 100, message = "字典编码长度不能超过100个字符")
+    private String roleCode;
+
+    /**
+     * 角色名称
+     */
+    @NotBlank(message = "角色名称不能为空")
+    @Size(max = 100, message = "字典编码长度不能超过100个字符")
+    private String roleName;
+
+    /**
+     * 数据范围 1全部数据权限;2自定数据权限;3本部门数据权限;4本部门及以下数据权限
+     */
+    @NotBlank(message = "数据范围不能为空")
+    private String dataScope;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+    /**
+     * 部门ID列表
+     */
+    private List<Long> deptIds;
+
+}

+ 33 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleAssignMenuDTO.java

@@ -0,0 +1,33 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysRoleAssignMenuDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 角色ID
+     */
+    @NotNull(message = "角色ID不能为空")
+    private String roleId;
+
+    /**
+     * 菜单组
+     */
+    private List<Long> menuIds;
+
+}

+ 73 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleEditDTO.java

@@ -0,0 +1,73 @@
+package cn.tr.module.sys.user.dto;
+
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysRoleEditDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @NotNull(message = "主键不能为空")
+    private Long id;
+
+    /**
+     * 角色编码
+     */
+    @NotBlank(message = "角色编码不能为空")
+    @Size(max = 100, message = "字典编码长度不能超过100个字符")
+    private String roleCode;
+
+    /**
+     * 角色名称
+     */
+    @NotBlank(message = "角色名称不能为空")
+    @Size(max = 100, message = "字典编码长度不能超过100个字符")
+    private String roleName;
+
+    /**
+     * 数据范围 1全部数据权限;2自定数据权限;3本部门数据权限;4本部门及以下数据权限
+     */
+    @NotBlank(message = "数据范围不能为空")
+    private String dataScope;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+    /**
+     * 部门ID列表
+     */
+    private List<Long> deptIds;
+
+}

+ 0 - 6
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleQueryDTO.java

@@ -25,11 +25,5 @@ public class SysRoleQueryDTO implements Serializable {
     @Schema(description = "角色名称")
     private String roleName;
 
-    @Schema(description = "角色类型", required = true)
-    @NotNull(message = "角色类型不能为空")
-    private String type;
-
-    @Schema(description = "是否启用 0、启用 1、关闭")
-    private Boolean disable;
 
 }

+ 138 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserAddDTO.java

@@ -0,0 +1,138 @@
+package cn.tr.module.sys.user.dto;
+
+import cn.tr.module.common.menus.SexEnum;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysUserAddDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 账号
+     */
+    @NotBlank(message = "账号不能为空")
+    @Size(max = 100, message = "账号长度不能超过100个字符")
+    private String account;
+
+    /**
+     * 密码
+     */
+    @NotBlank(message = "密码不能为空")
+    @Size(max = 100, message = "密码长度不能超过100个字符")
+    private String password;
+
+    /**
+     * 昵称
+     */
+    @NotBlank(message = "昵称不能为空")
+    @Size(max = 100, message = "昵称长度不能超过100个字符")
+    private String nickname;
+
+    /**
+     * 姓名
+     */
+    @Size(max = 100, message = "姓名长度不能超过100个字符")
+    private String realname;
+
+    /**
+     * 英文名
+     */
+    @Size(max = 100, message = "英文名长度不能超过100个字符")
+    private String englishName;
+
+    /**
+     * 头像
+     */
+    @Size(max = 100, message = "头像长度不能超过100个字符")
+    private String avatar;
+
+    /**
+     * 邮箱
+     */
+    @Size(max = 100, message = "邮箱长度不能超过100个字符")
+    private String email;
+
+    /**
+     * 手机号
+     */
+    @Size(max = 30, message = "手机号长度不能超过30个字符")
+    private String phone;
+
+    /**
+     * 工号
+     */
+    @Size(max = 30, message = "工号长度不能超过30个字符")
+    private String staffNumber;
+
+    /**
+     * 生日
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date birthday;
+
+    /**
+     * 性别 1男;2女;3未知
+     */
+    @NotNull(message = "性别不能为空")
+    private SexEnum sex;
+
+    /**
+     * 部门ID
+     */
+    private String deptId;
+
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
+    private String status;
+
+    /**
+     * 岗位组
+     */
+    private List<Long> postIds;
+
+    /**
+     * 角色组
+     */
+    private List<Long> roleIds;
+
+    private Boolean isSys;
+
+    private Long tenantId;
+}

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

@@ -4,7 +4,15 @@ import cn.tr.core.pojo.BaseDTO;
 import cn.tr.core.utils.UserUtil;
 import cn.tr.core.validation.Insert;
 import cn.tr.core.validation.Update;
+import cn.tr.module.common.annotation.ExcelDict;
+import cn.tr.module.common.convert.ExcelDictConverter;
+import cn.tr.module.common.menus.SexEnum;
+import cn.tr.module.common.mybatisplus.handler.TenantNameHandler;
 import cn.tr.module.sys.user.enums.UserStatusEnum;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -12,8 +20,10 @@ import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import lombok.Getter;
 import org.hibernate.validator.constraints.Length;
 import java.util.Date;
+import java.util.List;
 import java.util.Set;
 import java.io.Serial;
 
@@ -30,119 +40,194 @@ public class SysUserDTO extends BaseDTO {
     @Serial
     private static final long serialVersionUID = 1L;
 
+    @TableId
+    private Long id;
     /**
-     * 用户主键Id
+     * 账号
      */
-    @Schema(description = "用户id")
-    private String id;
+    @ExcelProperty(value = "账号", index = 0)
+    private String account;
 
     /**
-     * 用户名
+     * 密码
      */
-    @Schema(description = "用户名", required = true)
-    @Length(min = 4,max = 16,message = "管理账号长度在4~16之间",groups = {Insert.class,Update.class})
-    private String username;
+
+    @JsonIgnore
+    private String password;
+
+    /**
+     * 修改密码标记 0未修改;1已修改
+     */
+
+    @JsonIgnore
+    private String pswModified;
 
     /**
      * 昵称
      */
-    @Schema(description = "昵称")
+    @ExcelProperty(value = "昵称", index = 2)
     private String nickname;
 
     /**
-     * 密码
+     * 姓名
      */
-    @JsonIgnoreProperties(allowSetters = true)
-    @NotBlank(message = "密码不能为空",groups = {Insert.class})
-    @Length(min = 6,max = 16,message = "密码长度在6~16之间",groups = {Insert.class})
-    private String password;
-
-    @Schema(description = "角色id")
-    @NotNull(message = "角色id不能为空",groups = {Insert.class,Update.class})
-    private Set<String> roleIds;
+    @ExcelProperty(value = "姓名", index = 4)
+    private String realname;
 
-    @Schema(description = "门户id")
-    @NotNull(message = "门户不能为空",groups = {Insert.class,Update.class})
-    private Set<String> portalIds;
+    /**
+     * 英文名
+     */
+    @ExcelProperty(value = "英文名", index = 5)
+    private String englishName;
 
     /**
-     * 性别
+     * 头像
      */
-    @Schema(description = "性别")
-    private String gender;
+    private String avatar;
 
     /**
-     * 部门id
+     * 邮箱
      */
-    @Schema(description = "组织id")
-    @NotBlank(message = "组织不能为空",groups = {Insert.class, Update.class})
-    private String orgId;
+    @ExcelProperty(value = "邮箱", index = 6)
+    private String email;
 
     /**
      * 手机号
      */
+    @ExcelProperty(value = "手机号", index = 7)
     private String phone;
 
     /**
-     * 邮箱地址
+     * 工号
      */
-    private String email;
+    @ExcelProperty(value = "工号", index = 8)
+    private String staffNumber;
 
     /**
-     * 生日
+     * 生日
      */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+    @ColumnWidth(20)
+    @ExcelProperty(value = "生日", index = 9)
     private Date birthday;
 
     /**
-     * 岗位id
+     * 性别 1男;2女;3未知
      */
-    private Set<String> postIds;
+//    @ExcelProperty(value = "性别", index = 3, converter = ExcelDictConverter.class)
+//    @ExcelDict("sys_sex")
+    private SexEnum sex;
 
     /**
-     * {@link UserStatusEnum#getValue()}
+     * 部门ID
      */
-    @Schema(description = "用户状态", required = true)
-    @NotBlank(message = "用户状态",groups = {Insert.class, Update.class})
-    private String status;
+    private String deptId;
+
 
     /**
-     * 最后登录IP
+     * 排序
      */
-    @JsonIgnoreProperties(allowGetters = true)
-    private String lastLoginIp;
+    @ExcelProperty(value = "排序", index = 11)
+    private Integer sort;
 
-    @JsonIgnoreProperties(allowGetters = true)
-    private String lastLoginAddress;
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注", index = 13)
+    private String remarks;
 
-    @JsonIgnoreProperties(allowGetters = true)
-    private Date lastLoginDate;
+    /**
+     * 状态 0正常;1停用
+     */
+    @ExcelProperty(value = "状态", index = 12, converter = ExcelDictConverter.class)
+    @ExcelDict("sys_status")
+    private String status;
 
     /**
-     * 备注
+     * 删除标记 0存在;1删除
      */
-    private String remark;
+    @TableLogic(value = "0",delval = "1")
+    private String delFlag;
 
-    private String tenantId;
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
 
-    @JsonIgnore
-    private String signature;
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
 
-    private String avatar;
+    /**
+     * 更新人
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
 
-    private String type;
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
 
     /**
-     * unionId
+     * 部门名称
      */
-    private String unionId;
+    @TableField(exist = false)
+    @ExcelProperty(value = "部门", index = 1)
+    private String deptName;
 
     /**
-     * 小程序appid
+     * 岗位组
      */
-    private String appId;
+    @TableField(exist = false)
+    private List<String> postIds;
 
     /**
-     * 小程序openId
+     * 角色组
      */
+    @TableField(exist = false)
+    private List<String> roleIds;
+
+    /**
+     * 是否为系统级别用户
+     *  0、否  1、是
+     **/
+    @TableField
+    private Boolean isSys;
+
+    @TableField
+    private Boolean pswNeedReset;
+
+    @TableField
+    @Schema(description = "最后修改密码时间")
+    private Date lastModifyPswTime;
+
+    @Schema(description = "小程序openId")
     private String openId;
+
+    @Schema(description = "微信unionId")
+    private String unionId;
+
+    @Schema(description = "用户类型")
+    private String type;
+
+    @Schema(description = "最后登录Ip")
+    private String lastLoginIp;
+
+    @Schema(description = "最后登录地址")
+    private String lastLoginAddress;
+
+    @Schema(description = "最后登录时间")
+    private Date lastLoginDate;
+
+
+    @Getter
+    @TableField(value = "tenant_id",insertStrategy = FieldStrategy.NEVER,updateStrategy = FieldStrategy.NEVER,typeHandler = TenantNameHandler.class)
+    private String tenantName;
 }

+ 101 - 48
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserEditDTO.java

@@ -1,81 +1,134 @@
 package cn.tr.module.sys.user.dto;
 
-import cn.tr.core.validation.Insert;
-import cn.tr.core.validation.Update;
-import cn.tr.module.sys.user.enums.UserStatusEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
+import cn.tr.module.common.menus.SexEnum;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
 import java.io.Serializable;
-import java.io.Serial;
 import java.util.Date;
-import java.util.Set;
+import java.util.List;
 
 /**
- * @ClassName : SysUserEditDTO
- * @Description : 系统用户修改、新增实体类
- * @Author : LF
- * @Date: 2023年03月31日
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
 @Data
-@Schema(description = "系统用户修改、新增实体类")
 public class SysUserEditDTO implements Serializable {
-    @Serial
+
     private static final long serialVersionUID = 1L;
 
-    @Schema(description = "用户id")
-    @NotBlank(message = "用户id不能为空", groups = {Update.class})
-    private String id;
+    /**
+     * 主键
+     */
+    @NotNull(message = "主键不能为空")
+    private Long id;
 
-    @Schema(description = "用户名", required = true)
-    @NotBlank(message = "用户名不能为空", groups = {Update.class, Insert.class})
-    private String username;
+    /**
+     * 账号
+     */
+    @NotBlank(message = "账号不能为空")
+    @Size(max = 100, message = "账号长度不能超过100个字符")
+    private String account;
 
-    @Schema(description = "昵称")
-    @NotBlank(message = "昵称不能为空", groups = {Update.class, Insert.class})
+    /**
+     * 昵称
+     */
+    @NotBlank(message = "昵称不能为空")
+    @Size(max = 100, message = "昵称长度不能超过100个字符")
     private String nickname;
 
-    @Schema(description = "角色id")
-    @NotNull(message = "角色不能为空", groups = {Insert.class, Update.class})
-    private Set<String> roleIds;
+    /**
+     * 姓名
+     */
+    @Size(max = 100, message = "姓名长度不能超过100个字符")
+    private String realname;
 
-    @Schema(description = "门户id")
-    @NotNull(message = "门户不能为空", groups = {Insert.class, Update.class})
-    private Set<String> portalIds;
+    /**
+     * 英文名
+     */
+    @Size(max = 100, message = "英文名长度不能超过100个字符")
+    private String englishName;
 
-    @Schema(description = "性别")
-    @NotBlank(message = "性别不能为空", groups = {Insert.class, Update.class})
-    private String gender;
+    /**
+     * 头像
+     */
+    @Size(max = 100, message = "头像长度不能超过100个字符")
+    private String avatar;
 
-    @Schema(description = "组织部门id")
-    @NotBlank(message = "组织部门不能为空", groups = {Insert.class, Update.class})
-    private String orgId;
+    /**
+     * 邮箱
+     */
+    @Size(max = 100, message = "邮箱长度不能超过100个字符")
+    private String email;
 
-    @Schema(description = "手机号")
+    /**
+     * 手机号
+     */
+    @Size(max = 30, message = "手机号长度不能超过30个字符")
     private String phone;
 
-    @Schema(description = "邮箱地址")
-    private String email;
+    /**
+     * 工号
+     */
+    @Size(max = 30, message = "工号长度不能超过30个字符")
+    private String staffNumber;
 
-    @Schema(description = "出生日期")
+    /**
+     * 生日
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private Date birthday;
 
-    @Schema(description = "岗位id")
-    private Set<String> postIds;
+    /**
+     * 性别 1男;2女;3未知
+     */
+    @NotNull(message = "性别不能为空")
+    private SexEnum sex;
+
+    /**
+     * 部门ID
+     */
+    private String deptId;
 
-    @Schema(description = "用户头像")
-    private String avatar;
+    /**
+     * 排序
+     */
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
 
     /**
-     * {@link UserStatusEnum#getValue()}
+     * 备注
      */
-    @Schema(description = "用户状态", required = true)
-    @NotBlank(message = "用户状态不能为空", groups = {Insert.class, Update.class})
+    @Size(max = 500, message = "备注长度不能超过500个字符")
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @NotBlank(message = "状态不能为空")
     private String status;
 
-    @Schema(description = "备注")
-    private String remark;
+    /**
+     * 状态 0否;1是
+     */
+    private Boolean isSys;
+
+    /**
+     * 岗位组
+     */
+    private List<Long> postIds;
+
+    /**
+     * 角色组
+     */
+    private List<Long> roleIds;
 
-}
+    private Long tenantId;
+}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio