diff --git a/README.md b/README.md
index 5ed7878f1..7a8864116 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,7 @@ MaxKey 业界领先单点登录产品 - https://gitee.com/dromara/MaxKey
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow
数舵科技 软件定制开发APP小程序等 - http://www.shuduokeji.com/
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc
+**启山商城系统 多租户商城源码可免费商用可二次开发 - https://www.73app.cn/**
[如何成为赞助商 加群联系作者详谈](https://plus-doc.dromara.org/#/common/add_group)
# 本框架与RuoYi的功能差异
diff --git a/pom.xml b/pom.xml
index 58672cae4..ebf2814ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,7 +36,7 @@
0.2.0
1.18.34
1.76
- 1.16.6
+ 1.16.7
2.7.0
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 2eae90ab7..41a802b44 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.CacheConstants;
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 @@ public class SysLoginService {
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 class SysLoginService {
*/
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 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 roles = roleService.selectRolesByUserId(user.getUserId());
+ List roles = roleService.selectRolesByUserId(userId);
+ List 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 948ed9acb..fa9b61819 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.dev33.satoken.stp.StpUtil;
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 @@ public class XcxAuthStrategy implements IAuthStrategy {
// 多个小程序识别使用
String appid = loginBody.getAppid();
- // todo 以下自行实现
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
- String openid = "";
+ AuthRequest authRequest = new AuthWechatMiniProgramRequest(AuthConfig.builder()
+ .clientId(appid).clientSecret("自行填写密钥 可根据不同appid填入不同密钥")
+ .ignoreCheckRedirectUri(true).ignoreCheckState(true).build());
+ AuthCallback authCallback = new AuthCallback();
+ authCallback.setCode(xcxCode);
+ AuthResponse resp = authRequest.login(authCallback);
+ String openid, unionId;
+ if (resp.ok()) {
+ AuthToken token = resp.getData().getToken();
+ openid = token.getOpenId();
+ // 微信小程序只有关联到微信开放平台下之后才能获取到 unionId,因此unionId不一定能返回。
+ 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-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index 283cdad44..e4f6086cc 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -200,7 +200,7 @@ justauth:
redirect-uri: ${justauth.address}/social-callback?source=maxkey
topiam:
# topiam 服务器地址
- server-url: http://127.0.0.1:1989/api/v1/authorize/y0q************spq***********8ol
+ server-url: http://127.0.0.1:1898/api/v1/authorize/y0q************spq***********8ol
client-id: 449c4*********937************759
client-secret: ac7***********1e0************28d
redirect-uri: ${justauth.address}/social-callback?source=topiam
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index dead74198..c42bb7f26 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -139,6 +139,8 @@ tenant:
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
+ # 自定义配置 是否全局开启逻辑删除 关闭后 所有逻辑删除功能将失效
+ enableLogicDelete: true
# 多包名使用 例如 org.dromara.**.mapper,org.xxx.**.mapper
mapperPackage: org.dromara.**.mapper
# 对应的 XML 文件位置
diff --git a/ruoyi-admin/src/main/resources/logback-plus.xml b/ruoyi-admin/src/main/resources/logback-plus.xml
index 40fa33b7c..b74289ecd 100644
--- a/ruoyi-admin/src/main/resources/logback-plus.xml
+++ b/ruoyi-admin/src/main/resources/logback-plus.xml
@@ -2,7 +2,7 @@
+ value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
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 000000000..65c012faf
--- /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;
+
+ /**
+ * 父部门ID
+ */
+ 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 000000000..7536ee33d
--- /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 c723e7668..338d4d70a 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;
@@ -111,6 +112,11 @@ public class LoginUser implements Serializable {
*/
private List roles;
+ /**
+ * 岗位对象
+ */
+ private List posts;
+
/**
* 数据权限 当前角色ID
*/
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 000000000..8d4b6d911
--- /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 db9463e79..f93d1778a 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 @@ public interface DeptService {
*/
String selectDeptNameByIds(String deptIds);
+ /**
+ * 根据部门ID查询部门负责人
+ *
+ * @param deptId 部门ID,用于指定需要查询的部门
+ * @return 返回该部门的负责人ID
+ */
+ Long selectDeptLeaderById(Long deptId);
+
+ /**
+ * 查询部门
+ *
+ * @return 部门列表
+ */
+ List 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 000000000..41d4e8308
--- /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 000000000..ba62c82ae
--- /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 43aef28cb..67cd54fba 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 @@ public interface UserService {
* @return 用户
*/
List selectUsersByDeptIds(List deptIds);
+
+ /**
+ * 通过岗位ID查询用户
+ *
+ * @param postIds 岗位ids
+ * @return 用户
+ */
+ List selectUsersByPostIds(List 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 72178a7b6..88cdbbc72 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 @@ package org.dromara.common.core.utils;
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 @@ import java.util.Date;
*/
@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();
}
/**
- * 获取当前日期, 默认格式为yyyy-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);
+ }
+
+ /**
+ * 获取当前日期和时间的字符串表示,格式为YYYYMMDDHHMMSS
+ *
+ * @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 解析后的 Date 对象
+ * @throws RuntimeException 如果解析过程中发生异常
+ */
+ 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 转换后的日期对象,如果转换失败或输入为null,则返回null
*/
public static Date parseDate(Object str) {
if (str == null) {
@@ -115,6 +165,8 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
/**
* 获取服务器启动时间
+ *
+ * @return 服务器启动时间的 Date 对象表示
*/
public static Date getServerStartDate() {
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
@@ -122,35 +174,66 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
}
/**
- * 计算相差天数
+ * 计算两个日期之间的天数差(以毫秒为单位)
+ *
+ * @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 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
}
/**
- * 增加 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/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
index fcf9fb4b6..1020c81eb 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
@@ -15,7 +15,7 @@ public class SqlUtil {
/**
* 定义常用的 sql关键字
*/
- public static String SQL_REGEX = "and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
+ public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelNotation.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelNotation.java
new file mode 100644
index 000000000..f358afcd6
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelNotation.java
@@ -0,0 +1,24 @@
+package org.dromara.common.excel.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 批注
+ * @author guzhouyanyu
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelNotation {
+
+ /**
+ * col index
+ */
+ int index() default -1;
+ /**
+ * 批注内容
+ */
+ String value() default "";
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelRequired.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelRequired.java
new file mode 100644
index 000000000..15784e140
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/annotation/ExcelRequired.java
@@ -0,0 +1,26 @@
+package org.dromara.common.excel.annotation;
+
+import org.apache.poi.ss.usermodel.IndexedColors;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 是否必填
+ * @author guzhouyanyu
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelRequired {
+
+ /**
+ * col index
+ */
+ int index() default -1;
+ /**
+ * 字体颜色
+ */
+ IndexedColors fontColor() default IndexedColors.RED;
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/handler/DataWriteHandler.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/handler/DataWriteHandler.java
new file mode 100644
index 000000000..a2aa4951b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/handler/DataWriteHandler.java
@@ -0,0 +1,135 @@
+package org.dromara.common.excel.handler;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.excel.metadata.data.DataFormatData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.util.StyleUtil;
+import com.alibaba.excel.write.handler.CellWriteHandler;
+import com.alibaba.excel.write.handler.SheetWriteHandler;
+import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.metadata.style.WriteFont;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import org.dromara.common.excel.annotation.ExcelNotation;
+import org.dromara.common.excel.annotation.ExcelRequired;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 批注、必填
+ *
+ * @author guzhouyanyu
+ */
+public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
+
+ /**
+ * 批注
+ */
+ private final Map notationMap;
+
+ /**
+ * 头列字体颜色
+ */
+ private final Map headColumnMap;
+
+
+ public DataWriteHandler(Class> clazz) {
+ notationMap = getNotationMap(clazz);
+ headColumnMap = getRequiredMap(clazz);
+ }
+
+ @Override
+ public void afterCellDispose(CellWriteHandlerContext context) {
+ if (CollUtil.isEmpty(notationMap) && CollUtil.isEmpty(headColumnMap)) {
+ return;
+ }
+ WriteCellData> cellData = context.getFirstCellData();
+ WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
+
+ DataFormatData dataFormatData = new DataFormatData();
+ // 单元格设置为文本格式
+ dataFormatData.setIndex((short) 49);
+ writeCellStyle.setDataFormatData(dataFormatData);
+
+ if (context.getHead()) {
+ Cell cell = context.getCell();
+ WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
+ Sheet sheet = writeSheetHolder.getSheet();
+ Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
+ Drawing> drawing = sheet.createDrawingPatriarch();
+ // 设置标题字体样式
+ WriteFont headWriteFont = new WriteFont();
+ // 加粗
+ headWriteFont.setBold(true);
+ if (CollUtil.isNotEmpty(headColumnMap) && headColumnMap.containsKey(cell.getColumnIndex())) {
+ // 设置字体颜色
+ headWriteFont.setColor(headColumnMap.get(cell.getColumnIndex()));
+ }
+ writeCellStyle.setWriteFont(headWriteFont);
+ CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, null, writeCellStyle);
+ cell.setCellStyle(cellStyle);
+
+ if (CollUtil.isNotEmpty(notationMap) && notationMap.containsKey(cell.getColumnIndex())) {
+ // 批注内容
+ String notationContext = notationMap.get(cell.getColumnIndex());
+ // 创建绘图对象
+ Comment comment = drawing.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), 0, (short) 5, 5));
+ comment.setString(new XSSFRichTextString(notationContext));
+ cell.setCellComment(comment);
+ }
+ }
+ }
+
+ /**
+ * 获取必填列
+ */
+ private static Map getRequiredMap(Class> clazz) {
+ Map requiredMap = new HashMap<>();
+ Field[] fields = clazz.getDeclaredFields();
+ // 检查 fields 数组是否为空
+ if (fields.length == 0) {
+ return requiredMap;
+ }
+ Field[] filteredFields = ReflectUtils.getFields(clazz, field -> !"serialVersionUID".equals(field.getName()));
+
+ for (int i = 0; i < filteredFields.length; i++) {
+ Field field = filteredFields[i];
+ if (!field.isAnnotationPresent(ExcelRequired.class)) {
+ continue;
+ }
+ ExcelRequired excelRequired = field.getAnnotation(ExcelRequired.class);
+ int columnIndex = excelRequired.index() == -1 ? i : excelRequired.index();
+ requiredMap.put(columnIndex, excelRequired.fontColor().getIndex());
+ }
+ return requiredMap;
+ }
+
+ /**
+ * 获取批注
+ */
+ private static Map getNotationMap(Class> clazz) {
+ Map notationMap = new HashMap<>();
+ Field[] fields = clazz.getDeclaredFields();
+ // 检查 fields 数组是否为空
+ if (fields.length == 0) {
+ return notationMap;
+ }
+ Field[] filteredFields = ReflectUtils.getFields(clazz, field -> !"serialVersionUID".equals(field.getName()));
+ for (int i = 0; i < filteredFields.length; i++) {
+ Field field = filteredFields[i];
+ if (!field.isAnnotationPresent(ExcelNotation.class)) {
+ continue;
+ }
+ ExcelNotation excelNotation = field.getAnnotation(ExcelNotation.class);
+ int columnIndex = excelNotation.index() == -1 ? i : excelNotation.index();
+ notationMap.put(columnIndex, excelNotation.value());
+ }
+ return notationMap;
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
index a6c14ad51..b22e6f987 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
@@ -18,6 +18,7 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.excel.convert.ExcelBigNumberConvert;
import org.dromara.common.excel.core.*;
+import org.dromara.common.excel.handler.DataWriteHandler;
import java.io.IOException;
import java.io.InputStream;
@@ -191,6 +192,7 @@ public class ExcelUtil {
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
+ .registerWriteHandler(new DataWriteHandler(clazz))
.sheet(sheetName);
if (merge) {
// 合并处理器
@@ -211,7 +213,7 @@ public class ExcelUtil {
* @param data 模板需要的数据
* @param response 响应体
*/
- public static void exportTemplate(List
\ No newline at end of file
+
diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/logback-plus.xml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/logback-plus.xml
index a40262c9f..be588110c 100644
--- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/logback-plus.xml
+++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/logback-plus.xml
@@ -2,7 +2,7 @@
+ value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java
index 016c2f7dc..e7ea8075c 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/domain/vo/TestDemoVo.java
@@ -2,6 +2,8 @@ package org.dromara.demo.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelNotation;
+import org.dromara.common.excel.annotation.ExcelRequired;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.demo.domain.TestDemo;
@@ -36,30 +38,35 @@ public class TestDemoVo implements Serializable {
/**
* 部门id
*/
+ @ExcelRequired
@ExcelProperty(value = "部门id")
private Long deptId;
/**
* 用户id
*/
+ @ExcelRequired
@ExcelProperty(value = "用户id")
private Long userId;
/**
* 排序号
*/
+ @ExcelRequired
@ExcelProperty(value = "排序号")
private Integer orderNum;
/**
* key键
*/
+ @ExcelNotation(value = "测试key")
@ExcelProperty(value = "key键")
private String testKey;
/**
* 值
*/
+ @ExcelNotation(value = "测试value")
@ExcelProperty(value = "值")
private String value;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
index 893b381e3..5f187cb91 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
@@ -98,8 +98,8 @@ public class SysProfileController extends BaseController {
if (BCrypt.checkpw(bo.getNewPassword(), password)) {
return R.fail("新密码不能与旧密码相同");
}
-
- if (userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(bo.getNewPassword())) > 0) {
+ int rows = DataPermissionHelper.ignore(() -> userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(bo.getNewPassword())));
+ if (rows > 0) {
return R.ok();
}
return R.fail("修改密码异常,请联系管理员");
@@ -121,7 +121,8 @@ public class SysProfileController extends BaseController {
}
SysOssVo oss = ossService.upload(avatarfile);
String avatar = oss.getUrl();
- if (userService.updateUserAvatar(LoginHelper.getUserId(), oss.getOssId())) {
+ boolean updateSuccess = DataPermissionHelper.ignore(() -> userService.updateUserAvatar(LoginHelper.getUserId(), oss.getOssId()));
+ if (updateSuccess) {
AvatarVo avatarVo = new AvatarVo();
avatarVo.setImgUrl(avatar);
return R.ok(avatarVo);
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 3751b23be..a760d497e 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
@@ -25,6 +25,14 @@ public interface ISysPostService {
*/
List selectPostList(SysPostBo post);
+ /**
+ * 查询用户所属岗位组
+ *
+ * @param userId 用户ID
+ * @return 岗位ID
+ */
+ List selectPostsByUserId(Long userId);
+
/**
* 查询所有岗位
*
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 470646f35..12a507203 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 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService {
* @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 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService {
* @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 1d6da45da..0199ec719 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 com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.*;
@@ -67,8 +69,6 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
*/
@Override
public List> selectDeptTreeList(SysDeptBo bo) {
- // 只查询未禁用部门
- bo.setStatus(SystemConstants.NORMAL);
LambdaQueryWrapper lqw = buildQueryWrapper(bo);
List depts = baseMapper.selectDeptList(lqw);
return buildDeptTreeSelect(depts);
@@ -176,6 +176,31 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
return String.join(StringUtils.SEPARATOR, list);
}
+ /**
+ * 根据部门ID查询部门负责人
+ *
+ * @param deptId 部门ID,用于指定需要查询的部门
+ * @return 返回该部门的负责人ID
+ */
+ @Override
+ public Long selectDeptLeaderById(Long deptId) {
+ SysDeptVo vo = SpringUtils.getAopProxy(this).selectDeptById(deptId);
+ return vo.getLeader();
+ }
+
+ /**
+ * 查询部门
+ *
+ * @return 部门列表
+ */
+ @Override
+ public List selectDeptsByList() {
+ List list = baseMapper.selectDeptList(new LambdaQueryWrapper()
+ .select(SysDept::getDeptId, SysDept::getDeptName, SysDept::getParentId)
+ .eq(SysDept::getStatus, SystemConstants.NORMAL));
+ return BeanUtil.copyToList(list, DeptDTO.class);
+ }
+
/**
* 根据ID查询所有子部门数(正常状态)
*
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 8643f0d92..72f1a5e31 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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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 @@ import java.util.List;
*/
@RequiredArgsConstructor
@Service
-public class SysPostServiceImpl implements ISysPostService {
+public class SysPostServiceImpl implements ISysPostService, PostService {
private final SysPostMapper baseMapper;
private final SysDeptMapper deptMapper;
@@ -57,6 +58,17 @@ public class SysPostServiceImpl implements ISysPostService {
return baseMapper.selectVoList(buildQueryWrapper(post));
}
+ /**
+ * 查询用户所属岗位组
+ *
+ * @param userId 用户ID
+ * @return 岗位ID
+ */
+ @Override
+ public List selectPostsByUserId(Long userId) {
+ return baseMapper.selectPostsByUserId(userId);
+ }
+
/**
* 根据查询条件构建查询包装器
*
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 cbca57e5d..4c007358e 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.SystemConstants;
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 @@ import java.util.*;
*/
@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 @@ public class SysRoleServiceImpl implements ISysRoleService {
private int insertRoleMenu(SysRoleBo role) {
int rows = 1;
// 新增用户与角色管理
- List list = new ArrayList();
+ List list = new ArrayList<>();
for (Long menuId : role.getMenuIds()) {
SysRoleMenu rm = new SysRoleMenu();
rm.setRoleId(role.getRoleId());
@@ -372,7 +373,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
private int insertRoleDept(SysRoleBo role) {
int rows = 1;
// 新增角色与部门(数据权限)管理
- List list = new ArrayList();
+ List 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 4b5758763..40811707b 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 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
.in(SysUser::getDeptId, deptIds));
return BeanUtil.copyToList(list, UserDTO.class);
}
+
+ /**
+ * 通过岗位ID查询用户
+ *
+ * @param postIds 岗位ids
+ * @return 用户
+ */
+ @Override
+ public List selectUsersByPostIds(List postIds) {
+ if (CollUtil.isEmpty(postIds)) {
+ return List.of();
+ }
+
+ // 通过岗位ID获取用户岗位信息
+ List userPosts = userPostMapper.selectList(
+ new LambdaQueryWrapper().in(SysUserPost::getPostId, postIds));
+
+ // 获取用户ID列表
+ Set userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId);
+
+ return selectListByIds(new ArrayList<>(userIds));
+ }
+
}