This commit is contained in:
root
2025-07-13 00:19:39 +08:00
parent 30d4eb4c55
commit 4b876f3c0d

View File

@@ -1,14 +1,30 @@
import React, { useState, useEffect } from 'react'
import { Plus, Edit, Trash2, Search, Save, X, Cloud, Users, Palette, BarChart3, Download, Upload } from 'lucide-react'
import {
ResourceCategoryServiceV2,
ResourceCategoryV2,
CategoryBatchItem
import {
ResourceCategoryServiceV2,
ResourceCategoryV2,
CategoryBatchItem
} from '../services/resourceCategoryServiceV2'
import {
useCategoriesData,
useCategoryActions,
useCategoryStore
} from '../stores/useCategoryStore'
const ResourceCategoryPageV2: React.FC = () => {
const [categories, setCategories] = useState<ResourceCategoryV2[]>([])
const [loading, setLoading] = useState(true)
// 使用 Zustand store 管理分类数据
const { categories, loading, error } = useCategoriesData()
const {
loadCategories,
refreshCategories,
addCategory,
updateCategory,
removeCategory,
clearError,
searchCategories
} = useCategoryActions()
// 本地 UI 状态
const [searchTerm, setSearchTerm] = useState('')
const [editingCategory, setEditingCategory] = useState<ResourceCategoryV2 | null>(null)
const [showCreateForm, setShowCreateForm] = useState(false)
@@ -16,7 +32,6 @@ const ResourceCategoryPageV2: React.FC = () => {
const [includeCloud, setIncludeCloud] = useState(true)
const [showDisabled, setShowDisabled] = useState(true)
const [selectedColor, setSelectedColor] = useState<string>('')
const [categoryCount, setCategoryCount] = useState(0)
const [formData, setFormData] = useState({
title: '',
ai_prompt: '',
@@ -35,32 +50,42 @@ const ResourceCategoryPageV2: React.FC = () => {
]
useEffect(() => {
// 使用 store 的 loadCategories 方法
loadCategories()
loadCategoryCount()
}, [includeCloud])
}, [loadCategories])
const loadCategories = async () => {
try {
setLoading(true)
const result = await ResourceCategoryServiceV2.getAllCategories({
include_cloud: includeCloud,
limit: 200
})
setCategories(result)
} catch (error) {
console.error('Failed to load categories:', error)
} finally {
setLoading(false)
// 获取过滤后的分类列表
const getFilteredCategories = () => {
let filtered = categories
// 根据搜索词过滤
if (searchTerm.trim()) {
filtered = searchCategories(searchTerm.trim())
}
// 根据云端/本地过滤
if (!includeCloud) {
filtered = filtered.filter(cat => !cat.is_cloud)
}
// 根据启用/禁用状态过滤
if (!showDisabled) {
filtered = filtered.filter(cat => cat.is_active)
}
// 根据颜色过滤
if (selectedColor) {
filtered = filtered.filter(cat => cat.color === selectedColor)
}
return filtered
}
const loadCategoryCount = async () => {
try {
const count = await ResourceCategoryServiceV2.getCategoryCount(includeCloud)
setCategoryCount(count)
} catch (error) {
console.error('Failed to load category count:', error)
}
const filteredCategories = getFilteredCategories()
// 刷新分类数据
const handleRefresh = async () => {
await refreshCategories()
}
const handleCreateCategory = async () => {
@@ -73,10 +98,10 @@ const ResourceCategoryPageV2: React.FC = () => {
)
if (newCategory) {
setCategories([...categories, newCategory])
// 使用 store 的 addCategory 方法
addCategory(newCategory)
setShowCreateForm(false)
setFormData({ title: '', ai_prompt: '', color: '#FF6B6B', is_cloud: false })
await loadCategoryCount()
}
} catch (error) {
console.error('Failed to create category:', error)
@@ -98,10 +123,8 @@ const ResourceCategoryPageV2: React.FC = () => {
)
if (updatedCategory) {
const updatedCategories = categories.map(cat =>
cat.id === editingCategory.id ? updatedCategory : cat
)
setCategories(updatedCategories)
// 使用 store 的 updateCategory 方法
updateCategory(editingCategory.id, updatedCategory)
setEditingCategory(null)
setFormData({ title: '', ai_prompt: '', color: '#FF6B6B', is_cloud: false })
}
@@ -116,8 +139,8 @@ const ResourceCategoryPageV2: React.FC = () => {
try {
await ResourceCategoryServiceV2.deleteCategory(categoryId, true)
setCategories(categories.filter(cat => cat.id !== categoryId))
await loadCategoryCount()
// 使用 store 的 removeCategory 方法
removeCategory(categoryId)
} catch (error) {
console.error('Failed to delete category:', error)
alert('删除分类失败: ' + (error instanceof Error ? error.message : '未知错误'))
@@ -132,10 +155,8 @@ const ResourceCategoryPageV2: React.FC = () => {
await ResourceCategoryServiceV2.deactivateCategory(categoryId)
}
const updatedCategories = categories.map(cat =>
cat.id === categoryId ? { ...cat, is_active: isActive } : cat
)
setCategories(updatedCategories)
// 使用 store 的 updateCategory 方法
updateCategory(categoryId, { is_active: isActive })
} catch (error) {
console.error('Failed to toggle category:', error)
alert('切换分类状态失败: ' + (error instanceof Error ? error.message : '未知错误'))
@@ -150,47 +171,28 @@ const ResourceCategoryPageV2: React.FC = () => {
alert(`批量导入完成: 成功 ${result.success} 个,失败 ${result.failed}`)
setShowBatchImport(false)
setBatchData('')
await loadCategories()
await loadCategoryCount()
// 刷新分类数据
await refreshCategories()
} catch (error) {
console.error('Failed to batch import:', error)
alert('批量导入失败: ' + (error instanceof Error ? error.message : '数据格式错误'))
}
}
const handleSearchByColor = async (color: string) => {
const handleSearchByColor = (color: string) => {
if (color === selectedColor) {
// 取消颜色筛选
setSelectedColor('')
await loadCategories()
} else {
// 按颜色筛选
setSelectedColor(color)
try {
const result = await ResourceCategoryServiceV2.getCategoriesByColor(color, {
include_cloud: includeCloud
})
setCategories(result)
} catch (error) {
console.error('Failed to search by color:', error)
}
}
// 过滤逻辑已经在 getFilteredCategories 中处理
}
const handleSearch = async () => {
if (!searchTerm.trim()) {
await loadCategories()
return
}
try {
const result = await ResourceCategoryServiceV2.searchCategories(searchTerm, {
include_cloud: includeCloud
})
setCategories(result)
} catch (error) {
console.error('Failed to search categories:', error)
}
const handleSearch = () => {
// 搜索逻辑已经在 getFilteredCategories 中处理
// 这里只需要触发重新渲染React 会自动调用 getFilteredCategories
}
const startEdit = (category: ResourceCategoryV2) => {
@@ -229,17 +231,7 @@ const ResourceCategoryPageV2: React.FC = () => {
URL.revokeObjectURL(url)
}
const filteredCategories = categories.filter(category => {
// 搜索过滤
const matchesSearch = !searchTerm ||
category.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
category.ai_prompt.toLowerCase().includes(searchTerm.toLowerCase())
// 状态过滤
const matchesStatus = showDisabled || category.is_active
return matchesSearch && matchesStatus
})
// 统计信息
const stats = {