新增:数据库 UI UX 大幅改进
功能增强: - 查询历史记录与快速重用(最多50条) - 查询模板管理(9个默认模板,支持自定义) - SQL 格式化功能(关键字大写、缩进美化) - 查询结果导出(CSV/JSON/Excel/Markdown) - 执行时间显示(带颜色指示:绿/橙/红) - 增强工具栏(整合所有功能) 新增组件: - QueryHistoryPanel.vue - 查询历史面板 - QueryTemplatesPanel.vue - 查询模板面板 - SQLEditorToolbar.vue - 增强工具栏 - useQueryHistory.js - 历史记录管理 - useQueryTemplates.js - 模板管理 - sqlFormatter.js - SQL 格式化工具 - resultExporter.js - 结果导出工具 修改组件: - SqlEditor.vue - 集成新功能与工具栏
This commit is contained in:
195
web/src/views/db-cli/composables/useQueryTemplates.js
Normal file
195
web/src/views/db-cli/composables/useQueryTemplates.js
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* 查询模板管理
|
||||
* 用于保存常用查询模板
|
||||
*/
|
||||
|
||||
const STORAGE_KEY = 'db-cli:query-templates'
|
||||
|
||||
// 默认模板
|
||||
const DEFAULT_TEMPLATES = [
|
||||
{
|
||||
id: 'template-1',
|
||||
name: '查询所有数据',
|
||||
description: '查询表中所有数据',
|
||||
query: 'SELECT * FROM table_name WHERE 1=1;',
|
||||
category: '基础查询'
|
||||
},
|
||||
{
|
||||
id: 'template-2',
|
||||
name: '分页查询',
|
||||
description: '带分页的数据查询',
|
||||
query: 'SELECT * FROM table_name WHERE 1=1 LIMIT 10 OFFSET 0;',
|
||||
category: '分页'
|
||||
},
|
||||
{
|
||||
id: 'template-3',
|
||||
name: '统计查询',
|
||||
description: '统计数据行数',
|
||||
query: 'SELECT COUNT(*) as total FROM table_name WHERE 1=1;',
|
||||
category: '统计'
|
||||
},
|
||||
{
|
||||
id: 'template-4',
|
||||
name: '插入数据',
|
||||
description: '插入单条数据',
|
||||
query: 'INSERT INTO table_name (column1, column2) VALUES (value1, value2);',
|
||||
category: '插入'
|
||||
},
|
||||
{
|
||||
id: 'template-5',
|
||||
name: '更新数据',
|
||||
description: '更新指定条件的数据',
|
||||
query: 'UPDATE table_name SET column1 = value1 WHERE id = 1;',
|
||||
category: '更新'
|
||||
},
|
||||
{
|
||||
id: 'template-6',
|
||||
name: '删除数据',
|
||||
description: '删除指定条件的数据',
|
||||
query: 'DELETE FROM table_name WHERE id = 1;',
|
||||
category: '删除'
|
||||
},
|
||||
{
|
||||
id: 'template-redis-1',
|
||||
name: 'Redis - 设置键值',
|
||||
description: 'SET 命令',
|
||||
query: 'SET key value',
|
||||
category: 'Redis',
|
||||
dbType: 'redis'
|
||||
},
|
||||
{
|
||||
id: 'template-redis-2',
|
||||
name: 'Redis - 获取键值',
|
||||
description: 'GET 命令',
|
||||
query: 'GET key',
|
||||
category: 'Redis',
|
||||
dbType: 'redis'
|
||||
},
|
||||
{
|
||||
id: 'template-mongo-1',
|
||||
name: 'MongoDB - 查询数据',
|
||||
description: 'find 查询',
|
||||
query: 'db.collection.find({ field: value })',
|
||||
category: 'MongoDB',
|
||||
dbType: 'mongodb'
|
||||
}
|
||||
]
|
||||
|
||||
export function useQueryTemplates() {
|
||||
/**
|
||||
* 获取模板列表
|
||||
*/
|
||||
const getTemplates = () => {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY)
|
||||
if (!stored) {
|
||||
// 首次使用,保存默认模板
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(DEFAULT_TEMPLATES))
|
||||
return DEFAULT_TEMPLATES
|
||||
}
|
||||
return JSON.parse(stored)
|
||||
} catch (e) {
|
||||
console.error('Failed to load query templates:', e)
|
||||
return DEFAULT_TEMPLATES
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存模板
|
||||
*/
|
||||
const saveTemplate = (template) => {
|
||||
const templates = getTemplates()
|
||||
const newTemplate = {
|
||||
id: `template-${Date.now()}`,
|
||||
name: template.name || '未命名模板',
|
||||
description: template.description || '',
|
||||
query: template.query,
|
||||
category: template.category || '自定义',
|
||||
dbType: template.dbType || 'mysql',
|
||||
createdAt: new Date().toISOString()
|
||||
}
|
||||
|
||||
const updated = [...templates, newTemplate]
|
||||
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(updated))
|
||||
return newTemplate
|
||||
} catch (e) {
|
||||
console.error('Failed to save query template:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模板
|
||||
*/
|
||||
const updateTemplate = (id, updates) => {
|
||||
const templates = getTemplates()
|
||||
const index = templates.findIndex(t => t.id === id)
|
||||
|
||||
if (index === -1) return null
|
||||
|
||||
templates[index] = {
|
||||
...templates[index],
|
||||
...updates,
|
||||
updatedAt: new Date().toISOString()
|
||||
}
|
||||
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(templates))
|
||||
return templates[index]
|
||||
} catch (e) {
|
||||
console.error('Failed to update query template:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模板
|
||||
*/
|
||||
const deleteTemplate = (id) => {
|
||||
const templates = getTemplates()
|
||||
const filtered = templates.filter(t => t.id !== id)
|
||||
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(filtered))
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('Failed to delete query template:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据数据库类型筛选模板
|
||||
*/
|
||||
const getTemplatesByType = (dbType) => {
|
||||
const templates = getTemplates()
|
||||
if (!dbType) return templates
|
||||
|
||||
// 通用模板(无 dbType) + 匹配当前 dbType 的模板
|
||||
return templates.filter(t => !t.dbType || t.dbType === dbType.toLowerCase())
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置为默认模板
|
||||
*/
|
||||
const resetToDefaults = () => {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(DEFAULT_TEMPLATES))
|
||||
return true
|
||||
} catch (e) {
|
||||
console.error('Failed to reset query templates:', e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getTemplates,
|
||||
saveTemplate,
|
||||
updateTemplate,
|
||||
deleteTemplate,
|
||||
getTemplatesByType,
|
||||
resetToDefaults
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user