mirror of
https://github.com/YunaiV/ruoyi-vue-pro.git
synced 2025-10-26 03:04:45 +08:00
Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java
This commit is contained in:
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.service.task;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
import cn.hutool.core.date.DatePattern;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.map.MapUtil;
|
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.ObjectUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
|
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.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.BpmModelMetaInfoVO;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
|
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
|
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.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.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNode;
|
||||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
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.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.enums.BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX;
|
||||||
import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseNodeType;
|
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)));
|
needSimulateTaskDefKeysByReturn.add(StrUtil.removePrefix(key, PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX)));
|
||||||
}
|
}
|
||||||
// 移除运行中的节点,运行中的节点无需预测
|
// 移除运行中的节点,运行中的节点无需预测
|
||||||
// TODO @jason:是不是 foreach runActivityNodes,然后移除 needSimulateTaskDefKeysByReturn 更好?(理解成本低一点)
|
if (CollUtil.isNotEmpty(runActivityNodes)) {
|
||||||
CollectionUtils.convertList(runActivityNodes, ActivityNode::getId).forEach(needSimulateTaskDefKeysByReturn::remove);
|
runActivityNodes.forEach( activityNode -> needSimulateTaskDefKeysByReturn.remove(activityNode.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
// 3.3 预测未运行节点的审批信息
|
// 3.3 预测未运行节点的审批信息
|
||||||
List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,
|
List<ActivityNode> simulateActivityNodes = getSimulateApproveNodeList(startUserId, bpmnModel,
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.service.task;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.*;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
@ -939,9 +938,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
|
|
||||||
// 3. 构建需要预测的任务流程变量
|
// 3. 构建需要预测的任务流程变量
|
||||||
// TODO @jason:【驳回预测相关】是不是搞成一个变量,里面是 set 更简洁一点呀?
|
// TODO @jason:【驳回预测相关】是不是搞成一个变量,里面是 set 更简洁一点呀?
|
||||||
Set<String> taskDefinitionKeyList = getNeedSimulateTaskDefinitionKeys(bpmnModel, currentTask, targetElement);
|
Set<String> needSimulateTaskDefinitionKeys = getNeedSimulateTaskDefinitionKeys(bpmnModel, currentTask, targetElement);
|
||||||
Map<String, Object> needSimulateVariables = convertMap(taskDefinitionKeyList,
|
Map<String, Object> needSimulateVariables = convertMap(needSimulateTaskDefinitionKeys,
|
||||||
taskId -> StrUtil.concat(false, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX, taskId), item -> Boolean.TRUE);
|
key -> StrUtil.concat(false, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_PREFIX, key), item -> Boolean.TRUE);
|
||||||
|
|
||||||
|
|
||||||
// 4. 执行驳回
|
// 4. 执行驳回
|
||||||
// 使用 moveExecutionsToSingleActivityId 替换 moveActivityIdsToSingleActivityId 原因:
|
// 使用 moveExecutionsToSingleActivityId 替换 moveActivityIdsToSingleActivityId 原因:
|
||||||
@ -962,22 +962,22 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
|||||||
// 1. 获取需要预测的任务的 definition key。因为当前任务还没完成,也需要预测
|
// 1. 获取需要预测的任务的 definition key。因为当前任务还没完成,也需要预测
|
||||||
Set<String> taskDefinitionKeys = CollUtil.newHashSet(currentTask.getTaskDefinitionKey());
|
Set<String> taskDefinitionKeys = CollUtil.newHashSet(currentTask.getTaskDefinitionKey());
|
||||||
|
|
||||||
// 2.1 从已结束任务中找到要回退的目标任务,按时间倒序最近的一个目标任务
|
// 2.1 获取已结束任务按时间倒序排序
|
||||||
List<HistoricTaskInstance> endTaskList = CollectionUtils.filterList(
|
List<HistoricTaskInstance> endTaskList = CollectionUtils.filterList(
|
||||||
getTaskListByProcessInstanceId(currentTask.getProcessInstanceId(), Boolean.FALSE),
|
getTaskListByProcessInstanceId(currentTask.getProcessInstanceId(), Boolean.FALSE),
|
||||||
item -> item.getEndTime() != null);
|
item -> item.getEndTime() != null);
|
||||||
// 2.2 遍历已结束的任务,找到在 targetTask 之后生成的任务,且串行可达的任务
|
// 2.2 从结束任务中找到最近一个的目标任务
|
||||||
HistoricTaskInstance targetTask = findFirst(endTaskList,
|
HistoricTaskInstance targetTask = findFirst(endTaskList,
|
||||||
item -> item.getTaskDefinitionKey().equals(targetElement.getId()));
|
item -> item.getTaskDefinitionKey().equals(targetElement.getId()));
|
||||||
// TODO @jason:【驳回预测相关】是不是 if targetTask 先判空?
|
if (targetTask == null) {
|
||||||
|
return taskDefinitionKeys;
|
||||||
|
}
|
||||||
|
// 2.3 遍历已结束的任务,找到在 targetTask 之后生成的任务,且串行可达的任务
|
||||||
endTaskList.forEach(item -> {
|
endTaskList.forEach(item -> {
|
||||||
FlowElement element = getFlowElementById(bpmnModel, item.getTaskDefinitionKey());
|
FlowElement element = getFlowElementById(bpmnModel, item.getTaskDefinitionKey());
|
||||||
// 如果已结束的任务在回退目标节点之后生成,且串行可达,则标记为需要预算节点
|
// 如果已结束的任务在回退目标节点之后生成,且串行可达,则加到需要预测节点中
|
||||||
// TODO 串行可达的方法需要和判断可回退节点 validateTargetTaskCanReturn 分开吗? 并行网关可能会有问题。
|
// TODO 串行可达的方法需要和判断可回退节点 validateTargetTaskCanReturn 分开吗? 并行网关可能会有问题。
|
||||||
// TODO @jason:【驳回预测相关】这里是不是判断 element 哈?
|
if (item.getCreateTime().compareTo(targetTask.getCreateTime()) > 0
|
||||||
if (targetTask != null
|
|
||||||
// TODO @jason:【驳回预测相关】这里直接 createTime 的 compare 更简单?因为不太会出现空哈。
|
|
||||||
&& DateUtil.compare(item.getCreateTime(), targetTask.getCreateTime()) > 0
|
|
||||||
&& BpmnModelUtils.isSequentialReachable(element, targetElement, null)) {
|
&& BpmnModelUtils.isSequentialReachable(element, targetElement, null)) {
|
||||||
taskDefinitionKeys.add(item.getTaskDefinitionKey());
|
taskDefinitionKeys.add(item.getTaskDefinitionKey());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,7 +124,6 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||||||
component: 'InputNumber',
|
component: 'InputNumber',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
controlsPosition: 'right',
|
|
||||||
placeholder: '请输入${comment}',
|
placeholder: '请输入${comment}',
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
@ -326,7 +325,6 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
|
|||||||
component: 'InputNumber',
|
component: 'InputNumber',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
controlsPosition: 'right',
|
|
||||||
placeholder: '请输入${comment}',
|
placeholder: '请输入${comment}',
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
@ -560,7 +558,6 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${api
|
|||||||
component: 'InputNumber',
|
component: 'InputNumber',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
controlsPosition: 'right',
|
|
||||||
placeholder: '请输入${comment}',
|
placeholder: '请输入${comment}',
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
|
|||||||
@ -127,9 +127,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
try {
|
try {
|
||||||
formData.value = await get${simpleClassName}(data.id);
|
formData.value = await get${simpleClassName}(data.id);
|
||||||
// 设置到 values
|
// 设置到 values
|
||||||
if (formData.value) {
|
await formApi.setValues(formData.value);
|
||||||
await formApi.setValues(formData.value);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,8 +124,9 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||||||
component: 'InputNumber',
|
component: 'InputNumber',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
controlsPosition: 'right',
|
|
||||||
placeholder: '请输入${comment}',
|
placeholder: '请输入${comment}',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
class: '!w-full',
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
},
|
},
|
||||||
@ -326,8 +327,9 @@ export function use${subSimpleClassName}FormSchema(): VbenFormSchema[] {
|
|||||||
component: 'InputNumber',
|
component: 'InputNumber',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
controlsPosition: 'right',
|
|
||||||
placeholder: '请输入${comment}',
|
placeholder: '请输入${comment}',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
class: '!w-full',
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
},
|
},
|
||||||
@ -560,8 +562,9 @@ export function use${subSimpleClassName}GridColumns(): VxeTableGridOptions<${api
|
|||||||
component: 'InputNumber',
|
component: 'InputNumber',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
controlsPosition: 'right',
|
|
||||||
placeholder: '请输入${comment}',
|
placeholder: '请输入${comment}',
|
||||||
|
controlsPosition: 'right',
|
||||||
|
class: '!w-full',
|
||||||
},
|
},
|
||||||
#end
|
#end
|
||||||
},
|
},
|
||||||
|
|||||||
@ -127,9 +127,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
try {
|
try {
|
||||||
formData.value = await get${simpleClassName}(data.id);
|
formData.value = await get${simpleClassName}(data.id);
|
||||||
// 设置到 values
|
// 设置到 values
|
||||||
if (formData.value) {
|
await formApi.setValues(formData.value);
|
||||||
await formApi.setValues(formData.value);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,14 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
|
|||||||
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleActionTypeEnum;
|
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleActionTypeEnum;
|
||||||
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
|
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
|
||||||
import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceMessageService;
|
import cn.iocoder.yudao.module.iot.service.device.message.IotDeviceMessageService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IoT 设备服务调用的 {@link IotSceneRuleAction} 实现类
|
* IoT 设备服务调用的 {@link IotSceneRuleAction} 实现类
|
||||||
|
|||||||
Reference in New Issue
Block a user