import { useMemo, useState, useCallback } from "react" import { message } from "antd" import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query" import { getTitles, createTitle, updateTitle, deleteTitle } from "@/api/titles" import type { TitleData, CategoryItem, Frequency } from "../types/titleLibrary" import { toTitleData, copyToClipboard } from "../utils/titleLibrary" import { ALL_CATEGORY_ID, FREQUENCY_THRESHOLDS } from "../constants/titleLibrary" export const useTitleLibrary = () => { const queryClient = useQueryClient() /* 分类 */ const [activeCatId, setActiveCatId] = useState(ALL_CATEGORY_ID) /* 数据获取 */ const { data: apiTitles = [] } = useQuery({ queryKey: ["titles"], queryFn: getTitles, staleTime: 30_000, }) const titles: TitleData[] = useMemo(() => apiTitles.map(toTitleData), [apiTitles]) /* 动态派生分类 */ const categories: CategoryItem[] = useMemo(() => { const cats = new Map() apiTitles.forEach((t) => { const cat = t.category || "未分类" cats.set(cat, (cats.get(cat) || 0) + 1) }) return [ { id: ALL_CATEGORY_ID, name: "全部标题", count: apiTitles.length }, ...Array.from(cats.entries()).map(([name, count]) => ({ id: `cat-${name}`, name, count, })), ] }, [apiTitles]) /* CRUD mutations */ const createMutation = useMutation({ mutationFn: (content: string) => createTitle({ content }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["titles"] }) }, onError: () => message.error("创建标题失败"), }) const updateMutation = useMutation({ mutationFn: ({ id, content }: { id: string; content: string }) => updateTitle(id, { content }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["titles"] }) }, onError: () => message.error("更新标题失败"), }) const deleteMutation = useMutation({ mutationFn: (id: string) => deleteTitle(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["titles"] }) }, onError: () => message.error("删除标题失败"), }) /* 筛选状态 */ const [searchText, setSearchText] = useState("") const [filterType, setFilterType] = useState("all") const [filterIndustry, setFilterIndustry] = useState("all") const [filterFrequency, setFilterFrequency] = useState("all") /* 派生:筛选后的标题列表 */ const activeCategory = categories.find((c) => c.id === activeCatId) const filteredTitles = useMemo(() => { let list = titles /* 按分类过滤 */ if (activeCatId !== ALL_CATEGORY_ID) { const catName = activeCategory?.name || "" if (catName) { list = list.filter((t) => t.category === catName) } } /* 按类型筛选 */ if (filterType !== "all") { list = list.filter((t) => t.type === filterType) } /* 按行业筛选 */ if (filterIndustry !== "all") { list = list.filter((t) => t.industry === filterIndustry) } /* 按使用频率筛选 */ if (filterFrequency !== "all") { switch (filterFrequency) { case "high": list = list.filter((t) => t.usageCount >= FREQUENCY_THRESHOLDS.high) break case "medium": list = list.filter( (t) => t.usageCount >= FREQUENCY_THRESHOLDS.medium && t.usageCount < FREQUENCY_THRESHOLDS.high, ) break case "low": list = list.filter((t) => t.usageCount < FREQUENCY_THRESHOLDS.medium) break } } /* 搜索 */ if (searchText.trim()) { const q = searchText.trim().toLowerCase() list = list.filter((t) => t.content.toLowerCase().includes(q)) } return list }, [titles, activeCatId, activeCategory, filterType, filterIndustry, filterFrequency, searchText]) /* 操作:收藏 */ const handleToggleFavorite = useCallback((_id: string) => { message.info("收藏功能即将上线") }, []) /* 操作:复制 */ const handleCopy = useCallback(async (title: TitleData) => { const ok = await copyToClipboard(title.content) if (ok) { message.success("已复制到剪贴板") } else { message.error("复制失败") } }, []) /* 操作:删除 */ const handleDelete = useCallback( (id: string) => { deleteMutation.mutate(id) message.success("标题已删除") }, [deleteMutation], ) return { /* 状态 */ titles, categories, activeCatId, activeCategory, filteredTitles, searchText, filterType, filterIndustry, filterFrequency, /* mutations */ createMutation, updateMutation, deleteMutation, /* setters */ setActiveCatId, setSearchText, setFilterType, setFilterIndustry, setFilterFrequency, /* handlers */ handleToggleFavorite, handleCopy, handleDelete, } }