mxivideo/src/stores/useCategoryStore.ts

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
}
}