mirror of
https://github.com/PlayEdu/backend
synced 2025-06-21 01:54:13 +08:00
创建课程课件编辑
This commit is contained in:
parent
d392878bf5
commit
c0994dc29b
@ -1,22 +1,20 @@
|
||||
import client from "./internal/httpClient";
|
||||
|
||||
export function updateCourseAttachment(
|
||||
export function storeCourseAttachmentMulti(
|
||||
courseId: number,
|
||||
id: number,
|
||||
chapterId: number,
|
||||
name: string,
|
||||
type: string,
|
||||
rid: number
|
||||
attachments: number[]
|
||||
) {
|
||||
return client.put(`/backend/v1/course/${courseId}/attachment/create-batch`, {
|
||||
chapter_id: chapterId,
|
||||
name,
|
||||
type,
|
||||
sort: 0,
|
||||
rid,
|
||||
return client.post(`/backend/v1/course/${courseId}/attachment/create-batch`, {
|
||||
attachments: attachments,
|
||||
});
|
||||
}
|
||||
|
||||
export function destroyAttachment(courseId: number, id: number) {
|
||||
return client.destroy(`/backend/v1/course/${courseId}/attachment/${id}`);
|
||||
}
|
||||
|
||||
export function transCourseAttachment(courseId: number, ids: number[]) {
|
||||
return client.put(`/backend/v1/course/${courseId}/attachment/update/sort`, {
|
||||
ids: ids,
|
||||
});
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ const GoLogin = () => {
|
||||
};
|
||||
|
||||
const GoError = () => {
|
||||
window.location.href = "/error";
|
||||
// window.location.href = "/error";
|
||||
};
|
||||
|
||||
export class HttpClient {
|
||||
|
43
src/pages/course/compenents/attachment-update.module.scss
Normal file
43
src/pages/course/compenents/attachment-update.module.scss
Normal file
@ -0,0 +1,43 @@
|
||||
.hous-box {
|
||||
width: 500.53px;
|
||||
min-height: 56px;
|
||||
background: #ffffff;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
/* Firefox */
|
||||
-webkit-box-sizing: border-box;
|
||||
/* Safari */
|
||||
padding: 8px 8px 0px 8px;
|
||||
margin-left: 42px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.no-hours {
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
line-height: 24px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
.top-content {
|
||||
width: 502px;
|
||||
height: auto;
|
||||
background: rgba(255, 77, 79, 0.1);
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 16px;
|
||||
margin: 0 auto;
|
||||
p {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #ff4d4f;
|
||||
line-height: 24px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
219
src/pages/course/compenents/attachment-update.tsx
Normal file
219
src/pages/course/compenents/attachment-update.tsx
Normal file
@ -0,0 +1,219 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Button, Drawer, Form, Modal, message } from "antd";
|
||||
import styles from "./hour-update.module.less";
|
||||
import { course, courseAttachment } from "../../../api/index";
|
||||
import { SelectAttachment } from "../../../compenents";
|
||||
import { ExclamationCircleFilled } from "@ant-design/icons";
|
||||
import { TreeAttachments } from "./attachments";
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
interface PropInterface {
|
||||
id: number;
|
||||
open: boolean;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export const CourseAttachmentUpdate: React.FC<PropInterface> = ({
|
||||
id,
|
||||
open,
|
||||
onCancel,
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const [attachmentVisible, setAttachmentVisible] = useState<boolean>(false);
|
||||
const [attachmentData, setAttachmentData] = useState<any>([]);
|
||||
const [attachments, setAttachments] = useState<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (id === 0) {
|
||||
return;
|
||||
}
|
||||
getDetail();
|
||||
}, [id, open]);
|
||||
|
||||
const getDetail = () => {
|
||||
course.course(id).then((res: any) => {
|
||||
let treeData = res.data.attachments;
|
||||
if (treeData.length > 0) {
|
||||
const arr: any = resetAttachments(treeData).arr;
|
||||
const keys: any = resetAttachments(treeData).keys;
|
||||
setAttachmentData(arr);
|
||||
setAttachments(keys);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const resetAttachments = (data: any) => {
|
||||
const arr: any = [];
|
||||
const keys: any = [];
|
||||
if (data) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
arr.push({
|
||||
type: data[i].type,
|
||||
name: data[i].title,
|
||||
rid: data[i].rid,
|
||||
id: data[i].id,
|
||||
});
|
||||
keys.push(data[i].rid);
|
||||
}
|
||||
}
|
||||
return { arr, keys };
|
||||
};
|
||||
|
||||
const onFinish = (values: any) => {};
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log("Failed:", errorInfo);
|
||||
};
|
||||
|
||||
const selectAttachmentData = (arr: any, videos: any) => {
|
||||
const hours: any = [];
|
||||
for (let i = 0; i < videos.length; i++) {
|
||||
if (videos[i].disabled === false) {
|
||||
hours.push({
|
||||
sort: attachmentData.length + i,
|
||||
title: videos[i].name,
|
||||
type: videos[i].type,
|
||||
rid: videos[i].rid,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (hours.length === 0) {
|
||||
message.error("请选择视频");
|
||||
return;
|
||||
}
|
||||
courseAttachment
|
||||
.storeCourseAttachmentMulti(id, hours)
|
||||
.then((res: any) => {
|
||||
console.log("ok");
|
||||
setAttachmentVisible(false);
|
||||
getDetail();
|
||||
})
|
||||
.catch((err) => {
|
||||
message.error(err.message);
|
||||
});
|
||||
};
|
||||
|
||||
const delAttachments = (hid: number) => {
|
||||
const data = [...attachmentData];
|
||||
confirm({
|
||||
title: "操作确认",
|
||||
icon: <ExclamationCircleFilled />,
|
||||
content: "确认删除此课件?",
|
||||
centered: true,
|
||||
okText: "确认",
|
||||
cancelText: "取消",
|
||||
onOk() {
|
||||
const index = data.findIndex((i: any) => i.rid === hid);
|
||||
let delId = data[index].id;
|
||||
if (index >= 0) {
|
||||
data.splice(index, 1);
|
||||
}
|
||||
if (data.length > 0) {
|
||||
setAttachmentData(data);
|
||||
const keys = data.map((item: any) => item.rid);
|
||||
setAttachments(keys);
|
||||
} else {
|
||||
setAttachmentData([]);
|
||||
setAttachments([]);
|
||||
}
|
||||
if (delId) {
|
||||
courseAttachment.destroyAttachment(id, delId).then((res: any) => {
|
||||
console.log("ok");
|
||||
});
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
console.log("Cancel");
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const transAttachments = (arr: any) => {
|
||||
setAttachments(arr);
|
||||
const data = [...attachmentData];
|
||||
const newArr: any = [];
|
||||
const hourIds: any = [];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
data.map((item: any) => {
|
||||
if (item.rid === arr[i]) {
|
||||
newArr.push(item);
|
||||
hourIds.push(item.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
setAttachmentData(newArr);
|
||||
courseAttachment.transCourseAttachment(id, hourIds).then((res: any) => {
|
||||
console.log("ok");
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Drawer
|
||||
title="课件管理"
|
||||
onClose={onCancel}
|
||||
maskClosable={false}
|
||||
open={open}
|
||||
width={634}
|
||||
>
|
||||
<div className={styles["top-content"]}>
|
||||
<p>1.线上课课件调整及时生效,操作不可逆,请谨慎操作。</p>
|
||||
</div>
|
||||
<div className="float-left mt-24">
|
||||
<SelectAttachment
|
||||
defaultKeys={attachments}
|
||||
open={attachmentVisible}
|
||||
onCancel={() => {
|
||||
setAttachmentVisible(false);
|
||||
}}
|
||||
onSelected={(arr: any, videos: any) => {
|
||||
selectAttachmentData(arr, videos);
|
||||
}}
|
||||
></SelectAttachment>
|
||||
<Form
|
||||
form={form}
|
||||
name="attachment-update-basic"
|
||||
labelCol={{ span: 5 }}
|
||||
wrapperCol={{ span: 19 }}
|
||||
initialValues={{ remember: true }}
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
autoComplete="off"
|
||||
>
|
||||
<div className="c-flex">
|
||||
<Form.Item>
|
||||
<div className="ml-42">
|
||||
<Button
|
||||
onClick={() => setAttachmentVisible(true)}
|
||||
type="primary"
|
||||
>
|
||||
添加课件
|
||||
</Button>
|
||||
</div>
|
||||
</Form.Item>
|
||||
<div className={styles["hous-box"]}>
|
||||
{attachmentData.length === 0 && (
|
||||
<span className={styles["no-hours"]}>
|
||||
请点击上方按钮添加课件
|
||||
</span>
|
||||
)}
|
||||
{attachmentData.length > 0 && (
|
||||
<TreeAttachments
|
||||
data={attachmentData}
|
||||
onRemoveItem={(id: number) => {
|
||||
delAttachments(id);
|
||||
}}
|
||||
onUpdate={(arr: any[]) => {
|
||||
transAttachments(arr);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
@ -32,12 +32,6 @@ interface PropInterface {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
interface Option {
|
||||
value: string | number;
|
||||
title: string;
|
||||
children?: Option[];
|
||||
}
|
||||
|
||||
export const CourseCreate: React.FC<PropInterface> = ({
|
||||
cateIds,
|
||||
depIds,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Space, Button, Drawer, Form, Input, Modal, message } from "antd";
|
||||
import { Button, Drawer, Form, Input, Modal, message } from "antd";
|
||||
import styles from "./hour-update.module.less";
|
||||
import { course, courseHour, courseChapter } from "../../../api/index";
|
||||
import { SelectResource } from "../../../compenents";
|
||||
@ -14,12 +14,6 @@ interface PropInterface {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
interface Option {
|
||||
value: string | number;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
|
||||
export const CourseHourUpdate: React.FC<PropInterface> = ({
|
||||
id,
|
||||
open,
|
||||
|
@ -16,20 +16,12 @@ import { useSelector } from "react-redux";
|
||||
import { course, department } from "../../../api/index";
|
||||
import { UploadImageButton } from "../../../compenents";
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
interface PropInterface {
|
||||
id: number;
|
||||
open: boolean;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
interface Option {
|
||||
value: string | number;
|
||||
title: string;
|
||||
children?: Option[];
|
||||
}
|
||||
|
||||
export const CourseUpdate: React.FC<PropInterface> = ({
|
||||
id,
|
||||
open,
|
||||
|
@ -27,6 +27,7 @@ import type { TabsProps } from "antd";
|
||||
import { CourseCreate } from "./compenents/create";
|
||||
import { CourseUpdate } from "./compenents/update";
|
||||
import { CourseHourUpdate } from "./compenents/hour-update";
|
||||
import { CourseAttachmentUpdate } from "./compenents/attachment-update";
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
@ -66,6 +67,8 @@ const CoursePage = () => {
|
||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||
const [updateHourVisible, setHourUpdateVisible] = useState<boolean>(false);
|
||||
const [updateAttachmentVisible, setUpdateAttachmentVisible] =
|
||||
useState<boolean>(false);
|
||||
const [cid, setCid] = useState<number>(0);
|
||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||
const [did, setDid] = useState(Number(result.get("did")));
|
||||
@ -241,6 +244,23 @@ const CoursePage = () => {
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
label: (
|
||||
<Button
|
||||
style={{ verticalAlign: "middle" }}
|
||||
type="link"
|
||||
size="small"
|
||||
className="b-n-link c-red"
|
||||
onClick={() => {
|
||||
setCid(Number(record.id));
|
||||
setUpdateAttachmentVisible(true);
|
||||
}}
|
||||
>
|
||||
课件
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "4",
|
||||
label: (
|
||||
<Button
|
||||
type="link"
|
||||
@ -455,6 +475,14 @@ const CoursePage = () => {
|
||||
setRefresh(!refresh);
|
||||
}}
|
||||
/>
|
||||
<CourseAttachmentUpdate
|
||||
id={cid}
|
||||
open={updateAttachmentVisible}
|
||||
onCancel={() => {
|
||||
setUpdateAttachmentVisible(false);
|
||||
setRefresh(!refresh);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user