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
106 changed files with 824 additions and 1265 deletions

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<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="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
</settings>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<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="sourceFilePath" value="ruoyi-admin/Dockerfile" />
</settings>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<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="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" />
</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)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
<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)]()
[![JDK-17](https://img.shields.io/badge/JDK-17-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>
<properties>
<revision>5.4.1</revision>
<spring-boot.version>3.4.7</spring-boot.version>
<revision>5.4.0</revision>
<spring-boot.version>3.4.6</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
@@ -23,12 +23,12 @@
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
<fastexcel.version>1.2.0</fastexcel.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>
<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>
<redisson.version>3.50.0</redisson.version>
<redisson.version>3.45.1</redisson.version>
<lock4j.version>2.2.7</lock4j.version>
<dynamic-ds.version>4.3.1</dynamic-ds.version>
<snailjob.version>1.5.0</snailjob.version>
@@ -39,6 +39,7 @@
<justauth.version>1.16.7</justauth.version>
<!-- 离线IP地址定位库 -->
<ip2region.version>2.7.0</ip2region.version>
<!-- OSS 配置 -->
<aws.sdk.version>2.28.22</aws.sdk.version>
<!-- SMS 配置 -->
@@ -46,15 +47,15 @@
<!-- 限制框架中的fastjson版本 -->
<fastjson.version>1.2.83</fastjson.version>
<!-- 面向运行时的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-war-plugin.version>3.4.0</maven-war-plugin.version>
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
<!-- 打包默认跳过测试 -->
<skipTests>true</skipTests>

View File

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

View File

@@ -158,6 +158,6 @@ public class UserActionListener implements SaTokenListener {
* 每次Token续期时触发
*/
@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.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthResponse;
@@ -65,6 +68,15 @@ public class SocialAuthStrategy implements IAuthStrategy {
throw new ServiceException(response.getMsg());
}
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());
if (CollUtil.isEmpty(list)) {

View File

@@ -183,7 +183,7 @@ springdoc:
# 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本
version: '版本号: ${project.version}'
version: '版本号: ${ruoyi.version}'
# 作者信息
contact:
name: Lion Li

View File

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

View File

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

View File

@@ -3,7 +3,6 @@ package org.dromara.common.core.service;
import org.dromara.common.core.domain.dto.DeptDTO;
import java.util.List;
import java.util.Map;
/**
* 通用 部门服务
@@ -35,12 +34,4 @@ public interface DeptService {
*/
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;
import java.util.List;
import java.util.Map;
/**
* 通用 岗位服务
*
@@ -10,12 +7,4 @@ import java.util.Map;
*/
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;
import java.util.List;
import java.util.Map;
/**
* 通用 角色服务
*
@@ -10,12 +7,4 @@ import java.util.Map;
*/
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);
/**
* 根据角色 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 java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -62,31 +60,6 @@ public class TreeBuildUtils extends TreeUtil {
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)
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) {
// 处理空串并过滤HTML标签
ip = HtmlUtil.cleanHtmlTag(StringUtils.blankToDefault(ip,""));
// 判断是否为IPv4
if (NetUtils.isIPv4(ip)) {
return resolverIPv4Region(ip);
boolean isIPv6 = NetUtils.isIPv6(ip);
// 判断是否为IPv4或IPv6如果不是则返回未知地址
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)) {
return LOCAL_ADDRESS;
if (NetUtils.isInnerIPv6(ip) || NetUtils.isInnerIP(ip)) {
return "内网IP";
}
// 不支持IPv6不再进行没有必要的IP地址信息的解析直接返回
if (isIPv6) {
log.warn("ip2region不支持IPV6地址解析{}", ip);
// 如有需要可自行实现IPv6地址信息解析逻辑并在这里返回
return "未知";
}
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

@@ -5,7 +5,6 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.dromara.common.core.utils.StringUtils;
@@ -40,23 +39,12 @@ public class MybatisDecryptInterceptor implements Interceptor {
@Override
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执行结果
Object result = invocation.proceed();
if (result == null) {
return null;
}
this.decryptHandler(result);
decryptHandler(result);
return result;
}

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
package org.dromara.common.excel.handler;
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.WriteCellData;
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.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.excel.annotation.ExcelNotation;
import org.dromara.common.excel.annotation.ExcelRequired;
@@ -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) {
@@ -49,16 +49,15 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
if (CollUtil.isEmpty(notationMap) && CollUtil.isEmpty(headColumnMap)) {
return;
}
// 第一行
WriteCellData<?> cellData = context.getFirstCellData();
// 第一个格子
WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
DataFormatData dataFormatData = new DataFormatData();
// 单元格设置为文本格式
dataFormatData.setIndex((short) 49);
writeCellStyle.setDataFormatData(dataFormatData);
if (context.getHead()) {
DataFormatData dataFormatData = new DataFormatData();
// 单元格设置为文本格式
dataFormatData.setIndex((short) 49);
writeCellStyle.setDataFormatData(dataFormatData);
Cell cell = context.getCell();
WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
Sheet sheet = writeSheetHolder.getSheet();
@@ -68,17 +67,17 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
WriteFont headWriteFont = new WriteFont();
// 加粗
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);
CellStyle cellStyle = StyleUtil.buildCellStyle(workbook, null, writeCellStyle);
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.setString(new XSSFRichTextString(notationContext));
@@ -90,16 +89,23 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
/**
* 获取必填列
*/
private static Map<String, Short> getRequiredMap(Class<?> clazz) {
Map<String, Short> requiredMap = new HashMap<>();
private static Map<Integer, Short> getRequiredMap(Class<?> clazz) {
Map<Integer, Short> requiredMap = new HashMap<>();
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)) {
continue;
}
ExcelRequired excelRequired = field.getAnnotation(ExcelRequired.class);
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
requiredMap.put(excelProperty.value()[0], excelRequired.fontColor().getIndex());
int columnIndex = excelRequired.index() == -1 ? i : excelRequired.index();
requiredMap.put(columnIndex, excelRequired.fontColor().getIndex());
}
return requiredMap;
}
@@ -107,16 +113,22 @@ public class DataWriteHandler implements SheetWriteHandler, CellWriteHandler {
/**
* 获取批注
*/
private static Map<String, String> getNotationMap(Class<?> clazz) {
Map<String, String> notationMap = new HashMap<>();
private static Map<Integer, String> getNotationMap(Class<?> clazz) {
Map<Integer, String> notationMap = new HashMap<>();
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)) {
continue;
}
ExcelNotation excelNotation = field.getAnnotation(ExcelNotation.class);
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
notationMap.put(excelProperty.value()[0], excelNotation.value());
int columnIndex = excelNotation.index() == -1 ? i : excelNotation.index();
notationMap.put(columnIndex, excelNotation.value());
}
return notationMap;
}

View File

