feat(快捷短语): 添加快捷短语核心功能模块
工具函数模块: - 实现 localStorage 存储和加载功能 - 提供默认快捷短语模板(写作助手、代码解释、优化建议等) - 添加数据验证和排序函数 Hook 模块: - 实现增删改查功能 - 支持拖拽排序 - 自动同步到 localStorage - 提供重置为默认值功能
This commit is contained in:
parent
92deb89e2a
commit
4499f7befd
141
src/hooks/useQuickPhrases.ts
Normal file
141
src/hooks/useQuickPhrases.ts
Normal file
@ -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<QuickPhrase, 'id' | 'createdAt' | 'updatedAt' | 'sortOrder'>) => void;
|
||||
updatePhrase: (id: string, updates: Partial<Omit<QuickPhrase, 'id' | 'createdAt'>>) => void;
|
||||
deletePhrase: (id: string) => void;
|
||||
reorderPhrases: (reorderedPhrases: QuickPhrase[]) => void;
|
||||
resetToDefaults: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 快捷短语管理 Hook
|
||||
* 提供快捷短语的增删改查功能,并自动同步到 localStorage
|
||||
*/
|
||||
export function useQuickPhrases(): UseQuickPhrasesReturn {
|
||||
const [phrases, setPhrases] = useState<QuickPhrase[]>([]);
|
||||
|
||||
// 初始化:从 localStorage 加载数据
|
||||
useEffect(() => {
|
||||
const loadedPhrases = loadPhrasesFromStorage();
|
||||
setPhrases(loadedPhrases);
|
||||
}, []);
|
||||
|
||||
// 保存到 localStorage 的辅助函数
|
||||
const saveAndUpdate = useCallback((newPhrases: QuickPhrase[]) => {
|
||||
savePhrasesToStorage(newPhrases);
|
||||
setPhrases(newPhrases);
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* 添加新短语
|
||||
*/
|
||||
const addPhrase = useCallback(
|
||||
(phrase: Omit<QuickPhrase, 'id' | 'createdAt' | 'updatedAt' | 'sortOrder'>) => {
|
||||
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<Omit<QuickPhrase, 'id' | 'createdAt'>>) => {
|
||||
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,
|
||||
};
|
||||
}
|
||||
118
src/lib/quick-phrases.ts
Normal file
118
src/lib/quick-phrases.ts
Normal file
@ -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<QuickPhrase>): 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);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user