|
@@ -159,6 +159,7 @@ import {
|
|
|
isWorkflowUnlockSchemeType,
|
|
isWorkflowUnlockSchemeType,
|
|
|
normalizeIsolationTypeForCoLockFamily,
|
|
normalizeIsolationTypeForCoLockFamily,
|
|
|
resolveWorkflowPaletteType,
|
|
resolveWorkflowPaletteType,
|
|
|
|
|
+ validateWorkflowDesignerSubmitTabForSave,
|
|
|
WORKFLOW_CO_LOCK_FAMILY_ISOLATION_TYPE,
|
|
WORKFLOW_CO_LOCK_FAMILY_ISOLATION_TYPE,
|
|
|
} from '../utils/workflowNodeTypes';
|
|
} from '../utils/workflowNodeTypes';
|
|
|
import { generateIconPaths, getIconPathByFileName, getWorkflowNodeDescription } from '../utils/workflowNodePanelUi';
|
|
import { generateIconPaths, getIconPathByFileName, getWorkflowNodeDescription } from '../utils/workflowNodePanelUi';
|
|
@@ -2549,15 +2550,31 @@ export default function ProcessDesigner() {
|
|
|
}),
|
|
}),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- // 将整个 JSON 作为 content 字段传递
|
|
|
|
|
- const content = JSON.stringify(exportData, null, 2);
|
|
|
|
|
-
|
|
|
|
|
// 必须有流程ID才能保存(因为新建时只传了name,设计完成后必须调用更新接口)
|
|
// 必须有流程ID才能保存(因为新建时只传了name,设计完成后必须调用更新接口)
|
|
|
if (!workflowId) {
|
|
if (!workflowId) {
|
|
|
message.warning('无法保存:缺少流程ID,请先创建流程');
|
|
message.warning('无法保存:缺少流程ID,请先创建流程');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const submitTabValidationError = validateWorkflowDesignerSubmitTabForSave(
|
|
|
|
|
+ nodes.map((n) => {
|
|
|
|
|
+ const cachedData = loadNodeCache(n.id);
|
|
|
|
|
+ const mergedData = (cachedData ? { ...n.data, ...cachedData } : n.data || {}) as Record<
|
|
|
|
|
+ string,
|
|
|
|
|
+ unknown
|
|
|
|
|
+ >;
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: n.id,
|
|
|
|
|
+ reactFlowType: String(n.type ?? ''),
|
|
|
|
|
+ mergedData,
|
|
|
|
|
+ };
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ if (submitTabValidationError) {
|
|
|
|
|
+ message.warning(submitTabValidationError);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 从暂存的详情中获取 name 和 description
|
|
// 从暂存的详情中获取 name 和 description
|
|
|
const name = workflowDetail?.name || '';
|
|
const name = workflowDetail?.name || '';
|
|
|
const description = workflowDetail?.description || '';
|
|
const description = workflowDetail?.description || '';
|
|
@@ -2670,15 +2687,31 @@ export default function ProcessDesigner() {
|
|
|
}),
|
|
}),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- // 将整个 JSON 作为 content 字段传递
|
|
|
|
|
- const content = JSON.stringify(exportData, null, 2);
|
|
|
|
|
-
|
|
|
|
|
// 必须有流程ID才能保存(因为新建时只传了name,设计完成后必须调用更新接口)
|
|
// 必须有流程ID才能保存(因为新建时只传了name,设计完成后必须调用更新接口)
|
|
|
if (!workflowId) {
|
|
if (!workflowId) {
|
|
|
message.warning('无法保存:缺少流程ID,请先创建流程');
|
|
message.warning('无法保存:缺少流程ID,请先创建流程');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const submitTabValidationError = validateWorkflowDesignerSubmitTabForSave(
|
|
|
|
|
+ nodes.map((n) => {
|
|
|
|
|
+ const cachedData = loadNodeCache(n.id);
|
|
|
|
|
+ const mergedData = (cachedData ? { ...n.data, ...cachedData } : n.data || {}) as Record<
|
|
|
|
|
+ string,
|
|
|
|
|
+ unknown
|
|
|
|
|
+ >;
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: n.id,
|
|
|
|
|
+ reactFlowType: String(n.type ?? ''),
|
|
|
|
|
+ mergedData,
|
|
|
|
|
+ };
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ if (submitTabValidationError) {
|
|
|
|
|
+ message.warning(submitTabValidationError);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 从暂存的详情中获取 name 和 description
|
|
// 从暂存的详情中获取 name 和 description
|
|
|
const name = workflowDetail?.name || '';
|
|
const name = workflowDetail?.name || '';
|
|
|
const description = workflowDetail?.description || '';
|
|
const description = workflowDetail?.description || '';
|
|
@@ -2826,6 +2859,25 @@ export default function ProcessDesigner() {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const submitTabValidationError = validateWorkflowDesignerSubmitTabForSave(
|
|
|
|
|
+ nodes.map((n) => {
|
|
|
|
|
+ const cachedData = loadNodeCache(n.id);
|
|
|
|
|
+ const mergedData = (cachedData ? { ...n.data, ...cachedData } : n.data || {}) as Record<
|
|
|
|
|
+ string,
|
|
|
|
|
+ unknown
|
|
|
|
|
+ >;
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: n.id,
|
|
|
|
|
+ reactFlowType: String(n.type ?? ''),
|
|
|
|
|
+ mergedData,
|
|
|
|
|
+ };
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ if (submitTabValidationError) {
|
|
|
|
|
+ message.warning(submitTabValidationError);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const name = workflowDetail?.name || '';
|
|
const name = workflowDetail?.name || '';
|
|
|
const description = workflowDetail?.description || '';
|
|
const description = workflowDetail?.description || '';
|
|
|
|
|
|
|
@@ -3794,8 +3846,18 @@ export default function ProcessDesigner() {
|
|
|
<div>
|
|
<div>
|
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
|
{isWorkflowUnlockCoLockType(selectedDataType)
|
|
{isWorkflowUnlockCoLockType(selectedDataType)
|
|
|
- ? '选择共锁任务'
|
|
|
|
|
- : '选择上锁任务'}
|
|
|
|
|
|
|
+ ? (
|
|
|
|
|
+ <>
|
|
|
|
|
+ 选择共锁任务{' '}
|
|
|
|
|
+ <span className="text-red-500" style={{ color: '#ef4444' }}>*</span>
|
|
|
|
|
+ </>
|
|
|
|
|
+ )
|
|
|
|
|
+ : (
|
|
|
|
|
+ <>
|
|
|
|
|
+ 选择上锁任务{' '}
|
|
|
|
|
+ <span className="text-red-500" style={{ color: '#ef4444' }}>*</span>
|
|
|
|
|
+ </>
|
|
|
|
|
+ )}
|
|
|
</label>
|
|
</label>
|
|
|
<Select
|
|
<Select
|
|
|
value={nodeConfig.isolationNodeUuid || undefined}
|
|
value={nodeConfig.isolationNodeUuid || undefined}
|