20 Commits

Author SHA1 Message Date
疯狂的狮子Li
d22b2a10df update 优化 PermissionService 无实现类也可以启动服务 2025-05-29 16:28:56 +08:00
疯狂的狮子Li
957a4d1fcd fix 修复 监听器 flowParams 为null报错问题 2025-05-29 16:28:56 +08:00
疯狂的狮子Li
49ef8378fe !691 发布 5.4.0 正式版
Merge pull request !691 from 疯狂的狮子Li/dev
2025-05-29 03:14:59 +00:00
疯狂的狮子Li
57dd6831d3 !664 发布 5.3.1 正式版
Merge pull request !664 from 疯狂的狮子Li/dev
2025-03-27 02:54:00 +00:00
疯狂的狮子Li
8aa60abb1f !663 回退 'Pull Request !662 : 发布 5.3.1 正式版'
* 回退 'Pull Request !662 : 发布 5.3.1 正式版'
2025-03-27 02:53:23 +00:00
疯狂的狮子Li
7a9f51fc7a !662 发布 5.3.1 正式版
* 🐳发布 5.3.1 正式版
* update 优化 删除无用配置
* fix 修复 excel模板导出数据被覆盖的问题
* update 优化 统一用户密码校验长度
* update mybatis-plus 3.5.10.1 => 3.5.11
* fix 修复 跨域未设置请求头问题(cloud版本不需要 vue版本需要)
2025-03-27 02:51:57 +00:00
疯狂的狮子Li
159e30c982 !661 发布 5.3.1-BETA2 公测版本
Merge pull request !661 from 疯狂的狮子Li/dev
2025-03-21 07:25:25 +00:00
疯狂的狮子Li
7334d91d6b !652 发布 5.3.1-BETA 公测版本
Merge pull request !652 from 疯狂的狮子Li/dev
2025-03-13 05:27:36 +00:00
疯狂的狮子Li
95c01301f6 !644 同步修复一些问题
Merge pull request !644 from 疯狂的狮子Li/dev
2025-02-07 06:19:28 +00:00
疯狂的狮子Li
296466fa13 !640 发布 5.3.0 新春版 祝大家新年快乐
Merge pull request !640 from 疯狂的狮子Li/dev
2025-01-24 05:08:28 +00:00
疯狂的狮子Li
3c8d864b5f !639 发布 5.3.0-BETA 公测版本
Merge pull request !639 from 疯狂的狮子Li/dev
2025-01-20 03:35:45 +00:00
疯狂的狮子Li
ea50a57602 update 优化 xss包装器 Parameter 处理 兼容某些容器不允许改参数的情况 2024-11-21 10:17:34 +08:00
疯狂的狮子Li
7e14b98676 reset 回滚错误修改
Signed-off-by: 疯狂的狮子Li <15040126243@163.com>
2024-10-28 09:46:28 +00:00
疯狂的狮子Li
015b406001 !591 发布 5.2.3 正式版
Merge pull request !591 from 疯狂的狮子Li/dev
2024-10-25 03:09:23 +00:00
疯狂的狮子Li
098d3347a0 !577 发布 5.2.2 正式版 安全性提升
Merge pull request !577 from 疯狂的狮子Li/dev
2024-08-26 03:43:59 +00:00
疯狂的狮子Li
08d4493994 update 优化 bug 模板 2024-07-15 15:19:22 +08:00
疯狂的狮子Li
367d739e2d Merge remote-tracking branch 'origin/5.X' into 5.X 2024-07-09 16:38:43 +08:00
疯狂的狮子Li
d6688a367d !562 ♥️发布 5.2.1 正式版本
Merge pull request !562 from 疯狂的狮子Li/dev
2024-07-09 02:42:40 +00:00
疯狂的狮子Li
0b331796e2 !551 ♥️发布 5.2.0 正式版本
Merge pull request !551 from 疯狂的狮子Li/dev
2024-06-20 02:10:15 +00:00
疯狂的狮子Li
456620b638 !549 ♥️发布 5.2.0-BETA2 公测版本
Merge pull request !549 from 疯狂的狮子Li/dev
2024-06-06 03:13:46 +00:00
155 changed files with 1337 additions and 3395 deletions

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> <configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile"> <deployment type="dockerfile">
<settings> <settings>
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.4.1" /> <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.4.0" />
<option name="buildOnly" value="true" /> <option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" /> <option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
</settings> </settings>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> <configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile"> <deployment type="dockerfile">
<settings> <settings>
<option name="imageTag" value="ruoyi/ruoyi-server:5.4.1" /> <option name="imageTag" value="ruoyi/ruoyi-server:5.4.0" />
<option name="buildOnly" value="true" /> <option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> <option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
</settings> </settings>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> <configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile"> <deployment type="dockerfile">
<settings> <settings>
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.4.1" /> <option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.4.0" />
<option name="buildOnly" value="true" /> <option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" /> <option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" />
</settings> </settings>

View File

@@ -10,7 +10,7 @@
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/5.X/LICENSE) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/5.X/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
<br> <br>
[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.4.1-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) [![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.4.0-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4-blue.svg)]() [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4-blue.svg)]()
[![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]() [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]()
[![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]() [![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]()

23
pom.xml
View File

@@ -13,8 +13,8 @@
<description>Dromara RuoYi-Vue-Plus多租户管理系统</description> <description>Dromara RuoYi-Vue-Plus多租户管理系统</description>
<properties> <properties>
<revision>5.4.1</revision> <revision>5.4.0</revision>
<spring-boot.version>3.4.7</spring-boot.version> <spring-boot.version>3.4.6</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version> <java.version>17</java.version>
@@ -23,12 +23,12 @@
<therapi-javadoc.version>0.15.0</therapi-javadoc.version> <therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<fastexcel.version>1.2.0</fastexcel.version> <fastexcel.version>1.2.0</fastexcel.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<satoken.version>1.44.0</satoken.version> <satoken.version>1.42.0</satoken.version>
<mybatis-plus.version>3.5.12</mybatis-plus.version> <mybatis-plus.version>3.5.12</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version> <p6spy.version>3.9.1</p6spy.version>
<hutool.version>5.8.38</hutool.version> <hutool.version>5.8.35</hutool.version>
<spring-boot-admin.version>3.4.7</spring-boot-admin.version> <spring-boot-admin.version>3.4.7</spring-boot-admin.version>
<redisson.version>3.50.0</redisson.version> <redisson.version>3.45.1</redisson.version>
<lock4j.version>2.2.7</lock4j.version> <lock4j.version>2.2.7</lock4j.version>
<dynamic-ds.version>4.3.1</dynamic-ds.version> <dynamic-ds.version>4.3.1</dynamic-ds.version>
<snailjob.version>1.5.0</snailjob.version> <snailjob.version>1.5.0</snailjob.version>
@@ -39,6 +39,7 @@
<justauth.version>1.16.7</justauth.version> <justauth.version>1.16.7</justauth.version>
<!-- 离线IP地址定位库 --> <!-- 离线IP地址定位库 -->
<ip2region.version>2.7.0</ip2region.version> <ip2region.version>2.7.0</ip2region.version>
<!-- OSS 配置 --> <!-- OSS 配置 -->
<aws.sdk.version>2.28.22</aws.sdk.version> <aws.sdk.version>2.28.22</aws.sdk.version>
<!-- SMS 配置 --> <!-- SMS 配置 -->
@@ -46,15 +47,15 @@
<!-- 限制框架中的fastjson版本 --> <!-- 限制框架中的fastjson版本 -->
<fastjson.version>1.2.83</fastjson.version> <fastjson.version>1.2.83</fastjson.version>
<!-- 面向运行时的D-ORM依赖 --> <!-- 面向运行时的D-ORM依赖 -->
<anyline.version>8.7.2-20250603</anyline.version> <anyline.version>8.7.2-20250101</anyline.version>
<!-- 工作流配置 --> <!-- 工作流配置 -->
<warm-flow.version>1.7.4</warm-flow.version> <warm-flow.version>1.7.3</warm-flow.version>
<!-- 插件版本 --> <!-- 插件版本 -->
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version> <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<maven-war-plugin.version>3.4.0</maven-war-plugin.version> <maven-war-plugin.version>3.2.2</maven-war-plugin.version>
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version> <maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version> <flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
<!-- 打包默认跳过测试 --> <!-- 打包默认跳过测试 -->
<skipTests>true</skipTests> <skipTests>true</skipTests>

View File

@@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ # 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds #FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
#FROM findepi/graalvm:java17-native #FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li" LABEL maintainer="Lion Li"

View File

@@ -158,6 +158,6 @@ public class UserActionListener implements SaTokenListener {
* 每次Token续期时触发 * 每次Token续期时触发
*/ */
@Override @Override
public void doRenewTimeout(String loginType, Object loginId, String tokenValue, long timeout) { public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
} }
} }

View File

@@ -3,7 +3,10 @@ package org.dromara.web.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.AuthResponse;
@@ -65,6 +68,15 @@ public class SocialAuthStrategy implements IAuthStrategy {
throw new ServiceException(response.getMsg()); throw new ServiceException(response.getMsg());
} }
AuthUser authUserData = response.getData(); AuthUser authUserData = response.getData();
if ("GITEE".equals(authUserData.getSource())) {
// 如用户使用 gitee 登录顺手 star 给作者一点支持 拒绝白嫖
HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Vue-Plus")
.formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken()))
.executeAsync();
HttpUtil.createRequest(Method.PUT, "https://gitee.com/api/v5/user/starred/dromara/RuoYi-Cloud-Plus")
.formStr(MapUtil.of("access_token", authUserData.getToken().getAccessToken()))
.executeAsync();
}
List<SysSocialVo> list = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid()); List<SysSocialVo> list = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid());
if (CollUtil.isEmpty(list)) { if (CollUtil.isEmpty(list)) {

View File

@@ -127,7 +127,6 @@ tenant:
- sys_user_role - sys_user_role
- sys_client - sys_client
- sys_oss_config - sys_oss_config
- flow_spel
# MyBatisPlus配置 # MyBatisPlus配置
# https://baomidou.com/config/ # https://baomidou.com/config/
@@ -184,12 +183,19 @@ springdoc:
# 描述 # 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...' description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本 # 版本
version: '版本号: ${project.version}' version: '版本号: ${ruoyi.version}'
# 作者信息 # 作者信息
contact: contact:
name: Lion Li name: Lion Li
email: crazylionli@163.com email: crazylionli@163.com
url: https://gitee.com/dromara/RuoYi-Vue-Plus url: https://gitee.com/dromara/RuoYi-Vue-Plus
components:
# 鉴权方式配置
security-schemes:
apiKey:
type: APIKEY
in: HEADER
name: ${sa-token.token-name}
#这里定义了两个分组,可定义多个,也可以不定义 #这里定义了两个分组,可定义多个,也可以不定义
group-configs: group-configs:
- group: 1.演示模块 - group: 1.演示模块
@@ -207,7 +213,7 @@ springdoc:
xss: xss:
# 过滤开关 # 过滤开关
enabled: true enabled: true
# 排除链接 # 排除链接(多个用逗号分隔)
excludeUrls: excludeUrls:
- /system/notice - /system/notice

View File

@@ -17,7 +17,6 @@ user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空 user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符 user.password.not.valid=* 5-50个字符
user.password.format.valid=密码必须包含大写字母、小写字母、数字和特殊字符
user.email.not.valid=邮箱格式错误 user.email.not.valid=邮箱格式错误
user.email.not.blank=邮箱不能为空 user.email.not.blank=邮箱不能为空
user.phonenumber.not.blank=用户手机号不能为空 user.phonenumber.not.blank=用户手机号不能为空

View File

@@ -17,7 +17,6 @@ user.username.length.valid=Account length must be between {min} and {max} charac
user.password.not.blank=Password cannot be empty user.password.not.blank=Password cannot be empty
user.password.length.valid=Password length must be between {min} and {max} characters user.password.length.valid=Password length must be between {min} and {max} characters
user.password.not.valid=* 5-50 characters user.password.not.valid=* 5-50 characters
user.password.format.valid=Password must contain uppercase, lowercase, digit, and special character
user.email.not.valid=Mailbox format error user.email.not.valid=Mailbox format error
user.email.not.blank=Mailbox cannot be blank user.email.not.blank=Mailbox cannot be blank
user.phonenumber.not.blank=Phone number cannot be blank user.phonenumber.not.blank=Phone number cannot be blank

View File

@@ -17,7 +17,6 @@ user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空 user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间 user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符 user.password.not.valid=* 5-50个字符
user.password.format.valid=密码必须包含大写字母、小写字母、数字和特殊字符
user.email.not.valid=邮箱格式错误 user.email.not.valid=邮箱格式错误
user.email.not.blank=邮箱不能为空 user.email.not.blank=邮箱不能为空
user.phonenumber.not.blank=用户手机号不能为空 user.phonenumber.not.blank=用户手机号不能为空

View File

@@ -14,7 +14,7 @@
</description> </description>
<properties> <properties>
<revision>5.4.1</revision> <revision>5.4.0</revision>
</properties> </properties>
<dependencyManagement> <dependencyManagement>

View File

@@ -77,9 +77,4 @@ public interface SystemConstants {
*/ */
String ROOT_DEPT_ANCESTORS = "0"; String ROOT_DEPT_ANCESTORS = "0";
/**
* 默认部门 ID
*/
Long DEFAULT_DEPT_ID = 100L;
} }

View File

@@ -52,14 +52,14 @@ public class TaskAssigneeDTO implements Serializable {
*/ */
public static <T> List<TaskHandler> convertToHandlerList( public static <T> List<TaskHandler> convertToHandlerList(
List<T> sourceList, List<T> sourceList,
Function<T, String> storageId, Function<T, Long> storageId,
Function<T, String> handlerCode, Function<T, String> handlerCode,
Function<T, String> handlerName, Function<T, String> handlerName,
Function<T, Long> groupName, Function<T, Long> groupName,
Function<T, Date> createTimeMapper) { Function<T, Date> createTimeMapper) {
return sourceList.stream() return sourceList.stream()
.map(item -> new TaskHandler( .map(item -> new TaskHandler(
storageId.apply(item), String.valueOf(storageId.apply(item)),
handlerCode.apply(item), handlerCode.apply(item),
handlerName.apply(item), handlerName.apply(item),
groupName != null ? String.valueOf(groupName.apply(item)) : null, groupName != null ? String.valueOf(groupName.apply(item)) : null,

View File

@@ -26,7 +26,6 @@ public class PasswordLoginBody extends LoginBody {
*/ */
@NotBlank(message = "{user.password.not.blank}") @NotBlank(message = "{user.password.not.blank}")
@Length(min = 5, max = 30, message = "{user.password.length.valid}") @Length(min = 5, max = 30, message = "{user.password.length.valid}")
// @Pattern(regexp = RegexConstants.PASSWORD, message = "{user.password.format.valid}")
private String password; private String password;
} }

View File

@@ -26,12 +26,8 @@ public class RegisterBody extends LoginBody {
*/ */
@NotBlank(message = "{user.password.not.blank}") @NotBlank(message = "{user.password.not.blank}")
@Length(min = 5, max = 30, message = "{user.password.length.valid}") @Length(min = 5, max = 30, message = "{user.password.length.valid}")
// @Pattern(regexp = RegexConstants.PASSWORD, message = "{user.password.format.valid}")
private String password; private String password;
/**
* 用户类型
*/
private String userType; private String userType;
} }

View File

@@ -3,7 +3,6 @@ package org.dromara.common.core.service;
import org.dromara.common.core.domain.dto.DeptDTO; import org.dromara.common.core.domain.dto.DeptDTO;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 通用 部门服务 * 通用 部门服务
@@ -35,12 +34,4 @@ public interface DeptService {
*/ */
List<DeptDTO> selectDeptsByList(); List<DeptDTO> selectDeptsByList();
/**
* 根据部门 ID 列表查询部门名称映射关系
*
* @param deptIds 部门 ID 列表
* @return Map其中 key 为部门 IDvalue 为对应的部门名称
*/
Map<Long, String> selectDeptNamesByIds(List<Long> deptIds);
} }

View File

@@ -1,8 +1,5 @@
package org.dromara.common.core.service; package org.dromara.common.core.service;
import java.util.List;
import java.util.Map;
/** /**
* 通用 岗位服务 * 通用 岗位服务
* *
@@ -10,12 +7,4 @@ import java.util.Map;
*/ */
public interface PostService { public interface PostService {
/**
* 根据岗位 ID 列表查询岗位名称映射关系
*
* @param postIds 岗位 ID 列表
* @return Map其中 key 为岗位 IDvalue 为对应的岗位名称
*/
Map<Long, String> selectPostNamesByIds(List<Long> postIds);
} }

View File

@@ -1,8 +1,5 @@
package org.dromara.common.core.service; package org.dromara.common.core.service;
import java.util.List;
import java.util.Map;
/** /**
* 通用 角色服务 * 通用 角色服务
* *
@@ -10,12 +7,4 @@ import java.util.Map;
*/ */
public interface RoleService { public interface RoleService {
/**
* 根据角色 ID 列表查询角色名称映射关系
*
* @param roleIds 角色 ID 列表
* @return Map其中 key 为角色 IDvalue 为对应的角色名称
*/
Map<Long, String> selectRoleNamesByIds(List<Long> roleIds);
} }

View File

@@ -100,4 +100,28 @@ public interface UserService {
*/ */
Map<Long, String> selectUserNamesByIds(List<Long> userIds); Map<Long, String> selectUserNamesByIds(List<Long> userIds);
/**
* 根据角色 ID 列表查询角色名称映射关系
*
* @param roleIds 角色 ID 列表
* @return Map其中 key 为角色 IDvalue 为对应的角色名称
*/
Map<Long, String> selectRoleNamesByIds(List<Long> roleIds);
/**
* 根据部门 ID 列表查询部门名称映射关系
*
* @param deptIds 部门 ID 列表
* @return Map其中 key 为部门 IDvalue 为对应的部门名称
*/
Map<Long, String> selectDeptNamesByIds(List<Long> deptIds);
/**
* 根据岗位 ID 列表查询岗位名称映射关系
*
* @param postIds 岗位 ID 列表
* @return Map其中 key 为岗位 IDvalue 为对应的岗位名称
*/
Map<Long, String> selectPostNamesByIds(List<Long> postIds);
} }

View File

@@ -10,8 +10,6 @@ import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.reflect.ReflectUtils; import org.dromara.common.core.utils.reflect.ReflectUtils;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -62,31 +60,6 @@ public class TreeBuildUtils extends TreeUtil {
return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser); return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser);
} }
/**
* 构建多根节点的树结构(支持多个顶级节点)
*
* @param list 原始数据列表
* @param getId 获取节点 ID 的方法引用例如node -> node.getId()
* @param getParentId 获取节点父级 ID 的方法引用例如node -> node.getParentId()
* @param parser 树节点属性映射器,用于将原始节点 T 转为 Tree 节点
* @param <T> 原始数据类型如实体类、DTO 等)
* @param <K> 节点 ID 类型(如 Long、String
* @return 构建完成的树形结构(可能包含多个顶级根节点)
*/
public static <T, K> List<Tree<K>> buildMultiRoot(List<T> list, Function<T, K> getId, Function<T, K> getParentId, NodeParser<T, K> parser) {
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
Set<K> rootParentIds = StreamUtils.toSet(list, getParentId);
rootParentIds.removeAll(StreamUtils.toSet(list, getId));
// 构建每一个根 parentId 下的树,并合并成最终结果列表
return rootParentIds.stream()
.flatMap(rootParentId -> TreeUtil.build(list, rootParentId, parser).stream())
.collect(Collectors.toList());
}
/** /**
* 获取节点列表中所有节点的叶子节点 * 获取节点列表中所有节点的叶子节点
* *

View File

@@ -16,55 +16,28 @@ import org.dromara.common.core.utils.StringUtils;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AddressUtils { public class AddressUtils {
// 未知IP
public static final String UNKNOWN_IP = "XX XX";
// 内网地址
public static final String LOCAL_ADDRESS = "内网IP";
// 未知地址 // 未知地址
public static final String UNKNOWN_ADDRESS = "未知"; public static final String UNKNOWN = "XX XX";
public static String getRealAddressByIP(String ip) { public static String getRealAddressByIP(String ip) {
// 处理空串并过滤HTML标签 // 处理空串并过滤HTML标签
ip = HtmlUtil.cleanHtmlTag(StringUtils.blankToDefault(ip,"")); ip = HtmlUtil.cleanHtmlTag(StringUtils.blankToDefault(ip,""));
// 判断是否为IPv4 boolean isIPv6 = NetUtils.isIPv6(ip);
if (NetUtils.isIPv4(ip)) { // 判断是否为IPv4或IPv6如果不是则返回未知地址
return resolverIPv4Region(ip); if (!NetUtils.isIPv4(ip) && !isIPv6) {
return UNKNOWN;
} }
// 判断是否为IPv6
if (NetUtils.isIPv6(ip)) {
return resolverIPv6Region(ip);
}
// 如果不是IPv4或IPv6则返回未知IP
return UNKNOWN_IP;
}
/**
* 根据IPv4地址查询IP归属行政区域
* @param ip ipv4地址
* @return 归属行政区域
*/
private static String resolverIPv4Region(String ip){
// 内网不查询 // 内网不查询
if (NetUtils.isInnerIP(ip)) { if (NetUtils.isInnerIPv6(ip) || NetUtils.isInnerIP(ip)) {
return LOCAL_ADDRESS; return "内网IP";
}
// 不支持IPv6不再进行没有必要的IP地址信息的解析直接返回
if (isIPv6) {
log.warn("ip2region不支持IPV6地址解析{}", ip);
// 如有需要可自行实现IPv6地址信息解析逻辑并在这里返回
return "未知";
} }
return RegionUtils.getCityInfo(ip); return RegionUtils.getCityInfo(ip);
} }
/**
* 根据IPv6地址查询IP归属行政区域
* @param ip ipv6地址
* @return 归属行政区域
*/
private static String resolverIPv6Region(String ip){
// 内网不查询
if (NetUtils.isInnerIPv6(ip)) {
return LOCAL_ADDRESS;
}
log.warn("ip2region不支持IPV6地址解析{}", ip);
// 不支持IPv6不再进行没有必要的IP地址信息的解析直接返回
// 如有需要可自行实现IPv6地址信息解析逻辑并在这里返回
return UNKNOWN_ADDRESS;
}
} }

View File

