feat(flow): 新增分组执行与异步模式支持
refactor(executors): 将 Rhai 引擎评估逻辑迁移至 script_rhai 模块 docs: 添加 Flow 架构文档与示例 JSON feat(i18n): 新增前端多语言支持 perf(axios): 优化 token 刷新与 401 处理逻辑 style: 统一代码格式化与简化条件判断
This commit is contained in:
@ -11,6 +11,7 @@ import {
|
||||
WorkflowDocument,
|
||||
} from '@flowgram.ai/free-layout-editor';
|
||||
import { Toast } from '@douyinfe/semi-ui';
|
||||
import { tr } from '../../utils/i18n';
|
||||
import { I18n } from '@flowgram.ai/free-layout-editor';
|
||||
import api, { type ApiResp } from '../../utils/axios';
|
||||
import { stringifyFlowDoc } from '../utils/yaml';
|
||||
@ -73,22 +74,29 @@ export class CustomService {
|
||||
@inject(WorkflowDocument) document!: WorkflowDocument;
|
||||
|
||||
// 新增可选参数,用于静默保存时不弹出 Toast,并返回是否保存成功
|
||||
async save(opts?: { silent?: boolean }): Promise<boolean> {
|
||||
async save(opts?: { silent?: boolean; executionMode?: 'sync'|'async'|'queued'|'bounded'; concurrencyLimit?: number }): Promise<boolean> {
|
||||
const silent = !!opts?.silent;
|
||||
try {
|
||||
const id = getFlowIdFromUrl();
|
||||
if (!id) {
|
||||
if (!silent) Toast.error(I18n.t('Flow ID is missing, cannot save'));
|
||||
if (!silent) Toast.error(tr('Flow ID is missing, cannot save'));
|
||||
return false;
|
||||
}
|
||||
const json = this.document.toJSON() as any;
|
||||
// 在根级写入执行配置(与后端契约保持一致:executionMode/concurrencyLimit)
|
||||
if (opts?.executionMode) {
|
||||
try { json.executionMode = opts.executionMode; } catch {}
|
||||
}
|
||||
if (typeof opts?.concurrencyLimit === 'number') {
|
||||
try { json.concurrencyLimit = opts.concurrencyLimit; } catch {}
|
||||
}
|
||||
const yaml = stringifyFlowDoc(json);
|
||||
// 使用转换后的 design_json,以便后端根据语言选择正确的执行器
|
||||
const designForBackend = transformDesignJsonForBackend(json);
|
||||
const design_json = JSON.stringify(designForBackend);
|
||||
const { data } = await api.put<ApiResp<{ saved: boolean }>>(`/flows/${id}`, { yaml, design_json });
|
||||
if (data?.code === 0) {
|
||||
if (!silent) Toast.success(I18n.t('Saved'));
|
||||
if (!silent) Toast.success(tr('Saved'));
|
||||
try {
|
||||
const key = (() => {
|
||||
const hash = window.location.hash || '';
|
||||
@ -101,12 +109,12 @@ export class CustomService {
|
||||
} catch {}
|
||||
return true;
|
||||
} else {
|
||||
const msg = data?.message || I18n.t('Save failed');
|
||||
const msg = data?.message || tr('Save failed');
|
||||
if (!silent) Toast.error(msg);
|
||||
return false;
|
||||
}
|
||||
} catch (e: any) {
|
||||
const msg = e?.message || I18n.t('Save failed');
|
||||
const msg = e?.message || tr('Save failed');
|
||||
if (!silent) Toast.error(msg);
|
||||
return false;
|
||||
}
|
||||
@ -116,16 +124,16 @@ export class CustomService {
|
||||
try {
|
||||
const id = getFlowIdFromUrl();
|
||||
if (!id) {
|
||||
Toast.error(I18n.t('Flow ID is missing, cannot run'));
|
||||
Toast.error(tr('Flow ID is missing, cannot run'));
|
||||
return null;
|
||||
}
|
||||
const { data } = await api.post<ApiResp<RunResult>>(`/flows/${id}/run`, { input });
|
||||
if (data?.code === 0) {
|
||||
return data.data;
|
||||
}
|
||||
throw new Error(data?.message || I18n.t('Run failed'));
|
||||
throw new Error(data?.message || tr('Run failed'));
|
||||
} catch (e: any) {
|
||||
Toast.error(e?.message || I18n.t('Run failed'));
|
||||
Toast.error(e?.message || tr('Run failed'));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -142,7 +150,7 @@ export class CustomService {
|
||||
) {
|
||||
const id = getFlowIdFromUrl();
|
||||
if (!id) {
|
||||
const err = new Error(I18n.t('Flow ID is missing, cannot run'));
|
||||
const err = new Error(tr('Flow ID is missing, cannot run'));
|
||||
handlers?.onFatal?.(err);
|
||||
return { cancel: () => {}, done: Promise.resolve<RunResult | null>(null) } as const;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user