diff --git a/pom.xml b/pom.xml
index a1891c9304..56a41ac4d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
https://github.com/YunaiV/ruoyi-vue-pro
- 2025.09-SNAPSHOT
+ 2025.10-SNAPSHOT
17
${java.version}
diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index e08f834fb9..8963fbd5d7 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -14,7 +14,7 @@
https://github.com/YunaiV/ruoyi-vue-pro
- 2025.09-SNAPSHOT
+ 2025.10-SNAPSHOT
1.7.2
3.5.5
diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
index b2bb28dbc1..554f482b6c 100644
--- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
@@ -51,7 +51,7 @@ public class YudaoWebAutoConfiguration {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
- var mapping = new RequestMappingHandlerMapping();
+ RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
// 实例化时就带上前缀
mapping.setPathPrefixes(buildPathPrefixes(webProperties));
return mapping;
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
index 00bf62ea83..a796fdb626 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.service.task;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
-import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
@@ -14,7 +13,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
@@ -73,7 +71,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNode;
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum.REJECT_CHILD_PROCESS;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.START_USER_NODE_ID;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX;
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseNodeType;
@@ -237,8 +234,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
needSimulateTaskDefKeysByReturn.add(StrUtil.removePrefix(key, PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX)));
}
// 移除运行中的节点,运行中的节点无需预测
- // TODO @jason:是不是 foreach runActivityNodes,然后移除 needSimulateTaskDefKeysByReturn 更好?(理解成本低一点)
- CollectionUtils.convertList(runActivityNodes, ActivityNode::getId).forEach(needSimulateTaskDefKeysByReturn::remove);
+ if (CollUtil.isNotEmpty(runActivityNodes)) {
+ runActivityNodes.forEach( activityNode -> needSimulateTaskDefKeysByReturn.remove(activityNode.getId()));
+ }
// 3.3 预测未运行节点的审批信息
List simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
index 342a8c6895..57450a9a6b 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.service.task;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
-import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.*;
import cn.hutool.extra.spring.SpringUtil;
@@ -939,9 +938,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 3. 构建需要预测的任务流程变量
// TODO @jason:【驳回预测相关】是不是搞成一个变量,里面是 set 更简洁一点呀?
- Set taskDefinitionKeyList = getNeedSimulateTaskDefinitionKeys(bpmnModel, currentTask, targetElement);
- Map needSimulateVariables = convertMap(taskDefinitionKeyList,
- taskId -> StrUtil.concat(false, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX, taskId), item -> Boolean.TRUE);
+ Set needSimulateTaskDefinitionKeys = getNeedSimulateTaskDefinitionKeys(bpmnModel, currentTask, targetElement);
+ Map needSimulateVariables = convertMap(needSimulateTaskDefinitionKeys,
+ key -> StrUtil.concat(false, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX, key), item -> Boolean.TRUE);
+
// 4. 执行驳回
// 使用 moveExecutionsToSingleActivityId 替换 moveActivityIdsToSingleActivityId 原因:
@@ -962,22 +962,22 @@ public class BpmTaskServiceImpl implements BpmTaskService {
// 1. 获取需要预测的任务的 definition key。因为当前任务还没完成,也需要预测
Set taskDefinitionKeys = CollUtil.newHashSet(currentTask.getTaskDefinitionKey());
- // 2.1 从已结束任务中找到要回退的目标任务,按时间倒序最近的一个目标任务
+ // 2.1 获取已结束任务按时间倒序排序
List endTaskList = CollectionUtils.filterList(
getTaskListByProcessInstanceId(currentTask.getProcessInstanceId(), Boolean.FALSE),
item -> item.getEndTime() != null);
- // 2.2 遍历已结束的任务,找到在 targetTask 之后生成的任务,且串行可达的任务
+ // 2.2 从结束任务中找到最近一个的目标任务
HistoricTaskInstance targetTask = findFirst(endTaskList,
item -> item.getTaskDefinitionKey().equals(targetElement.getId()));
- // TODO @jason:【驳回预测相关】是不是 if targetTask 先判空?
+ if (targetTask == null) {
+ return taskDefinitionKeys;
+ }
+ // 2.3 遍历已结束的任务,找到在 targetTask 之后生成的任务,且串行可达的任务
endTaskList.forEach(item -> {
FlowElement element = getFlowElementById(bpmnModel, item.getTaskDefinitionKey());
- // 如果已结束的任务在回退目标节点之后生成,且串行可达,则标记为需要预算节点
+ // 如果已结束的任务在回退目标节点之后生成,且串行可达,则加到需要预测节点中
// TODO 串行可达的方法需要和判断可回退节点 validateTargetTaskCanReturn 分开吗? 并行网关可能会有问题。
- // TODO @jason:【驳回预测相关】这里是不是判断 element 哈?
- if (targetTask != null
- // TODO @jason:【驳回预测相关】这里直接 createTime 的 compare 更简单?因为不太会出现空哈。
- && DateUtil.compare(item.getCreateTime(), targetTask.getCreateTime()) > 0
+ if (item.getCreateTime().compareTo(targetTask.getCreateTime()) > 0
&& BpmnModelUtils.isSequentialReachable(element, targetElement, null)) {
taskDefinitionKeys.add(item.getTaskDefinitionKey());
}
diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
index 58d64fc2c1..e2b131db1b 100644
--- a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
+++ b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
@@ -124,7 +124,6 @@ export function useFormSchema(): VbenFormSchema[] {
component: 'InputNumber',
componentProps: {
min: 0,
- controlsPosition: 'right',
placeholder: '请输入${comment}',
},
#end
@@ -326,7 +325,6 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
component: 'InputNumber',
componentProps: {
min: 0,
- controlsPosition: 'right',
placeholder: '请输入${comment}',
},
#end
@@ -560,7 +558,6 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${api
component: 'InputNumber',
componentProps: {
min: 0,
- controlsPosition: 'right',
placeholder: '请输入${comment}',
},
#end
diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
index e94f439f43..ea654da0b9 100644
--- a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
+++ b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
@@ -127,9 +127,7 @@ const [Modal, modalApi] = useVbenModal({
try {
formData.value = await get${simpleClassName}(data.id);
// 设置到 values
- if (formData.value) {
- await formApi.setValues(formData.value);
- }
+ await formApi.setValues(formData.value);
} finally {
modalApi.unlock();
}
diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm
index 375a3c90ac..da9582448e 100644
--- a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm
+++ b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm
@@ -124,8 +124,9 @@ export function useFormSchema(): VbenFormSchema[] {
component: 'InputNumber',
componentProps: {
min: 0,
- controlsPosition: 'right',
placeholder: '请输入${comment}',
+ controlsPosition: 'right',
+ class: '!w-full',
},
#end
},
@@ -326,8 +327,9 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
component: 'InputNumber',
componentProps: {
min: 0,
- controlsPosition: 'right',
placeholder: '请输入${comment}',
+ controlsPosition: 'right',
+ class: '!w-full',
},
#end
},
@@ -560,8 +562,9 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${api
component: 'InputNumber',
componentProps: {
min: 0,
- controlsPosition: 'right',
placeholder: '请输入${comment}',
+ controlsPosition: 'right',
+ class: '!w-full',
},
#end
},
diff --git a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm
index c3342c4d49..fa4c346061 100644
--- a/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm
+++ b/yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm
@@ -127,9 +127,7 @@ const [Modal, modalApi] = useVbenModal({
try {
formData.value = await get${simpleClassName}(data.id);
// 设置到 values
- if (formData.value) {
- await formApi.setValues(formData.value);
- }
+ await formApi.setValues(formData.value);
} finally {
modalApi.unlock();
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java
index a29ff98616..0de5107acd 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java
@@ -240,24 +240,20 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
* @return 规则场景列表
*/
private List getMatchedSceneRuleListByMessage(IotDeviceMessage message) {
- // 1. 匹配设备
- // TODO 缓存 @puhui999:可能需要 getSelf()
// 1.1 通过 deviceId 获取设备信息
IotDeviceDO device = getSelf().deviceService.getDeviceFromCache(message.getDeviceId());
if (device == null) {
log.warn("[getMatchedSceneRuleListByMessage][设备({}) 不存在]", message.getDeviceId());
- return List.of();
+ return ListUtil.of();
}
-
// 1.2 通过 productId 获取产品信息
IotProductDO product = getSelf().productService.getProductFromCache(device.getProductId());
if (product == null) {
log.warn("[getMatchedSceneRuleListByMessage][产品({}) 不存在]", device.getProductId());
- return List.of();
+ return ListUtil.of();
}
-
// 1.3 获取匹配的规则场景
- List sceneRules = getSceneRuleListByProductIdAndDeviceIdFromCache(
+ List sceneRules = getSelf().getSceneRuleListByProductIdAndDeviceIdFromCache(
product.getId(), device.getId());
if (CollUtil.isEmpty(sceneRules)) {
return sceneRules;
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java
index dd10ed8134..79da298442 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.iot.service.rule.scene.action;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
@@ -126,7 +127,7 @@ public class IotDeviceControlSceneRuleAction implements IotSceneRuleAction {
private IotDeviceMessage buildPropertySetMessage(IotSceneRuleDO.Action actionConfig, IotDeviceDO device) {
try {
// 属性设置参数格式: {"properties": {"identifier": value}}
- Object params = Map.of("properties", Map.of(actionConfig.getIdentifier(), actionConfig.getParams()));
+ Object params = MapUtil.of("properties", MapUtil.of(actionConfig.getIdentifier(), actionConfig.getParams()));
return IotDeviceMessage.requestOf(IotDeviceMessageMethodEnum.PROPERTY_SET.getMethod(), params);
} catch (Exception e) {
log.error("[buildPropertySetMessage][构建属性设置消息异常]", e);
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java
index eb7bedf2f0..646990601f 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.iot.service.rule.scene.action;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
@@ -13,6 +14,8 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -126,10 +129,10 @@ public class IotDeviceServiceInvokeSceneRuleAction implements IotSceneRuleAction
private IotDeviceMessage buildServiceInvokeMessage(IotSceneRuleDO.Action actionConfig, IotDeviceDO device) {
try {
// 服务调用参数格式: {"identifier": "serviceId", "params": {...}}
- Object params = Map.of(
- "identifier", actionConfig.getIdentifier(),
- "params", actionConfig.getParams() != null ? actionConfig.getParams() : Map.of()
- );
+ Object params = MapUtil.builder()
+ .put("identifier", actionConfig.getIdentifier())
+ .put("params", actionConfig.getParams() != null ? actionConfig.getParams() : Collections.emptyMap())
+ .build();
return IotDeviceMessage.requestOf(IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod(), params);
} catch (Exception e) {
log.error("[buildServiceInvokeMessage][构建服务调用消息异常]", e);