From 4499f7befd81f4c7bbe45d4b5143f09e98b6350b Mon Sep 17 00:00:00 2001 From: gaoziman <2942894660@qq.com> Date: Wed, 24 Dec 2025 00:07:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=BF=AB=E6=8D=B7=E7=9F=AD=E8=AF=AD):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BF=AB=E6=8D=B7=E7=9F=AD=E8=AF=AD=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 工具函数模块: - 实现 localStorage 存储和加载功能 - 提供默认快捷短语模板(写作助手、代码解释、优化建议等) - 添加数据验证和排序函数 Hook 模块: - 实现增删改查功能 - 支持拖拽排序 - 自动同步到 localStorage - 提供重置为默认值功能 --- src/hooks/useQuickPhrases.ts | 141 +++++++++++++++++++++++++++++++++++ src/lib/quick-phrases.ts | 118 +++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 src/hooks/useQuickPhrases.ts create mode 100644 src/lib/quick-phrases.ts diff --git a/src/hooks/useQuickPhrases.ts b/src/hooks/useQuickPhrases.ts new file mode 100644 index 0000000..6de758a --- /dev/null +++ b/src/hooks/useQuickPhrases.ts @@ -0,0 +1,141 @@ +import { useState, useEffect, useCallback, useMemo } from 'react'; +import type { QuickPhrase } from '@/types'; +import { + loadPhrasesFromStorage, + savePhrasesToStorage, + generatePhraseId, + sortPhrases, + validatePhrase, +} from '@/lib/quick-phrases'; + +interface UseQuickPhrasesReturn { + phrases: QuickPhrase[]; + addPhrase: (phrase: Omit) => void; + updatePhrase: (id: string, updates: Partial>) => void; + deletePhrase: (id: string) => void; + reorderPhrases: (reorderedPhrases: QuickPhrase[]) => void; + resetToDefaults: () => void; +} + +/** + * 快捷短语管理 Hook + * 提供快捷短语的增删改查功能,并自动同步到 localStorage + */ +export function useQuickPhrases(): UseQuickPhrasesReturn { + const [phrases, setPhrases] = useState([]); + + // 初始化:从 localStorage 加载数据 + useEffect(() => { + const loadedPhrases = loadPhrasesFromStorage(); + setPhrases(loadedPhrases); + }, []); + + // 保存到 localStorage 的辅助函数 + const saveAndUpdate = useCallback((newPhrases: QuickPhrase[]) => { + savePhrasesToStorage(newPhrases); + setPhrases(newPhrases); + }, []); + + /** + * 添加新短语 + */ + const addPhrase = useCallback( + (phrase: Omit) => { + const now = Date.now(); + const newPhrase: QuickPhrase = { + ...phrase, + id: generatePhraseId(), + sortOrder: phrases.length + 1, // 添加到末尾 + createdAt: now, + updatedAt: now, + }; + + // 验证短语数据 + if (!validatePhrase(newPhrase)) { + console.error('Invalid phrase data:', newPhrase); + return; + } + + const newPhrases = [...phrases, newPhrase]; + saveAndUpdate(newPhrases); + }, + [phrases, saveAndUpdate] + ); + + /** + * 更新短语 + */ + const updatePhrase = useCallback( + (id: string, updates: Partial>) => { + const newPhrases = phrases.map((phrase) => { + if (phrase.id === id) { + const updatedPhrase = { + ...phrase, + ...updates, + updatedAt: Date.now(), + }; + return updatedPhrase; + } + return phrase; + }); + + saveAndUpdate(newPhrases); + }, + [phrases, saveAndUpdate] + ); + + /** + * 删除短语 + */ + const deletePhrase = useCallback( + (id: string) => { + const newPhrases = phrases.filter((phrase) => phrase.id !== id); + // 重新调整 sortOrder + const reorderedPhrases = newPhrases.map((phrase, index) => ({ + ...phrase, + sortOrder: index + 1, + })); + saveAndUpdate(reorderedPhrases); + }, + [phrases, saveAndUpdate] + ); + + /** + * 重新排序短语(用于拖拽排序) + */ + const reorderPhrases = useCallback( + (reorderedPhrases: QuickPhrase[]) => { + // 更新 sortOrder + const phrasesWithNewOrder = reorderedPhrases.map((phrase, index) => ({ + ...phrase, + sortOrder: index + 1, + updatedAt: Date.now(), + })); + saveAndUpdate(phrasesWithNewOrder); + }, + [saveAndUpdate] + ); + + /** + * 重置为默认短语 + */ + const resetToDefaults = useCallback(() => { + const defaultPhrases = loadPhrasesFromStorage(); + // 清除 localStorage 并重新加载默认值 + localStorage.removeItem('cch_quick_phrases'); + const freshDefaults = loadPhrasesFromStorage(); + saveAndUpdate(freshDefaults); + }, [saveAndUpdate]); + + // 返回排序后的短语列表 + const sortedPhrases = useMemo(() => sortPhrases(phrases), [phrases]); + + return { + phrases: sortedPhrases, + addPhrase, + updatePhrase, + deletePhrase, + reorderPhrases, + resetToDefaults, + }; +} diff --git a/src/lib/quick-phrases.ts b/src/lib/quick-phrases.ts new file mode 100644 index 0000000..b49067f --- /dev/null +++ b/src/lib/quick-phrases.ts @@ -0,0 +1,118 @@ +import type { QuickPhrase } from '@/types'; + +/** + * 生成唯一的快捷短语 ID + */ +export function generatePhraseId(): string { + return `phrase-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; +} + +/** + * 默认的快捷短语列表 + */ +export const DEFAULT_PHRASES: QuickPhrase[] = [ + { + id: 'default-1', + title: '写作助手', + content: '请帮我写一篇关于', + icon: 'PenTool', + sortOrder: 1, + createdAt: Date.now(), + updatedAt: Date.now(), + }, + { + id: 'default-2', + title: '代码解释', + content: '请解释这段代码的功能和工作原理:\n\n', + icon: 'Code', + sortOrder: 2, + createdAt: Date.now(), + updatedAt: Date.now(), + }, + { + id: 'default-3', + title: '优化建议', + content: '请帮我优化以下内容,使其更加专业和准确:\n\n', + icon: 'Sparkles', + sortOrder: 3, + createdAt: Date.now(), + updatedAt: Date.now(), + }, + { + id: 'default-4', + title: '翻译助手', + content: '请帮我翻译以下内容:\n\n', + icon: 'Languages', + sortOrder: 4, + createdAt: Date.now(), + updatedAt: Date.now(), + }, + { + id: 'default-5', + title: '头脑风暴', + content: '请帮我进行头脑风暴,给我一些关于以下主题的创意想法:\n\n', + icon: 'Lightbulb', + sortOrder: 5, + createdAt: Date.now(), + updatedAt: Date.now(), + }, +]; + +/** + * localStorage 的 key + */ +export const STORAGE_KEY = 'cch_quick_phrases'; + +/** + * 从 localStorage 加载快捷短语 + */ +export function loadPhrasesFromStorage(): QuickPhrase[] { + try { + const stored = localStorage.getItem(STORAGE_KEY); + if (stored) { + const phrases = JSON.parse(stored) as QuickPhrase[]; + // 验证数据格式 + if (Array.isArray(phrases) && phrases.length > 0) { + return phrases; + } + } + } catch (error) { + console.error('Failed to load quick phrases from storage:', error); + } + // 如果没有存储的数据或加载失败,返回默认短语 + return DEFAULT_PHRASES; +} + +/** + * 保存快捷短语到 localStorage + */ +export function savePhrasesToStorage(phrases: QuickPhrase[]): void { + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify(phrases)); + } catch (error) { + console.error('Failed to save quick phrases to storage:', error); + } +} + +/** + * 验证快捷短语数据 + */ +export function validatePhrase(phrase: Partial): phrase is QuickPhrase { + return ( + typeof phrase.id === 'string' && + typeof phrase.title === 'string' && + phrase.title.trim().length > 0 && + typeof phrase.content === 'string' && + phrase.content.trim().length > 0 && + typeof phrase.sortOrder === 'number' && + typeof phrase.createdAt === 'number' && + typeof phrase.updatedAt === 'number' + ); +} + +/** + * 按排序顺序对短语进行排序 + */ +export function sortPhrases(phrases: QuickPhrase[]): QuickPhrase[] { + return [...phrases].sort((a, b) => a.sortOrder - b.sortOrder); +}