Jelajahi Sumber

修改登录

zhouzeyu 1 Minggu lalu
induk
melakukan
68d26258ad
100 mengubah file dengan 7177 tambahan dan 2854 penghapusan
  1. TEMPAT SAMPAH
      logs/2026-01/hdis-2026-01-08-1.log.gz
  2. TEMPAT SAMPAH
      logs/2026-01/hdis-2026-01-14-1.log.gz
  3. TEMPAT SAMPAH
      logs/2026-01/hdis-2026-01-15-1.log.gz
  4. TEMPAT SAMPAH
      logs/2026-01/hdis-2026-01-16-1.log.gz
  5. TEMPAT SAMPAH
      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. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/cache/manager/ConfigStorageManager.java
  12. 25 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/RecordCreationEntity.java
  13. 28 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/RecordModifierEntity.java
  14. 26 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/entity/TenantGenericEntity.java
  15. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/MenuTypeEnum.java
  16. 34 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/SexEnum.java
  17. 29 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/StatusEnum.java
  18. 36 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/UserPlatformEnum.java
  19. 26 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/menus/YesNoEnum.java
  20. 50 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/handler/IntegerStringTypeHandler.java
  21. 61 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/mybatisplus/handler/TenantNameHandler.java
  22. 52 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedisConfig.java
  23. 587 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedisUtils.java
  24. 113 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/redis/RedissonClientAutoConfiguration.java
  25. 139 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/SecurityUtil.java
  26. 19 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/common/utils/TenantUtil.java
  27. 40 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/bean/SysRoleInfo.java
  28. 42 42
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/config/StdStpInterface.java
  29. 100 100
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/OAuth2ServerController.java
  30. 27 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/enums/StpTypeEnum.java
  31. 45 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/granter/TokenParameter.java
  32. 127 128
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/psw/operator/LoginWxUserOperator.java
  33. 140 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/utils/SecurityUtil.java
  34. 21 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/vo/RoleInfoVO.java
  35. 41 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/vo/UserInfoVO.java
  36. 1 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/sms/service/impl/SmsSendServiceImpl.java
  37. 93 93
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantController.java
  38. 104 105
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantPackageController.java
  39. 148 149
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantPackageMenuServiceImpl.java
  40. 118 118
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantPackageServiceImpl.java
  41. 217 217
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/service/impl/SysTenantServiceImpl.java
  42. 114 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysDeptController.java
  43. 85 86
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysMenuController.java
  44. 98 98
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysOrgController.java
  45. 101 101
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPortalController.java
  46. 0 82
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPositionController.java
  47. 119 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPostController.java
  48. 122 74
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysRoleController.java
  49. 88 81
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysUserController.java
  50. 102 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptAddDTO.java
  51. 104 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptEditDTO.java
  52. 80 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysDeptQueryDTO.java
  53. 119 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuAddDTO.java
  54. 96 98
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuDTO.java
  55. 119 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuEditDTO.java
  56. 1 9
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysMenuQueryDTO.java
  57. 0 1
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysOrgDTO.java
  58. 60 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostAddDTO.java
  59. 62 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostEditDTO.java
  60. 31 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPostQueryDTO.java
  61. 72 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleAddDTO.java
  62. 33 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleAssignMenuDTO.java
  63. 73 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleEditDTO.java
  64. 0 6
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysRoleQueryDTO.java
  65. 138 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserAddDTO.java
  66. 140 55
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserDTO.java
  67. 101 48
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserEditDTO.java
  68. 34 9
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserQueryDTO.java
  69. 37 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysUserResetPwdDTO.java
  70. 18 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysDeptMapper.java
  71. 33 33
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysOrgMapper.java
  72. 16 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysRoleDeptMapper.java
  73. 40 40
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysUserMapper.java
  74. 27 27
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysUserPortalMapper.java
  75. 129 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysDeptPO.java
  76. 100 78
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysMenuPO.java
  77. 107 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysPostPO.java
  78. 38 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysRoleDeptPO.java
  79. 17 7
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysRoleMenuPO.java
  80. 57 33
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysRolePO.java
  81. 190 63
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysUserPO.java
  82. 41 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysUserPostPO.java
  83. 14 8
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysUserRolePO.java
  84. 41 41
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/provider/SysUserNickNameProvider.java
  85. 18 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysDeptRepository.java
  86. 0 9
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysMenuRepository.java
  87. 16 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysPostRepository.java
  88. 16 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysRoleDeptRepository.java
  89. 16 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysUserPostRepository.java
  90. 215 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysDeptServiceImpl.java
  91. 220 184
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysMenuServiceImpl.java
  92. 95 95
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysOrgServiceImpl.java
  93. 118 118
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPortalMenuServiceImpl.java
  94. 139 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPostServiceImpl.java
  95. 21 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysRoleDeptServiceImpl.java
  96. 0 85
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysRoleMenuServiceImpl.java
  97. 229 88
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysRoleServiceImpl.java
  98. 20 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysUserPostServiceImpl.java
  99. 6 47
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysUserRoleServiceImpl.java
  100. 260 195
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysUserServiceImpl.java

TEMPAT SAMPAH
logs/2026-01/hdis-2026-01-08-1.log.gz


TEMPAT SAMPAH
logs/2026-01/hdis-2026-01-14-1.log.gz


TEMPAT SAMPAH
logs/2026-01/hdis-2026-01-15-1.log.gz


TEMPAT SAMPAH
logs/2026-01/hdis-2026-01-16-1.log.gz


TEMPAT SAMPAH
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);
+    }
+}

+ 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);
+    }
+}

+ 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;
+}

+ 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));
+    }
+}

+ 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);
+    }
+}

+ 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");
+    }
+
+}

+ 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());
+//    }
+//}

+ 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);
+//    }
+//}

+ 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;
+}
+

+ 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);
+    }
+}

+ 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;
+//    }
+//}

+ 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));
+//    }
+//}

+ 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;
+}

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

@@ -18,18 +18,43 @@ public class SysUserQueryDTO implements Serializable {
     @Serial
     private static final long serialVersionUID = -262693810220247854L;
 
-    @Schema(description = "组织id")
-    private String orgId;
+    /**
+     * 账号
+     */
+    private String account;
+
+    /**
+     * 昵称
+     */
+    private String nickname;
+
+    /**
+     * 姓名
+     */
+    private String realname;
 
-    @Schema(description = "用户名")
-    private String username;
+    /**
+     * 英文名
+     */
+    private String englishName;
 
-    @Schema(description = "手机号")
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 手机号
+     */
     private String phone;
 
-    @Schema(description = "昵称")
-    private String nickname;
+    /**
+     * 工号
+     */
+    private String staffNumber;
 
-    @Schema(description = "用户状态")
-    private String status;
+    /**
+     * 部门ID
+     */
+    private String deptId;
 }

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

@@ -0,0 +1,37 @@
+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-10
+ */
+@Data
+public class SysUserResetPwdDTO<T> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 主键
+     */
+    @NotNull(message = "主键不能为空")
+    private T id;
+
+    /**
+     * 密码
+     */
+    @NotBlank(message = "密码不能为空")
+    @Size(max = 100, message = "密码长度不能超过100个字符")
+    private String password;
+
+}

+ 18 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysDeptMapper.java

@@ -0,0 +1,18 @@
+package cn.tr.module.sys.user.mapper;
+
+import cn.tr.module.sys.user.po.SysDeptPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 部门表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Mapper
+public interface SysDeptMapper extends BaseMapper<SysDeptPO> {
+
+}

+ 33 - 33
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysOrgMapper.java

@@ -1,33 +1,33 @@
-package cn.tr.module.sys.user.mapper;
-
-import cn.tr.module.sys.user.dto.SysOrgDTO;
-import cn.tr.module.sys.user.dto.SysOrgSmallDTO;
-import cn.tr.module.sys.user.dto.SysOrgTreeDTO;
-import cn.tr.module.sys.user.po.SysOrgPO;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-/**
- * @ClassName : SysOrgMapper
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-@Mapper
-public interface SysOrgMapper {
-    SysOrgMapper INSTANCE = Mappers.getMapper(SysOrgMapper.class);
-
-    List<SysOrgDTO> toSysOrgDTOList(List<SysOrgPO> source);
-
-    SysOrgDTO toSysOrgDTO(SysOrgPO source);
-
-    SysOrgSmallDTO convertSmall(SysOrgDTO source);
-
-    SysOrgPO toSysOrgPO(SysOrgDTO source);
-    
-    List<SysOrgTreeDTO> toSysOrgTree(List<SysOrgDTO> source);
-
-    SysOrgTreeDTO convertSysOrgTreeNode(SysOrgDTO source);
-}
+//package cn.tr.module.sys.user.mapper;
+//
+//import cn.tr.module.sys.user.dto.SysOrgDTO;
+//import cn.tr.module.sys.user.dto.SysOrgSmallDTO;
+//import cn.tr.module.sys.user.dto.SysOrgTreeDTO;
+//import cn.tr.module.sys.user.po.SysOrgPO;
+//import org.mapstruct.Mapper;
+//import org.mapstruct.factory.Mappers;
+//
+//import java.util.List;
+//
+///**
+// * @ClassName : SysOrgMapper
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//@Mapper
+//public interface SysOrgMapper {
+//    SysOrgMapper INSTANCE = Mappers.getMapper(SysOrgMapper.class);
+//
+//    List<SysOrgDTO> toSysOrgDTOList(List<SysOrgPO> source);
+//
+//    SysOrgDTO toSysOrgDTO(SysOrgPO source);
+//
+//    SysOrgSmallDTO convertSmall(SysOrgDTO source);
+//
+//    SysOrgPO toSysOrgPO(SysOrgDTO source);
+//
+//    List<SysOrgTreeDTO> toSysOrgTree(List<SysOrgDTO> source);
+//
+//    SysOrgTreeDTO convertSysOrgTreeNode(SysOrgDTO source);
+//}

+ 16 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysRoleDeptMapper.java

@@ -0,0 +1,16 @@
+package cn.tr.module.sys.user.mapper;
+
+import cn.tr.module.sys.user.po.SysRoleDeptPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色部门表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+public interface SysRoleDeptMapper extends BaseMapper<SysRoleDeptPO> {
+
+}

+ 40 - 40
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysUserMapper.java

@@ -1,40 +1,40 @@
-package cn.tr.module.sys.user.mapper;
-
-import cn.tr.module.sys.user.dto.SysUserEditDTO;
-import cn.tr.module.sys.user.dto.SysUserSmallDTO;
-import cn.tr.plugin.security.bo.UserLoginInfoBO;
-import cn.tr.module.sys.user.po.SysUserPO;
-import org.mapstruct.Mapper;
-import cn.tr.module.sys.user.dto.SysUserDTO;
-import org.mapstruct.Mapping;
-import org.mapstruct.Mappings;
-import org.mapstruct.factory.Mappers;
-import java.util.*;
-/**
- * @ClassName : SyUserMapper
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-@Mapper
-public interface SysUserMapper {
-    SysUserMapper INSTANCE = Mappers.getMapper(SysUserMapper.class);
-
-    @Mappings({
-            @Mapping(source = "id",target = "id"),
-            @Mapping(target = "builderField", ignore = true)}
-    )
-    List<UserLoginInfoBO> toUserLoginInfoDTOList(List<SysUserPO> source);
-
-    UserLoginInfoBO toUserLoginInfoDTO(SysUserPO source);
-
-    SysUserDTO toUserDTO(SysUserPO source);
-
-    SysUserPO toUserPO(SysUserEditDTO source);
-
-    List<SysUserDTO> toUserDTOList(List<SysUserPO> source);
-
-    List<SysUserSmallDTO> toUserSmallDTOList(List<SysUserDTO> source);
-
-    SysUserPO toUserPO(SysUserDTO source);
-}
+//package cn.tr.module.sys.user.mapper;
+//
+//import cn.tr.module.sys.user.dto.SysUserEditDTO;
+//import cn.tr.module.sys.user.dto.SysUserSmallDTO;
+//import cn.tr.module.sys.user.po.SysUserPO;
+//import cn.tr.plugin.security.bo.UserLoginInfoBO;
+//import org.mapstruct.Mapper;
+//import cn.tr.module.sys.user.dto.SysUserDTO;
+//import org.mapstruct.Mapping;
+//import org.mapstruct.Mappings;
+//import org.mapstruct.factory.Mappers;
+//import java.util.*;
+///**
+// * @ClassName : SyUserMapper
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//@Mapper
+//public interface SysUserMapper {
+//    SysUserMapper INSTANCE = Mappers.getMapper(SysUserMapper.class);
+//
+//    @Mappings({
+//            @Mapping(source = "id",target = "id"),
+//            @Mapping(target = "builderField", ignore = true)}
+//    )
+//    List<UserLoginInfoBO> toUserLoginInfoDTOList(List<SysUserPO> source);
+//
+//    UserLoginInfoBO toUserLoginInfoDTO(SysUserPO source);
+//
+//    SysUserDTO toUserDTO(SysUserPO source);
+//
+//    SysUserPO toUserPO(SysUserEditDTO source);
+//
+//    List<SysUserDTO> toUserDTOList(List<SysUserPO> source);
+//
+//    List<SysUserSmallDTO> toUserSmallDTOList(List<SysUserDTO> source);
+//
+//    SysUserPO toUserPO(SysUserDTO source);
+//}

+ 27 - 27
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/mapper/SysUserPortalMapper.java

@@ -1,27 +1,27 @@
-package cn.tr.module.sys.user.mapper;
-
-import cn.tr.module.sys.user.dto.SysUserPortalDTO;
-import cn.tr.module.sys.user.po.SysUserPortalPO;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-/**
- * @ClassName : SysUserPortalMapper
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-@Mapper
-public interface SysUserPortalMapper {
-    SysUserPortalMapper INSTANCE = Mappers.getMapper(SysUserPortalMapper.class);
-
-    List<SysUserPortalDTO> toSysUserPortalDTOList(List<SysUserPortalPO> source);
-
-    List<SysUserPortalPO> toSysUserPortalPOList(List<SysUserPortalDTO> source);
-
-    SysUserPortalDTO toSysUserPortalDTO(SysUserPortalPO source);
-
-    SysUserPortalPO toSysUserPortalPO(SysUserPortalDTO source);
-}
+//package cn.tr.module.sys.user.mapper;
+//
+//import cn.tr.module.sys.user.dto.SysUserPortalDTO;
+//import cn.tr.module.sys.user.po.SysUserPortalPO;
+//import org.mapstruct.Mapper;
+//import org.mapstruct.factory.Mappers;
+//
+//import java.util.List;
+//
+///**
+// * @ClassName : SysUserPortalMapper
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//@Mapper
+//public interface SysUserPortalMapper {
+//    SysUserPortalMapper INSTANCE = Mappers.getMapper(SysUserPortalMapper.class);
+//
+//    List<SysUserPortalDTO> toSysUserPortalDTOList(List<SysUserPortalPO> source);
+//
+//    List<SysUserPortalPO> toSysUserPortalPOList(List<SysUserPortalDTO> source);
+//
+//    SysUserPortalDTO toSysUserPortalDTO(SysUserPortalPO source);
+//
+//    SysUserPortalPO toSysUserPortalPO(SysUserPortalDTO source);
+//}

+ 129 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysDeptPO.java

@@ -0,0 +1,129 @@
+package cn.tr.module.sys.user.po;
+
+import cn.tr.module.common.entity.TenantGenericEntity;
+import cn.tr.module.common.menus.StatusEnum;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+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 lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 部门表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+//@TableName("sys_dept")
+public class SysDeptPO extends TenantGenericEntity<Long,String> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 父部门ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    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;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    private StatusEnum status;
+
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @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;
+
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private List<SysDeptPO> children;
+
+}

+ 100 - 78
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysMenuPO.java

@@ -1,128 +1,150 @@
 package cn.tr.module.sys.user.po;
 
-import cn.tr.core.pojo.BasePO;
-import cn.tr.plugin.mybatis.config.handler.PostgreSQLBooleanTypeHandler;
-import cn.tr.plugin.mybatis.config.handler.PostgresStringArrayTypeHandler;
-import cn.tr.plugin.mybatis.config.handler.StringListTypeHandler;
+import cn.tr.module.common.mybatisplus.handler.IntegerStringTypeHandler;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
+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 lombok.Data;
-import lombok.ToString;
-import java.io.Serial;
+
+import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 /**
- * 菜单对象 sys_menu
+ * <p>
+ * 菜单表
+ * </p>
  *
- * @author tr
- * @date 2022-11-23 15:34:37
+ * @author Kevin
+ * @since 2021-06-19
  */
-@Data
 @TableName(value = "sys_menu",autoResultMap = true)