@@ -54,15 +54,14 @@ public class SpringDocConfig {
openApi.externalDocs(properties.getExternalDocs()); openApi.externalDocs(properties.getExternalDocs());
openApi.tags(properties.getTags()); openApi.tags(properties.getTags());
openApi.paths(properties.getPaths()); openApi.paths(properties.getPaths());
if (properties.getComponents() != null) { openApi.components(properties.getComponents());
openApi.components(properties.getComponents()); Set<String> keySet = properties.getComponents().getSecuritySchemes().keySet();
Set<String> keySet = properties.getComponents().getSecuritySchemes().keySet(); List<SecurityRequirement> list = new ArrayList<>();
List<SecurityRequirement> list = new ArrayList<>(); SecurityRequirement securityRequirement = new SecurityRequirement();
SecurityRequirement securityRequirement = new SecurityRequirement(); keySet.forEach(securityRequirement::addList);
keySet.forEach(securityRequirement::addList); list.add(securityRequirement);
list.add(securityRequirement); openApi.security(list);
openApi.security(list);
}
return openApi; return openApi;
} }

View File

@@ -5,7 +5,6 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*; import org.apache.ibatis.plugin.*;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
@@ -40,23 +39,12 @@ public class MybatisDecryptInterceptor implements Interceptor {
@Override @Override
public Object intercept(Invocation invocation) throws Throwable { public Object intercept(Invocation invocation) throws Throwable {
// 开始进行参数解密
ResultSetHandler resultSetHandler = (ResultSetHandler) invocation.getTarget();
Field parameterHandlerField = resultSetHandler.getClass().getDeclaredField("parameterHandler");
parameterHandlerField.setAccessible(true);
Object target = parameterHandlerField.get(resultSetHandler);
if (target instanceof ParameterHandler parameterHandler) {
Object parameterObject = parameterHandler.getParameterObject();
if (ObjectUtil.isNotNull(parameterObject) && !(parameterObject instanceof String)) {
this.decryptHandler(parameterObject);
}
}
// 获取执行mysql执行结果 // 获取执行mysql执行结果
Object result = invocation.proceed(); Object result = invocation.proceed();
if (result == null) { if (result == null) {
return null; return null;
} }
this.decryptHandler(result); decryptHandler(result);
return result; return result;
} }

View File

@@ -6,13 +6,17 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 批注 此注解仅用于单表头 不支持多层级表头 * 批注
* @author guzhouyanyu * @author guzhouyanyu
*/ */
@Target({ElementType.FIELD}) @Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface ExcelNotation { public @interface ExcelNotation {
/**
* col index
*/
int index() default -1;
/** /**
* 批注内容 * 批注内容
*/ */

View File

@@ -8,13 +8,17 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 是否必填 此注解仅用于单表头 不支持多层级表头 * 是否必填
* @author guzhouyanyu * @author guzhouyanyu
*/ */
@Target({ElementType.FIELD}) @Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface ExcelRequired { public @interface ExcelRequired {
/**
* col index
*/
int index() default -1;
/** /**
* 字体颜色 * 字体颜色
*/ */

View File

@@ -1,7 +1,6 @@
package org.dromara.common.excel.handler; package org.dromara.common.excel.handler;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.metadata.data.DataFormatData; import cn.idev.excel.metadata.data.DataFormatData;
import cn.idev.excel.metadata.data.WriteCellData; import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.util.StyleUtil; import cn.idev.excel.util.StyleUtil;
@@ -14,6 +13,7 @@ import cn.idev.excel.write.metadata.style.WriteFont;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString; 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.ExcelNotation;
import org.dromara.common.excel.annotation.ExcelRequired; import org.dromara.common.excel.annotation.ExcelRequired;
@@ -31,12 +31,12 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
/** /**
* 批注 * 批注
*/ */
private final Map<String, String> notationMap; private final Map<Integer, String> notationMap;
/** /**
* 头列字体颜色 * 头列字体颜色
*/ */
private final Map<String, Short> headColumnMap; private final Map<Integer, Short> headColumnMap;
public DataWriteHandler(Class<?> clazz) { public DataWriteHandler(Class<?> clazz) {
@@ -49,16 +49,15 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
if (CollUtil.isEmpty(notationMap) && CollUtil.isEmpty(headColumnMap)) { if (CollUtil.isEmpty(notationMap) && CollUtil.isEmpty(headColumnMap)) {
return; return;
} }
// 第一行
WriteCellData<?> cellData = context.getFirstCellData(); WriteCellData<?> cellData = context.getFirstCellData();
// 第一个格子
WriteCellStyle writeCellStyle = cellData.getOrCreateStyle(); WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
DataFormatData dataFormatData = new DataFormatData();
// 单元格设置为文本格式
dataFormatData.setIndex((short) 49);
writeCellStyle.setDataFormatData(dataFormatData);
if (context.getHead()) { if (context.getHead()) {
DataFormatData dataFormatData = new DataFormatData();
// 单元格设置为文本格式
dataFormatData.setIndex((short) 49);
writeCellStyle.setDataFormatData(dataFormatData);
Cell cell = context.getCell(); Cell cell = context.getCell();
WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder(); WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
Sheet sheet = writeSheetHolder.getSheet(); Sheet sheet = writeSheetHolder.getSheet();
@@ -68,17 +67,17 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
WriteFont headWriteFont = new WriteFont(); WriteFont headWriteFont = new WriteFont();
// 加粗 // 加粗
headWriteFont.setBold(true); headWriteFont.setBold(true);
if (CollUtil.isNotEmpty(headColumnMap) && headColumnMap.containsKey(cell.getStringCellValue())) { if (CollUtil.isNotEmpty(headColumnMap) && headColumnMap.containsKey(cell.getColumnIndex())) {
// 设置字体颜色 // 设置字体颜色
headWriteFont.setColor(headColumnMap.get(cell.getStringCellValue())); headWriteFont.setColor(headColumnMap.get(cell.getColumnIndex()));
} }
writeCellStyle.setWriteFont(headWriteFont); writeCellStyle.setWriteFont(headWriteFont);
CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, null, writeCellStyle); CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, null, writeCellStyle);
cell.setCellStyle(cellStyle); cell.setCellStyle(cellStyle);
if (CollUtil.isNotEmpty(notationMap) && notationMap.containsKey(cell.getStringCellValue())) { if (CollUtil.isNotEmpty(notationMap) && notationMap.containsKey(cell.getColumnIndex())) {
// 批注内容 // 批注内容
String notationContext = notationMap.get(cell.getStringCellValue()); String notationContext = notationMap.get(cell.getColumnIndex());
// 创建绘图对象 // 创建绘图对象
Comment comment = drawing.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), 0, (short) 5, 5)); Comment comment = drawing.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), 0, (short) 5, 5));
comment.setString(new XSSFRichTextString(notationContext)); comment.setString(new XSSFRichTextString(notationContext));
@@ -90,16 +89,23 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
/** /**
* 获取必填列 * 获取必填列
*/ */
private static Map<String, Short> getRequiredMap(Class<?> clazz) { private static Map<Integer, Short> getRequiredMap(Class<?> clazz) {
Map<String, Short> requiredMap = new HashMap<>(); Map<Integer, Short> requiredMap = new HashMap<>();
Field[] fields = clazz.getDeclaredFields(); Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) { // 检查 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)) { if (!field.isAnnotationPresent(ExcelRequired.class)) {
continue; continue;
} }
ExcelRequired excelRequired = field.getAnnotation(ExcelRequired.class); ExcelRequired excelRequired = field.getAnnotation(ExcelRequired.class);
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); int columnIndex = excelRequired.index() == -1 ? i : excelRequired.index();
requiredMap.put(excelProperty.value()[0], excelRequired.fontColor().getIndex()); requiredMap.put(columnIndex, excelRequired.fontColor().getIndex());
} }
return requiredMap; return requiredMap;
} }
@@ -107,16 +113,22 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
/** /**
* 获取批注 * 获取批注
*/ */
private static Map<String, String> getNotationMap(Class<?> clazz) { private static Map<Integer, String> getNotationMap(Class<?> clazz) {
Map<String, String> notationMap = new HashMap<>(); Map<Integer, String> notationMap = new HashMap<>();
Field[] fields = clazz.getDeclaredFields(); Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) { // 检查 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)) { if (!field.isAnnotationPresent(ExcelNotation.class)) {
continue; continue;
} }
ExcelNotation excelNotation = field.getAnnotation(ExcelNotation.class); ExcelNotation excelNotation = field.getAnnotation(ExcelNotation.class);
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); int columnIndex = excelNotation.index() == -1 ? i : excelNotation.index();
notationMap.put(excelProperty.value()[0], excelNotation.value()); notationMap.put(columnIndex, excelNotation.value());
} }
return notationMap; return notationMap;
} }

View File

@@ -22,11 +22,6 @@ import java.util.Date;
@Slf4j @Slf4j
public class InjectionMetaObjectHandler implements MetaObjectHandler { public class InjectionMetaObjectHandler implements MetaObjectHandler {
/**
* 如果用户不存在默认注入-1代表无用户
*/
private static final Long DEFAULT_USER_ID = -1L;
/** /**
* 插入填充方法,用于在插入数据时自动填充实体对象中的创建时间、更新时间、创建人、更新人等信息 * 插入填充方法,用于在插入数据时自动填充实体对象中的创建时间、更新时间、创建人、更新人等信息
* *
@@ -50,11 +45,6 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler {
baseEntity.setCreateBy(userId); baseEntity.setCreateBy(userId);
baseEntity.setUpdateBy(userId); baseEntity.setUpdateBy(userId);
baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), loginUser.getDeptId())); baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), loginUser.getDeptId()));
} else {
// 填充创建人、更新人和创建部门信息
baseEntity.setCreateBy(DEFAULT_USER_ID);
baseEntity.setUpdateBy(DEFAULT_USER_ID);
baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), DEFAULT_USER_ID));
} }
} }
} else { } else {
@@ -84,8 +74,6 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler {
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
if (ObjectUtil.isNotNull(userId)) { if (ObjectUtil.isNotNull(userId)) {
baseEntity.setUpdateBy(userId); baseEntity.setUpdateBy(userId);
} else {
baseEntity.setUpdateBy(DEFAULT_USER_ID);
} }
} else { } else {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
@@ -105,6 +93,7 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler {
try { try {
loginUser = LoginHelper.getLoginUser(); loginUser = LoginHelper.getLoginUser();
} catch (Exception e) { } catch (Exception e) {
log.warn("自动注入警告 => 用户未登录");
return null; return null;
} }
return loginUser; return loginUser;

View File

@@ -16,9 +16,7 @@ import java.util.function.Function;
* *
* @author Lion Li * @author Lion Li
* @version 3.6.0 新增 * @version 3.6.0 新增
* @deprecated redisson 新版本已经将队列功能标记删除 一些技术问题无法解决 建议搭建MQ使用
*/ */
@Deprecated
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class QueueUtils { public class QueueUtils {

View File

@@ -1,6 +1,7 @@
package org.dromara.common.redis.utils; package org.dromara.common.redis.utils;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.SpringUtils;
@@ -9,10 +10,6 @@ import org.redisson.api.RIdGenerator;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
/** /**
* 发号器工具类 * 发号器工具类
@@ -26,12 +23,12 @@ public class SequenceUtils {
/** /**
* 默认初始值 * 默认初始值
*/ */
public static final long DEFAULT_INIT_VALUE = 1L; public static final Long DEFAULT_INIT_VALUE = 1L;
/** /**
* 默认步长 * 默认步长
*/ */
public static final long DEFAULT_STEP_VALUE = 1L; public static final Long DEFAULT_STEP_VALUE = 1L;
/** /**
* 默认过期时间-天 * 默认过期时间-天
@@ -43,11 +40,6 @@ public class SequenceUtils {
*/ */
public static final Duration DEFAULT_EXPIRE_TIME_MINUTE = Duration.ofMinutes(1); public static final Duration DEFAULT_EXPIRE_TIME_MINUTE = Duration.ofMinutes(1);
/**
* 默认最小ID容量位数 - 6位数即至少可以生成的ID为999999个
*/
public static final int DEFAULT_MIN_ID_CAPACITY_BITS = 6;
/** /**
* 获取Redisson客户端实例 * 获取Redisson客户端实例
*/ */
@@ -62,11 +54,14 @@ public class SequenceUtils {
* @param stepValue ID步长 * @param stepValue ID步长
* @return ID生成器 * @return ID生成器
*/ */
public static RIdGenerator getIdGenerator(String key, Duration expireTime, long initValue, long stepValue) { 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); RIdGenerator idGenerator = REDISSON_CLIENT.getIdGenerator(key);
// 初始值和步长不能小于等于0
initValue = initValue <= 0 ? DEFAULT_INIT_VALUE : initValue;
stepValue = stepValue <= 0 ? DEFAULT_STEP_VALUE : stepValue;
// 设置初始值和步长 // 设置初始值和步长
idGenerator.tryInit(initValue, stepValue); idGenerator.tryInit(initValue, stepValue);
// 设置过期时间 // 设置过期时间
@@ -74,17 +69,6 @@ public class SequenceUtils {
return idGenerator; return idGenerator;
} }
/**
* 获取ID生成器
*
* @param key 业务key
* @param expireTime 过期时间
* @return ID生成器
*/
public static RIdGenerator getIdGenerator(String key, Duration expireTime) {
return getIdGenerator(key, expireTime, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE);
}
/** /**
* 获取指定业务key的唯一id * 获取指定业务key的唯一id
* *
@@ -94,21 +78,10 @@ public class SequenceUtils {
* @param stepValue ID步长 * @param stepValue ID步长
* @return 唯一id * @return 唯一id
*/ */
public static long getNextId(String key, Duration expireTime, long initValue, long stepValue) { public static long nextId(String key, Duration expireTime, Long initValue, Long stepValue) {
return getIdGenerator(key, expireTime, initValue, stepValue).nextId(); return getIdGenerator(key, expireTime, initValue, stepValue).nextId();
} }
/**
* 获取指定业务key的唯一id (ID初始值=1,ID步长=1)
*
* @param key 业务key
* @param expireTime 过期时间
* @return 唯一id
*/
public static long getNextId(String key, Duration expireTime) {
return getIdGenerator(key, expireTime).nextId();
}
/** /**
* 获取指定业务key的唯一id字符串 * 获取指定业务key的唯一id字符串
* *
@@ -118,8 +91,19 @@ public class SequenceUtils {
* @param stepValue ID步长 * @param stepValue ID步长
* @return 唯一id * @return 唯一id
*/ */
public static String getNextIdString(String key, Duration expireTime, long initValue, long stepValue) { public static String nextIdStr(String key, Duration expireTime, Long initValue, Long stepValue) {
return String.valueOf(getNextId(key, expireTime, initValue, 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();
} }
/** /**
@@ -129,8 +113,8 @@ public class SequenceUtils {
* @param expireTime 过期时间 * @param expireTime 过期时间
* @return 唯一id * @return 唯一id
*/ */
public static String getNextIdString(String key, Duration expireTime) { public static String nextIdStr(String key, Duration expireTime) {
return String.valueOf(getNextId(key, expireTime)); return String.valueOf(nextId(key, expireTime));
} }
/** /**
@@ -141,210 +125,56 @@ public class SequenceUtils {
* @param width 位数不足左补0 * @param width 位数不足左补0
* @return 补零后的唯一id字符串 * @return 补零后的唯一id字符串
*/ */
public static String getPaddedNextIdString(String key, Duration expireTime, Integer width) { public static String nextPaddedIdStr(String key, Duration expireTime, Integer width) {
return StringUtils.leftPad(getNextIdString(key, expireTime), width, '0'); return StringUtils.leftPad(nextIdStr(key, expireTime), width, '0');
} }
/** /**
* 获取 yyyyMMdd 格式的唯一id * 获取 yyyyMMdd 开头的唯一id
* *
* @return 唯一id * @return 唯一id
* @deprecated 请使用 {@link #getDateId(String)} 或 {@link #getDateId(String, boolean)}、{@link #getDateId(String, boolean, int)}确保不同业务的ID连续性
*/ */
@Deprecated public static String nextIdDate() {
public static String getDateId() { return nextIdDate("");
return getDateId("");
} }
/** /**
* 获取 prefix + yyyyMMdd 格式的唯一id * 获取 prefix + yyyyMMdd 开头的唯一id
* *
* @param prefix 业务前缀 * @param prefix 业务前缀
* @return 唯一id * @return 唯一id
*/ */
public static String getDateId(String prefix) { public static String nextIdDate(String prefix) {
return getDateId(prefix, true); // 前缀+日期 构建 prefixKey
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_FORMATTER));
// 获取下一个id
long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_DAY, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
// 返回完整id
return StringUtils.format("{}{}", prefixKey, nextId);
} }
/** /**
* 获取 prefix + yyyyMMdd 格式的唯一id * 获取 yyyyMMddHHmmss 开头的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @return 唯一id
*/
public static String getDateId(String prefix, boolean isWithPrefix) {
return getDateId(prefix, isWithPrefix, -1);
}
/**
* 获取 prefix + yyyyMMdd 格式的唯一id (启用ID补位补位长度 = {@link #DEFAULT_MIN_ID_CAPACITY_BITS})}
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @return 唯一id
*/
public static String getPaddedDateId(String prefix, boolean isWithPrefix) {
return getDateId(prefix, isWithPrefix, DEFAULT_MIN_ID_CAPACITY_BITS);
}
/**
* 获取 prefix + yyyyMMdd 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @return 唯一id
*/
public static String getDateId(String prefix, boolean isWithPrefix, int minIdCapacityBits) {
return getDateId(prefix, isWithPrefix, minIdCapacityBits, LocalDate.now());
}
/**
* 获取 prefix + yyyyMMdd 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @param time 时间
* @return 唯一id
*/
public static String getDateId(String prefix, boolean isWithPrefix, int minIdCapacityBits, LocalDate time) {
return getDateId(prefix, isWithPrefix, minIdCapacityBits, time, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE);
}
/**
* 获取 prefix + yyyyMMdd 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @param time 时间
* @param initValue ID初始值
* @param stepValue ID步长
* @return 唯一id
*/
public static String getDateId(String prefix, boolean isWithPrefix, int minIdCapacityBits, LocalDate time, long initValue, long stepValue) {
return getDatePatternId(prefix, isWithPrefix, minIdCapacityBits, time, DatePattern.PURE_DATE_FORMATTER, DEFAULT_EXPIRE_TIME_DAY, initValue, stepValue);
}
/**
* 获取 yyyyMMddHHmmss 格式的唯一id
* *
* @return 唯一id * @return 唯一id
* @deprecated 请使用 {@link #getDateTimeId(String)} 或 {@link #getDateTimeId(String, boolean)}、{@link #getDateTimeId(String, boolean, int)}确保不同业务的ID连续性
*/ */
@Deprecated public static String nextIdDateTime() {
public static String getDateTimeId() { return nextIdDateTime("");
return getDateTimeId("", false);
} }
/** /**
* 获取 prefix + yyyyMMddHHmmss 格式的唯一id * 获取 prefix + yyyyMMddHHmmss 开头的唯一id
* *
* @param prefix 业务前缀 * @param prefix 业务前缀
* @return 唯一id * @return 唯一id
*/ */
public static String getDateTimeId(String prefix) { public static String nextIdDateTime(String prefix) {
return getDateTimeId(prefix, true); // 前缀+日期时间 构建 prefixKey
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_FORMATTER));
// 获取下一个id
long nextId = getIdGenerator(prefixKey, DEFAULT_EXPIRE_TIME_MINUTE, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE).nextId();
// 返回完整id
return StringUtils.format("{}{}", prefixKey, nextId);
} }
/**
* 获取 prefix + yyyyMMddHHmmss 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @return 唯一id
*/
public static String getDateTimeId(String prefix, boolean isWithPrefix) {
return getDateTimeId(prefix, isWithPrefix, -1);
}
/**
* 获取 prefix + yyyyMMddHHmmss 格式的唯一id (启用ID补位补位长度 = {@link #DEFAULT_MIN_ID_CAPACITY_BITS})}
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @return 唯一id
*/
public static String getPaddedDateTimeId(String prefix, boolean isWithPrefix) {
return getDateTimeId(prefix, isWithPrefix, DEFAULT_MIN_ID_CAPACITY_BITS);
}
/**
* 获取 prefix + yyyyMMddHHmmss 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @return 唯一id
*/
public static String getDateTimeId(String prefix, boolean isWithPrefix, int minIdCapacityBits) {
return getDateTimeId(prefix, isWithPrefix, minIdCapacityBits, LocalDateTime.now());
}
/**
* 获取 prefix + yyyyMMddHHmmss 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @param time 时间
* @return 唯一id
*/
public static String getDateTimeId(String prefix, boolean isWithPrefix, int minIdCapacityBits, LocalDateTime time) {
return getDateTimeId(prefix, isWithPrefix, minIdCapacityBits, time, DEFAULT_INIT_VALUE, DEFAULT_STEP_VALUE);
}
/**
* 获取 prefix + yyyyMMddHHmmss 格式的唯一id
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @param initValue ID初始值
* @param stepValue ID步长
* @return 唯一id
*/
public static String getDateTimeId(String prefix, boolean isWithPrefix, int minIdCapacityBits, LocalDateTime time, long initValue, long stepValue) {
return getDatePatternId(prefix, isWithPrefix, minIdCapacityBits, time, DatePattern.PURE_DATETIME_FORMATTER, DEFAULT_EXPIRE_TIME_MINUTE, initValue, stepValue);
}
/**
* 获取指定业务key的指定时间格式的ID
*
* @param prefix 业务前缀
* @param isWithPrefix id是否携带业务前缀
* @param minIdCapacityBits 最小ID容量位数小于该位数的ID左补0小于等于0表示不启用补位
* @param temporalAccessor 时间访问器
* @param timeFormatter 时间格式
* @param expireTime 过期时间
* @param initValue ID初始值
* @param stepValue ID步长
* @return 唯一id
*/
private static String getDatePatternId(String prefix, boolean isWithPrefix, int minIdCapacityBits, TemporalAccessor temporalAccessor, DateTimeFormatter timeFormatter, Duration expireTime, long initValue, long stepValue) {
// 时间前缀
String timePrefix = timeFormatter.format(temporalAccessor);
// 业务前缀 + 时间前缀 构建 prefixKey
String prefixKey = StringUtils.format("{}{}", StringUtils.blankToDefault(prefix, ""), timePrefix);
// 获取id例 -> 1
String nextId = getNextIdString(prefixKey, expireTime, initValue, stepValue);
// minIdCapacityBits 大于0且 nextId 的长度小于 minIdCapacityBits则左补0
if (minIdCapacityBits > 0 && nextId.length() < minIdCapacityBits) {
nextId = StringUtils.leftPad(nextId, minIdCapacityBits, '0');
}
// 是否携带业务前缀
if (isWithPrefix) {
// 例 -> P202507031
// 其中 P 为业务前缀202507031 为 yyyyMMdd 格式时间, 1 为nextId
return StringUtils.format("{}{}", prefixKey, nextId);
}
// 例 -> 202507031
// 其中 202507031 为 yyyyMMdd 格式时间, 1 为nextId
return StringUtils.format("{}{}", timePrefix, nextId);
}
} }

