From c24750dcb22e3a9de5def170a4a16ad9f00ad45c Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Thu, 20 Jul 2023 17:59:57 +0800 Subject: [PATCH 01/40] =?UTF-8?q?=E5=88=86=E7=B1=BB=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/resource/resource-category/index.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pages/resource/resource-category/index.tsx b/src/pages/resource/resource-category/index.tsx index 79e0a53..1566605 100644 --- a/src/pages/resource/resource-category/index.tsx +++ b/src/pages/resource/resource-category/index.tsx @@ -158,6 +158,15 @@ const ResourceCategoryPage = () => { res.data.videos.length === 0 ) { delUser(id); + } else if ( + res.data.children && + res.data.children.length === 0 && + res.data.courses && + res.data.courses.length === 0 && + !res.data.images && + !res.data.videos + ) { + delUser(id); } else { if (res.data.children && res.data.children.length > 0) { modal.warning({ From 79982b0ca86da5d5618f2031a4702adcd48e0085 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Fri, 21 Jul 2023 11:22:16 +0800 Subject: [PATCH 02/40] =?UTF-8?q?=E8=A7=86=E9=A2=91=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=96=87=E6=A1=88=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/resource/videos/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/resource/videos/index.tsx b/src/pages/resource/videos/index.tsx index 15790a9..49bf25b 100644 --- a/src/pages/resource/videos/index.tsx +++ b/src/pages/resource/videos/index.tsx @@ -83,7 +83,7 @@ const ResourceVideosPage = () => { JSON.stringify(adminUsers) !== "{}" && {adminUsers[text]}, }, { - title: "视频时长", + title: "创建时间", dataIndex: "created_at", render: (text: string) => {dateFormat(text)}, }, From 86972e55a3d0a4354ed66d9275bcb3d20ad16ff6 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Mon, 24 Jul 2023 10:15:23 +0800 Subject: [PATCH 03/40] =?UTF-8?q?=E7=BC=93=E5=8A=A0=E8=BD=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index.module.less | 0 .../with-header-without-footer}/index.tsx | 12 ++++--- .../index.module.less | 8 +++++ .../without-header-without-footer/index.tsx | 16 ++++++++++ src/pages/loading/index.module.less | 8 ++--- src/pages/loading/index.tsx | 17 +++++++--- src/routes/index.tsx | 32 ++++++++++++------- 7 files changed, 69 insertions(+), 24 deletions(-) rename src/pages/{home => layouts/with-header-without-footer}/index.module.less (100%) rename src/pages/{home => layouts/with-header-without-footer}/index.tsx (63%) create mode 100644 src/pages/layouts/without-header-without-footer/index.module.less create mode 100644 src/pages/layouts/without-header-without-footer/index.tsx diff --git a/src/pages/home/index.module.less b/src/pages/layouts/with-header-without-footer/index.module.less similarity index 100% rename from src/pages/home/index.module.less rename to src/pages/layouts/with-header-without-footer/index.module.less diff --git a/src/pages/home/index.tsx b/src/pages/layouts/with-header-without-footer/index.tsx similarity index 63% rename from src/pages/home/index.tsx rename to src/pages/layouts/with-header-without-footer/index.tsx index aba2ef7..dc2510f 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/layouts/with-header-without-footer/index.tsx @@ -1,7 +1,9 @@ -import React, { useEffect } from "react"; +import { useEffect } from "react"; import styles from "./index.module.less"; import { Outlet } from "react-router-dom"; -import { Header, LeftMenu } from "../../compenents"; +import { Header, LeftMenu } from "../../../compenents"; +import { Suspense } from "react"; +import LoadingPage from "../../loading"; const HomePage = () => { useEffect(() => {}, []); @@ -17,8 +19,10 @@ const HomePage = () => {
- {/* 二级路由出口 */} - + }> + {/* 二级路由出口 */} + {" "} +
diff --git a/src/pages/layouts/without-header-without-footer/index.module.less b/src/pages/layouts/without-header-without-footer/index.module.less new file mode 100644 index 0000000..d41ce28 --- /dev/null +++ b/src/pages/layouts/without-header-without-footer/index.module.less @@ -0,0 +1,8 @@ +.layout-wrap { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; +} diff --git a/src/pages/layouts/without-header-without-footer/index.tsx b/src/pages/layouts/without-header-without-footer/index.tsx new file mode 100644 index 0000000..31cd2a7 --- /dev/null +++ b/src/pages/layouts/without-header-without-footer/index.tsx @@ -0,0 +1,16 @@ +import { Suspense } from "react"; +import styles from "./index.module.less"; +import { Outlet } from "react-router-dom"; +import LoadingPage from "../../loading"; + +const WithoutHeaderWithoutFooter = () => { + return ( +
+ }> + + +
+ ); +}; + +export default WithoutHeaderWithoutFooter; diff --git a/src/pages/loading/index.module.less b/src/pages/loading/index.module.less index 0ada21a..ca9d22e 100644 --- a/src/pages/loading/index.module.less +++ b/src/pages/loading/index.module.less @@ -1,6 +1,6 @@ -.loading-parent-box { - width: 100vd; - height: 100vh; - text-align: center; +.loading-box { + width: 100vw; line-height: 100vh; + text-align: center; } + diff --git a/src/pages/loading/index.tsx b/src/pages/loading/index.tsx index 58a90d9..2e51159 100644 --- a/src/pages/loading/index.tsx +++ b/src/pages/loading/index.tsx @@ -1,11 +1,20 @@ import { Spin } from "antd"; import styles from "./index.module.less"; -const LoadingPage = () => { +interface PropsInterface { + height?: string; +} + +const LoadingPage = (props: PropsInterface) => { return ( -
- -
+ <> +
+ +
+ ); }; diff --git a/src/routes/index.tsx b/src/routes/index.tsx index f44e6f8..742dcaf 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -7,7 +7,9 @@ import KeepAlive from "../compenents/keep-alive"; // 页面加载 import InitPage from "../pages/init"; import LoginPage from "../pages/login"; -import HomePage from "../pages/home"; +import WithHeaderWithoutFooter from "../pages/layouts/with-header-without-footer"; +import WithoutHeaderWithoutFooter from "../pages/layouts/without-header-without-footer"; + //首页 const DashboardPage = lazy(() => import("../pages/dashboard")); //修改密码页面 @@ -77,7 +79,7 @@ const routes: RouteObject[] = [ children: [ { path: "/", - element: } />, + element: } />, children: [ { path: "/", @@ -150,16 +152,22 @@ const routes: RouteObject[] = [ ], }, { - path: "/login", - element: , - }, - { - path: "/test", - element: , - }, - { - path: "*", - element: , + path: "/", + element: , + children: [ + { + path: "/login", + element: , + }, + { + path: "/test", + element: , + }, + { + path: "*", + element: , + }, + ], }, ], }, From 2e44c79e9726230508d481b1828458dd158f6f64 Mon Sep 17 00:00:00 2001 From: none Date: Fri, 28 Jul 2023 15:52:07 +0800 Subject: [PATCH 04/40] merge-video -> merge-file --- src/api/upload.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/upload.ts b/src/api/upload.ts index 8011867..53f20b2 100644 --- a/src/api/upload.ts +++ b/src/api/upload.ts @@ -27,7 +27,7 @@ export function minioMergeVideo( duration: number, poster: string ) { - return client.post("/backend/v1/upload/minio/merge-video", { + return client.post("/backend/v1/upload/minio/merge-file", { filename, upload_id: uploadId, original_filename: originalFilename, From 727f1741b627e7db15a017806f8ddf78a7975ec6 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Fri, 28 Jul 2023 16:30:23 +0800 Subject: [PATCH 05/40] =?UTF-8?q?=E8=B5=84=E6=BA=90=E8=AF=BE=E4=BB=B6?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=88=9D=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compenents/left-menu/index.tsx | 1 + .../resource/courseware/index.module.less | 0 src/pages/resource/courseware/index.tsx | 370 ++++++++++++++++++ src/pages/resource/videos/index.tsx | 2 +- src/routes/index.tsx | 7 + 5 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 src/pages/resource/courseware/index.module.less create mode 100644 src/pages/resource/courseware/index.tsx diff --git a/src/compenents/left-menu/index.tsx b/src/compenents/left-menu/index.tsx index 4b3a579..0903301 100644 --- a/src/compenents/left-menu/index.tsx +++ b/src/compenents/left-menu/index.tsx @@ -46,6 +46,7 @@ const items = [ [ getItem("视频", "/videos", null, null, null, null), getItem("图片", "/images", null, null, null, null), + getItem("课件", "/courseware", null, null, null, null), ], null, null diff --git a/src/pages/resource/courseware/index.module.less b/src/pages/resource/courseware/index.module.less new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/resource/courseware/index.tsx b/src/pages/resource/courseware/index.tsx new file mode 100644 index 0000000..7ea4ac2 --- /dev/null +++ b/src/pages/resource/courseware/index.tsx @@ -0,0 +1,370 @@ +import { useEffect, useState } from "react"; +import { + Modal, + Table, + message, + Space, + Typography, + Input, + Select, + Button, +} from "antd"; +import type { MenuProps } from "antd"; +import { resource } from "../../../api"; +// import styles from "./index.module.less"; +import { useLocation } from "react-router-dom"; +import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons"; +import type { ColumnsType } from "antd/es/table"; +import { dateFormat } from "../../../utils/index"; +import { TreeCategory, DurationText, PerButton } from "../../../compenents"; + +const { confirm } = Modal; + +interface DataType { + id: React.Key; + name: string; + created_at: string; + disk: string; + number: number; +} + +const ResourceCoursewarePage = () => { + const result = new URLSearchParams(useLocation().search); + const [list, setList] = useState([]); + const [adminUsers, setAdminUsers] = useState({}); + const [existingTypes, setExistingTypes] = useState([]); + const [refresh, setRefresh] = useState(false); + const [page, setPage] = useState(1); + const [size, setSize] = useState(10); + const [total, setTotal] = useState(0); + const [loading, setLoading] = useState(true); + const [category_ids, setCategoryIds] = useState([]); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [type, setType] = useState("WORD,EXCE,PPT,PDF,TXT,RAR,ZIP"); + const [title, setTitle] = useState(""); + const [multiConfig, setMultiConfig] = useState(false); + const [selLabel, setLabel] = useState( + result.get("label") ? String(result.get("label")) : "全部课件" + ); + const [cateId, setCateId] = useState(Number(result.get("cid"))); + const [updateId, setUpdateId] = useState(0); + const [updateVisible, setUpdateVisible] = useState(false); + const types = [ + { label: "全部", value: "WORD,EXCE,PPT,PDF,TXT,RAR,ZIP" }, + { label: "WORD", value: "WORD" }, + { label: "EXCEL", value: "EXCE" }, + { label: "PPT", value: "PPT" }, + { label: "PDF", value: "PDF" }, + { label: "TXT", value: "TXT" }, + { label: "RAR", value: "RAR" }, + { label: "ZIP", value: "ZIP" }, + ]; + + useEffect(() => { + setCateId(Number(result.get("cid"))); + if (Number(result.get("cid"))) { + let arr = []; + arr.push(Number(result.get("cid"))); + setCategoryIds(arr); + } + }, [result.get("cid")]); + + // 加载课件列表 + useEffect(() => { + getList(); + }, [category_ids, refresh, page, size]); + + const getList = () => { + setLoading(true); + let categoryIds = category_ids.join(","); + resource + .resourceList(page, size, "", "", title, type, categoryIds) + .then((res: any) => { + setTotal(res.data.result.total); + setList(res.data.result.data); + setExistingTypes(res.data.existing_types); + setAdminUsers(res.data.admin_users); + setLoading(false); + }) + .catch((err: any) => { + console.log("错误,", err); + }); + }; + + const columns: ColumnsType = [ + { + title: "课件名称", + dataIndex: "name", + render: (text: string) => ( +
+ + {text} +
+ ), + }, + { + title: "课件格式", + dataIndex: "id", + width: 204, + render: (id: string) => {id}, + }, + { + title: "课件大小", + dataIndex: "size", + width: 204, + render: (size: number) => {(size / 1024 / 1024).toFixed(2)}M, + }, + { + title: "创建人", + dataIndex: "admin_id", + width: 204, + render: (text: number) => + JSON.stringify(adminUsers) !== "{}" && {adminUsers[text]}, + }, + { + title: "创建时间", + dataIndex: "created_at", + width: 204, + render: (text: string) => {dateFormat(text)}, + }, + { + title: "操作", + key: "action", + fixed: "right", + width: 180, + render: (_, record: any) => { + return ( + + +
+ +
+ +
+ ); + }, + }, + ]; + + const paginationProps = { + current: page, //当前页码 + pageSize: size, + total: total, // 总条数 + onChange: (page: number, pageSize: number) => + handlePageChange(page, pageSize), //改变页码的函数 + showSizeChanger: true, + }; + + const handlePageChange = (page: number, pageSize: number) => { + setPage(page); + setSize(pageSize); + }; + + const rowSelection = { + onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => { + setSelectedRowKeys(selectedRowKeys); + }, + }; + + // 重置列表 + const resetList = () => { + setPage(1); + setSize(10); + setList([]); + setSelectedRowKeys([]); + setType("WORD,EXCE,PPT,PDF,TXT,RAR,ZIP"); + setRefresh(!refresh); + }; + + // 删除课件 + const removeResource = (id: number) => { + if (id === 0) { + return; + } + confirm({ + title: "操作确认", + icon: , + content: "删除前请检查选中课件文件无关联课程,确认删除?", + centered: true, + okText: "确认", + cancelText: "取消", + onOk() { + resource.destroyResource(id).then(() => { + message.success("删除成功"); + resetList(); + }); + }, + onCancel() { + console.log("Cancel"); + }, + }); + }; + + // 批量删除课件 + const removeResourceMulti = () => { + if (selectedRowKeys.length === 0) { + return; + } + confirm({ + title: "操作确认", + icon: , + content: "删除前请检查选中课件文件无关联课程,确认删除?", + centered: true, + okText: "确认", + cancelText: "取消", + onOk() { + resource.destroyResourceMulti(selectedRowKeys).then(() => { + message.success("删除成功"); + resetList(); + }); + }, + onCancel() { + console.log("Cancel"); + }, + }); + }; + + const downLoadFile = (id: number) => {}; + + return ( + <> +
+
+ { + setPage(1); + setCategoryIds(keys); + if (typeof title === "string") { + setLabel(title); + } else { + setLabel(title.props.children[0]); + } + }} + /> +
+
+
+ 课件 | {selLabel} +
+
+
+ + +
+
+
+
+ 名称: + { + setTitle(e.target.value); + }} + allowClear + style={{ width: 160 }} + placeholder="请输入名称关键字" + /> +
+
+ 格式: + + + +
+ + + ); +}; diff --git a/src/pages/resource/courseware/index.tsx b/src/pages/resource/courseware/index.tsx index b51ee2a..a889b38 100644 --- a/src/pages/resource/courseware/index.tsx +++ b/src/pages/resource/courseware/index.tsx @@ -16,12 +16,8 @@ import { useLocation } from "react-router-dom"; import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons"; import type { ColumnsType } from "antd/es/table"; import { dateFormat } from "../../../utils/index"; -import { - TreeCategory, - DurationText, - PerButton, - UploadCoursewareButton, -} from "../../../compenents"; +import { TreeCategory, UploadCoursewareButton } from "../../../compenents"; +import { CoursewareUpdateDialog } from "./compenents/update-dialog"; const { confirm } = Modal; @@ -378,6 +374,15 @@ const ResourceCoursewarePage = () => { )}
+ setUpdateVisible(false)} + onSuccess={() => { + setUpdateVisible(false); + setRefresh(!refresh); + }} + >
); From 1556d8ec035deadb695537ce8633d4be194db792 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 10:27:28 +0800 Subject: [PATCH 18/40] =?UTF-8?q?=E8=AF=BE=E4=BB=B6=E6=96=B0=E5=A2=9Eapi?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/course-attachment.ts | 22 ++++++++++++++++++++++ src/api/course.ts | 4 +++- src/api/index.ts | 1 + src/pages/course/compenents/create.tsx | 3 ++- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/api/course-attachment.ts diff --git a/src/api/course-attachment.ts b/src/api/course-attachment.ts new file mode 100644 index 0000000..dae980a --- /dev/null +++ b/src/api/course-attachment.ts @@ -0,0 +1,22 @@ +import client from "./internal/httpClient"; + +export function updateCourseAttachment( + courseId: number, + id: number, + chapterId: number, + name: string, + type: string, + rid: number +) { + return client.put(`/backend/v1/course/${courseId}/attachment/create-batch`, { + chapter_id: chapterId, + name, + type, + sort: 0, + rid, + }); +} + +export function destroyAttachment(courseId: number, id: number) { + return client.destroy(`/backend/v1/course/${courseId}/attachment/${id}`); +} diff --git a/src/api/course.ts b/src/api/course.ts index bb93ea1..87dedc4 100644 --- a/src/api/course.ts +++ b/src/api/course.ts @@ -35,7 +35,8 @@ export function storeCourse( depIds: number[], categoryIds: number[], chapters: number[], - hours: number[] + hours: number[], + attachments: any[] ) { return client.post("/backend/v1/course/create", { title: title, @@ -47,6 +48,7 @@ export function storeCourse( category_ids: categoryIds, chapters: chapters, hours: hours, + attachments: attachments, }); } diff --git a/src/api/index.ts b/src/api/index.ts index ad717e8..733df58 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -6,6 +6,7 @@ export * as courseCategory from "./course-category"; export * as courseChapter from "./course-chapter"; export * as course from "./course"; export * as courseHour from "./course-hour"; +export * as courseAttachment from "./course-attachment"; export * as department from "./department"; export * as resourceCategory from "./resource-category"; export * as resource from "./resource"; diff --git a/src/pages/course/compenents/create.tsx b/src/pages/course/compenents/create.tsx index 23cd599..1d82990 100644 --- a/src/pages/course/compenents/create.tsx +++ b/src/pages/course/compenents/create.tsx @@ -224,7 +224,8 @@ export const CourseCreate: React.FC = ({ dep_ids, values.category_ids, chapters, - treeData + treeData, + [] ) .then((res: any) => { message.success("保存成功!"); From 3ca314112a2c6c04ea94b3b806ba55a253c5753b Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 10:28:33 +0800 Subject: [PATCH 19/40] =?UTF-8?q?=E8=AF=BE=E4=BB=B6=E6=96=B0=E5=A2=9Eapi?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.less b/src/index.less index 283a914..2931939 100644 --- a/src/index.less +++ b/src/index.less @@ -525,7 +525,7 @@ textarea.ant-input { &:hover { box-shadow: none !important; color: #ff4d4f !important; - border-color: #ff4d4f; + border-color: #ff4d4f !important; outline: none; } } From ea176bdf76b0b073eb54347e5919b135bea6f2ae Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 10:56:32 +0800 Subject: [PATCH 20/40] =?UTF-8?q?=E8=B5=84=E6=BA=90=E8=AF=BE=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resource/courseware/compenents/update-dialog/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/resource/courseware/compenents/update-dialog/index.tsx b/src/pages/resource/courseware/compenents/update-dialog/index.tsx index 69b82de..32f88da 100644 --- a/src/pages/resource/courseware/compenents/update-dialog/index.tsx +++ b/src/pages/resource/courseware/compenents/update-dialog/index.tsx @@ -74,9 +74,6 @@ export const CoursewareUpdateDialog: React.FC = ({ }; const onFinish = (values: any) => { - if (loading) { - return; - } setLoading(true); if (Array.isArray(values.category_id)) { values.category_id = values.category_id[0]; From d392878bf552e1e1ac9e371c70f17fe223061512 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 12:08:50 +0800 Subject: [PATCH 21/40] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E8=AF=BE=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/iconfont/iconfont.css | 54 +++- src/assets/iconfont/iconfont.ttf | Bin 7856 -> 10964 bytes src/assets/iconfont/iconfont.woff | Bin 5068 -> 7156 bytes src/assets/iconfont/iconfont.woff2 | Bin 4328 -> 6132 bytes src/compenents/index.ts | 2 + src/compenents/select-attachment/index.tsx | 77 ++++++ .../upload-courseware-sub/index.module.less | 0 .../upload-courseware-sub/index.tsx | 242 ++++++++++++++++++ src/index.less | 24 ++ src/pages/course/compenents/attachments.tsx | 157 ++++++++++++ src/pages/course/compenents/create.tsx | 128 ++++++++- 11 files changed, 669 insertions(+), 15 deletions(-) create mode 100644 src/compenents/select-attachment/index.tsx create mode 100644 src/compenents/upload-courseware-sub/index.module.less create mode 100644 src/compenents/upload-courseware-sub/index.tsx create mode 100644 src/pages/course/compenents/attachments.tsx diff --git a/src/assets/iconfont/iconfont.css b/src/assets/iconfont/iconfont.css index bfbcd32..a6751c1 100644 --- a/src/assets/iconfont/iconfont.css +++ b/src/assets/iconfont/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 3943555 */ - src: url('iconfont.woff2?t=1679383201256') format('woff2'), - url('iconfont.woff?t=1679383201256') format('woff'), - url('iconfont.ttf?t=1679383201256') format('truetype'); + src: url('iconfont.woff2?t=1690600882833') format('woff2'), + url('iconfont.woff?t=1690600882833') format('woff'), + url('iconfont.ttf?t=1690600882833') format('truetype'); } .iconfont { @@ -13,6 +13,54 @@ -moz-osx-font-smoothing: grayscale; } +.icon-playedu:before { + content: "\e756"; +} + +.icon-icon-xuexi:before { + content: "\e753"; +} + +.icon-icon-wode:before { + content: "\e754"; +} + +.icon-icon-shouye:before { + content: "\e755"; +} + +.icon-icon-xiala:before { + content: "\e752"; +} + +.icon-close:before { + content: "\e751"; +} + +.icon-fullscreen:before { + content: "\e74b"; +} + +.icon-speed:before { + content: "\e74c"; +} + +.icon-mute:before { + content: "\e74d"; +} + +.icon-play:before { + content: "\e74e"; +} + +.icon-pause:before { + content: "\e74f"; +} + +.icon-unmute:before { + content: "\e750"; +} + .icon-icon-tips:before { content: "\e74a"; } diff --git a/src/assets/iconfont/iconfont.ttf b/src/assets/iconfont/iconfont.ttf index ab333cf8a0e87ee4323d1a86cad26bfb96380c6e..80df28fa9a01d06bd69bf88269e9a507d2c56f88 100644 GIT binary patch delta 4472 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 Au>b%7 diff --git a/src/assets/iconfont/iconfont.woff2 b/src/assets/iconfont/iconfont.woff2 index 5dd256c87b254cd4a46b0dae27b9911ebc950d24..53acad625e6778be2061a6acd3a9e98ae9cd0728 100644 GIT binary patch literal 6132 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 Gn~X-C@!f?0 literal 4328 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 WZab|AGREg5Js~SbrPNzrFaQ9uw?PyD diff --git a/src/compenents/index.ts b/src/compenents/index.ts index 8143d58..6fb5c12 100644 --- a/src/compenents/index.ts +++ b/src/compenents/index.ts @@ -11,3 +11,5 @@ export * from "./duration-text"; export * from "./upload-video-sub"; export * from "./select-resource"; export * from "./upload-courseware-button"; +export * from "./upload-courseware-sub"; +export * from "./select-attachment"; diff --git a/src/compenents/select-attachment/index.tsx b/src/compenents/select-attachment/index.tsx new file mode 100644 index 0000000..2129965 --- /dev/null +++ b/src/compenents/select-attachment/index.tsx @@ -0,0 +1,77 @@ +import { useEffect, useState } from "react"; +import { Button, Row, Modal, message, Tabs } from "antd"; +import styles from "./index.module.less"; +import { UploadCoursewareSub } from "../../compenents"; +import type { TabsProps } from "antd"; + +interface VideoItem { + id: number; + category_id: number; + name: string; + duration: number; +} + +interface PropsInterface { + defaultKeys: any[]; + open: boolean; + onSelected: (arr: any[], videos: any[]) => void; + onCancel: () => void; +} + +export const SelectAttachment = (props: PropsInterface) => { + const [refresh, setRefresh] = useState(true); + const [tabKey, setTabKey] = useState(1); + const [selectKeys, setSelectKeys] = useState([]); + const [selectVideos, setSelectVideos] = useState([]); + + const items: TabsProps["items"] = [ + { + key: "1", + label: `课件`, + children: ( +

+ { + setSelectKeys(arr); + setSelectVideos(videos); + }} + /> +
+ ), + }, + ]; + + const onChange = (key: string) => { + setTabKey(Number(key)); + }; + + return ( + <> + { + setSelectKeys([]); + setSelectVideos([]); + props.onCancel(); + }} + open={props.open} + width={800} + maskClosable={false} + onOk={() => { + props.onSelected(selectKeys, selectVideos); + setSelectKeys([]); + setSelectVideos([]); + }} + > + + + + + + ); +}; diff --git a/src/compenents/upload-courseware-sub/index.module.less b/src/compenents/upload-courseware-sub/index.module.less new file mode 100644 index 0000000..e69de29 diff --git a/src/compenents/upload-courseware-sub/index.tsx b/src/compenents/upload-courseware-sub/index.tsx new file mode 100644 index 0000000..23d7985 --- /dev/null +++ b/src/compenents/upload-courseware-sub/index.tsx @@ -0,0 +1,242 @@ +import { useEffect, useState } from "react"; +import { Checkbox, Row, Col, Empty, message, Pagination } from "antd"; +import { resource } from "../../api"; +import styles from "./index.module.less"; +import { TreeCategory, UploadCoursewareButton } from "../../compenents"; +import type { CheckboxChangeEvent } from "antd/es/checkbox"; +import type { CheckboxValueType } from "antd/es/checkbox/Group"; + +const CheckboxGroup = Checkbox.Group; + +interface VideoItem { + id: number; + category_id: number; + name: string; +} + +interface PropsInterface { + defaultCheckedList: any[]; + label: string; + open: boolean; + onSelected: (arr: any[], videos: []) => void; +} + +export const UploadCoursewareSub = (props: PropsInterface) => { + const [category_ids, setCategoryIds] = useState([]); + const [loading, setLoading] = useState(false); + const [videoList, setVideoList] = useState([]); + const [existingTypes, setExistingTypes] = useState([]); + const [refresh, setRefresh] = useState(false); + const [page, setPage] = useState(1); + const [size, setSize] = useState(10); + const [total, setTotal] = useState(0); + + const [plainOptions, setPlainOptions] = useState([]); + const [checkedList, setCheckedList] = useState([]); + const [indeterminate, setIndeterminate] = useState(false); + const [checkAll, setCheckAll] = useState(false); + + // 获取列表 + const getvideoList = (defaultKeys: any[]) => { + let categoryIds = category_ids.join(","); + resource + .resourceList( + page, + size, + "", + "", + "", + "WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP", + categoryIds + ) + .then((res: any) => { + setTotal(res.data.result.total); + setExistingTypes(res.data.existing_types); + setVideoList(res.data.result.data); + let data = res.data.result.data; + const arr = []; + for (let i = 0; i < data.length; i++) { + arr.push({ + label: ( +
+ +
{data[i].name}
+
{data[i].type}
+
+ ), + value: data[i].id, + disabled: false, + }); + } + if (defaultKeys.length > 0 && arr.length > 0) { + for (let i = 0; i < defaultKeys.length; i++) { + for (let j = 0; j < arr.length; j++) { + if (arr[j].value === defaultKeys[i]) { + arr[j].disabled = true; + } + } + } + } + setPlainOptions(arr); + }) + .catch((err) => { + console.log("错误,", err); + }); + }; + // 重置列表 + const resetVideoList = () => { + setPage(1); + setVideoList([]); + setRefresh(!refresh); + }; + + // 加载列表 + useEffect(() => { + const arr = [...props.defaultCheckedList]; + setCheckedList(arr); + if (arr.length === 0) { + setIndeterminate(false); + setCheckAll(false); + } + getvideoList(arr); + }, [props.open, props.defaultCheckedList, category_ids, refresh, page, size]); + + const onChange = (list: CheckboxValueType[]) => { + setCheckedList(list); + setIndeterminate(!!list.length && list.length < plainOptions.length); + setCheckAll(list.length === plainOptions.length); + const defalut = [...props.defaultCheckedList]; + let localKeys: any = []; + list.map((item: any) => { + if (defalut.indexOf(item) === -1) { + localKeys.push(item); + } + }); + + let arrVideos: any = []; + + for (let i = 0; i < localKeys.length; i++) { + videoList.map((item: any, index: number) => { + if (item.id === localKeys[i]) { + arrVideos.push({ + name: item.name, + type: item.type, + rid: item.id, + disabled: plainOptions[index].disabled, + }); + } + }); + } + props.onSelected(localKeys, arrVideos); + }; + + const onCheckAllChange = (e: CheckboxChangeEvent) => { + const arr = plainOptions.map((item: any) => item.value); + setCheckedList(e.target.checked ? arr : []); + setIndeterminate(false); + setCheckAll(e.target.checked); + const defalut = [...props.defaultCheckedList]; + let localKeys: any = []; + arr.map((item: any) => { + if (defalut.indexOf(item) === -1) { + localKeys.push(item); + } + }); + let arrVideos: any = []; + for (let i = 0; i < localKeys.length; i++) { + videoList.map((item: any, index: number) => { + if (item.id === localKeys[i]) { + arrVideos.push({ + name: item.name, + type: item.type, + rid: item.id, + disabled: plainOptions[index].disabled, + }); + } + }); + } + if (e.target.checked) { + props.onSelected(localKeys, arrVideos); + } else { + props.onSelected([], []); + } + }; + + return ( + <> + + + setCategoryIds(keys)} + /> + + + + + { + resetVideoList(); + }} + > + + +
+ {videoList.length === 0 && ( + + + + )} + {videoList.length > 0 && ( +
+ + 全选 + + +
+ )} +
+ + {videoList.length > 0 && total > 10 && ( + + { + setPage(currentPage); + setSize(currentSize); + }} + defaultCurrent={page} + total={total} + /> + + )} + + +
+ + ); +}; diff --git a/src/index.less b/src/index.less index 2931939..5858831 100644 --- a/src/index.less +++ b/src/index.less @@ -596,6 +596,7 @@ textarea.ant-input { .ant-checkbox-wrapper { margin-inline-start: 0px; height: 38px; + align-items: center !important; } .video-title { @@ -660,3 +661,26 @@ textarea.ant-input { transform: rotate(90deg); } } + +.drop-item { + width: 140px; + height: 32px; + display: flex; + align-items: center; + cursor: pointer; + &.active { + i { + transform: rotate(180deg); + } + } + i { + margin-right: 12px; + } + span { + font-size: 12px; + font-weight: 400; + color: rgba(0, 0, 0, 0.45); + line-height: 32px; + } +} + diff --git a/src/pages/course/compenents/attachments.tsx b/src/pages/course/compenents/attachments.tsx new file mode 100644 index 0000000..5a0aa58 --- /dev/null +++ b/src/pages/course/compenents/attachments.tsx @@ -0,0 +1,157 @@ +import { message, Tree, Tooltip } from "antd"; +import { useState, useEffect } from "react"; +import type { DataNode, TreeProps } from "antd/es/tree"; + +interface Option { + id: number; + name: string; +} + +interface PropInterface { + data: Option[]; + onRemoveItem: (id: number) => void; + onUpdate: (arr: any[]) => void; +} + +export const TreeAttachments = (props: PropInterface) => { + const [treeData, setTreeData] = useState([]); + const [loading, setLoading] = useState(true); + useEffect(() => { + const hours = props.data; + if (hours.length === 0) { + return; + } + checkTree(hours); + }, [props.data]); + + const checkTree = (hours: any) => { + const arr = []; + for (let i = 0; i < hours.length; i++) { + arr.push({ + title: ( +
+
+ +
{hours[i].name}
+
+ + + + removeItem(hours[i].rid)} + /> +
+ ), + key: hours[i].rid, + }); + } + setTreeData(arr); + }; + + const removeItem = (id: number) => { + if (id === 0) { + return; + } + props.onRemoveItem(id); + }; + const onDrop: TreeProps["onDrop"] = (info) => { + const dropKey = info.node.key; + const dragKey = info.dragNode.key; + const dropPos = info.node.pos.split("-"); + const dropPosition = + info.dropPosition - Number(dropPos[dropPos.length - 1]); + const loop = ( + data: DataNode[], + key: React.Key, + callback: (node: DataNode, i: number, data: DataNode[]) => void + ) => { + for (let i = 0; i < data.length; i++) { + if (data[i].key === key) { + return callback(data[i], i, data); + } + if (data[i].children) { + loop(data[i].children!, key, callback); + } + } + }; + const data = [...treeData]; + let isTop = false; + + for (let i = 0; i < data.length; i++) { + if (data[i].key === dragKey) { + isTop = true; + } + } + + // Find dragObject + let dragObj: DataNode; + loop(data, dragKey, (item, index, arr) => { + arr.splice(index, 1); + dragObj = item; + }); + + if (!info.dropToGap) { + // Drop on the content + loop(data, dropKey, (item) => { + item.children = item.children || []; + // where to insert 示例添加到头部,可以是随意位置 + item.children.unshift(dragObj); + }); + } else if ( + ((info.node as any).props.children || []).length > 0 && // Has children + (info.node as any).props.expanded && // Is expanded + dropPosition === 1 // On the bottom gap + ) { + loop(data, dropKey, (item) => { + item.children = item.children || []; + // where to insert 示例添加到头部,可以是随意位置 + item.children.unshift(dragObj); + // in previous version, we use item.children.push(dragObj) to insert the + // item to the tail of the children + }); + } else { + let ar: DataNode[] = []; + let i: number; + loop(data, dropKey, (_item, index, arr) => { + ar = arr; + i = index; + }); + if (dropPosition === -1) { + ar.splice(i!, 0, dragObj!); + } else { + ar.splice(i! + 1, 0, dragObj!); + } + } + setTreeData(data); + const keys = data.map((item: any) => item.key); + props.onUpdate(keys); + }; + + const onDragEnter: TreeProps["onDragEnter"] = (info) => { + console.log(info); + }; + + return ( +
+ +
+ ); +}; diff --git a/src/pages/course/compenents/create.tsx b/src/pages/course/compenents/create.tsx index 1d82990..79989cd 100644 --- a/src/pages/course/compenents/create.tsx +++ b/src/pages/course/compenents/create.tsx @@ -14,9 +14,14 @@ import { import styles from "./create.module.less"; import { useSelector } from "react-redux"; import { course, department } from "../../../api/index"; -import { UploadImageButton, SelectResource } from "../../../compenents"; +import { + UploadImageButton, + SelectResource, + SelectAttachment, +} from "../../../compenents"; import { ExclamationCircleFilled } from "@ant-design/icons"; import { TreeHours } from "./hours"; +import { TreeAttachments } from "./attachments"; const { confirm } = Modal; @@ -58,6 +63,10 @@ export const CourseCreate: React.FC = ({ const [videoVisible, setVideoVisible] = useState(false); const [treeData, setTreeData] = useState([]); const [addvideoCurrent, setAddvideoCurrent] = useState(0); + const [showDrop, setShowDrop] = useState(false); + const [attachmentVisible, setAttachmentVisible] = useState(false); + const [attachmentData, setAttachmentData] = useState([]); + const [attachments, setAttachments] = useState([]); useEffect(() => { if (open) { @@ -80,6 +89,7 @@ export const CourseCreate: React.FC = ({ setChapterHours([]); setHours([]); setTreeData([]); + setAttachmentData([]); }, [form, open]); const getParams = () => { @@ -225,7 +235,7 @@ export const CourseCreate: React.FC = ({ values.category_ids, chapters, treeData, - [] + attachmentData ) .then((res: any) => { message.success("保存成功!"); @@ -269,6 +279,20 @@ export const CourseCreate: React.FC = ({ setVideoVisible(false); }; + const selectAttachmentData = (arr: any, videos: any) => { + if (arr.length === 0) { + message.error("请选择课件"); + return; + } + let keys = [...attachments]; + let data = [...attachmentData]; + keys = keys.concat(arr); + data = data.concat(videos); + setAttachments(keys); + setAttachmentData(data); + setAttachmentVisible(false); + }; + const getChapterType = (e: any) => { const arr = [...chapters]; if (arr.length > 0) { @@ -327,6 +351,36 @@ export const CourseCreate: React.FC = ({ setTreeData(newArr); }; + const delAttachments = (id: number) => { + const data = [...attachmentData]; + const index = data.findIndex((i: any) => i.rid === 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([]); + } + }; + + const transAttachments = (arr: any) => { + setAttachments(arr); + const data = [...attachmentData]; + const newArr: any = []; + for (let i = 0; i < arr.length; i++) { + data.map((item: any) => { + if (item.rid === arr[i]) { + newArr.push(item); + } + }); + } + setAttachmentData(newArr); + }; + const addNewChapter = () => { const arr = [...chapters]; const keys = [...chapterHours]; @@ -446,6 +500,16 @@ export const CourseCreate: React.FC = ({ } }} /> + { + setAttachmentVisible(false); + }} + onSelected={(arr: any, videos: any) => { + selectAttachmentData(arr, videos); + }} + >
= ({
- - - = ({ {chapterType === 0 && ( -
+
)} {chapterType === 1 && ( -
+
{chapters.length > 0 && chapters.map((item: any, index: number) => { return ( @@ -738,6 +794,54 @@ export const CourseCreate: React.FC = ({
)} + +
setShowDrop(!showDrop)} + > + + (课程简介、课件) +
+
+
+ + + + + + +
+ {attachmentData.length === 0 && ( + + 请点击上方按钮添加课件 + + )} + {attachmentData.length > 0 && ( + { + delAttachments(id); + }} + onUpdate={(arr: any[]) => { + transAttachments(arr); + }} + /> + )} +
+
From c0994dc29bb13198e9befd43ae68e52143ef18d5 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 15:33:14 +0800 Subject: [PATCH 22/40] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E8=AF=BE=E4=BB=B6=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/course-attachment.ts | 22 +- src/api/internal/httpClient.ts | 2 +- .../compenents/attachment-update.module.scss | 43 ++++ .../course/compenents/attachment-update.tsx | 219 ++++++++++++++++++ src/pages/course/compenents/create.tsx | 6 - src/pages/course/compenents/hour-update.tsx | 8 +- src/pages/course/compenents/update.tsx | 8 - src/pages/course/index.tsx | 28 +++ 8 files changed, 302 insertions(+), 34 deletions(-) create mode 100644 src/pages/course/compenents/attachment-update.module.scss create mode 100644 src/pages/course/compenents/attachment-update.tsx diff --git a/src/api/course-attachment.ts b/src/api/course-attachment.ts index dae980a..8629805 100644 --- a/src/api/course-attachment.ts +++ b/src/api/course-attachment.ts @@ -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, + }); +} diff --git a/src/api/internal/httpClient.ts b/src/api/internal/httpClient.ts index 8c75dee..a029412 100644 --- a/src/api/internal/httpClient.ts +++ b/src/api/internal/httpClient.ts @@ -8,7 +8,7 @@ const GoLogin = () => { }; const GoError = () => { - window.location.href = "/error"; + // window.location.href = "/error"; }; export class HttpClient { diff --git a/src/pages/course/compenents/attachment-update.module.scss b/src/pages/course/compenents/attachment-update.module.scss new file mode 100644 index 0000000..cc25058 --- /dev/null +++ b/src/pages/course/compenents/attachment-update.module.scss @@ -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; + } +} diff --git a/src/pages/course/compenents/attachment-update.tsx b/src/pages/course/compenents/attachment-update.tsx new file mode 100644 index 0000000..a21cde4 --- /dev/null +++ b/src/pages/course/compenents/attachment-update.tsx @@ -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 = ({ + id, + open, + onCancel, +}) => { + const [form] = Form.useForm(); + const [attachmentVisible, setAttachmentVisible] = useState(false); + const [attachmentData, setAttachmentData] = useState([]); + const [attachments, setAttachments] = useState([]); + + 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: , + 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 ( + <> + +
+

1.线上课课件调整及时生效,操作不可逆,请谨慎操作。

+
+
+ { + setAttachmentVisible(false); + }} + onSelected={(arr: any, videos: any) => { + selectAttachmentData(arr, videos); + }} + > +
+
+ +
+ +
+
+
+ {attachmentData.length === 0 && ( + + 请点击上方按钮添加课件 + + )} + {attachmentData.length > 0 && ( + { + delAttachments(id); + }} + onUpdate={(arr: any[]) => { + transAttachments(arr); + }} + /> + )} +
+
+
+
+
+ + ); +}; diff --git a/src/pages/course/compenents/create.tsx b/src/pages/course/compenents/create.tsx index 79989cd..c67d186 100644 --- a/src/pages/course/compenents/create.tsx +++ b/src/pages/course/compenents/create.tsx @@ -32,12 +32,6 @@ interface PropInterface { onCancel: () => void; } -interface Option { - value: string | number; - title: string; - children?: Option[]; -} - export const CourseCreate: React.FC = ({ cateIds, depIds, diff --git a/src/pages/course/compenents/hour-update.tsx b/src/pages/course/compenents/hour-update.tsx index 14d5f33..2c91660 100644 --- a/src/pages/course/compenents/hour-update.tsx +++ b/src/pages/course/compenents/hour-update.tsx @@ -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 = ({ id, open, diff --git a/src/pages/course/compenents/update.tsx b/src/pages/course/compenents/update.tsx index 41d6cb4..c36b3ae 100644 --- a/src/pages/course/compenents/update.tsx +++ b/src/pages/course/compenents/update.tsx @@ -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 = ({ id, open, diff --git a/src/pages/course/index.tsx b/src/pages/course/index.tsx index a4643c1..5374f6b 100644 --- a/src/pages/course/index.tsx +++ b/src/pages/course/index.tsx @@ -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(false); const [updateVisible, setUpdateVisible] = useState(false); const [updateHourVisible, setHourUpdateVisible] = useState(false); + const [updateAttachmentVisible, setUpdateAttachmentVisible] = + useState(false); const [cid, setCid] = useState(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: ( + + ), + }, + { + key: "4", label: (
From 540d1e01e733cc75256a581571dabf079595a0da Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 15:37:18 +0800 Subject: [PATCH 23/40] =?UTF-8?q?http=E5=A4=87=E6=B3=A8=E8=BF=98=E5=8E=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/internal/httpClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/internal/httpClient.ts b/src/api/internal/httpClient.ts index a029412..8c75dee 100644 --- a/src/api/internal/httpClient.ts +++ b/src/api/internal/httpClient.ts @@ -8,7 +8,7 @@ const GoLogin = () => { }; const GoError = () => { - // window.location.href = "/error"; + window.location.href = "/error"; }; export class HttpClient { From a6923632d1645d6ac0fe516cc4e7576d44d3a9d6 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 17:27:21 +0800 Subject: [PATCH 24/40] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/admin-log.ts | 21 ++ src/api/index.ts | 1 + src/compenents/left-menu/index.tsx | 1 + src/main.tsx | 1 + src/pages/system/adminlog/index.module.less | 0 src/pages/system/adminlog/index.tsx | 180 ++++++++++++++++++ .../system/adminroles/compenents/create.tsx | 5 + .../system/adminroles/compenents/update.tsx | 5 + src/routes/index.tsx | 5 + src/utils/index.ts | 7 + 10 files changed, 226 insertions(+) create mode 100644 src/api/admin-log.ts create mode 100644 src/pages/system/adminlog/index.module.less create mode 100644 src/pages/system/adminlog/index.tsx diff --git a/src/api/admin-log.ts b/src/api/admin-log.ts new file mode 100644 index 0000000..f7e68f2 --- /dev/null +++ b/src/api/admin-log.ts @@ -0,0 +1,21 @@ +import client from "./internal/httpClient"; + +export function adminLogList( + page: number, + size: number, + admin_id: number | null, + title: string, + opt: string, + start_time: string, + end_time: string +) { + return client.get("/backend/v1/admin/log/index", { + page: page, + size: size, + admin_id: admin_id, + title: title, + opt: opt, + start_time: start_time, + end_time: end_time, + }); +} diff --git a/src/api/index.ts b/src/api/index.ts index 733df58..927f052 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -14,3 +14,4 @@ export * as upload from "./upload"; export * as user from "./user"; export * as appConfig from "./app-config"; export * as dashboard from "./dashboard"; +export * as adminLog from "./admin-log"; diff --git a/src/compenents/left-menu/index.tsx b/src/compenents/left-menu/index.tsx index 40b26c6..85f7715 100644 --- a/src/compenents/left-menu/index.tsx +++ b/src/compenents/left-menu/index.tsx @@ -91,6 +91,7 @@ const items = [ null, "admin-user-index" ), + getItem("管理日志", "/system/adminlog", null, null, null, "admin-log"), // getItem("角色配置", "/system/adminroles", null, null, null, null), ], null, diff --git a/src/main.tsx b/src/main.tsx index 98bf043..b20c456 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -7,6 +7,7 @@ import { Provider } from "react-redux"; import store from "./store"; import { ConfigProvider } from "antd"; import zhCN from "antd/locale/zh_CN"; +import "dayjs/locale/zh-cn"; import AutoScorllTop from "./AutoTop"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/src/pages/system/adminlog/index.module.less b/src/pages/system/adminlog/index.module.less new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx new file mode 100644 index 0000000..d66cd84 --- /dev/null +++ b/src/pages/system/adminlog/index.tsx @@ -0,0 +1,180 @@ +import { useEffect, useState } from "react"; +import { Table, Typography, Input, Select, Button, DatePicker } from "antd"; +import { adminLog } from "../../../api"; +// import styles from "./index.module.less"; +import type { ColumnsType } from "antd/es/table"; +import { dateWholeFormat } from "../../../utils/index"; +const { RangePicker } = DatePicker; +import moment from "moment"; + +interface DataType { + id: React.Key; + admin_id: number; + ip: string; + opt: string; + adminName: string; + module: string; + created_at: string; + title: string; +} + +const SystemLogPage = () => { + const [loading, setLoading] = useState(true); + const [page, setPage] = useState(1); + const [size, setSize] = useState(10); + const [list, setList] = useState([]); + const [total, setTotal] = useState(0); + const [refresh, setRefresh] = useState(false); + const [title, setTitle] = useState(""); + const [adminId, setAdminId] = useState(0); + const [created_at, setCreatedAt] = useState([]); + const [createdAts, setCreatedAts] = useState([]); + + useEffect(() => { + getData(); + }, [refresh, page, size]); + + const getData = () => { + setLoading(true); + adminLog + .adminLogList( + page, + size, + adminId > 0 ? adminId : null, + title, + "", + created_at[0], + created_at[1] + ) + .then((res: any) => { + setList(res.data.data); + setTotal(res.data.total); + setLoading(false); + }) + .catch((e) => { + setLoading(false); + }); + }; + + const resetData = () => { + setTitle(""); + setAdminId(0); + setPage(1); + setSize(10); + setList([]); + setCreatedAts([]); + setCreatedAt([]); + setRefresh(!refresh); + }; + + const paginationProps = { + current: page, //当前页码 + pageSize: size, + total: total, // 总条数 + onChange: (page: number, pageSize: number) => + handlePageChange(page, pageSize), //改变页码的函数 + showSizeChanger: true, + }; + + const handlePageChange = (page: number, pageSize: number) => { + setPage(page); + setSize(pageSize); + }; + + const disabledDate = (current: any) => { + return current && current >= moment().add(0, "days"); // 选择时间要大于等于当前天。若今天不能被选择,去掉等号即可。 + }; + + const columns: ColumnsType = [ + { + title: "管理员ID", + width: 100, + render: (_, record: any) => {record.admin_id}, + }, + { + title: "管理员", + width: 150, + render: (_, record: any) => {record.adminName}, + }, + { + title: "标题", + render: (_, record: any) => {record.title}, + }, + { + title: "操作模块", + width: 100, + dataIndex: "module", + render: (module: string) => {module}, + }, + { + title: "操作指令", + width: 100, + dataIndex: "opt", + render: (opt: string) => {opt}, + }, + { + title: "IP", + width: 200, + dataIndex: "ip", + render: (ip: string) => {ip}, + }, + { + title: "时间", + width: 200, + dataIndex: "created_at", + render: (created_at: string) => ( + {dateWholeFormat(created_at)} + ), + }, + ]; + + return ( +
+
+
+
+
+ { + dateString[0] += " 00:00:00"; + dateString[1] += " 23:59:59"; + setCreatedAt(dateString); + setCreatedAts(date); + }} + placeholder={["时间-开始", "时间-结束"]} + /> +
+
+ + +
+
+
+
+ record.id} + pagination={paginationProps} + /> + + + ); +}; + +export default SystemLogPage; diff --git a/src/pages/system/adminroles/compenents/create.tsx b/src/pages/system/adminroles/compenents/create.tsx index f6ca78a..cf5d0ba 100644 --- a/src/pages/system/adminroles/compenents/create.tsx +++ b/src/pages/system/adminroles/compenents/create.tsx @@ -62,6 +62,11 @@ export const SystemAdminrolesCreate: React.FC = ({ value: "管理员-n", children: [], }, + { + title: "管理员日志", + value: "管理员日志-n", + children: [], + }, { title: "管理员角色", value: "管理员角色-n", diff --git a/src/pages/system/adminroles/compenents/update.tsx b/src/pages/system/adminroles/compenents/update.tsx index 0638e2e..d2b2639 100644 --- a/src/pages/system/adminroles/compenents/update.tsx +++ b/src/pages/system/adminroles/compenents/update.tsx @@ -65,6 +65,11 @@ export const SystemAdminrolesUpdate: React.FC = ({ value: "管理员-n", children: [], }, + { + title: "管理员日志", + value: "管理员日志-n", + children: [], + }, { title: "管理员角色", value: "管理员角色-n", diff --git a/src/routes/index.tsx b/src/routes/index.tsx index de42930..b137f33 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -39,6 +39,7 @@ const SystemAdministratorPage = lazy( () => import("../pages/system/administrator") ); const SystemAdminrolesPage = lazy(() => import("../pages/system/adminroles")); +const SystemLogPage = lazy(() => import("../pages/system/adminlog")); //部门页面 const DepartmentPage = lazy(() => import("../pages/department")); //测试 @@ -152,6 +153,10 @@ const routes: RouteObject[] = [ path: "/system/adminroles", element: } />, }, + { + path: "/system/adminlog", + element: } />, + }, { path: "/department", element: } />, diff --git a/src/utils/index.ts b/src/utils/index.ts index 05c0a0c..9bc1079 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -133,3 +133,10 @@ export function checkUrl(value: any) { } return url; } + +export function dateWholeFormat(dateStr: string) { + if (!dateStr) { + return ""; + } + return moment(dateStr).format("YYYY-MM-DD HH:mm:ss"); +} From ede944217a0d5f0bd08ae2dc5d9d7dd29873044d Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 17:30:02 +0800 Subject: [PATCH 25/40] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/system/adminlog/index.tsx | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index d66cd84..aa18091 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -12,10 +12,11 @@ interface DataType { admin_id: number; ip: string; opt: string; - adminName: string; + admin_name: string; module: string; created_at: string; title: string; + ip_area: string; } const SystemLogPage = () => { @@ -87,36 +88,24 @@ const SystemLogPage = () => { const columns: ColumnsType = [ { - title: "管理员ID", + title: "ID", width: 100, - render: (_, record: any) => {record.admin_id}, + render: (_, record: any) => {record.id}, }, { title: "管理员", width: 150, - render: (_, record: any) => {record.adminName}, + render: (_, record: any) => {record.admin_name}, }, { title: "标题", render: (_, record: any) => {record.title}, }, { - title: "操作模块", - width: 100, - dataIndex: "module", - render: (module: string) => {module}, - }, - { - title: "操作指令", - width: 100, - dataIndex: "opt", - render: (opt: string) => {opt}, - }, - { - title: "IP", - width: 200, - dataIndex: "ip", - render: (ip: string) => {ip}, + title: "IP地区", + width: 250, + dataIndex: "ip_area", + render: (ip_area: string) => {ip_area}, }, { title: "时间", From 23d0e6265c08c3c4947ef3c87e5702fe6a708331 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 17:43:49 +0800 Subject: [PATCH 26/40] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adminlog/compenents/detail-dialog.tsx | 57 +++++++++++++++++++ src/pages/system/adminlog/index.tsx | 41 ++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/pages/system/adminlog/compenents/detail-dialog.tsx diff --git a/src/pages/system/adminlog/compenents/detail-dialog.tsx b/src/pages/system/adminlog/compenents/detail-dialog.tsx new file mode 100644 index 0000000..1c62d52 --- /dev/null +++ b/src/pages/system/adminlog/compenents/detail-dialog.tsx @@ -0,0 +1,57 @@ +import React, { useState, useEffect } from "react"; +import { Modal, Form } from "antd"; + +interface PropInterface { + param: string; + result: string; + open: boolean; + onCancel: () => void; +} + +export const AdminLogDetailDialog: React.FC = ({ + param, + open, + onCancel, + result, +}) => { + const [form] = Form.useForm(); + const [loading, setLoading] = useState(true); + + const onFinish = (values: any) => {}; + + const onFinishFailed = (errorInfo: any) => { + console.log("Failed:", errorInfo); + }; + + return ( + <> + onCancel()} + onCancel={() => onCancel()} + footer={null} + maskClosable={false} + > +
+
+ {param} + {result} + +
+
+ + ); +}; diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index aa18091..b60640d 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -1,9 +1,18 @@ import { useEffect, useState } from "react"; -import { Table, Typography, Input, Select, Button, DatePicker } from "antd"; +import { + Table, + Typography, + Input, + Select, + Space, + Button, + DatePicker, +} from "antd"; import { adminLog } from "../../../api"; // import styles from "./index.module.less"; import type { ColumnsType } from "antd/es/table"; import { dateWholeFormat } from "../../../utils/index"; +import { AdminLogDetailDialog } from "./compenents/detail-dialog"; const { RangePicker } = DatePicker; import moment from "moment"; @@ -17,6 +26,8 @@ interface DataType { created_at: string; title: string; ip_area: string; + param: string; + result: string; } const SystemLogPage = () => { @@ -30,6 +41,9 @@ const SystemLogPage = () => { const [adminId, setAdminId] = useState(0); const [created_at, setCreatedAt] = useState([]); const [createdAts, setCreatedAts] = useState([]); + const [param, setParam] = useState(""); + const [result, setResult] = useState(""); + const [visiable, setVisiable] = useState(false); useEffect(() => { getData(); @@ -115,6 +129,25 @@ const SystemLogPage = () => { {dateWholeFormat(created_at)} ), }, + { + title: "操作", + key: "action", + fixed: "right", + width: 160, + render: (_, record) => ( + + ), + }, ]; return ( @@ -162,6 +195,12 @@ const SystemLogPage = () => { pagination={paginationProps} /> + setVisiable(false)} + > ); }; From 5f959f37196ac6484c9fcb5777d8ea2996b0533a Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sat, 29 Jul 2023 17:58:39 +0800 Subject: [PATCH 27/40] =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/admin-log.ts | 2 +- src/api/internal/httpClient.ts | 13 +++++---- src/pages/error/index.tsx | 26 +++++++++++++++-- src/pages/system/adminlog/index.tsx | 43 ++++++++++++++++++++--------- 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/api/admin-log.ts b/src/api/admin-log.ts index f7e68f2..2fd0502 100644 --- a/src/api/admin-log.ts +++ b/src/api/admin-log.ts @@ -3,7 +3,7 @@ import client from "./internal/httpClient"; export function adminLogList( page: number, size: number, - admin_id: number | null, + admin_id: string, title: string, opt: string, start_time: string, diff --git a/src/api/internal/httpClient.ts b/src/api/internal/httpClient.ts index 8c75dee..97ca635 100644 --- a/src/api/internal/httpClient.ts +++ b/src/api/internal/httpClient.ts @@ -7,8 +7,8 @@ const GoLogin = () => { window.location.href = "/login"; }; -const GoError = () => { - window.location.href = "/error"; +const GoError = (code: number) => { + window.location.href = "/error?code=" + code; }; export class HttpClient { @@ -56,13 +56,16 @@ export class HttpClient { GoLogin(); } else if (status === 404) { // 跳转到404页面 - GoError(); + GoError(404); } else if (status === 403) { // 跳转到无权限页面 - GoError(); + GoError(403); + } else if (status === 429) { + // 跳转到429页面 + GoError(429); } else if (status === 500) { // 跳转到500异常页面 - GoError(); + GoError(500); } return Promise.reject(error.response); } diff --git a/src/pages/error/index.tsx b/src/pages/error/index.tsx index 9a1a37d..e71298f 100644 --- a/src/pages/error/index.tsx +++ b/src/pages/error/index.tsx @@ -1,15 +1,35 @@ +import { useEffect, useState } from "react"; import { Button, Result } from "antd"; -import { useNavigate } from "react-router-dom"; +import { useParams, useNavigate, useLocation } from "react-router-dom"; import styles from "./index.module.less"; const ErrorPage = () => { const navigate = useNavigate(); + const result = new URLSearchParams(useLocation().search); + const [code, setCode] = useState(Number(result.get("code"))); + const [error, setError] = useState(""); + + useEffect(() => { + setCode(Number(result.get("code"))); + }, [result.get("code")]); + + useEffect(() => { + if (code === 403) { + setError("无权限操作"); + } else if (code === 404) { + setError("URL或资源不存在"); + } else if (code === 429) { + setError("请求次数过多,请稍后再试"); + } else { + setError("系统错误"); + } + }, [code]); return ( { const [total, setTotal] = useState(0); const [refresh, setRefresh] = useState(false); const [title, setTitle] = useState(""); - const [adminId, setAdminId] = useState(0); + const [adminId, setAdminId] = useState(""); const [created_at, setCreatedAt] = useState([]); const [createdAts, setCreatedAts] = useState([]); const [param, setParam] = useState(""); @@ -55,7 +47,7 @@ const SystemLogPage = () => { .adminLogList( page, size, - adminId > 0 ? adminId : null, + adminId, title, "", created_at[0], @@ -73,7 +65,7 @@ const SystemLogPage = () => { const resetData = () => { setTitle(""); - setAdminId(0); + setAdminId(""); setPage(1); setSize(10); setList([]); @@ -107,7 +99,7 @@ const SystemLogPage = () => { render: (_, record: any) => {record.id}, }, { - title: "管理员", + title: "管理员名称", width: 150, render: (_, record: any) => {record.admin_name}, }, @@ -156,6 +148,31 @@ const SystemLogPage = () => {
+ 标题: + { + setTitle(e.target.value); + }} + allowClear + style={{ width: 160 }} + placeholder="请输入标题" + /> +
+
+ 管理员ID: + { + setAdminId(e.target.value); + }} + allowClear + style={{ width: 160 }} + placeholder="请输入管理员ID" + /> +
+
+ 时间: Date: Sat, 29 Jul 2023 18:14:47 +0800 Subject: [PATCH 28/40] =?UTF-8?q?=E8=B7=B3=E8=BD=AC=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/internal/httpClient.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/api/internal/httpClient.ts b/src/api/internal/httpClient.ts index 97ca635..db55e9d 100644 --- a/src/api/internal/httpClient.ts +++ b/src/api/internal/httpClient.ts @@ -43,7 +43,24 @@ export class HttpClient { if (code === 0) { return Promise.resolve(response); + } else if (code === 404) { + message.error(msg); + // 跳转到404页面 + GoError(404); + } else if (code === 403) { + message.error(msg); + // 跳转到无权限页面 + GoError(403); + } else if (code === 429) { + message.error(msg); + // 跳转到429页面 + GoError(429); + } else if (code === 500) { + message.error(msg); + // 跳转到500异常页面 + GoError(500); } else { + GoError(code); message.error(msg); } return Promise.reject(response); @@ -66,6 +83,8 @@ export class HttpClient { } else if (status === 500) { // 跳转到500异常页面 GoError(500); + } else { + GoError(status); } return Promise.reject(error.response); } From 4e3d6b09696e7d4c261c7a8e110928a896836144 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 12:51:58 +0800 Subject: [PATCH 29/40] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compenents/upload-courseware-button/index.tsx | 5 ++++- src/pages/course/compenents/create.tsx | 7 ++++++- src/pages/system/adminlog/index.tsx | 11 +++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/compenents/upload-courseware-button/index.tsx b/src/compenents/upload-courseware-button/index.tsx index d4dd9cb..64435c0 100644 --- a/src/compenents/upload-courseware-button/index.tsx +++ b/src/compenents/upload-courseware-button/index.tsx @@ -71,6 +71,7 @@ export const UploadCoursewareButton = (props: PropsInterface) => { file.type === "application/x-zip-compressed" || file.type === "application/octet-stream" || file.type === "application/zip" || + file.type === "application/x-rar" || file.type === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || file.type === "application/vnd.ms-excel" || @@ -188,7 +189,9 @@ export const UploadCoursewareButton = (props: PropsInterface) => {

-

请将文件拖拽到此处上传

+

+ 支持word、excel、ppt、pdf、zip、txt格式文件 +

支持一次上传多个文件

diff --git a/src/pages/course/compenents/create.tsx b/src/pages/course/compenents/create.tsx index c67d186..cba360e 100644 --- a/src/pages/course/compenents/create.tsx +++ b/src/pages/course/compenents/create.tsx @@ -84,6 +84,8 @@ export const CourseCreate: React.FC = ({ setHours([]); setTreeData([]); setAttachmentData([]); + setAttachments([]); + setShowDrop(false); }, [form, open]); const getParams = () => { @@ -793,7 +795,10 @@ export const CourseCreate: React.FC = ({ className={showDrop ? "drop-item active" : "drop-item"} onClick={() => setShowDrop(!showDrop)} > - + (课程简介、课件)
diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index b05c597..36c24d4 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -93,18 +93,13 @@ const SystemLogPage = () => { }; const columns: ColumnsType = [ - { - title: "ID", - width: 100, - render: (_, record: any) => {record.id}, - }, { title: "管理员名称", width: 150, render: (_, record: any) => {record.admin_name}, }, { - title: "标题", + title: "操作", render: (_, record: any) => {record.title}, }, { @@ -148,7 +143,7 @@ const SystemLogPage = () => {
- 标题: + 操作: { @@ -156,7 +151,7 @@ const SystemLogPage = () => { }} allowClear style={{ width: 160 }} - placeholder="请输入标题" + placeholder="请输入操作" />
From 7af7fccc3a06465a0bc9e98bb2518bd1811db59b Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 12:57:01 +0800 Subject: [PATCH 30/40] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.less b/src/index.less index 5858831..090e205 100644 --- a/src/index.less +++ b/src/index.less @@ -594,8 +594,7 @@ textarea.ant-input { .list-select-column-box { .ant-checkbox-wrapper { - margin-inline-start: 0px; - height: 38px; + height: 38px !important; align-items: center !important; } @@ -604,10 +603,12 @@ textarea.ant-input { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + line-height: 38px; } .video-time { width: 80px; display: flex; + line-height: 38px; flex-direction: row-reverse; } } @@ -683,4 +684,3 @@ textarea.ant-input { line-height: 32px; } } - From 761b8cdf023a9c5121e356e221de85eab5d37990 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 13:01:48 +0800 Subject: [PATCH 31/40] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/admin-log.ts | 2 ++ src/pages/system/adminlog/index.tsx | 27 +++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/api/admin-log.ts b/src/api/admin-log.ts index 2fd0502..05cfc6f 100644 --- a/src/api/admin-log.ts +++ b/src/api/admin-log.ts @@ -4,6 +4,7 @@ export function adminLogList( page: number, size: number, admin_id: string, + admin_name: string, title: string, opt: string, start_time: string, @@ -13,6 +14,7 @@ export function adminLogList( page: page, size: size, admin_id: admin_id, + admin_name: admin_name, title: title, opt: opt, start_time: start_time, diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index 36c24d4..e37bc66 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -31,6 +31,7 @@ const SystemLogPage = () => { const [refresh, setRefresh] = useState(false); const [title, setTitle] = useState(""); const [adminId, setAdminId] = useState(""); + const [adminName, setAdminName] = useState(""); const [created_at, setCreatedAt] = useState([]); const [createdAts, setCreatedAts] = useState([]); const [param, setParam] = useState(""); @@ -48,6 +49,7 @@ const SystemLogPage = () => { page, size, adminId, + adminName, title, "", created_at[0], @@ -66,6 +68,7 @@ const SystemLogPage = () => { const resetData = () => { setTitle(""); setAdminId(""); + setAdminName(""); setPage(1); setSize(10); setList([]); @@ -142,6 +145,18 @@ const SystemLogPage = () => {
+
+ 管理员名称: + { + setAdminName(e.target.value); + }} + allowClear + style={{ width: 160 }} + placeholder="请输入管理员名称" + /> +
操作: { placeholder="请输入操作" />
-
- 管理员ID: - { - setAdminId(e.target.value); - }} - allowClear - style={{ width: 160 }} - placeholder="请输入管理员ID" - /> -
时间: Date: Sun, 30 Jul 2023 13:04:54 +0800 Subject: [PATCH 32/40] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/admin-log.ts | 2 -- src/pages/system/adminlog/index.tsx | 1 - 2 files changed, 3 deletions(-) diff --git a/src/api/admin-log.ts b/src/api/admin-log.ts index 05cfc6f..806c607 100644 --- a/src/api/admin-log.ts +++ b/src/api/admin-log.ts @@ -3,7 +3,6 @@ import client from "./internal/httpClient"; export function adminLogList( page: number, size: number, - admin_id: string, admin_name: string, title: string, opt: string, @@ -13,7 +12,6 @@ export function adminLogList( return client.get("/backend/v1/admin/log/index", { page: page, size: size, - admin_id: admin_id, admin_name: admin_name, title: title, opt: opt, diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index e37bc66..4c63253 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -48,7 +48,6 @@ const SystemLogPage = () => { .adminLogList( page, size, - adminId, adminName, title, "", From dc616d482923339da259061242faaf6b5fc0d783 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 15:27:06 +0800 Subject: [PATCH 33/40] =?UTF-8?q?=E7=BA=BF=E4=B8=8A=E8=AF=BE=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E8=A7=86=E9=A2=91=E3=80=81=E8=AF=BE=E4=BB=B6=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E5=BC=B9=E7=AA=97=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compenents/upload-courseware-button/index.tsx | 7 ++++--- src/index.less | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compenents/upload-courseware-button/index.tsx b/src/compenents/upload-courseware-button/index.tsx index 64435c0..741b1ae 100644 --- a/src/compenents/upload-courseware-button/index.tsx +++ b/src/compenents/upload-courseware-button/index.tsx @@ -189,10 +189,11 @@ export const UploadCoursewareButton = (props: PropsInterface) => {

-

- 支持word、excel、ppt、pdf、zip、txt格式文件 +

请将文件拖拽到此处上传

+

+ 支持一次上传多个 / + 支持word、excel、ppt、pdf、zip、rar、txt格式文件

-

支持一次上传多个文件

diff --git a/src/index.less b/src/index.less index 090e205..e9f6e6d 100644 --- a/src/index.less +++ b/src/index.less @@ -594,8 +594,9 @@ textarea.ant-input { .list-select-column-box { .ant-checkbox-wrapper { + display: flex; height: 38px !important; - align-items: center !important; + align-items: center; } .video-title { @@ -603,12 +604,10 @@ textarea.ant-input { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - line-height: 38px; } .video-time { width: 80px; display: flex; - line-height: 38px; flex-direction: row-reverse; } } From 862ee4e5ae70a4cd73d5adae30c4d237d80170ca Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 16:20:27 +0800 Subject: [PATCH 34/40] =?UTF-8?q?=E5=8F=AF=E8=A7=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/resource/courseware/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/resource/courseware/index.tsx b/src/pages/resource/courseware/index.tsx index a889b38..fe49a49 100644 --- a/src/pages/resource/courseware/index.tsx +++ b/src/pages/resource/courseware/index.tsx @@ -95,8 +95,7 @@ const ResourceCoursewarePage = () => { const columns: ColumnsType = [ { title: "课件名称", - dataIndex: "name", - render: (name: string) => ( + render: (_, record: any) => (
{ color: "rgba(0,0,0,0.3)", }} /> - {name} + + {record.name}.{record.extension} +
), }, From 5ca6c18513abc0a9ad8e7efc66db23e034927ded Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 16:40:25 +0800 Subject: [PATCH 35/40] =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=97=B6=E5=8C=BA=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/system/adminlog/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index 4c63253..05cbb5a 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -176,8 +176,8 @@ const SystemLogPage = () => { value={createdAts} style={{ marginLeft: 10 }} onChange={(date, dateString) => { - dateString[0] += " 00:00:00"; - dateString[1] += " 23:59:59"; + dateString[0] += "T00:00:00.000+00:00"; + dateString[1] += "T23:59:59.000+00:00"; setCreatedAt(dateString); setCreatedAts(date); }} From 8e5c07263472dc61083570c647fb17087ac9d254 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Sun, 30 Jul 2023 16:58:44 +0800 Subject: [PATCH 36/40] =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=97=B6=E5=8C=BA=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/system/adminlog/index.tsx | 8 +++++--- src/utils/index.ts | 10 ++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/pages/system/adminlog/index.tsx b/src/pages/system/adminlog/index.tsx index 05cbb5a..754d2d1 100644 --- a/src/pages/system/adminlog/index.tsx +++ b/src/pages/system/adminlog/index.tsx @@ -3,7 +3,7 @@ import { Table, Typography, Input, Button, DatePicker } from "antd"; import { adminLog } from "../../../api"; // import styles from "./index.module.less"; import type { ColumnsType } from "antd/es/table"; -import { dateWholeFormat } from "../../../utils/index"; +import { dateWholeFormat, transUtcTime } from "../../../utils/index"; import { AdminLogDetailDialog } from "./compenents/detail-dialog"; const { RangePicker } = DatePicker; import moment from "moment"; @@ -176,8 +176,10 @@ const SystemLogPage = () => { value={createdAts} style={{ marginLeft: 10 }} onChange={(date, dateString) => { - dateString[0] += "T00:00:00.000+00:00"; - dateString[1] += "T23:59:59.000+00:00"; + let date1 = dateString[0] + " 00:00:00"; + let date2 = dateString[1] + " 23:59:59"; + dateString[0] = transUtcTime(date1); + dateString[1] = transUtcTime(date2); setCreatedAt(dateString); setCreatedAts(date); }} diff --git a/src/utils/index.ts b/src/utils/index.ts index 9bc1079..b37888b 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -140,3 +140,13 @@ export function dateWholeFormat(dateStr: string) { } return moment(dateStr).format("YYYY-MM-DD HH:mm:ss"); } + +export function transUtcTime(value: string) { + const specifiedTime = value; + // 创建一个新的Date对象,传入指定时间 + const specifiedDate = new Date(specifiedTime); + //将指定时间转换为UTC+0时间 + const utcTime = specifiedDate.toISOString(); + + return utcTime; +} From 2ce6292f446a6c29ec319cf5f2f15c97aac8377a Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Mon, 31 Jul 2023 10:44:32 +0800 Subject: [PATCH 37/40] =?UTF-8?q?=E9=80=89=E6=8B=A9=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E3=80=81=E8=AF=BE=E4=BB=B6=E7=BB=84=E4=BB=B6=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/internal/httpClient.ts | 2 +- src/compenents/select-attachment/index.tsx | 13 +- src/compenents/select-resource/index.tsx | 13 +- .../upload-courseware-sub/index.tsx | 220 ++++++++-------- src/compenents/upload-video-sub/index.tsx | 234 ++++++++---------- src/index.less | 17 +- .../course/compenents/attachment-update.tsx | 18 +- src/pages/course/compenents/hour-update.tsx | 36 ++- 8 files changed, 247 insertions(+), 306 deletions(-) diff --git a/src/api/internal/httpClient.ts b/src/api/internal/httpClient.ts index db55e9d..b3856ef 100644 --- a/src/api/internal/httpClient.ts +++ b/src/api/internal/httpClient.ts @@ -8,7 +8,7 @@ const GoLogin = () => { }; const GoError = (code: number) => { - window.location.href = "/error?code=" + code; + // window.location.href = "/error?code=" + code; }; export class HttpClient { diff --git a/src/compenents/select-attachment/index.tsx b/src/compenents/select-attachment/index.tsx index 2129965..8739670 100644 --- a/src/compenents/select-attachment/index.tsx +++ b/src/compenents/select-attachment/index.tsx @@ -1,16 +1,9 @@ import { useEffect, useState } from "react"; -import { Button, Row, Modal, message, Tabs } from "antd"; +import { Row, Modal, Tabs } from "antd"; import styles from "./index.module.less"; import { UploadCoursewareSub } from "../../compenents"; import type { TabsProps } from "antd"; -interface VideoItem { - id: number; - category_id: number; - name: string; - duration: number; -} - interface PropsInterface { defaultKeys: any[]; open: boolean; @@ -24,6 +17,10 @@ export const SelectAttachment = (props: PropsInterface) => { const [selectKeys, setSelectKeys] = useState([]); const [selectVideos, setSelectVideos] = useState([]); + useEffect(() => { + setRefresh(!refresh); + }, [props.open]); + const items: TabsProps["items"] = [ { key: "1", diff --git a/src/compenents/select-resource/index.tsx b/src/compenents/select-resource/index.tsx index e7f9525..017cf30 100644 --- a/src/compenents/select-resource/index.tsx +++ b/src/compenents/select-resource/index.tsx @@ -1,16 +1,9 @@ import { useEffect, useState } from "react"; -import { Button, Row, Modal, message, Tabs } from "antd"; +import { Row, Modal, Tabs } from "antd"; import styles from "./index.module.less"; import { UploadVideoSub } from "../../compenents"; import type { TabsProps } from "antd"; -interface VideoItem { - id: number; - category_id: number; - name: string; - duration: number; -} - interface PropsInterface { defaultKeys: any[]; open: boolean; @@ -24,6 +17,10 @@ export const SelectResource = (props: PropsInterface) => { const [selectKeys, setSelectKeys] = useState([]); const [selectVideos, setSelectVideos] = useState([]); + useEffect(() => { + setRefresh(!refresh); + }, [props.open]); + const items: TabsProps["items"] = [ { key: "1", diff --git a/src/compenents/upload-courseware-sub/index.tsx b/src/compenents/upload-courseware-sub/index.tsx index 23d7985..0222640 100644 --- a/src/compenents/upload-courseware-sub/index.tsx +++ b/src/compenents/upload-courseware-sub/index.tsx @@ -1,17 +1,32 @@ import { useEffect, useState } from "react"; -import { Checkbox, Row, Col, Empty, message, Pagination } from "antd"; +import { Row, Col, Empty, Table, Pagination } from "antd"; +import type { ColumnsType } from "antd/es/table"; import { resource } from "../../api"; import styles from "./index.module.less"; import { TreeCategory, UploadCoursewareButton } from "../../compenents"; -import type { CheckboxChangeEvent } from "antd/es/checkbox"; -import type { CheckboxValueType } from "antd/es/checkbox/Group"; - -const CheckboxGroup = Checkbox.Group; interface VideoItem { id: number; - category_id: number; name: string; + created_at: string; + type: string; + url: string; + path: string; + size: number; + extension: string; + admin_id: number; +} + +interface DataType { + id: React.Key; + name: string; + created_at: string; + type: string; + url: string; + path: string; + size: number; + extension: string; + admin_id: number; } interface PropsInterface { @@ -30,14 +45,21 @@ export const UploadCoursewareSub = (props: PropsInterface) => { const [page, setPage] = useState(1); const [size, setSize] = useState(10); const [total, setTotal] = useState(0); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [plainOptions, setPlainOptions] = useState([]); - const [checkedList, setCheckedList] = useState([]); - const [indeterminate, setIndeterminate] = useState(false); - const [checkAll, setCheckAll] = useState(false); + // 加载列表 + useEffect(() => { + getvideoList(); + }, [props.open, category_ids, refresh, page, size]); + + useEffect(() => { + if (props.defaultCheckedList.length > 0) { + setSelectedRowKeys(props.defaultCheckedList); + } + }, [props.defaultCheckedList]); // 获取列表 - const getvideoList = (defaultKeys: any[]) => { + const getvideoList = () => { let categoryIds = category_ids.join(","); resource .resourceList( @@ -53,42 +75,12 @@ export const UploadCoursewareSub = (props: PropsInterface) => { setTotal(res.data.result.total); setExistingTypes(res.data.existing_types); setVideoList(res.data.result.data); - let data = res.data.result.data; - const arr = []; - for (let i = 0; i < data.length; i++) { - arr.push({ - label: ( -
- -
{data[i].name}
-
{data[i].type}
-
- ), - value: data[i].id, - disabled: false, - }); - } - if (defaultKeys.length > 0 && arr.length > 0) { - for (let i = 0; i < defaultKeys.length; i++) { - for (let j = 0; j < arr.length; j++) { - if (arr[j].value === defaultKeys[i]) { - arr[j].disabled = true; - } - } - } - } - setPlainOptions(arr); }) .catch((err) => { console.log("错误,", err); }); }; + // 重置列表 const resetVideoList = () => { setPage(1); @@ -96,76 +88,64 @@ export const UploadCoursewareSub = (props: PropsInterface) => { setRefresh(!refresh); }; - // 加载列表 - useEffect(() => { - const arr = [...props.defaultCheckedList]; - setCheckedList(arr); - if (arr.length === 0) { - setIndeterminate(false); - setCheckAll(false); - } - getvideoList(arr); - }, [props.open, props.defaultCheckedList, category_ids, refresh, page, size]); - - const onChange = (list: CheckboxValueType[]) => { - setCheckedList(list); - setIndeterminate(!!list.length && list.length < plainOptions.length); - setCheckAll(list.length === plainOptions.length); - const defalut = [...props.defaultCheckedList]; - let localKeys: any = []; - list.map((item: any) => { - if (defalut.indexOf(item) === -1) { - localKeys.push(item); - } - }); - - let arrVideos: any = []; - - for (let i = 0; i < localKeys.length; i++) { - videoList.map((item: any, index: number) => { - if (item.id === localKeys[i]) { - arrVideos.push({ - name: item.name, - type: item.type, - rid: item.id, - disabled: plainOptions[index].disabled, - }); - } - }); - } - props.onSelected(localKeys, arrVideos); + const paginationProps = { + current: page, //当前页码 + pageSize: size, + total: total, // 总条数 + onChange: (page: number, pageSize: number) => + handlePageChange(page, pageSize), //改变页码的函数 + showSizeChanger: true, }; - const onCheckAllChange = (e: CheckboxChangeEvent) => { - const arr = plainOptions.map((item: any) => item.value); - setCheckedList(e.target.checked ? arr : []); - setIndeterminate(false); - setCheckAll(e.target.checked); - const defalut = [...props.defaultCheckedList]; - let localKeys: any = []; - arr.map((item: any) => { - if (defalut.indexOf(item) === -1) { - localKeys.push(item); - } - }); - let arrVideos: any = []; - for (let i = 0; i < localKeys.length; i++) { - videoList.map((item: any, index: number) => { - if (item.id === localKeys[i]) { - arrVideos.push({ - name: item.name, - type: item.type, - rid: item.id, - disabled: plainOptions[index].disabled, - }); + const handlePageChange = (page: number, pageSize: number) => { + setPage(page); + setSize(pageSize); + }; + + const columns: ColumnsType = [ + { + title: "课件", + render: (_, record: any) => ( +
+ +
{record.name}
+
+ ), + }, + { + title: "类型", + render: (_, record: any) => {record.type}, + }, + ]; + + const rowSelection = { + selectedRowKeys: selectedRowKeys, + onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => { + let row: any = selectedRows; + let arrVideos: any = []; + if (row) { + for (var i = 0; i < row.length; i++) { + if (props.defaultCheckedList.indexOf(row[i].id) === -1) { + arrVideos.push({ + name: row[i].name, + type: row[i].type, + rid: row[i].id, + }); + } } - }); - } - if (e.target.checked) { - props.onSelected(localKeys, arrVideos); - } else { - props.onSelected([], []); - } + props.onSelected(selectedRowKeys, arrVideos); + } + setSelectedRowKeys(selectedRowKeys); + }, + getCheckboxProps: (record: any) => ({ + disabled: props.defaultCheckedList.indexOf(record.id) !== -1, //禁用的条件 + }), }; return ( @@ -198,18 +178,16 @@ export const UploadCoursewareSub = (props: PropsInterface) => { )} {videoList.length > 0 && (
- - 全选 - - record.id} />
)} diff --git a/src/compenents/upload-video-sub/index.tsx b/src/compenents/upload-video-sub/index.tsx index 530e63c..547b9a9 100644 --- a/src/compenents/upload-video-sub/index.tsx +++ b/src/compenents/upload-video-sub/index.tsx @@ -1,19 +1,33 @@ import { useEffect, useState } from "react"; -import { Checkbox, Row, Col, Empty, message, Pagination } from "antd"; +import { Row, Col, Empty, Table, Pagination } from "antd"; +import type { ColumnsType } from "antd/es/table"; import { resource } from "../../api"; import styles from "./index.module.less"; import { UploadVideoButton } from "../upload-video-button"; import { DurationText, TreeCategory } from "../../compenents"; -import type { CheckboxChangeEvent } from "antd/es/checkbox"; -import type { CheckboxValueType } from "antd/es/checkbox/Group"; - -const CheckboxGroup = Checkbox.Group; interface VideoItem { id: number; - category_id: number; name: string; - duration: number; + created_at: string; + type: string; + url: string; + path: string; + size: number; + extension: string; + admin_id: number; +} + +interface DataType { + id: React.Key; + name: string; + created_at: string; + type: string; + url: string; + path: string; + size: number; + extension: string; + admin_id: number; } interface PropsInterface { @@ -32,14 +46,21 @@ export const UploadVideoSub = (props: PropsInterface) => { const [page, setPage] = useState(1); const [size, setSize] = useState(10); const [total, setTotal] = useState(0); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [plainOptions, setPlainOptions] = useState([]); - const [checkedList, setCheckedList] = useState([]); - const [indeterminate, setIndeterminate] = useState(false); - const [checkAll, setCheckAll] = useState(false); + // 加载列表 + useEffect(() => { + getvideoList(); + }, [props.open, category_ids, refresh, page, size]); + + useEffect(() => { + if (props.defaultCheckedList.length > 0) { + setSelectedRowKeys(props.defaultCheckedList); + } + }, [props.defaultCheckedList]); // 获取列表 - const getvideoList = (defaultKeys: any[]) => { + const getvideoList = () => { let categoryIds = category_ids.join(","); resource .resourceList(page, size, "", "", "", "VIDEO", categoryIds) @@ -47,46 +68,12 @@ export const UploadVideoSub = (props: PropsInterface) => { setTotal(res.data.result.total); setVideoExtra(res.data.videos_extra); setVideoList(res.data.result.data); - let data = res.data.result.data; - const arr = []; - for (let i = 0; i < data.length; i++) { - arr.push({ - label: ( -
- -
{data[i].name}
-
- -
-
- ), - value: data[i].id, - disabled: false, - }); - } - if (defaultKeys.length > 0 && arr.length > 0) { - for (let i = 0; i < defaultKeys.length; i++) { - for (let j = 0; j < arr.length; j++) { - if (arr[j].value === defaultKeys[i]) { - arr[j].disabled = true; - } - } - } - } - setPlainOptions(arr); }) .catch((err) => { console.log("错误,", err); }); }; + // 重置列表 const resetVideoList = () => { setPage(1); @@ -94,78 +81,71 @@ export const UploadVideoSub = (props: PropsInterface) => { setRefresh(!refresh); }; - // 加载列表 - useEffect(() => { - const arr = [...props.defaultCheckedList]; - setCheckedList(arr); - if (arr.length === 0) { - setIndeterminate(false); - setCheckAll(false); - } - getvideoList(arr); - }, [props.open, props.defaultCheckedList, category_ids, refresh, page, size]); - - const onChange = (list: CheckboxValueType[]) => { - setCheckedList(list); - setIndeterminate(!!list.length && list.length < plainOptions.length); - setCheckAll(list.length === plainOptions.length); - const defalut = [...props.defaultCheckedList]; - let localKeys: any = []; - list.map((item: any) => { - if (defalut.indexOf(item) === -1) { - localKeys.push(item); - } - }); - - let arrVideos: any = []; - - for (let i = 0; i < localKeys.length; i++) { - videoList.map((item: any, index: number) => { - if (item.id === localKeys[i]) { - arrVideos.push({ - name: item.name, - type: item.type, - rid: item.id, - duration: videosExtra[item.id].duration, - disabled: plainOptions[index].disabled, - }); - } - }); - } - props.onSelected(localKeys, arrVideos); + const paginationProps = { + current: page, //当前页码 + pageSize: size, + total: total, // 总条数 + onChange: (page: number, pageSize: number) => + handlePageChange(page, pageSize), //改变页码的函数 + showSizeChanger: true, }; - const onCheckAllChange = (e: CheckboxChangeEvent) => { - const arr = plainOptions.map((item: any) => item.value); - setCheckedList(e.target.checked ? arr : []); - setIndeterminate(false); - setCheckAll(e.target.checked); - const defalut = [...props.defaultCheckedList]; - let localKeys: any = []; - arr.map((item: any) => { - if (defalut.indexOf(item) === -1) { - localKeys.push(item); - } - }); - let arrVideos: any = []; - for (let i = 0; i < localKeys.length; i++) { - videoList.map((item: any, index: number) => { - if (item.id === localKeys[i]) { - arrVideos.push({ - name: item.name, - type: item.type, - rid: item.id, - duration: videosExtra[item.id].duration, - disabled: plainOptions[index].disabled, - }); + const handlePageChange = (page: number, pageSize: number) => { + setPage(page); + setSize(pageSize); + }; + + const columns: ColumnsType = [ + { + title: "视频", + render: (_, record: any) => ( +
+ +
{record.name}
+
+ ), + }, + { + title: "时长", + render: (_, record: any) => ( +
+ +
+ ), + }, + ]; + + const rowSelection = { + selectedRowKeys: selectedRowKeys, + onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => { + let row: any = selectedRows; + let arrVideos: any = []; + if (row) { + for (var i = 0; i < row.length; i++) { + if (props.defaultCheckedList.indexOf(row[i].id) === -1) { + arrVideos.push({ + name: row[i].name, + type: row[i].type, + rid: row[i].id, + duration: videosExtra[row[i].id].duration, + }); + } } - }); - } - if (e.target.checked) { - props.onSelected(localKeys, arrVideos); - } else { - props.onSelected([], []); - } + props.onSelected(selectedRowKeys, arrVideos); + } + setSelectedRowKeys(selectedRowKeys); + }, + getCheckboxProps: (record: any) => ({ + disabled: props.defaultCheckedList.indexOf(record.id) !== -1, //禁用的条件 + }), }; return ( @@ -198,18 +178,16 @@ export const UploadVideoSub = (props: PropsInterface) => { )} {videoList.length > 0 && (
- - 全选 - - record.id} />
)} diff --git a/src/index.less b/src/index.less index e9f6e6d..5251d39 100644 --- a/src/index.less +++ b/src/index.less @@ -593,23 +593,18 @@ textarea.ant-input { } .list-select-column-box { - .ant-checkbox-wrapper { - display: flex; - height: 38px !important; - align-items: center; + width: 100%; + height: auto; + float: left; + .ant-table-cell { + padding: 0px 0px; } - .video-title { - width: 390px; + width: 360px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } - .video-time { - width: 80px; - display: flex; - flex-direction: row-reverse; - } } .image-list-box { diff --git a/src/pages/course/compenents/attachment-update.tsx b/src/pages/course/compenents/attachment-update.tsx index a21cde4..8b1ccb1 100644 --- a/src/pages/course/compenents/attachment-update.tsx +++ b/src/pages/course/compenents/attachment-update.tsx @@ -69,19 +69,19 @@ export const CourseAttachmentUpdate: React.FC = ({ 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, - }); - } + hours.push({ + sort: attachmentData.length + i, + title: videos[i].name, + type: videos[i].type, + rid: videos[i].rid, + }); } if (hours.length === 0) { - message.error("请选择视频"); + message.error("请选择课件"); return; } + console.log(hours); + courseAttachment .storeCourseAttachmentMulti(id, hours) .then((res: any) => { diff --git a/src/pages/course/compenents/hour-update.tsx b/src/pages/course/compenents/hour-update.tsx index 2c91660..d4b8b9f 100644 --- a/src/pages/course/compenents/hour-update.tsx +++ b/src/pages/course/compenents/hour-update.tsx @@ -100,16 +100,14 @@ export const CourseHourUpdate: React.FC = ({ const selectData = (arr: any, videos: any) => { const hours: any = []; for (let i = 0; i < videos.length; i++) { - if (videos[i].disabled === false) { - hours.push({ - chapter_id: 0, - sort: treeData.length + i, - title: videos[i].name, - type: videos[i].type, - duration: videos[i].duration, - rid: videos[i].rid, - }); - } + hours.push({ + chapter_id: 0, + sort: treeData.length + i, + title: videos[i].name, + type: videos[i].type, + duration: videos[i].duration, + rid: videos[i].rid, + }); } if (hours.length === 0) { message.error("请选择视频"); @@ -135,16 +133,14 @@ export const CourseHourUpdate: React.FC = ({ } const hours: any = []; for (let i = 0; i < videos.length; i++) { - if (videos[i].disabled === false) { - hours.push({ - chapter_id: data[addvideoCurrent].id, - sort: data[addvideoCurrent].hours.length + i, - title: videos[i].name, - type: videos[i].type, - duration: videos[i].duration, - rid: videos[i].rid, - }); - } + hours.push({ + chapter_id: data[addvideoCurrent].id, + sort: data[addvideoCurrent].hours.length + i, + title: videos[i].name, + type: videos[i].type, + duration: videos[i].duration, + rid: videos[i].rid, + }); } if (hours.length === 0) { message.error("请选择视频"); From 242d29bf5e6f4620097a7efda8e14503cadcd12b Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Mon, 31 Jul 2023 10:48:43 +0800 Subject: [PATCH 38/40] =?UTF-8?q?=E8=A7=86=E9=A2=91=E3=80=81=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=88=97=E8=A1=A8=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../course/compenents/attachment-update.tsx | 1 - src/pages/resource/images/index.tsx | 18 ++++++++++-------- src/pages/resource/videos/index.tsx | 6 +++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/pages/course/compenents/attachment-update.tsx b/src/pages/course/compenents/attachment-update.tsx index 8b1ccb1..233d5fe 100644 --- a/src/pages/course/compenents/attachment-update.tsx +++ b/src/pages/course/compenents/attachment-update.tsx @@ -80,7 +80,6 @@ export const CourseAttachmentUpdate: React.FC = ({ message.error("请选择课件"); return; } - console.log(hours); courseAttachment .storeCourseAttachmentMulti(id, hours) diff --git a/src/pages/resource/images/index.tsx b/src/pages/resource/images/index.tsx index f6c9d8f..99d94dc 100644 --- a/src/pages/resource/images/index.tsx +++ b/src/pages/resource/images/index.tsx @@ -183,24 +183,25 @@ const ResourceImagesPage = () => {
- { - resetImageList(); - }} - >
+ { + resetImageList(); + }} + > {selectKey.length > 0 && ( - )} {imageList.length !== 0 && ( <> -
+
diff --git a/src/pages/resource/videos/index.tsx b/src/pages/resource/videos/index.tsx index 4d83e71..4376509 100644 --- a/src/pages/resource/videos/index.tsx +++ b/src/pages/resource/videos/index.tsx @@ -286,11 +286,9 @@ const ResourceVideosPage = () => { resetVideoList(); }} > - -
+
{multiConfig ? ( From 2fa7a1dd4e8258f27d27e28d0cf9047407f1ad8f Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Mon, 31 Jul 2023 11:03:51 +0800 Subject: [PATCH 39/40] =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=85=A8=E9=80=89=E6=8C=89=E9=92=AE=E9=80=BB=E8=BE=91=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/resource/images/index.tsx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pages/resource/images/index.tsx b/src/pages/resource/images/index.tsx index 99d94dc..bc4f09f 100644 --- a/src/pages/resource/images/index.tsx +++ b/src/pages/resource/images/index.tsx @@ -192,23 +192,23 @@ const ResourceImagesPage = () => { > {selectKey.length > 0 && ( + )} + {selectKey.length === 0 && ( + )} {imageList.length !== 0 && ( - <> - - - + )}
From e95343fe0ab7df6a17d724f59ac8852b0e7f5498 Mon Sep 17 00:00:00 2001 From: unknown <18119604035@163.com> Date: Mon, 31 Jul 2023 11:06:45 +0800 Subject: [PATCH 40/40] =?UTF-8?q?=E9=80=89=E6=8B=A9=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E3=80=81=E8=AF=BE=E4=BB=B6=E7=BB=84=E4=BB=B6=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../upload-courseware-sub/index.tsx | 23 +------------------ src/compenents/upload-video-sub/index.tsx | 23 +------------------ 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/src/compenents/upload-courseware-sub/index.tsx b/src/compenents/upload-courseware-sub/index.tsx index 0222640..d2d4689 100644 --- a/src/compenents/upload-courseware-sub/index.tsx +++ b/src/compenents/upload-courseware-sub/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { Row, Col, Empty, Table, Pagination } from "antd"; +import { Row, Col, Empty, Table } from "antd"; import type { ColumnsType } from "antd/es/table"; import { resource } from "../../api"; import styles from "./index.module.less"; @@ -192,27 +192,6 @@ export const UploadCoursewareSub = (props: PropsInterface) => { )} - - {videoList.length > 0 && total > 10 && ( -
- { - setPage(currentPage); - setSize(currentSize); - }} - defaultCurrent={page} - total={total} - /> - - )} - diff --git a/src/compenents/upload-video-sub/index.tsx b/src/compenents/upload-video-sub/index.tsx index 547b9a9..b9fe6db 100644 --- a/src/compenents/upload-video-sub/index.tsx +++ b/src/compenents/upload-video-sub/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { Row, Col, Empty, Table, Pagination } from "antd"; +import { Row, Col, Empty, Table } from "antd"; import type { ColumnsType } from "antd/es/table"; import { resource } from "../../api"; import styles from "./index.module.less"; @@ -192,27 +192,6 @@ export const UploadVideoSub = (props: PropsInterface) => { )} - - {videoList.length > 0 && total > 10 && ( - - { - setPage(currentPage); - setSize(currentSize); - }} - defaultCurrent={page} - total={total} - /> - - )} -