chore: replace all cn comments of fe to en version by volc api (#320)

This commit is contained in:
tecvan
2025-07-31 10:32:15 +08:00
committed by GitHub
parent 716ec0cba8
commit 71f6245a01
2960 changed files with 15545 additions and 15545 deletions

View File

@@ -61,7 +61,7 @@ describe('encapsulate-lines-service', () => {
expect(outputLines).toEqual([]);
});
// 解封节点有多个输入且解封流程start节点有多个输出不能创建输入连线
// The unblocking node has multiple inputs, and the unblocking process start node has multiple outputs, so an input connection cannot be created
it('should not create decapsulate input lines', async () => {
const json = {
...cloneDeep(complexMock),
@@ -97,7 +97,7 @@ describe('encapsulate-lines-service', () => {
expect(inputLines).toEqual([]);
});
// 解封节点有多个输出且解封流程end节点有多个输入不能创建输出连线
// The unblocking node has multiple outputs, and the unblocking process end node has multiple inputs, so an output connection cannot be created
it('should not create decapsulate output lines', async () => {
const json = {
...cloneDeep(complexMock),

View File

@@ -83,7 +83,7 @@ export class EncapsulateApiServiceImpl implements EncapsulateApiService {
async getWorkflow(spaceId: string, workflowId: string, version?: string) {
let json;
// 有历史版本的场景获取历史版本的数据
// Scenes with historical versions get historical versions of data
if (version) {
const res = await workflowApi.GetHistorySchema({
space_id: spaceId,

View File

@@ -29,20 +29,20 @@ export interface EncapsulateWorkflowParams {
export interface EncapsulateApiService {
/**
* 封装流程
* encapsulation process
* @param name
*/
encapsulateWorkflow: (
params: EncapsulateWorkflowParams,
) => Promise<{ workflowId: string } | null>;
/**
* 校验流程
* Validation Process
* @param schema
* @returns
*/
validateWorkflow: (json: WorkflowJSON) => Promise<ValidateErrorData[]>;
/**
* 获取流程数据
* Get process data
* @param spaceId
* @param workflowId
* @returns

View File

@@ -35,11 +35,11 @@ export class EncapsulateLinesService {
@inject(WorkflowLinesManager) declare linesManager: WorkflowLinesManager;
/**
* 获取有效的封装连接端口
* @param nodes 封装范围内的节点数组
* @throws Error 输入线不符合封装规则
* @throws Error 输出线不符合封装规则
* @returns 封装范围内的输入和输出端口对象
* Get a valid encapsulation connection port
* @Param nodes Encapsulated array of nodes
* @throws Error input line does not conform to encapsulation rules
* @Throws Error Output line does not conform to encapsulation rules
* @Returns Encapsulated input and output port objects
*/
getValidEncapsulateConnectPorts(
nodes: WorkflowNodeEntity[],
@@ -98,9 +98,9 @@ export class EncapsulateLinesService {
}
/**
* 获取封装范围内的所有输入线
* @param nodes 流程图节点数组
* @returns 封装范围内的输入线数组
* Get all input lines in the package range
* @Param nodes flowchart node array
* @Returns array of input lines in the encapsulated range
*/
getEncapsulateNodesInputLines(
nodes: WorkflowNodeEntity[],
@@ -118,9 +118,9 @@ export class EncapsulateLinesService {
}
/**
* 获取封装范围内的所有输出线
* @param nodes 流程图节点数组
* @returns 封装范围内的输出线数组
* Get all output lines in the package range
* @Param nodes flowchart node array
* @Returns array of output lines in the encapsulated range
*/
getEncapsulateNodesOutputLines(
nodes: WorkflowNodeEntity[],
@@ -138,7 +138,7 @@ export class EncapsulateLinesService {
}
/**
* 校验封装范围内的输入和输出线是否符合封装规则
* Verify that the input and output lines within the package range comply with the package rules
*/
validateEncapsulateLines(lines: WorkflowLineEntity[]): boolean {
const isFromPortUniq =
@@ -148,7 +148,7 @@ export class EncapsulateLinesService {
}
/**
* 创建封装连线
* Create encapsulation connection
* @param ports
* @param subFlowNode
* @returns
@@ -197,7 +197,7 @@ export class EncapsulateLinesService {
}
/**
* 创建解封线
* Create unsealing line
* @param options
*/
createDecapsulateLines(options: {
@@ -210,7 +210,7 @@ export class EncapsulateLinesService {
const { node, startNodeId, endNodeId, idsMap, workflowJSON } = options;
const edges = [
...workflowJSON.edges,
// 子画布中的连线
// Lines in the sub-canvas
...workflowJSON.nodes
.map(n => n.edges)
.filter(Boolean)
@@ -228,20 +228,20 @@ export class EncapsulateLinesService {
return 'internal';
});
// 内部连线
// interconnect
const internalLines = this.createDecapsulateInternalLines(
edgesGroup.internal || [],
idsMap,
);
// 输入连线
// input connection
const inputLines = this.createDecapsulateInputLines(
edgesGroup.input || [],
node,
idsMap,
);
// 输出连线
// output connection
const outputLines = this.createDecapsulateOutputLines(
edgesGroup.output || [],
node,
@@ -256,7 +256,7 @@ export class EncapsulateLinesService {
}
/**
* 创建解封内部连线
* Create an unblocked internal connection
* @param internalEdges
* @param idsMap
* @returns
@@ -300,7 +300,7 @@ export class EncapsulateLinesService {
}
/**
* 创建解封输入连线
* Create an unsealed input connection
* @param inputEdges
* @param node
* @param idsMap
@@ -314,7 +314,7 @@ export class EncapsulateLinesService {
const createdLines: WorkflowLineEntity[] = [];
const { inputLines } = node.getData(WorkflowNodeLinesData);
// 封装多开头+封装上游多个输入 不创建连线
// Encapsulate multiple starts + encapsulate multiple upstream inputs, do not create connections
if (inputLines.length > 1 && inputEdges.length > 1) {
return createdLines;
}
@@ -341,7 +341,7 @@ export class EncapsulateLinesService {
}
/**
* 创建解封输出连线
* Create an unsealed output connection
* @param outputEdges
* @param node
* @param idsMap
@@ -355,7 +355,7 @@ export class EncapsulateLinesService {
const createdLines: WorkflowLineEntity[] = [];
const { outputLines } = node.getData(WorkflowNodeLinesData);
// 封装多输出+封装下游多个输出 不创建连线
// Encapsulate multiple outputs + Encapsulate multiple downstream outputs without creating wires
if (outputLines.length > 1 && outputEdges.length > 1) {
return createdLines;
}
@@ -382,7 +382,7 @@ export class EncapsulateLinesService {
}
/**
* 创建连线
* Create a connection
* @param info
* @param createdLines
*/
@@ -399,9 +399,9 @@ export class EncapsulateLinesService {
private isSubCanvasLinkLine(line: WorkflowLineEntity): boolean {
if (
// loop内的最后一根线
// The last wire in the loop
line.toPort?.portID === 'loop-function-inline-input' ||
// loop内的第一根线
// The first wire in the loop
line.fromPort.portID === 'loop-function-inline-output'
) {
return true;

View File

@@ -43,7 +43,7 @@ import { EncapsulateContext } from '../encapsulate-context';
import { ENCAPSULATE_START_END_PAD } from './constants';
/**
* 节点操作服务
* Node Operation Service
*/
@injectable()
export class EncapsulateNodesService {
@@ -66,9 +66,9 @@ export class EncapsulateNodesService {
private playgroundContext: PlaygroundContext;
/**
* 获取一批节点的中心点
* @param nodes 节点数组
* @returns 中心点的坐标对象
* Get the center point of a batch of nodes
* @param nodes array
* @Returns the coordinate object of the center point
*/
getNodesMiddlePoint(
nodes: Array<WorkflowNodeEntity | WorkflowNodeJSON>,
@@ -86,9 +86,9 @@ export class EncapsulateNodesService {
}
/**
* 创建解封节点
* @param sourceNode 原始被解封的节点
* @param nodes 要生成节点的node json数据
* Create an unblocked node
* @param sourceNode The original unblocked node
* @Param nodes to generate node json data
* @returns
*/
async createDecapsulateNodes(
@@ -102,7 +102,7 @@ export class EncapsulateNodesService {
}
const nodePoint = getNodePoint(sourceNode);
const centerPoint = this.getNodesMiddlePoint(middleNodes);
// 平移到中心
// Translate to Center
const translate: IPoint = {
x: nodePoint.x - centerPoint.x,
y: nodePoint.y - centerPoint.y,
@@ -122,7 +122,7 @@ export class EncapsulateNodesService {
}
/**
* 创建封装节点
* Create encapsulation node
* @param name
* @param nodes
* @returns
@@ -151,7 +151,7 @@ export class EncapsulateNodesService {
}
/**
* 通过json创建一个新节点
* Create a new node with JSON
* @param json
* @returns
*/
@@ -172,7 +172,7 @@ export class EncapsulateNodesService {
}
/**
* 解封布局,将所有节点向外平移一半的宽高
* Unseal the layout and move all nodes outward by half their width and height
*/
decapsulateLayout(sourceNode: WorkflowNodeEntity, nodes: WorkflowNodeJSON[]) {
const point = getNodePoint(sourceNode);
@@ -227,10 +227,10 @@ export class EncapsulateNodesService {
}
/**
* 获取解封后的节点JSON
* @param nodeJSON 原来的node json
* @param translate 平移的距离
* @param idsMap ids映射
* Get the unblocked node JSON.
* @param nodeJSON original node json
* @param translate distance
* @param idsMap ids
* @returns
*/
private getDecapsulateNodeJSON(
@@ -264,7 +264,7 @@ export class EncapsulateNodesService {
}
/**
* 获取解封后的节点坐标
* Get the unblocked node coordinates
* @param nodeJSON
* @param translate
* @returns
@@ -284,7 +284,7 @@ export class EncapsulateNodesService {
}
/**
* 节点分组
* Node grouping
* @param nodes
* @returns
*/
@@ -310,7 +310,7 @@ export class EncapsulateNodesService {
}
/**
* 获取多个节点合起来的宽高
* Get the combined width and height of multiple nodes
* @param nodes
* @returns
*/
@@ -351,13 +351,13 @@ export class EncapsulateNodesService {
}
/**
* 删除节点
* Delete Node
* @param node */
async deleteNodes(nodes: WorkflowNodeEntity[]) {
nodes.forEach(node => {
node.dispose();
});
// 有些节点删除会有删除出相关连线,等待其执行完成
// Some nodes will delete the relevant connection and wait for its execution to complete.
await delay(10);
}

View File

@@ -119,7 +119,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
let res;
try {
res = await this.encapsulateNodes(name, selectedNodes);
// 封装完成选中封装后的节点
// Encapsulation complete Select the encapsulated node
if (res.success) {
this.workflowSelectService.selectNode(res.subFlowNode);
}
@@ -159,7 +159,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
return;
}
// 获取流程数据
// Get process data
const workflow = await this.encapsulateApiService.getWorkflow(
info.spaceId && info.spaceId !== '0'
? info.spaceId
@@ -176,7 +176,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
return;
}
// 如果解封子画布里面的节点,需要校验是否有子画布
// If you unseal the nodes in the sub-canvas, you need to verify whether there is a sub-canvas.
if (
isNodeInSubCanvas(node) &&
hasSubCanvasNodes(this.workflowDocument, workflow.nodes)
@@ -193,10 +193,10 @@ export class EncapsulateServiceImpl implements EncapsulateService {
this.historyService.startTransaction();
// 以节点为中心向外扩张
// Node-centric expansion
this.encapsulateNodesService.decapsulateLayout(node, workflow.nodes);
// 创建节点
// Create Node
const { idsMap, startNode, endNode, middleNodes } =
await this.encapsulateNodesService.createDecapsulateNodes(
node,
@@ -204,7 +204,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
node.parent?.id,
);
// 解封后更新变量引用
// Update variable reference after unblocking
this.encapsulateVariableService.updateVarsAfterDecapsulate(node, {
idsMap,
startNode,
@@ -212,7 +212,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
middleNodes,
});
// 创建连线
// Create a connection
this.encapsulateLinesService.createDecapsulateLines({
node,
workflowJSON: workflow as WorkflowJSON,
@@ -223,7 +223,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
await delay(30);
// 移除老节点
// Remove old node
await this.encapsulateNodesService.deleteNodes([node]);
this.historyService.endTransaction();
}
@@ -245,7 +245,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
const startEndRects =
this.encapsulateNodesService.getEncapsulateStartEndRects(nodes);
// 生成 json并更新 JSON 内的变量引用
// Generate JSON and update the variable references in JSON
const json = await this.encapsulateGenerateService.generateWorkflowJSON(
nodes,
{
@@ -264,7 +264,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
}
try {
// 保存流程
// save process
const res = await this.encapsulateApiService.encapsulateWorkflow({
name,
desc: name,
@@ -284,7 +284,7 @@ export class EncapsulateServiceImpl implements EncapsulateService {
}
this.historyService.startTransaction();
// 替换成调用流程节点
// Replace with calling process node
const subFlowNode =
await this.encapsulateNodesService.createEncapsulateNode(
workflowId,
@@ -292,17 +292,17 @@ export class EncapsulateServiceImpl implements EncapsulateService {
nodes,
);
// 更新变量引用(上下游 + 封装节点本身输入)
// Update variable references (upstream and downstream + encapsulate node itself input)
this.encapsulateVariableService.updateVarsAfterEncapsulate(
subFlowNode,
nodes,
encapsulateVars,
);
// 移除老节点
// Remove old node
await this.encapsulateNodesService.deleteNodes(nodes);
// 生成新连线
// Create a new connection
const { inputLines, outputLines } =
this.encapsulateLinesService.createEncapsulateLines(ports, subFlowNode);
await delay(30);

View File

@@ -69,7 +69,7 @@ export class EncapsulateVariableService {
@inject(EncapsulateContext) encapsulateContext: EncapsulateContext;
/**
* 获取封装变量
* Get encapsulation variable
* @param nodes
* @returns
*/
@@ -84,7 +84,7 @@ export class EncapsulateVariableService {
}
/**
* 主动封装时,更新 WorkflowJSON 内部的变量引用
* When actively encapsulating, update variable references inside WorkflowJSON
* @param workflowJSON
* @param vars
* @returns
@@ -109,7 +109,7 @@ export class EncapsulateVariableService {
}
/**
* 更新节点JSON中的变量
* Update variables in node JSON
* @param nodes
* @param vars
* @param startId
@@ -126,7 +126,7 @@ export class EncapsulateVariableService {
_node.data = {};
}
// 开始节点设置
// Start Node Setup
if (_node.type === StandardNodeType.Start) {
_node.data.outputs = Object.entries(startVars).map(_entry => {
const [name, variable] = _entry;
@@ -137,7 +137,7 @@ export class EncapsulateVariableService {
});
return;
}
// 结束节点设置
// End Node Settings
if (_node.type === StandardNodeType.End) {
_node.data.inputs = {
terminatePlan: 'returnVariables',
@@ -167,7 +167,7 @@ export class EncapsulateVariableService {
_var.keyPath[1] === targetKeyPath[1],
);
// 如果命中开始节点的变量,则替换为开始节点的变量
// If the variable of the start node is hit, it is replaced with the variable of the start node
if (targetEntry) {
_ref.content.blockID = startId;
_ref.content.name = [targetEntry[0], ...targetKeyPath.slice(2)].join(
@@ -176,7 +176,7 @@ export class EncapsulateVariableService {
}
});
// 子画布场景需要递归
// Sub-canvas scenes need to be recursive
if (_node.blocks) {
this.updateVarsInEncapsulateNodesJSON(_node.blocks, vars, startId);
}
@@ -184,10 +184,10 @@ export class EncapsulateVariableService {
}
/**
* 封装后更新上下游的变量引用
* @param subFlowNode 封装节点
* @param selectNodes 选中的节点
* @param vars 封装变量
* Update upstream and downstream variable references after encapsulation
* @param subFlowNode encapsulation node
* @param selectNodes selected node
* @param vars encapsulation variable
*/
updateVarsAfterEncapsulate(
subFlowNode: FlowNodeEntity,
@@ -196,10 +196,10 @@ export class EncapsulateVariableService {
) {
const { startVars, endVars } = vars;
// 封装节点输入变量
// Encapsulating node input variables
this.setSubFlowNodeInputs(subFlowNode, startVars);
// 下游引用封装节点的变量
// Variables that encapsulate nodes by downstream references
const updateRefInfos: UpdateRefInfo[] = Object.entries(endVars).map(
_entry => {
const [name, variable] = _entry;
@@ -219,7 +219,7 @@ export class EncapsulateVariableService {
}
/**
* 解封装后更新上下游的变量引用
* Update upstream and downstream variable references after unencapsulation
*/
updateVarsAfterDecapsulate(
sourceNode: FlowNodeEntity,
@@ -231,17 +231,17 @@ export class EncapsulateVariableService {
.map(_node => this.document.getNode(_node.id || ''))
.filter(Boolean) as FlowNodeEntity[];
// 1, 更新封装节点内的变量
// 1. Update the variables in the encapsulated node
const sourceInputParameters: Record<string, ValueExpression> = sourceNode
.getData(FlowNodeFormData)
.formModel.getFormItemValueByPath('/inputs/inputParameters');
const updateInsideRefInfos: UpdateRefInfo[] = [
// 变量引用节点 Id 更新
// Variable reference node Id update
...idsMap.entries().map(_entry => ({
beforeKeyPath: [_entry[0]],
afterKeyPath: [_entry[1]],
})),
// 输入到封装节点内的变量
// Variables entered into the encapsulated node
...Object.entries(sourceInputParameters || {}).map(_entry => {
const [name, value] = _entry;
@@ -259,10 +259,10 @@ export class EncapsulateVariableService {
.batchUpdateRefs(updateInsideRefInfos);
});
// 2. 下游引用封装节点内的变量
// 2. Downstream references encapsulate variables within the node
const endOutputs: InputValueDTO[] =
get(endNode?.data || {}, 'inputs.inputParameters') || [];
// 从封装节点内输出的变量
// Variables output from within the encapsulated node
const updateOutsideRefInfos: UpdateRefInfo[] = endOutputs.map(_output => {
const { name, input } = _output || {};
const beforeKeyPath = [sourceNode.id, name || ''];
@@ -299,7 +299,7 @@ export class EncapsulateVariableService {
) {
const formData = subFlowNode.getData(FlowNodeFormData);
// SubFlow inputParameters Object 类型
// SubFlow's inputParameters are of type Object
const inputParameters: Record<string, InputValueVO> = Object.entries(
startVars,
)
@@ -318,14 +318,14 @@ export class EncapsulateVariableService {
};
}, {});
// 新表单引擎更新数据
// New form engine updates data
if (isFormV2(subFlowNode)) {
(formData.formModel as FormModelV2).setValueIn(
'inputs.inputParameters',
inputParameters,
);
} else {
// 老表单引擎更新数据
// Old form engine updates data
const fullData = formData.formModel.getFormItemValueByPath('/');
set(fullData, 'inputs.inputParameters', inputParameters);
formData.fireChange();
@@ -333,7 +333,7 @@ export class EncapsulateVariableService {
}
/**
* 获取封装节点的开始变量
* Get the start variable of the encapsulated node
* @param nodes
*/
protected getEncapsulateStartVars(nodes: FlowNodeEntity[]): VariableMap {
@@ -344,7 +344,7 @@ export class EncapsulateVariableService {
}
/**
* 获取封装节点变量
* Get encapsulated node variable
* @param _nodes
* @returns
*/
@@ -364,7 +364,7 @@ export class EncapsulateVariableService {
)
.map(_keyPath =>
this.variableService.getWorkflowVariableByKeyPath(
// 产品要求,只要取第一级即可
// Product requirements, as long as you take the first level.
_keyPath.slice(0, 2),
{ node: _node },
),
@@ -378,13 +378,13 @@ export class EncapsulateVariableService {
}
/**
* 获取封装节点的结束变量
* Get the end variable of the encapsulated node
* @param nodes
*/
protected getEncapsulateEndVars(nodes: FlowNodeEntity[]): VariableMap {
const selectNodeIds = nodes.map(_node => _node.id);
// 获取在圈选范围外的节点的所有引用圈选范围内的变量引用
// Get all references to nodes outside the circled scope Variable references in the circled scope
const variables = uniq(
this.getBeyondNodes(nodes)
.map(
@@ -393,7 +393,7 @@ export class EncapsulateVariableService {
.filter(_keyPath => selectNodeIds.includes(_keyPath[0]))
.map(_keyPath =>
this.variableService.getWorkflowVariableByKeyPath(
// 产品要求,只要取第一级即可
// Product requirements, as long as you take the first level.
_keyPath.slice(0, 2),
{ node: _node },
),
@@ -407,7 +407,7 @@ export class EncapsulateVariableService {
}
/**
* 获取圈选范围外的节点
* Get nodes outside the circled range
* @param nodes
* @returns
*/
@@ -420,7 +420,7 @@ export class EncapsulateVariableService {
}
/**
* 生成变量映射
* Generate variable mapping
* @param variables
*/
protected generateVariableMap(variables: WorkflowVariable[]): VariableMap {
@@ -429,7 +429,7 @@ export class EncapsulateVariableService {
let name = _keyPath[1];
let index = 1;
// 如果 name 已经存在,或者和系统默认字段冲突,则需要添加后缀
// If name already exists or conflicts with the system default field, you need to add a suffix
while (acm[name] || ['BOT_USER_INPUT'].includes(name)) {
name = `${_keyPath[1]}_${index}`;
index++;
@@ -449,9 +449,9 @@ export class EncapsulateVariableService {
}
/**
* 1. 情况1框选范围内所有节点的入参不包含USER_INPUTCONVERSATION_NAME此时封装出的子流程为workflow子流程start不带默认参数
* 2. 情况2框选范围内所有节点的入参同时包含了USER_INPUTCONVERSATION_NAME此时封装出的子流程为chatflow子流程start默认带参数USER_INPUTCONVERSATION_NAME,命名不变,建立和父流程引用关系
* 3. 情况3框选范围内所有节点的入参包含了USER_INPUTCONVERSATION_NAME中的一种此时封装出的子流程为workflow子流程start不带默认参数新建参数USER_INPUT_1CONVERSATION_NAME_1,建立和父流程引用关系
* 1. Case 1: The imported parameters of all nodes in the box selection range do not contain USER_INPUT and CONVERSATION_NAME. At this time, the encapsulated sub-process is workflow, and the sub-process start does not have default parameters
* 2. Case 2: The imported parameters of all nodes in the box selection range contain both USER_INPUT and CONVERSATION_NAME. At this time, the encapsulated sub-process is chatflow. The sub-process start defaults to parameters USER_INPUT and CONVERSATION_NAME, the name remains unchanged, and the reference relationship with the parent process is established
* 3. Case 3: The imported parameters of all nodes in the box selection range contain one of USER_INPUT and CONVERSATION_NAME. At this time, the encapsulated sub-process is workflow, the sub-process start does not have default parameters, and the new parameters USER_INPUT_1 or CONVERSATION_NAME_1 to establish a reference relationship with the parent process
*/
protected generateChatVariableMap(variablesMap: VariableMap): VariableMap {
if (variablesMap.USER_INPUT && !variablesMap.CONVERSATION_NAME) {

View File

@@ -26,48 +26,48 @@ import { type WorkflowVariable } from '@coze-workflow/variable';
import { type EncapsulateValidateResult } from '../validate';
/**
* 封装结果
* Encapsulation result
*/
export type EncapsulateResult =
| EncapsulateErrorResult
| EncapsulateSuccessResult;
/**
* 错误结果
* Wrong result
*/
export interface EncapsulateErrorResult {
/**
* 状态
* state
*/
success: false;
/**
* 消息提示
* message prompt
*/
message: string;
}
/**
* 成功结果
* successful outcome
*/
export interface EncapsulateSuccessResult {
/**
* 状态
* state
*/
success: true;
/**
* 生成的节点
* generated node
*/
subFlowNode: WorkflowNodeEntity;
/**
* 生成的输入线
* Generated input line
*/
inputLines: WorkflowLineEntity[];
/**
* 生成的输出线
* Generated output line
*/
outputLines: WorkflowLineEntity[];
/**
* 生成的workflow id
* Generated workflow id
*/
workflowId: string;
/**
@@ -77,35 +77,35 @@ export interface EncapsulateSuccessResult {
}
/**
* 封装/解封服务
* Encapsulation/unsealing service
*/
export interface EncapsulateService {
/**
* 是否可以封装
* Can it be encapsulated?
*/
canEncapsulate: () => boolean;
/**
* 封装
* package
*/
encapsulate: () => Promise<EncapsulateResult>;
/**
* 是否支持解封
* Whether to support unblocking
*/
canDecapsulate: (node: WorkflowNodeEntity) => boolean;
/**
* 解封
* unblock
*/
decapsulate: (node: WorkflowNodeEntity) => Promise<void>;
/**
* 校验
* validation
*/
validate: () => Promise<EncapsulateValidateResult>;
/**
* 封装成功回调
* Package successful callback
*/
onEncapsulate: Event<EncapsulateResult>;
/**
* 销毁
* destroy
*/
dispose: () => void;
}
@@ -113,15 +113,15 @@ export interface EncapsulateService {
export const EncapsulateService = Symbol('EncapsulateService');
/**
* 封装/解封管理
* Encapsulation/unsealing management
*/
export interface EncapsulateManager {
/**
* 初始化
* initialization
*/
init: () => void;
/**
* 销毁
* destroy
* @returns
*/
dispose: () => void;
@@ -130,7 +130,7 @@ export interface EncapsulateManager {
export const EncapsulateManager = Symbol('EncapsulateManager');
/**
* 连接端口
* connection port
*/
export interface ConnectPortsInfo {
inputLines: WorkflowLineEntity[];

View File

@@ -41,7 +41,7 @@ import {
} from './types';
/**
* 封装生成服务产生workflow相关的json数据
* Encapsulate the generation service and generate json data related to workflow
*/
@injectable()
export class EncapsulateGenerateServiceImpl
@@ -61,7 +61,7 @@ export class EncapsulateGenerateServiceImpl
private encapsulateContext: EncapsulateContext;
/**
* 生成workflow的json
* Generate json for workflow
* @param nodes
* @param options
* @returns
@@ -75,7 +75,7 @@ export class EncapsulateGenerateServiceImpl
const json = await this.workflowDocument.toJSON();
const nodeIds = nodes.map(node => node.id);
// step 1: 生成json
// Step 1: Generate JSON
const defaultJSON = this.defaultJSON();
const startNode = defaultJSON.nodes.find(
node => node.type === StandardNodeType.Start,
@@ -88,7 +88,7 @@ export class EncapsulateGenerateServiceImpl
throw new Error('start or end node not found');
}
// step 2: 生成封装节点的json
// Step 2: Generate JSON for encapsulated nodes
const parentId = getNodesParentId(nodes);
const parentNodes =
parentId === 'root'
@@ -107,14 +107,14 @@ export class EncapsulateGenerateServiceImpl
nodeIds.includes(edge.targetNodeID),
);
// step 3: 将 start end 连接到封装节点
// Step 3: Connect the start end to the encapsulation node
const { startEdges, endEdges } = this.generateStartEndEdges(
startNode,
endNode,
ports,
);
// step 4: 更新start end 的位置
// Step 4: Update the start end position
if (options?.startEndRects) {
setNodePositionByRect(startNode, options.startEndRects.start);
setNodePositionByRect(endNode, options.startEndRects.end);
@@ -130,7 +130,7 @@ export class EncapsulateGenerateServiceImpl
],
};
// step 5: 更新变量引用关系
// Step 5: Update variable reference relationships
const vars = this.encapsulateVariableService.getEncapsulateVars(nodes);
workflowJSON = this.encapsulateVariableService.updateVarsInEncapsulateJSON(
workflowJSON,
@@ -140,7 +140,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 生成子流程节点
* Generate subprocess nodes
* @param param0
* @returns
*/
@@ -169,7 +169,7 @@ export class EncapsulateGenerateServiceImpl
};
/**
* 生成开始结束边
* Generate start end edge
* @param startNode
* @param endNode
* @param ports
@@ -211,7 +211,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 默认的工作流json
* Default workflow json
*/
private defaultJSON() {
return {
@@ -222,7 +222,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 生成开始节点
* Generate start node
*/
private generateStartNode() {
return {
@@ -239,7 +239,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 生成结束节点
* end node generation
*/
private generateEndNode() {
return {
@@ -256,7 +256,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 获取节点的元数据
* Get the node's metadata
*/
private getTemplateNodeMeta(type: StandardNodeType) {
const template = this.encapsulateContext.getNodeTemplate(type);
@@ -271,7 +271,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 查找子工作流对应的json
* Find the json corresponding to the child workflow
* @param nodeJSONs
* @param parentId
* @returns
@@ -285,7 +285,7 @@ export class EncapsulateGenerateServiceImpl
}
/**
* 查找子画布对应的节点
* Find the node corresponding to the child canvas
* @param subCanvasId
* @returns
*/

View File

@@ -23,7 +23,7 @@ import {
import { type Rect } from '../types';
/**
* 生成子流程节点选项
* Generate subprocess node options
*/
export interface GenerateSubWorkflowNodeOptions {
name: string;
@@ -33,11 +33,11 @@ export interface GenerateSubWorkflowNodeOptions {
}
/**
* 封装生成服务
* Encapsulation Generation Service
*/
export interface EncapsulateGenerateService {
/**
* 生成流程
* generation flow
* @param nodes
* @returns
*/
@@ -51,7 +51,7 @@ export interface EncapsulateGenerateService {
},
) => Promise<WorkflowJSON>;
/**
* 生成子流程节点
* Generate subprocess nodes
* @param options
* @returns
*/

View File

@@ -31,7 +31,7 @@ import styles from './styles.module.less';
const HOVER_DELAY = 200;
/**
* 封装按钮
* encapsulation button
*/
export function EncapsulateButton() {
const encapsulateRenderService = useService<EncapsulateRenderService>(

View File

@@ -30,7 +30,7 @@ import { EncapsulateCommands } from './types';
import { EncapsulateRenderService } from './encapsulate-render-service';
/**
* 封装 快捷键
* Package shortcut
*/
@injectable()
export class EncapsulateShortcutsContribution
@@ -51,7 +51,7 @@ export class EncapsulateShortcutsContribution
registerShortcuts(registry: WorkflowShortcutsRegistry): void {
registry.addHandlers(
/**
* 封装
* package
*/
{
commandId: EncapsulateCommands.ENCAPSULATE,
@@ -82,7 +82,7 @@ export class EncapsulateShortcutsContribution
},
},
/**
* 解封
* unblock
*/
{
commandId: EncapsulateCommands.DECAPSULATE,

View File

@@ -109,14 +109,14 @@ export const EncapsulateTooltip: FC<PropsWithChildren<Props>> = ({
)}
</div>
{/* 没有错误来源的 */}
{/* No wrong sources */}
{(groupErrors.withoutSource || []).map((error, index) => (
<div key={index} className="flex mt-3 gap-4 items-start">
<ErrorMessage error={error} />
</div>
))}
{/* 有错误来源的 */}
{/* There is a wrong source */}
{(groupErrors.withSource || []).length ? (
<div className={styles.errors}>
{(groupErrors.withSource || []).map(error => (

View File

@@ -20,7 +20,7 @@ import { useService } from '@flowgram-adapter/free-layout-editor';
import { WorkflowSelectService } from '@flowgram-adapter/free-layout-editor';
/**
* 选中节点
* selected node
*/
export function useSelectedNodes() {
const selectService = useService<WorkflowSelectService>(

View File

@@ -30,7 +30,7 @@ import { useSelectedNodes } from './use-selected-nodes';
const DEBOUNCE_DELAY = 100;
/**
* 校验
* validation
*/
export function useValidate() {
const { selectedNodes } = useSelectedNodes();
@@ -38,7 +38,7 @@ export function useValidate() {
const [validating, setValidating] = useState(false);
const [errors, setErrors] = useState<EncapsulateValidateError[]>([]);
const validationIdRef = useRef(0); // 新增校验ID跟踪
const validationIdRef = useRef(0); // Added Verification ID Tracking
const handleValidate = async () => {
if (selectedNodes.length <= 1) {
@@ -46,13 +46,13 @@ export function useValidate() {
}
setValidating(true);
// 生成当前校验ID
// Generate the current verification ID
const currentValidationId = ++validationIdRef.current;
try {
const validateResult = await encapsulateService.validate();
// 只处理最后一次校验结果
// Only process the last verification result
if (currentValidationId === validationIdRef.current) {
setErrors(validateResult.getErrors());
setValidating(false);

View File

@@ -15,15 +15,15 @@
*/
/**
* 封装/解封命令
* Encapsulate/unencapsulate commands
*/
export enum EncapsulateCommands {
/**
* 封装
* package
*/
ENCAPSULATE = 'ENCAPSULATE',
/**
* 解封
* unblock
*/
DECAPSULATE = 'DECAPSULATE',
}

View File

@@ -16,8 +16,8 @@
import { getFlags } from '@coze-arch/bot-flags';
/**
* 校验是否可以封装
* @returns 是否可以封装
* Verify whether it can be encapsulated
* Can @returns be encapsulated?
*/
export function checkEncapsulateGray() {
const FLAGS = getFlags();

View File

@@ -18,7 +18,7 @@ import { StandardNodeType } from '@coze-workflow/base';
import { type WorkflowNodeEntity } from '@flowgram-adapter/free-layout-editor';
/**
* 排除开始和结束节点
* Exclude start and end nodes
* @param nodes
* @returns
*/

View File

@@ -22,7 +22,7 @@ import {
import { type IPoint } from '@flowgram-adapter/common';
/**
* 获取节点坐标
* Get node coordinates
* @param node
* @returns
*/

View File

@@ -17,7 +17,7 @@
import { type FlowNodeEntity } from '@flowgram-adapter/free-layout-editor';
/**
* 获取节点的父节点ID
* Get the parent ID of the node
*/
export const getNodesParentId = (nodes: FlowNodeEntity[]): string =>
nodes[0]?.parent?.id || 'root';

View File

@@ -21,7 +21,7 @@ import {
} from '@flowgram-adapter/free-layout-editor';
/**
* 获取有子节点的节点列表
* Get a list of nodes with sub-nodes
* @param nodes
* @returns
*/
@@ -34,7 +34,7 @@ export const getNodesWithSubCanvas = (nodes: FlowNodeEntity[]) =>
return [
node,
// 子画布对应的所有子节点
// All sub-nodes corresponding to the sub-canvas
...(subCanvas?.(node)?.canvasNode?.allCollapsedChildren || []),
];
})

View File

@@ -24,9 +24,9 @@ interface SubWorkflowInfo {
}
/**
* 获取子流程信息
* @param node 子流程节点
* @returns spaceId workflowId
* Get subprocess information
* @param node child process node
* @returns spaceId and workflowId
*/
export function getSubWorkflowInfo(
node: WorkflowNodeEntity,

View File

@@ -21,7 +21,7 @@ import {
} from '@flowgram-adapter/free-layout-editor';
/**
* 是否包含有子画布的节点
* Is there a node with a child canvas?
*/
export const hasSubCanvasNodes = (
workflowDocument: WorkflowDocument,

View File

@@ -20,7 +20,7 @@ import { type IPoint } from '@flowgram-adapter/common';
import { type Rect } from '../types';
/**
* 设置节点坐标
* Set node coordinates
* @param node
* @returns
*/
@@ -36,7 +36,7 @@ export function setNodePosition(
}
/**
* 根据矩形设置节点坐标
* Set node coordinates according to the rectangle
* @param node
* @param rect
*/

View File

@@ -21,7 +21,7 @@ import {
import { type WorkflowSubCanvas } from '@flowgram-adapter/free-layout-editor';
/**
* 多节点是否在子画布中
* Is the multi-node in the subcanvas?
* @param nodes
* @returns
*/
@@ -29,7 +29,7 @@ export const isNodesInSubCanvas = (nodes?: FlowNodeEntity[]) =>
isNodeInSubCanvas(nodes?.[0]);
/**
* 单节点是否在子画布中
* Is the single node in the subcanvas?
* @param nodes
* @returns
*/
@@ -37,7 +37,7 @@ export const isNodeInSubCanvas = (node?: FlowNodeEntity) =>
node?.parent?.id !== 'root';
/**
* 是不是子画布节点
* Is it a child canvas node?
* @param node
* @returns
*/
@@ -45,7 +45,7 @@ export const isSubCanvasNode = (node?: FlowNodeEntity) =>
node?.flowNodeType === FlowNodeBaseType.SUB_CANVAS;
/**
* 获取子画布的父节点
* Get the parent node of the child canvas
* @param node
* @returns
*/

View File

@@ -19,7 +19,7 @@ import { type WorkflowVariable } from '@coze-workflow/variable';
import { type DTODefine } from '@coze-workflow/base';
/**
* 遍历 DTO JSON 中的变量引用
* Traverse variable references in DTO JSON
* @param data
* @param cb
* @returns
@@ -29,7 +29,7 @@ export function traverseRefsInNodeJSON(
cb: (_ref: DTODefine.RefExpression) => void,
) {
if (isObject(data)) {
// 判断是否符合 ValueExpressionDTO 的结构
// Determine if it conforms to the structure of ValueExpressionDTO
if (
get(data, 'type') === 'ref' &&
get(data, 'content.source') === 'block-output' &&
@@ -53,7 +53,7 @@ export function traverseRefsInNodeJSON(
}
/**
* 变量排序
* variable sort
* @param variable
* @returns
*/

View File

@@ -87,8 +87,8 @@ export class EncapsulateValidateServiceImpl
this.encapsulateValidateManager.getNodesValidators();
for (const nodesValidator of nodesValidators) {
// 如果节点校验器需要包含起始节点和结束节点,则直接校验
// 否则需要排除起始节点和结束节点
// If the node validator needs to include a start node and an end node, it is directly validated
// Otherwise, the start and end nodes need to be excluded.
nodesValidator.validate(
nodesValidator.includeStartEnd ? nodes : excludeStartEnd(nodes),
validateResult,

View File

@@ -21,33 +21,33 @@ import {
} from '@flowgram-adapter/free-layout-editor';
/**
* 封装校验结果
* Encapsulation check result
*/
export interface EncapsulateValidateError {
/**
* 错误码
* error code
*/
code: EncapsulateValidateErrorCode;
/**
* 错误信息
* error message
*/
message: string;
/**
* 错误来源, 如果是节点问题, 就是节点ID
* The source of the error, if it is a node problem, is the node ID.
*/
source?: string;
/**
* 错误来源名称
* Error source name
*/
sourceName?: string;
/**
* 来源图标
* source icon
*/
sourceIcon?: string;
}
/**
* 校验错误码
* check error code
*/
export enum EncapsulateValidateErrorCode {
NO_START_END = '1001',
@@ -62,24 +62,24 @@ export enum EncapsulateValidateErrorCode {
}
/**
* 校验结果
* verification result
*/
export interface EncapsulateValidateResult {
/**
* 是否有错误
* Is there an error?
*/
hasError: () => boolean;
/**
* 添加错误
* add error
*/
addError: (error: EncapsulateValidateError) => void;
/**
* 获取错误列表
* Get error list
* @returns
*/
getErrors: () => EncapsulateValidateError[];
/**
* 是否有特定code的错误
* Is there a specific code error?
*/
hasErrorCode: (code: EncapsulateValidateErrorCode) => boolean;
}
@@ -87,7 +87,7 @@ export interface EncapsulateValidateResult {
export const EncapsulateValidateResult = Symbol('EncapsulateValidateResult');
/**
* 校验结果工厂
* Validation Result Factory
*/
export type EncapsulateValidateResultFactory = () => EncapsulateValidateResult;
@@ -96,15 +96,15 @@ export const EncapsulateValidateResultFactory = Symbol(
);
/**
* 封装节点校验器
* Encapsulated Node Verifier
*/
export interface EncapsulateNodeValidator {
/**
* 节点类型
* Node type
*/
canHandle: (type: StandardNodeType) => boolean;
/**
* 节点校验
* node validation
*/
validate: (
node: WorkflowNodeEntity,
@@ -115,18 +115,18 @@ export interface EncapsulateNodeValidator {
export const EncapsulateNodeValidator = Symbol('EncapsulateNodeValidator');
/**
* 所有节点级别的校验器
* Validators for all node levels
*/
export interface EncapsulateNodesValidator {
/**
* 所有节点校验
* validate all nodes
*/
validate: (
nodes: WorkflowNodeEntity[],
result: EncapsulateValidateResult,
) => void;
/**
* 是否包含开始和结束节点
* Whether to include start and end nodes
*/
includeStartEnd?: boolean;
}
@@ -134,7 +134,7 @@ export interface EncapsulateNodesValidator {
export const EncapsulateNodesValidator = Symbol('EncapsulateNodesValidator');
/**
* 流程JSON校验器
* Process JSON validator
*/
export interface EncapsulateWorkflowJSONValidator {
validate: (
@@ -148,15 +148,15 @@ export const EncapsulateWorkflowJSONValidator = Symbol(
);
/**
* 封装校验管理
* Encapsulation Validation Management
*/
export interface EncapsulateValidateManager {
/**
* 获取所有节点校验器
* Get all node validators
*/
getNodeValidators: () => EncapsulateNodeValidator[];
/**
* 根据节点类型获取对应的校验器
* Get the corresponding validator according to the node type
* @param type
* @returns
*/
@@ -164,16 +164,16 @@ export interface EncapsulateValidateManager {
type: StandardNodeType,
) => EncapsulateNodeValidator[];
/**
* 获取所有流程级别校验器
* Get all process level validators
*/
getNodesValidators: () => EncapsulateNodesValidator[];
/**
* 获取所有流程JSON校验器
* Get all process JSON validators
* @returns
*/
getWorkflowJSONValidators: () => EncapsulateWorkflowJSONValidator[];
/**
* 销毁
* destroy
*/
dispose: () => void;
}
@@ -181,11 +181,11 @@ export interface EncapsulateValidateManager {
export const EncapsulateValidateManager = Symbol('EncapsulateValidateManager');
/**
* 封装校验服务
* Encapsulation Validation Service
*/
export interface EncapsulateValidateService {
/**
* 校验
* validation
* @param nodes
* @returns
*/

View File

@@ -39,7 +39,7 @@ export class EncapsulateFormValidator
}
async validate(node: WorkflowNodeEntity, result: EncapsulateValidateResult) {
// 注释节点不需要校验
// Note nodes do not require validation
if (
[StandardNodeType.Comment].includes(node.flowNodeType as StandardNodeType)
) {