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(); 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 { 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(); 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 { 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, }; }