From 4d566071db7853c66805a1ffac2fd9c93a6aac8a Mon Sep 17 00:00:00 2001
From: xlsea <m@xlsea.cn>
Date: 星期一, 16 十二月 2024 19:26:37 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java              |   19 +
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java         |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java           |   29 +
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java        |    3 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java     |    3 
 pom.xml                                                                                                    |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java                   |    8 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java           |   14 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/FormatsType.java                |  146 +++++++++
 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java     |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java     |    2 
 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java |    8 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java            |  165 ++++++++++
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java                |   17 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java              |    9 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java           |    8 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java                 |    2 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java          |    7 
 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeyRequest.java     |    4 
 ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java                                     |   13 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java           |   23 +
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java                    |   12 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java               |    7 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java      |    4 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java               |   37 ++
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java                  |  250 +++++++++++----
 ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java                                |   26 +
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java        |    5 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java           |    7 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/PostService.java              |   10 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/RoleService.java              |   10 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java       |    2 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/PostDTO.java               |   46 ++
 33 files changed, 780 insertions(+), 124 deletions(-)

diff --git a/pom.xml b/pom.xml
index 58672ca..ebf2814 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,7 +36,7 @@
         <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
         <lombok.version>1.18.34</lombok.version>
         <bouncycastle.version>1.76</bouncycastle.version>
-        <justauth.version>1.16.6</justauth.version>
+        <justauth.version>1.16.7</justauth.version>
         <!-- 绂荤嚎IP鍦板潃瀹氫綅搴� -->
         <ip2region.version>2.7.0</ip2region.version>
 
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
index 2eae90a..41a802b 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
@@ -14,6 +14,7 @@
 import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.constant.SystemConstants;
 import org.dromara.common.core.constant.TenantConstants;
+import org.dromara.common.core.domain.dto.PostDTO;
 import org.dromara.common.core.domain.dto.RoleDTO;
 import org.dromara.common.core.domain.model.LoginUser;
 import org.dromara.common.core.enums.LoginType;
@@ -60,6 +61,7 @@
     private final ISysSocialService sysSocialService;
     private final ISysRoleService roleService;
     private final ISysDeptService deptService;
+    private final ISysPostService postService;
     private final SysUserMapper userMapper;
 
 
@@ -148,21 +150,24 @@
      */
     public LoginUser buildLoginUser(SysUserVo user) {
         LoginUser loginUser = new LoginUser();
+        Long userId = user.getUserId();
         loginUser.setTenantId(user.getTenantId());
-        loginUser.setUserId(user.getUserId());
+        loginUser.setUserId(userId);
         loginUser.setDeptId(user.getDeptId());
         loginUser.setUsername(user.getUserName());
         loginUser.setNickname(user.getNickName());
         loginUser.setUserType(user.getUserType());
-        loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId()));
-        loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId()));
+        loginUser.setMenuPermission(permissionService.getMenuPermission(userId));
+        loginUser.setRolePermission(permissionService.getRolePermission(userId));
         if (ObjectUtil.isNotNull(user.getDeptId())) {
             Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById);
             loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY));
             loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY));
         }
-        List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId());
+        List<SysRoleVo> roles = roleService.selectRolesByUserId(userId);
+        List<SysPostVo> posts = postService.selectPostsByUserId(userId);
         loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class));
+        loginUser.setPosts(BeanUtil.copyToList(posts, PostDTO.class));
         return loginUser;
     }
 
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
index 948ed9a..fa9b618 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
@@ -5,9 +5,17 @@
 import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import me.zhyd.oauth.config.AuthConfig;
+import me.zhyd.oauth.model.AuthCallback;
+import me.zhyd.oauth.model.AuthResponse;
+import me.zhyd.oauth.model.AuthToken;
+import me.zhyd.oauth.model.AuthUser;
+import me.zhyd.oauth.request.AuthRequest;
+import me.zhyd.oauth.request.AuthWechatMiniProgramRequest;
 import org.dromara.common.core.constant.SystemConstants;
 import org.dromara.common.core.domain.model.XcxLoginBody;
 import org.dromara.common.core.domain.model.XcxLoginUser;
+import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.ValidatorUtils;
 import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
@@ -39,12 +47,24 @@
         // 澶氫釜灏忕▼搴忚瘑鍒娇鐢�
         String appid = loginBody.getAppid();
 
-        // todo 浠ヤ笅鑷瀹炵幇
         // 鏍¢獙 appid + appsrcret + xcxCode 璋冪敤鐧诲綍鍑瘉鏍¢獙鎺ュ彛 鑾峰彇 session_key 涓� openid
-        String openid = "";
+        AuthRequest authRequest = new AuthWechatMiniProgramRequest(AuthConfig.builder()
+            .clientId(appid).clientSecret("鑷濉啓瀵嗛挜 鍙牴鎹笉鍚宎ppid濉叆涓嶅悓瀵嗛挜")
+            .ignoreCheckRedirectUri(true).ignoreCheckState(true).build());
+        AuthCallback authCallback = new AuthCallback();
+        authCallback.setCode(xcxCode);
+        AuthResponse<AuthUser> resp = authRequest.login(authCallback);
+        String openid, unionId;
+        if (resp.ok()) {
+            AuthToken token = resp.getData().getToken();
+            openid = token.getOpenId();
+            // 寰俊灏忕▼搴忓彧鏈夊叧鑱斿埌寰俊寮�鏀惧钩鍙颁笅涔嬪悗鎵嶈兘鑾峰彇鍒� unionId锛屽洜姝nionId涓嶄竴瀹氳兘杩斿洖銆�
+            unionId = token.getUnionId();
+        } else {
+            throw new ServiceException(resp.getMsg());
+        }
         // 妗嗘灦鐧诲綍涓嶉檺鍒朵粠浠�涔堣〃鏌ヨ 鍙鏈�缁堟瀯寤哄嚭 LoginUser 鍗冲彲
         SysUserVo user = loadUserByOpenid(openid);
-
         // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜�
         XcxLoginUser loginUser = new XcxLoginUser();
         loginUser.setTenantId(user.getTenantId());
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java
new file mode 100644
index 0000000..65c012f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/DeptDTO.java
@@ -0,0 +1,37 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 閮ㄩ棬
+ *
+ * @author AprilWind
+ */
+
+@Data
+@NoArgsConstructor
+public class DeptDTO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 閮ㄩ棬ID
+     */
+    private Long deptId;
+
+    /**
+     * 鐖堕儴闂↖D
+     */
+    private Long parentId;
+
+    /**
+     * 閮ㄩ棬鍚嶇О
+     */
+    private String deptName;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/PostDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/PostDTO.java
new file mode 100644
index 0000000..7536ee3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/PostDTO.java
@@ -0,0 +1,46 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 宀椾綅
+ *
+ * @author AprilWind
+ */
+@Data
+@NoArgsConstructor
+public class PostDTO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 宀椾綅ID
+     */
+    private Long postId;
+
+    /**
+     * 閮ㄩ棬id
+     */
+    private Long deptId;
+
+    /**
+     * 宀椾綅缂栫爜
+     */
+    private String postCode;
+
+    /**
+     * 宀椾綅鍚嶇О
+     */
+    private String postName;
+
+    /**
+     * 宀椾綅绫诲埆缂栫爜
+     */
+    private String postCategory;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java
index c723e76..338d4d7 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java
@@ -1,8 +1,9 @@
 package org.dromara.common.core.domain.model;
 
