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