-@ToString
-@Schema(description = "菜单对象")
-public class SysMenuPO extends BasePO {
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    @Schema(description = "主键")
-    private String id;
+@Data
+public class SysMenuPO implements Serializable {
 
-    @Schema(description = "父级id 顶级目录的父级id为0")
-    private String parentId;
+    private static final long serialVersionUID = 1L;
 
-    @Schema(description = "排序")
-    private Integer sort;
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
 
-    @Schema(description = "菜单类型 dir目录;menu菜单;button按钮")
+    /**
+     * 菜单类型 dir目录;menu菜单;button按钮
+     */
     private String menuType;
 
-    @Schema(description = "菜单名称")
-    private String name;
+    /**
+     * 菜单名称
+     */
+    private String menuName;
+
+    /**
+     * 上级菜单
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long parentId;
+//
+//    @TableField(exist = false)
+//    private String parentName;
 
-    @Schema(description = "路由地址")
+    /**
+     * 路由地址
+     */
     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缓存")
-    private Boolean keepalive;
-
-    @Schema(description = "是否外链 0否;1是")
-    private Boolean linkExternal;
-
-    @Schema(description = "是否显示 0隐藏;1显示")
-    private Boolean visible;
-
-    @Schema(description = "是否内嵌 0不内嵌;1、内嵌")
-    private Boolean frame;
+    /**
+     * 是否缓存 0缓存;1不缓存
+     */
+    private String keepalive;
 
-    @Schema(description = "外部链接")
-    private String linkUrl;
+    /**
+     * 是否外链 0是;1否
+     */
+    private String linkExternal;
 
-    @Schema(description = "备注")
-    private String remark;
+    /**
+     * 是否显示 0显示;1隐藏
+     */
+    private String visible;
 
-    @Schema(description = "状态 0正常;1停用")
-    @TableField(typeHandler = PostgreSQLBooleanTypeHandler.class)
-    private Boolean disable;
+    @Schema(description = "是否为租户菜单, 0、否(租户不可见) 1、是(租户可见)")
+    private Boolean tenantMenu;
 
-    // 新增字段
     /**
-     * 权限列表
-     * 存储该菜单关联的角色权限标识列表
+     * 是否内嵌 0内嵌;1不内嵌
      */
-    @TableField(typeHandler = PostgresStringArrayTypeHandler.class)
-    private List<String> authority;
+    private String frame;
 
     /**
-     * 是否不使用基础布局
-     * true表示不使用基础布局,false表示使用基础布局
+     * 外部链接
      */
-    private Boolean noBasicLayout;
+    private String linkUrl;
 
     /**
-     * 徽标
-     * 用于在菜单项上显示徽标文字
+     * 排序
      */
-    private String badge;
+    private Integer sort;
 
     /**
-     * 徽标类型
-     * 定义徽标的显示类型,如:primary、success、warning、danger等
+     * 备注
      */
-    private String badgeType;
+    private String remarks;
 
     /**
-     * 徽标变体
-     * 定义徽标的样式变体
+     * 状态 0正常;1停用
      */
-    private String badgeVariants;
-
-    @Schema(description = "0非快捷菜单;1快捷菜单")
-    private Integer quickMenu;
+    @TableField(typeHandler = IntegerStringTypeHandler.class)
+    private String status;
 
-    @Schema(description = "快捷菜单排序")
-    private String quickMenuSort;
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
 
-    @Schema(description = "快捷菜单图标")
-    private String quickMenuIcon;
+    /**
+     * 创建时间
+     */
+    @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;
 
-//    /**
-//     * 菜单是否可以匿名访问
-//     */
-//    private Boolean anonymous;
-//
-//    private Boolean hideChildrenInMenu;
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
 
-//    private Boolean   hideInMenu;
+//    @TableField(exist = false)
+//    private List<SysMenuPO> children;
 }

+ 107 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysPostPO.java

@@ -0,0 +1,107 @@
+package cn.tr.module.sys.user.po;
+
+import cn.tr.module.common.annotation.ExcelDict;
+import cn.tr.module.common.convert.ExcelDictConverter;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.*;
+import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+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 lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 岗位表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+@Data
+@ColumnWidth(15)
+@HeadRowHeight(15)
+@ContentRowHeight(15)
+@HeadStyle
+@HeadFontStyle(fontHeightInPoints = 12)
+@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
+@ContentFontStyle(fontHeightInPoints = 10)
+@ExcelIgnoreUnannotated
+public class SysPostPO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    /**
+     * 岗位编码
+     */
+    @ExcelProperty(value = "岗位编码", index = 1)
+    private String postCode;
+
+    /**
+     * 岗位名称
+     */
+    @ExcelProperty(value = "岗位名称", index = 0)
+    private String postName;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注", index = 4)
+    private String remarks;
+
+    /**
+     * 排序
+     */
+    @ExcelProperty(value = "排序", index = 2)
+    private Integer sort;
+
+    /**
+     * 状态 0正常;1停用
+     */
+    @ExcelProperty(value = "状态", index = 3, converter = ExcelDictConverter.class)
+    @ExcelDict("sys_status")
+    private String status;
+
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @ColumnWidth(20)
+    @ExcelProperty(value = "创建时间", index = 5)
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @ColumnWidth(20)
+    @ExcelProperty(value = "更新时间", index = 6)
+    private Date updateTime;
+
+}

+ 38 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysRoleDeptPO.java

@@ -0,0 +1,38 @@
+package cn.tr.module.sys.user.po;
+
+import cn.tr.module.common.entity.TenantGenericEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 角色部门表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+@TableName("sys_role_dept")
+public class SysRoleDeptPO extends TenantGenericEntity<Long,String> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 角色ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long roleId;
+
+    /**
+     * 部门ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long deptId;
+
+
+}

+ 17 - 7
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysRoleMenuPO.java

@@ -2,6 +2,8 @@ package cn.tr.module.sys.user.po;
 
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import lombok.Data;
 import java.io.Serial;
 
@@ -16,13 +18,21 @@ import java.io.Serial;
 public class SysRoleMenuPO {
     @Serial
     private static final long serialVersionUID = 1L;
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
 
-    @TableId
-    private String id;
+    /**
+     * 角色ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long roleId;
 
-    /** 角色id */
-    private String roleId;
-
-    /** 菜单id */
-    private String menuId;
+    /**
+     * 菜单ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long menuId;
 }

+ 57 - 33
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysRolePO.java

@@ -1,15 +1,19 @@
 package cn.tr.module.sys.user.po;
 
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.core.pojo.TenantPO;
-import cn.tr.plugin.mybatis.config.handler.StringListTypeHandler;
+import cn.tr.module.common.annotation.ExcelDict;
+import cn.tr.module.common.convert.ExcelDictConverter;
+import cn.tr.module.common.entity.TenantGenericEntity;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.*;
+import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
 import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import cn.tr.module.common.mybatisplus.handler.IntegerStringTypeHandler;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import lombok.Data;
-import org.apache.ibatis.type.JdbcType;
-import java.io.Serial;
-import java.util.*;
+import java.io.Serializable;
 
 /**
  * @ClassName : SysRolePO
@@ -18,40 +22,60 @@ import java.util.*;
  * @Date: 2023年04月03日
  */
 @Data
+@ColumnWidth(15)
+@HeadRowHeight(15)
+@ContentRowHeight(15)
+@HeadStyle
+@HeadFontStyle(fontHeightInPoints = 12)
+@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
+@ContentFontStyle(fontHeightInPoints = 10)
+@ExcelIgnoreUnannotated
 @TableName("sys_role")
-public class SysRolePO extends TenantPO {
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    @TableId
-    /** 角色id */
-    private String id;
+public class SysRolePO extends TenantGenericEntity<Long,String> implements Serializable {
 
-    /** 角色编码 */
-    private String code;
-
-    /** 角色名称 */
-    private String name;
+    private static final long serialVersionUID = 1L;
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
 
-//    /** 数据范围 1、全部数据权限;2、自定义数据权限;3、本部门数据权限;4、本部门及以下数据权限 */
-//    private String dataScope;
+    /**
+     * 角色编码
+     */
+    @ExcelProperty(value = "角色编码", index = 1)
+    private String roleCode;
 
-    /** 数据组织id */
-    @TableField(typeHandler = StringListTypeHandler.class,jdbcType = JdbcType.VARCHAR)
-    private List<String> orgIds;
+    /**
+     * 角色名称
+     */
+    @ExcelProperty(value = "角色名称", index = 0)
+    private String roleName;
 
     /**
-     * {@link CreateEnum}
+     * 数据范围 1全部数据权限;2自定数据权限;3本部门数据权限;4本部门及以下数据权限
      */
-    /** 角色类型 sys、系统角色 custom、自定义角色 */
-    private String type;
+    @ExcelProperty(value = "数据范围", index = 2, converter = ExcelDictConverter.class)
+    @ExcelDict("sys_data_scope")
+    private String dataScope;
 
-    /** 备注 */
-    private String remark;
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注", index = 5)
+    private String remarks;
 
-    /** 排序 */
+    /**
+     * 排序
+     */
+    @ExcelProperty(value = "排序", index = 3)
     private Integer sort;
 
-    /** 是否启用 0、启用 1、关闭 */
-    private Boolean disable;
-}
+    /**
+     * 状态 0正常;1停用
+     */
+    @ExcelProperty(value = "状态", index = 4, converter = ExcelDictConverter.class)
+    @ExcelDict("sys_status")
+    @TableField(typeHandler = IntegerStringTypeHandler.class)
+    private String status;
+}

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

@@ -1,110 +1,237 @@
 package cn.tr.module.sys.user.po;
 
-import cn.tr.core.pojo.TenantPO;
-import cn.tr.module.sys.user.enums.UserStatusEnum;
-import cn.tr.plugin.mybatis.config.handler.StringListTypeHandler;
+import cn.tr.module.common.annotation.ExcelDict;
+import cn.tr.module.common.convert.ExcelDictConverter;
+import cn.tr.module.common.entity.TenantGenericEntity;
+import cn.tr.module.common.menus.SexEnum;
+import cn.tr.module.common.mybatisplus.handler.IntegerStringTypeHandler;
+import cn.tr.module.common.mybatisplus.handler.TenantNameHandler;
+import cn.tr.plugin.mybatis.config.handler.PostgreSQLBooleanTypeHandler;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.*;
+import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.apache.ibatis.type.JdbcType;
+import lombok.Getter;
+
 import java.util.Date;
-import java.io.Serial;
-import java.util.*;
+import java.util.List;
 
 /**
- * @ClassName : SysUserPO
- * @Description : 系统用户实体类
- * @Author : LF
- * @Date: 2023年03月31日
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
 @Data
+@ColumnWidth(15)
+@HeadRowHeight(15)
+@ContentRowHeight(15)
+@HeadStyle
+@HeadFontStyle(fontHeightInPoints = 12)
+@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
+@ContentFontStyle(fontHeightInPoints = 10)
+@ExcelIgnoreUnannotated
 @TableName(value = "sys_user",autoResultMap = true)
-@EqualsAndHashCode(callSuper = true)
-public class SysUserPO extends TenantPO {
-    @Serial
-    private static final long serialVersionUID = -588007107794525494L;
+public class SysUserPO extends TenantGenericEntity<Long,Long> {
 
-    /** 用户主键Id */
+    private static final long serialVersionUID = 1L;
+//
     @TableId
-    private String id;
-
-    /** 用户名 */
-    @TableField(updateStrategy = FieldStrategy.NEVER)
-    private String username;
+    private Long id;
+    /**
+     * 账号
+     */
+    @ExcelProperty(value = "账号", index = 0)
+    private String account;
 
     /**
-     * {@link cn.tr.core.utils.PswUtils#encryptPassword(String)} 加密
-     * {@link cn.tr.core.utils.PswUtils#matchesPassword(String, String)} (String)} 匹配密码
+     * 密码
      */
-    /** 密码 */
+
+    @JsonIgnore
     private String password;
 
-    /** 昵称 */
+    /**
+     * 修改密码标记 0未修改;1已修改
+     */
+
+    @JsonIgnore
+    private String pswModified;
+
+    /**
+     * 昵称
+     */
+    @ExcelProperty(value = "昵称", index = 2)
     private String nickname;
 
-    /** 性别 */
-    private String gender;
+    /**
+     * 姓名
+     */
+    @ExcelProperty(value = "姓名", index = 4)
+    private String realname;
 
-    /** 部门id */
-    @TableField(exist = false)
-    private String orgId;
+    /**
+     * 英文名
+     */
+    @ExcelProperty(value = "英文名", index = 5)
+    private String englishName;
 
-    /** 手机号 */
-    private String phone;
+    /**
+     * 头像
+     */
+    private String avatar;
 
-    /** 邮箱地址 */
+    /**
+     * 邮箱
+     */
+    @ExcelProperty(value = "邮箱", index = 6)
     private String email;
 
+    /**
+     * 手机号
+     */
+    @ExcelProperty(value = "手机号", index = 7)
+    private String phone;
 
-    /** 岗位id */
-    @TableField(typeHandler = StringListTypeHandler.class,exist = false)
-    private List<String> postIds;
+    /**
+     * 工号
+     */
+    @ExcelProperty(value = "工号", index = 8)
+    private String staffNumber;
 
-    /** 用户头像 */
-    private String avatar;
+    /**
+     * 生日
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+    @ColumnWidth(20)
+    @ExcelProperty(value = "生日", index = 9)
+    private Date birthday;
+
+    /**
+     * 性别 1男;2女;3未知
+     */
+//    @ExcelProperty(value = "性别", index = 3, converter = ExcelDictConverter.class)
+//    @ExcelDict("sys_sex")
+    private SexEnum sex;
+
+    /**
+     * 部门ID
+     */
+    private String deptId;
+
+
+    /**
+     * 排序
+     */
+    @ExcelProperty(value = "排序", index = 11)
+    private Integer sort;
 
     /**
-     * 用户签名
+     * 备注
      */
-    private String signature;
+    @ExcelProperty(value = "备注", index = 13)
+    private String remarks;
 
     /**
-     * {@link UserStatusEnum#getValue()}
+     * 状态 0正常;1停用
      */
-    /** 用户状态 */
+    @ExcelProperty(value = "状态", index = 12, converter = ExcelDictConverter.class)
+    @ExcelDict("sys_status")
+    @TableField(typeHandler = IntegerStringTypeHandler.class)
     private String status;
 
-    /** 最后登录IP */
-    private String lastLoginIp;
+    /**
+     * 删除标记 0存在;1删除
+     */
+    @TableLogic(value = "0",delval = "1")
+    private String delFlag;
 
-    /** 最后登录地址 */
-    private String lastLoginAddress;
+    /**
+     * 创建人
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
 
-    /** 最后登录时间 */
-    private Date lastLoginDate;
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
 
-    /** 备注 */
-    private String remark;
+    /**
+     * 更新人
+     */
+    @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(typeHandler = PostgreSQLBooleanTypeHandler.class)
+    private Boolean isSys;
+
+    @TableField(typeHandler = PostgreSQLBooleanTypeHandler.class)
+    private Boolean pswNeedReset;
+
+    @TableField
+    @Schema(description = "最后修改密码时间")
+    private Date lastModifyPswTime;
+
+    @Schema(description = "小程序openId")
     private String openId;
 
-    /** 删除标记 */
-    @TableLogic
-    @TableField(jdbcType = JdbcType.TINYINT)
-    private Boolean deleted;
-}
+    @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;
+}

+ 41 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/po/SysUserPostPO.java

@@ -0,0 +1,41 @@
+package cn.tr.module.sys.user.po;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 用户岗位表
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Data
+public class SysUserPostPO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    /**
+     * 用户ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
+
+    /**
+     * 岗位ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long postId;
+
+
+}

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

@@ -1,7 +1,10 @@
 package cn.tr.module.sys.user.po;
 
+import cn.tr.module.common.entity.TenantGenericEntity;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import lombok.Data;
 import java.io.Serial;
 import java.io.Serializable;
@@ -14,16 +17,19 @@ import java.io.Serializable;
  */
 @Data
 @TableName("sys_user_role")
