diff --git a/sql/tools/convertor.py b/sql/tools/convertor.py index d286d3b23..b54d1337c 100644 --- a/sql/tools/convertor.py +++ b/sql/tools/convertor.py @@ -6,12 +6,12 @@ Author: dhb52 (https://gitee.com/dhb52) pip install simple-ddl-parser or with uv -uv run --with simple-ddl-parser convertor.py postgres > ../postgresql/ruoyi-vue-pro.sql 239ms  四 5/22 21:03:16 2025 -uv run --with simple-ddl-parser convertor.py sqlserver > ../sqlserver/ruoyi-vue-pro.sql -uv run --with simple-ddl-parser convertor.py kingbase > ../kingbase/ruoyi-vue-pro.sql -uv run --with simple-ddl-parser convertor.py opengauss > ../opengauss/ruoyi-vue-pro.sql -uv run --with simple-ddl-parser convertor.py oracle > ../oracle/ruoyi-vue-pro.sql -uv run --with simple-ddl-parser convertor.py dm8 > ../dm/ruoyi-vue-pro-dm8.sql +uv run --with simple-ddl-parser convertor.py postgres ../mysql/ruoyi-vue-pro.sql > ../postgresql/ruoyi-vue-pro.sql +uv run --with simple-ddl-parser convertor.py sqlserver ../mysql/ruoyi-vue-pro.sql > ../sqlserver/ruoyi-vue-pro.sql +uv run --with simple-ddl-parser convertor.py kingbase ../mysql/ruoyi-vue-pro.sql > ../kingbase/ruoyi-vue-pro.sql +uv run --with simple-ddl-parser convertor.py opengauss ../mysql/ruoyi-vue-pro.sql > ../opengauss/ruoyi-vue-pro.sql +uv run --with simple-ddl-parser convertor.py oracle ../mysql/ruoyi-vue-pro.sql > ../oracle/ruoyi-vue-pro.sql +uv run --with simple-ddl-parser convertor.py dm8 ../mysql/ruoyi-vue-pro.sql > ../dm/ruoyi-vue-pro-dm8.sql """ import argparse @@ -24,6 +24,9 @@ from typing import Dict, Generator, Optional, Tuple, Union from simple_ddl_parser import DDLParser +# 避免 Windows 系统使用默认的 GBK 编码 +sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf-8', buffering=1) + PREAMBLE = """/* Yudao Database Transfer Tool @@ -919,9 +922,15 @@ def main(): help="目标数据库类型", choices=["postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss"], ) + parser.add_argument( + "path", + type=str, + help="源数据库脚本路径", + default="../mysql/ruoyi-vue-pro.sql" + ) args = parser.parse_args() - sql_file = pathlib.Path("../mysql/ruoyi-vue-pro.sql").resolve().as_posix() + sql_file = pathlib.Path(args.path).resolve().as_posix() convertor = None if args.type == "postgres": convertor = PostgreSQLConvertor(sql_file) diff --git a/yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index bdbc7d67a..4938cf17a 100644 --- a/yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -234,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/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 3b3b1264d..a658d6d4f 100644 --- a/yudao-module-bpm/yudao-module-bpm-server/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-server/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/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm b/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm index 58d64fc2c..e2b131db1 100644 --- a/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_antd/schema/views/data.ts.vm +++ b/yudao-module-infra/yudao-module-infra-server/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/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm b/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm index e94f439f4..ea654da0b 100644 --- a/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_antd/schema/views/form.vue.vm +++ b/yudao-module-infra/yudao-module-infra-server/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/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm b/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm index 375a3c90a..da9582448 100644 --- a/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_ele/schema/views/data.ts.vm +++ b/yudao-module-infra/yudao-module-infra-server/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/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm b/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm index c3342c4d4..fa4c34606 100644 --- a/yudao-module-infra/yudao-module-infra-server/src/main/resources/codegen/vue3_vben5_ele/schema/views/form.vue.vm +++ b/yudao-module-infra/yudao-module-infra-server/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-api/src/main/java/cn/iocoder/yudao/module/iot/core/enums/IotDeviceMessageMethodEnum.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/core/enums/IotDeviceMessageMethodEnum.java deleted file mode 100644 index e62b78e24..000000000 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/core/enums/IotDeviceMessageMethodEnum.java +++ /dev/null @@ -1,86 +0,0 @@ -package cn.iocoder.yudao.module.iot.core.enums; - -import cn.hutool.core.util.ArrayUtil; -import cn.iocoder.yudao.framework.common.core.ArrayValuable; -import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; -import java.util.Set; - -/** - * IoT 设备消息的方法枚举 - * - * @author haohao - */ -@Getter -@AllArgsConstructor -public enum IotDeviceMessageMethodEnum implements ArrayValuable { - - // ========== 设备状态 ========== - - STATE_UPDATE("thing.state.update", "设备状态更新", true), - - // TODO 芋艿:要不要加个 ping 消息; - - // ========== 设备属性 ========== - // 可参考:https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services - - PROPERTY_POST("thing.property.post", "属性上报", true), - PROPERTY_SET("thing.property.set", "属性设置", false), - - // ========== 设备事件 ========== - // 可参考:https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services - - EVENT_POST("thing.event.post", "事件上报", true), - - // ========== 设备服务调用 ========== - // 可参考:https://help.aliyun.com/zh/iot/user-guide/device-properties-events-and-services - - SERVICE_INVOKE("thing.service.invoke", "服务调用", false), - - // ========== 设备配置 ========== - // 可参考:https://help.aliyun.com/zh/iot/user-guide/remote-configuration-1 - - CONFIG_PUSH("thing.config.push", "配置推送", false), - - // ========== OTA 固件 ========== - // 可参考:https://help.aliyun.com/zh/iot/user-guide/perform-ota-updates - - OTA_UPGRADE("thing.ota.upgrade", "OTA 固定信息推送", false), - OTA_PROGRESS("thing.ota.progress", "OTA 升级进度上报", true), - ; - - public static final String[] ARRAYS = Arrays.stream(values()).map(IotDeviceMessageMethodEnum::getMethod) - .toArray(String[]::new); - - /** - * 不进行 reply 回复的方法集合 - */ - public static final Set REPLY_DISABLED = SetUtils.asSet( - STATE_UPDATE.getMethod(), - OTA_PROGRESS.getMethod() // 参考阿里云,OTA 升级进度上报,不进行回复 - ); - - private final String method; - - private final String name; - - private final Boolean upstream; - - @Override - public String[] array() { - return ARRAYS; - } - - public static IotDeviceMessageMethodEnum of(String method) { - return ArrayUtil.firstMatch(item -> item.getMethod().equals(method), - IotDeviceMessageMethodEnum.values()); - } - - public static boolean isReplyDisabled(String method) { - return REPLY_DISABLED.contains(method); - } - -} diff --git a/yudao-module-iot/yudao-module-iot-server/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java b/yudao-module-iot/yudao-module-iot-server/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java index dd10ed813..5e57743a5 100644 --- a/yudao-module-iot/yudao-module-iot-server/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceControlSceneRuleAction.java +++ b/yudao-module-iot/yudao-module-iot-server/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; @@ -14,7 +15,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.List; -import java.util.Map; /** * IoT 设备属性设置的 {@link IotSceneRuleAction} 实现类 @@ -126,7 +126,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-server/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java b/yudao-module-iot/yudao-module-iot-server/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java index eb7bedf2f..d665a14b9 100644 --- a/yudao-module-iot/yudao-module-iot-server/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotDeviceServiceInvokeSceneRuleAction.java +++ b/yudao-module-iot/yudao-module-iot-server/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,8 +14,8 @@ import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.util.Collections; import java.util.List; -import java.util.Map; /** * IoT 设备服务调用的 {@link IotSceneRuleAction} 实现类 @@ -126,10 +127,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);