@@ -22,11 +22,6 @@ import java.util.Date;
@Slf4j
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.setUpdateBy(userId);
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 {
@@ -84,8 +74,6 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler {
Long userId = LoginHelper.getUserId();
if (ObjectUtil.isNotNull(userId)) {
baseEntity.setUpdateBy(userId);
} else {
baseEntity.setUpdateBy(DEFAULT_USER_ID);
}
} else {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
@@ -105,6 +93,7 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler {
try {
loginUser = LoginHelper.getLoginUser();
} catch (Exception e) {
log.warn("自动注入警告 => 用户未登录");
return null;
}
return loginUser;

View File

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

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

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

View File

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

View File

@@ -1,12 +1,9 @@
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.interceptor.PlusWebInvokeTimeInterceptor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
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.WebMvcConfigurer;
import java.util.Date;
/**
* 通用配置
*
@@ -30,17 +25,6 @@ public class ResourcesConfig implements WebMvcConfigurer {
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
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}

View File

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

View File

@@ -1,6 +1,6 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
#FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
#FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li"
@@ -9,7 +9,7 @@ RUN mkdir -p /ruoyi/snailjob/logs
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 17888

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -59,9 +59,4 @@ public class TestDemoBo extends BaseEntity {
@NotBlank(message = "值不能为空", groups = {AddGroup.class, EditGroup.class})
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.ExcelProperty;
import cn.idev.excel.annotation.format.DateTimeFormat;
import org.dromara.common.excel.annotation.ExcelNotation;
import org.dromara.common.excel.annotation.ExcelRequired;
import org.dromara.common.translation.annotation.Translation;
@@ -47,7 +46,7 @@ public class TestDemoVo implements Serializable {
* 用户id
*/
@ExcelRequired
@ExcelProperty(value = "用户id", index = 5)
@ExcelProperty(value = "用户id")
private Long userId;
/**
@@ -74,8 +73,6 @@ public class TestDemoVo implements Serializable {
/**
* 创建时间
*/
@ExcelRequired
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "创建时间")
private Date createTime;
@@ -111,9 +108,4 @@ public class TestDemoVo implements Serializable {
@ExcelProperty(value = "更新人账号")
private String updateByName;
/**
* 版本
*/
private Long version;
}

View File

@@ -3,21 +3,21 @@ package org.dromara.generator.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
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.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.GenTableColumn;
import org.dromara.generator.service.IGenTableService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@@ -80,8 +80,11 @@ public class GenController extends BaseController {
@SaCheckPermission("tool:gen:list")
@GetMapping(value = "/column/{tableId}")
public TableDataInfo<GenTableColumn> columnList(@PathVariable("tableId") Long tableId) {
TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>();
List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
return TableDataInfo.build(list);
dataInfo.setRows(list);
dataInfo.setTotal(list.size());
return dataInfo;
}
/**

View File

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

View File

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

View File

@@ -1,8 +1,6 @@
package org.dromara.system.controller.system;
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.excel.utils.ExcelUtil;
import org.dromara.common.log.annotation.Log;
@@ -13,10 +11,11 @@ import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.bo.SysConfigBo;
import org.dromara.system.domain.vo.SysConfigVo;
import org.dromara.system.service.ISysConfigService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
@@ -121,7 +120,7 @@ public class SysConfigController extends BaseController {
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}")
public R<Void> remove(@PathVariable Long[] configIds) {
configService.deleteConfigByIds(Arrays.asList(configIds));
configService.deleteConfigByIds(configIds);
return R.ok();
}

View File

@@ -113,9 +113,6 @@ public class SysDeptController extends BaseController {
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}")
public R<Void> remove(@PathVariable Long deptId) {
if (SystemConstants.DEFAULT_DEPT_ID.equals(deptId)) {
return R.warn("默认部门,不允许删除");
}
if (deptService.hasChildByDeptId(deptId)) {
return R.warn("存在下级部门,不允许删除");
}

View File

@@ -2,24 +2,23 @@ package org.dromara.system.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.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.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.vo.SysDictDataVo;
import org.dromara.system.service.ISysDictDataService;
import org.dromara.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -118,7 +117,7 @@ public class SysDictDataController extends BaseController {
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public R<Void> remove(@PathVariable Long[] dictCodes) {
dictDataService.deleteDictDataByIds(Arrays.asList(dictCodes));
dictDataService.deleteDictDataByIds(dictCodes);
return R.ok();
}
}

View File

@@ -1,8 +1,6 @@
package org.dromara.system.controller.system;
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.excel.utils.ExcelUtil;
import org.dromara.common.log.annotation.Log;
@@ -13,10 +11,11 @@ import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.bo.SysDictTypeBo;
import org.dromara.system.domain.vo.SysDictTypeVo;
import org.dromara.system.service.ISysDictTypeService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
@@ -100,7 +99,7 @@ public class SysDictTypeController extends BaseController {
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}")
public R<Void> remove(@PathVariable Long[] dictIds) {
dictTypeService.deleteDictTypeByIds(Arrays.asList(dictIds));
dictTypeService.deleteDictTypeByIds(dictIds);
return R.ok();
}

View File

@@ -21,7 +21,6 @@ import org.dromara.system.service.ISysMenuService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
@@ -112,14 +111,9 @@ public class SysMenuController extends BaseController {
@GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
List<Tree<Long>> list = menuService.buildMenuTreeSelect(menus);
// 删除租户管理菜单
list.removeIf(menu -> menu.getId() == 6L);
List<Long> ids = new ArrayList<>();
if (packageId > 0L) {
ids = menuService.selectMenuListByPackageId(packageId);
}
MenuTreeSelectVo selectVo = new MenuTreeSelectVo(ids, list);
MenuTreeSelectVo selectVo = new MenuTreeSelectVo(
menuService.selectMenuListByPackageId(packageId),
menuService.buildMenuTreeSelect(menus));
return R.ok(selectVo);
}

View File

@@ -19,7 +19,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -108,7 +107,7 @@ public class SysPostController extends BaseController {
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}")
public R<Void> remove(@PathVariable Long[] postIds) {
return toAjax(postService.deletePostByIds(Arrays.asList(postIds)));
return toAjax(postService.deletePostByIds(postIds));
}
/**

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

@@ -2,9 +2,9 @@ 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.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -30,23 +30,18 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
@DataPermission({
@DataColumn(key = "deptName", value = "dept_id")
})
default List<SysDeptVo> selectDeptList(Wrapper<SysDept> queryWrapper) {
return this.selectVoList(queryWrapper);
}
List<SysDeptVo> selectDeptList(@Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
/**
* 分页查询部门管理数据
*
* @param page 分页信息
* @param queryWrapper 查询条件
* @return 部门信息集合
*/
@DataPermission({
@DataColumn(key = "deptName", value = "dept_id"),
})
default Page<SysDeptVo> selectPageDeptList(Page<SysDept> page, Wrapper<SysDept> queryWrapper) {
return this.selectVoPage(page, queryWrapper);
}
Page<SysDeptVo> selectPageDeptList(@Param("page") Page<SysDeptVo> page, @Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
/**
* 统计指定部门ID的部门数量
@@ -57,9 +52,7 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
@DataPermission({
@DataColumn(key = "deptName", value = "dept_id")
})
default long countDeptById(Long deptId) {
return this.selectCount(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptId, deptId));
}
long countDeptById(Long deptId);
/**
* 根据父部门ID查询其所有子部门的列表
@@ -73,19 +66,6 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
.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查询部门树信息
*

View File

@@ -1,7 +1,9 @@
package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
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.DataPermission;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -28,9 +30,7 @@ public interface SysPostMapper extends BaseMapperPlus<SysPost, SysPostVo> {
@DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by")
})
default Page<SysPostVo> selectPagePostList(Page<SysPost> page, Wrapper<SysPost> queryWrapper) {
return this.selectVoPage(page, queryWrapper);
}
Page<SysPostVo> selectPagePostList(@Param("page") Page<SysPostVo> page, @Param(Constants.WRAPPER) Wrapper<SysPost> queryWrapper);
/**
* 查询用户所属岗位组

View File

@@ -16,11 +16,12 @@ public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenu, SysRoleMe
/**
* 根据菜单ID串删除关联关系
*
* @param menuIds 菜单ID串
* @return 结果
*/
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;
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 org.apache.ibatis.annotations.Param;
@@ -29,12 +28,10 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
* @return 分页的用户信息
*/
@DataPermission({
@DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "user_id")
@DataColumn(key = "deptName", value = "u.dept_id"),
@DataColumn(key = "userName", value = "u.user_id")
})
default Page<SysUserVo> selectPageUserList(Page<SysUser> page, Wrapper<SysUser> queryWrapper) {
return this.selectVoPage(page, queryWrapper);
}
Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/**
* 查询用户列表,并进行数据权限控制
@@ -46,9 +43,7 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
@DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "user_id")
})
default List<SysUserVo> selectUserList(Wrapper<SysUser> queryWrapper) {
return this.selectVoList(queryWrapper);
}
List<SysUserVo> selectUserList(@Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
/**
* 根据条件分页查询用户列表
@@ -65,7 +60,6 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
/**
* 根据条件分页查询已配用户角色列表
*
* @param page 分页信息
* @param queryWrapper 查询条件
* @return 用户信息集合信息
*/
@@ -97,9 +91,7 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
@DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "user_id")
})
default long countUserById(Long userId) {
return this.selectCount(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId, userId));
}
long countUserById(Long userId);
/**
* 根据条件更新用户数据

View File

@@ -69,7 +69,7 @@ public interface ISysConfigService {
*
* @param configIds 需要删除的参数ID
*/
void deleteConfigByIds(List<Long> configIds);
void deleteConfigByIds(Long[] configIds);
/**
* 重置参数缓存数据

View File

@@ -47,7 +47,7 @@ public interface ISysDictDataService {
*
* @param dictCodes 需要删除的字典数据ID
*/
void deleteDictDataByIds(List<Long> dictCodes);
void deleteDictDataByIds(Long[] dictCodes);
/**
* 新增保存字典数据信息

View File

@@ -62,7 +62,7 @@ public interface ISysDictTypeService {
*
* @param dictIds 需要删除的字典ID
*/
void deleteDictTypeByIds(List<Long> dictIds);
void deleteDictTypeByIds(Long[] dictIds);
/**
* 重置字典缓存数据

View File

@@ -110,7 +110,7 @@ public interface ISysPostService {
* @param postIds 需要删除的岗位ID
* @return 结果
*/
int deletePostByIds(List<Long> postIds);
int deletePostByIds(Long[] postIds);
/**
* 新增保存岗位信息

View File

@@ -1,6 +1,5 @@
package org.dromara.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -44,10 +43,11 @@ public class SysClientServiceImpl implements ISysClientService {
@Override
public SysClientVo queryById(Long id) {
SysClientVo vo = baseMapper.selectVoById(id);
vo.setGrantTypeList(StringUtils.splitList(vo.getGrantType()));
vo.setGrantTypeList(List.of(vo.getGrantType().split(",")));
return vo;
}
/**
* 查询客户端管理
*/
@@ -64,7 +64,7 @@ public class SysClientServiceImpl implements ISysClientService {
public TableDataInfo<SysClientVo> queryPageList(SysClientBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysClient> lqw = buildQueryWrapper(bo);
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);
}
@@ -93,7 +93,8 @@ public class SysClientServiceImpl implements ISysClientService {
@Override
public Boolean insertByBo(SysClientBo bo) {
SysClient add = MapstructUtils.convert(bo, SysClient.class);
add.setGrantType(CollUtil.join(bo.getGrantTypeList(), StringUtils.SEPARATOR));
validEntityBeforeSave(add);
add.setGrantType(String.join(",", bo.getGrantTypeList()));
// 生成clientid
String clientKey = bo.getClientKey();
String clientSecret = bo.getClientSecret();
@@ -112,6 +113,7 @@ public class SysClientServiceImpl implements ISysClientService {
@Override
public Boolean updateByBo(SysClientBo bo) {
SysClient update = MapstructUtils.convert(bo, SysClient.class);
validEntityBeforeSave(update);
update.setGrantType(String.join(",", bo.getGrantTypeList()));
return baseMapper.updateById(update) > 0;
}
@@ -128,12 +130,22 @@ public class SysClientServiceImpl implements ISysClientService {
.eq(SysClient::getClientId, clientId));
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysClient entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除客户端管理
*/
@CacheEvict(cacheNames = CacheNames.SYS_CLIENT, allEntries = true)
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
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.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.SystemConstants;
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.mapper.SysConfigMapper;
import org.dromara.system.service.ISysConfigService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -55,6 +57,7 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
* @return 参数配置信息
*/
@Override
@DS("master")
public SysConfigVo selectConfigById(Long configId) {
return baseMapper.selectVoById(configId);
}
@@ -80,10 +83,14 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
*/
@Override
public boolean selectRegisterEnabled(String tenantId) {
String configValue = TenantHelper.dynamic(tenantId, () ->
this.selectConfigByKey("sys.account.registerUser")
);
return Convert.toBool(configValue);
SysConfig retConfig = TenantHelper.dynamic(tenantId, () -> {
return baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
.eq(SysConfig::getConfigKey, "sys.account.registerUser"));
});
if (ObjectUtil.isNull(retConfig)) {
return false;
}
return Convert.toBool(retConfig.getConfigValue());
}
/**
@@ -161,15 +168,15 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
* @param configIds 需要删除的参数ID
*/
@Override
public void deleteConfigByIds(List<Long> configIds) {
List<SysConfig> list = baseMapper.selectByIds(configIds);
list.forEach(config -> {
public void deleteConfigByIds(Long[] configIds) {
for (Long configId : configIds) {
SysConfig config = baseMapper.selectById(configId);
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());
});
baseMapper.deleteByIds(configIds);
}
baseMapper.deleteByIds(Arrays.asList(configIds));
}
/**
@@ -188,10 +195,12 @@ public class SysConfigServiceImpl implements ISysConfigService, ConfigService {
*/
@Override
public boolean checkConfigKeyUnique(SysConfigBo config) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysConfig>()
.eq(SysConfig::getConfigKey, config.getConfigKey())
.ne(ObjectUtil.isNotNull(config.getConfigId()), SysConfig::getConfigId, config.getConfigId()));
return !exist;
long configId = ObjectUtils.notNull(config.getConfigId(), -1L);
SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
if (ObjectUtil.isNotNull(info) && info.getConfigId() != configId) {
return false;
}
return true;
}
/**

View File

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.SysRoleDept;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysRoleDeptMapper;
@@ -65,8 +66,13 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService {
if (ObjectUtil.isNull(deptId)) {
return "-1";
}
List<Long> deptIds = deptMapper.selectDeptAndChildById(deptId);
return CollUtil.isNotEmpty(deptIds) ? StreamUtils.join(deptIds, Convert::toStr) : "-1";
List<SysDept> deptList = deptMapper.selectListByParentId(deptId);
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.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())) {
//部门树搜索
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);
});
}
@@ -125,17 +131,23 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
if (CollUtil.isEmpty(depts)) {
return CollUtil.newArrayList();
}
return TreeBuildUtils.buildMultiRoot(
depts,
SysDeptVo::getDeptId,
SysDeptVo::getParentId,
(node, treeNode) -> treeNode
.setId(node.getDeptId())
.setParentId(node.getParentId())
.setName(node.getDeptName())
.setWeight(node.getOrderNum())
.putExtra("disabled", SystemConstants.DISABLE.equals(node.getStatus()))
);
// 获取当前列表中每一个节点的parentId然后在列表中查找是否有id与其parentId对应若无对应则表明此时节点列表中该节点在当前列表中属于顶级节点
List<Tree<Long>> treeList = CollUtil.newArrayList();
for (SysDeptVo d : depts) {
Long parentId = d.getParentId();
SysDeptVo sysDeptVo = StreamUtils.findFirst(depts, it -> it.getDeptId().longValue() == parentId);
if (ObjectUtil.isNull(sysDeptVo)) {
List<Tree<Long>> trees = TreeBuildUtils.build(depts, parentId, (dept, tree) ->
tree.setId(dept.getDeptId())
.setParentId(dept.getParentId())
.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);
}
/**
* 根据部门 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.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
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.StringUtils;
import org.dromara.common.core.utils.ObjectUtils;
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.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.vo.SysDictDataVo;
import org.dromara.system.mapper.SysDictDataMapper;
import org.dromara.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
@@ -57,7 +58,7 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
lqw.eq(bo.getDictSort() != null, SysDictData::getDictSort, bo.getDictSort());
lqw.like(StringUtils.isNotBlank(bo.getDictLabel()), SysDictData::getDictLabel, bo.getDictLabel());
lqw.eq(StringUtils.isNotBlank(bo.getDictType()), SysDictData::getDictType, bo.getDictType());
lqw.orderByAsc(SysDictData::getDictSort, SysDictData::getDictCode);
lqw.orderByAsc(SysDictData::getDictSort);
return lqw;
}
@@ -94,10 +95,12 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
* @param dictCodes 需要删除的字典数据ID
*/
@Override
public void deleteDictDataByIds(List<Long> dictCodes) {
List<SysDictData> list = baseMapper.selectByIds(dictCodes);
baseMapper.deleteByIds(dictCodes);
list.forEach(x -> CacheUtils.evict(CacheNames.SYS_DICT, x.getDictType()));
public void deleteDictDataByIds(Long[] dictCodes) {
for (Long dictCode : dictCodes) {
SysDictData data = baseMapper.selectById(dictCode);
baseMapper.deleteById(dictCode);
CacheUtils.evict(CacheNames.SYS_DICT, data.getDictType());
}
}
/**
@@ -142,11 +145,13 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
*/
@Override
public boolean checkDictDataUnique(SysDictDataBo dict) {
boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictType, dict.getDictType())
.eq(SysDictData::getDictValue, dict.getDictValue())
.ne(ObjectUtil.isNotNull(dict.getDictCode()), SysDictData::getDictCode, dict.getDictCode()));
return !exist;
Long dictCode = ObjectUtils.notNull(dict.getDictCode(), -1L);
SysDictData entity = baseMapper.selectOne(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictType, dict.getDictType()).eq(SysDictData::getDictValue, dict.getDictValue()));
if (ObjectUtil.isNotNull(entity) && !dictCode.equals(entity.getDictCode())) {
return false;
}
return true;
}
}

