From 96eaa810f39dceaba8f36a19bcd08195dab124c5 Mon Sep 17 00:00:00 2001 From: zhxiao1124 Date: Thu, 2 Jul 2026 17:59:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E7=9F=AD=E5=89=A7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=96=E8=BE=91=E3=80=81=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 重构接口类型定义,新增创建/更新短剧和剧集的载荷类型 2. 新增表单数据转换工具,规范化表单提交参数 3. 优化短剧列表展示,新增封面图和更清晰的集数统计 4. 新增短剧和剧集的编辑弹窗功能 5. 修复测试文件导入路径和README标题 6. 优化角色管理页面的表单提示样式 --- README.md | 2 +- src/Drama/components/DramaDetail.tsx | 131 ++++++++++++- src/Drama/components/DramaList.tsx | 237 ++++++++++++------------ src/Drama/components/EpisodeTable.tsx | 253 +++++++++++++++++++------- src/Drama/formPayload.ts | 82 +++++++++ src/Drama/interface.ts | 1 + src/Role/index.tsx | 2 +- src/api/dramas.ts | 16 +- src/api/interface.ts | 9 + tests/pageData.test.ts | 2 +- 10 files changed, 542 insertions(+), 193 deletions(-) create mode 100644 src/Drama/formPayload.ts diff --git a/README.md b/README.md index 179eda7..c1ca840 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CTH TikTok 短剧管理后台 +# TikTok 短剧管理后台 基于 Vite + TypeScript + React + Arco Design 的后台管理系统,默认中文界面。 diff --git a/src/Drama/components/DramaDetail.tsx b/src/Drama/components/DramaDetail.tsx index 4f76680..160498e 100644 --- a/src/Drama/components/DramaDetail.tsx +++ b/src/Drama/components/DramaDetail.tsx @@ -1,11 +1,21 @@ import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; -import { Button, Card, Descriptions, InputNumber, Message, Space } from "@arco-design/web-react"; +import { Button, Card, Descriptions, Form, Grid, Input, InputNumber, InputTag, Message, Modal, Select, Space, Switch } from "@arco-design/web-react"; import { IconArrowLeft, IconRefresh } from "@arco-design/web-react/icon"; import { dramaApi, mediaApi } from "../../api"; +import { toDramaPayload, toEpisodePayload } from "../formPayload"; import type { Drama, DramaDetailPageProps, Episode } from "../interface"; import { EpisodeTable } from "./EpisodeTable"; +const { Row, Col } = Grid; + +const STATUS_OPTIONS = [ + { value: "draft", label: "草稿" }, + { value: "scheduled", label: "定时发布" }, + { value: "published", label: "已发布" }, + { value: "offline", label: "已下线" }, +]; + const PUBLISH_STATUS_LABEL: Record = { draft: "草稿", scheduled: "定时发布", @@ -20,6 +30,8 @@ export function DramaDetail({ dramaId }: DramaDetailPageProps) { const [loading, setLoading] = useState(false); const [episodeCount, setEpisodeCount] = useState(1); const [uploadingEpisodeId, setUploadingEpisodeId] = useState(null); + const [editVisible, setEditVisible] = useState(false); + const [updatingDrama, setUpdatingDrama] = useState(false); const loadDetail = async () => { setLoading(true); @@ -49,6 +61,18 @@ export function DramaDetail({ dramaId }: DramaDetailPageProps) { await loadDetail(); }; + const updateDrama = async (values: Partial) => { + setUpdatingDrama(true); + try { + await dramaApi.updateDrama(dramaId, toDramaPayload(values)); + Message.success("短剧信息已更新"); + setEditVisible(false); + await loadDetail(); + } finally { + setUpdatingDrama(false); + } + }; + const uploadEpisodeVideo = async (episode: Episode, file: File) => { setUploadingEpisodeId(episode.id); try { @@ -76,6 +100,12 @@ export function DramaDetail({ dramaId }: DramaDetailPageProps) { await loadDetail(); }; + const updateEpisode = async (episode: Episode, values: Partial) => { + await dramaApi.updateDramaEpisode(dramaId, episode.id, toEpisodePayload(values)); + Message.success("剧集信息已更新"); + await loadDetail(); + }; + return (
} onClick={loadDetail}> 刷新 + + +
+ + + )} ); } diff --git a/src/Drama/components/DramaList.tsx b/src/Drama/components/DramaList.tsx index 492dc17..46149ce 100644 --- a/src/Drama/components/DramaList.tsx +++ b/src/Drama/components/DramaList.tsx @@ -4,6 +4,7 @@ import { Button, Card, Form, Grid, Input, InputNumber, InputTag, Message, Modal, import { IconPlus } from "@arco-design/web-react/icon"; import { dramaApi } from "../../api"; import { usePageData } from "../../hooks/usePageData"; +import { toDramaPayload } from "../formPayload"; import type { Drama, StatusOption } from "../interface"; const { Row, Col } = Grid; @@ -31,7 +32,7 @@ export function DramaList() { const createDrama = async (values: Partial) => { setCreating(true); try { - await dramaApi.createDrama(values); + await dramaApi.createDrama(toDramaPayload(values)); Message.success("短剧创建成功"); setVisible(false); await reload(); @@ -41,124 +42,128 @@ export function DramaList() { }; return ( - +