From 81b0e937b31fce77bf33263b22c1f897c73c73dc Mon Sep 17 00:00:00 2001 From: empty Date: Mon, 12 Jan 2026 01:18:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=86=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E8=8C=83=E5=BC=8F=E4=BB=8E=20localStorage=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **数据库层 (src/db/index.js)**: - 为 paradigms 表添加 4 个新字段: * specialized_prompt: 存储专业化提示词 * expert_guidelines: 存储专家检查指令(JSON) * outline_template: 存储大纲模板 * recommended_tags: 存储推荐标签(JSON) - 新增数据库迁移函数 migrateDatabase(),自动为现有数据库添加新列 - 更新 getAllParadigms() 解析新字段 - 更新 addParadigm() 保存新字段 - 更新 updateParadigm() 支持新字段的更新 **Store 层 (src/stores/paradigm.js)**: - 将存储从 localStorage 改为数据库(IndexedDB/SQLite) - loadCustomParadigms() 现在从数据库加载,并自动迁移 localStorage 旧数据 - 新增 saveCustomParadigm(paradigm) 用于保存单个范式 - addCustomParadigm() 改为异步,调用数据库保存 - deleteCustomParadigm() 改为异步,调用数据库删除 - updateParadigmField() 改为异步,调用数据库更新 - clearAllCustomParadigms() 改为异步,调用数据库清空 - 迁移后自动清理 localStorage 中的旧数据 **优势**: - 范式数据现在包含在数据导出中 - 统一的数据管理接口 - 更可靠的数据持久化 - 自动迁移现有数据,用户无感知 Co-Authored-By: Claude --- src/db/index.js | 92 ++++++++++++++++++++++++++----- src/stores/paradigm.js | 120 +++++++++++++++++++++++++++++++++-------- 2 files changed, 179 insertions(+), 33 deletions(-) diff --git a/src/db/index.js b/src/db/index.js index 7fcfc99..74eb3d8 100644 --- a/src/db/index.js +++ b/src/db/index.js @@ -128,6 +128,10 @@ const initTables = async () => { logic_paradigms TEXT, auto_match_refs INTEGER DEFAULT 1, selected_refs TEXT, + specialized_prompt TEXT, + expert_guidelines TEXT, + outline_template TEXT, + recommended_tags TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, is_custom INTEGER DEFAULT 0 @@ -213,6 +217,45 @@ const initTables = async () => { `) console.log('✅ 数据表初始化完成') + + // 运行数据库迁移 + migrateDatabase() +} + +/** + * 数据库迁移:添加范式表的新字段 + */ +const migrateDatabase = () => { + try { + // 检查是否已存在 specialized_prompt 列 + const columns = query(` + SELECT name FROM pragma_table_info('paradigms') + `).map(row => row.name) + + const neededColumns = ['specialized_prompt', 'expert_guidelines', 'outline_template', 'recommended_tags'] + const missingColumns = neededColumns.filter(col => !columns.includes(col)) + + if (missingColumns.length > 0) { + console.log('🔄 检测到数据库需要迁移,添加新字段...') + + if (missingColumns.includes('specialized_prompt')) { + execute('ALTER TABLE paradigms ADD COLUMN specialized_prompt TEXT') + } + if (missingColumns.includes('expert_guidelines')) { + execute('ALTER TABLE paradigms ADD COLUMN expert_guidelines TEXT') + } + if (missingColumns.includes('outline_template')) { + execute('ALTER TABLE paradigms ADD COLUMN outline_template TEXT') + } + if (missingColumns.includes('recommended_tags')) { + execute('ALTER TABLE paradigms ADD COLUMN recommended_tags TEXT') + } + + console.log('✅ 数据库迁移完成') + } + } catch (error) { + console.error('❌ 数据库迁移失败:', error) + } } // ============================================ @@ -508,7 +551,7 @@ export const deleteReference = (id) => { */ export const getAllParadigms = () => { const paradigms = query('SELECT * FROM paradigms ORDER BY is_custom ASC, created_at DESC') - + return paradigms.map(p => ({ ...p, tags: p.tags ? JSON.parse(p.tags) : [], @@ -516,6 +559,10 @@ export const getAllParadigms = () => { customDimensions: p.custom_dimensions ? JSON.parse(p.custom_dimensions) : null, logicParadigms: p.logic_paradigms ? JSON.parse(p.logic_paradigms) : null, selectedRefs: p.selected_refs ? JSON.parse(p.selected_refs) : [], + specializedPrompt: p.specialized_prompt || null, + expertGuidelines: p.expert_guidelines ? JSON.parse(p.expert_guidelines) : null, + outlineTemplate: p.outline_template || null, + recommendedTags: p.recommended_tags ? JSON.parse(p.recommended_tags) : [], isCustom: p.is_custom === 1, autoMatchRefs: p.auto_match_refs === 1 })) @@ -526,11 +573,12 @@ export const getAllParadigms = () => { */ export const addParadigm = (paradigm) => { const id = paradigm.id || `paradigm-${Date.now()}` - + execute(` - INSERT INTO paradigms (id, name, icon, description, tags, tag_class, system_constraints, - dimension_set_id, custom_dimensions, logic_paradigms, auto_match_refs, selected_refs, is_custom) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + INSERT INTO paradigms (id, name, icon, description, tags, tag_class, system_constraints, + dimension_set_id, custom_dimensions, logic_paradigms, auto_match_refs, selected_refs, + specialized_prompt, expert_guidelines, outline_template, recommended_tags, is_custom) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, [ id, paradigm.name, @@ -544,9 +592,13 @@ export const addParadigm = (paradigm) => { paradigm.logicParadigms ? JSON.stringify(paradigm.logicParadigms) : null, paradigm.autoMatchRefs !== false ? 1 : 0, JSON.stringify(paradigm.selectedRefs || []), + paradigm.specializedPrompt || null, + paradigm.expertGuidelines ? JSON.stringify(paradigm.expertGuidelines) : null, + paradigm.outlineTemplate || null, + paradigm.recommendedTags ? JSON.stringify(paradigm.recommendedTags || []) : null, paradigm.isCustom ? 1 : 0 ]) - + return id } @@ -556,7 +608,7 @@ export const addParadigm = (paradigm) => { export const updateParadigm = (id, updates) => { const setClauses = [] const params = [] - + const fieldMap = { name: 'name', icon: 'icon', @@ -565,14 +617,14 @@ export const updateParadigm = (id, updates) => { dimensionSetId: 'dimension_set_id', autoMatchRefs: 'auto_match_refs' } - + Object.entries(updates).forEach(([key, value]) => { if (fieldMap[key]) { setClauses.push(`${fieldMap[key]} = ?`) params.push(key === 'autoMatchRefs' ? (value ? 1 : 0) : value) } }) - + if (updates.tags !== undefined) { setClauses.push('tags = ?') params.push(JSON.stringify(updates.tags)) @@ -589,12 +641,28 @@ export const updateParadigm = (id, updates) => { setClauses.push('selected_refs = ?') params.push(JSON.stringify(updates.selectedRefs)) } - + if (updates.specializedPrompt !== undefined) { + setClauses.push('specialized_prompt = ?') + params.push(updates.specializedPrompt) + } + if (updates.expertGuidelines !== undefined) { + setClauses.push('expert_guidelines = ?') + params.push(updates.expertGuidelines ? JSON.stringify(updates.expertGuidelines) : null) + } + if (updates.outlineTemplate !== undefined) { + setClauses.push('outline_template = ?') + params.push(updates.outlineTemplate) + } + if (updates.recommendedTags !== undefined) { + setClauses.push('recommended_tags = ?') + params.push(updates.recommendedTags ? JSON.stringify(updates.recommendedTags) : null) + } + setClauses.push('updated_at = CURRENT_TIMESTAMP') params.push(id) - + execute(`UPDATE paradigms SET ${setClauses.join(', ')} WHERE id = ?`, params) - + return true } diff --git a/src/stores/paradigm.js b/src/stores/paradigm.js index 05aee0e..e5bddf7 100644 --- a/src/stores/paradigm.js +++ b/src/stores/paradigm.js @@ -4,11 +4,15 @@ import { ref, computed } from 'vue' /** * 自定义范式管理 Store * 用于管理用户通过需求文档生成的自定义范式 + * 现已迁移到数据库存储(IndexedDB/SQLite) */ export const useParadigmStore = defineStore('paradigm', () => { - // 自定义范式列表(存储在 localStorage) + // 自定义范式列表(从数据库加载) const customParadigms = ref([]) + // 数据库是否已初始化 + const isDbInitialized = ref(false) + // 当前正在编辑的范式 const editingParadigm = ref(null) @@ -19,14 +23,62 @@ export const useParadigmStore = defineStore('paradigm', () => { const parsingProgress = ref('') /** - * 从 localStorage 加载自定义范式 + * 从数据库加载自定义范式 + * 如果 localStorage 中有旧数据,自动迁移到数据库 */ - function loadCustomParadigms() { + async function loadCustomParadigms() { try { - const stored = localStorage.getItem('customParadigms') - if (stored) { - customParadigms.value = JSON.parse(stored) + // 动态导入数据库模块(避免循环依赖) + const { getAllParadigms, addParadigm, updateParadigm } = await import('../db/index.js') + + // 从数据库加载所有范式 + const allParadigms = getAllParadigms() + + // 过滤出自定义范式 + customParadigms.value = allParadigms.filter(p => p.isCustom) + + // 检查 localStorage 中是否有旧数据需要迁移 + const localStorageData = localStorage.getItem('customParadigms') + if (localStorageData && !isDbInitialized.value) { + try { + const oldParadigms = JSON.parse(localStorageData) + + if (oldParadigms.length > 0) { + console.log(`🔄 检测到 localStorage 中有 ${oldParadigms.length} 个范式,开始迁移...`) + + // 迁移每个范式到数据库 + for (const oldParadigm of oldParadigms) { + // 检查数据库中是否已存在 + const existing = customParadigms.value.find(p => p.id === oldParadigm.id) + + if (existing) { + // 更新现有范式 + updateParadigm(oldParadigm.id, oldParadigm) + } else { + // 添加新范式 + addParadigm({ + ...oldParadigm, + isCustom: true, + autoMatchRefs: oldParadigm.autoMatchRefs !== false + }) + } + } + + // 重新加载从数据库 + const updatedParadigms = getAllParadigms() + customParadigms.value = updatedParadigms.filter(p => p.isCustom) + + // 清除 localStorage 中的旧数据 + localStorage.removeItem('customParadigms') + + console.log('✅ 范式迁移完成,localStorage 已清理') + } + } catch (migrateError) { + console.error('❌ 迁移 localStorage 数据失败:', migrateError) + } } + + isDbInitialized.value = true } catch (error) { console.error('加载自定义范式失败:', error) customParadigms.value = [] @@ -34,11 +86,26 @@ export const useParadigmStore = defineStore('paradigm', () => { } /** - * 保存自定义范式到 localStorage + * 保存单个自定义范式到数据库(替换旧的批量保存) */ - function saveCustomParadigms() { + async function saveCustomParadigm(paradigm) { try { - localStorage.setItem('customParadigms', JSON.stringify(customParadigms.value)) + const { addParadigm, updateParadigm } = await import('../db/index.js') + + // 检查是否已存在 + const existing = customParadigms.value.find(p => p.id === paradigm.id) + + if (existing) { + // 更新现有范式 + updateParadigm(paradigm.id, paradigm) + } else { + // 添加新范式 + addParadigm({ + ...paradigm, + isCustom: true, + autoMatchRefs: paradigm.autoMatchRefs !== false + }) + } } catch (error) { console.error('保存自定义范式失败:', error) } @@ -48,7 +115,7 @@ export const useParadigmStore = defineStore('paradigm', () => { * 添加自定义范式 * @param {Object} paradigm - 范式对象 */ - function addCustomParadigm(paradigm) { + async function addCustomParadigm(paradigm) { // 检查是否已存在相同ID const index = customParadigms.value.findIndex(p => p.id === paradigm.id) if (index >= 0) { @@ -58,16 +125,21 @@ export const useParadigmStore = defineStore('paradigm', () => { // 添加新范式 customParadigms.value.push(paradigm) } - saveCustomParadigms() + await saveCustomParadigm(paradigm) } /** * 删除自定义范式 * @param {string} paradigmId - 范式ID */ - function deleteCustomParadigm(paradigmId) { - customParadigms.value = customParadigms.value.filter(p => p.id !== paradigmId) - saveCustomParadigms() + async function deleteCustomParadigm(paradigmId) { + try { + const { deleteParadigm } = await import('../db/index.js') + deleteParadigm(paradigmId) + customParadigms.value = customParadigms.value.filter(p => p.id !== paradigmId) + } catch (error) { + console.error('删除自定义范式失败:', error) + } } /** @@ -85,11 +157,11 @@ export const useParadigmStore = defineStore('paradigm', () => { * @param {string} field - 字段名 * @param {any} value - 新值 */ - function updateParadigmField(paradigmId, field, value) { + async function updateParadigmField(paradigmId, field, value) { const paradigm = getCustomParadigmById(paradigmId) if (paradigm) { paradigm[field] = value - saveCustomParadigms() + await saveCustomParadigm(paradigm) } } @@ -170,9 +242,14 @@ export const useParadigmStore = defineStore('paradigm', () => { /** * 清空所有自定义范式(慎用) */ - function clearAllCustomParadigms() { - customParadigms.value = [] - saveCustomParadigms() + async function clearAllCustomParadigms() { + try { + const { execute } = await import('../db/index.js') + execute('DELETE FROM paradigms WHERE is_custom = 1') + customParadigms.value = [] + } catch (error) { + console.error('清空自定义范式失败:', error) + } } /** @@ -234,7 +311,7 @@ export const useParadigmStore = defineStore('paradigm', () => { return updatedParadigm } - // 初始化时加载 + // 初始化时加载(异步) loadCustomParadigms() return { @@ -243,6 +320,7 @@ export const useParadigmStore = defineStore('paradigm', () => { editingParadigm, isParsing, parsingProgress, + isDbInitialized, // 计算属性 customParadigmCount, @@ -250,7 +328,7 @@ export const useParadigmStore = defineStore('paradigm', () => { // 方法 loadCustomParadigms, - saveCustomParadigms, + saveCustomParadigm, // 单个保存(新) addCustomParadigm, deleteCustomParadigm, getCustomParadigmById,