refactor: 重构项目接口与API调用体系,统一类型管理
1. 合并拆分的API类型定义到统一的api/interface.ts文件 2. 删除旧的api/client.ts与api/types.ts文件 3. 重构所有页面与组件的API调用方式,统一使用api/index.ts导出的接口 4. 调整组件文件结构,将分散的组件按模块整理 5. 统一类型导入路径,移除冗余的类型重复定义
This commit is contained in:
142
src/Drama/components/DramaDetail.tsx
Normal file
142
src/Drama/components/DramaDetail.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Card, Descriptions, InputNumber, Message, Space } from "@arco-design/web-react";
|
||||
import { IconArrowLeft, IconRefresh } from "@arco-design/web-react/icon";
|
||||
import { dramaApi, mediaApi } from "../../api";
|
||||
import type { Drama, DramaDetailPageProps, Episode } from "../interface";
|
||||
import { EpisodeTable } from "./EpisodeTable";
|
||||
|
||||
const PUBLISH_STATUS_LABEL: Record<string, string> = {
|
||||
draft: "草稿",
|
||||
scheduled: "定时发布",
|
||||
published: "已发布",
|
||||
offline: "已下线",
|
||||
};
|
||||
|
||||
export function DramaDetail({ dramaId }: DramaDetailPageProps) {
|
||||
const navigate = useNavigate();
|
||||
const [drama, setDrama] = useState<Drama | null>(null);
|
||||
const [episodes, setEpisodes] = useState<Episode[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [episodeCount, setEpisodeCount] = useState(1);
|
||||
const [uploadingEpisodeId, setUploadingEpisodeId] = useState<number | null>(null);
|
||||
|
||||
const loadDetail = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const [dramaData, episodeList] = await Promise.all([dramaApi.getDrama(dramaId), dramaApi.getDramaEpisodes(dramaId)]);
|
||||
setDrama(dramaData);
|
||||
setEpisodeCount(dramaData.totalEpisodes || 1);
|
||||
setEpisodes(episodeList);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
void loadDetail();
|
||||
}, [dramaId]);
|
||||
|
||||
const configureEpisodes = async () => {
|
||||
await dramaApi.configureDramaEpisodes(dramaId, episodeCount);
|
||||
Message.success("剧集数量已更新");
|
||||
await loadDetail();
|
||||
};
|
||||
|
||||
const updateDramaStatus = async (status: string) => {
|
||||
await dramaApi.updateDrama(dramaId, { status });
|
||||
Message.success("短剧状态已更新");
|
||||
await loadDetail();
|
||||
};
|
||||
|
||||
const uploadEpisodeVideo = async (episode: Episode, file: File) => {
|
||||
setUploadingEpisodeId(episode.id);
|
||||
try {
|
||||
const task = await mediaApi.createUploadTask({
|
||||
episodeId: episode.id,
|
||||
fileName: file.name,
|
||||
contentType: file.type || "video/mp4",
|
||||
fileSize: file.size,
|
||||
});
|
||||
await mediaApi.completeUploadTask(task.jobId);
|
||||
await mediaApi.syncReviewStatus();
|
||||
Message.success("视频上传并审核通过");
|
||||
await loadDetail();
|
||||
} finally {
|
||||
setUploadingEpisodeId(null);
|
||||
}
|
||||
};
|
||||
|
||||
const publishEpisode = async (episode: Episode) => {
|
||||
await dramaApi.updateEpisode(episode.id, {
|
||||
publishStatus: "published",
|
||||
status: "published",
|
||||
});
|
||||
Message.success("剧集已发布");
|
||||
await loadDetail();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="page-stack">
|
||||
<Card
|
||||
className="section-card"
|
||||
loading={loading && !drama}
|
||||
title={
|
||||
<Space>
|
||||
<Button icon={<IconArrowLeft />} onClick={() => navigate("/dramas")} />
|
||||
短剧详情
|
||||
</Space>
|
||||
}
|
||||
extra={
|
||||
<Space>
|
||||
<Button icon={<IconRefresh />} onClick={loadDetail}>
|
||||
刷新
|
||||
</Button>
|
||||
<Button onClick={() => updateDramaStatus("draft")}>设为草稿</Button>
|
||||
<Button type="primary" onClick={() => updateDramaStatus("published")}>
|
||||
上架短剧
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
{drama && (
|
||||
<Descriptions
|
||||
column={3}
|
||||
data={[
|
||||
{ label: "短剧ID", value: drama.id },
|
||||
{ label: "名称", value: drama.title },
|
||||
{ label: "地区", value: drama.region || "-" },
|
||||
{ label: "类型", value: drama.type },
|
||||
{ label: "总集数", value: drama.totalEpisodes || 0 },
|
||||
{ label: "已发布集数", value: drama.publishedEpisodes || 0 },
|
||||
{ label: "状态", value: PUBLISH_STATUS_LABEL[drama.status] || drama.status },
|
||||
{ label: "封面", value: drama.coverUrl },
|
||||
{ label: "简介", value: drama.description || "-" },
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
className="section-card"
|
||||
title="剧集配置"
|
||||
extra={
|
||||
<Space>
|
||||
<InputNumber min={1} max={500} value={episodeCount} onChange={(value) => setEpisodeCount(Number(value) || 1)} />
|
||||
<Button type="primary" onClick={configureEpisodes}>
|
||||
保存集数
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<EpisodeTable
|
||||
episodes={episodes}
|
||||
loading={loading}
|
||||
uploadingEpisodeId={uploadingEpisodeId}
|
||||
onUploadVideo={uploadEpisodeVideo}
|
||||
onPublishEpisode={publishEpisode}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user