mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-15 19:19:35 +08:00
- 新增外部 SQL 文件的新建、重命名、删除和目录管理接口 - 后端限制 SQL 目录只加载 .sql 文件并补充目录操作测试 - 前端补齐 Wails 类型、浏览器 mock 和外部 SQL 树过滤逻辑 - 支持从外部 SQL 文件标签定位到侧栏目录节点
142 lines
4.6 KiB
TypeScript
142 lines
4.6 KiB
TypeScript
import type { ExternalSQLDirectory, ExternalSQLTreeEntry } from '../types';
|
|
|
|
export type ExternalSQLNodeType =
|
|
| 'external-sql-root'
|
|
| 'external-sql-directory'
|
|
| 'external-sql-folder'
|
|
| 'external-sql-file';
|
|
|
|
export interface ExternalSQLTreeNode {
|
|
title: string;
|
|
key: string;
|
|
isLeaf?: boolean;
|
|
children?: ExternalSQLTreeNode[];
|
|
type: ExternalSQLNodeType;
|
|
dataRef: Record<string, unknown>;
|
|
}
|
|
|
|
type BuildExternalSQLRootNodeParams = {
|
|
dbNodeKey?: string;
|
|
connectionId?: string;
|
|
dbName?: string;
|
|
directories: ExternalSQLDirectory[];
|
|
directoryTrees: Record<string, ExternalSQLTreeEntry[]>;
|
|
};
|
|
|
|
const normalizeExternalSQLPath = (value: string): string =>
|
|
String(value || '').trim().replace(/\\/g, '/');
|
|
|
|
const resolveDirectoryDisplayName = (directory: ExternalSQLDirectory): string => {
|
|
const explicitName = String(directory.name || '').trim();
|
|
if (explicitName) return explicitName;
|
|
const normalizedPath = normalizeExternalSQLPath(directory.path);
|
|
const segments = normalizedPath.split('/').filter(Boolean);
|
|
return segments[segments.length - 1] || 'SQL目录';
|
|
};
|
|
|
|
export const buildExternalSQLDirectoryId = (connectionId: string, dbName: string, directoryPath: string): string =>
|
|
`external-sql-dir:${normalizeExternalSQLPath(directoryPath)}`;
|
|
|
|
export const buildExternalSQLTabId = (connectionId: string, dbName: string, filePath: string): string =>
|
|
`external-sql-tab:${String(connectionId || '').trim()}:${String(dbName || '').trim()}:${normalizeExternalSQLPath(filePath)}`;
|
|
|
|
const buildExternalSQLNodeKey = (type: ExternalSQLNodeType, base: string): string =>
|
|
`${type}:${normalizeExternalSQLPath(base)}`;
|
|
|
|
const isExternalSQLFileEntry = (entry: ExternalSQLTreeEntry): boolean => {
|
|
const name = String(entry.name || '').trim();
|
|
const path = normalizeExternalSQLPath(entry.path);
|
|
return /\.sql$/i.test(name) || /\.sql$/i.test(path);
|
|
};
|
|
|
|
const mapExternalSQLTreeEntries = (
|
|
entries: ExternalSQLTreeEntry[],
|
|
context: { connectionId: string; dbName: string; dbNodeKey: string; directoryId: string },
|
|
): ExternalSQLTreeNode[] => entries.flatMap((entry): ExternalSQLTreeNode[] => {
|
|
const entryPath = normalizeExternalSQLPath(entry.path);
|
|
if (entry.isDir) {
|
|
const children = mapExternalSQLTreeEntries(entry.children || [], context);
|
|
return [{
|
|
title: entry.name,
|
|
key: buildExternalSQLNodeKey('external-sql-folder', entryPath),
|
|
type: 'external-sql-folder',
|
|
isLeaf: children.length === 0,
|
|
children: children.length > 0 ? children : undefined,
|
|
dataRef: {
|
|
connectionId: context.connectionId,
|
|
dbName: context.dbName,
|
|
dbNodeKey: context.dbNodeKey,
|
|
directoryId: context.directoryId,
|
|
path: entry.path,
|
|
name: entry.name,
|
|
},
|
|
}];
|
|
}
|
|
|
|
if (!isExternalSQLFileEntry(entry)) {
|
|
return [];
|
|
}
|
|
|
|
return [{
|
|
title: entry.name,
|
|
key: buildExternalSQLNodeKey('external-sql-file', entryPath),
|
|
type: 'external-sql-file',
|
|
isLeaf: true,
|
|
dataRef: {
|
|
connectionId: context.connectionId,
|
|
dbName: context.dbName,
|
|
dbNodeKey: context.dbNodeKey,
|
|
directoryId: context.directoryId,
|
|
path: entry.path,
|
|
name: entry.name,
|
|
},
|
|
}];
|
|
});
|
|
|
|
export const buildExternalSQLRootNode = ({
|
|
dbNodeKey = 'external-sql-root',
|
|
connectionId = '',
|
|
dbName = '',
|
|
directories,
|
|
directoryTrees,
|
|
}: BuildExternalSQLRootNodeParams): ExternalSQLTreeNode => {
|
|
const sortedDirectories = [...directories].sort((left, right) =>
|
|
resolveDirectoryDisplayName(left).toLowerCase().localeCompare(resolveDirectoryDisplayName(right).toLowerCase()),
|
|
);
|
|
|
|
const children = sortedDirectories.map((directory) => {
|
|
const directoryChildren = mapExternalSQLTreeEntries(directoryTrees[directory.id] || [], {
|
|
connectionId,
|
|
dbName,
|
|
dbNodeKey,
|
|
directoryId: directory.id,
|
|
});
|
|
return {
|
|
title: resolveDirectoryDisplayName(directory),
|
|
key: buildExternalSQLNodeKey('external-sql-directory', directory.id),
|
|
type: 'external-sql-directory' as const,
|
|
isLeaf: directoryChildren.length === 0,
|
|
children: directoryChildren.length > 0 ? directoryChildren : undefined,
|
|
dataRef: {
|
|
...directory,
|
|
connectionId,
|
|
dbName,
|
|
dbNodeKey,
|
|
},
|
|
};
|
|
});
|
|
|
|
return {
|
|
title: children.length > 0 ? `外部 SQL 目录 (${children.length})` : '外部 SQL 目录',
|
|
key: dbNodeKey === 'external-sql-root' ? 'external-sql-root' : `${dbNodeKey}-external-sql`,
|
|
type: 'external-sql-root',
|
|
isLeaf: children.length === 0,
|
|
children: children.length > 0 ? children : undefined,
|
|
dataRef: {
|
|
connectionId,
|
|
dbName,
|
|
dbNodeKey,
|
|
},
|
|
};
|
|
};
|