This commit is contained in:
ditiqi 2025-02-23 21:42:44 +08:00
parent e790321e6a
commit 510b75b206
1 changed files with 32 additions and 11 deletions

View File

@ -2,6 +2,7 @@ import {
DragOutlined, DragOutlined,
CaretRightOutlined, CaretRightOutlined,
SaveOutlined, SaveOutlined,
CaretDownOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { Form, Button, Input, Select, Space } from "antd"; import { Form, Button, Input, Select, Space } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
@ -9,14 +10,16 @@ import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities"; import { CSS } from "@dnd-kit/utilities";
import QuillEditor from "@web/src/components/common/editor/quill/QuillEditor"; import QuillEditor from "@web/src/components/common/editor/quill/QuillEditor";
import { TusUploader } from "@web/src/components/common/uploader/TusUploader"; import { TusUploader } from "@web/src/components/common/uploader/TusUploader";
import { LectureType, LessonTypeLabel, PostType } from "@nice/common"; import { Lecture, LectureType, LessonTypeLabel, PostType } from "@nice/common";
import { usePost } from "@nice/client"; import { usePost } from "@nice/client";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { LectureData } from "./interface";
import { env } from "@web/src/env"; import { env } from "@web/src/env";
import CollapsibleContent from "@web/src/components/common/container/CollapsibleContent";
import { VideoPlayer } from "@web/src/components/presentation/video-player/VideoPlayer";
interface SortableLectureProps { interface SortableLectureProps {
field: LectureData; field: Lecture;
remove: () => void; remove: () => void;
sectionFieldKey: string; sectionFieldKey: string;
} }
@ -37,6 +40,11 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
const [form] = Form.useForm(); const [form] = Form.useForm();
const [editing, setEditing] = useState(field?.id ? false : true); const [editing, setEditing] = useState(field?.id ? false : true);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isContentVisible, setIsContentVisible] = useState(false); // State to manage content visibility
const handleToggleContent = () => {
setIsContentVisible(!isContentVisible); // Toggle content visibility
};
const lectureType = const lectureType =
Form.useWatch(["meta", "type"], form) || LectureType.ARTICLE; Form.useWatch(["meta", "type"], form) || LectureType.ARTICLE;
const handleSave = async () => { const handleSave = async () => {
@ -44,12 +52,12 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
setLoading(true); setLoading(true);
const values = await form.validateFields(); const values = await form.validateFields();
let result; let result;
const videoUrlId = Array.isArray(values?.videoUrlIds) const videoUrlId = Array.isArray(values?.meta?.videoIds)
? values.videoUrlIds[0] ? values?.meta?.videoIds[0]
: typeof values?.videoUrlIds === "string" : typeof values?.meta?.videoIds === "string"
? values.videoUrlIds ? values?.meta?.videoIds
: undefined; : undefined;
console.log(sectionFieldKey);
if (!field.id) { if (!field.id) {
result = await create.mutateAsync({ result = await create.mutateAsync({
data: { data: {
@ -58,7 +66,7 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
title: values?.title, title: values?.title,
meta: { meta: {
type: values?.meta?.type, type: values?.meta?.type,
// fileIds: values?.meta?.fileIds, videoIds: videoUrlId ? [videoUrlId] : [],
videoUrl: videoUrlId videoUrl: videoUrlId
? `http://${env.SERVER_IP}:${env.FILE_PORT}/uploads/${videoUrlId}/stream/index.m3u8` ? `http://${env.SERVER_IP}:${env.FILE_PORT}/uploads/${videoUrlId}/stream/index.m3u8`
: undefined, : undefined,
@ -79,9 +87,11 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
id: field?.id, id: field?.id,
}, },
data: { data: {
parentId: sectionFieldKey,
title: values?.title, title: values?.title,
meta: { meta: {
type: values?.meta?.type, type: values?.meta?.type,
videoIds: videoUrlId ? [videoUrlId] : [],
videoUrl: videoUrlId videoUrl: videoUrlId
? `http://${env.SERVER_IP}:${env.FILE_PORT}/uploads/${videoUrlId}/stream/index.m3u8` ? `http://${env.SERVER_IP}:${env.FILE_PORT}/uploads/${videoUrlId}/stream/index.m3u8`
: undefined, : undefined,
@ -146,7 +156,7 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
<div className="mt-4 flex flex-1 "> <div className="mt-4 flex flex-1 ">
{lectureType === LectureType.VIDEO ? ( {lectureType === LectureType.VIDEO ? (
<Form.Item <Form.Item
name={"videoUrlIds"} name={["meta", "videoIds"]}
className="mb-0 flex-1" className="mb-0 flex-1"
rules={[{ required: true }]}> rules={[{ required: true }]}>
<TusUploader multiple={false} /> <TusUploader multiple={false} />
@ -188,7 +198,11 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
{...listeners} {...listeners}
className="cursor-move" className="cursor-move"
/> />
<CaretRightOutlined /> {isContentVisible ? (
<CaretDownOutlined onClick={handleToggleContent} />
) : (
<CaretRightOutlined onClick={handleToggleContent} />
)}
<span>{LessonTypeLabel[field?.meta?.type]}</span> <span>{LessonTypeLabel[field?.meta?.type]}</span>
<span>{field?.title || "未命名课时"}</span> <span>{field?.title || "未命名课时"}</span>
</Space> </Space>
@ -202,6 +216,13 @@ export const SortableLecture: React.FC<SortableLectureProps> = ({
</Space> </Space>
</div> </div>
)} )}
{isContentVisible &&
!editing && // Conditionally render content based on type
(field?.meta?.type === LectureType.ARTICLE ? (
<CollapsibleContent content={field?.content} />
) : (
<VideoPlayer src={field?.meta?.videoUrl} />
))}
</div> </div>
); );
}; };