View File

@@ -1,154 +0,0 @@
package me.zhyd.oauth.request;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.HttpUtils;
import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder;
/**
* <p>
* 企业微信登录父类
* </p>
*
* @author liguanhua (347826496(a)qq.com)
* @since 1.15.9
*/
public abstract class AbstractAuthWeChatEnterpriseRequest extends AuthDefaultRequest {
public AbstractAuthWeChatEnterpriseRequest(AuthConfig config, AuthSource source) {
super(config,source);
}
public AbstractAuthWeChatEnterpriseRequest(AuthConfig config, AuthSource source, AuthStateCache authStateCache) {
super(config, source, authStateCache);
}
@Override
public AuthToken getAccessToken(AuthCallback authCallback) {
String response = doGetAuthorizationCode(accessTokenUrl(null));
JSONObject object = this.checkResponse(response);
return AuthToken.builder()
.accessToken(object.getString("access_token"))
.expireIn(object.getIntValue("expires_in"))
.code(authCallback.getCode())
.build();
}
@Override
public AuthUser getUserInfo(AuthToken authToken) {
String response = doGetUserInfo(authToken);
JSONObject object = this.checkResponse(response);
// 返回 OpenId 或其他,均代表非当前企业用户,不支持
// https://github.com/justauth/JustAuth/issues/227 修复bug
if (!object.containsKey("userid")) {
throw new AuthException(AuthResponseStatus.UNIDENTIFIED_PLATFORM, source);
}
String userId = object.getString("userid");
String userTicket = object.getString("user_ticket");
JSONObject userDetail = getUserDetail(authToken.getAccessToken(), userId, userTicket);
return AuthUser.builder()
.rawUserInfo(userDetail)
.username(userDetail.getString("name"))
.nickname(userDetail.getString("alias"))
.avatar(userDetail.getString("avatar"))
.location(userDetail.getString("address"))
.email(userDetail.getString("email"))
.uuid(userId)
.gender(AuthUserGender.getWechatRealGender(userDetail.getString("gender")))
.token(authToken)
.source(source.toString())
.build();
}
/**
* 校验请求结果
*
* @param response 请求结果
* @return 如果请求结果正常则返回JSONObject
*/
private JSONObject checkResponse(String response) {
JSONObject object = JSONObject.parseObject(response);
if (object.containsKey("errcode") && object.getIntValue("errcode") != 0) {
throw new AuthException(object.getString("errmsg"), source);
}
return object;
}
/**
* 返回获取accessToken的url
*
* @param code 授权码
* @return 返回获取accessToken的url
*/
@Override
protected String accessTokenUrl(String code) {
return UrlBuilder.fromBaseUrl(source.accessToken())
.queryParam("corpid", config.getClientId())
.queryParam("corpsecret", config.getClientSecret())
.build();
}
/**
* 返回获取userInfo的url
*
* @param authToken 用户授权后的token
* @return 返回获取userInfo的url
*/
@Override
protected String userInfoUrl(AuthToken authToken) {
return UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("access_token", authToken.getAccessToken())
.queryParam("code", authToken.getCode())
.build();
}
/**
* 用户详情
*
* @param accessToken accessToken
* @param userId 企业内用户id
* @param userTicket 成员票据,用于获取用户信息或敏感信息
* @return 用户详情
*/
private JSONObject getUserDetail(String accessToken, String userId, String userTicket) {
// 用户基础信息
String userInfoUrl = UrlBuilder.fromBaseUrl("https://qyapi.weixin.qq.com/cgi-bin/user/get")
.queryParam("access_token", accessToken)
.queryParam("userid", userId)
.build();
String userInfoResponse = new HttpUtils(config.getHttpConfig()).get(userInfoUrl).getBody();
JSONObject userInfo = checkResponse(userInfoResponse);
// 用户敏感信息
if (StringUtils.isNotEmpty(userTicket)) {
String userDetailUrl = UrlBuilder.fromBaseUrl("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail")
.queryParam("access_token", accessToken)
.build();
JSONObject param = new JSONObject();
param.put("user_ticket", userTicket);
String userDetailResponse = new HttpUtils(config.getHttpConfig()).post(userDetailUrl, param.toJSONString()).getBody();
JSONObject userDetail = checkResponse(userDetailResponse);
userInfo.putAll(userDetail);
}
return userInfo;
}
}

