Spaces:
Sleeping
Sleeping
import React, { createContext, useContext, useState, useEffect } from 'react'; | |
import { PromptGroup, Category } from '../types'; | |
import { promptGroupAPI, categoryAPI } from '../services/api'; | |
import { useAuth } from './AuthContext'; | |
interface AppContextType { | |
promptGroups: PromptGroup[]; | |
categories: Category[]; | |
loading: boolean; | |
error: string | null; | |
fetchPromptGroups: () => Promise<void>; | |
fetchCategories: () => Promise<void>; | |
addPromptGroup: (promptGroup: { name: string; description: string; category: string }) => Promise<PromptGroup>; | |
updatePromptGroup: (id: string, promptGroup: { name: string; description: string; category: string }) => Promise<void>; | |
deletePromptGroup: (id: string) => Promise<void>; | |
addPrompt: (groupId: string, prompt: { title: string; content: string; tags: string[] }) => Promise<void>; | |
updatePrompt: (groupId: string, promptId: string, prompt: { title: string; content: string; tags: string[] }) => Promise<void>; | |
deletePrompt: (groupId: string, promptId: string) => Promise<void>; | |
addDslFile: (groupId: string, dslFile: { name: string; content?: string; fileData?: string; mimeType?: string }) => Promise<void>; | |
updateDslFile: (groupId: string, fileId: string, dslFile: { name?: string; content?: string }) => Promise<void>; | |
deleteDslFile: (groupId: string, fileId: string) => Promise<void>; | |
addCategory: (category: { name: string; color: string }) => Promise<void>; | |
updateCategory: (id: string, category: { name: string; color: string }) => Promise<void>; | |
deleteCategory: (id: string) => Promise<void>; | |
} | |
const AppContext = createContext<AppContextType | undefined>(undefined); | |
export const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { | |
const [promptGroups, setPromptGroups] = useState<PromptGroup[]>([]); | |
const [categories, setCategories] = useState<Category[]>([]); | |
const [loading, setLoading] = useState<boolean>(false); | |
const [error, setError] = useState<string | null>(null); | |
const { isAuthenticated } = useAuth(); | |
// 初始加载数据 - 只有在用户已经认证后才加载 | |
useEffect(() => { | |
const loadInitialData = async () => { | |
if (isAuthenticated) { | |
setLoading(true); | |
try { | |
await Promise.all([fetchPromptGroups(), fetchCategories()]); | |
} catch (err: any) { | |
setError(err.message || '加载数据失败'); | |
} finally { | |
setLoading(false); | |
} | |
} | |
}; | |
loadInitialData(); | |
// eslint-disable-next-line | |
}, [isAuthenticated]); // 添加 isAuthenticated 作为依赖项 | |
// 获取所有提示词组 | |
const fetchPromptGroups = async () => { | |
if (!isAuthenticated) return; // 如果未认证,直接返回 | |
try { | |
const data = await promptGroupAPI.getAll(); | |
setPromptGroups(data); | |
} catch (err: any) { | |
setError(err.message || '获取提示词组失败'); | |
throw err; | |
} | |
}; | |
// 获取所有分类 | |
const fetchCategories = async () => { | |
if (!isAuthenticated) return; // 如果未认证,直接返回 | |
try { | |
const data = await categoryAPI.getAll(); | |
setCategories(data); | |
} catch (err: any) { | |
setError(err.message || '获取分类失败'); | |
throw err; | |
} | |
}; | |
// 添加提示词组 | |
const addPromptGroup = async (promptGroupData: Omit<PromptGroup, '_id' | 'createdAt' | 'updatedAt' | 'prompts' | 'workflows' | 'dslFiles'>) => { | |
try { | |
// 确保 category 始终是字符串类型 | |
const categoryId = typeof promptGroupData.category === 'object' | |
? promptGroupData.category._id | |
: promptGroupData.category; | |
const newPromptGroup = await promptGroupAPI.create({ | |
name: promptGroupData.name, | |
description: promptGroupData.description, | |
category: categoryId | |
}); | |
setPromptGroups(prev => [...prev, newPromptGroup]); | |
return newPromptGroup; | |
} catch (err: any) { | |
setError(err.message || '添加提示词组失败'); | |
throw err; | |
} | |
}; | |
// 更新提示词组 | |
const updatePromptGroup = async (id: string, promptGroupData: Omit<PromptGroup, '_id' | 'createdAt' | 'updatedAt' | 'prompts' | 'workflows' | 'dslFiles'>) => { | |
try { | |
// 确保 category 始终是字符串类型 | |
const categoryId = typeof promptGroupData.category === 'object' | |
? promptGroupData.category._id | |
: promptGroupData.category; | |
await promptGroupAPI.update(id, { | |
name: promptGroupData.name, | |
description: promptGroupData.description, | |
category: categoryId | |
}); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '更新提示词组失败'); | |
throw err; | |
} | |
}; | |
// 删除提示词组 | |
const deletePromptGroup = async (id: string) => { | |
try { | |
await promptGroupAPI.delete(id); | |
setPromptGroups(prev => prev.filter(group => group._id !== id)); | |
} catch (err: any) { | |
setError(err.message || '删除提示词组失败'); | |
throw err; | |
} | |
}; | |
// 添加提示词 | |
const addPrompt = async (groupId: string, promptData: { title: string; content: string; tags: string[] }) => { | |
try { | |
await promptGroupAPI.addPrompt(groupId, promptData); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '添加提示词失败'); | |
throw err; | |
} | |
}; | |
// 更新提示词 | |
const updatePrompt = async (groupId: string, promptId: string, promptData: { title: string; content: string; tags: string[] }) => { | |
try { | |
await promptGroupAPI.updatePrompt(groupId, promptId, promptData); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '更新提示词失败'); | |
throw err; | |
} | |
}; | |
// 删除提示词 | |
const deletePrompt = async (groupId: string, promptId: string) => { | |
try { | |
await promptGroupAPI.deletePrompt(groupId, promptId); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '删除提示词失败'); | |
throw err; | |
} | |
}; | |
// 添加DSL文件 - 修改为支持文本内容 | |
const addDslFile = async (groupId: string, dslFileData: { name: string; content?: string; fileData?: string; mimeType?: string }) => { | |
try { | |
await promptGroupAPI.addDslFile(groupId, dslFileData); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '添加YAML文件失败'); | |
throw err; | |
} | |
}; | |
// 更新DSL文件 | |
const updateDslFile = async (groupId: string, fileId: string, dslFileData: { name?: string; content?: string }) => { | |
try { | |
await promptGroupAPI.updateDslFile(groupId, fileId, dslFileData); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '更新YAML文件失败'); | |
throw err; | |
} | |
}; | |
// 删除DSL文件 | |
const deleteDslFile = async (groupId: string, fileId: string) => { | |
try { | |
await promptGroupAPI.deleteDslFile(groupId, fileId); | |
await fetchPromptGroups(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '删除YAML文件失败'); | |
throw err; | |
} | |
}; | |
// 添加分类 | |
const addCategory = async (categoryData: { name: string; color: string }) => { | |
try { | |
const newCategory = await categoryAPI.create(categoryData); | |
setCategories(prev => [...prev, newCategory]); | |
} catch (err: any) { | |
setError(err.message || '添加分类失败'); | |
throw err; | |
} | |
}; | |
// 更新分类 | |
const updateCategory = async (id: string, categoryData: { name: string; color: string }) => { | |
try { | |
await categoryAPI.update(id, categoryData); | |
await fetchCategories(); // 重新获取最新数据 | |
} catch (err: any) { | |
setError(err.message || '更新分类失败'); | |
throw err; | |
} | |
}; | |
// 删除分类 | |
const deleteCategory = async (id: string) => { | |
try { | |
await categoryAPI.delete(id); | |
setCategories(prev => prev.filter(category => category._id !== id)); | |
} catch (err: any) { | |
setError(err.message || '删除分类失败'); | |
throw err; | |
} | |
}; | |
const value = { | |
promptGroups, | |
categories, | |
loading, | |
error, | |
fetchPromptGroups, | |
fetchCategories, | |
addPromptGroup, | |
updatePromptGroup, | |
deletePromptGroup, | |
addPrompt, | |
updatePrompt, | |
deletePrompt, | |
addDslFile, | |
updateDslFile, | |
deleteDslFile, | |
addCategory, | |
updateCategory, | |
deleteCategory | |
}; | |
return <AppContext.Provider value={value}>{children}</AppContext.Provider>; | |
}; | |
export const useApp = () => { | |
const context = useContext(AppContext); | |
if (context === undefined) { | |
throw new Error('useApp must be used within an AppProvider'); | |
} | |
return context; | |
}; |