View File

@@ -98,7 +98,10 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
@Override
public List<SysDictDataVo> selectDictDataByType(String dictType) {
List<SysDictDataVo> dictDatas = dictDataMapper.selectDictDataByType(dictType);
return CollUtil.isNotEmpty(dictDatas) ? dictDatas : null;
if (CollUtil.isNotEmpty(dictDatas)) {
return dictDatas;
}
return null;
}
/**
@@ -130,20 +133,17 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
* @param dictIds 需要删除的字典ID
*/
@Override
public void deleteDictTypeByIds(List<Long> dictIds) {
List<SysDictType> list = baseMapper.selectByIds(dictIds);
list.forEach(x -> {
boolean assigned = dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictType, x.getDictType()));
if (assigned) {
throw new ServiceException(String.format("%1$s已分配,不能删除", x.getDictName()));
public void deleteDictTypeByIds(Long[] dictIds) {
for (Long dictId : dictIds) {
SysDictType dictType = baseMapper.selectById(dictId);
if (dictDataMapper.exists(new LambdaQueryWrapper<SysDictData>()
.eq(SysDictData::getDictType, dictType.getDictType()))) {
throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
}
});
baseMapper.deleteByIds(dictIds);
list.forEach(x -> {
CacheUtils.evict(CacheNames.SYS_DICT, x.getDictType());
CacheUtils.evict(CacheNames.SYS_DICT_TYPE, x.getDictType());
});
CacheUtils.evict(CacheNames.SYS_DICT, dictType.getDictType());
CacheUtils.evict(CacheNames.SYS_DICT_TYPE, dictType.getDictType());
}
baseMapper.deleteByIds(Arrays.asList(dictIds));
}
/**

View File

@@ -8,7 +8,6 @@ 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 org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StreamUtils;
@@ -143,7 +142,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
} else {
menus = baseMapper.selectMenuTreeByUserId(userId);
}
return getChildPerms(menus, Constants.TOP_PARENT_ID);
return getChildPerms(menus, 0);
}
/**
@@ -222,7 +221,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
children.setQuery(menu.getQueryParam());
childrenList.add(children);
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.setPath("/");
List<RouterVo> childrenList = new ArrayList<>();
@@ -376,11 +375,11 @@ public class SysMenuServiceImpl implements ISysMenuService {
* @param parentId 传入的父节点ID
* @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<>();
for (SysMenu t : list) {
// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
if (t.getParentId().equals(parentId)) {
if (t.getParentId() == parentId) {
recursionFn(list, t);
returnList.add(t);
}

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.StringUtils;
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.TableDataInfo;
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.factory.OssFactory;
import org.dromara.system.domain.SysOss;
import org.dromara.system.domain.SysOssExt;
import org.dromara.system.domain.bo.SysOssBo;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.mapper.SysOssMapper;
@@ -201,11 +199,8 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
} catch (IOException e) {
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());
OssClient storage = OssFactory.instance();
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
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();
oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalfileName);
oss.setService(configKey);
oss.setExt1(JsonUtils.toJsonString(ext1));
baseMapper.insert(oss);
SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class);
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.mybatis.core.page.PageQuery;
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.SysUserPost;
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.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -91,7 +92,9 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
} else if (ObjectUtil.isNotNull(bo.getBelongDeptId())) {
//部门树搜索
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);
});
}
@@ -214,14 +217,14 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
* @return 结果
*/
@Override
public int deletePostByIds(List<Long> postIds) {
List<SysPost> list = baseMapper.selectByIds(postIds);
for (SysPost post : list) {
if (this.countUserPostById(post.getPostId()) > 0) {
public int deletePostByIds(Long[] postIds) {
for (Long postId : postIds) {
SysPost post = baseMapper.selectById(postId);
if (countUserPostById(postId) > 0) {
throw new ServiceException(String.format("%1$s已分配不能删除!", post.getPostName()));
}
}
return baseMapper.deleteByIds(postIds);
return baseMapper.deleteByIds(Arrays.asList(postIds));
}
/**
@@ -248,23 +251,4 @@ public class SysPostServiceImpl implements ISysPostService, PostService {
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

@@ -549,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 lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
import org.dromara.common.core.domain.model.TaskAssigneeBody;
import org.dromara.common.core.service.TaskAssigneeService;
@@ -52,7 +51,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysRoleBo bo = new SysRoleBo();
bo.setRoleKey(taskQuery.getHandlerCode());
bo.setRoleName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime());
@@ -75,7 +73,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysPostBo bo = new SysPostBo();
bo.setPostCategory(taskQuery.getHandlerCode());
bo.setPostName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime());
@@ -99,7 +96,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysDeptBo bo = new SysDeptBo();
bo.setDeptCategory(taskQuery.getHandlerCode());
bo.setDeptName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime());
@@ -111,6 +107,7 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
return new TaskAssigneeDTO(page.getTotal(), handlers);
}
/**
* 查询用户并返回任务指派的列表,支持分页
*
@@ -123,7 +120,6 @@ public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
SysUserBo bo = new SysUserBo();
bo.setUserName(taskQuery.getHandlerCode());
bo.setNickName(taskQuery.getHandlerName());
bo.setStatus(SystemConstants.NORMAL);
Map<String, Object> params = bo.getParams();
params.put("beginTime", taskQuery.getBeginTime());
params.put("endTime", taskQuery.getEndTime());

View File

@@ -22,10 +22,7 @@ import org.dromara.common.core.utils.*;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysRole;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.SysUserPost;
import org.dromara.system.domain.SysUserRole;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysPostVo;
import org.dromara.system.domain.vo.SysRoleVo;
@@ -39,6 +36,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* 用户 业务层处理
@@ -71,9 +69,15 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
*/
@Override
public List<SysUserExportVo> selectUserExportList(SysUserBo user) {
return baseMapper.selectUserExportList(this.buildQueryWrapper(user));
}
private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
Map<String, Object> params = user.getParams();
QueryWrapper<SysUser> wrapper = Wrappers.query();
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.getNickName()), "u.nick_name", user.getNickName())
.eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
@@ -81,30 +85,13 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
.between(params.get("beginTime") != null && params.get("endTime") != null,
"u.create_time", params.get("beginTime"), params.get("endTime"))
.and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
List<Long> deptIds = deptMapper.selectDeptAndChildById(user.getDeptId());
w.in("u.dept_id", deptIds);
List<SysDept> deptList = deptMapper.selectListByParentId(user.getDeptId());
List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
ids.add(user.getDeptId());
w.in("u.dept_id", ids);
}).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())) {
wrapper.notIn(SysUser::getUserId, StringUtils.splitList(user.getExcludeUserIds()));
wrapper.notIn("u.user_id", StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong));
}
return wrapper;
}
@@ -648,10 +635,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
return List.of();
}
List<SysUserVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserId, SysUser::getDeptId, SysUser::getUserName,
SysUser::getNickName, SysUser::getUserType, SysUser::getEmail,
SysUser::getPhonenumber, SysUser::getSex, SysUser::getStatus,
SysUser::getCreateTime)
.select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber)
.eq(SysUser::getStatus, SystemConstants.NORMAL)
.in(SysUser::getUserId, userIds));
return BeanUtil.copyToList(list, UserDTO.class);
@@ -692,7 +676,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
// 获取用户ID列表
Set<Long> userIds = StreamUtils.toSet(userRoles, SysUserRole::getUserId);
return this.selectListByIds(new ArrayList<>(userIds));
return selectListByIds(new ArrayList<>(userIds));
}
/**
@@ -732,7 +716,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
// 获取用户ID列表
Set<Long> userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId);
return this.selectListByIds(new ArrayList<>(userIds));
return selectListByIds(new ArrayList<>(userIds));
}
/**
@@ -746,12 +730,69 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
if (CollUtil.isEmpty(userIds)) {
return Collections.emptyMap();
}
List<SysUser> list = baseMapper.selectList(
new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserId, SysUser::getNickName)
.in(SysUser::getUserId, userIds)
);
return StreamUtils.toMap(list, SysUser::getUserId, SysUser::getNickName);
return baseMapper.selectList(
new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserId, SysUser::getNickName)
.in(SysUser::getUserId, userIds)
).stream()
.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

@@ -7,6 +7,32 @@
<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

View File

@@ -7,6 +7,17 @@
<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

View File

@@ -11,6 +11,32 @@
<id property="userId" column="user_id"/>
</resultMap>
<select id="selectPageUserList" resultMap="SysUserResult">
select
<if test="ew.getSqlSelect != null">
${ew.getSqlSelect}
</if>
<if test="ew.getSqlSelect == null">
u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark
</if>
from sys_user u
${ew.getCustomSqlSegment}
</select>
<select id="selectUserList" resultMap="SysUserResult">
select
<if test="ew.getSqlSelect != null">
${ew.getSqlSelect}
</if>
<if test="ew.getSqlSelect == null">
u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark
</if>
from sys_user u
${ew.getCustomSqlSegment}
</select>
<select id="selectUserExportList" resultMap="SysUserExportResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
@@ -39,4 +65,9 @@
${ew.getCustomSqlSegment}
</select>
<select id="countUserById" resultType="Long">
select count(*) from sys_user where del_flag = '0' and user_id = #{userId}
</select>
</mapper>

View File

@@ -73,9 +73,4 @@ public interface FlowConstant {
*/
String MESSAGE_NOTICE = "messageNotice";
/**
* 任务状态
*/
String WF_TASK_STATUS = "wf_task_status";
}