View File

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.sse.core.SseEmitterManager; import org.dromara.common.sse.core.SseEmitterManager;
import org.dromara.common.sse.dto.SseMessageDto;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@@ -13,6 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.List;
/** /**
* SSE 控制器 * SSE 控制器
* *
@@ -30,9 +33,7 @@ public class SseController implements DisposableBean {
*/ */
@GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) @GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter connect() { public SseEmitter connect() {
if (!StpUtil.isLogin()) { StpUtil.checkLogin();
return null;
}
String tokenValue = StpUtil.getTokenValue(); String tokenValue = StpUtil.getTokenValue();
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
return sseEmitterManager.connect(userId, tokenValue); return sseEmitterManager.connect(userId, tokenValue);
@@ -50,32 +51,31 @@ public class SseController implements DisposableBean {
return R.ok(); return R.ok();
} }
// 以下为demo仅供参考 禁止使用 请在业务逻辑中使用工具发送而不是用接口发送 /**
// /** * 向特定用户发送消息
// * 向特定用户发送消息 *
// * * @param userId 目标用户的 ID
// * @param userId 目标用户的 ID * @param msg 要发送的消息内容
// * @param msg 要发送的消息内容 */
// */ @GetMapping(value = "${sse.path}/send")
// @GetMapping(value = "${sse.path}/send") public R<Void> send(Long userId, String msg) {
// public R<Void> send(Long userId, String msg) { SseMessageDto dto = new SseMessageDto();
// SseMessageDto dto = new SseMessageDto(); dto.setUserIds(List.of(userId));
// dto.setUserIds(List.of(userId)); dto.setMessage(msg);
// dto.setMessage(msg); sseEmitterManager.publishMessage(dto);
// sseEmitterManager.publishMessage(dto); return R.ok();
// return R.ok(); }
// }
// /**
// /** * 向所有用户发送消息
// * 向所有用户发送消息 *
// * * @param msg 要发送的消息内容
// * @param msg 要发送的消息内容 */
// */ @GetMapping(value = "${sse.path}/sendAll")
// @GetMapping(value = "${sse.path}/sendAll") public R<Void> send(String msg) {
// public R<Void> send(String msg) { sseEmitterManager.publishAll(msg);
// sseEmitterManager.publishAll(msg); return R.ok();
// return R.ok(); }
// }
/** /**
* 清理资源。此方法目前不执行任何操作,但避免因未实现而导致错误 * 清理资源。此方法目前不执行任何操作,但避免因未实现而导致错误

View File

@@ -38,8 +38,8 @@ public class SseEmitterManager {
// 每个用户可以有多个 SSE 连接,通过 token 进行区分 // 每个用户可以有多个 SSE 连接,通过 token 进行区分
Map<String, SseEmitter> emitters = USER_TOKEN_EMITTERS.computeIfAbsent(userId, k -> new ConcurrentHashMap<>()); Map<String, SseEmitter> emitters = USER_TOKEN_EMITTERS.computeIfAbsent(userId, k -> new ConcurrentHashMap<>());
// 创建一个新的 SseEmitter 实例,超时时间设置为一天 避免连接之后直接关闭浏览器导致连接停滞 // 创建一个新的 SseEmitter 实例,超时时间设置为 0 表示无限制
SseEmitter emitter = new SseEmitter(86400000L); SseEmitter emitter = new SseEmitter(0L);
emitters.put(token, emitter); emitters.put(token, emitter);

View File

@@ -48,7 +48,7 @@ public class PlusTenantLineHandler implements TenantLineHandler {
"gen_table_column" "gen_table_column"
); );
tables.addAll(excludes); tables.addAll(excludes);
return StringUtils.equalsAnyIgnoreCase(tableName, tables.toArray(new String[0])); return StringUtils.containsAnyIgnoreCase(tableName, tables.toArray(new String[0]));
} }
return true; return true;
} }

View File

@@ -1,12 +1,9 @@
package org.dromara.common.web.config; package org.dromara.common.web.config;
import cn.hutool.core.date.DateUtil;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.web.handler.GlobalExceptionHandler; import org.dromara.common.web.handler.GlobalExceptionHandler;
import org.dromara.common.web.interceptor.PlusWebInvokeTimeInterceptor; import org.dromara.common.web.interceptor.PlusWebInvokeTimeInterceptor;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
@@ -14,8 +11,6 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Date;
/** /**
* 通用配置 * 通用配置
* *
@@ -30,17 +25,6 @@ public class ResourcesConfig implements WebMvcConfigurer {
registry.addInterceptor(new PlusWebInvokeTimeInterceptor()); registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
} }
@Override
public void addFormatters(FormatterRegistry registry) {
// 全局日期格式转换配置
registry.addConverter(String.class, Date.class, source -> {
if (StringUtils.isBlank(source)) {
return null;
}
return DateUtil.parse(source);
});
}
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
} }

View File

@@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ # 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds #FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
#FROM findepi/graalvm:java17-native #FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li" LABEL maintainer="Lion Li"

View File

@@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/ # 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds #FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
#FROM findepi/graalvm:java17-native #FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li" LABEL maintainer="Lion Li"
@@ -9,7 +9,7 @@ RUN mkdir -p /ruoyi/snailjob/logs
WORKDIR /ruoyi/snailjob WORKDIR /ruoyi/snailjob
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="-Xms512m -Xmx1024m"
EXPOSE 8800 EXPOSE 8800
EXPOSE 17888 EXPOSE 17888

View File

@@ -1,5 +1,6 @@
package org.dromara.demo.controller; package org.dromara.demo.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.mail.utils.MailUtils; import org.dromara.common.mail.utils.MailUtils;
@@ -17,11 +18,12 @@ import java.util.Arrays;
* *
* @author Michelle.Chung * @author Michelle.Chung
*/ */
@SaIgnore
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/demo/mail") @RequestMapping("/demo/mail")
public class MailSendController { public class MailController {
/** /**
* 发送邮件 * 发送邮件
@@ -42,11 +44,11 @@ public class MailSendController {
* @param to 接收人 * @param to 接收人
* @param subject 标题 * @param subject 标题
* @param text 内容 * @param text 内容
* @param filePath 附件路径
*/ */
@GetMapping("/sendMessageWithAttachment") @GetMapping("/sendMessageWithAttachment")
public R<Void> sendMessageWithAttachment(String to, String subject, String text) { public R<Void> sendMessageWithAttachment(String to, String subject, String text, String filePath) {
// 附件路径 禁止前端传递 有任意读取系统文件风险 MailUtils.sendText(to, subject, text, new File(filePath));
MailUtils.sendText(to, subject, text, new File("/xxx/xxx"));
return R.ok(); return R.ok();
} }
@@ -56,11 +58,10 @@ public class MailSendController {
* @param to 接收人 * @param to 接收人
* @param subject 标题 * @param subject 标题
* @param text 内容 * @param text 内容
* @param paths 附件路径
*/ */
@GetMapping("/sendMessageWithAttachments") @GetMapping("/sendMessageWithAttachments")
public R<Void> sendMessageWithAttachments(String to, String subject, String text) { public R<Void> sendMessageWithAttachments(String to, String subject, String text, String[] paths) {
// 附件路径 禁止前端传递 有任意读取系统文件风险
String[] paths = new String[]{"/xxx/xxx", "/xxx/xxx"};
File[] array = Arrays.stream(paths).map(File::new).toArray(File[]::new); File[] array = Arrays.stream(paths).map(File::new).toArray(File[]::new);
MailUtils.sendText(to, subject, text, array); MailUtils.sendText(to, subject, text, array);
return R.ok(); return R.ok();

View File

@@ -1,9 +1,11 @@
package org.dromara.demo.controller.queue; package org.dromara.demo.controller.queue;
import lombok.RequiredArgsConstructor; import cn.dev33.satoken.annotation.SaIgnore;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.redis.utils.QueueUtils; import org.dromara.common.redis.utils.QueueUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBoundedBlockingQueue;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -18,9 +20,7 @@ import org.springframework.web.bind.annotation.RestController;
* *
* @author Lion Li * @author Lion Li
* @version 3.6.0 * @version 3.6.0
* @deprecated redisson 新版本已经将队列功能标记删除 一些技术问题无法解决 建议搭建MQ使用
*/ */
@Deprecated
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController

View File

@@ -1,5 +1,6 @@
package org.dromara.demo.controller.queue; package org.dromara.demo.controller.queue;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
@@ -22,9 +23,8 @@ import java.util.concurrent.TimeUnit;
* *
* @author Lion Li * @author Lion Li
* @version 3.6.0 * @version 3.6.0
* @deprecated redisson 新版本已经将队列功能标记删除 一些技术问题无法解决 建议搭建MQ使用
*/ */
@Deprecated @SaIgnore
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController

View File

@@ -8,9 +8,7 @@ import lombok.NoArgsConstructor;
* *
* @author Lion Li * @author Lion Li
* @version 3.6.0 * @version 3.6.0
* @deprecated redisson 新版本已经将队列功能标记删除 一些技术问题无法解决 建议搭建MQ使用
*/ */
@Deprecated
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class PriorityDemo implements Comparable<PriorityDemo> { public class PriorityDemo implements Comparable<PriorityDemo> {

View File

@@ -19,9 +19,7 @@ import org.springframework.web.bind.annotation.RestController;
* *
* @author Lion Li * @author Lion Li
* @version 3.6.0 * @version 3.6.0
* @deprecated redisson 新版本已经将队列功能标记删除 一些技术问题无法解决 建议搭建MQ使用
*/ */
@Deprecated
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController

View File

@@ -59,9 +59,4 @@ public class TestDemoBo extends BaseEntity {
@NotBlank(message = "值不能为空", groups = {AddGroup.class, EditGroup.class}) @NotBlank(message = "值不能为空", groups = {AddGroup.class, EditGroup.class})
private String value; private String value;
/**
* 版本
*/
private Long version;
} }

View File

@@ -2,7 +2,6 @@ package org.dromara.demo.domain.vo;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.format.DateTimeFormat;
import org.dromara.common.excel.annotation.ExcelNotation; import org.dromara.common.excel.annotation.ExcelNotation;
import org.dromara.common.excel.annotation.ExcelRequired; import org.dromara.common.excel.annotation.ExcelRequired;
import org.dromara.common.translation.annotation.Translation; import org.dromara.common.translation.annotation.Translation;
@@ -47,7 +46,7 @@ public class TestDemoVo implements Serializable {
* 用户id * 用户id
*/ */
@ExcelRequired @ExcelRequired
@ExcelProperty(value = "用户id", index = 5) @ExcelProperty(value = "用户id")
private Long userId; private Long userId;
/** /**
@@ -74,8 +73,6 @@ public class TestDemoVo implements Serializable {
/** /**
* 创建时间 * 创建时间
*/ */
@ExcelRequired
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "创建时间") @ExcelProperty(value = "创建时间")
private Date createTime; private Date createTime;
@@ -111,9 +108,4 @@ public class TestDemoVo implements Serializable {
@ExcelProperty(value = "更新人账号") @ExcelProperty(value = "更新人账号")
private String updateByName; private String updateByName;
/**
* 版本
*/
private Long version;
} }

View File

@@ -42,11 +42,6 @@
<artifactId>ruoyi-common-log</artifactId> <artifactId>ruoyi-common-log</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-idempotent</artifactId>
</dependency>
<!--velocity代码生成使用模板 --> <!--velocity代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>

View File

@@ -3,23 +3,21 @@ package org.dromara.generator.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import com.baomidou.lock.annotation.Lock4j;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.helper.DataBaseHelper; import org.dromara.common.mybatis.helper.DataBaseHelper;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.generator.domain.GenTable; import org.dromara.generator.domain.GenTable;
import org.dromara.generator.domain.GenTableColumn; import org.dromara.generator.domain.GenTableColumn;
import org.dromara.generator.service.IGenTableService; import org.dromara.generator.service.IGenTableService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -52,7 +50,6 @@ public class GenController extends BaseController {
* *
* @param tableId 表ID * @param tableId 表ID
*/ */
@RepeatSubmit()
@SaCheckPermission("tool:gen:query") @SaCheckPermission("tool:gen:query")
@GetMapping(value = "/{tableId}") @GetMapping(value = "/{tableId}")
public R<Map<String, Object>> getInfo(@PathVariable Long tableId) { public R<Map<String, Object>> getInfo(@PathVariable Long tableId) {
@@ -83,8 +80,11 @@ public class GenController extends BaseController {
@SaCheckPermission("tool:gen:list") @SaCheckPermission("tool:gen:list")
@GetMapping(value = "/column/{tableId}") @GetMapping(value = "/column/{tableId}")
public TableDataInfo<GenTableColumn> columnList(@PathVariable("tableId") Long tableId) { public TableDataInfo<GenTableColumn> columnList(@PathVariable("tableId") Long tableId) {
TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>();
List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId); List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
return TableDataInfo.build(list); dataInfo.setRows(list);
dataInfo.setTotal(list.size());
return dataInfo;
} }
/** /**
@@ -94,7 +94,6 @@ public class GenController extends BaseController {
*/ */
@SaCheckPermission("tool:gen:import") @SaCheckPermission("tool:gen:import")
@Log(title = "代码生成", businessType = BusinessType.IMPORT) @Log(title = "代码生成", businessType = BusinessType.IMPORT)
@RepeatSubmit()
@PostMapping("/importTable") @PostMapping("/importTable")
public R<Void> importTableSave(String tables, String dataName) { public R<Void> importTableSave(String tables, String dataName) {
String[] tableNames = Convert.toStrArray(tables); String[] tableNames = Convert.toStrArray(tables);
@@ -109,7 +108,6 @@ public class GenController extends BaseController {
*/ */
@SaCheckPermission("tool:gen:edit") @SaCheckPermission("tool:gen:edit")
@Log(title = "代码生成", businessType = BusinessType.UPDATE) @Log(title = "代码生成", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> editSave(@Validated @RequestBody GenTable genTable) { public R<Void> editSave(@Validated @RequestBody GenTable genTable) {
genTableService.validateEdit(genTable); genTableService.validateEdit(genTable);
@@ -175,7 +173,6 @@ public class GenController extends BaseController {
*/ */
@SaCheckPermission("tool:gen:edit") @SaCheckPermission("tool:gen:edit")
@Log(title = "代码生成", businessType = BusinessType.UPDATE) @Log(title = "代码生成", businessType = BusinessType.UPDATE)
@Lock4j
@GetMapping("/synchDb/{tableId}") @GetMapping("/synchDb/{tableId}")
public R<Void> synchDb(@PathVariable("tableId") Long tableId) { public R<Void> synchDb(@PathVariable("tableId") Long tableId) {
genTableService.synchDb(tableId); genTableService.synchDb(tableId);

View File

@@ -297,13 +297,13 @@ public class GenTableServiceImpl implements IGenTableService {
List<GenTableColumn> tableColumns = new ArrayList<>(); List<GenTableColumn> tableColumns = new ArrayList<>();
columns.forEach((columnName, column) -> { columns.forEach((columnName, column) -> {
GenTableColumn tableColumn = new GenTableColumn(); GenTableColumn tableColumn = new GenTableColumn();
tableColumn.setIsPk(column.isPrimaryKey() ? "1" : "0"); tableColumn.setIsPk(String.valueOf(column.isPrimaryKey()));
tableColumn.setColumnName(column.getName()); tableColumn.setColumnName(column.getName());
tableColumn.setColumnComment(column.getComment()); tableColumn.setColumnComment(column.getComment());
tableColumn.setColumnType(column.getOriginType().toLowerCase()); tableColumn.setColumnType(column.getOriginType().toLowerCase());
tableColumn.setSort(column.getPosition()); tableColumn.setSort(column.getPosition());
tableColumn.setIsRequired(column.isNullable() ? "1" : "0"); tableColumn.setIsRequired(column.isNullable() == 0 ? "1" : "0");
tableColumn.setIsIncrement(column.isAutoIncrement() ? "1" : "0"); tableColumn.setIsIncrement(column.isAutoIncrement() == -1 ? "0" : "1");
tableColumns.add(tableColumn); tableColumns.add(tableColumn);
}); });
return tableColumns; return tableColumns;

View File

@@ -6,7 +6,6 @@ import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.redisson.spring.data.connection.RedissonConnectionFactory; import org.redisson.spring.data.connection.RedissonConnectionFactory;
import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -32,9 +31,9 @@ public class CacheController {
@GetMapping() @GetMapping()
public R<CacheListInfoVo> getInfo() throws Exception { public R<CacheListInfoVo> getInfo() throws Exception {
RedisConnection connection = connectionFactory.getConnection(); RedisConnection connection = connectionFactory.getConnection();
try { Properties commandStats = connection.commands().info("commandstats");
Properties commandStats = connection.commands().info("commandstats");
List<Map<String, String>> pieList = new ArrayList<>(); List<Map<String, String>> pieList = new ArrayList<>();
if (commandStats != null) { if (commandStats != null) {
commandStats.stringPropertyNames().forEach(key -> { commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2); Map<String, String> data = new HashMap<>(2);
@@ -44,13 +43,10 @@ public class CacheController {
pieList.add(data); pieList.add(data);
}); });
} }
return R.ok(new CacheListInfoVo( return R.ok(new CacheListInfoVo(
connection.commands().info(), connection.commands().info(),
connection.commands().dbSize(), pieList)); connection.commands().dbSize(), pieList));
} finally {
// 归还连接给连接池
RedisConnectionUtils.releaseConnection(connection, connectionFactory);
}
} }
public record CacheListInfoVo(Properties info, Long dbSize, List<Map<String, String>> commandStats) {} public record CacheListInfoVo(Properties info, Long dbSize, List<Map<String, String>> commandStats) {}

View File

@@ -1,13 +1,11 @@
package org.dromara.system.controller.monitor; package org.dromara.system.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.lock.annotation.Lock4j;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -71,7 +69,6 @@ public class SysLogininforController extends BaseController {
*/ */
@SaCheckPermission("monitor:logininfor:remove") @SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.CLEAN) @Log(title = "登录日志", businessType = BusinessType.CLEAN)
@Lock4j
@DeleteMapping("/clean") @DeleteMapping("/clean")
public R<Void> clean() { public R<Void> clean() {
logininforService.cleanLogininfor(); logininforService.cleanLogininfor();
@@ -80,7 +77,6 @@ public class SysLogininforController extends BaseController {
@SaCheckPermission("monitor:logininfor:unlock") @SaCheckPermission("monitor:logininfor:unlock")
@Log(title = "账户解锁", businessType = BusinessType.OTHER) @Log(title = "账户解锁", businessType = BusinessType.OTHER)
@RepeatSubmit()
@GetMapping("/unlock/{userName}") @GetMapping("/unlock/{userName}")
public R<Void> unlock(@PathVariable("userName") String userName) { public R<Void> unlock(@PathVariable("userName") String userName) {
String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName;

View File

@@ -1,22 +1,21 @@
package org.dromara.system.controller.monitor; package org.dromara.system.controller.monitor;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.lock.annotation.Lock4j;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.system.domain.bo.SysOperLogBo; import org.dromara.system.domain.bo.SysOperLogBo;
import org.dromara.system.domain.vo.SysOperLogVo; import org.dromara.system.domain.vo.SysOperLogVo;
import org.dromara.system.service.ISysOperLogService; import org.dromara.system.service.ISysOperLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
/** /**
@@ -68,7 +67,6 @@ public class SysOperlogController extends BaseController {
*/ */
@Log(title = "操作日志", businessType = BusinessType.CLEAN) @Log(title = "操作日志", businessType = BusinessType.CLEAN)
@SaCheckPermission("monitor:operlog:remove") @SaCheckPermission("monitor:operlog:remove")
@Lock4j
@DeleteMapping("/clean") @DeleteMapping("/clean")
public R<Void> clean() { public R<Void> clean() {
operLogService.cleanOperLog(); operLogService.cleanOperLog();

View File

@@ -10,7 +10,6 @@ import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.dto.UserOnlineDTO; import org.dromara.common.core.domain.dto.UserOnlineDTO;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -82,7 +81,6 @@ public class SysUserOnlineController extends BaseController {
*/ */
@SaCheckPermission("monitor:online:forceLogout") @SaCheckPermission("monitor:online:forceLogout")
@Log(title = "在线用户", businessType = BusinessType.FORCE) @Log(title = "在线用户", businessType = BusinessType.FORCE)
@RepeatSubmit()
@DeleteMapping("/{tokenId}") @DeleteMapping("/{tokenId}")
public R<Void> forceLogout(@PathVariable String tokenId) { public R<Void> forceLogout(@PathVariable String tokenId) {
try { try {
@@ -116,7 +114,6 @@ public class SysUserOnlineController extends BaseController {
* @param tokenId token值 * @param tokenId token值
*/ */
@Log(title = "在线设备", businessType = BusinessType.FORCE) @Log(title = "在线设备", businessType = BusinessType.FORCE)
@RepeatSubmit()
@DeleteMapping("/myself/{tokenId}") @DeleteMapping("/myself/{tokenId}")
public R<Void> remove(@PathVariable("tokenId") String tokenId) { public R<Void> remove(@PathVariable("tokenId") String tokenId) {
try { try {

View File

@@ -1,11 +1,8 @@
package org.dromara.system.controller.system; package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -14,10 +11,11 @@ import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.bo.SysConfigBo; import org.dromara.system.domain.bo.SysConfigBo;
import org.dromara.system.domain.vo.SysConfigVo; import org.dromara.system.domain.vo.SysConfigVo;
import org.dromara.system.service.ISysConfigService; import org.dromara.system.service.ISysConfigService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -79,7 +77,6 @@ public class SysConfigController extends BaseController {
*/ */
@SaCheckPermission("system:config:add") @SaCheckPermission("system:config:add")
@Log(title = "参数管理", businessType = BusinessType.INSERT) @Log(title = "参数管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysConfigBo config) { public R<Void> add(@Validated @RequestBody SysConfigBo config) {
if (!configService.checkConfigKeyUnique(config)) { if (!configService.checkConfigKeyUnique(config)) {
@@ -94,7 +91,6 @@ public class SysConfigController extends BaseController {
*/ */
@SaCheckPermission("system:config:edit") @SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE) @Log(title = "参数管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysConfigBo config) { public R<Void> edit(@Validated @RequestBody SysConfigBo config) {
if (!configService.checkConfigKeyUnique(config)) { if (!configService.checkConfigKeyUnique(config)) {
@@ -109,7 +105,6 @@ public class SysConfigController extends BaseController {
*/ */
@SaCheckPermission("system:config:edit") @SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE) @Log(title = "参数管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/updateByKey") @PutMapping("/updateByKey")
public R<Void> updateByKey(@RequestBody SysConfigBo config) { public R<Void> updateByKey(@RequestBody SysConfigBo config) {
configService.updateConfig(config); configService.updateConfig(config);
@@ -125,7 +120,7 @@ public class SysConfigController extends BaseController {
@Log(title = "参数管理", businessType = BusinessType.DELETE) @Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}") @DeleteMapping("/{configIds}")
public R<Void> remove(@PathVariable Long[] configIds) { public R<Void> remove(@PathVariable Long[] configIds) {
configService.deleteConfigByIds(Arrays.asList(configIds)); configService.deleteConfigByIds(configIds);
return R.ok(); return R.ok();
} }

View File

@@ -6,7 +6,6 @@ import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
@@ -74,7 +73,6 @@ public class SysDeptController extends BaseController {
*/ */
@SaCheckPermission("system:dept:add") @SaCheckPermission("system:dept:add")
@Log(title = "部门管理", businessType = BusinessType.INSERT) @Log(title = "部门管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysDeptBo dept) { public R<Void> add(@Validated @RequestBody SysDeptBo dept) {
if (!deptService.checkDeptNameUnique(dept)) { if (!deptService.checkDeptNameUnique(dept)) {
@@ -88,7 +86,6 @@ public class SysDeptController extends BaseController {
*/ */
@SaCheckPermission("system:dept:edit") @SaCheckPermission("system:dept:edit")
@Log(title = "部门管理", businessType = BusinessType.UPDATE) @Log(title = "部门管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysDeptBo dept) { public R<Void> edit(@Validated @RequestBody SysDeptBo dept) {
Long deptId = dept.getDeptId(); Long deptId = dept.getDeptId();
@@ -116,9 +113,6 @@ public class SysDeptController extends BaseController {
@Log(title = "部门管理", businessType = BusinessType.DELETE) @Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}") @DeleteMapping("/{deptId}")
public R<Void> remove(@PathVariable Long deptId) { public R<Void> remove(@PathVariable Long deptId) {
if (SystemConstants.DEFAULT_DEPT_ID.equals(deptId)) {
return R.warn("默认部门,不允许删除");
}
if (deptService.hasChildByDeptId(deptId)) { if (deptService.hasChildByDeptId(deptId)) {
return R.warn("存在下级部门,不允许删除"); return R.warn("存在下级部门,不允许删除");
} }

View File

@@ -2,25 +2,23 @@ package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.system.domain.bo.SysDictDataBo; import org.dromara.system.domain.bo.SysDictDataBo;
import org.dromara.system.domain.vo.SysDictDataVo; import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.service.ISysDictDataService; import org.dromara.system.service.ISysDictDataService;
import org.dromara.system.service.ISysDictTypeService; import org.dromara.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -87,7 +85,6 @@ public class SysDictDataController extends BaseController {
*/ */
@SaCheckPermission("system:dict:add") @SaCheckPermission("system:dict:add")
@Log(title = "字典数据", businessType = BusinessType.INSERT) @Log(title = "字典数据", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysDictDataBo dict) { public R<Void> add(@Validated @RequestBody SysDictDataBo dict) {
if (!dictDataService.checkDictDataUnique(dict)) { if (!dictDataService.checkDictDataUnique(dict)) {
@@ -102,7 +99,6 @@ public class SysDictDataController extends BaseController {
*/ */
@SaCheckPermission("system:dict:edit") @SaCheckPermission("system:dict:edit")
@Log(title = "字典数据", businessType = BusinessType.UPDATE) @Log(title = "字典数据", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysDictDataBo dict) { public R<Void> edit(@Validated @RequestBody SysDictDataBo dict) {
if (!dictDataService.checkDictDataUnique(dict)) { if (!dictDataService.checkDictDataUnique(dict)) {
@@ -121,7 +117,7 @@ public class SysDictDataController extends BaseController {
@Log(title = "字典类型", businessType = BusinessType.DELETE) @Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}") @DeleteMapping("/{dictCodes}")
public R<Void> remove(@PathVariable Long[] dictCodes) { public R<Void> remove(@PathVariable Long[] dictCodes) {
dictDataService.deleteDictDataByIds(Arrays.asList(dictCodes)); dictDataService.deleteDictDataByIds(dictCodes);
return R.ok(); return R.ok();
} }
} }

View File

@@ -1,12 +1,8 @@
package org.dromara.system.controller.system; package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.lock.annotation.Lock4j;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -15,10 +11,11 @@ import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.bo.SysDictTypeBo; import org.dromara.system.domain.bo.SysDictTypeBo;
import org.dromara.system.domain.vo.SysDictTypeVo; import org.dromara.system.domain.vo.SysDictTypeVo;
import org.dromara.system.service.ISysDictTypeService; import org.dromara.system.service.ISysDictTypeService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -70,7 +67,6 @@ public class SysDictTypeController extends BaseController {
*/ */
@SaCheckPermission("system:dict:add") @SaCheckPermission("system:dict:add")
@Log(title = "字典类型", businessType = BusinessType.INSERT) @Log(title = "字典类型", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysDictTypeBo dict) { public R<Void> add(@Validated @RequestBody SysDictTypeBo dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) { if (!dictTypeService.checkDictTypeUnique(dict)) {
@@ -85,7 +81,6 @@ public class SysDictTypeController extends BaseController {
*/ */
@SaCheckPermission("system:dict:edit") @SaCheckPermission("system:dict:edit")
@Log(title = "字典类型", businessType = BusinessType.UPDATE) @Log(title = "字典类型", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysDictTypeBo dict) { public R<Void> edit(@Validated @RequestBody SysDictTypeBo dict) {
if (!dictTypeService.checkDictTypeUnique(dict)) { if (!dictTypeService.checkDictTypeUnique(dict)) {
@@ -104,7 +99,7 @@ public class SysDictTypeController extends BaseController {
@Log(title = "字典类型", businessType = BusinessType.DELETE) @Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}") @DeleteMapping("/{dictIds}")
public R<Void> remove(@PathVariable Long[] dictIds) { public R<Void> remove(@PathVariable Long[] dictIds) {
dictTypeService.deleteDictTypeByIds(Arrays.asList(dictIds)); dictTypeService.deleteDictTypeByIds(dictIds);
return R.ok(); return R.ok();
} }
@@ -113,7 +108,6 @@ public class SysDictTypeController extends BaseController {
*/ */
@SaCheckPermission("system:dict:remove") @SaCheckPermission("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN) @Log(title = "字典类型", businessType = BusinessType.CLEAN)
@Lock4j
@DeleteMapping("/refreshCache") @DeleteMapping("/refreshCache")
public R<Void> refreshCache() { public R<Void> refreshCache() {
dictTypeService.resetDictCache(); dictTypeService.resetDictCache();

View File

@@ -9,7 +9,6 @@ import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
@@ -22,7 +21,6 @@ import org.dromara.system.service.ISysMenuService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -113,14 +111,9 @@ public class SysMenuController extends BaseController {
@GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}") @GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) { public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId()); List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
List<Tree<Long>> list = menuService.buildMenuTreeSelect(menus); MenuTreeSelectVo selectVo = new MenuTreeSelectVo(
// 删除租户管理菜单 menuService.selectMenuListByPackageId(packageId),
list.removeIf(menu -> menu.getId() == 6L); menuService.buildMenuTreeSelect(menus));
List<Long> ids = new ArrayList<>();
if (packageId > 0L) {
ids = menuService.selectMenuListByPackageId(packageId);
}
MenuTreeSelectVo selectVo = new MenuTreeSelectVo(ids, list);
return R.ok(selectVo); return R.ok(selectVo);
} }
@@ -130,7 +123,6 @@ public class SysMenuController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:add") @SaCheckPermission("system:menu:add")
@Log(title = "菜单管理", businessType = BusinessType.INSERT) @Log(title = "菜单管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysMenuBo menu) { public R<Void> add(@Validated @RequestBody SysMenuBo menu) {
if (!menuService.checkMenuNameUnique(menu)) { if (!menuService.checkMenuNameUnique(menu)) {
@@ -147,7 +139,6 @@ public class SysMenuController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:edit") @SaCheckPermission("system:menu:edit")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE) @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysMenuBo menu) { public R<Void> edit(@Validated @RequestBody SysMenuBo menu) {
if (!menuService.checkMenuNameUnique(menu)) { if (!menuService.checkMenuNameUnique(menu)) {

View File

@@ -4,7 +4,6 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.service.DictService; import org.dromara.common.core.service.DictService;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -56,7 +55,6 @@ public class SysNoticeController extends BaseController {
*/ */
@SaCheckPermission("system:notice:add") @SaCheckPermission("system:notice:add")
@Log(title = "通知公告", businessType = BusinessType.INSERT) @Log(title = "通知公告", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysNoticeBo notice) { public R<Void> add(@Validated @RequestBody SysNoticeBo notice) {
int rows = noticeService.insertNotice(notice); int rows = noticeService.insertNotice(notice);
@@ -73,7 +71,6 @@ public class SysNoticeController extends BaseController {
*/ */
@SaCheckPermission("system:notice:edit") @SaCheckPermission("system:notice:edit")
@Log(title = "通知公告", businessType = BusinessType.UPDATE) @Log(title = "通知公告", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysNoticeBo notice) { public R<Void> edit(@Validated @RequestBody SysNoticeBo notice) {
return toAjax(noticeService.updateNotice(notice)); return toAjax(noticeService.updateNotice(notice));

View File

@@ -98,7 +98,6 @@ public class SysOssConfigController extends BaseController {
*/ */
@SaCheckPermission("system:ossConfig:edit") @SaCheckPermission("system:ossConfig:edit")
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE) @Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/changeStatus") @PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) { public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
return toAjax(ossConfigService.updateOssConfigStatus(bo)); return toAjax(ossConfigService.updateOssConfigStatus(bo));

View File

@@ -7,7 +7,6 @@ import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -20,7 +19,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -72,7 +70,6 @@ public class SysPostController extends BaseController {
*/ */
@SaCheckPermission("system:post:add") @SaCheckPermission("system:post:add")
@Log(title = "岗位管理", businessType = BusinessType.INSERT) @Log(title = "岗位管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysPostBo post) { public R<Void> add(@Validated @RequestBody SysPostBo post) {
if (!postService.checkPostNameUnique(post)) { if (!postService.checkPostNameUnique(post)) {
@@ -88,7 +85,6 @@ public class SysPostController extends BaseController {
*/ */
@SaCheckPermission("system:post:edit") @SaCheckPermission("system:post:edit")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE) @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysPostBo post) { public R<Void> edit(@Validated @RequestBody SysPostBo post) {
if (!postService.checkPostNameUnique(post)) { if (!postService.checkPostNameUnique(post)) {
@@ -111,7 +107,7 @@ public class SysPostController extends BaseController {
@Log(title = "岗位管理", businessType = BusinessType.DELETE) @Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}") @DeleteMapping("/{postIds}")
public R<Void> remove(@PathVariable Long[] postIds) { public R<Void> remove(@PathVariable Long[] postIds) {
return toAjax(postService.deletePostByIds(Arrays.asList(postIds))); return toAjax(postService.deletePostByIds(postIds));
} }
/** /**

View File

@@ -6,7 +6,6 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -78,7 +77,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:add") @SaCheckPermission("system:role:add")
@Log(title = "角色管理", businessType = BusinessType.INSERT) @Log(title = "角色管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysRoleBo role) { public R<Void> add(@Validated @RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role); roleService.checkRoleAllowed(role);
@@ -96,7 +94,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:edit") @SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE) @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysRoleBo role) { public R<Void> edit(@Validated @RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role); roleService.checkRoleAllowed(role);
@@ -119,7 +116,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:edit") @SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE) @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/dataScope") @PutMapping("/dataScope")
public R<Void> dataScope(@RequestBody SysRoleBo role) { public R<Void> dataScope(@RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role); roleService.checkRoleAllowed(role);
@@ -132,7 +128,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:edit") @SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE) @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/changeStatus") @PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysRoleBo role) { public R<Void> changeStatus(@RequestBody SysRoleBo role) {
roleService.checkRoleAllowed(role); roleService.checkRoleAllowed(role);
@@ -149,7 +144,7 @@ public class SysRoleController extends BaseController {
@Log(title = "角色管理", businessType = BusinessType.DELETE) @Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}") @DeleteMapping("/{roleIds}")
public R<Void> remove(@PathVariable Long[] roleIds) { public R<Void> remove(@PathVariable Long[] roleIds) {
return toAjax(roleService.deleteRoleByIds(List.of(roleIds))); return toAjax(roleService.deleteRoleByIds(roleIds));
} }
/** /**
@@ -186,7 +181,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:edit") @SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT) @Log(title = "角色管理", businessType = BusinessType.GRANT)
@RepeatSubmit()
@PutMapping("/authUser/cancel") @PutMapping("/authUser/cancel")
public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) { public R<Void> cancelAuthUser(@RequestBody SysUserRole userRole) {
return toAjax(roleService.deleteAuthUser(userRole)); return toAjax(roleService.deleteAuthUser(userRole));
@@ -200,7 +194,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:edit") @SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT) @Log(title = "角色管理", businessType = BusinessType.GRANT)
@RepeatSubmit()
@PutMapping("/authUser/cancelAll") @PutMapping("/authUser/cancelAll")
public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) { public R<Void> cancelAuthUserAll(Long roleId, Long[] userIds) {
return toAjax(roleService.deleteAuthUsers(roleId, userIds)); return toAjax(roleService.deleteAuthUsers(roleId, userIds));
@@ -214,7 +207,6 @@ public class SysRoleController extends BaseController {
*/ */
@SaCheckPermission("system:role:edit") @SaCheckPermission("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT) @Log(title = "角色管理", businessType = BusinessType.GRANT)
@RepeatSubmit()
@PutMapping("/authUser/selectAll") @PutMapping("/authUser/selectAll")
public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) { public R<Void> selectAuthUserAll(Long roleId, Long[] userIds) {
roleService.checkRoleDataScope(roleId); roleService.checkRoleDataScope(roleId);

View File

@@ -118,7 +118,6 @@ public class SysTenantController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:edit") @SaCheckPermission("system:tenant:edit")
@Log(title = "租户管理", businessType = BusinessType.UPDATE) @Log(title = "租户管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/changeStatus") @PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysTenantBo bo) { public R<Void> changeStatus(@RequestBody SysTenantBo bo) {
tenantService.checkTenantAllowed(bo.getTenantId()); tenantService.checkTenantAllowed(bo.getTenantId());
@@ -171,7 +170,6 @@ public class SysTenantController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenant:edit") @SaCheckPermission("system:tenant:edit")
@Log(title = "租户管理", businessType = BusinessType.UPDATE) @Log(title = "租户管理", businessType = BusinessType.UPDATE)
@Lock4j
@GetMapping("/syncTenantPackage") @GetMapping("/syncTenantPackage")
public R<Void> syncTenantPackage(@NotBlank(message = "租户ID不能为空") String tenantId, public R<Void> syncTenantPackage(@NotBlank(message = "租户ID不能为空") String tenantId,
@NotNull(message = "套餐ID不能为空") Long packageId) { @NotNull(message = "套餐ID不能为空") Long packageId) {
@@ -183,7 +181,6 @@ public class SysTenantController extends BaseController {
*/ */
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@Log(title = "租户管理", businessType = BusinessType.INSERT) @Log(title = "租户管理", businessType = BusinessType.INSERT)
@Lock4j
@GetMapping("/syncTenantDict") @GetMapping("/syncTenantDict")
public R<Void> syncTenantDict() { public R<Void> syncTenantDict() {
if (!TenantHelper.isEnable()) { if (!TenantHelper.isEnable()) {

View File

@@ -121,7 +121,6 @@ public class SysTenantPackageController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:tenantPackage:edit") @SaCheckPermission("system:tenantPackage:edit")
@Log(title = "租户套餐", businessType = BusinessType.UPDATE) @Log(title = "租户套餐", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/changeStatus") @PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysTenantPackageBo bo) { public R<Void> changeStatus(@RequestBody SysTenantPackageBo bo) {
return toAjax(tenantPackageService.updatePackageStatus(bo)); return toAjax(tenantPackageService.updatePackageStatus(bo));

View File

@@ -16,7 +16,6 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.encrypt.annotation.ApiEncrypt; import org.dromara.common.encrypt.annotation.ApiEncrypt;
import org.dromara.common.excel.core.ExcelResult; import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
@@ -155,7 +154,6 @@ public class SysUserController extends BaseController {
*/ */
@SaCheckPermission("system:user:add") @SaCheckPermission("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT) @Log(title = "用户管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping @PostMapping
public R<Void> add(@Validated @RequestBody SysUserBo user) { public R<Void> add(@Validated @RequestBody SysUserBo user) {
deptService.checkDeptDataScope(user.getDeptId()); deptService.checkDeptDataScope(user.getDeptId());
@@ -180,7 +178,6 @@ public class SysUserController extends BaseController {
*/ */
@SaCheckPermission("system:user:edit") @SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping @PutMapping
public R<Void> edit(@Validated @RequestBody SysUserBo user) { public R<Void> edit(@Validated @RequestBody SysUserBo user) {
userService.checkUserAllowed(user.getUserId()); userService.checkUserAllowed(user.getUserId());
@@ -230,7 +227,6 @@ public class SysUserController extends BaseController {
@ApiEncrypt @ApiEncrypt
@SaCheckPermission("system:user:resetPwd") @SaCheckPermission("system:user:resetPwd")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/resetPwd") @PutMapping("/resetPwd")
public R<Void> resetPwd(@RequestBody SysUserBo user) { public R<Void> resetPwd(@RequestBody SysUserBo user) {
userService.checkUserAllowed(user.getUserId()); userService.checkUserAllowed(user.getUserId());
@@ -244,7 +240,6 @@ public class SysUserController extends BaseController {
*/ */
@SaCheckPermission("system:user:edit") @SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/changeStatus") @PutMapping("/changeStatus")
public R<Void> changeStatus(@RequestBody SysUserBo user) { public R<Void> changeStatus(@RequestBody SysUserBo user) {
userService.checkUserAllowed(user.getUserId()); userService.checkUserAllowed(user.getUserId());
@@ -277,7 +272,6 @@ public class SysUserController extends BaseController {
*/ */
@SaCheckPermission("system:user:edit") @SaCheckPermission("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.GRANT) @Log(title = "用户管理", businessType = BusinessType.GRANT)
@RepeatSubmit()
@PutMapping("/authRole") @PutMapping("/authRole")
public R<Void> insertAuthRole(Long userId, Long[] roleIds) { public R<Void> insertAuthRole(Long userId, Long[] roleIds) {
userService.checkUserDataScope(userId); userService.checkUserDataScope(userId);

View File

@@ -1,75 +0,0 @@
package org.dromara.system.domain;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
* 附件扩展字段对象(存储在 SysOss.ext1 的 JSON 字符串中)
*
* @author AprilWind
*/
@Data
public class SysOssExt implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 所属业务类型(如 avatar、report、contract
*/
private String bizType;
/**
* 文件大小(单位:字节)
*/
private Long fileSize;
/**
* 文件类型MIME类型如 image/png
*/
private String contentType;
/**
* 来源标识(如 userUpload、systemImport
*/
private String source;
/**
* 上传 IP 地址,便于审计和追踪
*/
private String uploadIp;
/**
* 附件说明或备注
*/
private String remark;
/**
* 附件标签,如 ["图片", "证件"]
*/
private List<String> tags;
/**
* 业务绑定ID如某业务记录ID
*/
private String refId;
/**
* 绑定业务类型
*/
private String refType;
/**
* 是否为临时文件,用于区分正式或待清理
*/
private Boolean isTemp;
/**
* 文件MD5值可用于去重或校验
*/
private String md5;
}

View File

@@ -1,17 +1,17 @@
package org.dromara.system.domain.bo; package org.dromara.system.domain.bo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup; import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.system.domain.SysTenant; import org.dromara.system.domain.SysTenant;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date; import java.util.Date;
import org.dromara.common.mybatis.core.domain.BaseEntity;
/** /**
* 租户业务对象 sys_tenant * 租户业务对象 sys_tenant
* *
@@ -62,7 +62,6 @@ public class SysTenantBo extends BaseEntity {
* 密码(创建系统用户) * 密码(创建系统用户)
*/ */
@NotBlank(message = "密码不能为空", groups = { AddGroup.class }) @NotBlank(message = "密码不能为空", groups = { AddGroup.class })
// @Pattern(regexp = RegexConstants.PASSWORD, message = "{user.password.format.valid}", groups = { AddGroup.class })
private String password; private String password;
/** /**

View File

@@ -2,8 +2,9 @@ package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.dromara.common.core.utils.StreamUtils; import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.annotation.DataColumn; import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -20,38 +21,6 @@ import java.util.List;
*/ */
public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> { public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
/**
* 构建角色对应的部门 SQL 查询语句
*
* <p>该 SQL 用于查询某个角色关联的所有部门 ID常用于数据权限控制</p>
*
* @param roleId 角色ID
* @return 查询部门ID的 SQL 语句字符串
*/
default String buildDeptByRoleSql(Long roleId) {
return """
select dept_id from sys_role_dept where role_id = %d
""".formatted(roleId);
}
/**
* 构建 SQL 查询用于获取当前角色拥有的部门中所有的父部门ID
*
* <p>
* 该 SQL 用于 deptCheckStrictly 场景下,排除非叶子节点(父节点)用。
* </p>
*
* @param roleId 角色ID
* @return SQL 语句字符串查询角色下部门的所有父部门ID
*/
default String buildParentDeptByRoleSql(Long roleId) {
return """
select parent_id from sys_dept where dept_id in (
select dept_id from sys_role_dept where role_id = %d
)
""".formatted(roleId);
}
/** /**
* 查询部门管理数据 * 查询部门管理数据
* *
@@ -61,23 +30,18 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id") @DataColumn(key = "deptName", value = "dept_id")
}) })
default List<SysDeptVo> selectDeptList(Wrapper<SysDept> queryWrapper) { List<SysDeptVo> selectDeptList(@Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
return this.selectVoList(queryWrapper);
}
/** /**
* 分页查询部门管理数据 * 分页查询部门管理数据
* *
* @param page 分页信息
* @param queryWrapper 查询条件 * @param queryWrapper 查询条件
* @return 部门信息集合 * @return 部门信息集合
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "dept_id"),
}) })
default Page<SysDeptVo> selectPageDeptList(Page<SysDept> page, Wrapper<SysDept> queryWrapper) { Page<SysDeptVo> selectPageDeptList(@Param("page") Page<SysDeptVo> page, @Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
return this.selectVoPage(page, queryWrapper);
}
/** /**
* 统计指定部门ID的部门数量 * 统计指定部门ID的部门数量
@@ -88,9 +52,7 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id") @DataColumn(key = "deptName", value = "dept_id")
}) })
default long countDeptById(Long deptId) { long countDeptById(Long deptId);
return this.selectCount(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptId, deptId));
}
/** /**
* 根据父部门ID查询其所有子部门的列表 * 根据父部门ID查询其所有子部门的列表
@@ -104,19 +66,6 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
.apply(DataBaseHelper.findInSet(parentId, "ancestors"))); .apply(DataBaseHelper.findInSet(parentId, "ancestors")));
} }
/**
* 查询某个部门及其所有子部门ID含自身
*
* @param parentId 父部门ID
* @return 部门ID集合
*/
default List<Long> selectDeptAndChildById(Long parentId) {
List<SysDept> deptList = this.selectListByParentId(parentId);
List<Long> deptIds = StreamUtils.toList(deptList, SysDept::getDeptId);
deptIds.add(parentId);
return deptIds;
}
/** /**
* 根据角色ID查询部门树信息 * 根据角色ID查询部门树信息
* *
@@ -124,16 +73,6 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
* @param deptCheckStrictly 部门树选择项是否关联显示 * @param deptCheckStrictly 部门树选择项是否关联显示
* @return 选中部门列表 * @return 选中部门列表
*/ */
default List<Long> selectDeptListByRoleId(Long roleId, boolean deptCheckStrictly) { List<Long> selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly);
LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
wrapper.select(SysDept::getDeptId)
.inSql(SysDept::getDeptId, this.buildDeptByRoleSql(roleId))
.orderByAsc(SysDept::getParentId)
.orderByAsc(SysDept::getOrderNum);
if (deptCheckStrictly) {
wrapper.notInSql(SysDept::getDeptId, this.buildParentDeptByRoleSql(roleId));
}
return this.selectObjs(wrapper);
}
} }

View File

@@ -1,6 +1,9 @@
package org.dromara.system.mapper; package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.system.domain.SysMenu; import org.dromara.system.domain.SysMenu;
@@ -16,58 +19,12 @@ import java.util.List;
public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> { public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
/** /**
* 构建用户权限菜单 SQL * 根据用户查询系统菜单列表
* *
* <p> * @param queryWrapper 查询条件
* 查询用户所属角色所拥有的菜单权限,用于权限判断、菜单加载等场景 * @return 菜单列表
* </p>
*
* @param userId 用户ID
* @return SQL 字符串,用于 inSql 条件
*/ */
default String buildMenuByUserSql(Long userId) { List<SysMenu> selectMenuListByUserId(@Param(Constants.WRAPPER) Wrapper<SysMenu> queryWrapper);
return """
select menu_id from sys_role_menu where role_id in (
select role_id from sys_user_role where user_id = %d
)
""".formatted(userId);
}
/**
* 构建角色对应的菜单ID SQL 子查询
*
* <p>
* 用于根据角色ID查询其所拥有的菜单权限用于权限标识、菜单显示等场景
* 通常配合 inSql 使用
* </p>
*
* @param roleId 角色ID
* @return 查询菜单ID的 SQL 子查询字符串
*/
default String buildMenuByRoleSql(Long roleId) {
return """
select menu_id from sys_role_menu where role_id = %d
""".formatted(roleId);
}
/**
* 构建角色所关联菜单的父菜单ID查询 SQL
*
* <p>
* 用于配合菜单勾选树结构的 {@code menuCheckStrictly} 模式,过滤掉非叶子节点(父菜单),
* 只返回角色实际勾选的末级菜单
* </p>
*
* @param roleId 角色ID
* @return SQL 语句字符串查询菜单的父菜单ID
*/
default String buildParentMenuByRoleSql(Long roleId) {
return """
select parent_id from sys_menu where menu_id in (
select menu_id from sys_role_menu where role_id = %d
)
""".formatted(roleId);
}
/** /**
* 根据用户ID查询权限 * 根据用户ID查询权限
@@ -75,13 +32,7 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
* @param userId 用户ID * @param userId 用户ID
* @return 权限列表 * @return 权限列表
*/ */
default List<String> selectMenuPermsByUserId(Long userId) { List<String> selectMenuPermsByUserId(Long userId);
return this.selectObjs(
new LambdaQueryWrapper<SysMenu>()
.select(SysMenu::getPerms)
.inSql(SysMenu::getMenuId, this.buildMenuByUserSql(userId))
);
}
/** /**
* 根据角色ID查询权限 * 根据角色ID查询权限
@@ -89,13 +40,7 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
* @param roleId 角色ID * @param roleId 角色ID
* @return 权限列表 * @return 权限列表
*/ */
default List<String> selectMenuPermsByRoleId(Long roleId) { List<String> selectMenuPermsByRoleId(Long roleId);
return this.selectObjs(
new LambdaQueryWrapper<SysMenu>()
.select(SysMenu::getPerms)
.inSql(SysMenu::getMenuId, this.buildMenuByRoleSql(roleId))
);
}
/** /**
* 根据用户ID查询菜单 * 根据用户ID查询菜单
@@ -111,6 +56,14 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
return this.selectList(lqw); return this.selectList(lqw);
} }
/**
* 根据用户ID查询菜单
*
* @param userId 用户ID
* @return 菜单列表
*/
List<SysMenu> selectMenuTreeByUserId(Long userId);
/** /**
* 根据角色ID查询菜单树信息 * 根据角色ID查询菜单树信息
* *
@@ -118,16 +71,6 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenu, SysMenuVo> {
* @param menuCheckStrictly 菜单树选择项是否关联显示 * @param menuCheckStrictly 菜单树选择项是否关联显示
* @return 选中菜单列表 * @return 选中菜单列表
*/ */
default List<Long> selectMenuListByRoleId(Long roleId, boolean menuCheckStrictly) { List<Long> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
wrapper.select(SysMenu::getMenuId)
.inSql(SysMenu::getMenuId, buildMenuByRoleSql(roleId))
.orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum);
if (menuCheckStrictly) {
wrapper.notInSql(SysMenu::getMenuId, this.buildParentMenuByRoleSql(roleId));
}
return this.selectObjs(wrapper);
}
} }

View File

@@ -1,8 +1,9 @@
package org.dromara.system.mapper; package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.annotation.DataColumn; import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -29,47 +30,14 @@ public interface SysPostMapper extends BaseMapperPlus<SysPost, SysPostVo> {
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "create_by")
}) })
default Page<SysPostVo> selectPagePostList(Page<SysPost> page, Wrapper<SysPost> queryWrapper) { Page<SysPostVo> selectPagePostList(@Param("page") Page<SysPostVo> page, @Param(Constants.WRAPPER) Wrapper<SysPost> queryWrapper);
return this.selectVoPage(page, queryWrapper);
}
/** /**
* 查询岗位列表 * 查询用户所属岗位组
*
* @param queryWrapper 查询条件
* @return 岗位信息列表
*/
@DataPermission({
@DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by")
})
default List<SysPostVo> selectPostList(Wrapper<SysPost> queryWrapper) {
return this.selectVoList(queryWrapper);
}
/**
* 根据岗位ID集合查询岗位数量
*
* @param postIds 岗位ID列表
* @return 匹配的岗位数量
*/
@DataPermission({
@DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by")
})
default long selectPostCount(List<Long> postIds) {
return this.selectCount(new LambdaQueryWrapper<SysPost>().in(SysPost::getPostId, postIds));
}
/**
* 根据用户ID查询其关联的岗位列表
* *
* @param userId 用户ID * @param userId 用户ID
* @return 岗位信息列表 * @return 结果
*/ */
default List<SysPostVo> selectPostsByUserId(Long userId) { List<SysPostVo> selectPostsByUserId(Long userId);
return this.selectVoList(new LambdaQueryWrapper<SysPost>()
.inSql(SysPost::getPostId, "select post_id from sys_user_post where user_id = " + userId));
}
} }

View File

@@ -1,7 +1,6 @@
package org.dromara.system.mapper; package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@@ -20,18 +19,6 @@ import java.util.List;
*/ */
public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> { public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
/**
* 构建根据用户ID查询角色ID的SQL子查询
*
* @param userId 用户ID
* @return 查询用户对应角色ID的SQL语句字符串
*/
default String buildRoleByUserSql(Long userId) {
return """
select role_id from sys_user_role where user_id = %d
""".formatted(userId);
}
/** /**
* 分页查询角色列表 * 分页查询角色列表
* *
@@ -40,40 +27,22 @@ public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
* @return 包含角色信息的分页结果 * @return 包含角色信息的分页结果
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "create_dept"), @DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "r.create_by")
}) })
default Page<SysRoleVo> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper) { Page<SysRoleVo> selectPageRoleList(@Param("page") Page<SysRole> page, @Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
return this.selectVoPage(page, queryWrapper);
}
/** /**
* 根据条件查询角色数据 * 根据条件分页查询角色数据
* *
* @param queryWrapper 查询条件 * @param queryWrapper 查询条件
* @return 角色数据集合信息 * @return 角色数据集合信息
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "create_dept"), @DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "r.create_by")
}) })
default List<SysRoleVo> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper) { List<SysRoleVo> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
return this.selectVoList(queryWrapper);
}
/**
* 根据角色ID集合查询角色数量
*
* @param roleIds 角色ID列表
* @return 匹配的角色数量
*/
@DataPermission({
@DataColumn(key = "deptName", value = "create_dept"),
@DataColumn(key = "userName", value = "create_by")
})
default long selectRoleCount(List<Long> roleIds) {
return this.selectCount(new LambdaQueryWrapper<SysRole>().in(SysRole::getRoleId, roleIds));
}
/** /**
* 根据角色ID查询角色信息 * 根据角色ID查询角色信息
@@ -82,12 +51,10 @@ public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
* @return 对应的角色信息 * @return 对应的角色信息
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "create_dept"), @DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "r.create_by")
}) })
default SysRoleVo selectRoleById(Long roleId) { SysRoleVo selectRoleById(Long roleId);
return this.selectVoById(roleId);
}
/** /**
* 根据用户ID查询角色 * 根据用户ID查询角色
@@ -95,11 +62,14 @@ public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
* @param userId 用户ID * @param userId 用户ID
* @return 角色列表 * @return 角色列表
*/ */
default List<SysRoleVo> selectRolesByUserId(Long userId) { List<SysRoleVo> selectRolePermissionByUserId(Long userId);
return this.selectVoList(new LambdaQueryWrapper<SysRole>()
.select(SysRole::getRoleId, SysRole::getRoleName, SysRole::getRoleKey, /**
SysRole::getRoleSort, SysRole::getDataScope, SysRole::getStatus) * 根据用户ID查询角色
.inSql(SysRole::getRoleId, this.buildRoleByUserSql(userId))); *
} * @param userId 用户ID
* @return 角色列表
*/
List<SysRoleVo> selectRolesByUserId(Long userId);
} }

View File

@@ -16,11 +16,12 @@ public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenu, SysRoleMe
/** /**
* 根据菜单ID串删除关联关系 * 根据菜单ID串删除关联关系
* *
* @param menuIds 菜单ID串
* @return 结果 * @return 结果
*/ */
default int deleteByMenuIds(List<Long> menuIds) { default int deleteByMenuIds(List<Long> menuIds) {
return this.delete(new LambdaUpdateWrapper<SysRoleMenu>().in(SysRoleMenu::getMenuId, menuIds)); LambdaUpdateWrapper<SysRoleMenu> lqw = new LambdaUpdateWrapper<SysRoleMenu>()
.in(SysRoleMenu::getMenuId, menuIds);
return this.delete(lqw);
} }
} }

View File

@@ -1,7 +1,6 @@
package org.dromara.system.mapper; package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@@ -29,12 +28,10 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
* @return 分页的用户信息 * @return 分页的用户信息
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "u.dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "u.user_id")
}) })
default Page<SysUserVo> selectPageUserList(Page<SysUser> page, Wrapper<SysUser> queryWrapper) { Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
return this.selectVoPage(page, queryWrapper);
}
/** /**
* 查询用户列表,并进行数据权限控制 * 查询用户列表,并进行数据权限控制
@@ -44,11 +41,9 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "user_id")
}) })
default List<SysUserVo> selectUserList(Wrapper<SysUser> queryWrapper) { List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
return this.selectVoList(queryWrapper);
}
/** /**
* 根据条件分页查询用户列表 * 根据条件分页查询用户列表
@@ -58,20 +53,19 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"), @DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.create_by") @DataColumn(key = "userName", value = "u.user_id")
}) })
List<SysUserExportVo> selectUserExportList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); List<SysUserExportVo> selectUserExportList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/** /**
* 根据条件分页查询已配用户角色列表 * 根据条件分页查询已配用户角色列表
* *
* @param page 分页信息
* @param queryWrapper 查询条件 * @param queryWrapper 查询条件
* @return 用户信息集合信息 * @return 用户信息集合信息
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"), @DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.create_by") @DataColumn(key = "userName", value = "u.user_id")
}) })
Page<SysUserVo> selectAllocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); Page<SysUserVo> selectAllocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
@@ -83,7 +77,7 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "d.dept_id"), @DataColumn(key = "deptName", value = "d.dept_id"),
@DataColumn(key = "userName", value = "u.create_by") @DataColumn(key = "userName", value = "u.user_id")
}) })
Page<SysUserVo> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper); Page<SysUserVo> selectUnallocatedList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
@@ -95,11 +89,9 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
*/ */
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "user_id")
}) })
default long countUserById(Long userId) { long countUserById(Long userId);
return this.selectCount(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId, userId));
}
/** /**
* 根据条件更新用户数据 * 根据条件更新用户数据
@@ -111,7 +103,7 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
@Override @Override
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "user_id")
}) })
int update(@Param(Constants.ENTITY) SysUser user, @Param(Constants.WRAPPER) Wrapper<SysUser> updateWrapper); int update(@Param(Constants.ENTITY) SysUser user, @Param(Constants.WRAPPER) Wrapper<SysUser> updateWrapper);
@@ -124,7 +116,7 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
@Override @Override
@DataPermission({ @DataPermission({
@DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by") @DataColumn(key = "userName", value = "user_id")
}) })
int updateById(@Param(Constants.ENTITY) SysUser user); int updateById(@Param(Constants.ENTITY) SysUser user);

View File

@@ -1,6 +1,5 @@
package org.dromara.system.mapper; package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.system.domain.SysUserRole; import org.dromara.system.domain.SysUserRole;
@@ -19,10 +18,6 @@ public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRole, SysUserRo
* @param roleId 角色ID * @param roleId 角色ID
* @return 关联到指定角色的用户ID列表 * @return 关联到指定角色的用户ID列表
*/ */
default List<Long> selectUserIdsByRoleId(Long roleId) { List<Long> selectUserIdsByRoleId(Long roleId);
return this.selectObjs(new LambdaQueryWrapper<SysUserRole>()
.select(SysUserRole::getUserId).eq(SysUserRole::getRoleId, roleId)
);
}
} }

View File

@@ -14,13 +14,7 @@ import java.util.List;
*/ */
public interface ISysConfigService { public interface ISysConfigService {
/**
* 分页查询参数配置列表
*
* @param config 查询条件
* @param pageQuery 分页参数
* @return 参数配置分页列表
*/
TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery); TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery);
/** /**
@@ -75,7 +69,7 @@ public interface ISysConfigService {
* *
* @param configIds 需要删除的参数ID * @param configIds 需要删除的参数ID
*/ */
void deleteConfigByIds(List<Long> configIds); void deleteConfigByIds(Long[] configIds);
/** /**
* 重置参数缓存数据 * 重置参数缓存数据

View File

@@ -14,13 +14,7 @@ import java.util.List;
*/ */
public interface ISysDictDataService { public interface ISysDictDataService {
/**
* 分页查询字典数据列表
*
* @param dictData 查询条件
* @param pageQuery 分页参数
* @return 字典数据分页列表
*/
TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery); TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery);
/** /**
@@ -53,7 +47,7 @@ public interface ISysDictDataService {
* *
* @param dictCodes 需要删除的字典数据ID * @param dictCodes 需要删除的字典数据ID
*/ */
void deleteDictDataByIds(List<Long> dictCodes); void deleteDictDataByIds(Long[] dictCodes);
/** /**
* 新增保存字典数据信息 * 新增保存字典数据信息

View File

@@ -15,13 +15,7 @@ import java.util.List;
*/ */
public interface ISysDictTypeService { public interface ISysDictTypeService {
/**
* 分页查询字典类型列表
*
* @param dictType 查询条件
* @param pageQuery 分页参数
* @return 字典类型分页列表
*/
TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery); TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery);
/** /**
@@ -68,7 +62,7 @@ public interface ISysDictTypeService {
* *
* @param dictIds 需要删除的字典ID * @param dictIds 需要删除的字典ID
*/ */
void deleteDictTypeByIds(List<Long> dictIds); void deleteDictTypeByIds(Long[] dictIds);
/** /**
* 重置字典缓存数据 * 重置字典缓存数据

View File

@@ -14,13 +14,7 @@ import java.util.List;
*/ */
public interface ISysLogininforService { public interface ISysLogininforService {
/**
* 分页查询登录日志列表
*
* @param logininfor 查询条件
* @param pageQuery 分页参数
* @return 登录日志分页列表
*/
TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery); TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery);
/** /**

View File

@@ -14,13 +14,7 @@ import java.util.List;
*/ */
public interface ISysNoticeService { public interface ISysNoticeService {
/**
* 分页查询通知公告列表
*
* @param notice 查询条件
* @param pageQuery 分页参数
* @return 通知公告分页列表
*/
TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery); TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery);
/** /**

View File

@@ -14,13 +14,6 @@ import java.util.List;
*/ */
public interface ISysOperLogService { public interface ISysOperLogService {
/**
* 分页查询操作日志列表
*
* @param operLog 查询条件
* @param pageQuery 分页参数
* @return 操作日志分页列表
*/
TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery); TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery);
/** /**

View File

@@ -14,13 +14,7 @@ import java.util.List;
*/ */
public interface ISysPostService { public interface ISysPostService {
/**
* 分页查询岗位列表
*
* @param post 查询条件
* @param pageQuery 分页参数
* @return 岗位分页列表
*/
TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery); TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery);
/** /**
@@ -116,7 +110,7 @@ public interface ISysPostService {
* @param postIds 需要删除的岗位ID * @param postIds 需要删除的岗位ID
* @return 结果 * @return 结果
*/ */
int deletePostByIds(List<Long> postIds); int deletePostByIds(Long[] postIds);
/** /**
* 新增保存岗位信息 * 新增保存岗位信息

View File

@@ -16,17 +16,11 @@ import java.util.Set;
*/ */
public interface ISysRoleService { public interface ISysRoleService {
/**
* 分页查询角色列表
*
* @param role 查询条件
* @param pageQuery 分页参数
* @return 角色分页列表
*/
TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery); TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery);
/** /**
* 根据条件查询角色数据 * 根据条件分页查询角色数据
* *
* @param role 角色信息 * @param role 角色信息
* @return 角色数据集合信息 * @return 角色数据集合信息
@@ -118,13 +112,6 @@ public interface ISysRoleService {
*/ */
void checkRoleDataScope(Long roleId); void checkRoleDataScope(Long roleId);
/**
* 校验角色是否有数据权限
*
* @param roleIds 角色ID列表支持传单个ID
*/
void checkRoleDataScope(List<Long> roleIds);
/** /**
* 通过角色ID查询角色使用数量 * 通过角色ID查询角色使用数量
* *
@@ -180,7 +167,7 @@ public interface ISysRoleService {
* @param roleIds 需要删除的角色ID * @param roleIds 需要删除的角色ID
* @return 结果 * @return 结果
*/ */
int deleteRoleByIds(List<Long> roleIds); int deleteRoleByIds(Long[] roleIds);
/** /**
* 取消授权用户角色 * 取消授权用户角色
@@ -208,29 +195,8 @@ public interface ISysRoleService {
*/ */
int insertAuthUsers(Long roleId, Long[] userIds); int insertAuthUsers(Long roleId, Long[] userIds);
/**
* 根据角色ID清除该角色关联的所有在线用户的登录状态踢出在线用户
*
* <p>
* 先判断角色是否绑定用户,若无绑定则直接返回
* 然后遍历当前所有在线Token查找拥有该角色的用户并强制登出
* 注意:在线用户量过大时,操作可能导致 Redis 阻塞,需谨慎调用
* </p>
*
* @param roleId 角色ID
*/
void cleanOnlineUserByRole(Long roleId); void cleanOnlineUserByRole(Long roleId);
/**
* 根据用户ID列表清除对应在线用户的登录状态踢出指定用户
*
* <p>
* 遍历当前所有在线Token匹配用户ID列表中的用户强制登出
* 注意:在线用户量过大时,操作可能导致 Redis 阻塞,需谨慎调用
* </p>
*
* @param userIds 需要清除的用户ID列表
*/
void cleanOnlineUser(List<Long> userIds); void cleanOnlineUser(List<Long> userIds);
} }

View File

@@ -1,6 +1,5 @@
package org.dromara.system.service.impl; package org.dromara.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -44,10 +43,11 @@ public class SysClientServiceImpl implements ISysClientService {
@Override @Override
public SysClientVo queryById(Long id) { public SysClientVo queryById(Long id) {
SysClientVo vo = baseMapper.selectVoById(id); SysClientVo vo = baseMapper.selectVoById(id);
vo.setGrantTypeList(StringUtils.splitList(vo.getGrantType())); vo.setGrantTypeList(List.of(vo.getGrantType().split(",")));
return vo; return vo;
} }
/** /**
* 查询客户端管理 * 查询客户端管理
*/ */
@@ -64,7 +64,7 @@ public class SysClientServiceImpl implements ISysClientService {
public TableDataInfo<SysClientVo> queryPageList(SysClientBo bo, PageQuery pageQuery) { public TableDataInfo<SysClientVo> queryPageList(SysClientBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysClient> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<SysClient> lqw = buildQueryWrapper(bo);
Page<SysClientVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<SysClientVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
result.getRecords().forEach(r -> r.setGrantTypeList(StringUtils.splitList(r.getGrantType()))); result.getRecords().forEach(r -> r.setGrantTypeList(List.of(r.getGrantType().split(","))));
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
@@ -93,7 +93,8 @@ public class SysClientServiceImpl implements ISysClientService {
@Override @Override
public Boolean insertByBo(SysClientBo bo) { public Boolean insertByBo(SysClientBo bo) {
SysClient add = MapstructUtils.convert(bo, SysClient.class); SysClient add = MapstructUtils.convert(bo, SysClient.class);
add.setGrantType(CollUtil.join(bo.getGrantTypeList(), StringUtils.SEPARATOR)); validEntityBeforeSave(add);
add.setGrantType(String.join(",", bo.getGrantTypeList()));
// 生成clientid // 生成clientid
String clientKey = bo.getClientKey(); String clientKey = bo.getClientKey();
String clientSecret = bo.getClientSecret(); String clientSecret = bo.getClientSecret();
@@ -112,6 +113,7 @@ public class SysClientServiceImpl implements ISysClientService {
@Override @Override
public Boolean updateByBo(SysClientBo bo) { public Boolean updateByBo(SysClientBo bo) {
SysClient update = MapstructUtils.convert(bo, SysClient.class); SysClient update = MapstructUtils.convert(bo, SysClient.class);
validEntityBeforeSave(update);
update.setGrantType(String.join(",", bo.getGrantTypeList())); update.setGrantType(String.join(",", bo.getGrantTypeList()));
return baseMapper.updateById(update) > 0; return baseMapper.updateById(update) > 0;
} }
@@ -128,12 +130,22 @@ public class SysClientServiceImpl implements ISysClientService {
.eq(SysClient::getClientId, clientId)); .eq(SysClient::getClientId, clientId));
} }
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysClient entity) {
//TODO 做一些数据校验,如唯一约束
}
/** /**
* 批量删除客户端管理 * 批量删除客户端管理
*/ */
@CacheEvict(cacheNames = CacheNames.SYS_CLIENT, allEntries = true) @CacheEvict(cacheNames = CacheNames.SYS_CLIENT, allEntries = true)
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
} }

View File

@@ -2,10 +2,10 @@ package org.dromara.system.service.impl;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
@@ -23,10 +23,12 @@ import org.dromara.system.domain.bo.SysConfigBo;
import org.dromara.system.domain.vo.SysConfigVo; import org.dromara.system.domain.vo.SysConfigVo;
import org.dromara.system.mapper.SysConfigMapper; import org.dromara.system.mapper.SysConfigMapper;
import org.dromara.system.service.ISysConfigService; import org.dromara.system.service.ISysConfigService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -41,13 +43,6 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
private final SysConfigMapper baseMapper; private final SysConfigMapper baseMapper;
/**
* 分页查询参数配置列表
*
* @param config 查询条件
* @param pageQuery 分页参数
* @return 参数配置分页列表
*/
@Override @Override
public TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery) { public TableDataInfo<SysConfigVo> selectPageConfigList(SysConfigBo config, PageQuery pageQuery) {
LambdaQueryWrapper<SysConfig> lqw = buildQueryWrapper(config); LambdaQueryWrapper<SysConfig> lqw = buildQueryWrapper(config);
@@ -62,6 +57,7 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
* @return 参数配置信息 * @return 参数配置信息
*/ */
@Override @Override
@DS("master")
public SysConfigVo selectConfigById(Long configId) { public SysConfigVo selectConfigById(Long configId) {
return baseMapper.selectVoById(configId); return baseMapper.selectVoById(configId);
} }
@@ -87,10 +83,14 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
*/ */
@Override @Override
public boolean selectRegisterEnabled(String tenantId) { public boolean selectRegisterEnabled(String tenantId) {
String configValue = TenantHelper.dynamic(tenantId, () -> SysConfig retConfig = TenantHelper.dynamic(tenantId, () -> {
this.selectConfigByKey("sys.account.registerUser") return baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
); .eq(SysConfig::getConfigKey, "sys.account.registerUser"));
return Convert.toBool(configValue); });
if (ObjectUtil.isNull(retConfig)) {
return false;
}
return Convert.toBool(retConfig.getConfigValue());
} }
/** /**
@@ -168,15 +168,15 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
* @param configIds 需要删除的参数ID * @param configIds 需要删除的参数ID
*/ */
@Override @Override
public void deleteConfigByIds(List<Long> configIds) { public void deleteConfigByIds(Long[] configIds) {
List<SysConfig> list = baseMapper.selectByIds(configIds); for (Long configId : configIds) {
list.forEach(config -> { SysConfig config = baseMapper.selectById(configId);
if (StringUtils.equals(SystemConstants.YES, config.getConfigType())) { if (StringUtils.equals(SystemConstants.YES, config.getConfigType())) {
throw new ServiceException(String.format("内置参数【%s】不能删除", config.getConfigKey())); throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
} }
CacheUtils.evict(CacheNames.SYS_CONFIG, config.getConfigKey()); CacheUtils.evict(CacheNames.SYS_CONFIG, config.getConfigKey());
}); }
baseMapper.deleteByIds(configIds); baseMapper.deleteByIds(Arrays.asList(configIds));
} }
/** /**
@@ -195,10 +195,12 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
*/ */
@Override @Override
public boolean checkConfigKeyUnique(SysConfigBo config) { public boolean checkConfigKeyUnique(SysConfigBo config) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysConfig>() long configId = ObjectUtils.notNull(config.getConfigId(), -1L);
.eq(SysConfig::getConfigKey, config.getConfigKey()) SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
.ne(ObjectUtil.isNotNull(config.getConfigId()), SysConfig::getConfigId, config.getConfigId())); if (ObjectUtil.isNotNull(info) && info.getConfigId() != configId) {
return !exist; return false;
}
return true;
} }
/** /**

View File

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysRoleDept; import org.dromara.system.domain.SysRoleDept;
import org.dromara.system.mapper.SysDeptMapper; import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysRoleDeptMapper; import org.dromara.system.mapper.SysRoleDeptMapper;
@@ -65,8 +66,13 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService {
if (ObjectUtil.isNull(deptId)) { if (ObjectUtil.isNull(deptId)) {
return "-1"; return "-1";
} }
List<Long> deptIds = deptMapper.selectDeptAndChildById(deptId); List<SysDept> deptList = deptMapper.selectListByParentId(deptId);
return CollUtil.isNotEmpty(deptIds) ? StreamUtils.join(deptIds, Convert::toStr) : "-1"; List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
ids.add(deptId);
if (CollUtil.isNotEmpty(ids)) {
return StreamUtils.join(ids, Convert::toStr);
}
return "-1";
} }
} }

View File

@@ -36,7 +36,10 @@ import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/** /**
* 部门管理 服务实现 * 部门管理 服务实现
@@ -107,7 +110,10 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
if (ObjectUtil.isNotNull(bo.getBelongDeptId())) { if (ObjectUtil.isNotNull(bo.getBelongDeptId())) {
//部门树搜索 //部门树搜索
lqw.and(x -> { lqw.and(x -> {
List<Long> deptIds = baseMapper.selectDeptAndChildById(bo.getBelongDeptId()); Long parentId = bo.getBelongDeptId();
List<SysDept> deptList = baseMapper.selectListByParentId(parentId);
List<Long> deptIds = StreamUtils.toList(deptList, SysDept::getDeptId);
deptIds.add(parentId);
x.in(SysDept::getDeptId, deptIds); x.in(SysDept::getDeptId, deptIds);
}); });
} }
@@ -125,17 +131,23 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
if (CollUtil.isEmpty(depts)) { if (CollUtil.isEmpty(depts)) {
return CollUtil.newArrayList(); return CollUtil.newArrayList();
} }
return TreeBuildUtils.buildMultiRoot( // 获取当前列表中每一个节点的parentId然后在列表中查找是否有id与其parentId对应若无对应则表明此时节点列表中该节点在当前列表中属于顶级节点
depts, List<Tree<Long>> treeList = CollUtil.newArrayList();
SysDeptVo::getDeptId, for (SysDeptVo d : depts) {
SysDeptVo::getParentId, Long parentId = d.getParentId();
(node, treeNode) -> treeNode SysDeptVo sysDeptVo = StreamUtils.findFirst(depts, it -> it.getDeptId().longValue() == parentId);
.setId(node.getDeptId()) if (ObjectUtil.isNull(sysDeptVo)) {
.setParentId(node.getParentId()) List<Tree<Long>> trees = TreeBuildUtils.build(depts, parentId, (dept, tree) ->
.setName(node.getDeptName()) tree.setId(dept.getDeptId())
.setWeight(node.getOrderNum()) .setParentId(dept.getParentId())
.putExtra("disabled", SystemConstants.DISABLE.equals(node.getStatus())) .setName(dept.getDeptName())
); .setWeight(dept.getOrderNum())
.putExtra("disabled", SystemConstants.DISABLE.equals(dept.getStatus())));
Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getDeptId());
treeList.add(tree);
}
}
return treeList;
} }
/** /**
@@ -403,24 +415,4 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
return baseMapper.deleteById(deptId); return baseMapper.deleteById(deptId);
} }
/**
* 根据部门 ID 列表查询部门名称映射关系
*
* @param deptIds 部门 ID 列表
* @return Map其中 key 为部门 IDvalue 为对应的部门名称
*/
@Override
public Map<Long, String> selectDeptNamesByIds(List<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return Collections.emptyMap();
}
List<SysDept> list = baseMapper.selectList(
new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptId, SysDept::getDeptName)
.in(SysDept::getDeptId, deptIds)
);
return StreamUtils.toMap(list, SysDept::getDeptId, SysDept::getDeptName);
}
} }

View File

@@ -4,19 +4,20 @@ import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.system.domain.SysDictData; import org.dromara.system.domain.SysDictData;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.system.domain.bo.SysDictDataBo; import org.dromara.system.domain.bo.SysDictDataBo;
import org.dromara.system.domain.vo.SysDictDataVo; import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.mapper.SysDictDataMapper; import org.dromara.system.mapper.SysDictDataMapper;
import org.dromara.system.service.ISysDictDataService; import org.dromara.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -33,13 +34,6 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
private final SysDictDataMapper baseMapper; private final SysDictDataMapper baseMapper;
/**
* 分页查询字典数据列表
*
* @param dictData 查询条件
* @param pageQuery 分页参数
* @return 字典数据分页列表
*/
@Override @Override
public TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery) { public TableDataInfo<SysDictDataVo> selectPageDictDataList(SysDictDataBo dictData, PageQuery pageQuery) {
LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData); LambdaQueryWrapper<SysDictData> lqw = buildQueryWrapper(dictData);
@@ -64,7 +58,7 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
lqw.eq(bo.getDictSort() != null, SysDictData::getDictSort, bo.getDictSort()); lqw.eq(bo.getDictSort() != null, SysDictData::getDictSort, bo.getDictSort());
lqw.like(StringUtils.isNotBlank(bo.getDictLabel()), SysDictData::getDictLabel, bo.getDictLabel()); lqw.like(StringUtils.isNotBlank(bo.getDictLabel()), SysDictData::getDictLabel, bo.getDictLabel());
lqw.eq(StringUtils.isNotBlank(bo.getDictType()), SysDictData::getDictType, bo.getDictType()); lqw.eq(StringUtils.isNotBlank(bo.getDictType()), SysDictData::getDictType, bo.getDictType());
lqw.orderByAsc(SysDictData::getDictSort, SysDictData::getDictCode); lqw.orderByAsc(SysDictData::getDictSort);
return lqw; return lqw;
} }
@@ -101,10 +95,12 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
* @param dictCodes 需要删除的字典数据ID * @param dictCodes 需要删除的字典数据ID
*/ */
@Override @Override
public void deleteDictDataByIds(List<Long> dictCodes) { public void deleteDictDataByIds(Long[] dictCodes) {
List<SysDictData> list = baseMapper.selectByIds(dictCodes); for (Long dictCode : dictCodes) {
baseMapper.deleteByIds(dictCodes); SysDictData data = baseMapper.selectById(dictCode);
list.forEach(x -> CacheUtils.evict(CacheNames.SYS_DICT, x.getDictType())); baseMapper.deleteById(dictCode);
CacheUtils.evict(CacheNames.SYS_DICT, data.getDictType());
}
} }
/** /**
@@ -149,11 +145,13 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
*/ */
@Override @Override
public boolean checkDictDataUnique(SysDictDataBo dict) { public boolean checkDictDataUnique(SysDictDataBo dict) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDictData>() Long dictCode = ObjectUtils.notNull(dict.getDictCode(), -1L);
.eq(SysDictData::getDictType, dict.getDictType()) SysDictData entity = baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictValue, dict.getDictValue()) .eq(SysDictData::getDictType, dict.getDictType()).eq(SysDictData::getDictValue, dict.getDictValue()));
.ne(ObjectUtil.isNotNull(dict.getDictCode()), SysDictData::getDictCode, dict.getDictCode())); if (ObjectUtil.isNotNull(entity) && !dictCode.equals(entity.getDictCode())) {
return !exist; return false;
}
return true;
} }
} }

View File

@@ -48,13 +48,6 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
private final SysDictTypeMapper baseMapper; private final SysDictTypeMapper baseMapper;
private final SysDictDataMapper dictDataMapper; private final SysDictDataMapper dictDataMapper;
/**
* 分页查询字典类型列表
*
* @param dictType 查询条件
* @param pageQuery 分页参数
* @return 字典类型分页列表
*/
@Override @Override
public TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery) { public TableDataInfo<SysDictTypeVo> selectPageDictTypeList(SysDictTypeBo dictType, PageQuery pageQuery) {
LambdaQueryWrapper<SysDictType> lqw = buildQueryWrapper(dictType); LambdaQueryWrapper<SysDictType> lqw = buildQueryWrapper(dictType);
@@ -105,7 +98,10 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
@Override @Override
public List<SysDictDataVo> selectDictDataByType(String dictType) { public List<SysDictDataVo> selectDictDataByType(String dictType) {
List<SysDictDataVo> dictDatas = dictDataMapper.selectDictDataByType(dictType); List<SysDictDataVo> dictDatas = dictDataMapper.selectDictDataByType(dictType);
return CollUtil.isNotEmpty(dictDatas) ? dictDatas : null; if (CollUtil.isNotEmpty(dictDatas)) {
return dictDatas;
}
return null;
} }
/** /**
@@ -137,20 +133,17 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
* @param dictIds 需要删除的字典ID * @param dictIds 需要删除的字典ID
*/ */
@Override @Override
public void deleteDictTypeByIds(List<Long> dictIds) { public void deleteDictTypeByIds(Long[] dictIds) {
List<SysDictType> list = baseMapper.selectByIds(dictIds); for (Long dictId : dictIds) {
list.forEach(x -> { SysDictType dictType = baseMapper.selectById(dictId);
boolean assigned = dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>() if (dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictType, x.getDictType())); .eq(SysDictData::getDictType, dictType.getDictType()))) {
if (assigned) { throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
throw new ServiceException(String.format("%1$s已分配,不能删除", x.getDictName()));
} }
}); CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
baseMapper.deleteByIds(dictIds); CacheUtils.evict(CacheNames.SYS_DICT_TYPE, dictType.getDictType());
list.forEach(x -> { }
CacheUtils.evict(CacheNames.SYS_DICT, x.getDictType()); baseMapper.deleteByIds(Arrays.asList(dictIds));
CacheUtils.evict(CacheNames.SYS_DICT_TYPE, x.getDictType());
});
} }
/** /**

View File

@@ -108,13 +108,6 @@ public class SysLogininforServiceImpl implements ISysLogininforService {
return "[" + msg.toString() + "]"; return "[" + msg.toString() + "]";
} }
/**
* 分页查询登录日志列表
*
* @param logininfor 查询条件
* @param pageQuery 分页参数
* @return 登录日志分页列表
*/
@Override @Override
public TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery) { public TableDataInfo<SysLogininforVo> selectPageLogininforList(SysLogininforBo logininfor, PageQuery pageQuery) {
Map<String, Object> params = logininfor.getParams(); Map<String, Object> params = logininfor.getParams();

View File

@@ -5,8 +5,9 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
@@ -65,20 +66,29 @@ public class SysMenuServiceImpl implements ISysMenuService {
@Override @Override
public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) { public List<SysMenuVo> selectMenuList(SysMenuBo menu, Long userId) {
List<SysMenuVo> menuList; List<SysMenuVo> menuList;
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>(); // 管理员显示所有菜单信息
// 管理员显示所有菜单信息 不是管理员 按用户id过滤菜单 if (LoginHelper.isSuperAdmin(userId)) {
if (!LoginHelper.isSuperAdmin(userId)) { menuList = baseMapper.selectVoList(new LambdaQueryWrapper<SysMenu>()
// 通过用户id获取角色id 通过角色id获取菜单id 然后in菜单 .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
wrapper.inSql(SysMenu::getMenuId, baseMapper.buildMenuByUserSql(userId));
}
menuList = baseMapper.selectVoList(
wrapper.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible()) .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus()) .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
.eq(StringUtils.isNotBlank(menu.getMenuType()), SysMenu::getMenuType, menu.getMenuType()) .eq(StringUtils.isNotBlank(menu.getMenuType()), SysMenu::getMenuType, menu.getMenuType())
.eq(ObjectUtil.isNotNull(menu.getParentId()), SysMenu::getParentId, menu.getParentId()) .eq(ObjectUtil.isNotNull(menu.getParentId()), SysMenu::getParentId, menu.getParentId())
.orderByAsc(SysMenu::getParentId) .orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum)); .orderByAsc(SysMenu::getOrderNum));
} else {
QueryWrapper<SysMenu> wrapper = Wrappers.query();
wrapper.inSql("r.role_id", "select role_id from sys_user_role where user_id = " + userId)
.like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
.eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
.eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
.eq(StringUtils.isNotBlank(menu.getMenuType()), "m.menu_type", menu.getMenuType())
.eq(ObjectUtil.isNotNull(menu.getParentId()), "m.parent_id", menu.getParentId())
.orderByAsc("m.parent_id")
.orderByAsc("m.order_num");
List<SysMenu> list = baseMapper.selectMenuListByUserId(wrapper);
menuList = MapstructUtils.convert(list, SysMenuVo.class);
}
return menuList; return menuList;
} }
@@ -130,15 +140,9 @@ public class SysMenuServiceImpl implements ISysMenuService {
if (LoginHelper.isSuperAdmin(userId)) { if (LoginHelper.isSuperAdmin(userId)) {
menus = baseMapper.selectMenuTreeAll(); menus = baseMapper.selectMenuTreeAll();
} else { } else {
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>(); menus = baseMapper.selectMenuTreeByUserId(userId);
menus = baseMapper.selectList(
wrapper.in(SysMenu::getMenuType, SystemConstants.TYPE_DIR, SystemConstants.TYPE_MENU)
.eq(SysMenu::getStatus, SystemConstants.NORMAL)
.inSql(SysMenu::getMenuId, baseMapper.buildMenuByUserSql(userId))
.orderByAsc(SysMenu::getParentId)
.orderByAsc(SysMenu::getOrderNum));
} }
return getChildPerms(menus, Constants.TOP_PARENT_ID); return getChildPerms(menus, 0);
} }
/** /**
@@ -217,7 +221,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
children.setQuery(menu.getQueryParam()); children.setQuery(menu.getQueryParam());
childrenList.add(children); childrenList.add(children);
router.setChildren(childrenList); router.setChildren(childrenList);
} else if (menu.getParentId().equals(Constants.TOP_PARENT_ID) && menu.isInnerLink()) { } else if (menu.getParentId().intValue() == 0 && menu.isInnerLink()) {
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/"); router.setPath("/");
List<RouterVo> childrenList = new ArrayList<>(); List<RouterVo> childrenList = new ArrayList<>();
@@ -371,11 +375,11 @@ public class SysMenuServiceImpl implements ISysMenuService {
* @param parentId 传入的父节点ID * @param parentId 传入的父节点ID
* @return String * @return String
*/ */
private List<SysMenu> getChildPerms(List<SysMenu> list, Long parentId) { private List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
List<SysMenu> returnList = new ArrayList<>(); List<SysMenu> returnList = new ArrayList<>();
for (SysMenu t : list) { for (SysMenu t : list) {
// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点 // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
if (t.getParentId().equals(parentId)) { if (t.getParentId() == parentId) {
recursionFn(list, t); recursionFn(list, t);
returnList.add(t); returnList.add(t);
} }

View File

@@ -3,7 +3,6 @@ package org.dromara.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
@@ -17,6 +16,7 @@ import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysNoticeMapper; import org.dromara.system.mapper.SysNoticeMapper;
import org.dromara.system.mapper.SysUserMapper; import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysNoticeService; import org.dromara.system.service.ISysNoticeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays; import java.util.Arrays;
@@ -34,13 +34,6 @@ public class SysNoticeServiceImpl implements ISysNoticeService {
private final SysNoticeMapper baseMapper; private final SysNoticeMapper baseMapper;
private final SysUserMapper userMapper; private final SysUserMapper userMapper;
/**
* 分页查询通知公告列表
*
* @param notice 查询条件
* @param pageQuery 分页参数
* @return 通知公告分页列表
*/
@Override @Override
public TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery) { public TableDataInfo<SysNoticeVo> selectPageNoticeList(SysNoticeBo notice, PageQuery pageQuery) {
LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(notice); LambdaQueryWrapper<SysNotice> lqw = buildQueryWrapper(notice);

View File

@@ -49,13 +49,6 @@ public class SysOperLogServiceImpl implements ISysOperLogService {
insertOperlog(operLog); insertOperlog(operLog);
} }
/**
* 分页查询操作日志列表
*
* @param operLog 查询条件
* @param pageQuery 分页参数
* @return 操作日志分页列表
*/
@Override @Override
public TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery) { public TableDataInfo<SysOperLogVo> selectPageOperLogList(SysOperLogBo operLog, PageQuery pageQuery) {
LambdaQueryWrapper<SysOperLog> lqw = buildQueryWrapper(operLog); LambdaQueryWrapper<SysOperLog> lqw = buildQueryWrapper(operLog);

View File

@@ -17,7 +17,6 @@ import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils; import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.oss.core.OssClient; import org.dromara.common.oss.core.OssClient;
@@ -25,7 +24,6 @@ import org.dromara.common.oss.entity.UploadResult;
import org.dromara.common.oss.enums.AccessPolicyType; import org.dromara.common.oss.enums.AccessPolicyType;
import org.dromara.common.oss.factory.OssFactory; import org.dromara.common.oss.factory.OssFactory;
import org.dromara.system.domain.SysOss; import org.dromara.system.domain.SysOss;
import org.dromara.system.domain.SysOssExt;
import org.dromara.system.domain.bo.SysOssBo; import org.dromara.system.domain.bo.SysOssBo;
import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.mapper.SysOssMapper; import org.dromara.system.mapper.SysOssMapper;
@@ -201,11 +199,8 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
} catch (IOException e) { } catch (IOException e) {
throw new ServiceException(e.getMessage()); throw new ServiceException(e.getMessage());
} }
SysOssExt ext1 = new SysOssExt();
ext1.setFileSize(file.getSize());
ext1.setContentType(file.getContentType());
// 保存文件信息 // 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, ext1); return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult);
} }
/** /**
@@ -220,21 +215,18 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance(); OssClient storage = OssFactory.instance();
UploadResult uploadResult = storage.uploadSuffix(file, suffix); UploadResult uploadResult = storage.uploadSuffix(file, suffix);
SysOssExt ext1 = new SysOssExt();
ext1.setFileSize(file.length());
// 保存文件信息 // 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, ext1); return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult);
} }
@NotNull @NotNull
private SysOssVo buildResultEntity(String originalfileName, String suffix, String configKey, UploadResult uploadResult, SysOssExt ext1) { private SysOssVo buildResultEntity(String originalfileName, String suffix, String configKey, UploadResult uploadResult) {
SysOss oss = new SysOss(); SysOss oss = new SysOss();
oss.setUrl(uploadResult.getUrl()); oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix); oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename()); oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalfileName); oss.setOriginalName(originalfileName);
oss.setService(configKey); oss.setService(configKey);
oss.setExt1(JsonUtils.toJsonString(ext1));
baseMapper.insert(oss); baseMapper.insert(oss);
SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class); SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class);
return this.matchingUrl(sysOssVo); return this.matchingUrl(sysOssVo);

View File

@@ -14,6 +14,7 @@ import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysPost; import org.dromara.system.domain.SysPost;
import org.dromara.system.domain.SysUserPost; import org.dromara.system.domain.SysUserPost;
import org.dromara.system.domain.bo.SysPostBo; import org.dromara.system.domain.bo.SysPostBo;
@@ -24,7 +25,7 @@ import org.dromara.system.mapper.SysUserPostMapper;
import org.dromara.system.service.ISysPostService; import org.dromara.system.service.ISysPostService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collections; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -41,13 +42,6 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
private final SysDeptMapper deptMapper; private final SysDeptMapper deptMapper;
private final SysUserPostMapper userPostMapper; private final SysUserPostMapper userPostMapper;
/**
* 分页查询岗位列表
*
* @param post 查询条件
* @param pageQuery 分页参数
* @return 岗位分页列表
*/
@Override @Override
public TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery) { public TableDataInfo<SysPostVo> selectPagePostList(SysPostBo post, PageQuery pageQuery) {
Page<SysPostVo> page = baseMapper.selectPagePostList(pageQuery.build(), buildQueryWrapper(post)); Page<SysPostVo> page = baseMapper.selectPagePostList(pageQuery.build(), buildQueryWrapper(post));
@@ -98,7 +92,9 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
} else if (ObjectUtil.isNotNull(bo.getBelongDeptId())) { } else if (ObjectUtil.isNotNull(bo.getBelongDeptId())) {
//部门树搜索 //部门树搜索
wrapper.and(x -> { wrapper.and(x -> {
List<Long> deptIds = deptMapper.selectDeptAndChildById(bo.getBelongDeptId()); List<SysDept> deptList = deptMapper.selectListByParentId(bo.getBelongDeptId());
List<Long> deptIds = StreamUtils.toList(deptList, SysDept::getDeptId);
deptIds.add(bo.getBelongDeptId());
x.in(SysPost::getDeptId, deptIds); x.in(SysPost::getDeptId, deptIds);
}); });
} }
@@ -221,14 +217,14 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
* @return 结果 * @return 结果
*/ */
@Override @Override
public int deletePostByIds(List<Long> postIds) { public int deletePostByIds(Long[] postIds) {
List<SysPost> list = baseMapper.selectByIds(postIds); for (Long postId : postIds) {
for (SysPost post : list) { SysPost post = baseMapper.selectById(postId);
if (this.countUserPostById(post.getPostId()) > 0) { if (countUserPostById(postId) > 0) {
throw new ServiceException(String.format("%1$s已分配不能删除!", post.getPostName())); throw new ServiceException(String.format("%1$s已分配不能删除!", post.getPostName()));
} }
} }
return baseMapper.deleteByIds(postIds); return baseMapper.deleteByIds(Arrays.asList(postIds));
} }
/** /**
@@ -255,23 +251,4 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
return baseMapper.updateById(post); return baseMapper.updateById(post);
} }
/**
* 根据岗位 ID 列表查询岗位名称映射关系
*
* @param postIds 岗位 ID 列表
* @return Map其中 key 为岗位 IDvalue 为对应的岗位名称
*/
@Override
public Map<Long, String> selectPostNamesByIds(List<Long> postIds) {
if (CollUtil.isEmpty(postIds)) {
return Collections.emptyMap();
}
List<SysPost> list = baseMapper.selectList(
new LambdaQueryWrapper<SysPost>()
.select(SysPost::getPostId, SysPost::getPostName)
.in(SysPost::getPostId, postIds)
);
return StreamUtils.toMap(list, SysPost::getPostId, SysPost::getPostName);
}
} }

View File

@@ -7,6 +7,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -54,13 +55,6 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
private final SysUserRoleMapper userRoleMapper; private final SysUserRoleMapper userRoleMapper;
private final SysRoleDeptMapper roleDeptMapper; private final SysRoleDeptMapper roleDeptMapper;
/**
* 分页查询角色列表
*
* @param role 查询条件
* @param pageQuery 分页参数
* @return 角色分页列表
*/
@Override @Override
public TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery) { public TableDataInfo<SysRoleVo> selectPageRoleList(SysRoleBo role, PageQuery pageQuery) {
Page<SysRoleVo> page = baseMapper.selectPageRoleList(pageQuery.build(), this.buildQueryWrapper(role)); Page<SysRoleVo> page = baseMapper.selectPageRoleList(pageQuery.build(), this.buildQueryWrapper(role));
@@ -68,7 +62,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
} }
/** /**
* 根据条件查询角色数据 * 根据条件分页查询角色数据
* *
* @param role 角色信息 * @param role 角色信息
* @return 角色数据集合信息 * @return 角色数据集合信息
@@ -80,14 +74,15 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
private Wrapper<SysRole> buildQueryWrapper(SysRoleBo bo) { private Wrapper<SysRole> buildQueryWrapper(SysRoleBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysRole> wrapper = Wrappers.lambdaQuery(); QueryWrapper<SysRole> wrapper = Wrappers.query();
wrapper.eq(ObjectUtil.isNotNull(bo.getRoleId()), SysRole::getRoleId, bo.getRoleId()) wrapper.eq("r.del_flag", SystemConstants.NORMAL)
.like(StringUtils.isNotBlank(bo.getRoleName()), SysRole::getRoleName, bo.getRoleName()) .eq(ObjectUtil.isNotNull(bo.getRoleId()), "r.role_id", bo.getRoleId())
.eq(StringUtils.isNotBlank(bo.getStatus()), SysRole::getStatus, bo.getStatus()) .like(StringUtils.isNotBlank(bo.getRoleName()), "r.role_name", bo.getRoleName())
.like(StringUtils.isNotBlank(bo.getRoleKey()), SysRole::getRoleKey, bo.getRoleKey()) .eq(StringUtils.isNotBlank(bo.getStatus()), "r.status", bo.getStatus())
.like(StringUtils.isNotBlank(bo.getRoleKey()), "r.role_key", bo.getRoleKey())
.between(params.get("beginTime") != null && params.get("endTime") != null, .between(params.get("beginTime") != null && params.get("endTime") != null,
SysRole::getCreateTime, params.get("beginTime"), params.get("endTime")) "r.create_time", params.get("beginTime"), params.get("endTime"))
.orderByAsc(SysRole::getRoleSort).orderByAsc(SysRole::getCreateTime); .orderByAsc("r.role_sort").orderByAsc("r.create_time");
return wrapper; return wrapper;
} }
@@ -181,9 +176,9 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
*/ */
@Override @Override
public List<SysRoleVo> selectRoleByIds(List<Long> roleIds) { public List<SysRoleVo> selectRoleByIds(List<Long> roleIds) {
return baseMapper.selectRoleList(new LambdaQueryWrapper<SysRole>() return baseMapper.selectRoleList(new QueryWrapper<SysRole>()
.eq(SysRole::getStatus, SystemConstants.NORMAL) .eq("r.status", SystemConstants.NORMAL)
.in(CollUtil.isNotEmpty(roleIds), SysRole::getRoleId, roleIds)); .in(CollUtil.isNotEmpty(roleIds), "r.role_id", roleIds));
} }
/** /**
@@ -254,23 +249,14 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
if (ObjectUtil.isNull(roleId)) { if (ObjectUtil.isNull(roleId)) {
return; return;
} }
this.checkRoleDataScope(Collections.singletonList(roleId)); if (LoginHelper.isSuperAdmin()) {
}
/**
* 校验角色是否有数据权限
*
* @param roleIds 角色ID列表支持传单个ID
*/
@Override
public void checkRoleDataScope(List<Long> roleIds) {
if (CollUtil.isEmpty(roleIds) || LoginHelper.isSuperAdmin()) {
return; return;
} }
long count = baseMapper.selectRoleCount(roleIds); List<SysRoleVo> roles = this.selectRoleList(new SysRoleBo(roleId));
if (count != roleIds.size()) { if (CollUtil.isEmpty(roles)) {
throw new ServiceException("没有权限访问部分角色数据!"); throw new ServiceException("没有权限访问角色数据!");
} }
} }
/** /**
@@ -373,7 +359,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
rm.setMenuId(menuId); rm.setMenuId(menuId);
list.add(rm); list.add(rm);
} }
if (CollUtil.isNotEmpty(list)) { if (list.size() > 0) {
rows = roleMenuMapper.insertBatch(list) ? list.size() : 0; rows = roleMenuMapper.insertBatch(list) ? list.size() : 0;
} }
return rows; return rows;
@@ -394,7 +380,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
rd.setDeptId(deptId); rd.setDeptId(deptId);
list.add(rd); list.add(rd);
} }
if (CollUtil.isNotEmpty(list)) { if (list.size() > 0) {
rows = roleDeptMapper.insertBatch(list) ? list.size() : 0; rows = roleDeptMapper.insertBatch(list) ? list.size() : 0;
} }
return rows; return rows;
@@ -426,20 +412,21 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
@CacheEvict(cacheNames = CacheNames.SYS_ROLE_CUSTOM, allEntries = true) @CacheEvict(cacheNames = CacheNames.SYS_ROLE_CUSTOM, allEntries = true)
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public int deleteRoleByIds(List<Long> roleIds) { public int deleteRoleByIds(Long[] roleIds) {
this.checkRoleDataScope(roleIds); for (Long roleId : roleIds) {
List<SysRole> roles = baseMapper.selectByIds(roleIds); SysRole role = baseMapper.selectById(roleId);
for (SysRole role : roles) {
checkRoleAllowed(BeanUtil.toBean(role, SysRoleBo.class)); checkRoleAllowed(BeanUtil.toBean(role, SysRoleBo.class));
if (countUserRoleByRoleId(role.getRoleId()) > 0) { checkRoleDataScope(roleId);
if (countUserRoleByRoleId(roleId) > 0) {
throw new ServiceException(String.format("%1$s已分配不能删除!", role.getRoleName())); throw new ServiceException(String.format("%1$s已分配不能删除!", role.getRoleName()));
} }
} }
List<Long> ids = Arrays.asList(roleIds);
// 删除角色与菜单关联 // 删除角色与菜单关联
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds)); roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids));
// 删除角色与部门关联 // 删除角色与部门关联
roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, roleIds)); roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, ids));
return baseMapper.deleteByIds(roleIds); return baseMapper.deleteByIds(ids);
} }
/** /**
@@ -450,9 +437,6 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
*/ */
@Override @Override
public int deleteAuthUser(SysUserRole userRole) { public int deleteAuthUser(SysUserRole userRole) {
if (LoginHelper.getUserId().equals(userRole.getUserId())) {
throw new ServiceException("不允许修改当前用户角色!");
}
int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>() int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, userRole.getRoleId()) .eq(SysUserRole::getRoleId, userRole.getRoleId())
.eq(SysUserRole::getUserId, userRole.getUserId())); .eq(SysUserRole::getUserId, userRole.getUserId()));
@@ -472,9 +456,6 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
@Override @Override
public int deleteAuthUsers(Long roleId, Long[] userIds) { public int deleteAuthUsers(Long roleId, Long[] userIds) {
List<Long> ids = List.of(userIds); List<Long> ids = List.of(userIds);
if (ids.contains(LoginHelper.getUserId())) {
throw new ServiceException("不允许修改当前用户角色!");
}
int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>() int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
.eq(SysUserRole::getRoleId, roleId) .eq(SysUserRole::getRoleId, roleId)
.in(SysUserRole::getUserId, ids)); .in(SysUserRole::getUserId, ids));
@@ -496,9 +477,6 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
// 新增用户与角色管理 // 新增用户与角色管理
int rows = 1; int rows = 1;
List<Long> ids = List.of(userIds); List<Long> ids = List.of(userIds);
if (ids.contains(LoginHelper.getUserId())) {
throw new ServiceException("不允许修改当前用户角色!");
}
List<SysUserRole> list = StreamUtils.toList(ids, userId -> { List<SysUserRole> list = StreamUtils.toList(ids, userId -> {
SysUserRole ur = new SysUserRole(); SysUserRole ur = new SysUserRole();
ur.setUserId(userId); ur.setUserId(userId);
@@ -514,17 +492,6 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
return rows; return rows;
} }
/**
* 根据角色ID清除该角色关联的所有在线用户的登录状态踢出在线用户
*
* <p>
* 先判断角色是否绑定用户,若无绑定则直接返回
* 然后遍历当前所有在线Token查找拥有该角色的用户并强制登出
* 注意:在线用户量过大时,操作可能导致 Redis 阻塞,需谨慎调用
* </p>
*
* @param roleId 角色ID
*/
@Override @Override
public void cleanOnlineUserByRole(Long roleId) { public void cleanOnlineUserByRole(Long roleId) {
// 如果角色未绑定用户 直接返回 // 如果角色未绑定用户 直接返回
@@ -556,16 +523,6 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
}); });
} }
/**
* 根据用户ID列表清除对应在线用户的登录状态踢出指定用户
*
* <p>
* 遍历当前所有在线Token匹配用户ID列表中的用户强制登出
* 注意:在线用户量过大时,操作可能导致 Redis 阻塞,需谨慎调用
* </p>
*
* @param userIds 需要清除的用户ID列表
*/
@Override @Override
public void cleanOnlineUser(List<Long> userIds) { public void cleanOnlineUser(List<Long> userIds) {
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false); List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
@@ -592,23 +549,4 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
}); });
} }
/**
* 根据角色 ID 列表查询角色名称映射关系
*
* @param roleIds 角色 ID 列表
* @return Map其中 key 为角色 IDvalue 为对应的角色名称
*/
@Override
public Map<Long, String> selectRoleNamesByIds(List<Long> roleIds) {
if (CollUtil.isEmpty(roleIds)) {
return Collections.emptyMap();
}
List<SysRole> list = baseMapper.selectList(
new LambdaQueryWrapper<SysRole>()
.select(SysRole::getRoleId, SysRole::getRoleName)
.in(SysRole::getRoleId, roleIds)
);
return StreamUtils.toMap(list, SysRole::getRoleId, SysRole::getRoleName);
}
} }

View File

@@ -2,7 +2,6 @@ package org.dromara.system.service.impl;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.dto.TaskAssigneeDTO; import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
import org.dromara.common.core.domain.model.TaskAssigneeBody; import org.dromara.common.core.domain.model.TaskAssigneeBody;
import org.dromara.common.core.service.TaskAssigneeService; import org.dromara.common.core.service.TaskAssigneeService;
@@ -52,14 +51,13 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysRoleBo bo = new SysRoleBo(); SysRoleBo bo = new SysRoleBo();
bo.setRoleKey(taskQuery.getHandlerCode()); bo.setRoleKey(taskQuery.getHandlerCode());
bo.setRoleName(taskQuery.getHandlerName()); bo.setRoleName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime()); params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime()); params.put("endTime", taskQuery.getEndTime());
TableDataInfo<SysRoleVo> page = roleService.selectPageRoleList(bo, pageQuery); TableDataInfo<SysRoleVo> page = roleService.selectPageRoleList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
item -> String.valueOf(item.getRoleId()), SysRoleVo::getRoleKey, SysRoleVo::getRoleName, null, SysRoleVo::getCreateTime); SysRoleVo::getRoleId, SysRoleVo::getRoleKey, SysRoleVo::getRoleName, null, SysRoleVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
@@ -75,7 +73,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysPostBo bo = new SysPostBo(); SysPostBo bo = new SysPostBo();
bo.setPostCategory(taskQuery.getHandlerCode()); bo.setPostCategory(taskQuery.getHandlerCode());
bo.setPostName(taskQuery.getHandlerName()); bo.setPostName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime()); params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime()); params.put("endTime", taskQuery.getEndTime());
@@ -83,7 +80,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysPostVo> page = postService.selectPagePostList(bo, pageQuery); TableDataInfo<SysPostVo> page = postService.selectPagePostList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
p -> String.valueOf(p.getPostId()), SysPostVo::getPostCategory, SysPostVo::getPostName, SysPostVo::getDeptId, SysPostVo::getCreateTime); SysPostVo::getPostId, SysPostVo::getPostCategory, SysPostVo::getPostName, SysPostVo::getDeptId, SysPostVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
@@ -99,7 +96,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysDeptBo bo = new SysDeptBo(); SysDeptBo bo = new SysDeptBo();
bo.setDeptCategory(taskQuery.getHandlerCode()); bo.setDeptCategory(taskQuery.getHandlerCode());
bo.setDeptName(taskQuery.getHandlerName()); bo.setDeptName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime()); params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime()); params.put("endTime", taskQuery.getEndTime());
@@ -107,10 +103,11 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysDeptVo> page = deptService.selectPageDeptList(bo, pageQuery); TableDataInfo<SysDeptVo> page = deptService.selectPageDeptList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
d -> String.valueOf(d.getDeptId()), SysDeptVo::getDeptCategory, SysDeptVo::getDeptName, SysDeptVo::getParentId, SysDeptVo::getCreateTime); SysDeptVo::getDeptId, SysDeptVo::getDeptCategory, SysDeptVo::getDeptName, SysDeptVo::getParentId, SysDeptVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }
/** /**
* 查询用户并返回任务指派的列表,支持分页 * 查询用户并返回任务指派的列表,支持分页
* *
@@ -123,7 +120,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysUserBo bo = new SysUserBo(); SysUserBo bo = new SysUserBo();
bo.setUserName(taskQuery.getHandlerCode()); bo.setUserName(taskQuery.getHandlerCode());
bo.setNickName(taskQuery.getHandlerName()); bo.setNickName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime()); params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime()); params.put("endTime", taskQuery.getEndTime());
@@ -131,7 +127,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
TableDataInfo<SysUserVo> page = userService.selectPageUserList(bo, pageQuery); TableDataInfo<SysUserVo> page = userService.selectPageUserList(bo, pageQuery);
// 使用封装的字段映射方法进行转换 // 使用封装的字段映射方法进行转换
List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(), List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRows(),
u -> String.valueOf(u.getUserId()), SysUserVo::getUserName, SysUserVo::getNickName, SysUserVo::getDeptId, SysUserVo::getCreateTime); SysUserVo::getUserId, SysUserVo::getUserName, SysUserVo::getNickName, SysUserVo::getDeptId, SysUserVo::getCreateTime);
return new TaskAssigneeDTO(page.getTotal(), handlers); return new TaskAssigneeDTO(page.getTotal(), handlers);
} }

View File

@@ -414,15 +414,12 @@ public class SysTenantServiceImpl implements ISysTenantService {
dictTypeList.addAll(dictTypeMapper.selectList()); dictTypeList.addAll(dictTypeMapper.selectList());
dictDataList.addAll(dictDataMapper.selectList()); dictDataList.addAll(dictDataMapper.selectList());
}); });
// 所有租户字典类型 Map<String, List<SysDictType>> typeMap = StreamUtils.groupByKey(dictTypeList, TenantEntity::getTenantId);
Map<String, List<SysDictType>> dictTypeMap = StreamUtils.groupByKey(dictTypeList, TenantEntity::getTenantId); Map<String, Map<String, List<SysDictData>>> typeDataMap = StreamUtils.groupBy2Key(
// 所有租户字典数据 dictDataList, TenantEntity::getTenantId, SysDictData::getDictType);
Map<String, Map<String, List<SysDictData>>> dictDataMap = StreamUtils.groupBy2Key(dictDataList, TenantEntity::getTenantId, SysDictData::getDictType); // 管理租户字典数据
List<SysDictType> defaultTypeMap = typeMap.get(TenantConstants.DEFAULT_TENANT_ID);
// 默认租户字典类型列表 Map<String, List<SysDictData>> defaultTypeDataMap = typeDataMap.get(TenantConstants.DEFAULT_TENANT_ID);
List<SysDictType> defaultDictTypeList = dictTypeMap.get(TenantConstants.DEFAULT_TENANT_ID);
// 默认租户字典数据
Map<String, List<SysDictData>> defaultDictDataMap = dictDataMap.get(TenantConstants.DEFAULT_TENANT_ID);
// 获取所有租户编号 // 获取所有租户编号
List<String> tenantIds = baseMapper.selectObjs( List<String> tenantIds = baseMapper.selectObjs(
@@ -430,67 +427,57 @@ public class SysTenantServiceImpl implements ISysTenantService {
.eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> { .eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> {
return Convert.toStr(x); return Convert.toStr(x);
}); });
// 待入库的字典类型和字典数据
List<SysDictType> saveTypeList = new ArrayList<>(); List<SysDictType> saveTypeList = new ArrayList<>();
List<SysDictData> saveDataList = new ArrayList<>(); List<SysDictData> saveDataList = new ArrayList<>();
// 待同步的租户编号(用于清除对于租户的字典缓存) Set<String> set = new HashSet<>();
Set<String> syncTenantIds = new HashSet<>();
// 循环所有租户,处理需要同步的数据
for (String tenantId : tenantIds) { for (String tenantId : tenantIds) {
// 排除默认租户
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
continue; continue;
} }
// 根据默认租户的字典类型进行数据同步 for (SysDictType dictType : defaultTypeMap) {
for (SysDictType dictType : defaultDictTypeList) { List<String> typeList = StreamUtils.toList(typeMap.get(tenantId), SysDictType::getDictType);
// 获取当前租户的字典类型列表 List<SysDictData> dataList = defaultTypeDataMap.get(dictType.getDictType());
List<String> typeList = StreamUtils.toList(dictTypeMap.get(tenantId), SysDictType::getDictType);
// 根据字典类型获取默认租户的字典数据
List<SysDictData> defaultDictDataList = defaultDictDataMap.get(dictType.getDictType());
// 排除不需要同步的字典数据
Set<String> excludeDictDataSet = CollUtil.newHashSet();
// 处理 存在type不存在data 的情况
if (typeList.contains(dictType.getDictType())) { if (typeList.contains(dictType.getDictType())) {
// 获取租户字典数据 List<SysDictData> dataListTenant = typeDataMap.get(tenantId).get(dictType.getDictType());
Optional.ofNullable(dictDataMap.get(tenantId)) Map<String, SysDictData> map = StreamUtils.toIdentityMap(dataListTenant, SysDictData::getDictValue);
// 获取租户当前字典类型的字典数据 for (SysDictData dictData : dataList) {
.map(tenantDictDataMap -> tenantDictDataMap.get(dictType.getDictType())) if (!map.containsKey(dictData.getDictValue())) {
// 保存字典数据项的字典键值,用于判断数据是否需要同步 SysDictData data = BeanUtil.toBean(dictData, SysDictData.class);
.map(data -> StreamUtils.toSet(data, SysDictData::getDictValue)) // 设置字典编码为 null
// 添加到排除集合中 data.setDictCode(null);
.ifPresent(excludeDictDataSet::addAll); data.setTenantId(tenantId);
data.setCreateTime(null);
data.setUpdateTime(null);
data.setCreateDept(null);
data.setCreateBy(null);
data.setUpdateBy(null);
set.add(tenantId);
saveDataList.add(data);
}
}
} else { } else {
// 同步字典类型
SysDictType type = BeanUtil.toBean(dictType, SysDictType.class); SysDictType type = BeanUtil.toBean(dictType, SysDictType.class);
type.setDictId(null); type.setDictId(null);
type.setTenantId(tenantId); type.setTenantId(tenantId);
type.setCreateTime(null); type.setCreateTime(null);
type.setUpdateTime(null); type.setUpdateTime(null);
syncTenantIds.add(tenantId); set.add(tenantId);
saveTypeList.add(type); saveTypeList.add(type);
} if (CollUtil.isNotEmpty(dataList)) {
// 筛选出 dictType 对应的 data
// 默认租户字典数据不为空再去处理 for (SysDictData dictData : dataList) {
if (CollUtil.isNotEmpty(defaultDictDataList)) { SysDictData data = BeanUtil.toBean(dictData, SysDictData.class);
// 提前优化排除判断if条件语句对于 && 并联条件,该优化可以避免不必要的 excludeDictDataSet.contains() 函数调用 // 设置字典编码为 null
boolean isExclude = CollUtil.isNotEmpty(excludeDictDataSet); data.setDictCode(null);
// 筛选出 dictType 对应的 data data.setTenantId(tenantId);
for (SysDictData dictData : defaultDictDataList) { data.setCreateTime(null);
// 排除不需要同步的字典数据 data.setUpdateTime(null);
if (isExclude && excludeDictDataSet.contains(dictData.getDictValue())) { data.setCreateDept(null);
continue; data.setCreateBy(null);
data.setUpdateBy(null);
set.add(tenantId);
saveDataList.add(data);
} }
SysDictData data = BeanUtil.toBean(dictData, SysDictData.class);
// 设置字典编码为 null
data.setDictCode(null);
data.setTenantId(tenantId);
data.setCreateTime(null);
data.setUpdateTime(null);
data.setCreateDept(null);
data.setCreateBy(null);
data.setUpdateBy(null);
syncTenantIds.add(tenantId);
saveDataList.add(data);
} }
} }
} }
@@ -503,7 +490,7 @@ public class SysTenantServiceImpl implements ISysTenantService {
dictDataMapper.insertBatch(saveDataList); dictDataMapper.insertBatch(saveDataList);
} }
}); });
for (String tenantId : syncTenantIds) { for (String tenantId : set) {
TenantHelper.dynamic(tenantId, () -> CacheUtils.clear(CacheNames.SYS_DICT)); TenantHelper.dynamic(tenantId, () -> CacheUtils.clear(CacheNames.SYS_DICT));
} }
} }

View File

@@ -22,9 +22,7 @@ import org.dromara.common.core.utils.*;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUser; import org.dromara.system.domain.*;
import org.dromara.system.domain.SysUserPost;
import org.dromara.system.domain.SysUserRole;
import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysPostVo; import org.dromara.system.domain.vo.SysPostVo;
import org.dromara.system.domain.vo.SysRoleVo; import org.dromara.system.domain.vo.SysRoleVo;
@@ -38,6 +36,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* 用户 业务层处理 * 用户 业务层处理
@@ -70,9 +69,15 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
*/ */
@Override @Override
public List<SysUserExportVo> selectUserExportList(SysUserBo user) { public List<SysUserExportVo> selectUserExportList(SysUserBo user) {
return baseMapper.selectUserExportList(this.buildQueryWrapper(user));
}
private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
Map<String, Object> params = user.getParams(); Map<String, Object> params = user.getParams();
QueryWrapper<SysUser> wrapper = Wrappers.query(); QueryWrapper<SysUser> wrapper = Wrappers.query();
wrapper.eq("u.del_flag", SystemConstants.NORMAL) wrapper.eq("u.del_flag", SystemConstants.NORMAL)
.eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
.in(StringUtils.isNotBlank(user.getUserIds()), "u.user_id", StringUtils.splitTo(user.getUserIds(), Convert::toLong))
.like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
.like(StringUtils.isNotBlank(user.getNickName()), "u.nick_name", user.getNickName()) .like(StringUtils.isNotBlank(user.getNickName()), "u.nick_name", user.getNickName())
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
@@ -80,30 +85,13 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
.between(params.get("beginTime") != null && params.get("endTime") != null, .between(params.get("beginTime") != null && params.get("endTime") != null,
"u.create_time", params.get("beginTime"), params.get("endTime")) "u.create_time", params.get("beginTime"), params.get("endTime"))
.and(ObjectUtil.isNotNull(user.getDeptId()), w -> { .and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
List<Long> deptIds = deptMapper.selectDeptAndChildById(user.getDeptId()); List<SysDept> deptList = deptMapper.selectListByParentId(user.getDeptId());
w.in("u.dept_id", deptIds); List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
ids.add(user.getDeptId());
w.in("u.dept_id", ids);
}).orderByAsc("u.user_id"); }).orderByAsc("u.user_id");
return baseMapper.selectUserExportList(wrapper);
}
private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
Map<String, Object> params = user.getParams();
LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery();
wrapper.eq(SysUser::getDelFlag, SystemConstants.NORMAL)
.eq(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())
.in(StringUtils.isNotBlank(user.getUserIds()), SysUser::getUserId, StringUtils.splitTo(user.getUserIds(), Convert::toLong))
.like(StringUtils.isNotBlank(user.getUserName()), SysUser::getUserName, user.getUserName())
.like(StringUtils.isNotBlank(user.getNickName()), SysUser::getNickName, user.getNickName())
.eq(StringUtils.isNotBlank(user.getStatus()), SysUser::getStatus, user.getStatus())
.like(StringUtils.isNotBlank(user.getPhonenumber()), SysUser::getPhonenumber, user.getPhonenumber())
.between(params.get("beginTime") != null && params.get("endTime") != null,
SysUser::getCreateTime, params.get("beginTime"), params.get("endTime"))
.and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
List<Long> ids = deptMapper.selectDeptAndChildById(user.getDeptId());
w.in(SysUser::getDeptId, ids);
}).orderByAsc(SysUser::getUserId);
if (StringUtils.isNotBlank(user.getExcludeUserIds())) { if (StringUtils.isNotBlank(user.getExcludeUserIds())) {
wrapper.notIn(SysUser::getUserId, StringUtils.splitList(user.getExcludeUserIds())); wrapper.notIn("u.user_id", StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong));
} }
return wrapper; return wrapper;
} }
@@ -451,31 +439,21 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
* @param clear 清除已存在的关联数据 * @param clear 清除已存在的关联数据
*/ */
private void insertUserPost(SysUserBo user, boolean clear) { private void insertUserPost(SysUserBo user, boolean clear) {
Long[] postIdArr = user.getPostIds(); Long[] posts = user.getPostIds();
if (ArrayUtil.isEmpty(postIdArr)) { if (ArrayUtil.isNotEmpty(posts)) {
return; if (clear) {
} // 删除用户与岗位关联
List<Long> postIds = Arrays.asList(postIdArr); userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
}
// 校验是否有权限操作这些岗位(含数据权限控制) // 新增用户与岗位管理
if (postMapper.selectPostCount(postIds) != postIds.size()) { List<SysUserPost> list = StreamUtils.toList(List.of(posts), postId -> {
throw new ServiceException("没有权限访问岗位的数据");
}
// 是否清除旧的用户岗位绑定
if (clear) {
userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
}
// 构建用户岗位关联列表并批量插入
List<SysUserPost> list = StreamUtils.toList(postIds,
postId -> {
SysUserPost up = new SysUserPost(); SysUserPost up = new SysUserPost();
up.setUserId(user.getUserId()); up.setUserId(user.getUserId());
up.setPostId(postId); up.setPostId(postId);
return up; return up;
}); });
userPostMapper.insertBatch(list); userPostMapper.insertBatch(list);
}
} }
/** /**
@@ -486,36 +464,30 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
* @param clear 清除已存在的关联数据 * @param clear 清除已存在的关联数据
*/ */
private void insertUserRole(Long userId, Long[] roleIds, boolean clear) { private void insertUserRole(Long userId, Long[] roleIds, boolean clear) {
if (ArrayUtil.isEmpty(roleIds)) { if (ArrayUtil.isNotEmpty(roleIds)) {
return; List<Long> roleList = new ArrayList<>(List.of(roleIds));
} if (!LoginHelper.isSuperAdmin(userId)) {
roleList.remove(SystemConstants.SUPER_ADMIN_ID);
List<Long> roleList = new ArrayList<>(Arrays.asList(roleIds)); }
// 判断是否具有此角色的操作权限
// 非超级管理员,禁止包含超级管理员角色 List<SysRoleVo> roles = roleMapper.selectRoleList(
if (!LoginHelper.isSuperAdmin(userId)) { new QueryWrapper<SysRole>().in("r.role_id", roleList));
roleList.remove(SystemConstants.SUPER_ADMIN_ID); if (CollUtil.isEmpty(roles)) {
} throw new ServiceException("没有权限访问角色的数据");
}
// 校验是否有权限访问这些角色(含数据权限控制) if (clear) {
if (roleMapper.selectRoleCount(roleList) != roleList.size()) { // 删除用户与角色关联
throw new ServiceException("没有权限访问角色的数据"); userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
} }
// 新增用户与角色管理
// 是否清除原有绑定 List<SysUserRole> list = StreamUtils.toList(roleList, roleId -> {
if (clear) {
userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
}
// 批量插入用户-角色关联
List<SysUserRole> list = StreamUtils.toList(roleList,
roleId -> {
SysUserRole ur = new SysUserRole(); SysUserRole ur = new SysUserRole();
ur.setUserId(userId); ur.setUserId(userId);
ur.setRoleId(roleId); ur.setRoleId(roleId);
return ur; return ur;
}); });
userRoleMapper.insertBatch(list); userRoleMapper.insertBatch(list);
}
} }
/** /**
@@ -663,10 +635,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
return List.of(); return List.of();
} }
List<SysUserVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>() List<SysUserVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserId, SysUser::getDeptId, SysUser::getUserName, .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber)
SysUser::getNickName, SysUser::getUserType, SysUser::getEmail,
SysUser::getPhonenumber, SysUser::getSex, SysUser::getStatus,
SysUser::getCreateTime)
.eq(SysUser::getStatus, SystemConstants.NORMAL) .eq(SysUser::getStatus, SystemConstants.NORMAL)
.in(SysUser::getUserId, userIds)); .in(SysUser::getUserId, userIds));
return BeanUtil.copyToList(list, UserDTO.class); return BeanUtil.copyToList(list, UserDTO.class);
@@ -707,7 +676,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
// 获取用户ID列表 // 获取用户ID列表
Set<Long> userIds = StreamUtils.toSet(userRoles, SysUserRole::getUserId); Set<Long> userIds = StreamUtils.toSet(userRoles, SysUserRole::getUserId);
return this.selectListByIds(new ArrayList<>(userIds)); return selectListByIds(new ArrayList<>(userIds));
} }
/** /**
@@ -747,7 +716,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
// 获取用户ID列表 // 获取用户ID列表
Set<Long> userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId); Set<Long> userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId);
return this.selectListByIds(new ArrayList<>(userIds)); return selectListByIds(new ArrayList<>(userIds));
} }
/** /**
@@ -761,12 +730,69 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
if (CollUtil.isEmpty(userIds)) { if (CollUtil.isEmpty(userIds)) {
return Collections.emptyMap(); return Collections.emptyMap();
} }
List<SysUser> list = baseMapper.selectList( return baseMapper.selectList(
new LambdaQueryWrapper<SysUser>() new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserId, SysUser::getNickName) .select(SysUser::getUserId, SysUser::getNickName)
.in(SysUser::getUserId, userIds) .in(SysUser::getUserId, userIds)
); ).stream()
return StreamUtils.toMap(list, SysUser::getUserId, SysUser::getNickName); .collect(Collectors.toMap(SysUser::getUserId, SysUser::getNickName));
}
/**
* 根据角色 ID 列表查询角色名称映射关系
*
* @param roleIds 角色 ID 列表
* @return Map其中 key 为角色 IDvalue 为对应的角色名称
*/
@Override
public Map<Long, String> selectRoleNamesByIds(List<Long> roleIds) {
if (CollUtil.isEmpty(roleIds)) {
return Collections.emptyMap();
}
return roleMapper.selectList(
new LambdaQueryWrapper<SysRole>()
.select(SysRole::getRoleId, SysRole::getRoleName)
.in(SysRole::getRoleId, roleIds)
).stream()
.collect(Collectors.toMap(SysRole::getRoleId, SysRole::getRoleName));
}
/**
* 根据部门 ID 列表查询部门名称映射关系
*
* @param deptIds 部门 ID 列表
* @return Map其中 key 为部门 IDvalue 为对应的部门名称
*/
@Override
public Map<Long, String> selectDeptNamesByIds(List<Long> deptIds) {
if (CollUtil.isEmpty(deptIds)) {
return Collections.emptyMap();
}
return deptMapper.selectList(
new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptId, SysDept::getDeptName)
.in(SysDept::getDeptId, deptIds)
).stream()
.collect(Collectors.toMap(SysDept::getDeptId, SysDept::getDeptName));
}
/**
* 根据岗位 ID 列表查询岗位名称映射关系
*
* @param postIds 岗位 ID 列表
* @return Map其中 key 为岗位 IDvalue 为对应的岗位名称
*/
@Override
public Map<Long, String> selectPostNamesByIds(List<Long> postIds) {
if (CollUtil.isEmpty(postIds)) {
return Collections.emptyMap();
}
return postMapper.selectList(
new LambdaQueryWrapper<SysPost>()
.select(SysPost::getPostId, SysPost::getPostName)
.in(SysPost::getPostId, postIds)
).stream()
.collect(Collectors.toMap(SysPost::getPostId, SysPost::getPostName));
} }
} }

View File

@@ -4,4 +4,44 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.system.mapper.SysDeptMapper"> <mapper namespace="org.dromara.system.mapper.SysDeptMapper">
<resultMap type="org.dromara.system.domain.vo.SysDeptVo" id="SysDeptResult">
</resultMap>
<select id="selectDeptList" resultMap="SysDeptResult">
select
<if test="ew.getSqlSelect != null">
${ew.getSqlSelect}
</if>
<if test="ew.getSqlSelect == null">
*
</if>
from sys_dept ${ew.getCustomSqlSegment}
</select>
<select id="selectPageDeptList" resultMap="SysDeptResult">
select
<if test="ew.getSqlSelect != null">
${ew.getSqlSelect}
</if>
<if test="ew.getSqlSelect == null">
*
</if>
from sys_dept ${ew.getCustomSqlSegment}
</select>
<select id="countDeptById" resultType="Long">
select count(*) from sys_dept where del_flag = '0' and dept_id = #{deptId}
</select>
<select id="selectDeptListByRoleId" resultType="Long">
select d.dept_id
from sys_dept d
left join sys_role_dept rd on d.dept_id = rd.dept_id
where rd.role_id = #{roleId}
<if test="deptCheckStrictly">
and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = #{roleId})
</if>
order by d.parent_id, d.order_num
</select>
</mapper> </mapper>

View File

@@ -4,4 +4,67 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.system.mapper.SysMenuMapper"> <mapper namespace="org.dromara.system.mapper.SysMenuMapper">
<resultMap type="org.dromara.system.domain.SysMenu" id="SysMenuResult">
</resultMap>
<select id="selectMenuListByUserId" resultMap="SysMenuResult">
select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.query_param, m.visible, m.status,
m.perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_role r on rm.role_id = r.role_id
${ew.getCustomSqlSegment}
</select>
<select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult">
select distinct m.menu_id,
m.parent_id,
m.menu_name,
m.path,
m.component,
m.query_param,
m.visible,
m.status,
m.perms,
m.is_frame,
m.is_cache,
m.menu_type,
m.icon,
m.order_num,
m.create_time
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id and m.status = '0'
left join sys_role r on rm.role_id = r.role_id and r.status = '0'
where m.menu_type in ('M', 'C')
and r.role_id in (select role_id from sys_user_role where user_id = #{userId})
order by m.parent_id, m.order_num
</select>
<select id="selectMenuListByRoleId" resultType="Long">
select m.menu_id
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where rm.role_id = #{roleId}
<if test="menuCheckStrictly">
and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id =
rm.menu_id and rm.role_id = #{roleId})
</if>
order by m.parent_id, m.order_num
</select>
<select id="selectMenuPermsByUserId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id and m.status = '0'
left join sys_role r on r.role_id = rm.role_id and r.status = '0'
where r.role_id in (select role_id from sys_user_role where user_id = #{userId})
</select>
<select id="selectMenuPermsByRoleId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where m.status = '0' and rm.role_id = #{roleId}
</select>
</mapper> </mapper>

View File

@@ -4,4 +4,26 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.system.mapper.SysPostMapper"> <mapper namespace="org.dromara.system.mapper.SysPostMapper">
<resultMap type="org.dromara.system.domain.vo.SysPostVo" id="SysPostResult">
</resultMap>
<select id="selectPagePostList" resultMap="SysPostResult">
select
<if test="ew.getSqlSelect != null">
${ew.getSqlSelect}
</if>
<if test="ew.getSqlSelect == null">
*
</if>
from sys_post ${ew.getCustomSqlSegment}
</select>
<select id="selectPostsByUserId" parameterType="Long" resultMap="SysPostResult">
select p.post_id, p.dept_id, p.post_name, p.post_code, p.post_category
from sys_post p
left join sys_user_post up on up.post_id = p.post_id
left join sys_user u on u.user_id = up.user_id
where u.user_id = #{userId}
</select>
</mapper> </mapper>

Some files were not shown because too many files have changed in this diff Show More