Files
EasyFlow/easyflow-ui-admin/app/src/views/ai/workflow/customNode/datasetOptions.ts
陈子默 d244a0404d fix: 收口管理端页面权限与工作流运行授权
- 页面选项接口改用所属页面权限并返回最小数据视图

- 统一校验工作流引用、租户、状态与定时任务执行主体

- 补充聊天记录权限迁移和权限隔离回归测试
2026-08-07 12:51:21 +08:00

191 lines
5.3 KiB
TypeScript

import { api } from '#/api/request';
export interface DatasetRefPayload {
sourceId: null | number | string;
catalogId?: null | number | string;
catalogName?: string;
tableId: null | number | string;
tableName: string;
versionId?: null | number | string;
}
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 tableId = option.datasetRef?.tableId;
const key =
tableId === null || tableId === undefined
? [
option.datasetRef?.sourceId ?? '',
option.datasetRef?.catalogId ?? '',
option.tableName ?? '',
].join(':')
: String(tableId);
if (!uniqueOptions.has(key)) {
uniqueOptions.set(key, option);
}
}
return [...uniqueOptions.values()];
}
export async function loadManagedDatasetOptions(): Promise<
ManagedDatasetOption[]
> {
const sourceRes = await api.get('/api/v1/workflow/designer/dataSources');
const sources = sourceRes.data || [];
const options: ManagedDatasetOption[] = [];
for (const source of sources) {
try {
const catalogRes = await api.get('/api/v1/workflow/designer/catalogs', {
params: {
sourceId: source.id,
},
});
const catalogs = catalogRes.data || [];
for (const catalog of catalogs) {
const tableRes = await api.get(
'/api/v1/workflow/designer/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 || sourceId === undefined) {
continue;
}
if (!grouped.has(sourceId)) {
grouped.set(sourceId, {
sourceId,
sourceName: option.sourceName,
sourceType: option.sourceType,
label: option.sourceName,
keywords: option.sourceName.toLowerCase(),
tables: [],
});
}
const group = grouped.get(sourceId);
if (group) {
group.tables.push(option);
}
}
return [...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/workflow/designer/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.tableName || datasetRef.tableName,
tableDesc: data.tableDesc,
fields,
};
}