-import org.dromara.common.core.domain.dto.RoleDTO;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.dromara.common.core.domain.dto.PostDTO;
+import org.dromara.common.core.domain.dto.RoleDTO;
 
 import java.io.Serial;
 import java.io.Serializable;
@@ -112,6 +113,11 @@
     private List<RoleDTO> roles;
 
     /**
+     * 宀椾綅瀵硅薄
+     */
+    private List<PostDTO> posts;
+
+    /**
      * 鏁版嵁鏉冮檺 褰撳墠瑙掕壊ID
      */
     private Long roleId;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/FormatsType.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/FormatsType.java
new file mode 100644
index 0000000..8d4b6d9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/FormatsType.java
@@ -0,0 +1,146 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.dromara.common.core.utils.StringUtils;
+
+/*
+ * 鏃ユ湡鏍煎紡
+ * "yyyy"锛�4浣嶆暟鐨勫勾浠斤紝渚嬪锛�2023骞磋〃绀轰负"2023"銆�
+ * "yy"锛�2浣嶆暟鐨勫勾浠斤紝渚嬪锛�2023骞磋〃绀轰负"23"銆�
+ * "MM"锛�2浣嶆暟鐨勬湀浠斤紝鍙栧�艰寖鍥翠负01鍒�12锛屼緥濡傦細7鏈堣〃绀轰负"07"銆�
+ * "M"锛氫笉甯﹀墠瀵奸浂鐨勬湀浠斤紝鍙栧�艰寖鍥翠负1鍒�12锛屼緥濡傦細7鏈堣〃绀轰负"7"銆�
+ * "dd"锛�2浣嶆暟鐨勬棩鏈燂紝鍙栧�艰寖鍥翠负01鍒�31锛屼緥濡傦細22鏃ヨ〃绀轰负"22"銆�
+ * "d"锛氫笉甯﹀墠瀵奸浂鐨勬棩鏈燂紝鍙栧�艰寖鍥翠负1鍒�31锛屼緥濡傦細22鏃ヨ〃绀轰负"22"銆�
+ * "EEEE"锛氭槦鏈熺殑鍏ㄥ悕锛屼緥濡傦細鏄熸湡涓夎〃绀轰负"Wednesday"銆�
+ * "E"锛氭槦鏈熺殑缂╁啓锛屼緥濡傦細鏄熸湡涓夎〃绀轰负"Wed"銆�
+ * "DDD" 鎴� "D"锛氫竴骞翠腑鐨勭鍑犲ぉ锛屽彇鍊艰寖鍥翠负001鍒�366锛屼緥濡傦細绗�200澶╄〃绀轰负"200"銆�
+ * 鏃堕棿鏍煎紡
+ * "HH"锛�24灏忔椂鍒剁殑灏忔椂鏁帮紝鍙栧�艰寖鍥翠负00鍒�23锛屼緥濡傦細涓嬪崍5鐐硅〃绀轰负"17"銆�
+ * "hh"锛�12灏忔椂鍒剁殑灏忔椂鏁帮紝鍙栧�艰寖鍥翠负01鍒�12锛屼緥濡傦細涓嬪崍5鐐硅〃绀轰负"05"銆�
+ * "mm"锛氬垎閽熸暟锛屽彇鍊艰寖鍥翠负00鍒�59锛屼緥濡傦細30鍒嗛挓琛ㄧず涓�"30"銆�
+ * "ss"锛氱鏁帮紝鍙栧�艰寖鍥翠负00鍒�59锛屼緥濡傦細45绉掕〃绀轰负"45"銆�
+ * "SSS"锛氭绉掓暟锛屽彇鍊艰寖鍥翠负000鍒�999锛屼緥濡傦細123姣琛ㄧず涓�"123"銆�
+ */
+
+/**
+ * 鏃ユ湡鏍煎紡涓庢椂闂存牸寮忔灇涓�
+ */
+@Getter
+@AllArgsConstructor
+public enum FormatsType {
+
+    /**
+     * 渚嬪锛�2023骞磋〃绀轰负"23"
+     */
+    YY("yy"),
+
+    /**
+     * 渚嬪锛�2023骞磋〃绀轰负"2023"
+     */
+    YYYY("yyyy"),
+
+    /**
+     * 渚嬩緥濡傦紝2023骞�7鏈堝彲浠ヨ〃绀轰负 "2023-07"
+     */
+    YYYY_MM("yyyy-MM"),
+
+    /**
+     * 渚嬪锛屾棩鏈� "2023骞�7鏈�22鏃�" 鍙互琛ㄧず涓� "2023-07-22"
+     */
+    YYYY_MM_DD("yyyy-MM-dd"),
+
+    /**
+     * 渚嬪锛屽綋鍓嶆椂闂村鏋滄槸 "2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�"锛屽垯鍙互琛ㄧず涓� "2023-07-22 15:30"
+     */
+    YYYY_MM_DD_HH_MM("yyyy-MM-dd HH:mm"),
+
+    /**
+     * 渚嬪锛屽綋鍓嶆椂闂村鏋滄槸 "2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�45绉�"锛屽垯鍙互琛ㄧず涓� "2023-07-22 15:30:45"
+     */
+    YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss"),
+
+    /**
+     * 渚嬪锛氫笅鍗�3鐐�30鍒�45绉掞紝琛ㄧず涓� "15:30:45"
+     */
+    HH_MM_SS("HH:mm:ss"),
+
+    /**
+     * 渚嬩緥濡傦紝2023骞�7鏈堝彲浠ヨ〃绀轰负 "2023/07"
+     */
+    YYYY_MM_SLASH("yyyy/MM"),
+
+    /**
+     * 渚嬪锛屾棩鏈� "2023骞�7鏈�22鏃�" 鍙互琛ㄧず涓� "2023/07/22"
+     */
+    YYYY_MM_DD_SLASH("yyyy/MM/dd"),
+
+    /**
+     * 渚嬪锛屽綋鍓嶆椂闂村鏋滄槸 "2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�45绉�"锛屽垯鍙互琛ㄧず涓� "2023/07/22 15:30:45"
+     */
+    YYYY_MM_DD_HH_MM_SLASH("yyyy/MM/dd HH:mm"),
+
+    /**
+     * 渚嬪锛屽綋鍓嶆椂闂村鏋滄槸 "2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�45绉�"锛屽垯鍙互琛ㄧず涓� "2023/07/22 15:30:45"
+     */
+    YYYY_MM_DD_HH_MM_SS_SLASH("yyyy/MM/dd HH:mm:ss"),
+
+    /**
+     * 渚嬩緥濡傦紝2023骞�7鏈堝彲浠ヨ〃绀轰负 "2023.07"
+     */
+    YYYY_MM_DOT("yyyy.MM"),
+
+    /**
+     * 渚嬪锛屾棩鏈� "2023骞�7鏈�22鏃�" 鍙互琛ㄧず涓� "2023.07.22"
+     */
+    YYYY_MM_DD_DOT("yyyy.MM.dd"),
+
+    /**
+     * 渚嬪锛屽綋鍓嶆椂闂村鏋滄槸 "2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�"锛屽垯鍙互琛ㄧず涓� "2023.07.22 15:30"
+     */
+    YYYY_MM_DD_HH_MM_DOT("yyyy.MM.dd HH:mm"),
+
+    /**
+     * 渚嬪锛屽綋鍓嶆椂闂村鏋滄槸 "2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�45绉�"锛屽垯鍙互琛ㄧず涓� "2023.07.22 15:30:45"
+     */
+    YYYY_MM_DD_HH_MM_SS_DOT("yyyy.MM.dd HH:mm:ss"),
+
+    /**
+     * 渚嬪锛�2023骞�7鏈堝彲浠ヨ〃绀轰负 "202307"
+     */
+    YYYYMM("yyyyMM"),
+
+    /**
+     * 渚嬪锛�2023骞�7鏈�22鏃ュ彲浠ヨ〃绀轰负 "20230722"
+     */
+    YYYYMMDD("yyyyMMdd"),
+
+    /**
+     * 渚嬪锛�2023骞�7鏈�22鏃ヤ笅鍗�3鐐瑰彲浠ヨ〃绀轰负 "2023072215"
+     */
+    YYYYMMDDHH("yyyyMMddHH"),
+
+    /**
+     * 渚嬪锛�2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒嗗彲浠ヨ〃绀轰负 "202307221530"
+     */
+    YYYYMMDDHHMM("yyyyMMddHHmm"),
+
+    /**
+     * 渚嬪锛�2023骞�7鏈�22鏃ヤ笅鍗�3鐐�30鍒�45绉掑彲浠ヨ〃绀轰负 "20230722153045"
+     */
+    YYYYMMDDHHMMSS("yyyyMMddHHmmss");
+
+    /**
+     * 鏃堕棿鏍煎紡
+     */
+    private final String timeFormat;
+
+    public static FormatsType getFormatsType(String str) {
+        for (FormatsType value : values()) {
+            if (StringUtils.contains(str, value.getTimeFormat())) {
+                return value;
+            }
+        }
+        throw new RuntimeException("'FormatsType' not found By " + str);
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java
index db9463e..f93d177 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/DeptService.java
@@ -1,5 +1,9 @@
 package org.dromara.common.core.service;
 
+import org.dromara.common.core.domain.dto.DeptDTO;
+
+import java.util.List;
+
 /**
  * 閫氱敤 閮ㄩ棬鏈嶅姟
  *
@@ -15,4 +19,19 @@
      */
     String selectDeptNameByIds(String deptIds);
 
+    /**
+     * 鏍规嵁閮ㄩ棬ID鏌ヨ閮ㄩ棬璐熻矗浜�
+     *
+     * @param deptId 閮ㄩ棬ID锛岀敤浜庢寚瀹氶渶瑕佹煡璇㈢殑閮ㄩ棬
+     * @return 杩斿洖璇ラ儴闂ㄧ殑璐熻矗浜篒D
+     */
+    Long selectDeptLeaderById(Long deptId);
+
+    /**
+     * 鏌ヨ閮ㄩ棬
+     *
+     * @return 閮ㄩ棬鍒楄〃
+     */
+    List<DeptDTO> selectDeptsByList();
+
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/PostService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/PostService.java
new file mode 100644
index 0000000..41d4e83
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/PostService.java
@@ -0,0 +1,10 @@
+package org.dromara.common.core.service;
+
+/**
+ * 閫氱敤 宀椾綅鏈嶅姟
+ *
+ * @author AprilWind
+ */
+public interface PostService {
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/RoleService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/RoleService.java
new file mode 100644
index 0000000..ba62c82
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/RoleService.java
@@ -0,0 +1,10 @@
+package org.dromara.common.core.service;
+
+/**
+ * 閫氱敤 瑙掕壊鏈嶅姟
+ *
+ * @author AprilWind
+ */
+public interface RoleService {
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
index 43aef28..67cd54f 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
@@ -82,4 +82,13 @@
      * @return 鐢ㄦ埛
      */
     List<UserDTO> selectUsersByDeptIds(List<Long> deptIds);
+
+    /**
+     * 閫氳繃宀椾綅ID鏌ヨ鐢ㄦ埛
+     *
+     * @param postIds 宀椾綅ids
+     * @return 鐢ㄦ埛
+     */
+    List<UserDTO> selectUsersByPostIds(List<Long> postIds);
+
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
index 72178a7..88cdbbc 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java
@@ -3,16 +3,15 @@
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.commons.lang3.time.DateFormatUtils;
+import org.dromara.common.core.enums.FormatsType;
+import org.dromara.common.core.exception.ServiceException;
 
 import java.lang.management.ManagementFactory;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
+import java.time.*;
 import java.util.Date;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 鏃堕棿宸ュ叿绫�
@@ -21,86 +20,137 @@
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
-
-    public static final String YYYY = "yyyy";
-
-    public static final String YYYY_MM = "yyyy-MM";
-
-    public static final String YYYY_MM_DD = "yyyy-MM-dd";
-
-    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
-
-    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
-
     private static final String[] PARSE_PATTERNS = {
         "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
         "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
         "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
 
     /**
-     * 鑾峰彇褰撳墠Date鍨嬫棩鏈�
+     * 鑾峰彇褰撳墠鏃ユ湡鍜屾椂闂�
      *
-     * @return Date() 褰撳墠鏃ユ湡
+     * @return 褰撳墠鏃ユ湡鍜屾椂闂寸殑 Date 瀵硅薄琛ㄧず
      */
     public static Date getNowDate() {
         return new Date();
     }
 
     /**
-     * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
+     * 鑾峰彇褰撳墠鏃ユ湡鐨勫瓧绗︿覆琛ㄧず锛屾牸寮忎负YYYY-MM-DD
      *
-     * @return String
+     * @return 褰撳墠鏃ユ湡鐨勫瓧绗︿覆琛ㄧず
      */
     public static String getDate() {
-        return dateTimeNow(YYYY_MM_DD);
+        return dateTimeNow(FormatsType.YYYY_MM_DD);
     }
 
+    /**
+     * 鑾峰彇褰撳墠鏃ユ湡鐨勫瓧绗︿覆琛ㄧず锛屾牸寮忎负yyyyMMdd
+     *
+     * @return 褰撳墠鏃ユ湡鐨勫瓧绗︿覆琛ㄧず
+     */
+    public static String getCurrentDate() {
+        return DateFormatUtils.format(new Date(), FormatsType.YYYYMMDD.getTimeFormat());
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃ユ湡鐨勮矾寰勬牸寮忓瓧绗︿覆锛屾牸寮忎负"yyyy/MM/dd"
+     *
+     * @return 褰撳墠鏃ユ湡鐨勮矾寰勬牸寮忓瓧绗︿覆
+     */
+    public static String datePath() {
+        Date now = new Date();
+        return DateFormatUtils.format(now, FormatsType.YYYY_MM_DD_SLASH.getTimeFormat());
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃堕棿鐨勫瓧绗︿覆琛ㄧず锛屾牸寮忎负YYYY-MM-DD HH:MM:SS
+     *
+     * @return 褰撳墠鏃堕棿鐨勫瓧绗︿覆琛ㄧず
+     */
     public static String getTime() {
-        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+        return dateTimeNow(FormatsType.YYYY_MM_DD_HH_MM_SS);
     }
 
+    /**
+     * 鑾峰彇褰撳墠鏃堕棿鐨勫瓧绗︿覆琛ㄧず锛屾牸寮忎负 "HH:MM:SS"
+     *
+     * @return 褰撳墠鏃堕棿鐨勫瓧绗︿覆琛ㄧず锛屾牸寮忎负 "HH:MM:SS"
+     */
+    public static String getTimeWithHourMinuteSecond() {
+        return dateTimeNow(FormatsType.HH_MM_SS);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃ユ湡鍜屾椂闂寸殑瀛楃涓茶〃绀猴紝鏍煎紡涓篩YYYMMDDHHMMSS
+     *
+     * @return 褰撳墠鏃ユ湡鍜屾椂闂寸殑瀛楃涓茶〃绀�
+     */
     public static String dateTimeNow() {
-        return dateTimeNow(YYYYMMDDHHMMSS);
+        return dateTimeNow(FormatsType.YYYYMMDDHHMMSS);
     }
 
-    public static String dateTimeNow(final String format) {
+    /**
+     * 鑾峰彇褰撳墠鏃ユ湡鍜屾椂闂寸殑鎸囧畾鏍煎紡鐨勫瓧绗︿覆琛ㄧず
+     *
+     * @param format 鏃ユ湡鏃堕棿鏍煎紡锛屼緥濡�"YYYY-MM-DD HH:MM:SS"
+     * @return 褰撳墠鏃ユ湡鍜屾椂闂寸殑瀛楃涓茶〃绀�
+     */
+    public static String dateTimeNow(final FormatsType format) {
         return parseDateToStr(format, new Date());
     }
 
-    public static String dateTime(final Date date) {
-        return parseDateToStr(YYYY_MM_DD, date);
+    /**
+     * 灏嗘寚瀹氭棩鏈熸牸寮忓寲涓� YYYY-MM-DD 鏍煎紡鐨勫瓧绗︿覆
+     *
+     * @param date 瑕佹牸寮忓寲鐨勬棩鏈熷璞�
+     * @return 鏍煎紡鍖栧悗鐨勬棩鏈熷瓧绗︿覆
+     */
+    public static String formatDate(final Date date) {
+        return parseDateToStr(FormatsType.YYYY_MM_DD, date);
     }
 
-    public static String parseDateToStr(final String format, final Date date) {
-        return new SimpleDateFormat(format).format(date);
+    /**
+     * 灏嗘寚瀹氭棩鏈熸牸寮忓寲涓� YYYY-MM-DD HH:MM:SS 鏍煎紡鐨勫瓧绗︿覆
+     *
+     * @param date 瑕佹牸寮忓寲鐨勬棩鏈熷璞�
+     * @return 鏍煎紡鍖栧悗鐨勬棩鏈熸椂闂村瓧绗︿覆
+     */
+    public static String formatDateTime(final Date date) {
+        return parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, date);
     }
 
-    public static Date dateTime(final String format, final String ts) {
+    /**
+     * 灏嗘寚瀹氭棩鏈熸寜鐓ф寚瀹氭牸寮忚繘琛屾牸寮忓寲
+     *
+     * @param format 瑕佷娇鐢ㄧ殑鏃ユ湡鏃堕棿鏍煎紡锛屼緥濡�"YYYY-MM-DD HH:MM:SS"
+     * @param date   瑕佹牸寮忓寲鐨勬棩鏈熷璞�
+     * @return 鏍煎紡鍖栧悗鐨勬棩鏈熸椂闂村瓧绗︿覆
+     */
+    public static String parseDateToStr(final FormatsType format, final Date date) {
+        return new SimpleDateFormat(format.getTimeFormat()).format(date);
+    }
+
+    /**
+     * 灏嗘寚瀹氭牸寮忕殑鏃ユ湡鏃堕棿瀛楃涓茶浆鎹负 Date 瀵硅薄
+     *
+     * @param format 瑕佽В鏋愮殑鏃ユ湡鏃堕棿鏍煎紡锛屼緥濡�"YYYY-MM-DD HH:MM:SS"
+     * @param ts     瑕佽В鏋愮殑鏃ユ湡鏃堕棿瀛楃涓�
+     * @return 瑙f瀽鍚庣殑 Date 瀵硅薄
+     * @throws RuntimeException 濡傛灉瑙f瀽杩囩▼涓彂鐢熷紓甯�
+     */
+    public static Date parseDateTime(final FormatsType format, final String ts) {
         try {
-            return new SimpleDateFormat(format).parse(ts);
+            return new SimpleDateFormat(format.getTimeFormat()).parse(ts);
         } catch (ParseException e) {
             throw new RuntimeException(e);
         }
     }
 
     /**
-     * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�2018/08/08
-     */
-    public static String datePath() {
-        Date now = new Date();
-        return DateFormatUtils.format(now, "yyyy/MM/dd");
-    }
-
-    /**
-     * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�20180808
-     */
-    public static String dateTime() {
-        Date now = new Date();
-        return DateFormatUtils.format(now, "yyyyMMdd");
-    }
-
-    /**
-     * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡
+     * 灏嗗璞¤浆鎹负鏃ユ湡瀵硅薄
+     *
+     * @param str 瑕佽浆鎹㈢殑瀵硅薄锛岄�氬父鏄瓧绗︿覆
+     * @return 杞崲鍚庣殑鏃ユ湡瀵硅薄锛屽鏋滆浆鎹㈠け璐ユ垨杈撳叆涓簄ull锛屽垯杩斿洖null
      */
     public static Date parseDate(Object str) {
         if (str == null) {
@@ -115,6 +165,8 @@
 
     /**
      * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂�
+     *
+     * @return 鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂寸殑 Date 瀵硅薄琛ㄧず
      */
     public static Date getServerStartDate() {
         long time = ManagementFactory.getRuntimeMXBean().getStartTime();
@@ -122,35 +174,66 @@
     }
 
     /**
-     * 璁$畻鐩稿樊澶╂暟
+     * 璁$畻涓や釜鏃ユ湡涔嬮棿鐨勫ぉ鏁板樊锛堜互姣涓哄崟浣嶏級
+     *
+     * @param date1 绗竴涓棩鏈�
+     * @param date2 绗簩涓棩鏈�
+     * @return 涓や釜鏃ユ湡涔嬮棿鐨勫ぉ鏁板樊鐨勭粷瀵瑰��
      */
     public static int differentDaysByMillisecond(Date date1, Date date2) {
         return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
     }
 
     /**
-     * 璁$畻涓や釜鏃堕棿宸�
+     * 璁$畻涓や釜鏃ユ湡涔嬮棿鐨勬椂闂村樊锛屽苟浠ュぉ銆佸皬鏃跺拰鍒嗛挓鐨勬牸寮忚繑鍥�
+     *
+     * @param endDate 缁撴潫鏃ユ湡
+     * @param nowDate 褰撳墠鏃ユ湡
+     * @return 琛ㄧず鏃堕棿宸殑瀛楃涓诧紝鏍煎紡涓�"澶� 灏忔椂 鍒嗛挓"
      */
     public static String getDatePoor(Date endDate, Date nowDate) {
-        long nd = 1000 * 24 * 60 * 60;
-        long nh = 1000 * 60 * 60;
-        long nm = 1000 * 60;
-        // long ns = 1000;
-        // 鑾峰緱涓や釜鏃堕棿鐨勬绉掓椂闂村樊寮�
-        long diff = endDate.getTime() - nowDate.getTime();
-        // 璁$畻宸灏戝ぉ
-        long day = diff / nd;
-        // 璁$畻宸灏戝皬鏃�
-        long hour = diff % nd / nh;
-        // 璁$畻宸灏戝垎閽�
-        long min = diff % nd % nh / nm;
-        // 璁$畻宸灏戠//杈撳嚭缁撴灉
-        // long sec = diff % nd % nh % nm / ns;
-        return day + "澶�" + hour + "灏忔椂" + min + "鍒嗛挓";
+        long diffInMillis = endDate.getTime() - nowDate.getTime();
+        long day = TimeUnit.MILLISECONDS.toDays(diffInMillis);
+        long hour = TimeUnit.MILLISECONDS.toHours(diffInMillis) % 24;
+        long min = TimeUnit.MILLISECONDS.toMinutes(diffInMillis) % 60;
+        return String.format("%d澶� %d灏忔椂 %d鍒嗛挓", day, hour, min);
     }
 
     /**
-     * 澧炲姞 LocalDateTime ==> Date
+     * 璁$畻涓や釜鏃堕棿鐐圭殑宸�硷紙澶┿�佸皬鏃躲�佸垎閽熴�佺锛夛紝褰撳�间负0鏃朵笉鏄剧ず璇ュ崟浣�
+     *
+     * @param endDate 缁撴潫鏃堕棿
+     * @param nowDate 褰撳墠鏃堕棿
+     * @return 鏃堕棿宸瓧绗︿覆锛屾牸寮忎负 "x澶� x灏忔椂 x鍒嗛挓 x绉�"锛岃嫢涓� 0 鍒欎笉鏄剧ず
+     */
+    public static String getTimeDifference(Date endDate, Date nowDate) {
+        long diffInMillis = endDate.getTime() - nowDate.getTime();
+        long day = TimeUnit.MILLISECONDS.toDays(diffInMillis);
+        long hour = TimeUnit.MILLISECONDS.toHours(diffInMillis) % 24;
+        long min = TimeUnit.MILLISECONDS.toMinutes(diffInMillis) % 60;
+        long sec = TimeUnit.MILLISECONDS.toSeconds(diffInMillis) % 60;
+        // 鏋勫缓鏃堕棿宸瓧绗︿覆锛屾潯浠舵槸鍊间笉涓�0鎵嶆樉绀�
+        StringBuilder result = new StringBuilder();
+        if (day > 0) {
+            result.append(String.format("%d澶� ", day));
+        }
+        if (hour > 0) {
+            result.append(String.format("%d灏忔椂 ", hour));
+        }
+        if (min > 0) {
+            result.append(String.format("%d鍒嗛挓 ", min));
+        }
+        if (sec > 0) {
+            result.append(String.format("%d绉�", sec));
+        }
+        return result.length() > 0 ? result.toString().trim() : "0绉�";
+    }
+
+    /**
+     * 灏� LocalDateTime 瀵硅薄杞崲涓� Date 瀵硅薄
+     *
+     * @param temporalAccessor 瑕佽浆鎹㈢殑 LocalDateTime 瀵硅薄
+     * @return 杞崲鍚庣殑 Date 瀵硅薄
      */
     public static Date toDate(LocalDateTime temporalAccessor) {
         ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
@@ -158,11 +241,46 @@
     }
 
     /**
-     * 澧炲姞 LocalDate ==> Date
+     * 灏� LocalDate 瀵硅薄杞崲涓� Date 瀵硅薄
+     *
+     * @param temporalAccessor 瑕佽浆鎹㈢殑 LocalDate 瀵硅薄
+     * @return 杞崲鍚庣殑 Date 瀵硅薄
      */
     public static Date toDate(LocalDate temporalAccessor) {
         LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
         ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
         return Date.from(zdt.toInstant());
     }
+
+    /**
+     * 鏍¢獙鏃ユ湡鑼冨洿
+     *
+     * @param startDate 寮�濮嬫棩鏈�
+     * @param endDate   缁撴潫鏃ユ湡
+     * @param maxValue  鏈�澶ф椂闂磋法搴︾殑闄愬埗鍊�
+     * @param unit      鏃堕棿璺ㄥ害鐨勫崟浣嶏紝鍙�夋嫨 "DAYS"銆�"HOURS" 鎴� "MINUTES"
+     */
+    public static void validateDateRange(Date startDate, Date endDate, int maxValue, TimeUnit unit) {
+        // 鏍¢獙缁撴潫鏃ユ湡涓嶈兘鏃╀簬寮�濮嬫棩鏈�
+        if (endDate.before(startDate)) {
+            throw new ServiceException("缁撴潫鏃ユ湡涓嶈兘鏃╀簬寮�濮嬫棩鏈�");
+        }
+
+        // 璁$畻鏃堕棿璺ㄥ害
+        long diffInMillis = endDate.getTime() - startDate.getTime();
+
+        // 鏍规嵁鍗曚綅杞崲鏃堕棿璺ㄥ害
+        long diff = switch (unit) {
+            case DAYS -> TimeUnit.MILLISECONDS.toDays(diffInMillis);
+            case HOURS -> TimeUnit.MILLISECONDS.toHours(diffInMillis);
+            case MINUTES -> TimeUnit.MILLISECONDS.toMinutes(diffInMillis);
+            default -> throw new IllegalArgumentException("涓嶆敮鎸佺殑鏃堕棿鍗曚綅");
+        };
+
+        // 鏍¢獙鏃堕棿璺ㄥ害涓嶈秴杩囨渶澶ч檺鍒�
+        if (diff > maxValue) {
+            throw new ServiceException("鏈�澶ф椂闂磋法搴︿负 " + maxValue + " " + unit.toString().toLowerCase());
+        }
+    }
+
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
index ae6cfa3..82ea5ca 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Threads.java
@@ -14,18 +14,6 @@
 @Slf4j
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class Threads {
-
-    /**
-     * sleep绛夊緟,鍗曚綅涓烘绉�
-     */
-    public static void sleep(long milliseconds) {
-        try {
-            Thread.sleep(milliseconds);
-        } catch (InterruptedException e) {
-            return;
-        }
-    }
-
     /**
      * 鍋滄绾跨▼姹�
      * 鍏堜娇鐢╯hutdown, 鍋滄鎺ユ敹鏂颁换鍔″苟灏濊瘯瀹屾垚鎵�鏈夊凡瀛樺湪浠诲姟.
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java
index d0e78a2..e44aa3d 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/properties/MailProperties.java
@@ -43,7 +43,13 @@
     private String pass;
 
     /**
-     * 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯
+     * 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯<br>
+     * 鍙戜欢浜哄彲浠ユ槸浠ヤ笅褰㈠紡锛�
+     *
+     * <pre>
+     * 1. user@xxx.xx
+     * 2.  name &lt;user@xxx.xx&gt;
+     * </pre>
      */
     private String from;
 
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java
index 3f7797d..1d5c3c9 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/core/page/PageQuery.java
@@ -119,4 +119,9 @@
         return (pageNum - 1) * pageSize;
     }
 
+    public PageQuery(Integer pageSize, Integer pageNum) {
+        this.pageSize = pageSize;
+        this.pageNum = pageNum;
+    }
+
 }
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java
new file mode 100644
index 0000000..3c2f703
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java
@@ -0,0 +1,165 @@
+package org.dromara.common.redis.utils;
+
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.DateUtil;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.redisson.api.RIdGenerator;
+import org.redisson.api.RedissonClient;
+
+import java.time.Duration;
+
+/**
+ * 鍙戝彿鍣ㄥ伐鍏风被
+ *
+ * @author 绉嬭緸鏈瘨
+ * @date 2024-12-10
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class SequenceUtils {
+
+    /**
+     * 榛樿鍒濆鍊�
+     */
+    public static final Long DEFAULT_INIT_VALUE = 1L;
+    /**
+     * 榛樿姝ラ暱
+     */
+    public static final Long DEFAULT_STEP_VALUE = 1L;
+    /**
+     * 榛樿杩囨湡鏃堕棿-澶�
+     */
+    public static final Duration DEFAULT_EXPIRE_TIME_DAY = Duration.ofDays(1);
+    /**
+     * 榛樿杩囨湡鏃堕棿-鍒嗛挓
+     */
+    public static final Duration DEFAULT_EXPIRE_TIME_MINUTE = Duration.ofMinutes(1);
+
+    /**
+     * 鑾峰彇Redisson瀹㈡埛绔疄渚�
+     */
+    private static final RedissonClient REDISSON_CLIENT = SpringUtils.getBean(RedissonClient.class);
+
+    /**
+     * 鑾峰彇ID鐢熸垚鍣�
+     *
+     * @param key        涓氬姟key
+     * @param expireTime 杩囨湡鏃堕棿
+     * @param initValue  ID鍒濆鍊�
+     * @param stepValue  ID姝ラ暱
+     * @return ID鐢熸垚鍣�
+     */
+    private static RIdGenerator getIdGenerator(String key, Duration expireTime, Long initValue, Long stepValue) {
+        if (initValue == null || initValue <= 0) {
+            initValue = DEFAULT_INIT_VALUE;
+        }
+        if (stepValue == null || stepValue <= 0) {
+            stepValue = DEFAULT_STEP_VALUE;
+        }
+        RIdGenerator idGenerator = REDISSON_CLIENT.getIdGenerator(key);
+        // 璁剧疆杩囨湡鏃堕棿
+        idGenerator.expire(expireTime);
+        // 璁剧疆鍒濆鍊煎拰姝ラ暱
+        idGenerator.tryInit(initValue, stepValue);
+        return idGenerator;
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾涓氬姟key鐨勫敮涓�id
+     *
+     * @param key        涓氬姟key
+     * @param expireTime 杩囨湡鏃堕棿
+     * @param initValue  ID鍒濆鍊�
+     * @param stepValue  ID姝ラ暱
+     * @return 鍞竴id
+     */
+    public static long nextId(String key, Duration expireTime, Long initValue, Long stepValue) {
+        return getIdGenerator(key, expireTime, initValue, stepValue).nextId();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾涓氬姟key鐨勫敮涓�id瀛楃涓�
+     *
+     * @param key        涓氬姟key
+     * @param expireTime 杩囨湡鏃堕棿
+     * @param initValue  ID鍒濆鍊�
+     * @param stepValue  ID姝ラ暱
+     * @return 鍞竴id
+     */
+    public static String nextIdStr(String key, Duration expireTime, Long initValue, Long stepValue) {
+        return String.valueOf(nextId(key, expireTime, initValue, stepValue));
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾涓氬姟key鐨勫敮涓�id (ID鍒濆鍊�=1,ID姝ラ暱=1)
+     *
+     * @param key        涓氬姟key
+     * @param expireTime 杩囨湡鏃堕棿
+     * @return 鍞竴id
+     */
+    public static long nextId(String key, Duration expireTime) {
+        return getIdGenerator(key, expireTime, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾涓氬姟key鐨勫敮涓�id瀛楃涓� (ID鍒濆鍊�=1,ID姝ラ暱=1)
+     *
+     * @param key        涓氬姟key
+     * @param expireTime 杩囨湡鏃堕棿
+     * @return 鍞竴id
+     */
+    public static String nextIdStr(String key, Duration expireTime) {
+        return String.valueOf(nextId(key, expireTime));
+    }
+
+    /**
+     * 鑾峰彇 yyyyMMdd 寮�澶寸殑鍞竴id
+     *
+     * @return 鍞竴id
+     */
+    public static String nextIdDate() {
+        return nextIdDate("");
+    }
+
+    /**
+     * 鑾峰彇 prefix + yyyyMMdd 寮�澶寸殑鍞竴id
+     *
+     * @param prefix 涓氬姟鍓嶇紑
+     * @return 鍞竴id
+     */
+    public static String nextIdDate(String prefix) {
+        // 鍓嶇紑+鏃ユ湡 鏋勫缓 prefixKey
+        String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_FORMATTER));
+        // 鑾峰彇涓嬩竴涓猧d
+        long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_DAY, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
+        // 杩斿洖瀹屾暣id
+        return StringUtils.format("{}{}", prefixKey, nextId);
+    }
+
+    /**
+     * 鑾峰彇 yyyyMMddHHmmss 寮�澶寸殑鍞竴id
+     *
+     * @return 鍞竴id
+     */
+    public static String nextIdDateTime() {
+        return nextIdDateTime("");
+    }
+
+    /**
+     * 鑾峰彇 prefix + yyyyMMddHHmmss 寮�澶寸殑鍞竴id
+     *
+     * @param prefix 涓氬姟鍓嶇紑
+     * @return 鍞竴id
+     */
+    public static String nextIdDateTime(String prefix) {
+        // 鍓嶇紑+鏃ユ湡鏃堕棿 鏋勫缓 prefixKey
+        String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_FORMATTER));
+        // 鑾峰彇涓嬩竴涓猧d
+        long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_MINUTE, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
+        // 杩斿洖瀹屾暣id
+        return StringUtils.format("{}{}", prefixKey, nextId);
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
index cdc5684..19557e1 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
@@ -89,6 +89,13 @@
     }
 
     /**
+     * 鑾峰彇鐢ㄦ埛id
+     */
+    public static String getUserIdStr() {
+        return Convert.toStr(getExtra(USER_KEY));
+    }
+
+    /**
      * 鑾峰彇鐢ㄦ埛璐︽埛
      */
     public static String getUsername() {
diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeyRequest.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeyRequest.java
index b95c19e..97774ac 100644
--- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeyRequest.java
+++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/maxkey/AuthMaxKeyRequest.java
@@ -30,7 +30,7 @@
     }
 
     @Override
-    protected AuthToken getAccessToken(AuthCallback authCallback) {
+    public AuthToken getAccessToken(AuthCallback authCallback) {
         String body = doPostAuthorizationCode(authCallback.getCode());
         Dict object = JsonUtils.parseMap(body);
         // oauth/token 楠岃瘉寮傚父
@@ -51,7 +51,7 @@
     }
 
     @Override
-    protected AuthUser getUserInfo(AuthToken authToken) {
+    public AuthUser getUserInfo(AuthToken authToken) {
         String body = doGetUserInfo(authToken);
         Dict object = JsonUtils.parseMap(body);
         // oauth/token 楠岃瘉寮傚父
diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java
index 4867cdc..31bb955 100644
--- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java
+++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java
@@ -44,7 +44,7 @@
     }
 
     @Override
-    protected AuthToken getAccessToken(AuthCallback authCallback) {
+    public AuthToken getAccessToken(AuthCallback authCallback) {
         String body = doPostAuthorizationCode(authCallback.getCode());
         Dict object = JsonUtils.parseMap(body);
         checkResponse(object);
@@ -58,7 +58,7 @@
     }
 
     @Override
-    protected AuthUser getUserInfo(AuthToken authToken) {
+    public AuthUser getUserInfo(AuthToken authToken) {
         String body = doGetUserInfo(authToken);
         Dict object = JsonUtils.parseMap(body);
         checkResponse(object);
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java
index 341880c..303cf88 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisCacheController.java
@@ -1,5 +1,6 @@
 package org.dromara.demo.controller;
 
+import cn.hutool.core.thread.ThreadUtil;
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.redis.utils.RedisUtils;
@@ -83,11 +84,7 @@
         RedisUtils.setCacheObject(key, value);
         boolean flag = RedisUtils.expire(key, Duration.ofSeconds(10));
         System.out.println("***********" + flag);
-        try {
-            Thread.sleep(11 * 1000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
+        ThreadUtil.sleep(11 * 1000);
         Object obj = RedisUtils.getCacheObject(key);
         return R.ok(value.equals(obj));
     }
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java
index b7e0962..237b6ee 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/RedisLockController.java
@@ -1,5 +1,6 @@
 package org.dromara.demo.controller;
 
+import cn.hutool.core.thread.ThreadUtil;
 import com.baomidou.lock.LockInfo;
 import com.baomidou.lock.LockTemplate;
 import com.baomidou.lock.annotation.Lock4j;
@@ -33,13 +34,9 @@
     @Lock4j(keys = {"#key"})
     @GetMapping("/testLock4j")
     public R<String> testLock4j(String key, String value) {
-        System.out.println("start:" + key + ",time:" + LocalTime.now().toString());
-        try {
-            Thread.sleep(10000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-        System.out.println("end :" + key + ",time:" + LocalTime.now().toString());
+        System.out.println("start:" + key + ",time:" + LocalTime.now());
+        ThreadUtil.sleep(10000);
+        System.out.println("end :" + key + ",time:" + LocalTime.now());
         return R.ok("鎿嶄綔鎴愬姛", value);
     }
 
@@ -54,11 +51,7 @@
         }
         // 鑾峰彇閿佹垚鍔燂紝澶勭悊涓氬姟
         try {
-            try {
-                Thread.sleep(8000);
-            } catch (InterruptedException e) {
-                //
-            }
+            ThreadUtil.sleep(8000);
             System.out.println("鎵ц绠�鍗曟柟娉�1 , 褰撳墠绾跨▼:" + Thread.currentThread().getName());
         } finally {
             //閲婃斁閿�
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java
index 13be4a4..eaed068 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java
@@ -97,7 +97,7 @@
     @Log(title = "瀹㈡埛绔鐞�", businessType = BusinessType.UPDATE)
     @PutMapping("/changeStatus")
     public R<Void> changeStatus(@RequestBody SysClientBo bo) {
-        return toAjax(sysClientService.updateUserStatus(bo.getClientId(), bo.getStatus()));
+        return toAjax(sysClientService.updateClientStatus(bo.getClientId(), bo.getStatus()));
     }
 
     /**
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
index d4cecbe..e1e868a 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
@@ -218,7 +218,7 @@
     @GetMapping("/optionselect")
     public R<List<SysUserVo>> optionselect(@RequestParam(required = false) Long[] userIds,
                                            @RequestParam(required = false) Long deptId) {
-        return R.ok(userService.selectUserByIds(userIds == null ? null : List.of(userIds), deptId));
+        return R.ok(userService.selectUserByIds(ArrayUtil.isEmpty(userIds) ? null : List.of(userIds), deptId));
     }
 
     /**
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java
index d0f8a3c..546c3f3 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java
@@ -50,7 +50,7 @@
     /**
      * 淇敼鐘舵��
      */
-    int updateUserStatus(String clientId, String status);
+    int updateClientStatus(String clientId, String status);
 
     /**
      * 鏍¢獙骞舵壒閲忓垹闄ゅ鎴风绠$悊淇℃伅
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java
index 3751b23..a760d49 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java
@@ -26,6 +26,14 @@
     List<SysPostVo> selectPostList(SysPostBo post);
 
     /**
+     * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 宀椾綅ID
+     */
+    List<SysPostVo> selectPostsByUserId(Long userId);
+
+    /**
      * 鏌ヨ鎵�鏈夊矖浣�
      *
      * @return 宀椾綅鍒楄〃
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java
index 1c69243..4f6e676 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java
@@ -123,7 +123,7 @@
      */
     @CacheEvict(cacheNames = CacheNames.SYS_CLIENT, key = "#clientId")
     @Override
-    public int updateUserStatus(String clientId, String status) {
+    public int updateClientStatus(String clientId, String status) {
         return baseMapper.update(null,
             new LambdaUpdateWrapper<SysClient>()
                 .set(SysClient::getStatus, status)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java
index 470646f..12a5072 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java
@@ -38,7 +38,7 @@
      * @param roleId 瑙掕壊Id
      * @return 閮ㄩ棬Id缁�
      */
-    @Cacheable(cacheNames = CacheNames.SYS_ROLE_CUSTOM, key = "#roleId")
+    @Cacheable(cacheNames = CacheNames.SYS_ROLE_CUSTOM, key = "#roleId", condition = "#roleId != null")
     @Override
     public String getRoleCustom(Long roleId) {
         if (ObjectUtil.isNull(roleId)) {
@@ -60,7 +60,7 @@
      * @param deptId 閮ㄩ棬Id
      * @return 閮ㄩ棬Id缁�
      */
-    @Cacheable(cacheNames = CacheNames.SYS_DEPT_AND_CHILD, key = "#deptId")
+    @Cacheable(cacheNames = CacheNames.SYS_DEPT_AND_CHILD, key = "#deptId", condition = "#deptId != null")
     @Override
     public String getDeptAndChild(Long deptId) {
         if (ObjectUtil.isNull(deptId)) {
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
index 478a42c..0199ec7 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
@@ -1,5 +1,6 @@
 package org.dromara.system.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.lang.tree.Tree;
@@ -10,6 +11,7 @@
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.domain.dto.DeptDTO;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.service.DeptService;
 import org.dromara.common.core.utils.*;
@@ -110,7 +112,7 @@
                         .setName(dept.getDeptName())
                         .setWeight(dept.getOrderNum())
                         .putExtra("disabled", SystemConstants.DISABLE.equals(dept.getStatus())));
-                Tree<Long> tree = trees.stream().filter(it -> it.getId().longValue() == d.getDeptId()).findFirst().get();
+                Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getDeptId());
                 treeList.add(tree);
             }
         }
@@ -175,6 +177,31 @@
     }
 
     /**
+     * 鏍规嵁閮ㄩ棬ID鏌ヨ閮ㄩ棬璐熻矗浜�
+     *
+     * @param deptId 閮ㄩ棬ID锛岀敤浜庢寚瀹氶渶瑕佹煡璇㈢殑閮ㄩ棬
+     * @return 杩斿洖璇ラ儴闂ㄧ殑璐熻矗浜篒D
+     */
+    @Override
+    public Long selectDeptLeaderById(Long deptId) {
+        SysDeptVo vo = SpringUtils.getAopProxy(this).selectDeptById(deptId);
+        return vo.getLeader();
+    }
+
+    /**
+     * 鏌ヨ閮ㄩ棬
+     *
+     * @return 閮ㄩ棬鍒楄〃
+     */
+    @Override
+    public List<DeptDTO> selectDeptsByList() {
+        List<SysDeptVo> list = baseMapper.selectDeptList(new LambdaQueryWrapper<SysDept>()
+            .select(SysDept::getDeptId, SysDept::getDeptName, SysDept::getParentId)
+            .eq(SysDept::getStatus, SystemConstants.NORMAL));
+        return BeanUtil.copyToList(list, DeptDTO.class);
+    }
+
+    /**
      * 鏍规嵁ID鏌ヨ鎵�鏈夊瓙閮ㄩ棬鏁帮紙姝e父鐘舵�侊級
      *
      * @param deptId 閮ㄩ棬ID
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java
index b95baf4..72b497e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysLogininforServiceImpl.java
@@ -118,8 +118,7 @@
             .between(params.get("beginTime") != null && params.get("endTime") != null,
                 SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"));
         if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
-            pageQuery.setOrderByColumn("info_id");
-            pageQuery.setIsAsc("desc");
+            lqw.orderByDesc(SysLogininfor::getInfoId);
         }
         Page<SysLogininforVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
         return TableDataInfo.build(page);
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java
index 750e455..27c2f32 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java
@@ -53,8 +53,7 @@
     public TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery) {
         LambdaQueryWrapper<SysOperLog> lqw = buildQueryWrapper(operLog);
         if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
-            pageQuery.setOrderByColumn("oper_id");
-            pageQuery.setIsAsc("desc");
+            lqw.orderByDesc(SysOperLog::getOperId);
         }
         Page<SysOperLogVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
         return TableDataInfo.build(page);
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
index 8643f0d..72f1a5e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
@@ -8,6 +8,7 @@
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.constant.SystemConstants;
 import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.PostService;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -34,7 +35,7 @@
  */
 @RequiredArgsConstructor
 @Service
-public class SysPostServiceImpl implements ISysPostService {
+public class SysPostServiceImpl implements ISysPostService, PostService {
 
     private final SysPostMapper baseMapper;
     private final SysDeptMapper deptMapper;
@@ -58,6 +59,17 @@
     }
 
     /**
+     * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 宀椾綅ID
+     */
+    @Override
+    public List<SysPostVo> selectPostsByUserId(Long userId) {
+        return baseMapper.selectPostsByUserId(userId);
+    }
+
+    /**
      * 鏍规嵁鏌ヨ鏉′欢鏋勫缓鏌ヨ鍖呰鍣�
      *
      * @param bo 鏌ヨ鏉′欢瀵硅薄
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
index cbca57e..4c00735 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
@@ -17,6 +17,7 @@
 import org.dromara.common.core.constant.TenantConstants;
 import org.dromara.common.core.domain.model.LoginUser;
 import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.RoleService;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -47,7 +48,7 @@
  */
 @RequiredArgsConstructor
 @Service
-public class SysRoleServiceImpl implements ISysRoleService {
+public class SysRoleServiceImpl implements ISysRoleService, RoleService {
 
     private final SysRoleMapper baseMapper;
     private final SysRoleMenuMapper roleMenuMapper;
@@ -351,7 +352,7 @@
     private int insertRoleMenu(SysRoleBo role) {
         int rows = 1;
         // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
-        List<SysRoleMenu> list = new ArrayList<SysRoleMenu>();
+        List<SysRoleMenu> list = new ArrayList<>();
         for (Long menuId : role.getMenuIds()) {
             SysRoleMenu rm = new SysRoleMenu();
             rm.setRoleId(role.getRoleId());
@@ -372,7 +373,7 @@
     private int insertRoleDept(SysRoleBo role) {
         int rows = 1;
         // 鏂板瑙掕壊涓庨儴闂紙鏁版嵁鏉冮檺锛夌鐞�
-        List<SysRoleDept> list = new ArrayList<SysRoleDept>();
+        List<SysRoleDept> list = new ArrayList<>();
         for (Long deptId : role.getDeptIds()) {
             SysRoleDept rd = new SysRoleDept();
             rd.setRoleId(role.getRoleId());
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
index 4b57587..4081170 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
@@ -696,4 +696,27 @@
             .in(SysUser::getDeptId, deptIds));
         return BeanUtil.copyToList(list, UserDTO.class);
     }
+
+    /**
+     * 閫氳繃宀椾綅ID鏌ヨ鐢ㄦ埛
+     *
+     * @param postIds 宀椾綅ids
+     * @return 鐢ㄦ埛
+     */
+    @Override
+    public List<UserDTO> selectUsersByPostIds(List<Long> postIds) {
+        if (CollUtil.isEmpty(postIds)) {
+            return List.of();
+        }
+
+        // 閫氳繃宀椾綅ID鑾峰彇鐢ㄦ埛宀椾綅淇℃伅
+        List<SysUserPost> userPosts = userPostMapper.selectList(
+            new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getPostId, postIds));
+
+        // 鑾峰彇鐢ㄦ埛ID鍒楄〃
+        Set<Long> userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId);
+
+        return selectListByIds(new ArrayList<>(userIds));
+    }
+
 }

--
Gitblit v1.9.3