From e677daa0c0c18b3e1cd1295281f8ad42b632c25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=B2=A9=E5=B2=A9?= Date: Wed, 11 Feb 2026 14:18:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(M3.2):=20=E8=AF=8D=E5=85=B8=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=99=A8=20(v0.2.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/QUICK_REF.md | 2 +- docs/README.md | 6 +- docs/VERSION.md | 2 +- manifest.json | 2 +- package.json | 2 +- src/shared/dictionary/manager.js | 140 +++++++++++++++++++++++++++++++ 6 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 src/shared/dictionary/manager.js diff --git a/docs/QUICK_REF.md b/docs/QUICK_REF.md index c620097..262dd83 100644 --- a/docs/QUICK_REF.md +++ b/docs/QUICK_REF.md @@ -7,7 +7,7 @@ ## 版本速查 ### 当前版本 -`0.2.1` → 下一目标 `0.2.2` ([M3.2](./M3.md)) +`0.2.2` → 下一目标 `0.2.3` ([M3.3](./M3.md)) ### 模块版本范围 diff --git a/docs/README.md b/docs/README.md index f9c4321..0b17515 100644 --- a/docs/README.md +++ b/docs/README.md @@ -65,9 +65,9 @@ M11.10完成 → 1.0.0 (正式发布) ## 当前状态 -**当前版本**: `0.2.1` -**当前进度**: 15/97 (15%) -**下一任务**: [M3.2 词典管理器](./M3.md#m32-词典管理器--目标版本-022) +**当前版本**: `0.2.2` +**当前进度**: 16/97 (16%) +**下一任务**: [M3.3 必应词典实现(Mock版)](./M3.md#m33-必应词典实现mock版--目标版本-023) --- diff --git a/docs/VERSION.md b/docs/VERSION.md index c746d83..36ad522 100644 --- a/docs/VERSION.md +++ b/docs/VERSION.md @@ -37,7 +37,7 @@ | 任务 | 版本 | 描述 | 状态 | 日期 | |------|------|------|------|------| | M3.1 | 0.2.1 | 词典接口基类 | ✅ | 2026-02-11 | -| M3.2 | 0.2.2 | 词典管理器 | ⬜ | - | +| M3.2 | 0.2.2 | 词典管理器 | ✅ | 2026-02-11 | | M3.3 | 0.2.3 | 必应词典(Mock) | ⬜ | - | | M3.4 | 0.2.4 | 后台查询接口 | ⬜ | - | | M3.5 | 0.2.5 | 结果展示组件 | ⬜ | - | diff --git a/manifest.json b/manifest.json index c9badd3..a508792 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "沙拉查词", - "version": "0.2.1", + "version": "0.2.2", "description": "聚合词典划词翻译", "permissions": [ "storage", diff --git a/package.json b/package.json index f2305f7..3accd74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salad-dict", - "version": "0.2.1", + "version": "0.2.2", "description": "聚合词典划词翻译", "private": true, "type": "module", diff --git a/src/shared/dictionary/manager.js b/src/shared/dictionary/manager.js new file mode 100644 index 0000000..11ca948 --- /dev/null +++ b/src/shared/dictionary/manager.js @@ -0,0 +1,140 @@ +/** + * @file 词典管理器 + * @description 管理多个词典实例,支持注册、查询和获取词典列表 + */ + +import { DictionaryBase } from './base.js'; + +/** + * 词典管理器类 + * 负责管理所有词典实例的注册和查询 + */ +class DictionaryManager { + constructor() { + /** @type {Map} */ + this.dictionaries = new Map(); + } + + /** + * 注册词典实例 + * @param {string} name - 词典唯一标识名 + * @param {DictionaryBase} dictionaryInstance - 词典实例 + * @throws {Error} 名称不能为空或实例必须继承 DictionaryBase + */ + register(name, dictionaryInstance) { + if (!name || typeof name !== 'string') { + throw new Error('Dictionary name must be a non-empty string'); + } + + if (!(dictionaryInstance instanceof DictionaryBase)) { + throw new Error('Dictionary instance must extend DictionaryBase'); + } + + this.dictionaries.set(name, dictionaryInstance); + } + + /** + * 取消注册词典 + * @param {string} name - 词典名称 + * @returns {boolean} 是否成功移除 + */ + unregister(name) { + return this.dictionaries.delete(name); + } + + /** + * 获取指定名称的词典 + * @param {string} name - 词典名称 + * @returns {DictionaryBase|undefined} 词典实例 + */ + get(name) { + return this.dictionaries.get(name); + } + + /** + * 获取所有已注册的词典 + * @returns {Array<{name: string, dictionary: DictionaryBase}>} 词典列表 + */ + getAll() { + const result = []; + for (const [name, dictionary] of this.dictionaries) { + result.push({ name, dictionary }); + } + return result; + } + + /** + * 获取所有词典名称列表 + * @returns {Array} 词典名称数组 + */ + getNames() { + return Array.from(this.dictionaries.keys()); + } + + /** + * 查询单词 + * @param {string} word - 要查询的单词 + * @param {Array} [dictNames] - 指定查询的词典名称列表,不传则查询所有 + * @returns {Promise} 查询结果 {results: Array<{name: string, result: DictionaryResult}>, errors: Array<{name: string, error: string}>} + */ + async search(word, dictNames = []) { + if (!word || typeof word !== 'string' || !word.trim()) { + throw new Error('Search word must be a non-empty string'); + } + + const targetNames = dictNames.length > 0 + ? dictNames.filter(name => this.dictionaries.has(name)) + : this.getNames(); + + const results = []; + const errors = []; + + // 并行查询所有目标词典 + const promises = targetNames.map(async (name) => { + const dictionary = this.dictionaries.get(name); + try { + const result = await dictionary.search(word.trim()); + results.push({ name, result }); + } catch (error) { + errors.push({ + name, + error: error instanceof Error ? error.message : String(error) + }); + } + }); + + await Promise.all(promises); + + return { results, errors }; + } + + /** + * 检查词典是否已注册 + * @param {string} name - 词典名称 + * @returns {boolean} 是否已注册 + */ + has(name) { + return this.dictionaries.has(name); + } + + /** + * 获取已注册词典数量 + * @returns {number} 词典数量 + */ + get count() { + return this.dictionaries.size; + } + + /** + * 清空所有词典 + */ + clear() { + this.dictionaries.clear(); + } +} + +// 导出单例实例 +export const dictionaryManager = new DictionaryManager(); + +// 导出类,方便需要时创建新实例 +export { DictionaryManager };