View File

@@ -70,8 +70,7 @@ public class CompleteTaskBo implements Serializable {
public Map<String, Object> getVariables() {
if (variables == null) {
variables = new HashMap<>(16);
return variables;
return new HashMap<>(16);
}
variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
return variables;

View File

@@ -4,13 +4,14 @@ import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.workflow.common.constant.FlowConstant;
import org.dromara.workflow.domain.FlowCategory;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 流程分类视图对象 wf_category
@@ -33,14 +34,13 @@ public class FlowCategoryVo implements Serializable {
private Long categoryId;
/**
* 父级分类id
* 父级id
*/
private Long parentId;
/**
* 父级分类名称
* 父类名称
*/
@Translation(type = FlowConstant.CATEGORY_ID_TO_NAME, mapper = "parentId")
private String parentName;
/**
@@ -66,4 +66,9 @@ public class FlowCategoryVo implements Serializable {
@ExcelProperty(value = "创建时间")
private Date createTime;
/**
* 子菜单
*/
private List<FlowCategoryVo> children = new ArrayList<>();
}

View File

@@ -145,7 +145,6 @@ public class FlowTaskVo implements Serializable {
/**
* 办理人名称
*/
@Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "assigneeIds")
private String assigneeNames;
/**

View File

@@ -42,12 +42,14 @@ public class TestLeaveVo implements Serializable {
* 开始时间
*/
@ExcelProperty(value = "开始时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date startDate;
/**
* 结束时间
*/
@ExcelProperty(value = "结束时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date endDate;
/**

View File

@@ -3,14 +3,11 @@ package org.dromara.workflow.handler;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.handler.PermissionHandler;
import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.service.IFlwTaskAssigneeService;
import org.dromara.workflow.service.IFlwCommonService;
import org.springframework.stereotype.Component;
import java.util.Collections;
@@ -27,7 +24,7 @@ import java.util.List;
@Slf4j
public class WorkflowPermissionHandler implements PermissionHandler {
private final IFlwTaskAssigneeService flwTaskAssigneeService;
private final IFlwCommonService flwCommonService;
/**
* 办理人权限标识,比如用户,角色,部门等,用于校验是否有权限办理任务
@@ -54,11 +51,9 @@ public class WorkflowPermissionHandler implements PermissionHandler {
*/
@Override
public List<String> convertPermissions(List<String> permissions) {
if (CollUtil.isEmpty(permissions)) {
return permissions;
if (CollUtil.isNotEmpty(permissions)) {
permissions = flwCommonService.buildUser(permissions);
}
String storageIds = CollUtil.join(permissions, StringUtils.SEPARATOR);
List<UserDTO> users = flwTaskAssigneeService.fetchUsersByStorageIds(storageIds);
return StreamUtils.toList(users, userDTO -> String.valueOf(userDTO.getUserId()));
return permissions;
}
}

View File

@@ -15,7 +15,6 @@ import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.core.listener.GlobalListener;
import org.dromara.warm.flow.core.listener.ListenerVariable;
import org.dromara.warm.flow.core.service.InsService;
import org.dromara.warm.flow.orm.entity.FlowInstance;
import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.constant.FlowConstant;
@@ -152,15 +151,13 @@ public class WorkflowGlobalListener implements GlobalListener {
flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
}
}
FlowInstance ins = new FlowInstance();
Map<String, Object> variableMap = instance.getVariableMap();
variableMap.remove(FlowConstant.FLOW_COPY_LIST);
variableMap.remove(FlowConstant.MESSAGE_TYPE);
variableMap.remove(FlowConstant.MESSAGE_NOTICE);
variableMap.remove(FlowConstant.SUBMIT);
ins.setId(instance.getId());
ins.setVariable(FlowEngine.jsonConvert.objToStr(variableMap));
insService.updateById(ins);
instance.setVariable(FlowEngine.jsonConvert.objToStr(variableMap));
insService.updateById(instance);
}
}
}

View File

@@ -29,9 +29,7 @@ public interface FlwCategoryMapper extends BaseMapperPlus<FlowCategory, FlowCate
@DataPermission({
@DataColumn(key = "deptName", value = "createDept")
})
default long countCategoryById(Long categoryId) {
return this.selectCount(new LambdaQueryWrapper<FlowCategory>().eq(FlowCategory::getCategoryId, categoryId));
}
long countCategoryById(Long categoryId);
/**
* 根据父流程分类ID查询其所有子流程分类的列表

View File

@@ -9,6 +9,8 @@ import org.dromara.workflow.domain.bo.FlowTaskBo;
import org.dromara.workflow.domain.vo.FlowHisTaskVo;
import org.dromara.workflow.domain.vo.FlowTaskVo;
import java.util.List;
/**
* 任务信息Mapper接口
@@ -27,6 +29,14 @@ public interface FlwTaskMapper {
*/
Page<FlowTaskVo> getListRunTask(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
/**
* 获取待办信息
*
* @param queryWrapper 条件
* @return 结果
*/
List<FlowTaskVo> getListRunTask(@Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
/**
* 获取已办
*

View File

@@ -9,6 +9,14 @@ import java.util.List;
*/
public interface IFlwCommonService {
/**
* 构建工作流用户
*
* @param permissionList 办理用户
* @return 用户
*/
List<String> buildUser(List<String> permissionList);
/**
* 发送消息
*

View File

@@ -35,6 +35,7 @@ public interface IFlwDefinitionService {
*/
TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery);
/**
* 发布流程定义
*

View File

@@ -141,6 +141,14 @@ public interface IFlwInstanceService {
*/
FlowInstance selectByTaskId(Long taskId);
/**
* 按任务id查询实例
*
* @param taskIdList 任务id
* @return 结果
*/
List<FlowInstance> selectByTaskIdList(List<Long> taskIdList);
/**
* 作废流程
*

View File

@@ -14,6 +14,7 @@ import org.dromara.workflow.domain.vo.FlowHisTaskVo;
import org.dromara.workflow.domain.vo.FlowTaskVo;
import java.util.List;
import java.util.Map;
/**
* 任务 服务层
@@ -149,6 +150,14 @@ public interface IFlwTaskService {
*/
List<FlowNode> getNextNodeList(FlowNextNodeBo bo);
/**
* 按照任务id查询任务
*
* @param taskIdList 任务id
* @return 结果
*/
List<FlowHisTask> selectHisTaskByIdList(List<Long> taskIdList);
/**
* 按照任务id查询任务
*
@@ -157,6 +166,14 @@ public interface IFlwTaskService {
*/
FlowHisTask selectHisTaskById(Long taskId);
/**
* 按照实例id查询任务
*
* @param instanceIdList 流程实例id
* @return 结果
*/
List<FlowTask> selectByInstIdList(List<Long> instanceIdList);
/**
* 按照实例id查询任务
*
@@ -174,6 +191,14 @@ public interface IFlwTaskService {
*/
boolean taskOperation(TaskOperationBo bo, String taskOperation);
/**
* 获取任务所有办理人
*
* @param taskIdList 任务id
* @return 结果
*/
Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList);
/**
* 获取当前任务的所有办理人
*

View File

@@ -26,6 +26,12 @@ public class CategoryNameTranslationImpl implements TranslationInterface<String>
@Override
public String translation(Object key, String other) {
return flwCategoryService.selectCategoryNameById(Convert.toLong(key));
Long id = null;
if (key instanceof String categoryId) {
id = Convert.toLong(categoryId);
} else if (key instanceof Long categoryId) {
id = categoryId;
}
return flwCategoryService.selectCategoryNameById(id);
}
}

View File

@@ -8,10 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.TreeBuildUtils;
import org.dromara.common.core.utils.*;
import org.dromara.common.mybatis.helper.DataBaseHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.warm.flow.core.service.DefService;
@@ -51,7 +48,14 @@ public class FlwCategoryServiceImpl implements IFlwCategoryService {
*/
@Override
public FlowCategoryVo queryById(Long categoryId) {
return baseMapper.selectVoById(categoryId);
FlowCategoryVo category = baseMapper.selectVoById(categoryId);
if (ObjectUtil.isNull(category)) {
return null;
}
FlowCategoryVo parentCategory = baseMapper.selectVoOne(new LambdaQueryWrapper<FlowCategory>()
.select(FlowCategory::getCategoryName).eq(FlowCategory::getCategoryId, category.getParentId()));
category.setParentName(ObjectUtils.notNullGetter(parentCategory, FlowCategoryVo::getCategoryName));
return category;
}
/**
@@ -91,20 +95,27 @@ public class FlwCategoryServiceImpl implements IFlwCategoryService {
*/
@Override
public List<Tree<String>> selectCategoryTreeList(FlowCategoryBo category) {
List<FlowCategoryVo> categoryList = this.queryList(category);
if (CollUtil.isEmpty(categoryList)) {
LambdaQueryWrapper<FlowCategory> lqw = buildQueryWrapper(category);
List<FlowCategoryVo> categorys = baseMapper.selectVoList(lqw);
if (CollUtil.isEmpty(categorys)) {
return CollUtil.newArrayList();
}
return TreeBuildUtils.buildMultiRoot(
categoryList,
node -> String.valueOf(node.getCategoryId()),
node -> String.valueOf(node.getParentId()),
(node, treeNode) -> treeNode
.setId(String.valueOf(node.getCategoryId()))
.setParentId(String.valueOf(node.getParentId()))
.setName(node.getCategoryName())
.setWeight(node.getOrderNum())
);
// 获取当前列表中每一个节点的parentId然后在列表中查找是否有id与其parentId对应若无对应则表明此时节点列表中该节点在当前列表中属于顶级节点
List<Tree<String>> treeList = CollUtil.newArrayList();
for (FlowCategoryVo d : categorys) {
String parentId = d.getParentId().toString();
FlowCategoryVo categoryVo = StreamUtils.findFirst(categorys, it -> it.getCategoryId().toString().equals(parentId));
if (ObjectUtil.isNull(categoryVo)) {
List<Tree<String>> trees = TreeBuildUtils.build(categorys, parentId, (dept, tree) ->
tree.setId(dept.getCategoryId().toString())
.setParentId(dept.getParentId().toString())
.setName(dept.getCategoryName())
.setWeight(dept.getOrderNum()));
Tree<String> tree = StreamUtils.findFirst(trees, it -> it.getId().equals(d.getCategoryId().toString()));
treeList.add(tree);
}
}
return treeList;
}
/**

View File

@@ -1,262 +0,0 @@
package org.dromara.workflow.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.service.DeptService;
import org.dromara.common.core.service.DictService;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.warm.flow.core.dto.DefJson;
import org.dromara.warm.flow.core.dto.NodeJson;
import org.dromara.warm.flow.core.dto.PromptContent;
import org.dromara.warm.flow.core.enums.NodeType;
import org.dromara.warm.flow.core.utils.MapUtil;
import org.dromara.warm.flow.orm.entity.FlowHisTask;
import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
import org.dromara.warm.flow.ui.service.ChartExtService;
import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.constant.FlowConstant;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 流程图提示信息
*
* @author AprilWind
*/
@ConditionalOnEnable
@Slf4j
@RequiredArgsConstructor
@Service
public class FlwChartExtServiceImpl implements ChartExtService {
private final UserService userService;
private final DeptService deptService;
private final FlowHisTaskMapper flowHisTaskMapper;
private final DictService dictService;
/**
* 设置流程图提示信息
*
* @param defJson 流程定义json对象
*/
@Override
public void execute(DefJson defJson) {
// 临时修复 后续版本将通过defjson获取流程实例ID
String[] parts = ServletUtils.getRequest().getRequestURI().split("/");
Long instanceId = Convert.toLong(parts[parts.length - 1]);
// 根据流程实例ID查询所有相关的历史任务列表
List<FlowHisTask> flowHisTasks = this.getHisTaskGroupedByNode(instanceId);
if (CollUtil.isEmpty(flowHisTasks)) {
return;
}
// 按节点编号nodeCode对历史任务进行分组
Map<String, List<FlowHisTask>> groupedByNode = StreamUtils.groupByKey(flowHisTasks, FlowHisTask::getNodeCode);
// 批量查询所有审批人的用户信息
List<UserDTO> userDTOList = userService.selectListByIds(StreamUtils.toList(flowHisTasks, e -> Convert.toLong(e.getApprover())));
// 将查询到的用户列表转换为以用户ID为key的映射
Map<Long, UserDTO> userMap = StreamUtils.toIdentityMap(userDTOList, UserDTO::getUserId);
Map<String, String> dictType = dictService.getAllDictByDictType(FlowConstant.WF_TASK_STATUS);
for (NodeJson nodeJson : defJson.getNodeList()) {
List<FlowHisTask> taskList = groupedByNode.get(nodeJson.getNodeCode());
if (CollUtil.isEmpty(taskList)) {
continue;
}
// 按审批人分组去重,保留最新处理记录,最终转换成 List
List<FlowHisTask> latestPerApprover = taskList.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(
FlowHisTask::getApprover,
Function.identity(),
(oldTask, newTask) -> newTask.getUpdateTime().after(oldTask.getUpdateTime()) ? newTask : oldTask,
LinkedHashMap::new
),
map -> new ArrayList<>(map.values())
));
// 处理当前节点的扩展信息
this.processNodeExtInfo(nodeJson, latestPerApprover, userMap, dictType);
}
}
/**
* 初始化流程图提示信息
*
* @param defJson 流程定义json对象
*/
@Override
public void initPromptContent(DefJson defJson) {
defJson.setTopText("流程名称: " + defJson.getFlowName());
defJson.getNodeList().forEach(nodeJson -> {
nodeJson.setPromptContent(
new PromptContent()
// 提示信息
.setInfo(
CollUtil.newArrayList(
new PromptContent.InfoItem()
.setPrefix("任务名称: ")
.setContent(nodeJson.getNodeName())
.setContentStyle(Map.of(
"border", "1px solid #d1e9ff",
"backgroundColor", "#e8f4ff",
"padding", "4px 8px",
"borderRadius", "4px"
))
.setRowStyle(Map.of(
"fontWeight", "bold",
"margin", "0 0 6px 0",
"padding", "0 0 8px 0",
"borderBottom", "1px solid #ccc"
))
)
)
// 弹窗样式
.setDialogStyle(MapUtil.mergeAll(
"position", "absolute",
"backgroundColor", "#fff",
"border", "1px solid #ccc",
"borderRadius", "4px",
"boxShadow", "0 2px 8px rgba(0, 0, 0, 0.15)",
"padding", "8px 12px",
"fontSize", "14px",
"zIndex", "1000",
"maxWidth", "500px",
"overflowY", "visible",
"overflowX", "hidden",
"color", "#333",
"pointerEvents", "auto",
"scrollbarWidth", "thin"
))
);
});
}
/**
* 处理节点的扩展信息,构建用于流程图悬浮提示的内容
*
* @param nodeJson 当前节点对象
* @param taskList 当前节点对应的历史审批任务列表
*/
private void processNodeExtInfo(NodeJson nodeJson, List<FlowHisTask> taskList, Map<Long, UserDTO> userMap, Map<String, String> dictType) {
// 获取节点提示内容对象中的 info 列表,用于追加提示项
List<PromptContent.InfoItem> info = nodeJson.getPromptContent().getInfo();
// 遍历所有任务记录,构建提示内容
for (FlowHisTask task : taskList) {
UserDTO userDTO = userMap.get(Convert.toLong(task.getApprover()));
if (ObjectUtil.isEmpty(userDTO)) {
continue;
}
// 查询用户所属部门名称
String deptName = deptService.selectDeptNameByIds(Convert.toStr(userDTO.getDeptId()));
// 添加标题项,如:👤 张三(市场部)
info.add(new PromptContent.InfoItem()
.setPrefix(StringUtils.format("👥 {}{}", userDTO.getNickName(), deptName))
.setPrefixStyle(Map.of(
"fontWeight", "bold",
"fontSize", "15px",
"color", "#333"
))
.setRowStyle(Map.of(
"margin", "8px 0",
"borderBottom", "1px dashed #ccc"
))
);
// 添加具体信息项:账号、耗时、时间
info.add(buildInfoItem("用户账号", userDTO.getUserName()));
info.add(buildInfoItem("审批状态", dictType.get(task.getFlowStatus())));
info.add(buildInfoItem("审批耗时", DateUtils.getTimeDifference(task.getUpdateTime(), task.getCreateTime())));
info.add(buildInfoItem("办理时间", DateUtils.formatDateTime(task.getUpdateTime())));
}
}
/**
* 构建单条提示内容对象 InfoItem用于悬浮窗显示key: value
*
* @param key 字段名(作为前缀)
* @param value 字段值
* @return 提示项对象
*/
private PromptContent.InfoItem buildInfoItem(String key, String value) {
return new PromptContent.InfoItem()
// 前缀
.setPrefix(key + ": ")
// 前缀样式
.setPrefixStyle(Map.of(
"textAlign", "right",
"color", "#444",
"userSelect", "none",
"display", "inline-block",
"width", "100px",
"paddingRight", "8px",
"fontWeight", "500",
"fontSize", "14px",
"lineHeight", "24px",
"verticalAlign", "middle"
))
// 内容
.setContent(value)
// 内容样式
.setContentStyle(Map.of(
"backgroundColor", "#f7faff",
"color", "#005cbf",
"padding", "4px 8px",
"fontSize", "14px",
"borderRadius", "4px",
"whiteSpace", "normal",
"border", "1px solid #d0e5ff",
"userSelect", "text",
"lineHeight", "20px"
))
// 行样式
.setRowStyle(Map.of(
"color", "#222",
"alignItems", "center",
"display", "flex",
"marginBottom", "6px",
"fontWeight", "400",
"fontSize", "14px"
));
}
/**
* 根据流程实例ID获取历史任务列表
*
* @param instanceId 流程实例ID
* @return 历史任务列表
*/
public List<FlowHisTask> getHisTaskGroupedByNode(Long instanceId) {
LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
wrapper.eq(FlowHisTask::getInstanceId, instanceId)
.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey())
.orderByDesc(FlowHisTask::getUpdateTime);
return flowHisTaskMapper.selectList(wrapper);
}
}

