"use client"; import { CopyOutlined, DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined, ReloadOutlined, SearchOutlined } from "@ant-design/icons"; import { ProTable, type ProColumns } from "@ant-design/pro-components"; import { App, Button, Card, Col, Flex, Form, Image, Input, Modal, Row, Select, Space, Tag, Tooltip, Typography } from "antd"; import { useEffect, useState } from "react"; import type { AdminAsset } from "@/services/api/admin"; import { useAdminAssets } from "../hooks/use-admin-assets"; type AssetFormValues = Partial & { tagText?: string }; const typeOptions = [ { label: "全部类型", value: "" }, { label: "文本", value: "text" }, { label: "图片", value: "image" }, ]; const editTypeOptions = typeOptions.slice(1); export default function AdminAssetsPage() { const { assets, tags, keyword, kind, tag, page, pageSize, total, isLoading, searchAssets, changeKind, changeTag, changePage, changePageSize, resetFilters, refreshAssets, saveAsset: saveAdminAsset, deleteAsset } = useAdminAssets(); const { message } = App.useApp(); const [form] = Form.useForm(); const [editingAsset, setEditingAsset] = useState | null>(null); const [detailAsset, setDetailAsset] = useState(null); const [deletingAsset, setDeletingAsset] = useState(null); const formType = Form.useWatch("type", form) || editingAsset?.type || "text"; const tagOptions = tags.map((item) => ({ label: item, value: item })); useEffect(() => { if (editingAsset) form.setFieldsValue({ ...editingAsset, tagText: editingAsset.tags?.join(", ") || "" }); }, [editingAsset, form]); const copyValue = async (value: string) => { await navigator.clipboard.writeText(value); message.success("已复制"); }; const saveAsset = async () => { const value = await form.validateFields(); const nextType = value.type || "text"; await saveAdminAsset({ ...editingAsset, ...value, type: nextType, coverUrl: value.coverUrl || (nextType === "image" ? value.url : ""), tags: (value.tagText || "").split(",").map((item) => item.trim()).filter(Boolean), }); setEditingAsset(null); }; const columns: ProColumns[] = [ { title: "封面", dataIndex: "coverUrl", width: 88, render: (_, item) => {item.title}, }, { title: "标题", dataIndex: "title", width: 260, render: (_, item) => setDetailAsset(item)}>{item.title}, }, { title: "类型", dataIndex: "type", width: 84, render: (_, item) => {item.type === "image" ? "图片" : "文本"}, }, { title: "标签", dataIndex: "tags", width: 180, render: (_, item) => {(item.tags || []).slice(0, 3).map((tag) => {tag})}, }, { title: "分类", dataIndex: "category", width: 120, render: (_, item) => {item.category || "未标注"}, }, { title: "操作", key: "actions", width: 112, align: "right", render: (_, item) => ( rowKey="id" columns={columns} dataSource={assets} loading={isLoading} search={false} defaultSize="middle" tableLayout="fixed" cardProps={{ variant: "borderless" }} headerTitle={素材列表{total} 条} options={{ density: true, setting: true, reload: () => void refreshAssets() }} toolBarRender={() => []} pagination={{ current: page, pageSize, total, showSizeChanger: true, pageSizeOptions: [10, 20, 50, 100], showTotal: (value) => `共 ${value} 条`, onChange: (nextPage, nextPageSize) => nextPageSize !== pageSize ? changePageSize(nextPageSize) : changePage(nextPage) }} /> setEditingAsset(null)} onOk={() => void saveAsset()} okText="保存" cancelText="取消" destroyOnHidden>
{formType === "image" ? : }
setDetailAsset(null)} footer={}> {detailAsset ? ( {detailAsset.title} {detailAsset.title} {detailAsset.type === "image" ? "图片" : "文本"}{detailAsset.category ? {detailAsset.category} : null}{(detailAsset.tags || []).map((tag) => {tag})} {detailAsset.description ? {detailAsset.description} : null} ) : null} setDeletingAsset(null)} onOk={async () => { if (!deletingAsset) return; await deleteAsset(deletingAsset.id); setDeletingAsset(null); }} okText="删除" okButtonProps={{ danger: true }} cancelText="取消"> 确定删除「{deletingAsset?.title}」吗?删除后会从服务器素材库中移除。 ); }