deploy-ease-platform/frontend/src/utils/workflow/variableConversion.ts
2025-11-20 15:02:59 +08:00

179 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { FlowNode } from '@/pages/Workflow/Design/types';
/**
* 正则1匹配 ${...} 块
*/
const BLOCK_PATTERN = /\$\{([^}]+)\}/g;
/**
* 正则2在表达式内匹配 节点名.字段 引用
* 支持中文节点名、UUID格式节点ID
*/
const NODE_REF_PATTERN = /([a-zA-Z0-9_\u4e00-\u9fa5\-]+)\.([a-zA-Z0-9_.]+)/g;
/**
* 将显示名称格式转换为UUID格式
* ${节点名称.字段名} → ${节点UUID.字段名}
*
* @param displayText 包含显示名称的文本
* @param allNodes 所有节点列表用于查找UUID
* @returns 转换后的UUID格式文本
*
* @example
* convertToUUID("构建${Jenkins构建.buildStatus}完成", allNodes)
* // 返回: "构建${uuid-123.buildStatus}完成"
*/
export const convertToUUID = (
displayText: string,
allNodes: FlowNode[]
): string => {
if (!displayText || typeof displayText !== 'string') {
return displayText;
}
// 阶段1处理 ${...} 块
return displayText.replace(BLOCK_PATTERN, (blockMatch, blockContent) => {
// 阶段2在块内容中查找并替换所有 节点名.字段 引用
const transformedContent = blockContent.replace(NODE_REF_PATTERN, (refMatch: string, nodeNameOrId: string, fieldPath: string) => {
// 特殊处理:表单字段
if (nodeNameOrId === '启动表单' || nodeNameOrId === 'form' || nodeNameOrId === 'notification') {
return `${nodeNameOrId}.${fieldPath}`;
}
// 尝试通过名称查找节点
const nodeByName = allNodes.find(n => {
const nodeName = n.data?.label || n.data?.nodeDefinition?.nodeName;
return nodeName === nodeNameOrId;
});
if (nodeByName) {
return `${nodeByName.id}.${fieldPath}`;
}
// 可能已经是UUID格式保持原样
return refMatch;
});
return `\${${transformedContent}}`;
});
};
/**
* 将UUID格式转换为显示名称格式
* ${节点UUID.字段名} → ${节点名称.字段名}
*
* @param uuidText 包含UUID的文本
* @param allNodes 所有节点列表(用于查找显示名称)
* @returns 转换后的显示名称格式文本
*
* @example
* convertToDisplayName("构建${uuid-123.buildStatus}完成", allNodes)
* // 返回: "构建${Jenkins构建.buildStatus}完成"
*/
export const convertToDisplayName = (
uuidText: string,
allNodes: FlowNode[]
): string => {
if (!uuidText || typeof uuidText !== 'string') {
return uuidText;
}
// 阶段1处理 ${...} 块
return uuidText.replace(BLOCK_PATTERN, (blockMatch, blockContent) => {
// 阶段2在块内容中查找并替换所有 UUID.字段 引用为 节点名.字段
const transformedContent = blockContent.replace(NODE_REF_PATTERN, (refMatch: string, nodeIdOrName: string, fieldPath: string) => {
// 特殊处理:表单字段
if (nodeIdOrName === 'form' || nodeIdOrName === '启动表单' || nodeIdOrName === 'notification') {
return `${nodeIdOrName}.${fieldPath}`;
}
// 尝试通过UUID查找节点
const nodeById = allNodes.find(n => n.id === nodeIdOrName);
if (nodeById) {
// 找到了,替换为显示名称
const nodeName = nodeById.data?.label || nodeById.data?.nodeDefinition?.nodeName || nodeIdOrName;
return `${nodeName}.${fieldPath}`;
}
// 可能已经是显示名称格式,保持原样
return refMatch;
});
return `\${${transformedContent}}`;
});
};
/**
* 转换对象中的所有字符串值从显示名称到UUID
* 递归处理嵌套对象和数组
*
* @param obj 要转换的对象
* @param allNodes 所有节点列表
* @returns 转换后的对象
*/
export const convertObjectToUUID = <T extends Record<string, any>>(
obj: T,
allNodes: FlowNode[]
): T => {
if (!obj || typeof obj !== 'object') {
return obj;
}
const result: any = Array.isArray(obj) ? [] : {};
for (const key in obj) {
const value = obj[key];
if (typeof value === 'string') {
// 字符串类型:进行转换
result[key] = convertToUUID(value, allNodes);
} else if (value && typeof value === 'object') {
// 对象或数组:递归转换
result[key] = convertObjectToUUID(value, allNodes);
} else {
// 其他类型:保持原样
result[key] = value;
}
}
return result as T;
};
/**
* 转换对象中的所有字符串值从UUID到显示名称
* 递归处理嵌套对象和数组
*
* @param obj 要转换的对象
* @param allNodes 所有节点列表
* @returns 转换后的对象
*/
export const convertObjectToDisplayName = <T extends Record<string, any>>(
obj: T,
allNodes: FlowNode[]
): T => {
if (!obj || typeof obj !== 'object') {
return obj;
}
const result: any = Array.isArray(obj) ? [] : {};
for (const key in obj) {
const value = obj[key];
if (typeof value === 'string') {
// 字符串类型:进行转换
result[key] = convertToDisplayName(value, allNodes);
} else if (value && typeof value === 'object') {
// 对象或数组:递归转换
result[key] = convertObjectToDisplayName(value, allNodes);
} else {
// 其他类型:保持原样
result[key] = value;
}
}
return result as T;
};