mirror of
https://github.com/PlayEdu/backend
synced 2025-09-10 22:03:38 +08:00
创建课程课件编辑
This commit is contained in:
parent
d392878bf5
commit
c0994dc29b
@ -1,22 +1,20 @@
|
|||||||
import client from "./internal/httpClient";
|
import client from "./internal/httpClient";
|
||||||
|
|
||||||
export function updateCourseAttachment(
|
export function storeCourseAttachmentMulti(
|
||||||
courseId: number,
|
courseId: number,
|
||||||
id: number,
|
attachments: number[]
|
||||||
chapterId: number,
|
|
||||||
name: string,
|
|
||||||
type: string,
|
|
||||||
rid: number
|
|
||||||
) {
|
) {
|
||||||
return client.put(`/backend/v1/course/${courseId}/attachment/create-batch`, {
|
return client.post(`/backend/v1/course/${courseId}/attachment/create-batch`, {
|
||||||
chapter_id: chapterId,
|
attachments: attachments,
|
||||||
name,
|
|
||||||
type,
|
|
||||||
sort: 0,
|
|
||||||
rid,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function destroyAttachment(courseId: number, id: number) {
|
export function destroyAttachment(courseId: number, id: number) {
|
||||||
return client.destroy(`/backend/v1/course/${courseId}/attachment/${id}`);
|
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 = () => {
|
const GoError = () => {
|
||||||
window.location.href = "/error";
|
// window.location.href = "/error";
|
||||||
};
|
};
|
||||||
|
|
||||||
export class HttpClient {
|
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;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Option {
|
|
||||||
value: string | number;
|
|
||||||
title: string;
|
|
||||||
children?: Option[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CourseCreate: React.FC<PropInterface> = ({
|
export const CourseCreate: React.FC<PropInterface> = ({
|
||||||
cateIds,
|
cateIds,
|
||||||
depIds,
|
depIds,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
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 styles from "./hour-update.module.less";
|
||||||
import { course, courseHour, courseChapter } from "../../../api/index";
|
import { course, courseHour, courseChapter } from "../../../api/index";
|
||||||
import { SelectResource } from "../../../compenents";
|
import { SelectResource } from "../../../compenents";
|
||||||
@ -14,12 +14,6 @@ interface PropInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Option {
|
|
||||||
value: string | number;
|
|
||||||
label: string;
|
|
||||||
children?: Option[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CourseHourUpdate: React.FC<PropInterface> = ({
|
export const CourseHourUpdate: React.FC<PropInterface> = ({
|
||||||
id,
|
id,
|
||||||
open,
|
open,
|
||||||
|
@ -16,20 +16,12 @@ import { useSelector } from "react-redux";
|
|||||||
import { course, department } from "../../../api/index";
|
import { course, department } from "../../../api/index";
|
||||||
import { UploadImageButton } from "../../../compenents";
|
import { UploadImageButton } from "../../../compenents";
|
||||||
|
|
||||||
const { confirm } = Modal;
|
|
||||||
|
|
||||||
interface PropInterface {
|
interface PropInterface {
|
||||||
id: number;
|
id: number;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Option {
|
|
||||||
value: string | number;
|
|
||||||
title: string;
|
|
||||||
children?: Option[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CourseUpdate: React.FC<PropInterface> = ({
|
export const CourseUpdate: React.FC<PropInterface> = ({
|
||||||
id,
|
id,
|
||||||
open,
|
open,
|
||||||
|
@ -27,6 +27,7 @@ import type { TabsProps } from "antd";
|
|||||||
import { CourseCreate } from "./compenents/create";
|
import { CourseCreate } from "./compenents/create";
|
||||||
import { CourseUpdate } from "./compenents/update";
|
import { CourseUpdate } from "./compenents/update";
|
||||||
import { CourseHourUpdate } from "./compenents/hour-update";
|
import { CourseHourUpdate } from "./compenents/hour-update";
|
||||||
|
import { CourseAttachmentUpdate } from "./compenents/attachment-update";
|
||||||
|
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
@ -66,6 +67,8 @@ const CoursePage = () => {
|
|||||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||||
const [updateHourVisible, setHourUpdateVisible] = useState<boolean>(false);
|
const [updateHourVisible, setHourUpdateVisible] = useState<boolean>(false);
|
||||||
|
const [updateAttachmentVisible, setUpdateAttachmentVisible] =
|
||||||
|
useState<boolean>(false);
|
||||||
const [cid, setCid] = useState<number>(0);
|
const [cid, setCid] = useState<number>(0);
|
||||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||||
const [did, setDid] = useState(Number(result.get("did")));
|
const [did, setDid] = useState(Number(result.get("did")));
|
||||||
@ -241,6 +244,23 @@ const CoursePage = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "3",
|
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: (
|
label: (
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
@ -455,6 +475,14 @@ const CoursePage = () => {
|
|||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<CourseAttachmentUpdate
|
||||||
|
id={cid}
|
||||||
|
open={updateAttachmentVisible}
|
||||||
|
onCancel={() => {
|
||||||
|
setUpdateAttachmentVisible(false);
|
||||||
|
setRefresh(!refresh);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user