Files
EasyFlow/easyflow-ui-admin/app/src/views/ai/workflow/customNode/datasetOptions.ts
陈子默 1ecc28e498 feat: 工作流适配数据中枢查询节点
- 新增查询数据与写入数据节点并移除旧数据中心节点入口

- 将查询数据节点切换为连接服务加 SQL 的执行模型

- 同步更新工作流校验、提示词上下文与设计器交互
2026-04-02 18:56:34 +08:00

185 lines
5.3 KiB
TypeScript

import { api } from '#/api/request';
export interface DatasetRefPayload {
sourceId: number | string | null;
catalogId?: number | string | null;
catalogName?: string;
tableId: number | string | null;
tableName: string;
versionId?: number | string | null;
}
export interface ManagedDatasetFieldOption {
fieldName: string;
fieldDesc?: string;
fieldType?: string;
}
export interface ManagedDatasetSchema {
tableName?: string;
tableDesc?: string;
fields: ManagedDatasetFieldOption[];
}
export interface ManagedDatasetOption {
label: string;
value: number | string;
keywords: string;
sourceName: string;
sourceType?: string;
catalogName: string;
tableName: string;
datasetRef: DatasetRefPayload;
}
export interface ManagedDatasetSourceOption {
sourceId: number | string;
sourceName: string;
sourceType?: string;
label: string;
keywords: string;
tables: ManagedDatasetOption[];
}
const SOURCE_MISSING_MESSAGE = '连接不存在';
const SOURCE_UNAVAILABLE_MESSAGE = '当前连接不可用,请检查连接配置后重试';
function shouldSkipSourceError(error: any) {
const responseData = error?.response?.data ?? {};
const message = String(responseData?.message ?? error?.message ?? '');
return (
message.includes(SOURCE_MISSING_MESSAGE) ||
message.includes(SOURCE_UNAVAILABLE_MESSAGE)
);
}
function dedupeManagedDatasetOptions(options: ManagedDatasetOption[]) {
const uniqueOptions = new Map<string, ManagedDatasetOption>();
for (const option of options || []) {
const key = option.datasetRef?.tableId != null
? String(option.datasetRef.tableId)
: [
option.datasetRef?.sourceId ?? '',
option.datasetRef?.catalogId ?? '',
option.tableName ?? '',
].join(':');
if (!uniqueOptions.has(key)) {
uniqueOptions.set(key, option);
}
}
return Array.from(uniqueOptions.values());
}
export async function loadManagedDatasetOptions(): Promise<ManagedDatasetOption[]> {
const sourceRes = await api.get('/api/v1/datacenterSource/page', {
params: {
pageNumber: 1,
pageSize: 200,
},
});
const sources = sourceRes.data?.records || [];
const options: ManagedDatasetOption[] = [];
for (const source of sources) {
try {
const catalogRes = await api.get('/api/v1/datacenterSource/catalogs', {
params: {
sourceId: source.id,
},
});
const catalogs = catalogRes.data || [];
for (const catalog of catalogs) {
const tableRes = await api.get('/api/v1/datacenterDataset/managedTables', {
params: {
sourceId: source.id,
catalogId: catalog.id,
},
});
const tables = tableRes.data || [];
for (const table of tables) {
const label = `${source.sourceName} / ${catalog.catalogName} / ${table.tableName}`;
options.push({
label,
value: table.id,
keywords: `${source.sourceName} ${catalog.catalogName} ${table.tableName}`.toLowerCase(),
sourceName: source.sourceName,
sourceType: source.sourceType,
catalogName: catalog.catalogName,
tableName: table.tableName,
datasetRef: {
sourceId: source.id,
catalogId: catalog.id,
catalogName: catalog.catalogName,
tableId: table.id,
tableName: table.tableName,
},
});
}
}
} catch (error) {
if (shouldSkipSourceError(error)) {
continue;
}
throw error;
}
}
return dedupeManagedDatasetOptions(options);
}
export function groupManagedDatasetOptions(
options: ManagedDatasetOption[],
): ManagedDatasetSourceOption[] {
const grouped = new Map<number | string, ManagedDatasetSourceOption>();
for (const option of dedupeManagedDatasetOptions(options || [])) {
const sourceId = option.datasetRef?.sourceId;
if (sourceId == null) {
continue;
}
if (!grouped.has(sourceId)) {
grouped.set(sourceId, {
sourceId,
sourceName: option.sourceName,
sourceType: option.sourceType,
label: option.sourceName,
keywords: option.sourceName.toLowerCase(),
tables: [],
});
}
grouped.get(sourceId)!.tables.push(option);
}
return Array.from(grouped.values()).map((item) => ({
...item,
keywords: `${item.sourceName} ${item.tables
.map((table) => `${table.catalogName} ${table.tableName}`)
.join(' ')}`.toLowerCase(),
tables: item.tables.sort((a, b) => a.label.localeCompare(b.label)),
}));
}
export async function loadManagedDatasetSchema(
datasetRef?: DatasetRefPayload | null,
): Promise<ManagedDatasetSchema> {
if (!datasetRef?.tableId) {
return {
tableName: datasetRef?.tableName,
fields: [],
};
}
const res = await api.get('/api/v1/datacenterDataset/schema', {
params: datasetRef,
});
const data = res.data || {};
const fields = Array.isArray(data.fields)
? data.fields.map((field: any) => ({
fieldName: field.fieldName,
fieldDesc: field.fieldDesc,
fieldType: field.jdbcType || field.fieldType,
}))
: [];
return {
tableName: data.table?.tableName || datasetRef.tableName,
tableDesc: data.table?.tableDesc,
fields,
};
}