169 lines
4.2 KiB
TypeScript
169 lines
4.2 KiB
TypeScript
import { create } from 'zustand'
|
|
import { ResourceCategoryServiceV2, ResourceCategoryV2 } from '../services/resourceCategoryServiceV2'
|
|
|
|
interface CategoryState {
|
|
// 状态
|
|
categories: ResourceCategoryV2[]
|
|
loading: boolean
|
|
error: string | null
|
|
lastLoadTime: number
|
|
|
|
// 缓存控制
|
|
cacheTimeout: number // 缓存超时时间(毫秒)
|
|
|
|
// 操作方法
|
|
loadCategories: (force?: boolean) => Promise<void>
|
|
refreshCategories: () => Promise<void>
|
|
addCategory: (category: ResourceCategoryV2) => void
|
|
updateCategory: (categoryId: string, updates: Partial<ResourceCategoryV2>) => void
|
|
removeCategory: (categoryId: string) => void
|
|
clearError: () => void
|
|
|
|
// 查询方法
|
|
getCategoryById: (id: string) => ResourceCategoryV2 | undefined
|
|
getActiveCategoriesOnly: () => ResourceCategoryV2[]
|
|
getCategoriesByColor: (color: string) => ResourceCategoryV2[]
|
|
searchCategories: (query: string) => ResourceCategoryV2[]
|
|
}
|
|
|
|
export const useCategoryStore = create<CategoryState>((set, get) => ({
|
|
// 初始状态
|
|
categories: [],
|
|
loading: false,
|
|
error: null,
|
|
lastLoadTime: 0,
|
|
cacheTimeout: 5 * 60 * 1000, // 5分钟缓存
|
|
|
|
// 加载分类数据
|
|
loadCategories: async (force = false) => {
|
|
const state = get()
|
|
const now = Date.now()
|
|
|
|
// 检查是否需要重新加载
|
|
if (!force &&
|
|
state.categories.length > 0 &&
|
|
(now - state.lastLoadTime) < state.cacheTimeout &&
|
|
!state.loading) {
|
|
return // 使用缓存数据
|
|
}
|
|
|
|
// 防止重复加载
|
|
if (state.loading) {
|
|
return
|
|
}
|
|
|
|
set({ loading: true, error: null })
|
|
|
|
try {
|
|
const result = await ResourceCategoryServiceV2.getAllCategories({
|
|
include_cloud: true
|
|
})
|
|
|
|
set({
|
|
categories: result,
|
|
loading: false,
|
|
error: null,
|
|
lastLoadTime: now
|
|
})
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : '加载分类失败'
|
|
console.error('Failed to load categories:', error)
|
|
|
|
set({
|
|
loading: false,
|
|
error: errorMessage
|
|
})
|
|
}
|
|
},
|
|
|
|
// 强制刷新分类数据
|
|
refreshCategories: async () => {
|
|
await get().loadCategories(true)
|
|
},
|
|
|
|
// 添加新分类
|
|
addCategory: (category: ResourceCategoryV2) => {
|
|
set(state => ({
|
|
categories: [...state.categories, category]
|
|
}))
|
|
},
|
|
|
|
// 更新分类
|
|
updateCategory: (categoryId: string, updates: Partial<ResourceCategoryV2>) => {
|
|
set(state => ({
|
|
categories: state.categories.map(category =>
|
|
category.id === categoryId
|
|
? { ...category, ...updates }
|
|
: category
|
|
)
|
|
}))
|
|
},
|
|
|
|
// 删除分类
|
|
removeCategory: (categoryId: string) => {
|
|
set(state => ({
|
|
categories: state.categories.filter(category => category.id !== categoryId)
|
|
}))
|
|
},
|
|
|
|
// 清除错误
|
|
clearError: () => {
|
|
set({ error: null })
|
|
},
|
|
|
|
// 根据ID获取分类
|
|
getCategoryById: (id: string) => {
|
|
return get().categories.find(category => category.id === id)
|
|
},
|
|
|
|
// 获取激活的分类
|
|
getActiveCategoriesOnly: () => {
|
|
return get().categories.filter(category => category.is_active)
|
|
},
|
|
|
|
// 根据颜色获取分类
|
|
getCategoriesByColor: (color: string) => {
|
|
return get().categories.filter(category => category.color === color)
|
|
},
|
|
|
|
// 搜索分类
|
|
searchCategories: (query: string) => {
|
|
const lowerQuery = query.toLowerCase()
|
|
return get().categories.filter(category =>
|
|
category.title.toLowerCase().includes(lowerQuery) ||
|
|
category.ai_prompt.toLowerCase().includes(lowerQuery)
|
|
)
|
|
}
|
|
}))
|
|
|
|
// 导出便捷的 hooks
|
|
export const useCategoriesData = () => {
|
|
const { categories, loading, error } = useCategoryStore()
|
|
return { categories, loading, error }
|
|
}
|
|
|
|
export const useActiveCategoriesOnly = () => {
|
|
const getActiveCategoriesOnly = useCategoryStore(state => state.getActiveCategoriesOnly)
|
|
return getActiveCategoriesOnly()
|
|
}
|
|
|
|
export const useCategoryActions = () => {
|
|
const {
|
|
loadCategories,
|
|
refreshCategories,
|
|
addCategory,
|
|
updateCategory,
|
|
removeCategory,
|
|
clearError
|
|
} = useCategoryStore()
|
|
|
|
return {
|
|
loadCategories,
|
|
refreshCategories,
|
|
addCategory,
|
|
updateCategory,
|
|
removeCategory,
|
|
clearError
|
|
}
|
|
}
|