"use client" import { getProjectList, getProjectTypeList, projectCollect, } from "@/components/label/api/project" import { Project } from "@/components/label/api/project/typing" import { initAllParams, initCollectParams, initDynamicParams, useAllUserStore, useProjectStore, } from "@/components/label/store/auth" import { projectLabelTypeOpts, projectStatusOpts, STATUS_CODE, } from "@/components/label/utils/constants" import { ActionIcon, Badge, Button, Collapse, Flex, Group, Loader, Pagination, Paper, Select, SimpleGrid, Stack, Text, TextInput, UnstyledButton, } from "@mantine/core" import { notifications } from "@mantine/notifications" import { IconCalendar, IconChevronDown, IconChevronUp, IconRefresh, IconSearch, IconStar, IconStarFilled, } from "@tabler/icons-react" import dayjs from "dayjs" import { User2 } from "lucide-react" import { useRouter, useSearchParams } from "next/navigation" import { useCallback, useEffect, useMemo, useState } from "react" import { CardCoverIcon } from "./components/ProjectIcon" type PageType = "all" | "collect" | "dynamic" function statusBadgeColor(status?: number | null) { if (!status) return "gray" if ([191, 199, 700].includes(status)) return "red" if ([580].includes(status)) return "yellow" if ([600].includes(status)) return "green" if ([201, 202, 203].includes(status)) return "cyan" return "blue" } function parseStatusValue(value?: string) { if (!value) return undefined if (value.includes(",")) { return value .split(",") .map((v) => Number(v)) .filter((n) => Number.isFinite(n)) } const n = Number(value) return Number.isFinite(n) ? [n] : undefined } export default function CollectionPage() { const router = useRouter() const urlParams = useSearchParams() const type = (urlParams.get("type") as PageType | null) ?? "collect" const { userOpts } = useAllUserStore() const { allParams, allTotal, collectParams, collectTotal, dynamicParams, dynamicTotal, resetParams, setSearchParams, setTotal, }: any = useProjectStore() const storeParams = useMemo(() => { return type === "collect" ? collectParams : type === "dynamic" ? dynamicParams : allParams }, [allParams, collectParams, dynamicParams, type]) const total = useMemo(() => { return type === "collect" ? collectTotal : type === "dynamic" ? dynamicTotal : allTotal }, [allTotal, collectTotal, dynamicTotal, type]) const [typeOpts, setTypeOpts] = useState< Array<{ label: string; value: string }> >([]) const [loading, setLoading] = useState(false) const [records, setRecords] = useState([]) const [searchExpanded, setSearchExpanded] = useState(false) const [filters, setFilters] = useState(() => { return { project_name: "", project_type: "", status: "", owner: "", label_type: "", admin_user: "", start_date: dayjs().subtract(6, "day").format("YYYY-MM-DD"), end_date: dayjs().format("YYYY-MM-DD"), } }) const [appliedFilters, setAppliedFilters] = useState(filters) const [queryTrigger, setQueryTrigger] = useState(0) useEffect(() => { const initFormOpts = async () => { const res = await getProjectTypeList() setTypeOpts((res ?? []).map((name) => ({ label: name, value: name }))) } initFormOpts() }, []) const queryParams = useMemo(() => { const base = type === "collect" ? { ...initCollectParams } : type === "dynamic" ? { ...initDynamicParams } : { ...initAllParams } const params: Project.ListRequest & any = { ...base, ...storeParams, page_number: storeParams.page_number ?? 1, page_size: storeParams.page_size ?? 15, project_name: appliedFilters.project_name || undefined, project_type: appliedFilters.project_type || undefined, owner: appliedFilters.owner || undefined, admin_user: appliedFilters.admin_user || undefined, start_date: appliedFilters.start_date || undefined, end_date: appliedFilters.end_date || undefined, label_type: appliedFilters.label_type ? Number(appliedFilters.label_type) : undefined, status: parseStatusValue(appliedFilters.status), } return params }, [appliedFilters, storeParams, type]) const load = useCallback(async () => { if (!queryTrigger) return setLoading(true) try { const res = await getProjectList(queryParams) setRecords(res?.project_list ?? []) setTotal(res?.total_items ?? 0, type) } catch (e) { setRecords([]) setTotal(0, type) notifications.show({ color: "red", title: "加载失败", message: e instanceof Error ? e.message : "请求失败", }) } finally { setLoading(false) } }, [queryParams, queryTrigger, setTotal, type]) useEffect(() => { load() }, [load]) useEffect(() => { queueMicrotask(() => { setQueryTrigger((v) => v + 1) }) }, []) const currentPage = storeParams.page_number ?? 1 const pageSize = storeParams.page_size ?? 15 const ProjectCard = (record: Project.DataProps) => { return ( { const url = type ? `/management/person/collection/detail?id=${record.id}&type=${type}` : `/management/person/collection/detail?id=${record.id}` router.push(url) }}> {record.name} {STATUS_CODE.get(record.status) ?? record.status} {record.owner ?? "-"} {record.create_at ? record.create_at.split(" ")[0] : "-"} { try { await projectCollect({ project_id: record.id, is_collect: !record.is_collect, }) notifications.show({ color: "green", title: "操作成功", message: record.is_collect ? "已取消收藏" : "已收藏", }) setQueryTrigger((v) => v + 1) } catch (e) { notifications.show({ color: "red", title: "操作失败", message: e instanceof Error ? e.message : "请求失败", }) } }}> {record.is_collect ? ( ) : ( )} 备注:{record.remarks ? record.remarks : "暂无备注"} ) } const PaginationBar = (props: { currentPage: number pageSize: number total: number onChangePage: (page: number) => void onChangePageSize: (size: number) => void }) => { const pageCount = Math.max( 1, Math.ceil((props.total ?? 0) / props.pageSize) ) return (
setFilters((s) => ({ ...s, project_type: v ?? "" })) } /> ({ label: o.label, value: String(o.value), }))} value={filters.label_type || null} onChange={(v) => setFilters((s) => ({ ...s, label_type: v ?? "" })) } />