Commit 5c17595593e561a667edfbdc5f374a391e9c6d9e
Committed by
GitHub
Merge branch 'YunaiV:master-jdk17' into master-jdk17
Showing
12 changed files
with
38 additions
and
44 deletions
pom.xml
| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 33 | 33 | |
| 34 | 34 | <properties> |
| 35 | - <revision>2025.09-SNAPSHOT</revision> | |
| 35 | + <revision>2025.10-SNAPSHOT</revision> | |
| 36 | 36 | <!-- Maven 相关 --> |
| 37 | 37 | <java.version>17</java.version> |
| 38 | 38 | <maven.compiler.source>${java.version}</maven.compiler.source> | ... | ... |
yudao-dependencies/pom.xml
| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 15 | 15 | |
| 16 | 16 | <properties> |
| 17 | - <revision>2025.09-SNAPSHOT</revision> | |
| 17 | + <revision>2025.10-SNAPSHOT</revision> | |
| 18 | 18 | <flatten-maven-plugin.version>1.7.2</flatten-maven-plugin.version> |
| 19 | 19 | <!-- 统一依赖管理 --> |
| 20 | 20 | <spring.boot.version>3.5.5</spring.boot.version> | ... | ... |
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 { |
| 51 | 51 | |
| 52 | 52 | @Override |
| 53 | 53 | public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { |
| 54 | - var mapping = new RequestMappingHandlerMapping(); | |
| 54 | + RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping(); | |
| 55 | 55 | // 实例化时就带上前缀 |
| 56 | 56 | mapping.setPathPrefixes(buildPathPrefixes(webProperties)); |
| 57 | 57 | return mapping; | ... | ... |
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; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.collection.ListUtil; |
| 5 | -import cn.hutool.core.date.DatePattern; | |
| 6 | 5 | import cn.hutool.core.date.DateUtil; |
| 7 | 6 | import cn.hutool.core.lang.Assert; |
| 8 | 7 | import cn.hutool.core.map.MapUtil; |
| ... | ... | @@ -14,7 +13,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 14 | 13 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 15 | 14 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; |
| 16 | 15 | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| 17 | -import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; | |
| 18 | 16 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; |
| 19 | 17 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| 20 | 18 | 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 |
| 73 | 71 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 74 | 72 | import static cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNode; |
| 75 | 73 | import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; |
| 76 | -import static cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum.REJECT_CHILD_PROCESS; | |
| 77 | 74 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.START_USER_NODE_ID; |
| 78 | 75 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX; |
| 79 | 76 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseNodeType; |
| ... | ... | @@ -237,8 +234,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService |
| 237 | 234 | needSimulateTaskDefKeysByReturn.add(StrUtil.removePrefix(key, PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX))); |
| 238 | 235 | } |
| 239 | 236 | // 移除运行中的节点,运行中的节点无需预测 |
| 240 | - // TODO @jason:是不是 foreach runActivityNodes,然后移除 needSimulateTaskDefKeysByReturn 更好?(理解成本低一点) | |
| 241 | - CollectionUtils.convertList(runActivityNodes, ActivityNode::getId).forEach(needSimulateTaskDefKeysByReturn::remove); | |
| 237 | + if (CollUtil.isNotEmpty(runActivityNodes)) { | |
| 238 | + runActivityNodes.forEach( activityNode -> needSimulateTaskDefKeysByReturn.remove(activityNode.getId())); | |
| 239 | + } | |
| 242 | 240 | |
| 243 | 241 | // 3.3 预测未运行节点的审批信息 |
| 244 | 242 | List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel, | ... | ... |
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; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.convert.Convert; |
| 5 | -import cn.hutool.core.date.DateUtil; | |
| 6 | 5 | import cn.hutool.core.lang.Assert; |
| 7 | 6 | import cn.hutool.core.util.*; |
| 8 | 7 | import cn.hutool.extra.spring.SpringUtil; |
| ... | ... | @@ -939,9 +938,10 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 939 | 938 | |
| 940 | 939 | // 3. 构建需要预测的任务流程变量 |
| 941 | 940 | // TODO @jason:【驳回预测相关】是不是搞成一个变量,里面是 set 更简洁一点呀? |
| 942 | - Set<String> taskDefinitionKeyList = getNeedSimulateTaskDefinitionKeys(bpmnModel, currentTask, targetElement); | |
| 943 | - Map<String, Object> needSimulateVariables = convertMap(taskDefinitionKeyList, | |
| 944 | - taskId -> StrUtil.concat(false, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX, taskId), item -> Boolean.TRUE); | |
| 941 | + Set<String> needSimulateTaskDefinitionKeys = getNeedSimulateTaskDefinitionKeys(bpmnModel, currentTask, targetElement); | |
| 942 | + Map<String, Object> needSimulateVariables = convertMap(needSimulateTaskDefinitionKeys, | |
| 943 | + key -> StrUtil.concat(false, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX, key), item -> Boolean.TRUE); | |
| 944 | + | |
| 945 | 945 | |
| 946 | 946 | // 4. 执行驳回 |
| 947 | 947 | // 使用 moveExecutionsToSingleActivityId 替换 moveActivityIdsToSingleActivityId 原因: |
| ... | ... | @@ -962,22 +962,22 @@ public class BpmTaskServiceImpl implements BpmTaskService { |
| 962 | 962 | // 1. 获取需要预测的任务的 definition key。因为当前任务还没完成,也需要预测 |
| 963 | 963 | Set<String> taskDefinitionKeys = CollUtil.newHashSet(currentTask.getTaskDefinitionKey()); |
| 964 | 964 | |
| 965 | - // 2.1 从已结束任务中找到要回退的目标任务,按时间倒序最近的一个目标任务 | |
| 965 | + // 2.1 获取已结束任务按时间倒序排序 | |
| 966 | 966 | List<HistoricTaskInstance> endTaskList = CollectionUtils.filterList( |
| 967 | 967 | getTaskListByProcessInstanceId(currentTask.getProcessInstanceId(), Boolean.FALSE), |
| 968 | 968 | item -> item.getEndTime() != null); |
| 969 | - // 2.2 遍历已结束的任务,找到在 targetTask 之后生成的任务,且串行可达的任务 | |
| 969 | + // 2.2 从结束任务中找到最近一个的目标任务 | |
| 970 | 970 | HistoricTaskInstance targetTask = findFirst(endTaskList, |
| 971 | 971 | item -> item.getTaskDefinitionKey().equals(targetElement.getId())); |
| 972 | - // TODO @jason:【驳回预测相关】是不是 if targetTask 先判空? | |
| 972 | + if (targetTask == null) { | |
| 973 | + return taskDefinitionKeys; | |
| 974 | + } | |
| 975 | + // 2.3 遍历已结束的任务,找到在 targetTask 之后生成的任务,且串行可达的任务 | |
| 973 | 976 | endTaskList.forEach(item -> { |
| 974 | 977 | FlowElement element = getFlowElementById(bpmnModel, item.getTaskDefinitionKey()); |
| 975 | - // 如果已结束的任务在回退目标节点之后生成,且串行可达,则标记为需要预算节点 | |
| 978 | + // 如果已结束的任务在回退目标节点之后生成,且串行可达,则加到需要预测节点中 | |
| 976 | 979 | // TODO 串行可达的方法需要和判断可回退节点 validateTargetTaskCanReturn 分开吗? 并行网关可能会有问题。 |
| 977 | - // TODO @jason:【驳回预测相关】这里是不是判断 element 哈? | |
| 978 | - if (targetTask != null | |
| 979 | - // TODO @jason:【驳回预测相关】这里直接 createTime 的 compare 更简单?因为不太会出现空哈。 | |
| 980 | - && DateUtil.compare(item.getCreateTime(), targetTask.getCreateTime()) > 0 | |
| 980 | + if (item.getCreateTime().compareTo(targetTask.getCreateTime()) > 0 | |
| 981 | 981 | && BpmnModelUtils.isSequentialReachable(element, targetElement, null)) { |
| 982 | 982 | taskDefinitionKeys.add(item.getTaskDefinitionKey()); |
| 983 | 983 | } | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm
| ... | ... | @@ -124,7 +124,6 @@ export function useFormSchema(): VbenFormSchema[] { |
| 124 | 124 | component: 'InputNumber', |
| 125 | 125 | componentProps: { |
| 126 | 126 | min: 0, |
| 127 | - controlsPosition: 'right', | |
| 128 | 127 | placeholder: '请输入${comment}', |
| 129 | 128 | }, |
| 130 | 129 | #end |
| ... | ... | @@ -326,7 +325,6 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] { |
| 326 | 325 | component: 'InputNumber', |
| 327 | 326 | componentProps: { |
| 328 | 327 | min: 0, |
| 329 | - controlsPosition: 'right', | |
| 330 | 328 | placeholder: '请输入${comment}', |
| 331 | 329 | }, |
| 332 | 330 | #end |
| ... | ... | @@ -560,7 +558,6 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${api |
| 560 | 558 | component: 'InputNumber', |
| 561 | 559 | componentProps: { |
| 562 | 560 | min: 0, |
| 563 | - controlsPosition: 'right', | |
| 564 | 561 | placeholder: '请输入${comment}', |
| 565 | 562 | }, |
| 566 | 563 | #end | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm
| ... | ... | @@ -127,9 +127,7 @@ const [Modal, modalApi] = useVbenModal({ |
| 127 | 127 | try { |
| 128 | 128 | formData.value = await get${simpleClassName}(data.id); |
| 129 | 129 | // 设置到 values |
| 130 | - if (formData.value) { | |
| 131 | - await formApi.setValues(formData.value); | |
| 132 | - } | |
| 130 | + await formApi.setValues(formData.value); | |
| 133 | 131 | } finally { |
| 134 | 132 | modalApi.unlock(); |
| 135 | 133 | } | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm
| ... | ... | @@ -124,8 +124,9 @@ export function useFormSchema(): VbenFormSchema[] { |
| 124 | 124 | component: 'InputNumber', |
| 125 | 125 | componentProps: { |
| 126 | 126 | min: 0, |
| 127 | - controlsPosition: 'right', | |
| 128 | 127 | placeholder: '请输入${comment}', |
| 128 | + controlsPosition: 'right', | |
| 129 | + class: '!w-full', | |
| 129 | 130 | }, |
| 130 | 131 | #end |
| 131 | 132 | }, |
| ... | ... | @@ -326,8 +327,9 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] { |
| 326 | 327 | component: 'InputNumber', |
| 327 | 328 | componentProps: { |
| 328 | 329 | min: 0, |
| 329 | - controlsPosition: 'right', | |
| 330 | 330 | placeholder: '请输入${comment}', |
| 331 | + controlsPosition: 'right', | |
| 332 | + class: '!w-full', | |
| 331 | 333 | }, |
| 332 | 334 | #end |
| 333 | 335 | }, |
| ... | ... | @@ -560,8 +562,9 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${api |
| 560 | 562 | component: 'InputNumber', |
| 561 | 563 | componentProps: { |
| 562 | 564 | min: 0, |
| 563 | - controlsPosition: 'right', | |
| 564 | 565 | placeholder: '请输入${comment}', |
| 566 | + controlsPosition: 'right', | |
| 567 | + class: '!w-full', | |
| 565 | 568 | }, |
| 566 | 569 | #end |
| 567 | 570 | }, | ... | ... |
yudao-module-infra/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm
| ... | ... | @@ -127,9 +127,7 @@ const [Modal, modalApi] = useVbenModal({ |
| 127 | 127 | try { |
| 128 | 128 | formData.value = await get${simpleClassName}(data.id); |
| 129 | 129 | // 设置到 values |
| 130 | - if (formData.value) { | |
| 131 | - await formApi.setValues(formData.value); | |
| 132 | - } | |
| 130 | + await formApi.setValues(formData.value); | |
| 133 | 131 | } finally { |
| 134 | 132 | modalApi.unlock(); |
| 135 | 133 | } | ... | ... |
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 { |
| 240 | 240 | * @return 规则场景列表 |
| 241 | 241 | */ |
| 242 | 242 | private List<IotSceneRuleDO> getMatchedSceneRuleListByMessage(IotDeviceMessage message) { |
| 243 | - // 1. 匹配设备 | |
| 244 | - // TODO 缓存 @puhui999:可能需要 getSelf() | |
| 245 | 243 | // 1.1 通过 deviceId 获取设备信息 |
| 246 | 244 | IotDeviceDO device = getSelf().deviceService.getDeviceFromCache(message.getDeviceId()); |
| 247 | 245 | if (device == null) { |
| 248 | 246 | log.warn("[getMatchedSceneRuleListByMessage][设备({}) 不存在]", message.getDeviceId()); |
| 249 | - return List.of(); | |
| 247 | + return ListUtil.of(); | |
| 250 | 248 | } |
| 251 | - | |
| 252 | 249 | // 1.2 通过 productId 获取产品信息 |
| 253 | 250 | IotProductDO product = getSelf().productService.getProductFromCache(device.getProductId()); |
| 254 | 251 | if (product == null) { |
| 255 | 252 | log.warn("[getMatchedSceneRuleListByMessage][产品({}) 不存在]", device.getProductId()); |
| 256 | - return List.of(); | |
| 253 | + return ListUtil.of(); | |
| 257 | 254 | } |
| 258 | - | |
| 259 | 255 | // 1.3 获取匹配的规则场景 |
| 260 | - List<IotSceneRuleDO> sceneRules = getSceneRuleListByProductIdAndDeviceIdFromCache( | |
| 256 | + List<IotSceneRuleDO> sceneRules = getSelf().getSceneRuleListByProductIdAndDeviceIdFromCache( | |
| 261 | 257 | product.getId(), device.getId()); |
| 262 | 258 | if (CollUtil.isEmpty(sceneRules)) { |
| 263 | 259 | return sceneRules; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.scene.action; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.map.MapUtil; | |
| 4 | 5 | import cn.hutool.core.util.StrUtil; |
| 5 | 6 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; |
| 6 | 7 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| ... | ... | @@ -126,7 +127,7 @@ public class IotDeviceControlSceneRuleAction implements IotSceneRuleAction { |
| 126 | 127 | private IotDeviceMessage buildPropertySetMessage(IotSceneRuleDO.Action actionConfig, IotDeviceDO device) { |
| 127 | 128 | try { |
| 128 | 129 | // 属性设置参数格式: {"properties": {"identifier": value}} |
| 129 | - Object params = Map.of("properties", Map.of(actionConfig.getIdentifier(), actionConfig.getParams())); | |
| 130 | + Object params = MapUtil.of("properties", MapUtil.of(actionConfig.getIdentifier(), actionConfig.getParams())); | |
| 130 | 131 | return IotDeviceMessage.requestOf(IotDeviceMessageMethodEnum.PROPERTY_SET.getMethod(), params); |
| 131 | 132 | } catch (Exception e) { |
| 132 | 133 | log.error("[buildPropertySetMessage][构建属性设置消息异常]", e); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.scene.action; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.map.MapUtil; | |
| 4 | 5 | import cn.hutool.core.util.StrUtil; |
| 5 | 6 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; |
| 6 | 7 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| ... | ... | @@ -13,6 +14,8 @@ import jakarta.annotation.Resource; |
| 13 | 14 | import lombok.extern.slf4j.Slf4j; |
| 14 | 15 | import org.springframework.stereotype.Component; |
| 15 | 16 | |
| 17 | +import java.util.Collections; | |
| 18 | +import java.util.HashMap; | |
| 16 | 19 | import java.util.List; |
| 17 | 20 | import java.util.Map; |
| 18 | 21 | |
| ... | ... | @@ -126,10 +129,10 @@ public class IotDeviceServiceInvokeSceneRuleAction implements IotSceneRuleAction |
| 126 | 129 | private IotDeviceMessage buildServiceInvokeMessage(IotSceneRuleDO.Action actionConfig, IotDeviceDO device) { |
| 127 | 130 | try { |
| 128 | 131 | // 服务调用参数格式: {"identifier": "serviceId", "params": {...}} |
| 129 | - Object params = Map.of( | |
| 130 | - "identifier", actionConfig.getIdentifier(), | |
| 131 | - "params", actionConfig.getParams() != null ? actionConfig.getParams() : Map.of() | |
| 132 | - ); | |
| 132 | + Object params = MapUtil.builder() | |
| 133 | + .put("identifier", actionConfig.getIdentifier()) | |
| 134 | + .put("params", actionConfig.getParams() != null ? actionConfig.getParams() : Collections.emptyMap()) | |
| 135 | + .build(); | |
| 133 | 136 | return IotDeviceMessage.requestOf(IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod(), params); |
| 134 | 137 | } catch (Exception e) { |
| 135 | 138 | log.error("[buildServiceInvokeMessage][构建服务调用消息异常]", e); | ... | ... |