feat: 工作流适配数据中枢查询节点
- 新增查询数据与写入数据节点并移除旧数据中心节点入口 - 将查询数据节点切换为连接服务加 SQL 的执行模型 - 同步更新工作流校验、提示词上下文与设计器交互
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user