View File

@@ -19,6 +19,7 @@ import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.enums.MessageTypeEnum;
import org.dromara.workflow.service.IFlwCommonService;
import org.dromara.workflow.service.IFlwTaskAssigneeService;
import org.dromara.workflow.service.IFlwTaskService;
import org.springframework.stereotype.Service;
@@ -39,6 +40,26 @@ import java.util.stream.Collectors;
public class FlwCommonServiceImpl implements IFlwCommonService {
private final NodeService nodeService;
/**
* 构建工作流用户
*
* @param permissionList 办理用户
* @return 用户
*/
@Override
public List<String> buildUser(List<String> permissionList) {
if (CollUtil.isEmpty(permissionList)) {
return List.of();
}
IFlwTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IFlwTaskAssigneeService.class);
String processedBys = CollUtil.join(permissionList, StringUtils.SEPARATOR);
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
List<UserDTO> users = taskAssigneeService.fetchUsersByStorageIds(processedBys);
return StreamUtils.toList(users, userDTO -> String.valueOf(userDTO.getUserId()));
}
/**
* 发送消息
*

View File

@@ -78,8 +78,10 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinition);
wrapper.eq(FlowDefinition::getIsPublish, PublishStatus.PUBLISHED.getKey());
Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper);
List<FlowDefinitionVo> list = BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class);
return new TableDataInfo<>(list, page.getTotal());
TableDataInfo<FlowDefinitionVo> build = TableDataInfo.build();
build.setRows(BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class));
build.setTotal(page.getTotal());
return build;
}
/**
@@ -94,8 +96,10 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinition);
wrapper.in(FlowDefinition::getIsPublish, Arrays.asList(PublishStatus.UNPUBLISHED.getKey(), PublishStatus.EXPIRED.getKey()));
Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper);
List<FlowDefinitionVo> list = BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class);
return new TableDataInfo<>(list, page.getTotal());
TableDataInfo<FlowDefinitionVo> build = TableDataInfo.build();
build.setRows(BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class));
build.setTotal(page.getTotal());
return build;
}
private LambdaQueryWrapper<FlowDefinition> buildQueryWrapper(FlowDefinition flowDefinition) {

View File

@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StreamUtils;
@@ -18,13 +19,11 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.warm.flow.core.FlowEngine;
import org.dromara.warm.flow.core.constant.ExceptionCons;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Definition;
import org.dromara.warm.flow.core.entity.Instance;
import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.core.entity.User;
import org.dromara.warm.flow.core.enums.NodeType;
import org.dromara.warm.flow.core.service.DefService;
import org.dromara.warm.flow.core.service.InsService;
@@ -50,7 +49,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 流程实例 服务层实现
@@ -204,11 +203,9 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
return false;
}
// 获取定义信息
Map<Long, Definition> definitionMap = StreamUtils.toMap(
defService.getByIds(StreamUtils.toList(instances, Instance::getDefinitionId)),
Definition::getId,
Function.identity()
);
Map<Long, Definition> definitionMap = defService.getByIds(
StreamUtils.toList(instances, Instance::getDefinitionId)
).stream().collect(Collectors.toMap(Definition::getId, definition -> definition));
// 逐一触发删除事件
instances.forEach(instance -> {
@@ -284,50 +281,37 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
throw new ServiceException(ExceptionCons.NOT_FOUNT_INSTANCE);
}
Long instanceId = flowInstance.getId();
// 先组装待审批任务(运行中的任务)
List<FlowHisTaskVo> runningTaskVos = new ArrayList<>();
List<FlowTask> runningTasks = flwTaskService.selectByInstId(instanceId);
if (CollUtil.isNotEmpty(runningTasks)) {
runningTaskVos = BeanUtil.copyToList(runningTasks, FlowHisTaskVo.class);
List<User> associatedUsers = FlowEngine.userService()
.getByAssociateds(StreamUtils.toList(runningTasks, FlowTask::getId));
Map<Long, List<User>> taskUserMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
for (FlowHisTaskVo vo : runningTaskVos) {
vo.setFlowStatus(TaskStatusEnum.WAITING.getStatus());
vo.setUpdateTime(null);
vo.setRunDuration(null);
List<User> users = taskUserMap.get(vo.getId());
if (CollUtil.isNotEmpty(users)) {
vo.setApprover(StreamUtils.join(users, User::getProcessedBy));
//运行中的任务
List<FlowHisTaskVo> list = new ArrayList<>();
List<FlowTask> flowTaskList = flwTaskService.selectByInstId(instanceId);
if (CollUtil.isNotEmpty(flowTaskList)) {
List<FlowHisTaskVo> flowHisTaskVos = BeanUtil.copyToList(flowTaskList, FlowHisTaskVo.class);
for (FlowHisTaskVo flowHisTaskVo : flowHisTaskVos) {
flowHisTaskVo.setFlowStatus(TaskStatusEnum.WAITING.getStatus());
flowHisTaskVo.setUpdateTime(null);
flowHisTaskVo.setRunDuration(null);
List<UserDTO> allUser = flwTaskService.currentTaskAllUser(flowHisTaskVo.getId());
if (CollUtil.isNotEmpty(allUser)) {
String join = StreamUtils.join(allUser, e -> String.valueOf(e.getUserId()));
flowHisTaskVo.setApprover(join);
}
if (BusinessStatusEnum.isDraftOrCancelOrBack(flowInstance.getFlowStatus())) {
vo.setApprover(LoginHelper.getUserIdStr());
flowHisTaskVo.setApprover(LoginHelper.getUserIdStr());
flowHisTaskVo.setApproveName(LoginHelper.getLoginUser().getNickname());
}
}
list.addAll(flowHisTaskVos);
}
// 再组装历史任务(已处理任务)
List<FlowHisTaskVo> hisTaskVos = new ArrayList<>();
List<FlowHisTask> hisTasks = flowHisTaskMapper.selectList(
new LambdaQueryWrapper<FlowHisTask>()
.eq(FlowHisTask::getInstanceId, instanceId)
.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey())
.orderByDesc(FlowHisTask::getUpdateTime)
);
if (CollUtil.isNotEmpty(hisTasks)) {
hisTaskVos = BeanUtil.copyToList(hisTasks, FlowHisTaskVo.class);
//历史任务
LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
wrapper.eq(FlowHisTask::getInstanceId, instanceId);
wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey());
wrapper.orderByDesc(FlowHisTask::getCreateTime).orderByDesc(FlowHisTask::getUpdateTime);
List<FlowHisTask> flowHisTasks = flowHisTaskMapper.selectList(wrapper);
if (CollUtil.isNotEmpty(flowHisTasks)) {
list.addAll(BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class));
}
// 结果列表,待审批任务在前,历史任务在后
List<FlowHisTaskVo> combinedList = new ArrayList<>();
combinedList.addAll(runningTaskVos);
combinedList.addAll(hisTaskVos);
return Map.of("list", combinedList, "instanceId", instanceId);
return Map.of("list", list,"instanceId",instanceId);
}
/**
@@ -393,6 +377,31 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
return null;
}
/**
* 按任务id查询实例
*
* @param taskIdList 任务id
*/
@Override
public List<FlowInstance> selectByTaskIdList(List<Long> taskIdList) {
if (CollUtil.isEmpty(taskIdList)) {
return Collections.emptyList();
}
Set<Long> instanceIds = new HashSet<>();
List<FlowTask> flowTaskList = flwTaskService.selectByIdList(taskIdList);
for (FlowTask flowTask : flowTaskList) {
instanceIds.add(flowTask.getInstanceId());
}
List<FlowHisTask> flowHisTaskList = flwTaskService.selectHisTaskByIdList(taskIdList);
for (FlowHisTask flowHisTask : flowHisTaskList) {
instanceIds.add(flowHisTask.getInstanceId());
}
if (!instanceIds.isEmpty()) {
return this.selectInstListByIdList(new ArrayList<>(instanceIds));
}
return Collections.emptyList();
}
/**
* 作废流程
*

View File

@@ -2,7 +2,6 @@ package org.dromara.workflow.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
@@ -12,7 +11,9 @@ import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.domain.model.TaskAssigneeBody;
import org.dromara.common.core.enums.FormatsType;
import org.dromara.common.core.service.*;
import org.dromara.common.core.service.DeptService;
import org.dromara.common.core.service.TaskAssigneeService;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.warm.flow.ui.dto.HandlerFunDto;
@@ -43,8 +44,6 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
private final TaskAssigneeService taskAssigneeService;
private final UserService userService;
private final DeptService deptService;
private final RoleService roleService;
private final PostService postService;
/**
* 获取办理人权限设置列表tabs页签
@@ -107,10 +106,15 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
.map(entry -> {
String storageId = entry.getKey();
Pair<TaskAssigneeEnum, Long> parsed = entry.getValue();
String handlerName = (parsed == null) ? null
: nameMap.getOrDefault(parsed.getKey(), Collections.emptyMap())
.get(parsed.getValue());
return new HandlerFeedBackVo(storageId, handlerName);
String handlerName = "格式错误";
if (parsed != null) {
Map<Long, String> nameMapping = nameMap.getOrDefault(parsed.getKey(), Collections.emptyMap());
handlerName = nameMapping.getOrDefault(parsed.getValue(), "未知名称");
}
HandlerFeedBackVo backVo = new HandlerFeedBackVo();
backVo.setStorageId(storageId);
backVo.setHandlerName(handlerName);
return backVo;
}).toList();
}
@@ -216,9 +220,9 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
private Map<Long, String> getNamesByType(TaskAssigneeEnum type, List<Long> ids) {
return switch (type) {
case USER -> userService.selectUserNamesByIds(ids);
case ROLE -> roleService.selectRoleNamesByIds(ids);
case DEPT -> deptService.selectDeptNamesByIds(ids);
case POST -> postService.selectPostNamesByIds(ids);
case ROLE -> userService.selectRoleNamesByIds(ids);
case DEPT -> userService.selectDeptNamesByIds(ids);
case POST -> userService.selectPostNamesByIds(ids);
};
}
@@ -229,21 +233,13 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
* @return Pair(TaskAssigneeEnum, Long),如果格式非法返回 null
*/
private Pair<TaskAssigneeEnum, Long> parseStorageId(String storageId) {
if (StringUtils.isBlank(storageId)) {
return null;
}
// 跳过以 $ 或 # 开头的字符串
if (StringUtils.startsWith(storageId, "$") || StringUtils.startsWith(storageId, "#")) {
log.debug("跳过 storageId 解析,检测到内置变量表达式:{}", storageId);
return null;
}
try {
String[] parts = storageId.split(StrUtil.COLON, 2);
if (parts.length < 2) {
return Pair.of(TaskAssigneeEnum.USER, Convert.toLong(parts[0]));
return Pair.of(TaskAssigneeEnum.USER, Long.valueOf(parts[0]));
} else {
TaskAssigneeEnum type = TaskAssigneeEnum.fromCode(parts[0] + StrUtil.COLON);
return Pair.of(type, Convert.toLong(parts[1]));
return Pair.of(type, Long.valueOf(parts[1]));
}
} catch (Exception e) {
log.warn("解析 storageId 失败,格式非法:{},错误信息:{}", storageId, e.getMessage());

View File

@@ -55,6 +55,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import static org.dromara.workflow.common.constant.FlowConstant.*;
@@ -251,12 +252,14 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
hisTask.setCreateTime(updateTime);
hisTask.setUpdateTime(updateTime);
hisTaskService.save(hisTask);
List<User> userList = StreamUtils.toList(flowCopyList, x ->
new FlowUser()
.setType(TaskAssigneeType.COPY.getCode())
.setProcessedBy(String.valueOf(x.getUserId()))
.setAssociated(taskId)
);
List<User> userList = flowCopyList.stream()
.map(flowCopy -> {
FlowUser flowUser = new FlowUser();
flowUser.setType(TaskAssigneeType.COPY.getCode());
flowUser.setProcessedBy(String.valueOf(flowCopy.getUserId()));
flowUser.setAssociated(taskId);
return flowUser;
}).collect(Collectors.toList());
// 批量保存抄送人员
FlowEngine.userService().saveBatch(userList);
}
@@ -273,8 +276,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
queryWrapper.in("t.processed_by", LoginHelper.getUserIdStr());
queryWrapper.in("t.flow_status", BusinessStatusEnum.WAITING.getStatus());
Page<FlowTaskVo> page = flwTaskMapper.getListRunTask(pageQuery.build(), queryWrapper);
this.wrapAssigneeInfo(page.getRecords());
Page<FlowTaskVo> page = this.getFlowTaskVoPage(pageQuery, queryWrapper);
return TableDataInfo.build(page);
}
@@ -304,28 +306,25 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
public TableDataInfo<FlowTaskVo> pageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
Page<FlowTaskVo> page = flwTaskMapper.getListRunTask(pageQuery.build(), queryWrapper);
this.wrapAssigneeInfo(page.getRecords());
Page<FlowTaskVo> page = getFlowTaskVoPage(pageQuery, queryWrapper);
return TableDataInfo.build(page);
}
/**
* 为流程任务列表封装处理人 IDassigneeIds
*
* @param taskList 流程任务列表
*/
private void wrapAssigneeInfo(List<FlowTaskVo> taskList) {
if (CollUtil.isEmpty(taskList)) {
return;
}
List<User> associatedUsers = FlowEngine.userService()
.getByAssociateds(StreamUtils.toList(taskList, FlowTaskVo::getId));
Map<Long, List<User>> taskUserMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
// 组装用户数据回任务列表
for (FlowTaskVo task : taskList) {
List<User> users = taskUserMap.get(task.getId());
task.setAssigneeIds(StreamUtils.join(users, User::getProcessedBy));
private Page<FlowTaskVo> getFlowTaskVoPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper) {
Page<FlowTaskVo> page = flwTaskMapper.getListRunTask(pageQuery.build(), queryWrapper);
List<FlowTaskVo> records = page.getRecords();
if (CollUtil.isNotEmpty(records)) {
List<Long> taskIds = StreamUtils.toList(records, FlowTaskVo::getId);
Map<Long, List<UserDTO>> listMap = currentTaskAllUser(taskIds);
records.forEach(t -> {
List<UserDTO> userList = listMap.getOrDefault(t.getId(), Collections.emptyList());
if (CollUtil.isNotEmpty(userList)) {
t.setAssigneeIds(StreamUtils.join(userList, e -> String.valueOf(e.getUserId())));
t.setAssigneeNames(StreamUtils.join(userList, UserDTO::getNickName));
}
});
}
return page;
}
/**
@@ -531,10 +530,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
// 构建以下节点数据
List<Task> buildNextTaskList = StreamUtils.toList(nextNodeList, node -> taskService.addTask(node, instance, definition, FlowParams.build()));
// 办理人变量替换
ExpressionUtil.evalVariable(buildNextTaskList,
FlowParams.build()
.variable(mergeVariable)
);
ExpressionUtil.evalVariable(buildNextTaskList, mergeVariable);
for (FlowNode flowNode : nextFlowNodes) {
buildNextTaskList.stream().filter(t -> t.getNodeCode().equals(flowNode.getNodeCode())).findFirst().ifPresent(t -> {
if (CollUtil.isNotEmpty(t.getPermissionList())) {
@@ -549,6 +545,18 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
return nextFlowNodes;
}
/**
* 按照任务id查询任务
*
* @param taskIdList 任务id
* @return 结果
*/
@Override
public List<FlowHisTask> selectHisTaskByIdList(List<Long> taskIdList) {
return flowHisTaskMapper.selectList(new LambdaQueryWrapper<>(FlowHisTask.class)
.in(FlowHisTask::getId, taskIdList));
}
/**
* 按照任务id查询任务
*
@@ -561,6 +569,17 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
.eq(FlowHisTask::getId, taskId));
}
/**
* 按照实例id查询任务
*
* @param instanceIdList 流程实例id
*/
@Override
public List<FlowTask> selectByInstIdList(List<Long> instanceIdList) {
return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
.in(FlowTask::getInstanceId, instanceIdList));
}
/**
* 按照实例id查询任务
*
@@ -661,12 +680,15 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
// 批量删除现有任务的办理人记录
if (CollUtil.isNotEmpty(flowTasks)) {
FlowEngine.userService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
List<User> userList = StreamUtils.toList(flowTasks, flowTask ->
new FlowUser()
.setType(TaskAssigneeType.APPROVER.getCode())
.setProcessedBy(userId)
.setAssociated(flowTask.getId())
);
List<User> userList = flowTasks.stream()
.map(flowTask -> {
FlowUser flowUser = new FlowUser();
flowUser.setType(TaskAssigneeType.APPROVER.getCode());
flowUser.setProcessedBy(userId);
flowUser.setAssociated(flowTask.getId());
return flowUser;
})
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(userList)) {
FlowEngine.userService().saveBatch(userList);
}
@@ -678,6 +700,27 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
return true;
}
/**
* 获取任务所有办理人
*
* @param taskIdList 任务id
*/
@Override
public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) {
Map<Long, List<UserDTO>> map = new HashMap<>();
// 获取与当前任务关联的用户列表
List<User> associatedUsers = FlowEngine.userService().getByAssociateds(taskIdList);
Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
List<User> value = entry.getValue();
if (CollUtil.isNotEmpty(value)) {
List<UserDTO> userDtoList = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
map.put(entry.getKey(), userDtoList);
}
}
return map;
}
/**
* 获取当前任务的所有办理人
*
@@ -690,7 +733,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
if (CollUtil.isEmpty(userList)) {
return Collections.emptyList();
}
return userService.selectListByIds(StreamUtils.toList(userList, e -> Convert.toLong(e.getProcessedBy())));
return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
}
/**

View File

@@ -145,7 +145,7 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
@EventListener(condition = "#processEvent.flowCode.startsWith('leave')")
public void processHandler(ProcessEvent processEvent) {
log.info("当前任务执行了{}", processEvent.toString());
TestLeave testLeave = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessId()));
testLeave.setStatus(processEvent.getStatus());
// 用于例如审批附件 审批意见等 存储到业务表内 自行根据业务实现存储流程
Map<String, Object> params = processEvent.getParams();
@@ -188,7 +188,7 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
@EventListener(condition = "#processDeleteEvent.flowCode.startsWith('leave')")
public void processDeleteHandler(ProcessDeleteEvent processDeleteEvent) {
log.info("监听删除流程事件,当前任务执行了{}", processDeleteEvent.toString());
TestLeave testLeave = baseMapper.selectById(Convert.toLong(processDeleteEvent.getBusinessId()));
TestLeave testLeave = baseMapper.selectById(Long.valueOf(processDeleteEvent.getBusinessId()));
if (ObjectUtil.isNull(testLeave)) {
return;
}

View File

@@ -4,4 +4,8 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.workflow.mapper.FlwCategoryMapper">
<select id="countCategoryById" resultType="Long">
select count(*) from flow_category where del_flag = '0' and category_id = #{categoryId}
</select>
</mapper>

View File

@@ -99,7 +99,7 @@ services:
network_mode: "host"
ruoyi-server1:
image: ruoyi/ruoyi-server:5.4.1
image: ruoyi/ruoyi-server:5.4.0
container_name: ruoyi-server1
environment:
# 时区上海
@@ -115,7 +115,7 @@ services:
network_mode: "host"
ruoyi-server2:
image: ruoyi/ruoyi-server:5.4.1
image: ruoyi/ruoyi-server:5.4.0
container_name: ruoyi-server2
environment:
# 时区上海
@@ -131,7 +131,7 @@ services:
network_mode: "host"
ruoyi-monitor-admin:
image: ruoyi/ruoyi-monitor-admin:5.4.1
image: ruoyi/ruoyi-monitor-admin:5.4.0
container_name: ruoyi-monitor-admin
environment:
# 时区上海
@@ -143,7 +143,7 @@ services:
network_mode: "host"
ruoyi-snailjob-server:
image: ruoyi/ruoyi-snailjob-server:5.4.1
image: ruoyi/ruoyi-snailjob-server:5.4.0
container_name: ruoyi-snailjob-server
environment:
# 时区上海

View File

@@ -411,7 +411,7 @@ CREATE TABLE sj_distributed_lock
);
ALTER TABLE sj_distributed_lock
ADD CONSTRAINT pk_sj_distributed_lock PRIMARY KEY (name);
ADD CONSTRAINT pk_sj_distributed_lock PRIMARY KEY (id);
COMMENT ON COLUMN sj_distributed_lock.name IS '锁名称';
COMMENT ON COLUMN sj_distributed_lock.lock_until IS '锁定时长';

View File

@@ -447,10 +447,10 @@ insert into sys_menu values('115', '代码生成', '3', '2', 'gen',
insert into sys_menu values('121', '租户管理', '6', '1', 'tenant', 'system/tenant/index', '', 1, 0, 'C', '0', '0', 'system:tenant:list', 'list', 103, 1, sysdate, null, null, '租户管理菜单');
insert into sys_menu values('122', '租户套餐管理', '6', '2', 'tenantPackage', 'system/tenantPackage/index', '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list', 'form', 103, 1, sysdate, null, null, '租户套餐管理菜单');
insert into sys_menu values('123', '客户端管理', '1', '11', 'client', 'system/client/index', '', 1, 0, 'C', '0', '0', 'system:client:list', 'international', 103, 1, sysdate, null, null, '客户端管理菜单');
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', 1, 1, 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, sysdate, null, null, '');
-- springboot-admin监控
@@ -623,10 +623,6 @@ insert into sys_role_menu values ('3', '107');
insert into sys_role_menu values ('3', '108');
insert into sys_role_menu values ('3', '118');
insert into sys_role_menu values ('3', '123');
insert into sys_role_menu values ('3', '130');
insert into sys_role_menu values ('3', '131');
insert into sys_role_menu values ('3', '132');
insert into sys_role_menu values ('3', '133');
insert into sys_role_menu values ('3', '500');
insert into sys_role_menu values ('3', '501');
insert into sys_role_menu values ('3', '1001');
@@ -700,11 +696,8 @@ insert into sys_role_menu values ('3', '1620');
insert into sys_role_menu values ('3', '1621');
insert into sys_role_menu values ('3', '1622');
insert into sys_role_menu values ('3', '1623');
insert into sys_role_menu values ('3', '11616');
insert into sys_role_menu values ('3', '11618');
insert into sys_role_menu values ('3', '11619');
insert into sys_role_menu values ('3', '11622');
insert into sys_role_menu values ('3', '11623');
insert into sys_role_menu values ('3', '11629');
insert into sys_role_menu values ('3', '11632');
insert into sys_role_menu values ('3', '11633');
@@ -714,7 +707,6 @@ insert into sys_role_menu values ('3', '11640');
insert into sys_role_menu values ('3', '11641');
insert into sys_role_menu values ('3', '11642');
insert into sys_role_menu values ('3', '11643');
insert into sys_role_menu values ('3', '11701');
insert into sys_role_menu values ('4', '5');
insert into sys_role_menu values ('4', '1500');
insert into sys_role_menu values ('4', '1501');

View File

@@ -61,7 +61,7 @@ create table FLOW_NODE
VERSION VARCHAR2(20),
CREATE_TIME DATE,
UPDATE_TIME DATE,
EXT CLOB,
EXT VARCHAR2(500),
DEL_FLAG VARCHAR2(1) default '0',
TENANT_ID VARCHAR2(40),
PERMISSION_FLAG VARCHAR2(200)
@@ -88,10 +88,10 @@ comment on column FLOW_NODE.FORM_PATH is '审批表单路径';
comment on column FLOW_NODE.VERSION is '版本';
comment on column FLOW_NODE.CREATE_TIME is '创建时间';
comment on column FLOW_NODE.UPDATE_TIME is '更新时间';
comment on column FLOW_NODE.EXT is '节点扩展属性';
comment on column FLOW_NODE.EXT is '扩展属性';
comment on column FLOW_NODE.DEL_FLAG is '删除标志';
comment on column FLOW_NODE.TENANT_ID is '租户id';
comment on column FLOW_NODE.PERMISSION_FLAG is '权限标识(权限类型:权限标识,可以多个,用@@隔开)';
comment on column FLOW_NODE.PERMISSION_FLAG is '权限标识(权限类型:权限标识,可以多个,用逗号隔开)';
create table FLOW_SKIP
(
@@ -179,7 +179,7 @@ create table FLOW_TASK
NODE_CODE VARCHAR2(100),
NODE_NAME VARCHAR2(100),
NODE_TYPE NUMBER(1),
FLOW_STATUS VARCHAR2(20),
FLOW_STATUS VARCHAR2(20),
FORM_CUSTOM VARCHAR2(1) default 'N',
FORM_PATH VARCHAR2(100),
CREATE_TIME DATE,
@@ -226,7 +226,7 @@ create table FLOW_HIS_TASK
FORM_PATH VARCHAR2(100),
MESSAGE VARCHAR2(500),
VARIABLE CLOB,
EXT CLOB,
EXT VARCHAR2(500),
CREATE_TIME DATE,
UPDATE_TIME DATE,
DEL_FLAG VARCHAR2(1) default '0',

View File

@@ -448,10 +448,10 @@ insert into sys_menu values('115', '代码生成', '3', '2', 'gen',
insert into sys_menu values('121', '租户管理', '6', '1', 'tenant', 'system/tenant/index', '', '1', '0', 'C', '0', '0', 'system:tenant:list', 'list', 103, 1, now(), null, null, '租户管理菜单');
insert into sys_menu values('122', '租户套餐管理', '6', '2', 'tenantPackage', 'system/tenantPackage/index', '', '1', '0', 'C', '0', '0', 'system:tenantPackage:list', 'form', 103, 1, now(), null, null, '租户套餐管理菜单');
insert into sys_menu values('123', '客户端管理', '1', '11', 'client', 'system/client/index', '', '1', '0', 'C', '0', '0', 'system:client:list', 'international', 103, 1, now(), null, null, '客户端管理菜单');
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId', 'tool/gen/editTable', '', '1', '1', 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId', 'system/role/authUser', '', '1', '1', 'C', '1', '0', 'system:role:edit', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId', 'system/user/authRole', '', '1', '1', 'C', '1', '0', 'system:user:edit', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId', 'system/dict/data', '', '1', '1', 'C', '1', '0', 'system:dict:list', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', '1', '1', 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', '1', '1', 'C', '1', '0', 'system:role:edit', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', '1', '1', 'C', '1', '0', 'system:user:edit', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', '1', '1', 'C', '1', '0', 'system:dict:list', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', '1', '1', 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, now(), null, null, '');
-- springboot-admin监控
@@ -624,10 +624,6 @@ insert into sys_role_menu values ('3', '107');
insert into sys_role_menu values ('3', '108');
insert into sys_role_menu values ('3', '118');
insert into sys_role_menu values ('3', '123');
insert into sys_role_menu values ('3', '130');
insert into sys_role_menu values ('3', '131');
insert into sys_role_menu values ('3', '132');
insert into sys_role_menu values ('3', '133');
insert into sys_role_menu values ('3', '500');
insert into sys_role_menu values ('3', '501');
insert into sys_role_menu values ('3', '1001');
@@ -701,11 +697,8 @@ insert into sys_role_menu values ('3', '1620');
insert into sys_role_menu values ('3', '1621');
insert into sys_role_menu values ('3', '1622');
insert into sys_role_menu values ('3', '1623');
insert into sys_role_menu values ('3', '11616');
insert into sys_role_menu values ('3', '11618');
insert into sys_role_menu values ('3', '11619');
insert into sys_role_menu values ('3', '11622');
insert into sys_role_menu values ('3', '11623');
insert into sys_role_menu values ('3', '11629');
insert into sys_role_menu values ('3', '11632');
insert into sys_role_menu values ('3', '11633');
@@ -715,7 +708,6 @@ insert into sys_role_menu values ('3', '11640');
insert into sys_role_menu values ('3', '11641');
insert into sys_role_menu values ('3', '11642');
insert into sys_role_menu values ('3', '11643');
insert into sys_role_menu values ('3', '11701');
insert into sys_role_menu values ('4', '5');
insert into sys_role_menu values ('4', '1500');
insert into sys_role_menu values ('4', '1501');

View File

@@ -47,7 +47,7 @@ CREATE TABLE flow_node
definition_id int8 NOT NULL, -- 流程定义id
node_code varchar(100) NOT NULL, -- 流程节点编码
node_name varchar(100) NULL, -- 流程节点名称
permission_flag varchar(200) NULL, -- 权限标识(权限类型:权限标识,可以多个,用@@隔开)
permission_flag varchar(200) NULL, -- 权限标识(权限类型:权限标识,可以多个,用逗号隔开)
node_ratio numeric(6, 3) NULL, -- 流程签署比例值
coordinate varchar(100) NULL, -- 坐标
any_node_skip varchar(100) NULL, -- 任意结点跳转
@@ -60,7 +60,7 @@ CREATE TABLE flow_node
"version" varchar(20) NOT NULL, -- 版本
create_time timestamp NULL, -- 创建时间
update_time timestamp NULL, -- 更新时间
ext text NULL, -- 扩展属性
ext varchar(500) NULL, -- 扩展属性
del_flag bpchar(1) NULL DEFAULT '0':: character varying, -- 删除标志
tenant_id varchar(40) NULL, -- 租户id
CONSTRAINT flow_node_pkey PRIMARY KEY (id)
@@ -72,7 +72,7 @@ COMMENT ON COLUMN flow_node.node_type IS '节点类型0开始节点 1中间
COMMENT ON COLUMN flow_node.definition_id IS '流程定义id';
COMMENT ON COLUMN flow_node.node_code IS '流程节点编码';
COMMENT ON COLUMN flow_node.node_name IS '流程节点名称';
COMMENT ON COLUMN flow_node.permission_flag IS '权限标识(权限类型:权限标识,可以多个,用@@隔开)';
COMMENT ON COLUMN flow_node.permission_flag IS '权限标识(权限类型:权限标识,可以多个,用逗号隔开)';
COMMENT ON COLUMN flow_node.node_ratio IS '流程签署比例值';
COMMENT ON COLUMN flow_node.coordinate IS '坐标';
COMMENT ON COLUMN flow_node.any_node_skip IS '任意结点跳转';
@@ -85,7 +85,7 @@ COMMENT ON COLUMN flow_node.form_path IS '审批表单路径';
COMMENT ON COLUMN flow_node."version" IS '版本';
COMMENT ON COLUMN flow_node.create_time IS '创建时间';
COMMENT ON COLUMN flow_node.update_time IS '更新时间';
COMMENT ON COLUMN flow_node.ext IS '节点扩展属性';
COMMENT ON COLUMN flow_node.ext IS '扩展属性';
COMMENT ON COLUMN flow_node.del_flag IS '删除标志';
COMMENT ON COLUMN flow_node.tenant_id IS '租户id';
@@ -172,7 +172,7 @@ CREATE TABLE flow_task
node_code varchar(100) NOT NULL, -- 节点编码
node_name varchar(100) NULL, -- 节点名称
node_type int2 NOT NULL, -- 节点类型0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关
flow_status varchar(20) NOT NULL, -- 流程状态0待提交 1审批中 2 审批通过 8已完成 9已退回 10失效
flow_status varchar(20) NOT NULL, -- 流程状态0待提交 1审批中 2 审批通过 8已完成 9已退回 10失效
form_custom bpchar(1) NULL DEFAULT 'N':: character varying, -- 审批表单是否自定义Y是 N否
form_path varchar(100) NULL, -- 审批表单路径
create_time timestamp NULL, -- 创建时间
@@ -215,7 +215,7 @@ CREATE TABLE flow_his_task
flow_status varchar(20) NOT NULL, -- 流程状态0待提交 1审批中 2 审批通过 8已完成 9已退回 10失效
form_custom bpchar(1) NULL DEFAULT 'N':: character varying, -- 审批表单是否自定义Y是 N否
form_path varchar(100) NULL, -- 审批表单路径
ext text NULL, -- 扩展字段,预留给业务系统使用
ext varchar(500) NULL, -- 扩展字段,预留给业务系统使用
message varchar(500) NULL, -- 审批意见
variable text NULL, -- 任务变量
create_time timestamp NULL, -- 创建时间
@@ -265,6 +265,7 @@ CREATE TABLE flow_user
);
CREATE INDEX user_processed_type ON flow_user USING btree (processed_by, type);
CREATE INDEX user_associated_idx ON FLOW_USER USING btree (associated);
COMMENT ON TABLE flow_user IS '流程用户表';
COMMENT ON COLUMN flow_user.id IS '主键id';

View File

@@ -282,10 +282,10 @@ insert into sys_menu values('115', '代码生成', '3', '2', 'gen',
insert into sys_menu values('121', '租户管理', '6', '1', 'tenant', 'system/tenant/index', '', 1, 0, 'C', '0', '0', 'system:tenant:list', 'list', 103, 1, sysdate(), null, null, '租户管理菜单');
insert into sys_menu values('122', '租户套餐管理', '6', '2', 'tenantPackage', 'system/tenantPackage/index', '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list', 'form', 103, 1, sysdate(), null, null, '租户套餐管理菜单');
insert into sys_menu values('123', '客户端管理', '1', '11', 'client', 'system/client/index', '', 1, 0, 'C', '0', '0', 'system:client:list', 'international', 103, 1, sysdate(), null, null, '客户端管理菜单');
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('116', '修改生成配置', '3', '2', 'gen-edit/index/:tableId(\\d+)', 'tool/gen/editTable', '', 1, 1, 'C', '1', '0', 'tool:gen:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('130', '分配用户', '1', '2', 'role-auth/user/:roleId(\\d+)', 'system/role/authUser', '', 1, 1, 'C', '1', '0', 'system:role:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('131', '分配角色', '1', '1', 'user-auth/role/:userId(\\d+)', 'system/user/authRole', '', 1, 1, 'C', '1', '0', 'system:user:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('132', '字典数据', '1', '6', 'dict-data/index/:dictId(\\d+)', 'system/dict/data', '', 1, 1, 'C', '1', '0', 'system:dict:list', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('133', '文件配置管理', '1', '10', 'oss-config/index', 'system/oss/config', '', 1, 1, 'C', '1', '0', 'system:ossConfig:list', '#', 103, 1, sysdate(), null, null, '');
-- springboot-admin监控
@@ -448,10 +448,6 @@ insert into sys_role_menu values ('3', '107');
insert into sys_role_menu values ('3', '108');
insert into sys_role_menu values ('3', '118');
insert into sys_role_menu values ('3', '123');
insert into sys_role_menu values ('3', '130');
insert into sys_role_menu values ('3', '131');
insert into sys_role_menu values ('3', '132');
insert into sys_role_menu values ('3', '133');
insert into sys_role_menu values ('3', '500');
insert into sys_role_menu values ('3', '501');
insert into sys_role_menu values ('3', '1001');
@@ -525,11 +521,8 @@ insert into sys_role_menu values ('3', '1620');
insert into sys_role_menu values ('3', '1621');
insert into sys_role_menu values ('3', '1622');
insert into sys_role_menu values ('3', '1623');
insert into sys_role_menu values ('3', '11616');
insert into sys_role_menu values ('3', '11618');
insert into sys_role_menu values ('3', '11619');
insert into sys_role_menu values ('3', '11622');
insert into sys_role_menu values ('3', '11623');
insert into sys_role_menu values ('3', '11629');
insert into sys_role_menu values ('3', '11632');
insert into sys_role_menu values ('3', '11633');
@@ -539,7 +532,6 @@ insert into sys_role_menu values ('3', '11640');
insert into sys_role_menu values ('3', '11641');
insert into sys_role_menu values ('3', '11642');
insert into sys_role_menu values ('3', '11643');
insert into sys_role_menu values ('3', '11701');
insert into sys_role_menu values ('4', '5');
insert into sys_role_menu values ('4', '1500');
insert into sys_role_menu values ('4', '1501');

View File

@@ -29,7 +29,7 @@ CREATE TABLE `flow_node`
`definition_id` bigint NOT NULL COMMENT '流程定义id',
`node_code` varchar(100) NOT NULL COMMENT '流程节点编码',
`node_name` varchar(100) DEFAULT NULL COMMENT '流程节点名称',
`permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用@@隔开)',
`permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用逗号隔开)',
`node_ratio` decimal(6, 3) DEFAULT NULL COMMENT '流程签署比例值',
`coordinate` varchar(100) DEFAULT NULL COMMENT '坐标',
`any_node_skip` varchar(100) DEFAULT NULL COMMENT '任意结点跳转',
@@ -42,7 +42,7 @@ CREATE TABLE `flow_node`
`version` varchar(20) NOT NULL COMMENT '版本',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`ext` text COMMENT '节点扩展属性',
`ext` text COMMENT '扩展属性',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
PRIMARY KEY (`id`) USING BTREE
@@ -108,25 +108,25 @@ CREATE TABLE `flow_task`
CREATE TABLE `flow_his_task`
(
`id` bigint(20) NOT NULL COMMENT '主键id',
`definition_id` bigint(20) NOT NULL COMMENT '对应flow_definition表的id',
`instance_id` bigint(20) NOT NULL COMMENT '对应flow_instance表的id',
`task_id` bigint(20) NOT NULL COMMENT '对应flow_task表的id',
`id` bigint(20) NOT NULL COMMENT '主键id',
`definition_id` bigint(20) NOT NULL COMMENT '对应flow_definition表的id',
`instance_id` bigint(20) NOT NULL COMMENT '对应flow_instance表的id',
`task_id` bigint(20) NOT NULL COMMENT '对应flow_task表的id',
`node_code` varchar(100) DEFAULT NULL COMMENT '开始节点编码',
`node_name` varchar(100) DEFAULT NULL COMMENT '开始节点名称',
`node_type` tinyint(1) DEFAULT NULL COMMENT '开始节点类型0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关',
`target_node_code` varchar(200) DEFAULT NULL COMMENT '目标节点编码',
`target_node_name` varchar(200) DEFAULT NULL COMMENT '结束节点名称',
`approver` varchar(40) DEFAULT NULL COMMENT '审批者',
`cooperate_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)',
`cooperate_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)',
`collaborator` varchar(40) DEFAULT NULL COMMENT '协作人',
`skip_type` varchar(10) NOT NULL COMMENT '流转类型PASS通过 REJECT退回 NONE无动作',
`flow_status` varchar(20) NOT NULL COMMENT '流程状态0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回',
`skip_type` varchar(10) NOT NULL COMMENT '流转类型PASS通过 REJECT退回 NONE无动作',
`flow_status` varchar(20) NOT NULL COMMENT '流程状态0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回',
`form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义Y是 N否',
`form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径',
`message` varchar(500) DEFAULT NULL COMMENT '审批意见',
`variable` TEXT DEFAULT NULL COMMENT '任务变量',
`ext` TEXT DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串',
`ext` varchar(500) DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串',
`create_time` datetime DEFAULT NULL COMMENT '任务开始时间',
`update_time` datetime DEFAULT NULL COMMENT '审批完成时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',

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