import { useEffect, useMemo, useState } from "react"; import { useNavigate } from "react-router-dom"; import { Button, Form, Grid, Input, InputNumber, InputTag, Message, Modal, Select, Space, Switch, Table, Tag } from "@arco-design/web-react"; import { IconDelete, IconPlus, IconSearch, IconRefresh } from "@arco-design/web-react/icon"; import { channelApi, dramaApi } from "../../api"; import type { DramaQuery } from "../../api/interface"; import { usePageData } from "../../hooks/usePageData"; import { Panel } from "../../components/Panel"; import { toDramaPayload } from "../formPayload"; import type { Channel, Drama, StatusOption } from "../interface"; const { Row, Col } = Grid; const STATUS_OPTIONS: StatusOption[] = [ { value: "draft", label: "草稿" }, { value: "scheduled", label: "定时发布" }, { value: "published", label: "已发布" }, { value: "offline", label: "已下线" }, ]; const PUBLISH_STATUS_LABEL: Record = { draft: "草稿", scheduled: "定时发布", published: "已发布", offline: "已下线", }; const INITIAL_QUERY: DramaQuery = { page: 1, pageSize: 20 }; export function DramaList() { const navigate = useNavigate(); const { data, loading, reload, changePage, setFilter } = usePageData(dramaApi.listDramas, INITIAL_QUERY); const [visible, setVisible] = useState(false); const [creating, setCreating] = useState(false); const [filterTitle, setFilterTitle] = useState(""); const [filterStatus, setFilterStatus] = useState(undefined); const [filterType, setFilterType] = useState(""); const [channels, setChannels] = useState([]); const defaultChannel = useMemo(() => channels.find((channel) => channel.isDefault) ?? channels[0], [channels]); useEffect(() => { channelApi.listChannels({ page: 1, pageSize: 100 }).then((page) => setChannels(page.list)).catch(() => setChannels([])); }, []); const handleSearch = () => { setFilter({ title: filterTitle || undefined, status: filterStatus, type: filterType || undefined }); }; const handleReset = () => { setFilterTitle(""); setFilterStatus(undefined); setFilterType(""); setFilter({ title: undefined, status: undefined, type: undefined }); }; const createDrama = async (values: Partial) => { setCreating(true); try { await dramaApi.createDrama(toDramaPayload(values)); Message.success("短剧创建成功"); setVisible(false); await reload(); } finally { setCreating(false); } }; const deleteDrama = (drama: Drama) => { Modal.confirm({ title: "删除短剧", content: `确认删除短剧「${drama.title}」?删除后该短剧下的剧集也会同步删除。`, okButtonProps: { status: "danger" }, onOk: async () => { await dramaApi.deleteDrama(drama.id); Message.success("短剧已删除"); await reload(); }, }); }; return (
} onClick={() => setVisible(true)}>新增短剧}>
短剧标题
状态
类型
操作
changePage(page, pageSize), }} columns={[ { title: "ID", dataIndex: "id", width: 80 }, { title: "封面图", dataIndex: "coverUrl", width: 120, render: (value) => (value ? 封面图 : null) }, { title: "标题", dataIndex: "title" }, { title: "地区", dataIndex: "region", width: 120 }, { title: "类型", dataIndex: "type", width: 140 }, { title: "已发布 / 总集数", dataIndex: "totalEpisodes", width: 180, render: (_, record) => `${record.publishedEpisodes || 0}(已发布)/共${record.totalEpisodes || 0}集` }, { title: "状态", dataIndex: "status", width: 120, render: (status) => {PUBLISH_STATUS_LABEL[String(status)] || String(status)}, }, { title: "推荐", dataIndex: "isRecommended", width: 100, render: (value) => (value ? : ), }, { title: "操作", width: 180, render: (_, record) => ( ), }, ]} /> setVisible(false)} footer={null} style={{ width: "40rem" }}>
); }