-public class SysUserRolePO implements Serializable {
+public class SysUserRolePO extends TenantGenericEntity<Long,String> implements Serializable  {
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @TableId
-    private String id;
+    /**
+     * 用户编号
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long userId;
 
-    /** 角色id */
-    private String roleId;
-
-    /** 用户id */
-    private String userId;
+    /**
+     * 角色编号
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long roleId;
 }

+ 41 - 41
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/provider/SysUserNickNameProvider.java

@@ -1,41 +1,41 @@
-package cn.tr.module.sys.user.provider;
-
-import cn.hutool.core.lang.Pair;
-import cn.tr.core.utils.UserUtil;
-import cn.tr.module.api.sys.user.SysUserApi;
-import cn.tr.module.sys.oauth2.service.CurrentUserService;
-import cn.tr.module.sys.user.service.ISysUserService;
-import jakarta.annotation.PostConstruct;
-import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Component;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @ClassName : SysUserNickNameProvider
- * @Description :
- * @Author : LF
- * @Date: 2023年09月05日
- */
-@Component
-@AllArgsConstructor
-public class SysUserNickNameProvider implements SysUserApi {
-    private final ISysUserService userService;
-    private final CurrentUserService currentUserService;
-
-    @PostConstruct
-    public void init(){
-        UserUtil.userNickNameSupplier=userService::selectNickNameAndAvatarById;
-    }
-
-    @Override
-    public List<Pair<String, String>> selectAllUserIdAndNickName() {
-        return userService.selectAllUserIdAndNickName();
-    }
-
-    @Override
-    public Collection<String> findUserPermission(String userId) {
-        return currentUserService.currentUserPermission(userId);
-    }
-}
+//package cn.tr.module.sys.user.provider;
+//
+//import cn.hutool.core.lang.Pair;
+//import cn.tr.core.utils.UserUtil;
+//import cn.tr.module.api.sys.user.SysUserApi;
+//import cn.tr.module.sys.oauth2.service.CurrentUserService;
+//import cn.tr.module.sys.user.service.impl.ISysUserService;
+//import jakarta.annotation.PostConstruct;
+//import lombok.AllArgsConstructor;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.Collection;
+//import java.util.List;
+//
+///**
+// * @ClassName : SysUserNickNameProvider
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年09月05日
+// */
+//@Component
+//@AllArgsConstructor
+//public class SysUserNickNameProvider implements SysUserApi {
+//    private final ISysUserService userService;
+//    private final CurrentUserService currentUserService;
+//
+//    @PostConstruct
+//    public void init(){
+//        UserUtil.userNickNameSupplier=userService::selectNickNameAndAvatarById;
+//    }
+//
+//    @Override
+//    public List<Pair<String, String>> selectAllUserIdAndNickName() {
+//        return userService.selectAllUserIdAndNickName();
+//    }
+//
+//    @Override
+//    public Collection<String> findUserPermission(String userId) {
+//        return currentUserService.currentUserPermission(userId);
+//    }
+//}

+ 18 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysDeptRepository.java

@@ -0,0 +1,18 @@
+package cn.tr.module.sys.user.repository;
+
+import cn.tr.module.sys.user.po.SysDeptPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 部门表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Mapper
+public interface SysDeptRepository extends BaseMapper<SysDeptPO> {
+
+}

+ 0 - 9
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysMenuRepository.java

@@ -13,14 +13,5 @@ import java.util.*;
  */
 @Mapper
 public interface SysMenuRepository extends BaseMapper<SysMenuPO> {
-    /**
-     * 找到角色下的所有菜单信息
-     * @param roleId 角色id
-     */
-    List<SysMenuPO> findAllMenuByRoleId(@Param("roleId") String roleId);
 
-    /**
-     * 根据门户id查询所有的菜单信息
-     */
-    List<SysMenuPO> findAllMenuByPortalId(String portalId);
 }

+ 16 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysPostRepository.java

@@ -0,0 +1,16 @@
+package cn.tr.module.sys.user.repository;
+
+import cn.tr.module.sys.user.po.SysPostPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 岗位表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+public interface SysPostRepository extends BaseMapper<SysPostPO> {
+
+}

+ 16 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysRoleDeptRepository.java

@@ -0,0 +1,16 @@
+package cn.tr.module.sys.user.repository;
+
+import cn.tr.module.sys.user.po.SysRoleDeptPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色部门表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+public interface SysRoleDeptRepository extends BaseMapper<SysRoleDeptPO> {
+
+}

+ 16 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/repository/SysUserPostRepository.java

@@ -0,0 +1,16 @@
+package cn.tr.module.sys.user.repository;
+
+import cn.tr.module.sys.user.po.SysUserPostPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 用户岗位表 Mapper 接口
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+public interface SysUserPostRepository extends BaseMapper<SysUserPostPO> {
+
+}

+ 215 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysDeptServiceImpl.java

@@ -0,0 +1,215 @@
+package cn.tr.module.sys.user.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.lang.tree.TreeNode;
+import cn.hutool.core.lang.tree.TreeUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.tr.module.common.menus.StatusEnum;
+import cn.tr.module.sys.exception.CustomException;
+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.mapper.SysDeptMapper;
+import cn.tr.module.sys.user.po.SysDeptPO;
+import cn.tr.module.sys.user.po.SysRoleDeptPO;
+import cn.tr.module.sys.user.po.SysUserPO;
+import cn.tr.module.sys.user.repository.SysUserRepository;
+import cn.tr.module.sys.user.service.ISysDeptService;
+import cn.tr.module.sys.user.service.ISysRoleDeptService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+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 org.springframework.util.CollectionUtils;
+
+import jakarta.annotation.Resource;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 部门表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Service
+public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDeptPO> implements ISysDeptService {
+
+    @Resource
+    private SysUserRepository sysUserRepository;
+
+    @Autowired(required = false)  // 使用自动装配并允许为空,避免启动时立即创建依赖
+    @Lazy  // 使用懒加载避免循环依赖
+    private ISysRoleDeptService sysRoleDeptService;
+
+    @Override
+    public IPage<SysDeptPO> page(Page reqPage, SysDeptQueryDTO req) {
+        LambdaQueryWrapper<SysDeptPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(Objects.nonNull(req.getParentId()), SysDeptPO::getParentId, req.getParentId());
+        queryWrapper.like(StrUtil.isNotBlank(req.getDeptName()), SysDeptPO::getDeptName, req.getDeptName());
+        queryWrapper.like(StrUtil.isNotBlank(req.getDeptFullname()), SysDeptPO::getDeptFullname, req.getDeptFullname());
+        queryWrapper.orderByAsc(SysDeptPO::getSort);
+        return this.page(reqPage, queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void add(SysDeptAddDTO req) {
+        if (!this.checkUniqueDeptName(req.getDeptName(), null)) {
+            throw new CustomException("部门名称已存在");
+        }
+        SysDeptPO entity = BeanUtil.copyProperties(req, SysDeptPO.class);
+        if (Objects.isNull(req.getParentId())) {
+            entity.setParentId(0L);
+            entity.setAncestors(entity.getParentId().toString());
+        } else {
+            SysDeptPO parent = this.getById(req.getParentId());
+            entity.setAncestors(parent.getAncestors() + "," + entity.getParentId().toString());
+        }
+        this.save(entity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void edit(SysDeptEditDTO req) {
+        if (!this.checkUniqueDeptName(req.getDeptName(), req.getId())) {
+            throw new CustomException("部门名称已存在");
+        }
+        if (req.getStatus().equals(StatusEnum.NO.getValue()) &&
+                this.list(Wrappers.lambdaQuery(SysDeptPO.class)
+                        .eq(SysDeptPO::getStatus, StatusEnum.YES)
+                        .apply("find_in_set({0}, ancestors)", req.getId())).size() > 0) {
+            throw new CustomException("该部门存在未停用的下级部门");
+        }
+        SysDeptPO entity = BeanUtil.copyProperties(req, SysDeptPO.class);
+        if (Objects.isNull(req.getParentId())) {
+            entity.setParentId(0L);
+            entity.setAncestors(entity.getParentId().toString());
+        } else {
+            SysDeptPO parent = this.getById(req.getParentId());
+            entity.setAncestors(parent.getAncestors() + "," + entity.getParentId().toString());
+        }
+        SysDeptPO sysDept = this.getById(req.getId());
+        // 更新子节点的祖级列表
+        List<SysDeptPO> sysDeptList = this.list(Wrappers.lambdaQuery(SysDeptPO.class)
+                .apply("find_in_set({0}, ancestors)", req.getId()));
+        sysDeptList.forEach(item -> {
+            item.setAncestors(item.getAncestors().replaceFirst(sysDept.getAncestors(), entity.getAncestors()));
+        });
+        this.updateById(entity);
+        // 启用该部门,则启用该部门的所有上级部门
+        List<SysDeptPO> parentList = Arrays.asList(entity.getAncestors().split(",")).stream().map(item -> {
+            SysDeptPO sysDeptTemp = new SysDeptPO();
+            sysDeptTemp.setId(Long.parseLong(item));
+            sysDeptTemp.setStatus(StatusEnum.YES);
+            return sysDeptTemp;
+        }).collect(Collectors.toList());
+        this.updateBatchById(parentList);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void remove(String ids) {
+        List<String> idList = Arrays.asList(ids.split(","));
+        idList.forEach(item -> {
+            SysDeptPO sysDept = this.getById(item);
+            SysDeptPO sysDeptChild = this.getOne(Wrappers.lambdaQuery(SysDeptPO.class).eq(SysDeptPO::getParentId, item));
+            if (Objects.nonNull(sysDeptChild)) {
+                throw new CustomException(String.format("部门【%s】存在下级部门,无法删除", sysDept.getDeptName()));
+            }
+            SysUserPO sysUser = sysUserRepository.selectOne(
+                    Wrappers.lambdaQuery(SysUserPO.class).eq(SysUserPO::getDeptId, item));
+            if (Objects.nonNull(sysUser)) {
+                throw new CustomException(String.format("部门【%s】存在用户,无法删除", sysDept.getDeptName()));
+            }
+            if (sysRoleDeptService != null) {  // 检查服务是否可用
+                SysRoleDeptPO sysRoleDept = sysRoleDeptService.getOne(Wrappers.lambdaQuery(SysRoleDeptPO.class).eq(SysRoleDeptPO::getDeptId, item));
+                if (Objects.nonNull(sysRoleDept)) {
+                    throw new CustomException(String.format("部门【%s】已被使用,无法删除", sysDept.getDeptName()));
+                }
+            }
+        });
+        this.removeByIds(Arrays.asList(ids.split(",")));
+    }
+
+    @Override
+    public SysDeptPO view(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<Tree<String>> listDeptTree() {
+        List<SysDeptPO> sysDeptList = this.list();
+        List treeNodeList = sysDeptList.stream().map(item -> {
+            TreeNode treeNode = new TreeNode();
+            treeNode.setId(item.getId().toString());
+            treeNode.setName(item.getDeptName());
+            treeNode.setParentId(item.getParentId().toString());
+            treeNode.setWeight(item.getSort());
+            return treeNode;
+        }).collect(Collectors.toList());
+        List<Tree<String>> treeList = TreeUtil.build(treeNodeList, "0");
+        return CollectionUtils.isEmpty(treeList) ? Lists.newArrayList() : treeList;
+    }
+
+    @Override
+    public List<Tree<String>> selectDeptTreeAndExcludeNode(String nodeId) {
+        List<SysDeptPO> sysDeptList = this.list();
+        if (StrUtil.isNotBlank(nodeId)) {
+            Iterator<SysDeptPO> it = sysDeptList.iterator();
+            while (it.hasNext()) {
+                SysDeptPO sysDept = it.next();
+                if (sysDept.getId().toString().equals(nodeId) || Arrays.asList(sysDept.getAncestors().split(",")).contains(nodeId)) {
+                    it.remove();
+                }
+            }
+        }
+        List treeNodeList = sysDeptList.stream().map(item -> {
+            TreeNode treeNode = new TreeNode();
+            treeNode.setId(item.getId().toString());
+            treeNode.setName(item.getDeptName());
+            treeNode.setParentId(item.getParentId().toString());
+            treeNode.setWeight(item.getSort());
+            return treeNode;
+        }).collect(Collectors.toList());
+        List<Tree<String>> treeList = TreeUtil.build(treeNodeList, "0");
+        return CollectionUtils.isEmpty(treeList) ? Lists.newArrayList() : treeList;
+    }
+
+    @Override
+    public List<Tree<String>> selectDeptTree() {
+        List<SysDeptPO> sysDeptList = this.list();
+        List treeNodeList = sysDeptList.stream().map(item -> {
+            TreeNode treeNode = new TreeNode();
+            treeNode.setId(item.getId().toString());
+            treeNode.setName(item.getDeptName());
+            treeNode.setParentId(item.getParentId().toString());
+            treeNode.setWeight(item.getSort());
+            return treeNode;
+        }).collect(Collectors.toList());
+        List<Tree<String>> treeList = TreeUtil.build(treeNodeList, "0");
+        return CollectionUtils.isEmpty(treeList) ? Lists.newArrayList() : treeList;
+    }
+
+    private Boolean checkUniqueDeptName(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
+        }
+        id = Objects.isNull(id) ? -1L : id;
+        SysDeptPO entity = this.getOne(Wrappers.lambdaQuery(SysDeptPO.class).eq(SysDeptPO::getDeptName, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
+    }
+
+}

+ 220 - 184
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysMenuServiceImpl.java

@@ -1,252 +1,288 @@
 package cn.tr.module.sys.user.service.impl;
 
-import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.lang.Pair;
-import cn.hutool.core.lang.Tuple;
-import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.lang.tree.TreeNode;
+import cn.hutool.core.lang.tree.TreeUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.tree.TreeBuilder;
-import cn.tr.core.tree.TreeNode;
-import cn.tr.module.sys.user.mapper.SysMenuMapper;
-import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
-import cn.tr.module.sys.tenant.service.ISysTenantService;
-import cn.tr.module.sys.user.dto.SysMenuDTO;
+import cn.tr.module.common.menus.LinkExternalEnum;
+import cn.tr.module.common.menus.MenuTypeEnum;
+import cn.tr.module.common.menus.StatusEnum;
+import cn.tr.module.common.utils.TenantUtil;
+import cn.tr.module.sys.exception.CustomException;
+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.dto.SysRoleDTO;
-import cn.tr.core.enums.CreateEnum;
-import cn.tr.module.sys.user.po.SysMenuPO;
+import cn.tr.module.sys.user.dto.SysUserDTO;
+import cn.tr.module.sys.user.po.*;
 import cn.tr.module.sys.user.repository.SysMenuRepository;
 import cn.tr.module.sys.user.service.*;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import jakarta.annotation.Resource;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- * @ClassName : SysMenuServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
+ * <p>
+ * 菜单表  服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-19
  */
 @Service
-public class SysMenuServiceImpl extends ServiceImpl<SysMenuRepository,SysMenuPO> implements ISysMenuService {
-    @Autowired
-    private SysMenuRepository menuRepository;
-    @Autowired
-    @Lazy
-    private ISysRoleMenuService roleMenuService;
+public class SysMenuServiceImpl extends ServiceImpl<SysMenuRepository, SysMenuPO> implements ISysMenuService {
 
     @Autowired
-    @Lazy
-    private ISysUserRoleService userRoleService;
+    private ISysUserRoleService sysUserRoleService;
 
     @Autowired
-    @Lazy
-    private ISysTenantPackageMenuService tenantPackageMenuService;
+    private ISysRoleMenuService sysRoleMenuService;
 
     @Autowired
     @Lazy
-    private ISysPortalMenuService portalMenuService;
+    private ISysRoleService sysRoleService;
 
     @Autowired
     @Lazy
-    private ISysTenantService tenantService;
-
-    @Autowired
-    @Lazy
-    private ISysMenuService self;
-
-    @Value("${tr.tenant.enable}")
-    private Boolean tenantEnable;
-
-
-    @Override
-    public List<SysMenuDTO> selectSysMenuList(SysMenuQueryDTO query) {
-        List<SysMenuDTO> selectResult =
-        SysMenuMapper.INSTANCE.toSysMenuDTOList( menuRepository.selectList(new LambdaQueryWrapper<SysMenuPO>()
-                .in(CollectionUtil.isNotEmpty(query.getTenantMenuIds()),SysMenuPO::getId,query.getTenantMenuIds())
-                .like(StrUtil.isNotEmpty(query.getName()), SysMenuPO::getName, query.getName())
-                .eq(ObjectUtil.isNotNull(query.getDisable()), SysMenuPO::getDisable, query.getDisable())
-                .in(CollectionUtil.isNotEmpty(query.getMenuType()), SysMenuPO::getMenuType, query.getMenuType())
-                .eq(ObjectUtil.isNotNull(query.getParentId()), SysMenuPO::getParentId, query.getParentId())));
-        //得到的结果与当期租户取交集
-        return selectResult;
-    }
+    private ISysUserService sysUserService;
 
     @Override
-    public SysMenuDTO selectSysMenuById(String id) {
-        return SysMenuMapper.INSTANCE.toSysMenuDTO(menuRepository.selectById(id));
+    public IPage<SysMenuPO> page(Page reqPage, SysMenuQueryDTO req) {
+        LambdaQueryWrapper<SysMenuPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(Objects.nonNull(req.getParentId()), SysMenuPO::getParentId, req.getParentId());
+        queryWrapper.eq(!TenantUtil.isTuoRen(), SysMenuPO::getTenantMenu, true);
+        queryWrapper.like(StrUtil.isNotBlank(req.getMenuName()), SysMenuPO::getMenuName, req.getMenuName());
+        queryWrapper.orderByAsc(SysMenuPO::getSort);
+        return this.page(reqPage, queryWrapper);
     }
 
-    @Override
-    public Tuple selectNameById(String menuId) {
-        SysMenuPO menu = getById(menuId);
-        if (menu == null){
-            return null;
-        }
-        return new Tuple(menu.getName(),menu.getMenuType());
-    }
-
-
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean updateSysMenuById(SysMenuDTO source) {
-        //判断是否是快捷菜单
-        if (ObjectUtil.isNotNull(source.getQuickMenu()) && source.getQuickMenu() == 1) {
-            //如果是快捷菜单修改时添加快捷菜单图片和快捷菜单排序
-            source.setQuickMenuIcon(source.getQuickMenuIcon());
-            source.setQuickMenuSort(source.getQuickMenuSort());
-        }
-        TreeBuilder.validateNode(source, TreeBuilder.buildTree(self.findAllMenu()));
-        boolean result = menuRepository.updateById(SysMenuMapper.INSTANCE.toSysMenuPO(source))!=0;
-        if (result) {
-            refreshCache(Collections.singleton(source.getId()));
-        }
-        return result;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean insertSysMenu(SysMenuDTO source) {
-        //判断是否是快捷菜单
-        if (ObjectUtil.isNotNull(source.getQuickMenu()) && source.getQuickMenu() == 1) {
-            //如果是快捷菜单添加时添加快捷菜单图片和快捷菜单排序
-            source.setQuickMenuIcon(source.getQuickMenuIcon());
-            source.setQuickMenuSort(source.getQuickMenuSort());
+    public void add(SysMenuAddDTO req) {
+        // 当前节点为目录
+        if (Objects.nonNull(req.getParentId()) && Objects.equals(req.getMenuType(), MenuTypeEnum.DIR.getCode())) {
+            SysMenuPO sysMenuParent = this.getById(req.getParentId());
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.MENU.getCode())) {
+                throw new CustomException("上级节点不允许为菜单");
+            }
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.BUTTON.getCode())) {
+                throw new CustomException("上级节点不允许为按钮");
+            }
         }
-        boolean result = menuRepository.insert(SysMenuMapper.INSTANCE.toSysMenuPO(source))!=0;
-        if (result) {
-            refreshCache(Collections.singleton(source.getId()));
+        // 当前节点为菜单
+        if (Objects.nonNull(req.getParentId()) && Objects.equals(req.getMenuType(), MenuTypeEnum.MENU.getCode())) {
+            SysMenuPO sysMenuParent = this.getById(req.getParentId());
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.MENU.getCode())) {
+                throw new CustomException("上级节点不允许为菜单");
+            }
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.BUTTON.getCode())) {
+                throw new CustomException("上级节点不允许为按钮");
+            }
         }
-        return result;
-    }
-
-    @Override
-    public boolean insertBatchSysMenu(List<SysMenuDTO> source) {
-        boolean result = this.saveBatch(SysMenuMapper.INSTANCE.toSysMenuPOList(source));
-        if (result) {
-            refreshCache(source.stream().map(SysMenuDTO::getId).collect(Collectors.toSet()));
+        SysMenuPO entity = BeanUtil.copyProperties(req, SysMenuPO.class);
+        if (Objects.isNull(req.getParentId())) {
+            entity.setParentId(0L);
         }
-        return result;
+        this.save(entity);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public int deleteSysMenuByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+    public void edit(SysMenuEditDTO req) {
+        // 当前节点为目录
+        if (Objects.nonNull(req.getParentId()) && Objects.equals(req.getMenuType(), MenuTypeEnum.DIR.getCode())) {
+            SysMenuPO sysMenuParent = this.getById(req.getParentId());
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.MENU.getCode())) {
+                throw new CustomException("上级节点不允许为菜单");
+            }
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.BUTTON.getCode())) {
+                throw new CustomException("上级节点不允许为按钮");
+            }
         }
-        List<SysMenuDTO> treeMenu = buildTree(self.findAllMenu());
-        List<SysMenuDTO> flatTree = flatTree(treeMenu);
-        Map<String, SysMenuDTO> menuMapById = flatTree.stream()
-                .collect(Collectors.groupingBy(SysMenuDTO::getId, Collectors.collectingAndThen(Collectors.toList(), CollUtil::getFirst)));
-        Set<String> allDelMenuIds = new HashSet<>();
-        for (String id : ids) {
-            SysMenuDTO existMenu = menuMapById.get(id);
-            findAllChildrenId(existMenu,allDelMenuIds);
+        // 当前节点为菜单
+        if (Objects.nonNull(req.getParentId()) && Objects.equals(req.getMenuType(), MenuTypeEnum.MENU.getCode())) {
+            SysMenuPO sysMenuParent = this.getById(req.getParentId());
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.MENU.getCode())) {
+                throw new CustomException("上级节点不允许为菜单");
+            }
+            if (Objects.equals(sysMenuParent.getMenuType(), MenuTypeEnum.BUTTON.getCode())) {
+                throw new CustomException("上级节点不允许为按钮");
+            }
         }
-        if (CollectionUtil.isEmpty(allDelMenuIds)) {
-            return CollectionUtil.size(allDelMenuIds);
+        SysMenuPO entity = BeanUtil.copyProperties(req, SysMenuPO.class);
+        if (Objects.isNull(req.getParentId())) {
+            entity.setParentId(0L);
         }
-        List<SysMenuPO> menus = menuRepository.selectBatchIds(allDelMenuIds);
-        if(CollectionUtil.isEmpty(menus)){
-            return CollectionUtil.size(allDelMenuIds);
+        if (entity.getMenuType().equals(MenuTypeEnum.DIR.getCode())) {
+            entity.setComponent("");
+            entity.setPermission("");
+            entity.setKeepalive("");
+            entity.setLinkExternal("");
+            entity.setFrame("");
+            entity.setLinkUrl("");
         }
-        //删除相应缓存
-        Set<String> roleIds = roleMenuService.findRoleByMenuId(allDelMenuIds,false);
-        if(CollectionUtil.isNotEmpty(roleIds)){
-            roleIds.forEach(roleMenuService::delRoleMenusCache);
+        if (entity.getMenuType().equals(MenuTypeEnum.MENU.getCode())) {
+            entity.setPermission("");
+            if (entity.getLinkExternal().equals(LinkExternalEnum.NO.getCode())) {
+                entity.setFrame("");
+                entity.setLinkUrl("");
+            }
         }
-        Set<String> packageIds = tenantPackageMenuService.findPackageIdByMenuId(allDelMenuIds,false);
-        if(CollectionUtil.isNotEmpty(packageIds)){
-            packageIds.forEach(tenantPackageMenuService::delCacheMenuIdByPackageId);
+        if (entity.getMenuType().equals(MenuTypeEnum.BUTTON.getCode())) {
+            entity.setIcon("");
+            entity.setRoutePath("");
+            entity.setComponent("");
+            entity.setVisible("");
+            entity.setKeepalive("");
+            entity.setLinkExternal("");
+            entity.setFrame("");
+            entity.setLinkUrl("");
         }
-        refreshCache(allDelMenuIds);
-        return menuRepository.deleteBatchIds(allDelMenuIds);
+        this.updateById(entity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void remove(String ids) {
+        List<String> idList = Arrays.asList(ids.split(","));
+        idList.forEach(item -> {
+            SysMenuPO sysMenu = this.getById(item);
+            SysMenuPO sysMenuChild = this.getOne(Wrappers.lambdaQuery(SysMenuPO.class).eq(SysMenuPO::getParentId, item));
+            if (Objects.nonNull(sysMenuChild)) {
+                throw new CustomException(String.format("菜单【%s】存在下级菜单,无法删除", sysMenu.getMenuName()));
+            }
+        });
+        this.removeByIds(Arrays.asList(ids.split(",")));
     }
 
     @Override
-    public List<SysMenuDTO> findAllMenu() {
-        return SysMenuMapper.INSTANCE.toSysMenuDTOList(menuRepository.selectList(new LambdaQueryWrapper<>()));
+    public SysMenuPO view(String id) {
+        return this.getById(id);
     }
 
     @Override
-    public Set<SysMenuDTO> findUserMenus(String userId) {
-        //通过中间表管理查询到roleid
-        List<SysRoleDTO> roles = userRoleService.findAllRolesByUserId(userId);
-        //判断是否存在管理员账户
-        if (CollectionUtil.isEmpty(roles)) {
-            return new HashSet<>();
-        }
-        for (SysRoleDTO role : roles) {
-            if(StrUtil.equals(role.getType(), CreateEnum.sys.name())){
-                if(Boolean.TRUE.equals(tenantEnable)){
-                    return tenantService.currentTenantMenus();
-                }else {
-                    return new HashSet<>(findAllMenu());
-                }
-            }
-        }
-        return roles.stream()
-                .filter(Objects::nonNull)
-                .filter(role->Boolean.FALSE.equals(role.getDisable()))
-                .map(SysRoleDTO::getId)
-                .map(roleMenuService::findAllMenuByRoleId)
-                .flatMap(Collection::stream)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toSet());
+    public List<Tree<String>> listMenuTree() {
+        List<SysMenuPO> sysMenuList=null;
+        sysMenuList=this.list(new QueryWrapper<SysMenuPO>().
+                lambda().
+                eq(!TenantUtil.isTuoRen(),SysMenuPO::getTenantMenu,true));
+        List treeNodeList = sysMenuList.stream().map(item -> {
+            TreeNode treeNode = new TreeNode();
+            treeNode.setId(item.getId().toString());
+            treeNode.setName(item.getMenuName());
+            treeNode.setParentId(item.getParentId().toString());
+            treeNode.setWeight(item.getSort());
+            Map extra = Maps.newHashMap();
+            extra.put("icon", item.getIcon());
+            treeNode.setExtra(extra);
+            return treeNode;
+        }).collect(Collectors.toList());
+        List<Tree<String>> treeList = TreeUtil.build(treeNodeList, "0");
+        return CollectionUtils.isEmpty(treeList) ? Lists.newArrayList() : treeList;
     }
 
     @Override
-    public List<SysMenuDTO> selectBatchIds(Set<String> menuIds) {
-        return SysMenuMapper.INSTANCE.toSysMenuDTOList(menuRepository.selectBatchIds(menuIds));
+    public List<Tree<String>> selectMenuTreeAndExcludeNode(String nodeId) {
+        List<SysMenuPO> sysMenuList = this.list(Wrappers.lambdaQuery(SysMenuPO.class).ne(StrUtil.isNotBlank(nodeId), SysMenuPO::getId, nodeId)
+                .eq(!TenantUtil.isTuoRen(),SysMenuPO::getTenantMenu,true));
+        List treeNodeList = sysMenuList.stream().map(item -> {
+            TreeNode treeNode = new TreeNode();
+            treeNode.setId(item.getId().toString());
+            treeNode.setName(item.getMenuName());
+            treeNode.setParentId(item.getParentId().toString());
+            treeNode.setWeight(item.getSort());
+            Map extra = Maps.newHashMap();
+            extra.put("icon", item.getIcon());
+            treeNode.setExtra(extra);
+            return treeNode;
+        }).collect(Collectors.toList());
+        List<Tree<String>> treeList = TreeUtil.build(treeNodeList, "0");
+        return CollectionUtils.isEmpty(treeList) ? Lists.newArrayList() : treeList;
     }
 
     @Override
-    public List<Pair<String, String>> selectAllMenuIdAndName() {
-        List<SysMenuPO> allMenu =
-                baseMapper.selectList(new LambdaQueryWrapper<SysMenuPO>()
-                        .select(SysMenuPO::getId,SysMenuPO::getName));
-        List<Pair<String, String>> result = new ArrayList<>();
-        for (SysMenuPO menuPO : allMenu) {
-            result.add(Pair.of(menuPO.getId(),menuPO.getName()));
-        }
-        return result;
+    public List<Tree<String>> selectMenuTree() {
+        List<SysMenuPO> sysMenuList = this.list(new QueryWrapper<SysMenuPO>()
+                .lambda()
+                .eq(!TenantUtil.isTuoRen(),SysMenuPO::getTenantMenu,true));
+        List treeNodeList = sysMenuList.stream().map(item -> {
+            TreeNode treeNode = new TreeNode();
+            treeNode.setId(item.getId().toString());
+            treeNode.setName(item.getMenuName());
+            treeNode.setParentId(item.getParentId().toString());
+            treeNode.setWeight(item.getSort());
+            Map extra = Maps.newHashMap();
+            extra.put("icon", item.getIcon());
+            treeNode.setExtra(extra);
+            return treeNode;
+        }).collect(Collectors.toList());
+        List<Tree<String>> treeList = TreeUtil.build(treeNodeList, "0");
+        return CollectionUtils.isEmpty(treeList) ? Lists.newArrayList() : treeList;
     }
 
-//    @Override
-//    public List<SysMenuDTO> findAnonymousMenus() {
-//        return SysMenuMapper.INSTANCE.toSysMenuDTOList(menuRepository.selectList(new LambdaQueryWrapper<SysMenuPO>()
-//                        .eq(SysMenuPO::getAnonymous,Boolean.TRUE)));
-//    }
-
-    private void refreshCache(Collection<String> source){
-        Set<String> roleIds = roleMenuService.findRoleByMenuId(source,true);
-        roleIds.parallelStream().forEach(self::delRoleMenusCache);
-        Set<String> packageIds = tenantPackageMenuService.findPackageIdByMenuId(source,true);
-        packageIds.parallelStream().forEach(tenantPackageMenuService::delCacheMenuIdByPackageId);
-        Set<String> portalIds=portalMenuService.findPortalIdByMenuId(source,true);
-        portalIds.parallelStream().forEach(portalMenuService::delCacheMenusByPortalId);
+    @Override
+    public Set<String> getPermissionsByUserId(Long userId) {
+        // 查询角色列表
+        SysUserPO user = sysUserService.getById(userId);
+        List<SysRolePO> sysRoleList = sysRoleService.listSysRoleByUserId(userId);
+        boolean admin=sysRoleList.stream().anyMatch(sysRole -> "admin".equalsIgnoreCase(sysRole.getRoleCode()));
+        if (!admin&&CollectionUtil.isEmpty(sysRoleList)) {
+            return Sets.newHashSet();
+        }
+        List<Long> roleIdList = sysRoleList.stream().map(SysRolePO::getId).collect(Collectors.toList()).reversed();
+        // 查询按钮菜单权限标识
+        List<SysRoleMenuPO> sysRoleMenuList = sysRoleMenuService.list(Wrappers.lambdaQuery(SysRoleMenuPO.class).in(SysRoleMenuPO::getRoleId, roleIdList));
+        if (!admin&&sysRoleMenuList.isEmpty()) {
+            return Sets.newHashSet();
+        }
+        // 查询菜单
+        Set<Long> menuIds = sysRoleMenuList.stream().map(item -> item.getMenuId()).collect(Collectors.toSet());
+        LambdaQueryWrapper<SysMenuPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysMenuPO::getMenuType, String.valueOf(MenuTypeEnum.BUTTON.getCode()));
+        queryWrapper.eq(SysMenuPO::getStatus, String.valueOf(StatusEnum.YES.getValue()));
+        queryWrapper.eq(!Boolean.TRUE.equals(user.getIsSys()),SysMenuPO::getTenantMenu, true);
+        queryWrapper.in(!admin,SysMenuPO::getId, menuIds);
+        List<SysMenuPO> sysMenuList = this.list(queryWrapper);
+        return sysMenuList.stream().map(SysMenuPO::getPermission).collect(Collectors.toSet());
     }
 
-    private void findAllChildrenId(TreeNode<SysMenuDTO,String> children, Set<String> result){
-        if(children==null){
-            return;
+    @Override
+    public List<SysMenuPO> listGrantMenuByUserId(Long userId) {
+        // 查询角色列表
+        List<SysUserRolePO> sysUserRoleList = sysUserRoleService.list(Wrappers.lambdaQuery(SysUserRolePO.class).eq(SysUserRolePO::getUserId, userId));
+        if (sysUserRoleList.isEmpty()) {
+            return Lists.newArrayList();
         }
-        result.add(children.getId());
-        List<? extends TreeNode<SysMenuDTO,String>> childrenNode = children.getChildren();
-        if(CollectionUtil.isNotEmpty(childrenNode)){
-            for (TreeNode<SysMenuDTO,String> treeNode : childrenNode) {
-                findAllChildrenId(treeNode,result);
-            }
+        List<Long> roleIdList = sysUserRoleList.stream().map(item -> item.getRoleId()).collect(Collectors.toList());
+        // 查询角色菜单
+        List<SysRoleMenuPO> sysRoleMenuList = sysRoleMenuService.list(Wrappers.lambdaQuery(SysRoleMenuPO.class).in(SysRoleMenuPO::getRoleId, roleIdList));
+        if (sysRoleMenuList.isEmpty()) {
+            return Lists.newArrayList();
         }
+        // 查询菜单
+        Set<Long> menuIds = sysRoleMenuList.stream().map(item -> item.getMenuId()).collect(Collectors.toSet());
+        LambdaQueryWrapper<SysMenuPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysMenuPO::getStatus, StatusEnum.YES.getValue());
+        queryWrapper.in(SysMenuPO::getMenuType, MenuTypeEnum.DIR.getCode(), MenuTypeEnum.MENU.getCode());
+        queryWrapper.in(SysMenuPO::getId, menuIds);
+        queryWrapper.eq(!TenantUtil.isTuoRen(),SysMenuPO::getTenantMenu,true);
+        return this.list(queryWrapper);
     }
+
 }

+ 95 - 95
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysOrgServiceImpl.java

@@ -1,95 +1,95 @@
-package cn.tr.module.sys.user.service.impl;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.tr.core.exception.ServiceException;
-import cn.tr.core.exception.TRExcCode;
-import cn.tr.core.tree.TreeBuilder;
-import cn.tr.core.utils.JsonUtils;
-import cn.tr.module.sys.user.mapper.SysOrgMapper;
-import cn.tr.module.sys.user.dto.SysOrgDTO;
-import cn.tr.module.sys.user.dto.SysOrgQueryDTO;
-import cn.tr.module.sys.user.po.SysOrgPO;
-import cn.tr.module.sys.user.po.SysUserPO;
-import cn.tr.module.sys.user.repository.SysOrgRepository;
-import cn.tr.module.sys.user.repository.SysUserRepository;
-import cn.tr.module.sys.user.service.ISysOrgService;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName : SysOrgServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
- */
-@Service
-public class SysOrgServiceImpl implements ISysOrgService {
-    @Autowired
-    private SysOrgRepository orgRepository;
-    @Autowired
-    private SysUserRepository userRepository;
-    @Autowired
-    @Lazy
-    private ISysOrgService self;
-
-    @Override
-    public List<SysOrgDTO> selectSysOrgList(SysOrgQueryDTO query) {
-        return orgRepository.stdSelectList(query);
-    }
-
-    @Override
-    public SysOrgDTO selectSysOrgById(String id) {
-        return orgRepository.stdSelectById(id);
-    }
-
-    @Override
-    public boolean updateSysOrgById(SysOrgDTO source) {
-        //判断上级节点到根节点的路径上是否包含当前节点
-        TreeBuilder.validateNode(SysOrgMapper.INSTANCE.convertSysOrgTreeNode(source),self.selectSysOrgTree());
-        boolean result = orgRepository.updateById(SysOrgMapper.INSTANCE.toSysOrgPO(source)) != 0;
-        if(result){
-            self.delSysOrgTreeCache();
-        }
-        return result;
-    }
-    @Override
-    public boolean insertSysOrg(SysOrgDTO source) {
-        boolean result = orgRepository.insert(SysOrgMapper.INSTANCE.toSysOrgPO(source)) != 0;
-        if( result){
-            self.delSysOrgTreeCache();
-        }
-        return result;
-    }
-
-    @Override
-    public int deleteSysOrgByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
-        }
-        List<SysOrgPO> orgs = orgRepository.selectBatchIds(ids);
-        if(CollectionUtil.isEmpty(orgs)){
-            return CollectionUtil.size(ids);
-        }
-        List<SysUserPO> orgUsers = userRepository.selectList(new LambdaQueryWrapper<SysUserPO>()
-                .in(SysUserPO::getOrgId, ids));
-        if(CollectionUtil.isNotEmpty(orgUsers)){
-            //部门用户
-            Map<String, SysOrgPO> orgMap = orgs.stream().collect(Collectors.groupingBy(SysOrgPO::getId, Collectors.collectingAndThen(Collectors.toList(), CollectionUtil::getFirst)));
-            Set<String> userOrgIds = orgUsers.stream().map(SysUserPO::getOrgId).collect(Collectors.toSet());
-            Set<String> existName = userOrgIds.stream()
-                    .map(orgMap::get)
-                    .filter(Objects::nonNull)
-                    .map(SysOrgPO::getName)
-                    .collect(Collectors.toSet());
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("部门 %s 下存在用户,不可删除", JsonUtils.toJsonString(existName)));
-
-        }
-        self.delSysOrgTreeCache();
-        return orgRepository.deleteBatchIds(ids);
-    }
-}
+//package cn.tr.module.sys.user.service.impl;
+//
+//import cn.hutool.core.collection.CollectionUtil;
+//import cn.tr.core.exception.ServiceException;
+//import cn.tr.core.exception.TRExcCode;
+//import cn.tr.core.tree.TreeBuilder;
+//import cn.tr.core.utils.JsonUtils;
+//import cn.tr.module.sys.user.mapper.SysOrgMapper;
+//import cn.tr.module.sys.user.dto.SysOrgDTO;
+//import cn.tr.module.sys.user.dto.SysOrgQueryDTO;
+//import cn.tr.module.sys.user.po.SysOrgPO;
+//import cn.tr.module.sys.user.po.SysUserPO;
+//import cn.tr.module.sys.user.repository.SysOrgRepository;
+//import cn.tr.module.sys.user.repository.SysUserRepository;
+//import cn.tr.module.sys.user.service.ISysOrgService;
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Lazy;
+//import org.springframework.stereotype.Service;
+//
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * @ClassName : SysOrgServiceImpl
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年03月31日
+// */
+//@Service
+//public class SysOrgServiceImpl implements ISysOrgService {
+//    @Autowired
+//    private SysOrgRepository orgRepository;
+//    @Autowired
+//    private SysUserRepository userRepository;
+//    @Autowired
+//    @Lazy
+//    private ISysOrgService self;
+//
+//    @Override
+//    public List<SysOrgDTO> selectSysOrgList(SysOrgQueryDTO query) {
+//        return orgRepository.stdSelectList(query);
+//    }
+//
+//    @Override
+//    public SysOrgDTO selectSysOrgById(String id) {
+//        return orgRepository.stdSelectById(id);
+//    }
+//
+//    @Override
+//    public boolean updateSysOrgById(SysOrgDTO source) {
+//        //判断上级节点到根节点的路径上是否包含当前节点
+//        TreeBuilder.validateNode(SysOrgMapper.INSTANCE.convertSysOrgTreeNode(source),self.selectSysOrgTree());
+//        boolean result = orgRepository.updateById(SysOrgMapper.INSTANCE.toSysOrgPO(source)) != 0;
+//        if(result){
+//            self.delSysOrgTreeCache();
+//        }
+//        return result;
+//    }
+//    @Override
+//    public boolean insertSysOrg(SysOrgDTO source) {
+//        boolean result = orgRepository.insert(SysOrgMapper.INSTANCE.toSysOrgPO(source)) != 0;
+//        if( result){
+//            self.delSysOrgTreeCache();
+//        }
+//        return result;
+//    }
+//
+//    @Override
+//    public int deleteSysOrgByIds(Collection<String> ids) {
+//        if(CollectionUtil.isEmpty(ids)){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+//        }
+//        List<SysOrgPO> orgs = orgRepository.selectBatchIds(ids);
+//        if(CollectionUtil.isEmpty(orgs)){
+//            return CollectionUtil.size(ids);
+//        }
+//        List<SysUserPO> orgUsers = userRepository.selectList(new LambdaQueryWrapper<SysUserPO>()
+//                .in(SysUserPO::getOrgId, ids));
+//        if(CollectionUtil.isNotEmpty(orgUsers)){
+//            //部门用户
+//            Map<String, SysOrgPO> orgMap = orgs.stream().collect(Collectors.groupingBy(SysOrgPO::getId, Collectors.collectingAndThen(Collectors.toList(), CollectionUtil::getFirst)));
+//            Set<String> userOrgIds = orgUsers.stream().map(SysUserPO::getOrgId).collect(Collectors.toSet());
+//            Set<String> existName = userOrgIds.stream()
+//                    .map(orgMap::get)
+//                    .filter(Objects::nonNull)
+//                    .map(SysOrgPO::getName)
+//                    .collect(Collectors.toSet());
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("部门 %s 下存在用户,不可删除", JsonUtils.toJsonString(existName)));
+//
+//        }
+//        self.delSysOrgTreeCache();
+//        return orgRepository.deleteBatchIds(ids);
+//    }
+//}

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

@@ -1,118 +1,118 @@
-package cn.tr.module.sys.user.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.user.mapper.SysMenuMapper;
-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.core.enums.CreateEnum;
-import cn.tr.module.sys.user.po.SysPortalMenuPO;
-import cn.tr.module.sys.user.repository.SysMenuRepository;
-import cn.tr.module.sys.user.repository.SysPortalMenuRepository;
-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 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.beans.factory.annotation.Value;
-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 : SysPortalMenuServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年04月09日
- */
-@Service
-public class SysPortalMenuServiceImpl extends ServiceImpl<SysPortalMenuRepository, SysPortalMenuPO> implements ISysPortalMenuService {
-    @Autowired
-    @Lazy
-    private ISysPortalMenuService portalMenuService;
-
-    @Autowired
-    private ISysMenuService menuService;
-
-    @Autowired
-    @Lazy
-    private ISysPortalService portalService;
-
-    @Autowired
-    private SysMenuRepository menuRepository;
-
-    @Autowired
-    @Lazy
-    private ISysTenantService tenantService;
-
-    @Value("${tr.tenant.enable}")
-    private Boolean tenantEnable;
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void assignPortalMenu(String portalId,List<String> menuIds) {
-        SysPortalDTO portal = portalService.selectSysPortalById(portalId);
-        if(StrUtil.equals(portal.getType(), CreateEnum.sys.name())){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统门户进行操作");
-        }
-        baseMapper.delete(
-                new LambdaQueryWrapper<SysPortalMenuPO>().eq(SysPortalMenuPO::getPortalId,portalId)
-        );
-        if(CollectionUtil.isNotEmpty(menuIds)){
-            List<SysPortalMenuPO> packageMenus = menuIds
-                    .stream()
-                    .distinct()
-                    .map(menuId -> {
-                        SysPortalMenuPO result = new SysPortalMenuPO();
-                        result.setMenuId(menuId);
-                        result.setPortalId(portalId);
-                        return result;
-                    })
-                    .collect(Collectors.toList());
-            this.saveBatch(packageMenus);
-        }
-        portalMenuService.delCacheMenusByPortalId(portalId);
-    }
-
-    @Override
-    public List<SysMenuDTO> findAllMenusByPortalId(String portalId) {
-        SysPortalDTO portal = portalService.selectSysPortalById(portalId);
-        if (Objects.isNull(portal)) {
-            return new ArrayList<>();
-        }
-        if(StrUtil.equals(portal.getType(), CreateEnum.sys.name())){
-            if(Boolean.TRUE.equals(tenantEnable)){
-                return new ArrayList<>(tenantService.currentTenantMenus());
-            }else {
-                return menuService.findAllMenu();
-            }
-
-        }
-        return SysMenuMapper.INSTANCE.toSysMenuDTOList(menuRepository.findAllMenuByPortalId(portalId));
-    }
-
-    @Override
-    public Set<String> findPortalIdByMenuId(Collection<String> menuIds, boolean containsSys) {
-        Set<String> portalIds = this.list(new LambdaQueryWrapper<SysPortalMenuPO>()
-                .in(SysPortalMenuPO::getMenuId, menuIds))
-                .stream()
-                .map(SysPortalMenuPO::getPortalId)
-                .collect(Collectors.toSet());
-        Set<String> sysPortalIds=new HashSet<>();
-        if(containsSys){
-            sysPortalIds = portalService.findAllSysPortals().stream()
-                    .map(SysPortalDTO::getId)
-                    .collect(Collectors.toSet());
-
-        }
-        sysPortalIds.addAll(portalIds);
-        return sysPortalIds;
-    }
-}
+//package cn.tr.module.sys.user.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.user.dto.SysMenuDTO;
+//import cn.tr.module.sys.user.mapper.SysMenuMapper;
+//import cn.tr.module.sys.tenant.service.ISysTenantService;
+//import cn.tr.module.sys.user.dto.SysPortalDTO;
+//import cn.tr.core.enums.CreateEnum;
+//import cn.tr.module.sys.user.po.SysPortalMenuPO;
+//import cn.tr.module.sys.user.repository.SysMenuRepository;
+//import cn.tr.module.sys.user.repository.SysPortalMenuRepository;
+//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 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.beans.factory.annotation.Value;
+//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 : SysPortalMenuServiceImpl
+// * @Description :
+// * @Author : LF
+// * @Date: 2023年04月09日
+// */
+//@Service
+//public class SysPortalMenuServiceImpl extends ServiceImpl<SysPortalMenuRepository, SysPortalMenuPO> implements ISysPortalMenuService {
+//    @Autowired
+//    @Lazy
+//    private ISysPortalMenuService portalMenuService;
+//
+//    @Autowired
+//    private ISysMenuService menuService;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysPortalService portalService;
+//
+//    @Autowired
+//    private SysMenuRepository menuRepository;
+//
+//    @Autowired
+//    @Lazy
+//    private ISysTenantService tenantService;
+//
+//    @Value("${tr.tenant.enable}")
+//    private Boolean tenantEnable;
+//
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public void assignPortalMenu(String portalId,List<String> menuIds) {
+//        SysPortalDTO portal = portalService.selectSysPortalById(portalId);
+//        if(StrUtil.equals(portal.getType(), CreateEnum.sys.name())){
+//            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统门户进行操作");
+//        }
+//        baseMapper.delete(
+//                new LambdaQueryWrapper<SysPortalMenuPO>().eq(SysPortalMenuPO::getPortalId,portalId)
+//        );
+//        if(CollectionUtil.isNotEmpty(menuIds)){
+//            List<SysPortalMenuPO> packageMenus = menuIds
+//                    .stream()
+//                    .distinct()
+//                    .map(menuId -> {
+//                        SysPortalMenuPO result = new SysPortalMenuPO();
+//                        result.setMenuId(menuId);
+//                        result.setPortalId(portalId);
+//                        return result;
+//                    })
+//                    .collect(Collectors.toList());
+//            this.saveBatch(packageMenus);
+//        }
+//        portalMenuService.delCacheMenusByPortalId(portalId);
+//    }
+//
+//    @Override
+//    public List<SysMenuDTO> findAllMenusByPortalId(String portalId) {
+//        SysPortalDTO portal = portalService.selectSysPortalById(portalId);
+//        if (Objects.isNull(portal)) {
+//            return new ArrayList<>();
+//        }
+//        if(StrUtil.equals(portal.getType(), CreateEnum.sys.name())){
+//            if(Boolean.TRUE.equals(tenantEnable)){
+//                return new ArrayList<>(tenantService.currentTenantMenus());
+//            }else {
+//                return menuService.findAllMenu();
+//            }
+//
+//        }
+//        return SysMenuMapper.INSTANCE.toSysMenuDTOList(menuRepository.findAllMenuByPortalId(portalId));
+//    }
+//
+//    @Override
+//    public Set<String> findPortalIdByMenuId(Collection<String> menuIds, boolean containsSys) {
+//        Set<String> portalIds = this.list(new LambdaQueryWrapper<SysPortalMenuPO>()
+//                .in(SysPortalMenuPO::getMenuId, menuIds))
+//                .stream()
+//                .map(SysPortalMenuPO::getPortalId)
+//                .collect(Collectors.toSet());
+//        Set<String> sysPortalIds=new HashSet<>();
+//        if(containsSys){
+//            sysPortalIds = portalService.findAllSysPortals().stream()
+//                    .map(SysPortalDTO::getId)
+//                    .collect(Collectors.toSet());
+//
+//        }
+//        sysPortalIds.addAll(portalIds);
+//        return sysPortalIds;
+//    }
+//}

+ 139 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPostServiceImpl.java

@@ -0,0 +1,139 @@
+package cn.tr.module.sys.user.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.tr.module.common.menus.StatusEnum;
+import cn.tr.module.sys.exception.CustomException;
+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.po.SysUserPostPO;
+import cn.tr.module.sys.user.repository.SysPostRepository;
+import cn.tr.module.sys.user.service.ISysPostService;
+import cn.tr.module.sys.user.service.ISysUserPostService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import jakarta.annotation.Resource;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 岗位表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-22
+ */
+@Service
+public class SysPostServiceImpl extends ServiceImpl<SysPostRepository, SysPostPO> implements ISysPostService {
+
+    @Resource
+    private ISysUserPostService sysUserPostService;
+
+    @Override
+    public IPage<SysPostPO> page(Page reqPage, SysPostQueryDTO req) {
+        LambdaQueryWrapper<SysPostPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.like(StrUtil.isNotBlank(req.getPostCode()), SysPostPO::getPostCode, req.getPostCode());
+        queryWrapper.like(StrUtil.isNotBlank(req.getPostName()), SysPostPO::getPostName, req.getPostName());
+        queryWrapper.orderByAsc(SysPostPO::getSort);
+        return this.page(reqPage, queryWrapper);
+    }
+
+    @Override
+    public List<SysPostPO> list(SysPostQueryDTO req) {
+        LambdaQueryWrapper<SysPostPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.like(StrUtil.isNotBlank(req.getPostCode()), SysPostPO::getPostCode, req.getPostCode());
+        queryWrapper.like(StrUtil.isNotBlank(req.getPostName()), SysPostPO::getPostName, req.getPostName());
+        queryWrapper.orderByAsc(SysPostPO::getSort);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void add(SysPostAddDTO req) {
+        if (!this.checkUniquePostName(req.getPostName(), null)) {
+            throw new CustomException("岗位名称已存在");
+        }
+        if (!this.checkUniquePostCode(req.getPostCode(), null)) {
+            throw new CustomException("岗位编码已存在");
+        }
+        SysPostPO entity = BeanUtil.copyProperties(req, SysPostPO.class);
+        this.save(entity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void edit(SysPostEditDTO req) {
+        if (!this.checkUniquePostName(req.getPostName(), req.getId())) {
+            throw new CustomException("岗位名称已存在");
+        }
+        if (!this.checkUniquePostCode(req.getPostCode(), req.getId())) {
+            throw new CustomException("岗位编码已存在");
+        }
+        SysPostPO entity = BeanUtil.copyProperties(req, SysPostPO.class);
+        this.updateById(entity);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void remove(String ids) {
+        List<String> idList = Arrays.asList(ids.split(","));
+        idList.forEach(item -> {
+            SysPostPO sysPost = this.getById(item);
+            SysUserPostPO sysUserPost = sysUserPostService.getOne(Wrappers.lambdaQuery(SysUserPostPO.class).eq(SysUserPostPO::getPostId, item));
+            if (Objects.nonNull(sysUserPost)) {
+                throw new CustomException(String.format("岗位【%s】已被使用,无法删除", sysPost.getPostName()));
+            }
+        });
+        this.removeByIds(Arrays.asList(ids.split(",")));
+    }
+
+    @Override
+    public SysPostPO view(String id) {
+        return this.getById(id);
+    }
+
+    @Override
+    public List<SysPostPO> listOptions() {
+        LambdaQueryWrapper<SysPostPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysPostPO::getStatus, StatusEnum.YES.getValue())
+                .orderByAsc(SysPostPO::getSort);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<SysPostPO> selectOptions() {
+        LambdaQueryWrapper<SysPostPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysPostPO::getStatus, StatusEnum.YES.getValue())
+                .orderByAsc(SysPostPO::getSort);
+        return this.list(queryWrapper);
+    }
+
+    private Boolean checkUniquePostCode(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
+        }
+        id = Objects.isNull(id) ? -1L : id;
+        SysPostPO entity = this.getOne(Wrappers.lambdaQuery(SysPostPO.class).eq(SysPostPO::getPostCode, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
+    }
+
+    private Boolean checkUniquePostName(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
+        }
+        id = Objects.isNull(id) ? -1L : id;
+        SysPostPO entity = this.getOne(Wrappers.lambdaQuery(SysPostPO.class).eq(SysPostPO::getPostName, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
+    }
+
+}

+ 21 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysRoleDeptServiceImpl.java

@@ -0,0 +1,21 @@
+package cn.tr.module.sys.user.service.impl;
+
+import cn.tr.module.sys.user.po.SysRoleDeptPO;
+import cn.tr.module.sys.user.repository.SysRoleDeptRepository;
+import cn.tr.module.sys.user.service.ISysRoleDeptService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 角色部门表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Service
+public class SysRoleDeptServiceImpl extends ServiceImpl<SysRoleDeptRepository, SysRoleDeptPO> implements ISysRoleDeptService {
+
+
+}

+ 0 - 85
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysRoleMenuServiceImpl.java

@@ -1,30 +1,11 @@
 package cn.tr.module.sys.user.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.user.mapper.SysMenuMapper;
-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.core.enums.CreateEnum;
 import cn.tr.module.sys.user.po.SysRoleMenuPO;
-import cn.tr.module.sys.user.po.SysRolePO;
-import cn.tr.module.sys.user.repository.SysMenuRepository;
 import cn.tr.module.sys.user.repository.SysRoleMenuRepository;
-import cn.tr.module.sys.user.repository.SysRoleRepository;
 import cn.tr.module.sys.user.service.ISysRoleMenuService;
-import cn.tr.module.sys.user.service.ISysRoleService;
-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 : SysRoleMenuServiceImpl
@@ -34,71 +15,5 @@ import java.util.stream.Collectors;
  */
 @Service
 public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuRepository,SysRoleMenuPO> implements ISysRoleMenuService {
-    @Autowired
-    private SysMenuRepository menuRepository;
 
-    @Autowired
-    @Lazy
-    private ISysRoleService roleService;
-
-    @Autowired
-    @Lazy
-    private ISysTenantService tenantService;
-
-    @Autowired
-    private SysRoleRepository roleRepository;
-
-    @Autowired
-    @Lazy
-    private ISysRoleMenuService self;
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void assignRoleMenu(String roleId, List<String> menuIds) {
-        SysRolePO role = roleRepository.selectById(roleId);
-        if(StrUtil.equals(role.getType(),CreateEnum.sys.name())){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统角色进行操作");
-        }
-        baseMapper.delete(new LambdaQueryWrapper<SysRoleMenuPO>().eq(SysRoleMenuPO::getRoleId,roleId));
-        if (CollectionUtil.isNotEmpty(menuIds)) {
-            List<SysRoleMenuPO> roleMenus = menuIds
-                    .stream()
-                    .distinct()
-                    .map(menuId -> {
-                        SysRoleMenuPO result = new SysRoleMenuPO();
-                        result.setMenuId(menuId);
-                        result.setRoleId(roleId);
-                        return result;
-                    })
-                    .collect(Collectors.toList());
-            saveBatch(roleMenus);
-        }
-        self.delRoleMenusCache(roleId);
-    }
-
-    @Override
-    public List<SysMenuDTO> findAllMenuByRoleId(String roleId) {
-        SysRoleDTO roleDTO = roleService.selectSysRoleById(roleId);
-        if (Objects.isNull(roleDTO)) {
-            return new ArrayList<>();
-        }
-        if(StrUtil.equals(roleDTO.getType(), CreateEnum.sys.name())){
-            //当前租户的所有菜单
-            return new ArrayList<>(tenantService.currentTenantMenus());
-        }
-        return SysMenuMapper.INSTANCE.toSysMenuDTOList(menuRepository.findAllMenuByRoleId(roleId));
-    }
-
-    @Override
-    public Set<String> findRoleByMenuId(Collection<String > menuIds,boolean containsSys) {
-        List<SysRoleMenuPO> roleMenus = this.list(new LambdaQueryWrapper<SysRoleMenuPO>().in(SysRoleMenuPO::getMenuId, menuIds));
-        Set<String> sysRoleIds=new HashSet<>();
-        if(containsSys){
-            sysRoleIds = roleService.findAllSysRoles().stream()
-                    .map(SysRoleDTO::getId)
-                    .collect(Collectors.toSet());
-        }
-        Set<String> roleIds = roleMenus.stream().map(SysRoleMenuPO::getRoleId).collect(Collectors.toSet());
-        sysRoleIds.addAll(roleIds);
-        return sysRoleIds;
-    }
 }

+ 229 - 88
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysRoleServiceImpl.java

@@ -1,141 +1,282 @@
 package cn.tr.module.sys.user.service.impl;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.hutool.core.bean.BeanUtil;
+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.module.sys.user.mapper.SysRoleMapper;
-import cn.tr.module.sys.user.dto.SysRoleDTO;
+import cn.tr.module.common.menus.MenuTypeEnum;
+import cn.tr.module.common.menus.StatusEnum;
+import cn.tr.module.common.utils.Constants;
+import cn.tr.module.common.utils.TenantUtil;
+import cn.tr.module.sys.exception.CustomException;
+import cn.tr.module.sys.oauth2.bean.LoginUser;
+import cn.tr.module.sys.oauth2.utils.SecurityUtil;
+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.core.enums.CreateEnum;
-import cn.tr.module.sys.user.po.SysRoleMenuPO;
-import cn.tr.module.sys.user.po.SysRolePO;
-import cn.tr.module.sys.user.repository.SysRoleMenuRepository;
+import cn.tr.module.sys.user.mapper.SysRoleMapper;
+import cn.tr.module.sys.user.po.*;
 import cn.tr.module.sys.user.repository.SysRoleRepository;
-import cn.tr.module.sys.user.service.ISysRoleService;
-import cn.tr.module.sys.user.service.ISysUserRoleService;
+import cn.tr.module.sys.user.service.*;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 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 jakarta.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
- * @ClassName : SysRoleServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
+ * <p>
+ * 角色表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
 @Service
-public class SysRoleServiceImpl implements ISysRoleService {
-    @Autowired
-    private SysRoleRepository roleRepository;
+public class SysRoleServiceImpl extends ServiceImpl<SysRoleRepository, SysRolePO> implements ISysRoleService {
 
     @Autowired
-    @Lazy
-    private ISysUserRoleService userRoleService;
-
+    private ISysUserRoleService sysUserRoleService;
+    @Resource
+    private ISysRoleDeptService sysRoleDeptService;
+    @Resource
+    private ISysRoleMenuService sysRoleMenuService;
+    @Resource
+    private ISysDeptService sysDeptService;
     @Autowired
-    private SysRoleMenuRepository roleMenuRepository;
+    @Lazy
+    private ISysMenuService sysMenuService;
 
     @Override
-    public List<SysRoleDTO> selectSysRoleList(SysRoleQueryDTO query) {
-        return SysRoleMapper.INSTANCE.toSysRoleDTOList(roleRepository.selectList(new LambdaQueryWrapper<SysRolePO>()
-                .like(StrUtil.isNotEmpty(query.getRoleCode()),SysRolePO::getCode,query.getRoleCode())
-                .like(StrUtil.isNotEmpty(query.getRoleName()),SysRolePO::getName,query.getRoleName())
-                .eq(StrUtil.isNotEmpty(query.getType()),SysRolePO::getType,query.getType())
-                .eq(ObjectUtil.isNotNull(query.getDisable()),SysRolePO::getDisable,query.getDisable())
-        ));
+    public IPage<SysRolePO> page(Page reqPage, SysRoleQueryDTO req) {
+        LambdaQueryWrapper<SysRolePO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.like(StrUtil.isNotBlank(req.getRoleCode()), SysRolePO::getRoleCode, req.getRoleCode());
+        queryWrapper.like(StrUtil.isNotBlank(req.getRoleName()), SysRolePO::getRoleName, req.getRoleName());
+        queryWrapper.orderByAsc(SysRolePO::getSort);
+        return this.page(reqPage, queryWrapper);
     }
 
     @Override
-    public Collection<SysRoleDTO> findAllSysRoles() {
-        return SysRoleMapper.INSTANCE.toSysRoleDTOList( roleRepository.selectList(new LambdaQueryWrapper<SysRolePO>()
-                .eq(SysRolePO::getType,CreateEnum.sys.name())));
+    public List<SysRolePO> list(SysRoleQueryDTO req) {
+        LambdaQueryWrapper<SysRolePO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.like(StrUtil.isNotBlank(req.getRoleCode()), SysRolePO::getRoleCode, req.getRoleCode());
+        queryWrapper.like(StrUtil.isNotBlank(req.getRoleName()), SysRolePO::getRoleName, req.getRoleName());
+        queryWrapper.orderByAsc(SysRolePO::getSort);
+        return this.list(queryWrapper);
     }
 
-    ;
-
     @Override
-    public SysRoleDTO selectSysRoleById(String id) {
-        return SysRoleMapper.INSTANCE.toSysRoleDTO(roleRepository.selectById(id));
+    @Transactional(rollbackFor = Exception.class)
+    public void add(SysRoleAddDTO req) {
+        if (!this.checkUniqueRoleName(req.getRoleName(), null)) {
+            throw new CustomException("角色名称已存在");
+        }
+        if (!this.checkUniqueRoleCode(req.getRoleCode(), null)) {
+            throw new CustomException("角色编码已存在");
+        }
+        SysRolePO entity = BeanUtil.copyProperties(req, SysRolePO.class);
+        this.save(entity);
+//        // 删除角色和部门关联
+//        sysRoleDeptService.remove(Wrappers.lambdaQuery(SysRoleDept.class).eq(SysRoleDept::getRoleId, req.getId()));
+//        // 新增角色和菜单关联
+//        if (Objects.nonNull(req.getDeptIds())) {
+//            req.getDeptIds().forEach(item -> {
+//                SysRoleDept sysRoleDept = new SysRoleDept();
+//                sysRoleDept.setRoleId(entity.getId());
+//                sysRoleDept.setDeptId(item);
+//                sysRoleDeptService.save(sysRoleDept);
+//            });
+//        }
     }
 
     @Override
-    public List<SysRoleDTO> selectSysRoleByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            return Collections.emptyList();
+    @Transactional(rollbackFor = Exception.class)
+    public void edit(SysRoleEditDTO req) {
+        if (!this.checkUniqueRoleName(req.getRoleName(), req.getId())) {
+            throw new CustomException("角色名称已存在");
+        }
+        if (!this.checkUniqueRoleCode(req.getRoleCode(), req.getId())) {
+            throw new CustomException("角色编码已存在");
+        }
+        SysRolePO originRole = this.getById(req.getId());
+        if("admin".equalsIgnoreCase(originRole.getRoleCode())){
+            throw new CustomException("管理员角色不可修改");
+        }
+        SysRolePO entity = BeanUtil.copyProperties(req, SysRolePO.class);
+        this.updateById(entity);
+        // 删除角色和部门关联
+        sysRoleDeptService.remove(Wrappers.lambdaQuery(SysRoleDeptPO.class).eq(SysRoleDeptPO::getRoleId, req.getId()));
+        // 新增角色和菜单关联
+        if (Objects.nonNull(req.getDeptIds())) {
+            req.getDeptIds().forEach(item -> {
+                SysRoleDeptPO sysRoleDept = new SysRoleDeptPO();
+                sysRoleDept.setRoleId(entity.getId());
+                sysRoleDept.setDeptId(item);
+                sysRoleDeptService.save(sysRoleDept);
+            });
         }
-        return SysRoleMapper.INSTANCE.toSysRoleDTOList( roleRepository.selectBatchIds(ids));
-
     }
 
     @Override
-    public boolean updateSysRoleById(SysRoleDTO source) {
-        SysRolePO po = SysRoleMapper.INSTANCE.toSysRolePO(source);
-        validateRoleSource(po);
-        Set<String> userIds = userRoleService.findUserByRoleId(Collections.singleton(source.getId()));
-        userIds.parallelStream().forEach(userRoleService::delUserRoleCache);
-        return roleRepository.updateById(po)!=0;
+    @Transactional(rollbackFor = Exception.class)
+    public void remove(Long id) {
+        SysRolePO sysRole = this.getById(id);
+        if("admin".equalsIgnoreCase(sysRole.getRoleCode())){
+            throw new CustomException("管理员角色不可删除");
+        }
+        long userRoleCount = sysUserRoleService.count(Wrappers.lambdaQuery(SysUserRolePO.class).eq(SysUserRolePO::getRoleId, id));
+        if (userRoleCount!=0) {
+            throw new CustomException(String.format("角色【%s】存在用户,无法删除", sysRole.getRoleName()));
+        }
+        this.removeById(id);
+        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenuPO>().lambda().eq(SysRoleMenuPO::getRoleId,sysRole.getId()));
     }
 
     @Override
-    @Transactional
-    public boolean insertSysRole(SysRoleDTO source) {
-        SysRolePO po = SysRoleMapper.INSTANCE.toSysRolePO(source);
-        validateRoleSource(po);
-        return roleRepository.insert(po)!=0;
+    public SysRolePO view(String id) {
+        return this.getById(Long.valueOf(id));
     }
 
     @Override
-    public boolean insertInnerSysRole(SysRoleDTO source) {
-        return roleRepository.insert(SysRoleMapper.INSTANCE.toSysRolePO(source))!=0;
+    public List<SysRolePO> listOptions() {
+        return this.list(Wrappers.lambdaQuery(SysRolePO.class).eq(SysRolePO::getStatus, StatusEnum.YES.getValue()).orderByAsc(SysRolePO::getSort));
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public int deleteSysRoleByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+    public void assignMenu(SysRoleAssignMenuDTO req) {
+        //判断角色蔬菜单是否发生变化
+        sysRoleMenuService.remove(Wrappers.lambdaQuery(SysRoleMenuPO.class).eq(SysRoleMenuPO::getRoleId, req.getRoleId()));
+        // 新增角色和菜单关联
+        if (Objects.nonNull(req.getMenuIds())) {
+            sysRoleMenuService.saveBatch(req.getMenuIds().stream().map(item -> {
+                SysRoleMenuPO sysRoleMenu = new SysRoleMenuPO();
+                sysRoleMenu.setRoleId(Long.valueOf(req.getRoleId()));
+                sysRoleMenu.setMenuId(item);
+                return sysRoleMenu;
+            }).collect(Collectors.toList()));
         }
-        List<SysRolePO> roles = roleRepository.selectBatchIds(ids);
-        for (SysRolePO role : roles) {
-            if (StrUtil.equals(role.getType(), CreateEnum.sys.name())) {
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统角色进行操作");
-            }
+        StpLogic stpLogic = SecurityUtil.getStpLogic();
+        //分配菜单后将对应的在线人员进行更新
+        List<SysUserRolePO> userRoleList = sysUserRoleService.list(new QueryWrapper<SysUserRolePO>().lambda().eq(SysUserRolePO::getRoleId, req.getRoleId()));
+        if (CollUtil.isNotEmpty(userRoleList)) {
+            userRoleList
+                    .parallelStream()
+                    .filter(Objects::nonNull)
+                    .forEach(sysUserRole -> {
+                        Set<String> permissionsByUserId = sysMenuService.getPermissionsByUserId(sysUserRole.getUserId());
+                        SaSession session = stpLogic.getSessionByLoginId(sysUserRole.getUserId());
+                        LoginUser user = (LoginUser) session.get(Constants.LOGIN_USER_KEY);
+                        if(user!=null){
+                            user.setPermissions(permissionsByUserId);
+                            session.set(Constants.LOGIN_USER_KEY,user);
+                        }
+//                        List<String> tokens =stpLogic.getTokenValueListByLoginId(sysUserRole.getUserId());
+//                        tokens.
+//                                parallelStream().forEach(token->{
+//                            SaSession tokenSessionByToken = stpLogic.getTokenSessionByToken(token);
+//                            LoginUser user = (LoginUser) tokenSessionByToken.get(Constants.LOGIN_USER_KEY);
+//                            if(user!=null){
+//                                user.setPermissions(permissionsByUserId);
+//                                tokenSessionByToken.set(Constants.LOGIN_USER_KEY,user);
+//                            }
+//                        });
+                    });
         }
-        Set<String> userIds = userRoleService.findUserByRoleId(ids);
-        if(CollectionUtil.isNotEmpty(userIds)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"所选角色已与用户关联,无法删除");
+
+    }
+
+    @Override
+    public List<SysMenuPO> listRoleMenus(String roleId) {
+        QueryWrapper<SysMenuPO> queryWrapper = new QueryWrapper<>();
+        SysRolePO role = this.getById(Long.valueOf(roleId));  // 将字符串转换为Long以匹配实体类型
+        //系统级医院
+        if(!TenantUtil.isTuoRen()){
+            queryWrapper.lambda().eq(SysMenuPO::getTenantMenu,true);
         }
-        int result = roleRepository.deleteBatchIds(ids);
-        if(result!=0){
-            roleMenuRepository.delete(new LambdaQueryWrapper<SysRoleMenuPO>().in(SysRoleMenuPO::getRoleId,ids));
+        if (role.getRoleCode().contains("admin")) {
+            queryWrapper.lambda().eq(SysMenuPO::getStatus, StatusEnum.YES.getValue());
+            queryWrapper.lambda().in(SysMenuPO::getMenuType, MenuTypeEnum.DIR.getCode(), MenuTypeEnum.MENU.getCode());
+            return sysMenuService.list(queryWrapper);
+        }else {
+            List<SysRoleMenuPO> sysRoleMenuList = sysRoleMenuService.list(Wrappers.lambdaQuery(SysRoleMenuPO.class).eq(SysRoleMenuPO::getRoleId, roleId));
+            if (CollUtil.isNotEmpty(sysRoleMenuList)) {
+                List<Long> menuIds = sysRoleMenuList.stream().map(SysRoleMenuPO::getMenuId).collect(Collectors.toList());
+                return sysMenuService.list(queryWrapper.lambda().in(SysMenuPO::getId,menuIds));
+            }
         }
-        return result;
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<SysDeptPO> listRoleDepts(String roleId) {
+        List<SysRoleDeptPO> sysRoleDeptList = sysRoleDeptService.list(Wrappers.lambdaQuery(SysRoleDeptPO.class).eq(SysRoleDeptPO::getRoleId, roleId));
+        return sysRoleDeptList.stream().map(item ->
+                sysDeptService.getById(item.getDeptId())
+        ).collect(Collectors.toList());
     }
 
-    private void validateRoleSource(SysRolePO source){
-        SysRolePO role = roleRepository.selectOne(new LambdaQueryWrapper<SysRolePO>()
-                .eq(SysRolePO::getCode, source.getCode())
-                .last("limit 1"));
-        if(role!=null&& !StrUtil.equals(role.getId(),source.getId())){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("角色编码{%s}不能重复",source.getCode()));
+    @Override
+    public List<SysRolePO> listSysRoleByUserId(Long userId) {
+        return listSysRoleByUserId(userId,null);
+    }
+
+    @Override
+    public List<SysRolePO> listSysRoleByUserId(Long userId, String tenantId) {
+        List<SysUserRolePO> sysUserRoleList = sysUserRoleService.list(Wrappers.lambdaQuery(SysUserRolePO.class).eq(SysUserRolePO::getUserId, userId)
+                .eq(StrUtil.isNotEmpty(tenantId),SysUserRolePO::getTenantId,tenantId));
+        if (sysUserRoleList.isEmpty()) {
+            return Lists.newArrayList();
         }
-        if(StrUtil.equals(source.getType(), CreateEnum.sys.name())){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统角色进行操作");
+        List<Long> roleIdList = sysUserRoleList.stream()
+                .map(SysUserRolePO::getRoleId)
+                .collect(Collectors.toList());
+
+        List<SysRolePO> sysRoleList = this.list(
+                Wrappers.lambdaQuery(SysRolePO.class)
+                .in(SysRolePO::getId, roleIdList)
+                .eq(SysRolePO::getStatus, String.valueOf(StatusEnum.YES.getValue())));
+        return sysRoleList;
+    }
+
+    @Override
+    public List<SysRolePO> selectOptions() {
+        List<SysRolePO> sysRoleList = this.list(Wrappers.lambdaQuery(SysRolePO.class)
+                .eq(SysRolePO::getStatus,String.valueOf(StatusEnum.YES.getValue()))
+                .orderByAsc(SysRolePO::getSort));
+        return sysRoleList;
+    }
+
+    private Boolean checkUniqueRoleCode(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
         }
-        if(StrUtil.isNotEmpty(source.getId())){
-            SysRolePO sysRolePO = roleRepository.selectById(source.getId());
-            if(sysRolePO==null){
-                return;
-            }
-            if(StrUtil.equals(sysRolePO.getType(), CreateEnum.sys.name())){
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统角色进行操作");
-            }
+        id = Objects.isNull(id) ? -1L : id;
+        SysRolePO entity = this.getOne(Wrappers.lambdaQuery(SysRolePO.class).eq(SysRolePO::getRoleCode, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
+    }
+
+    private Boolean checkUniqueRoleName(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
         }
+        id = Objects.isNull(id) ? -1L : id;
+        SysRolePO entity = this.getOne(Wrappers.lambdaQuery(SysRolePO.class).eq(SysRolePO::getRoleName, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
     }
+
 }

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

@@ -0,0 +1,20 @@
+package cn.tr.module.sys.user.service.impl;
+
+import cn.tr.module.sys.user.po.SysUserPostPO;
+import cn.tr.module.sys.user.repository.SysUserPostRepository;
+import cn.tr.module.sys.user.service.ISysUserPostService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 用户岗位表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
+ */
+@Service
+public class SysUserPostServiceImpl extends ServiceImpl<SysUserPostRepository, SysUserPostPO> implements ISysUserPostService {
+
+}

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

@@ -1,61 +1,20 @@
 package cn.tr.module.sys.user.service.impl;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.tr.module.sys.user.mapper.SysRoleMapper;
-import cn.tr.module.sys.user.dto.SysRoleDTO;
 import cn.tr.module.sys.user.po.SysUserRolePO;
-import cn.tr.module.sys.user.repository.SysRoleRepository;
 import cn.tr.module.sys.user.repository.SysUserRoleRepository;
 import cn.tr.module.sys.user.service.ISysUserRoleService;
-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 java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
- * @ClassName : SysRoleMenuServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年04月04日
+ * <p>
+ * 用户角色表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
 @Service
 public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleRepository, SysUserRolePO> implements ISysUserRoleService {
-    @Autowired
-    @Lazy
-    private ISysUserRoleService self;
 
-    @Autowired
-    private SysRoleRepository roleRepository;
-
-    @Override
-    public void assignUserRole(String userId,Collection<String> roleIds) {
-        baseMapper.delete(new LambdaQueryWrapper<SysUserRolePO>().eq(SysUserRolePO::getUserId,userId));
-        if(CollectionUtil.isNotEmpty(roleIds)){
-            List<SysUserRolePO> userRoles = roleIds.stream()
-                    .map(roleId -> {
-                        SysUserRolePO userRole = new SysUserRolePO();
-                        userRole.setRoleId(roleId);
-                        userRole.setUserId(userId);
-                        return userRole;
-                    }).collect(Collectors.toList());
-            saveBatch(userRoles);
-        }
-        self.delUserRoleCache(userId);
-    }
-
-    @Override
-    public Set<String> findUserByRoleId(Collection<String> roleIds) {
-        List<SysUserRolePO> userRoles = this.list(new LambdaQueryWrapper<SysUserRolePO>().in(SysUserRolePO::getRoleId, roleIds));
-        return userRoles.stream().map(SysUserRolePO::getUserId).collect(Collectors.toSet());
-    }
-
-    @Override
-    public List<SysRoleDTO> findAllRolesByUserId(String userId) {
-        return SysRoleMapper.INSTANCE.toSysRoleDTOList(roleRepository.findAllRoleByUserId(userId));
-    }
 }

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

@@ -1,266 +1,331 @@
 package cn.tr.module.sys.user.service.impl;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjectUtil;
+import cn.dev33.satoken.exception.NotPermissionException;
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.hutool.core.bean.BeanUtil;
 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.core.utils.PswUtils;
-import cn.tr.module.sys.config.SysConfigManager;
-import cn.tr.module.sys.user.constant.UserType;
-import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
-import cn.tr.module.sys.user.mapper.SysUserMapper;
-import cn.tr.module.sys.user.dto.SysUserDTO;
-import cn.tr.module.sys.user.dto.SysUserEditDTO;
-import cn.tr.module.sys.user.dto.SysUserQueryDTO;
+import cn.tr.module.common.menus.StatusEnum;
+import cn.tr.module.common.menus.YesNoEnum;
+import cn.tr.module.common.utils.Constants;
+import cn.tr.module.sys.exception.CustomException;
+import cn.tr.module.sys.oauth2.bean.LoginUser;
+import cn.tr.module.sys.oauth2.bean.SysRoleInfo;
+import cn.tr.module.sys.oauth2.utils.SecurityUtil;
+import cn.tr.module.sys.user.dto.*;
+import cn.tr.module.sys.user.po.*;
 import cn.tr.module.sys.user.repository.SysUserRepository;
-import cn.tr.module.sys.user.service.ISysUserPortalService;
-import cn.tr.module.sys.user.service.ISysUserPositionService;
-import cn.tr.module.sys.user.service.ISysUserRoleService;
-import cn.tr.module.sys.user.service.ISysUserService;
-import cn.tr.module.sys.user.po.SysUserPO;
+import cn.tr.module.sys.user.service.*;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import jakarta.annotation.Resource;
+import lombok.SneakyThrows;
+import org.apache.commons.compress.utils.Lists;
+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 org.springframework.util.CollectionUtils;
+import jakarta.annotation.Resource;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
-import cn.hutool.core.lang.Pair;
+
 /**
- * @ClassName : SysUserServiceImpl
- * @Description :
- * @Author : LF
- * @Date: 2023年03月31日
+ * <p>
+ * 用户表 服务实现类
+ * </p>
+ *
+ * @author Kevin
+ * @since 2021-06-10
  */
 @Service
-public class SysUserServiceImpl extends ServiceImpl<SysUserRepository,SysUserPO> implements ISysUserService {
+public class SysUserServiceImpl extends ServiceImpl<SysUserRepository, SysUserPO> implements ISysUserService {
 
     @Resource
-    @Lazy
-    private ISysUserService userService;
-    @Resource
-    @Lazy
-    private ISysUserRoleService userRoleService;
-    @Resource
-    @Lazy
-    private ISysUserPortalService userPortalService;
+    private ISysUserRoleService sysUserRoleService;
+
     @Resource
-    @Lazy
-    private ISysUserPositionService userPositionService;
+    private ISysUserPostService sysUserPostService;
+
+    @Autowired(required = false)  // 使用自动装配并允许为空,避免启动时立即创建依赖
+    @Lazy  // 使用懒加载避免循环依赖
+    private ISysDeptService sysDeptService;
+
     @Resource
-    @Lazy
-    private SysConfigManager configManager;
+    private ISysMenuService sysMenuService;
 
     @Resource
-    @Lazy
-    private ISysUserService sysUserService;
+    private ISysRoleService sysRoleService;
 
-    @Override
-    public List<SysUserDTO> selectSysUserList(SysUserQueryDTO query) {
-        return SysUserMapper.INSTANCE.toUserDTOList(baseMapper.selectList(
-                new LambdaQueryWrapper<SysUserPO>()
-                        .eq(StrUtil.isNotEmpty(query.getStatus()),SysUserPO::getStatus,query.getStatus())
-                        .eq(StrUtil.isNotEmpty(query.getOrgId()),SysUserPO::getOrgId,query.getOrgId())
-                        .like(StrUtil.isNotEmpty(query.getNickname()),SysUserPO::getNickname,query.getNickname())
-                        .like(StrUtil.isNotEmpty(query.getPhone()),SysUserPO::getPhone,query.getPhone())
-                        .like(StrUtil.isNotEmpty(query.getUsername()),SysUserPO::getUsername,query.getUsername())
-        ));
-    }
 
     @Override
-    public SysUserDTO selectSysUserById(String id) {
-        SysUserDTO result = SysUserMapper.INSTANCE.toUserDTO(baseMapper.selectById(id));
-        if(result==null){
-            return result;
+    public IPage<SysUserPO> page(Page reqPage, SysUserQueryDTO req) {
+        List<SysDeptPO> sysDeptList = Lists.newArrayList();
+        if (StrUtil.isNotBlank(req.getDeptId()) && sysDeptService != null) {
+            sysDeptList = sysDeptService.list(Wrappers.lambdaQuery(SysDeptPO.class).apply("find_in_set({0}, ancestors)", req.getDeptId()));
+        }
+        List<String> sysDeptIdList = sysDeptList.stream().map(item -> String.valueOf(item.getId())).collect(Collectors.toList());
+        LambdaQueryWrapper<SysUserPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.like(StrUtil.isNotBlank(req.getAccount()), SysUserPO::getAccount, req.getAccount());
+        queryWrapper.like(StrUtil.isNotBlank(req.getNickname()), SysUserPO::getNickname, req.getNickname());
+        queryWrapper.like(StrUtil.isNotBlank(req.getRealname()), SysUserPO::getRealname, req.getRealname());
+        queryWrapper.like(StrUtil.isNotBlank(req.getEnglishName()), SysUserPO::getEnglishName, req.getEnglishName());
+        queryWrapper.like(StrUtil.isNotBlank(req.getEmail()), SysUserPO::getEmail, req.getEmail());
+        queryWrapper.like(StrUtil.isNotBlank(req.getPhone()), SysUserPO::getPhone, req.getPhone());
+        queryWrapper.like(StrUtil.isNotBlank(req.getStaffNumber()), SysUserPO::getStaffNumber, req.getStaffNumber());
+        queryWrapper.eq(SysUserPO::getStatus, StatusEnum.YES.getValue());
+        queryWrapper.and(StrUtil.isNotBlank(req.getDeptId()), wrapper -> wrapper.eq(SysUserPO::getDeptId, req.getDeptId())
+                .or(!CollectionUtils.isEmpty(sysDeptIdList), wrapper2 -> wrapper2.in(SysUserPO::getDeptId, sysDeptIdList)));
+        queryWrapper.orderByAsc(SysUserPO::getCreateTime);
+        IPage<SysUserPO> page = this.page(reqPage, queryWrapper);
+        if(sysDeptService != null) {
+            page.getRecords().forEach(item -> {
+                // 设置部门名称
+                SysDeptPO sysDept = sysDeptService.getById(item.getDeptId());
+                item.setDeptName(Objects.isNull(sysDept) ? null : sysDept.getDeptName());
+            });
         }
-        result.setRoleIds(userRoleService.findRoleIdsByUserId(id));
-        result.setPortalIds(userPortalService.findPortalsByUserId(id).stream()
-                .map(SysUserPortalListDTO::getId).collect(Collectors.toSet()));
-        result.setPostIds(userPositionService.findPositionIdsByUserId(id));
-        return result;
+        return page;
     }
 
     @Override
-    public Pair<String,String> selectNickNameAndAvatarById(String userId) {
-        SysUserPO user = getById(userId);
-        if(user==null){
-            return null;
+    public List<SysUserPO> list(SysUserQueryDTO req) {
+        LambdaQueryWrapper<SysUserPO> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.like(StrUtil.isNotBlank(req.getAccount()), SysUserPO::getAccount, req.getAccount());
+        queryWrapper.like(StrUtil.isNotBlank(req.getNickname()), SysUserPO::getNickname, req.getNickname());
+        queryWrapper.like(StrUtil.isNotBlank(req.getRealname()), SysUserPO::getRealname, req.getRealname());
+        queryWrapper.like(StrUtil.isNotBlank(req.getEnglishName()), SysUserPO::getEnglishName, req.getEnglishName());
+        queryWrapper.like(StrUtil.isNotBlank(req.getEmail()), SysUserPO::getEmail, req.getEmail());
+        queryWrapper.like(StrUtil.isNotBlank(req.getPhone()), SysUserPO::getPhone, req.getPhone());
+        queryWrapper.like(StrUtil.isNotBlank(req.getStaffNumber()), SysUserPO::getStaffNumber, req.getStaffNumber());
+        queryWrapper.like(StrUtil.isNotBlank(req.getDeptId()), SysUserPO::getDeptId, req.getDeptId());
+        queryWrapper.eq(SysUserPO::getStatus, StatusEnum.YES.getValue());
+        queryWrapper.orderByAsc(SysUserPO::getCreateTime);
+        List<SysUserPO> list = this.list(queryWrapper);
+        if(sysDeptService != null) {
+            list.forEach(item -> {
+                SysDeptPO sysDept = sysDeptService.getById(item.getDeptId());
+                item.setDeptName(Objects.isNull(sysDept) ? null : sysDept.getDeptName());
+            });
         }
-        return Pair.of(user.getNickname(),user.getGender());
+        return list;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean updateSysUserById(SysUserEditDTO source) {
-        SysUserPO po = SysUserMapper.INSTANCE.toUserPO(source);
-        boolean result= baseMapper.updateById(po)!=0;
-        if(result){
-            assignUserRole(source.getId(),source.getRoleIds());
-            assignUserPortal(source.getId(),source.getPortalIds());
-            assignUserPosition(source.getId(),source.getPostIds());
+    public void add(SysUserAddDTO req) {
+        if (!this.checkUniqueAccount(req.getAccount(), null)) {
+            throw new CustomException("账号已存在");
         }
-        sysUserService.delNickNameAndAvatarCache(source.getId());
-        return result;
-    }
-
-    @Override
-    public SysUserDTO selectUserByUsername(String username) {
-        return SysUserMapper.INSTANCE.toUserDTO(baseMapper.selectOne(new LambdaQueryWrapper<SysUserPO>()
-                .eq(SysUserPO::getUsername,username)
-                .last("limit 1")));
-    }
+//        if (!this.checkUniqueEmail(req.getEmail(), null)) {
+//            throw new CustomException("邮箱已存在");
+//        }
+//        if (!this.checkUniquePhone(req.getPhone(), null)) {
+//            throw new CustomException("手机号已存在");
+//        }
+//        if (!this.checkUniqueStaffNumber(req.getStaffNumber(), null)) {
+//            throw new CustomException("工号已存在");
+//        }
+        LoginUser loginUser = SecurityUtil.getLoginUser();
+        if(!Boolean.TRUE.equals(loginUser.isSys())&&Boolean.TRUE.equals(req.getIsSys())){
+            throw new NotPermissionException("无权设置系统用户");
+        }
+        SysUserPO entity = BeanUtil.copyProperties(req, SysUserPO.class);
+        // 密码加密
+        entity.setPassword(SecurityUtil.encryptPassword(entity.getPassword()));
+        entity.setPswModified(YesNoEnum.NO.getCode());
+        this.save(entity);
 
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean updatePsw(String userId, String oldPsw, String newPsw) {
-        SysUserPO user = baseMapper.selectById(userId);
-        if(user==null){
-            return true;
+        // 删除用户与岗位关联
+        sysUserPostService.remove(Wrappers.lambdaQuery(SysUserPostPO.class).eq(SysUserPostPO::getUserId, entity.getId()));
+        // 新增用户与岗位关联
+        if (Objects.nonNull(req.getPostIds())) {
+            List<SysUserPostPO> sysUserPostList = req.getPostIds().stream().map(item -> {
+                SysUserPostPO sysUserPost = new SysUserPostPO();
+                sysUserPost.setUserId(entity.getId());
+                sysUserPost.setPostId(item);
+                return sysUserPost;
+            }).collect(Collectors.toList());
+            sysUserPostService.saveBatch(sysUserPostList);
         }
-        if (StrUtil.isNotBlank(user.getPassword())&&!PswUtils.matchesPassword(oldPsw, user.getPassword())) {
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"旧密码错误");
+
+        // 删除用户与角色关联
+        sysUserRoleService.remove(Wrappers.lambdaQuery(SysUserRolePO.class).eq(SysUserRolePO::getUserId, entity.getId()));
+        // 新增用户与角色关联
+        if (Objects.nonNull(req.getRoleIds())) {
+            List<SysUserRolePO> sysUserRoleList = req.getRoleIds().stream().map(item -> {
+                SysUserRolePO sysUserRole = new SysUserRolePO();
+                sysUserRole.setUserId(entity.getId());
+                sysUserRole.setRoleId(item);
+                return sysUserRole;
+            }).collect(Collectors.toList());
+            sysUserRoleService.saveBatch(sysUserRoleList);
         }
-        SysUserPO updateUser = new SysUserPO();
-        updateUser.setId(user.getId());
-        updateUser.setPassword(PswUtils.encryptPassword(newPsw));
-        return  baseMapper.updateById(updateUser) != 0;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean insertSysUser(SysUserDTO source) {
-        boolean result=false;
-        SysUserPO insertUser = SysUserMapper.INSTANCE.toUserPO(source);
-        insertUser.setType(UserType.NORMAL);
-        insertUser.setPassword(PswUtils.encryptPassword(insertUser.getPassword()));
-        //所有租户下的正常使用的账号
-        List<SysUserDTO> allUsingUser = userService.selectUserByUsernameIgnoreTenant(source.getUsername());
-        if(CollectionUtil.isNotEmpty(allUsingUser)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("系统中已存在账户{%s},不可重复添加",source.getUsername()));
+    public void edit(SysUserEditDTO req) {
+        if (!this.checkUniqueAccount(req.getAccount(), req.getId())) {
+            throw new CustomException("账号已存在");
         }
-        //当前租户下的账号
-        SysUserPO delUser = baseMapper.selectUserByUsernameIgnoreDel(source.getUsername());
-        if(delUser==null){
-            result= baseMapper.insert(insertUser)!=0;
-        }else {
-            if(Boolean.TRUE.equals(delUser.getDeleted())){
-                baseMapper.recoverBatch(Arrays.asList(delUser));
-                result= baseMapper.updateById(insertUser)!=0;
-            }else {
-                throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("当前租户中已存在账户{%s},不可重复添加",source.getUsername()));
+        if(Boolean.TRUE.equals(req.getIsSys())){
+            try {
+                LoginUser loginUser =SecurityUtil.getLoginUser();
+                if(!Boolean.TRUE.equals(loginUser.isSys())){
+                    throw new CustomException("当前用户没有操作系统级别用户的权限");
+                }
+            }catch (Exception e){
+                throw new CustomException("当前用户没有操作系统级别用户的权限");
             }
         }
-        source.setId(insertUser.getId());
-        if(result){
-            assignUserRole(source.getId(),source.getRoleIds());
-            assignUserPortal(source.getId(),source.getPortalIds());
-            assignUserPosition(source.getId(),source.getPostIds());
-            sysUserService.delUserIdAndNickNameCache();
+        // 当前用户不是超级管理员,不允许修改
+        if (!SecurityUtil.getId().equals(req.getId()) && SecurityUtil.isSysSuperAdmin(req.getId())) {
+            throw new CustomException("超管账户不允许修改");
+        }
+        SysUserPO entity = BeanUtil.copyProperties(req, SysUserPO.class);
+        this.updateById(entity);
+        // 删除用户与岗位关联
+        sysUserPostService.remove(Wrappers.lambdaQuery(SysUserPostPO.class).eq(SysUserPostPO::getUserId, entity.getId()));
+        // 新增用户与岗位关联
+        if (Objects.nonNull(req.getPostIds())) {
+            List<SysUserPostPO> sysUserPostList = req.getPostIds().stream().map(item -> {
+                SysUserPostPO sysUserPost = new SysUserPostPO();
+                sysUserPost.setUserId(entity.getId());
+                sysUserPost.setPostId(item);
+                return sysUserPost;
+            }).collect(Collectors.toList());
+            sysUserPostService.saveBatch(sysUserPostList);
         }
-        return result;
-    }
 
-    @Override
-    public String insertWxUserAndReturnId(SysUserDTO source,String appId) {
-        SysUserPO insertUser = SysUserMapper.INSTANCE.toUserPO(source);
-        insertUser.setType(UserType.NORMAL);
-        //所有租户下的正常使用的账号
-        SysUserPO user = baseMapper.selectOne(new LambdaQueryWrapper<SysUserPO>()
-                .eq(SysUserPO::getOpenId, source.getOpenId())
-//                .eq(SysUserPO::getAppId, appId)
-                .last("limit 1"));
-        if(ObjectUtil.isNotEmpty(user)){
-            insertUser.setId(user.getId());
-            baseMapper.updateById(user);
-            return user.getId();
-        }else {
-            baseMapper.insert(insertUser);
-            return insertUser.getId();
+        // 删除用户与角色关联
+        sysUserRoleService.remove(Wrappers.lambdaQuery(SysUserRolePO.class).eq(SysUserRolePO::getUserId, entity.getId()));
+        // 新增用户与角色关联
+        if (Objects.nonNull(req.getRoleIds())) {
+            List<SysUserRolePO> sysUserRoleList = req.getRoleIds().stream().map(item -> {
+                SysUserRolePO sysUserRole = new SysUserRolePO();
+                sysUserRole.setUserId(entity.getId());
+                sysUserRole.setRoleId(item);
+                return sysUserRole;
+            }).collect(Collectors.toList());
+            sysUserRoleService.saveBatch(sysUserRoleList);
+
+            //更新缓存用户权限信息
+            Set<String> permissionsByUserId = sysMenuService.getPermissionsByUserId(req.getId());
+            List<String> tokens = SecurityUtil.getStpLogic().getTokenValueListByLoginId(req.getId());
+            List<SysRolePO> sysRoleList = sysRoleService.listSysRoleByUserId(req.getId());
+            StpLogic stpLogic = SecurityUtil.getStpLogic();
+            tokens.parallelStream()
+                    .forEach(token->{
+                        SaSession tokenSessionByToken = stpLogic.getTokenSessionByToken(token);
+                        LoginUser user = (LoginUser) tokenSessionByToken.get(Constants.LOGIN_USER_KEY);
+                        if(user!=null){
+                            user.setPermissions(permissionsByUserId);
+                            user.setRoles(sysRoleList.stream().map(item -> BeanUtil.copyProperties(item, SysRoleInfo.class)).collect(Collectors.toList()));
+                            tokenSessionByToken.set(Constants.LOGIN_USER_KEY,user);
+                        }
+                    });
         }
     }
 
     @Override
-    @TenantIgnore
-    public List<SysUserDTO> selectUserByUsernameIgnoreTenant(String username) {
-        return SysUserMapper.INSTANCE.toUserDTOList(baseMapper.selectList(new LambdaQueryWrapper<SysUserPO>()
-                .eq(SysUserPO::getUsername,username)));
+    @Transactional(rollbackFor = Exception.class)
+    public void remove(Long id) {
+        sysUserRoleService.remove(new QueryWrapper<SysUserRolePO>()
+                .lambda().eq(SysUserRolePO::getUserId,id));
+        this.removeById(id);
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteSysUserByIds(Collection<String> ids) {
-        if(CollectionUtil.isEmpty(ids)){
-            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"请选择要删除的数据");
+    public SysUserPO view(String id) {
+        SysUserPO sysUser = this.getById(id);
+        if(sysUser==null){
+            throw new CustomException("查询用户不存在");
         }
-        int result = baseMapper.deleteByIds(ids);
-        sysUserService.delUserIdAndNickNameCache();
-        return result;
-    }
+        List<SysUserRolePO> sysUserRoleList = sysUserRoleService.list(Wrappers.lambdaQuery(SysUserRolePO.class)
+                .eq(SysUserRolePO::getUserId, sysUser.getId()));
+        sysUser.setRoleIds(sysUserRoleList.stream().map(item2 -> item2.getRoleId().toString()).collect(Collectors.toList()));
 
-    @Override
-    @TenantIgnore
-    public boolean isValidUsername(String userId, String username) {
-        return baseMapper.selectCount(new LambdaQueryWrapper<SysUserPO>()
-                .ne(StrUtil.isNotEmpty(userId),SysUserPO::getId,userId)
-                .eq(SysUserPO::getUsername,username))==0;
+        List<SysUserPostPO> sysUserPostList = sysUserPostService.list(Wrappers.lambdaQuery(SysUserPostPO.class)
+                .eq(SysUserPostPO::getUserId, sysUser.getId()));
+        sysUser.setPostIds(sysUserPostList.stream().map(item2 -> item2.getPostId().toString()).collect(Collectors.toList()));
+        return sysUser;
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean resetPsw(Collection<String> userIds) {
-        String defaultPsw = configManager.getCurrent().getDefaultPsw();
-        String password = PswUtils.encryptPassword(defaultPsw);
-        List<SysUserPO> users = baseMapper.selectByIds(userIds);
-        for (SysUserPO user : users) {
-            user.setPassword(password);
-        }
-        this.updateBatchById(users);
-        return true;
+    public void resetPwd(SysUserResetPwdDTO<Long> req) {
+        SysUserPO entity = BeanUtil.copyProperties(req, SysUserPO.class);
+        // 密码加密
+        entity.setPassword(SecurityUtil.encryptPassword(entity.getPassword()));
+        entity.setPswModified(YesNoEnum.YES.getCode());
+        this.updateById(entity);
     }
 
+    /**
+     * 根据用户id查询用户信息
+     * @param userId
+     * @return
+     */
     @Override
-    public void updateLastLoginInfo(String id, Date loginTime, String ip, String cityInfo) {
-        SysUserPO user = this.getById(id);
-        user.setLastLoginDate(loginTime);
-        user.setLastLoginIp(ip);
-        user.setLastLoginAddress(cityInfo);
-        this.updateById(user);
-        sysUserService.delUserIdAndNickNameCache();
+    public SysUserDTO selectSysUserById(String userId) {
+        SysUserPO byId = this.getById(userId);
+        return BeanUtil.copyProperties(byId, SysUserDTO.class);
     }
 
-    @Override
-    public List<Pair<String, String>> selectAllUserIdAndNickName() {
-        List<SysUserPO> allUser = baseMapper.selectList(new LambdaQueryWrapper<SysUserPO>()
-                .select(SysUserPO::getId, SysUserPO::getNickname));
-        List<Pair<String, String>> result = new ArrayList<>();
-        for (SysUserPO userPO : allUser) {
-            result.add(Pair.of(userPO.getId(),userPO.getNickname()));
+    @SneakyThrows
+    private Boolean checkUniqueAccount(String value, Long id){
+        if (StrUtil.isBlank(value)) {
+            return true;
         }
-        return result;
+        id = Objects.isNull(id) ? -1L : id;
+        SysUserPO entity = CompletableFuture.supplyAsync(() ->
+                getOne(Wrappers.lambdaQuery(SysUserPO.class)
+                        .select(SysUserPO::getId, SysUserPO::getAccount)
+                        .eq(SysUserPO::getAccount, value)
+                        .eq(SysUserPO::getDelFlag,"0"))
+        ).get();
+
+
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
     }
 
-    @Override
-    public SysUserDTO selectUserByOpenId(String openId) {
-        SysUserPO userPO = baseMapper.selectOne(new LambdaQueryWrapper<SysUserPO>()
-                .eq(SysUserPO::getOpenId, openId));
-        if (userPO == null) {
-            return null;
+    private Boolean checkUniqueEmail(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
         }
-        return SysUserMapper.INSTANCE.toUserDTO(userPO);
+        id = Objects.isNull(id) ? -1L : id;
+        SysUserPO entity = getOne(Wrappers.lambdaQuery(SysUserPO.class)
+                .select(SysUserPO::getId, SysUserPO::getEmail)
+                .eq(SysUserPO::getEmail, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
     }
 
-    private void assignUserRole(String userId, Set<String> roleIds){
-        userRoleService.assignUserRole(userId,roleIds);
+    private Boolean checkUniquePhone(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
+        }
+        id = Objects.isNull(id) ? -1L : id;
+        SysUserPO entity = getOne(Wrappers.lambdaQuery(SysUserPO.class)
+                .select(SysUserPO::getId, SysUserPO::getPhone)
+                .eq(SysUserPO::getPhone, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
     }
 
-    private void assignUserPortal(String userId, Set<String> portalIds){
-        userPortalService.assignUserPortal(userId,portalIds);
+    private Boolean checkUniqueStaffNumber(String value, Long id) {
+        if (StrUtil.isBlank(value)) {
+            return true;
+        }
+        id = Objects.isNull(id) ? -1L : id;
+        SysUserPO entity = getOne(Wrappers.lambdaQuery(SysUserPO.class)
+                .select(SysUserPO::getId, SysUserPO::getStaffNumber)
+                .eq(SysUserPO::getStaffNumber, value));
+        return Objects.isNull(entity) || entity.getId().longValue() == id.longValue();
     }
 
-    private void assignUserPosition(String userId, Set<String> positionIds){
-        userPositionService.assignUserPosition(userId,positionIds);
-    }
-}
+}

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini