feat(saved-query): 支持已存查询后端持久化与连接重绑

- 后端新增 saved_queries.json 仓库,保存、导入、删除和重绑统一走 Wails 方法
- 启动时导入旧 lite-db-storage 中的 savedQueries 和连接快照,成功后清理旧字段
- 新增连接指纹匹配,唯一强匹配自动重绑,歧义场景保留为未匹配
- 侧边栏新增未匹配已存查询分组,并支持手动绑定到目标连接
- 前端保存、重命名、删除查询改为后端持久化,并补充浏览器 mock
- 补充后端与前端迁移回归测试
This commit is contained in:
Syngnat
2026-06-15 12:20:57 +08:00
parent 0b9f0448c8
commit eca9601ab0
20 changed files with 1870 additions and 66 deletions

View File

@@ -5192,7 +5192,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
return rawTitle;
};
const persistQuery = (payload: { id: string; name: string; createdAt?: number }) => {
const persistQuery = async (payload: { id: string; name: string; createdAt?: number }) => {
const sql = getCurrentQuery();
const saved = {
id: payload.id,
@@ -5202,16 +5202,16 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
dbName: currentDb || tab.dbName || '',
createdAt: payload.createdAt ?? Date.now(),
};
saveQuery(saved);
const persisted = await saveQuery(saved);
addTab({
...tab,
title: payload.name,
title: persisted.name,
query: sql,
connectionId: currentConnectionId,
dbName: currentDb || tab.dbName || '',
savedQueryId: payload.id,
savedQueryId: persisted.id,
});
return saved;
return persisted;
};
const openSaveQueryModal = (mode: 'save' | 'rename') => {
@@ -5254,8 +5254,12 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
return;
}
const saveName = existed?.name || resolveDefaultQueryName();
persistQuery({ id: saveId, name: saveName, createdAt: existed?.createdAt });
message.success('查询已保存!');
try {
await persistQuery({ id: saveId, name: saveName, createdAt: existed?.createdAt });
message.success('查询已保存!');
} catch (error) {
message.error('保存查询失败: ' + (error instanceof Error ? error.message : String(error)));
}
};
const handleRenameQuery = () => {
@@ -5384,7 +5388,7 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
const existed = currentSavedQuery || null;
const fallbackSavedId = String(tab.savedQueryId || '').trim();
const nextSavedId = existed?.id || fallbackSavedId || `saved-${Date.now()}`;
persistQuery({
await persistQuery({
id: nextSavedId,
name: String(values.name || '').trim() || '未命名查询',
createdAt: existed?.createdAt,
@@ -5392,6 +5396,9 @@ const QueryEditor: React.FC<{ tab: TabData; isActive?: boolean }> = ({ tab, isAc
message.success(saveModalMode === 'rename' ? '查询已重命名!' : '查询已保存!');
setIsSaveModalOpen(false);
} catch (e) {
if (e instanceof Error) {
message.error('保存查询失败: ' + e.message);
}
}
};