mirror of
https://github.com/PlayEdu/backend
synced 2025-07-23 01:59:34 +08:00
commit
beb5a011f5
@ -34,8 +34,8 @@ export function storeCourse(
|
|||||||
isRequired: number,
|
isRequired: number,
|
||||||
depIds: number[],
|
depIds: number[],
|
||||||
categoryIds: number[],
|
categoryIds: number[],
|
||||||
chapters: number[],
|
chapters: any[],
|
||||||
hours: number[],
|
hours: any[],
|
||||||
attachments: any[]
|
attachments: any[]
|
||||||
) {
|
) {
|
||||||
return client.post("/backend/v1/course/create", {
|
return client.post("/backend/v1/course/create", {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Row, Modal, Tabs, Spin } from "antd";
|
import { Row, Modal, Tabs } from "antd";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { UploadCoursewareSub } from "../../compenents";
|
import { UploadCoursewareSub } from "../../compenents";
|
||||||
import type { TabsProps } from "antd";
|
import type { TabsProps } from "antd";
|
||||||
@ -11,15 +11,20 @@ interface PropsInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type selAttachmentModel = {
|
||||||
|
name: string;
|
||||||
|
rid: number;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const SelectAttachment = (props: PropsInterface) => {
|
export const SelectAttachment = (props: PropsInterface) => {
|
||||||
const [refresh, setRefresh] = useState(true);
|
const [refresh, setRefresh] = useState(true);
|
||||||
const [init, setInit] = useState(true);
|
|
||||||
const [tabKey, setTabKey] = useState(1);
|
const [tabKey, setTabKey] = useState(1);
|
||||||
const [selectKeys, setSelectKeys] = useState<any>([]);
|
const [selectKeys, setSelectKeys] = useState<number[]>([]);
|
||||||
const [selectVideos, setSelectVideos] = useState<any>([]);
|
const [selectVideos, setSelectVideos] = useState<selAttachmentModel[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInit(true);
|
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}, [props.open]);
|
}, [props.open]);
|
||||||
|
|
||||||
@ -28,23 +33,15 @@ export const SelectAttachment = (props: PropsInterface) => {
|
|||||||
key: "1",
|
key: "1",
|
||||||
label: `课件`,
|
label: `课件`,
|
||||||
children: (
|
children: (
|
||||||
<div
|
<UploadCoursewareSub
|
||||||
className="float-left"
|
label="课件"
|
||||||
style={{ display: init ? "none" : "block" }}
|
defaultCheckedList={props.defaultKeys}
|
||||||
>
|
open={refresh}
|
||||||
<UploadCoursewareSub
|
onSelected={(arr: any[], videos: any[]) => {
|
||||||
label="课件"
|
setSelectKeys(arr);
|
||||||
defaultCheckedList={props.defaultKeys}
|
setSelectVideos(videos);
|
||||||
open={refresh}
|
}}
|
||||||
onSelected={(arr: any[], videos: any[]) => {
|
/>
|
||||||
setSelectKeys(arr);
|
|
||||||
setSelectVideos(videos);
|
|
||||||
}}
|
|
||||||
onSuccess={() => {
|
|
||||||
setInit(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -77,11 +74,6 @@ export const SelectAttachment = (props: PropsInterface) => {
|
|||||||
<Row>
|
<Row>
|
||||||
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
|
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
|
||||||
</Row>
|
</Row>
|
||||||
{init && (
|
|
||||||
<div className="float-left text-center mt-30">
|
|
||||||
<Spin></Spin>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Modal>
|
</Modal>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Row, Modal, Tabs, Spin } from "antd";
|
import { Row, Modal, Tabs } from "antd";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { UploadVideoSub } from "../../compenents";
|
import { UploadVideoSub } from "../../compenents";
|
||||||
import type { TabsProps } from "antd";
|
import type { TabsProps } from "antd";
|
||||||
@ -11,15 +11,20 @@ interface PropsInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type selVideosModel = {
|
||||||
|
name: string;
|
||||||
|
rid: number;
|
||||||
|
type: string;
|
||||||
|
duration: number;
|
||||||
|
};
|
||||||
|
|
||||||
export const SelectResource = (props: PropsInterface) => {
|
export const SelectResource = (props: PropsInterface) => {
|
||||||
const [refresh, setRefresh] = useState(true);
|
const [refresh, setRefresh] = useState(true);
|
||||||
const [init, setInit] = useState(true);
|
|
||||||
const [tabKey, setTabKey] = useState(1);
|
const [tabKey, setTabKey] = useState(1);
|
||||||
const [selectKeys, setSelectKeys] = useState<any>([]);
|
const [selectKeys, setSelectKeys] = useState<number[]>([]);
|
||||||
const [selectVideos, setSelectVideos] = useState<any>([]);
|
const [selectVideos, setSelectVideos] = useState<selVideosModel[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInit(true);
|
|
||||||
setRefresh(!refresh);
|
setRefresh(!refresh);
|
||||||
}, [props.open]);
|
}, [props.open]);
|
||||||
|
|
||||||
@ -28,10 +33,7 @@ export const SelectResource = (props: PropsInterface) => {
|
|||||||
key: "1",
|
key: "1",
|
||||||
label: `视频`,
|
label: `视频`,
|
||||||
children: (
|
children: (
|
||||||
<div
|
<div className="float-left">
|
||||||
className="float-left"
|
|
||||||
style={{ display: init ? "none" : "block" }}
|
|
||||||
>
|
|
||||||
<UploadVideoSub
|
<UploadVideoSub
|
||||||
label="视频"
|
label="视频"
|
||||||
defaultCheckedList={props.defaultKeys}
|
defaultCheckedList={props.defaultKeys}
|
||||||
@ -40,9 +42,6 @@ export const SelectResource = (props: PropsInterface) => {
|
|||||||
setSelectKeys(arr);
|
setSelectKeys(arr);
|
||||||
setSelectVideos(videos);
|
setSelectVideos(videos);
|
||||||
}}
|
}}
|
||||||
onSuccess={() => {
|
|
||||||
setInit(false);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
@ -77,11 +76,6 @@ export const SelectResource = (props: PropsInterface) => {
|
|||||||
<Row>
|
<Row>
|
||||||
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
|
<Tabs defaultActiveKey="1" items={items} onChange={onChange} />
|
||||||
</Row>
|
</Row>
|
||||||
{init && (
|
|
||||||
<div className="float-left text-center mt-30">
|
|
||||||
<Spin></Spin>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Modal>
|
</Modal>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
@ -18,7 +18,7 @@ interface PropInterface {
|
|||||||
export const TreeCategory = (props: PropInterface) => {
|
export const TreeCategory = (props: PropInterface) => {
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [selectKey, setSelectKey] = useState<any>([]);
|
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.selected && props.selected.length > 0) {
|
if (props.selected && props.selected.length > 0) {
|
||||||
@ -28,7 +28,7 @@ export const TreeCategory = (props: PropInterface) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
resourceCategory.resourceCategoryList().then((res: any) => {
|
resourceCategory.resourceCategoryList().then((res: any) => {
|
||||||
const categories = res.data.categories;
|
const categories: CategoriesBoxModel = res.data.categories;
|
||||||
if (JSON.stringify(categories) !== "{}") {
|
if (JSON.stringify(categories) !== "{}") {
|
||||||
const new_arr: Option[] = checkArr(categories, 0);
|
const new_arr: Option[] = checkArr(categories, 0);
|
||||||
if (props.type === "no-cate") {
|
if (props.type === "no-cate") {
|
||||||
@ -43,7 +43,7 @@ export const TreeCategory = (props: PropInterface) => {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const checkArr = (categories: any[], id: number) => {
|
const checkArr = (categories: CategoriesBoxModel, id: number) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
for (let i = 0; i < categories[id].length; i++) {
|
for (let i = 0; i < categories[id].length; i++) {
|
||||||
if (!categories[categories[id][i].id]) {
|
if (!categories[categories[id][i].id]) {
|
||||||
|
@ -20,7 +20,7 @@ interface PropInterface {
|
|||||||
export const TreeDepartment = (props: PropInterface) => {
|
export const TreeDepartment = (props: PropInterface) => {
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [selectKey, setSelectKey] = useState<any>([]);
|
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||||
const [userTotal, setUserTotal] = useState(0);
|
const [userTotal, setUserTotal] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -32,8 +32,8 @@ export const TreeDepartment = (props: PropInterface) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
department.departmentList().then((res: any) => {
|
department.departmentList().then((res: any) => {
|
||||||
const departments = res.data.departments;
|
const departments: DepartmentsBoxModel = res.data.departments;
|
||||||
const departCount = res.data.dep_user_count;
|
const departCount: DepIdsModel = res.data.dep_user_count;
|
||||||
setUserTotal(res.data.user_total);
|
setUserTotal(res.data.user_total);
|
||||||
if (JSON.stringify(departments) !== "{}") {
|
if (JSON.stringify(departments) !== "{}") {
|
||||||
if (props.showNum) {
|
if (props.showNum) {
|
||||||
@ -57,7 +57,11 @@ export const TreeDepartment = (props: PropInterface) => {
|
|||||||
});
|
});
|
||||||
}, [props.refresh]);
|
}, [props.refresh]);
|
||||||
|
|
||||||
const checkNewArr = (departments: any[], id: number, counts: any) => {
|
const checkNewArr = (
|
||||||
|
departments: DepartmentsBoxModel,
|
||||||
|
id: number,
|
||||||
|
counts: any
|
||||||
|
) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
for (let i = 0; i < departments[id].length; i++) {
|
for (let i = 0; i < departments[id].length; i++) {
|
||||||
if (!departments[departments[id][i].id]) {
|
if (!departments[departments[id][i].id]) {
|
||||||
@ -89,7 +93,7 @@ export const TreeDepartment = (props: PropInterface) => {
|
|||||||
return arr;
|
return arr;
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkArr = (departments: any[], id: number) => {
|
const checkArr = (departments: DepartmentsBoxModel, id: number) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
for (let i = 0; i < departments[id].length; i++) {
|
for (let i = 0; i < departments[id].length; i++) {
|
||||||
if (!departments[departments[id][i].id]) {
|
if (!departments[departments[id][i].id]) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Row, Col, Empty, Table } from "antd";
|
import { Row, Col, Empty, Table, Spin } from "antd";
|
||||||
import type { ColumnsType } from "antd/es/table";
|
import type { ColumnsType } from "antd/es/table";
|
||||||
import { resource } from "../../api";
|
import { resource } from "../../api";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
@ -34,10 +34,10 @@ interface PropsInterface {
|
|||||||
label: string;
|
label: string;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onSelected: (arr: any[], videos: []) => void;
|
onSelected: (arr: any[], videos: []) => void;
|
||||||
onSuccess: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UploadCoursewareSub = (props: PropsInterface) => {
|
export const UploadCoursewareSub = (props: PropsInterface) => {
|
||||||
|
const [init, setInit] = useState(true);
|
||||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
const [category_ids, setCategoryIds] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [videoList, setVideoList] = useState<VideoItem[]>([]);
|
const [videoList, setVideoList] = useState<VideoItem[]>([]);
|
||||||
@ -50,6 +50,7 @@ export const UploadCoursewareSub = (props: PropsInterface) => {
|
|||||||
|
|
||||||
// 加载列表
|
// 加载列表
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setInit(true);
|
||||||
getvideoList();
|
getvideoList();
|
||||||
}, [props.open, category_ids, refresh, page, size]);
|
}, [props.open, category_ids, refresh, page, size]);
|
||||||
|
|
||||||
@ -61,6 +62,7 @@ export const UploadCoursewareSub = (props: PropsInterface) => {
|
|||||||
|
|
||||||
// 获取列表
|
// 获取列表
|
||||||
const getvideoList = () => {
|
const getvideoList = () => {
|
||||||
|
setLoading(true);
|
||||||
let categoryIds = category_ids.join(",");
|
let categoryIds = category_ids.join(",");
|
||||||
resource
|
resource
|
||||||
.resourceList(
|
.resourceList(
|
||||||
@ -76,9 +78,12 @@ export const UploadCoursewareSub = (props: PropsInterface) => {
|
|||||||
setTotal(res.data.result.total);
|
setTotal(res.data.result.total);
|
||||||
setExistingTypes(res.data.existing_types);
|
setExistingTypes(res.data.existing_types);
|
||||||
setVideoList(res.data.result.data);
|
setVideoList(res.data.result.data);
|
||||||
props.onSuccess();
|
setLoading(false);
|
||||||
|
setInit(false);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
setLoading(false);
|
||||||
|
setInit(false);
|
||||||
console.log("错误,", err);
|
console.log("错误,", err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -154,12 +159,22 @@ export const UploadCoursewareSub = (props: PropsInterface) => {
|
|||||||
<>
|
<>
|
||||||
<Row style={{ width: 752, minHeight: 520 }}>
|
<Row style={{ width: 752, minHeight: 520 }}>
|
||||||
<Col span={7}>
|
<Col span={7}>
|
||||||
<TreeCategory
|
{init && (
|
||||||
selected={[]}
|
<div className="float-left text-center mt-30">
|
||||||
type="no-cate"
|
<Spin></Spin>
|
||||||
text={props.label}
|
</div>
|
||||||
onUpdate={(keys: any) => setCategoryIds(keys)}
|
)}
|
||||||
/>
|
<div
|
||||||
|
className="float-left"
|
||||||
|
style={{ display: init ? "none" : "block" }}
|
||||||
|
>
|
||||||
|
<TreeCategory
|
||||||
|
selected={[]}
|
||||||
|
type="no-cate"
|
||||||
|
text={props.label}
|
||||||
|
onUpdate={(keys: any) => setCategoryIds(keys)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={17}>
|
<Col span={17}>
|
||||||
<Row style={{ marginBottom: 24, paddingLeft: 10 }}>
|
<Row style={{ marginBottom: 24, paddingLeft: 10 }}>
|
||||||
@ -172,7 +187,15 @@ export const UploadCoursewareSub = (props: PropsInterface) => {
|
|||||||
></UploadCoursewareButton>
|
></UploadCoursewareButton>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<div className={styles["video-list"]}>
|
{init && (
|
||||||
|
<div className="float-left text-center mt-30">
|
||||||
|
<Spin></Spin>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={styles["video-list"]}
|
||||||
|
style={{ display: init ? "none" : "block" }}
|
||||||
|
>
|
||||||
{videoList.length === 0 && (
|
{videoList.length === 0 && (
|
||||||
<Col span={24} style={{ marginTop: 150 }}>
|
<Col span={24} style={{ marginTop: 150 }}>
|
||||||
<Empty description="暂无课件" />
|
<Empty description="暂无课件" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Row, Col, Empty, Table } from "antd";
|
import { Row, Col, Empty, Table, Spin } from "antd";
|
||||||
import type { ColumnsType } from "antd/es/table";
|
import type { ColumnsType } from "antd/es/table";
|
||||||
import { resource } from "../../api";
|
import { resource } from "../../api";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
@ -35,10 +35,10 @@ interface PropsInterface {
|
|||||||
label: string;
|
label: string;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onSelected: (arr: any[], videos: []) => void;
|
onSelected: (arr: any[], videos: []) => void;
|
||||||
onSuccess: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UploadVideoSub = (props: PropsInterface) => {
|
export const UploadVideoSub = (props: PropsInterface) => {
|
||||||
|
const [init, setInit] = useState(true);
|
||||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
const [category_ids, setCategoryIds] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [videoList, setVideoList] = useState<VideoItem[]>([]);
|
const [videoList, setVideoList] = useState<VideoItem[]>([]);
|
||||||
@ -51,6 +51,7 @@ export const UploadVideoSub = (props: PropsInterface) => {
|
|||||||
|
|
||||||
// 加载列表
|
// 加载列表
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setInit(true);
|
||||||
getvideoList();
|
getvideoList();
|
||||||
}, [props.open, category_ids, refresh, page, size]);
|
}, [props.open, category_ids, refresh, page, size]);
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ export const UploadVideoSub = (props: PropsInterface) => {
|
|||||||
|
|
||||||
// 获取列表
|
// 获取列表
|
||||||
const getvideoList = () => {
|
const getvideoList = () => {
|
||||||
|
setLoading(true);
|
||||||
let categoryIds = category_ids.join(",");
|
let categoryIds = category_ids.join(",");
|
||||||
resource
|
resource
|
||||||
.resourceList(page, size, "", "", "", "VIDEO", categoryIds)
|
.resourceList(page, size, "", "", "", "VIDEO", categoryIds)
|
||||||
@ -69,9 +71,12 @@ export const UploadVideoSub = (props: PropsInterface) => {
|
|||||||
setTotal(res.data.result.total);
|
setTotal(res.data.result.total);
|
||||||
setVideoExtra(res.data.videos_extra);
|
setVideoExtra(res.data.videos_extra);
|
||||||
setVideoList(res.data.result.data);
|
setVideoList(res.data.result.data);
|
||||||
props.onSuccess();
|
setLoading(false);
|
||||||
|
setInit(false);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
setLoading(false);
|
||||||
|
setInit(false);
|
||||||
console.log("错误,", err);
|
console.log("错误,", err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -154,12 +159,22 @@ export const UploadVideoSub = (props: PropsInterface) => {
|
|||||||
<>
|
<>
|
||||||
<Row style={{ width: 752, minHeight: 520 }}>
|
<Row style={{ width: 752, minHeight: 520 }}>
|
||||||
<Col span={7}>
|
<Col span={7}>
|
||||||
<TreeCategory
|
{init && (
|
||||||
selected={[]}
|
<div className="float-left text-center mt-30">
|
||||||
type="no-cate"
|
<Spin></Spin>
|
||||||
text={props.label}
|
</div>
|
||||||
onUpdate={(keys: any) => setCategoryIds(keys)}
|
)}
|
||||||
/>
|
<div
|
||||||
|
className="float-left"
|
||||||
|
style={{ display: init ? "none" : "block" }}
|
||||||
|
>
|
||||||
|
<TreeCategory
|
||||||
|
selected={[]}
|
||||||
|
type="no-cate"
|
||||||
|
text={props.label}
|
||||||
|
onUpdate={(keys: any) => setCategoryIds(keys)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={17}>
|
<Col span={17}>
|
||||||
<Row style={{ marginBottom: 24, paddingLeft: 10 }}>
|
<Row style={{ marginBottom: 24, paddingLeft: 10 }}>
|
||||||
@ -172,7 +187,15 @@ export const UploadVideoSub = (props: PropsInterface) => {
|
|||||||
></UploadVideoButton>
|
></UploadVideoButton>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<div className={styles["video-list"]}>
|
{init && (
|
||||||
|
<div className="float-left text-center mt-30">
|
||||||
|
<Spin></Spin>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={styles["video-list"]}
|
||||||
|
style={{ display: init ? "none" : "block" }}
|
||||||
|
>
|
||||||
{videoList.length === 0 && (
|
{videoList.length === 0 && (
|
||||||
<Col span={24} style={{ marginTop: 150 }}>
|
<Col span={24} style={{ marginTop: 150 }}>
|
||||||
<Empty description="暂无视频" />
|
<Empty description="暂无视频" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Button, Drawer, Form, Modal, message } from "antd";
|
import { Button, Drawer, Form, Modal, message, Spin } from "antd";
|
||||||
import styles from "./hour-update.module.less";
|
import styles from "./hour-update.module.less";
|
||||||
import { course, courseAttachment } from "../../../api/index";
|
import { course, courseAttachment } from "../../../api/index";
|
||||||
import { SelectAttachment } from "../../../compenents";
|
import { SelectAttachment } from "../../../compenents";
|
||||||
@ -20,11 +20,15 @@ export const CourseAttachmentUpdate: React.FC<PropInterface> = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const [init, setInit] = useState(true);
|
||||||
const [attachmentVisible, setAttachmentVisible] = useState<boolean>(false);
|
const [attachmentVisible, setAttachmentVisible] = useState<boolean>(false);
|
||||||
const [attachmentData, setAttachmentData] = useState<any>([]);
|
const [attachmentData, setAttachmentData] = useState<AttachmentDataModel[]>(
|
||||||
const [attachments, setAttachments] = useState<any>([]);
|
[]
|
||||||
|
);
|
||||||
|
const [attachments, setAttachments] = useState<number[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setInit(true);
|
||||||
if (id === 0) {
|
if (id === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -43,6 +47,7 @@ export const CourseAttachmentUpdate: React.FC<PropInterface> = ({
|
|||||||
setAttachmentData(arr);
|
setAttachmentData(arr);
|
||||||
setAttachments(keys);
|
setAttachments(keys);
|
||||||
}
|
}
|
||||||
|
setInit(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,47 +174,57 @@ export const CourseAttachmentUpdate: React.FC<PropInterface> = ({
|
|||||||
selectAttachmentData(arr, videos);
|
selectAttachmentData(arr, videos);
|
||||||
}}
|
}}
|
||||||
></SelectAttachment>
|
></SelectAttachment>
|
||||||
<Form
|
{init && (
|
||||||
form={form}
|
<div className="float-left text-center mt-30">
|
||||||
name="attachment-update-basic"
|
<Spin></Spin>
|
||||||
labelCol={{ span: 5 }}
|
|
||||||
wrapperCol={{ span: 19 }}
|
|
||||||
initialValues={{ remember: true }}
|
|
||||||
onFinish={onFinish}
|
|
||||||
onFinishFailed={onFinishFailed}
|
|
||||||
autoComplete="off"
|
|
||||||
>
|
|
||||||
<div className="c-flex">
|
|
||||||
<Form.Item>
|
|
||||||
<div className="ml-42">
|
|
||||||
<Button
|
|
||||||
onClick={() => setAttachmentVisible(true)}
|
|
||||||
type="primary"
|
|
||||||
>
|
|
||||||
添加课件
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Form.Item>
|
|
||||||
<div className={styles["hous-box"]}>
|
|
||||||
{attachmentData.length === 0 && (
|
|
||||||
<span className={styles["no-hours"]}>
|
|
||||||
请点击上方按钮添加课件
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{attachmentData.length > 0 && (
|
|
||||||
<TreeAttachments
|
|
||||||
data={attachmentData}
|
|
||||||
onRemoveItem={(id: number) => {
|
|
||||||
delAttachments(id);
|
|
||||||
}}
|
|
||||||
onUpdate={(arr: any[]) => {
|
|
||||||
transAttachments(arr);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
)}
|
||||||
|
<div
|
||||||
|
className="float-left"
|
||||||
|
style={{ display: init ? "none" : "block" }}
|
||||||
|
>
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
name="attachment-update-basic"
|
||||||
|
labelCol={{ span: 5 }}
|
||||||
|
wrapperCol={{ span: 19 }}
|
||||||
|
initialValues={{ remember: true }}
|
||||||
|
onFinish={onFinish}
|
||||||
|
onFinishFailed={onFinishFailed}
|
||||||
|
autoComplete="off"
|
||||||
|
>
|
||||||
|
<div className="c-flex">
|
||||||
|
<Form.Item>
|
||||||
|
<div className="ml-42">
|
||||||
|
<Button
|
||||||
|
onClick={() => setAttachmentVisible(true)}
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
添加课件
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
<div className={styles["hous-box"]}>
|
||||||
|
{attachmentData.length === 0 && (
|
||||||
|
<span className={styles["no-hours"]}>
|
||||||
|
请点击上方按钮添加课件
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{attachmentData.length > 0 && (
|
||||||
|
<TreeAttachments
|
||||||
|
data={attachmentData}
|
||||||
|
onRemoveItem={(id: number) => {
|
||||||
|
delAttachments(id);
|
||||||
|
}}
|
||||||
|
onUpdate={(arr: any[]) => {
|
||||||
|
transAttachments(arr);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import { message, Tree, Tooltip } from "antd";
|
import { Tree, Tooltip } from "antd";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import type { DataNode, TreeProps } from "antd/es/tree";
|
import type { DataNode, TreeProps } from "antd/es/tree";
|
||||||
|
|
||||||
interface Option {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PropInterface {
|
interface PropInterface {
|
||||||
data: Option[];
|
data: AttachmentDataModel[];
|
||||||
onRemoveItem: (id: number) => void;
|
onRemoveItem: (id: number) => void;
|
||||||
onUpdate: (arr: any[]) => void;
|
onUpdate: (arr: any[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
key: string | number;
|
||||||
|
title: any;
|
||||||
|
}
|
||||||
|
|
||||||
export const TreeAttachments = (props: PropInterface) => {
|
export const TreeAttachments = (props: PropInterface) => {
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<Option[]>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hours = props.data;
|
const hours = props.data;
|
||||||
|
@ -32,6 +32,12 @@ interface PropInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
value: string | number;
|
||||||
|
title: string;
|
||||||
|
children?: Option[];
|
||||||
|
}
|
||||||
|
|
||||||
export const CourseCreate: React.FC<PropInterface> = ({
|
export const CourseCreate: React.FC<PropInterface> = ({
|
||||||
cateIds,
|
cateIds,
|
||||||
depIds,
|
depIds,
|
||||||
@ -45,22 +51,24 @@ export const CourseCreate: React.FC<PropInterface> = ({
|
|||||||
const defaultThumb1 = courseDefaultThumbs[0];
|
const defaultThumb1 = courseDefaultThumbs[0];
|
||||||
const defaultThumb2 = courseDefaultThumbs[1];
|
const defaultThumb2 = courseDefaultThumbs[1];
|
||||||
const defaultThumb3 = courseDefaultThumbs[2];
|
const defaultThumb3 = courseDefaultThumbs[2];
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [departments, setDepartments] = useState<any>([]);
|
const [departments, setDepartments] = useState<Option[]>([]);
|
||||||
const [categories, setCategories] = useState<any>([]);
|
const [categories, setCategories] = useState<Option[]>([]);
|
||||||
const [thumb, setThumb] = useState<string>("");
|
const [thumb, setThumb] = useState("");
|
||||||
const [type, setType] = useState<string>("open");
|
const [type, setType] = useState("open");
|
||||||
const [chapterType, setChapterType] = useState(0);
|
const [chapterType, setChapterType] = useState(0);
|
||||||
const [chapters, setChapters] = useState<any>([]);
|
const [chapters, setChapters] = useState<CourseChaptersModel[]>([]);
|
||||||
const [hours, setHours] = useState<any>([]);
|
const [hours, setHours] = useState<number[]>([]);
|
||||||
const [chapterHours, setChapterHours] = useState<any>([]);
|
const [chapterHours, setChapterHours] = useState<any>([]);
|
||||||
const [videoVisible, setVideoVisible] = useState<boolean>(false);
|
const [videoVisible, setVideoVisible] = useState(false);
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<CourseHourModel[]>([]);
|
||||||
const [addvideoCurrent, setAddvideoCurrent] = useState(0);
|
const [addvideoCurrent, setAddvideoCurrent] = useState(0);
|
||||||
const [showDrop, setShowDrop] = useState<boolean>(false);
|
const [showDrop, setShowDrop] = useState(false);
|
||||||
const [attachmentVisible, setAttachmentVisible] = useState<boolean>(false);
|
const [attachmentVisible, setAttachmentVisible] = useState(false);
|
||||||
const [attachmentData, setAttachmentData] = useState<any>([]);
|
const [attachmentData, setAttachmentData] = useState<AttachmentDataModel[]>(
|
||||||
const [attachments, setAttachments] = useState<any>([]);
|
[]
|
||||||
|
);
|
||||||
|
const [attachments, setAttachments] = useState<number[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
@ -91,7 +99,7 @@ export const CourseCreate: React.FC<PropInterface> = ({
|
|||||||
const getParams = () => {
|
const getParams = () => {
|
||||||
department.departmentList().then((res: any) => {
|
department.departmentList().then((res: any) => {
|
||||||
const departments = res.data.departments;
|
const departments = res.data.departments;
|
||||||
const departCount = res.data.dep_user_count;
|
const departCount: DepIdsModel = res.data.dep_user_count;
|
||||||
if (JSON.stringify(departments) !== "{}") {
|
if (JSON.stringify(departments) !== "{}") {
|
||||||
const new_arr: any = checkArr(departments, 0, departCount);
|
const new_arr: any = checkArr(departments, 0, departCount);
|
||||||
setDepartments(new_arr);
|
setDepartments(new_arr);
|
||||||
@ -438,7 +446,6 @@ export const CourseCreate: React.FC<PropInterface> = ({
|
|||||||
const keys = [...chapterHours];
|
const keys = [...chapterHours];
|
||||||
keys[index] = arr;
|
keys[index] = arr;
|
||||||
setChapterHours(keys);
|
setChapterHours(keys);
|
||||||
|
|
||||||
const data = [...chapters];
|
const data = [...chapters];
|
||||||
const newArr: any = [];
|
const newArr: any = [];
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Button, Drawer, Form, Input, Modal, message } from "antd";
|
import { Button, Drawer, Form, Input, Modal, message, Spin } from "antd";
|
||||||
import styles from "./hour-update.module.less";
|
import styles from "./hour-update.module.less";
|
||||||
import { course, courseHour, courseChapter } from "../../../api/index";
|
import { course, courseHour, courseChapter } from "../../../api/index";
|
||||||
import { SelectResource } from "../../../compenents";
|
import { SelectResource } from "../../../compenents";
|
||||||
@ -20,15 +20,17 @@ export const CourseHourUpdate: React.FC<PropInterface> = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const [init, setInit] = useState(true);
|
||||||
const [chapterType, setChapterType] = useState(0);
|
const [chapterType, setChapterType] = useState(0);
|
||||||
const [chapters, setChapters] = useState<any>([]);
|
const [chapters, setChapters] = useState<CourseChaptersModel[]>([]);
|
||||||
const [hours, setHours] = useState<any>([]);
|
const [hours, setHours] = useState<number[]>([]);
|
||||||
const [chapterHours, setChapterHours] = useState<any>([]);
|
const [chapterHours, setChapterHours] = useState<any>([]);
|
||||||
const [videoVisible, setVideoVisible] = useState<boolean>(false);
|
const [videoVisible, setVideoVisible] = useState<boolean>(false);
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<CourseHourModel[]>([]);
|
||||||
const [addvideoCurrent, setAddvideoCurrent] = useState(0);
|
const [addvideoCurrent, setAddvideoCurrent] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setInit(true);
|
||||||
if (id === 0) {
|
if (id === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -77,6 +79,7 @@ export const CourseHourUpdate: React.FC<PropInterface> = ({
|
|||||||
setHours([]);
|
setHours([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setInit(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -231,7 +234,7 @@ export const CourseHourUpdate: React.FC<PropInterface> = ({
|
|||||||
const arr = [...chapters];
|
const arr = [...chapters];
|
||||||
if (arr[index].id) {
|
if (arr[index].id) {
|
||||||
courseChapter
|
courseChapter
|
||||||
.updateCourseChapter(id, arr[index].id, value, arr.length)
|
.updateCourseChapter(id, Number(arr[index].id), value, arr.length)
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
console.log("ok");
|
console.log("ok");
|
||||||
getDetail();
|
getDetail();
|
||||||
@ -259,7 +262,7 @@ export const CourseHourUpdate: React.FC<PropInterface> = ({
|
|||||||
onOk() {
|
onOk() {
|
||||||
if (arr[index].id) {
|
if (arr[index].id) {
|
||||||
courseChapter
|
courseChapter
|
||||||
.destroyCourseChapter(id, arr[index].id)
|
.destroyCourseChapter(id, Number(arr[index].id))
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
console.log("ok");
|
console.log("ok");
|
||||||
getDetail();
|
getDetail();
|
||||||
@ -373,117 +376,129 @@ export const CourseHourUpdate: React.FC<PropInterface> = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Form
|
{init && (
|
||||||
form={form}
|
<div className="float-left text-center mt-30">
|
||||||
name="hour-update-basic"
|
<Spin></Spin>
|
||||||
labelCol={{ span: 5 }}
|
</div>
|
||||||
wrapperCol={{ span: 19 }}
|
)}
|
||||||
initialValues={{ remember: true }}
|
<div
|
||||||
onFinish={onFinish}
|
className="float-left"
|
||||||
onFinishFailed={onFinishFailed}
|
style={{ display: init ? "none" : "block" }}
|
||||||
autoComplete="off"
|
|
||||||
>
|
>
|
||||||
{chapterType === 0 && (
|
<Form
|
||||||
<div className="c-flex">
|
form={form}
|
||||||
<Form.Item>
|
name="hour-update-basic"
|
||||||
<div className="ml-42">
|
labelCol={{ span: 5 }}
|
||||||
<Button
|
wrapperCol={{ span: 19 }}
|
||||||
onClick={() => setVideoVisible(true)}
|
initialValues={{ remember: true }}
|
||||||
type="primary"
|
onFinish={onFinish}
|
||||||
>
|
onFinishFailed={onFinishFailed}
|
||||||
添加课时
|
autoComplete="off"
|
||||||
</Button>
|
>
|
||||||
</div>
|
{chapterType === 0 && (
|
||||||
</Form.Item>
|
<div className="c-flex">
|
||||||
<div className={styles["hous-box"]}>
|
<Form.Item>
|
||||||
{treeData.length === 0 && (
|
<div className="ml-42">
|
||||||
<span className={styles["no-hours"]}>
|
<Button
|
||||||
请点击上方按钮添加课时
|
onClick={() => setVideoVisible(true)}
|
||||||
</span>
|
type="primary"
|
||||||
)}
|
|
||||||
{treeData.length > 0 && (
|
|
||||||
<TreeHours
|
|
||||||
data={treeData}
|
|
||||||
onRemoveItem={(id: number) => {
|
|
||||||
delHour(id);
|
|
||||||
}}
|
|
||||||
onUpdate={(arr: any[]) => {
|
|
||||||
transHour(arr);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{chapterType === 1 && (
|
|
||||||
<div className="c-flex">
|
|
||||||
{chapters.length > 0 &&
|
|
||||||
chapters.map((item: any, index: number) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={item.hours.length + "章节" + index}
|
|
||||||
className={styles["chapter-item"]}
|
|
||||||
>
|
>
|
||||||
<div className="d-flex">
|
添加课时
|
||||||
<div className={styles["label"]}>
|
</Button>
|
||||||
章节{index + 1}:
|
</div>
|
||||||
</div>
|
</Form.Item>
|
||||||
<Input
|
<div className={styles["hous-box"]}>
|
||||||
value={item.name}
|
{treeData.length === 0 && (
|
||||||
className={styles["input"]}
|
<span className={styles["no-hours"]}>
|
||||||
onChange={(e) => {
|
请点击上方按钮添加课时
|
||||||
setChapterName(index, e.target.value);
|
</span>
|
||||||
}}
|
)}
|
||||||
onBlur={(e) => {
|
{treeData.length > 0 && (
|
||||||
saveChapterName(index, e.target.value);
|
<TreeHours
|
||||||
}}
|
data={treeData}
|
||||||
placeholder="请在此处输入章节名称"
|
onRemoveItem={(id: number) => {
|
||||||
allowClear
|
delHour(id);
|
||||||
/>
|
}}
|
||||||
<Button
|
onUpdate={(arr: any[]) => {
|
||||||
disabled={!item.name}
|
transHour(arr);
|
||||||
className="mr-16"
|
}}
|
||||||
type="primary"
|
/>
|
||||||
onClick={() => {
|
)}
|
||||||
setVideoVisible(true);
|
|
||||||
setAddvideoCurrent(index);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
添加课时
|
|
||||||
</Button>
|
|
||||||
<Button onClick={() => delChapter(index)}>
|
|
||||||
删除章节
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div className={styles["chapter-hous-box"]}>
|
|
||||||
{item.hours.length === 0 && (
|
|
||||||
<span className={styles["no-hours"]}>
|
|
||||||
请点击上方按钮添加课时
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{item.hours.length > 0 && (
|
|
||||||
<TreeHours
|
|
||||||
data={item.hours}
|
|
||||||
onRemoveItem={(id: number) => {
|
|
||||||
delChapterHour(index, id);
|
|
||||||
}}
|
|
||||||
onUpdate={(arr: any[]) => {
|
|
||||||
transChapterHour(index, arr);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
<Form.Item>
|
|
||||||
<div className="ml-42">
|
|
||||||
<Button onClick={() => addNewChapter()}>添加章节</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Form.Item>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
{chapterType === 1 && (
|
||||||
</Form>
|
<div className="c-flex">
|
||||||
|
{chapters.length > 0 &&
|
||||||
|
chapters.map((item: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={item.hours.length + "章节" + index}
|
||||||
|
className={styles["chapter-item"]}
|
||||||
|
>
|
||||||
|
<div className="d-flex">
|
||||||
|
<div className={styles["label"]}>
|
||||||
|
章节{index + 1}:
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
value={item.name}
|
||||||
|
className={styles["input"]}
|
||||||
|
onChange={(e) => {
|
||||||
|
setChapterName(index, e.target.value);
|
||||||
|
}}
|
||||||
|
onBlur={(e) => {
|
||||||
|
saveChapterName(index, e.target.value);
|
||||||
|
}}
|
||||||
|
placeholder="请在此处输入章节名称"
|
||||||
|
allowClear
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
disabled={!item.name}
|
||||||
|
className="mr-16"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setVideoVisible(true);
|
||||||
|
setAddvideoCurrent(index);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
添加课时
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => delChapter(index)}>
|
||||||
|
删除章节
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className={styles["chapter-hous-box"]}>
|
||||||
|
{item.hours.length === 0 && (
|
||||||
|
<span className={styles["no-hours"]}>
|
||||||
|
请点击上方按钮添加课时
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{item.hours.length > 0 && (
|
||||||
|
<TreeHours
|
||||||
|
data={item.hours}
|
||||||
|
onRemoveItem={(id: number) => {
|
||||||
|
delChapterHour(index, id);
|
||||||
|
}}
|
||||||
|
onUpdate={(arr: any[]) => {
|
||||||
|
transChapterHour(index, arr);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<Form.Item>
|
||||||
|
<div className="ml-42">
|
||||||
|
<Button onClick={() => addNewChapter()}>
|
||||||
|
添加章节
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -3,18 +3,18 @@ import { useState, useEffect } from "react";
|
|||||||
import type { DataNode, TreeProps } from "antd/es/tree";
|
import type { DataNode, TreeProps } from "antd/es/tree";
|
||||||
|
|
||||||
interface Option {
|
interface Option {
|
||||||
id: number;
|
key: string | number;
|
||||||
name: string;
|
title: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PropInterface {
|
interface PropInterface {
|
||||||
data: Option[];
|
data: CourseHourModel[];
|
||||||
onRemoveItem: (id: number) => void;
|
onRemoveItem: (id: number) => void;
|
||||||
onUpdate: (arr: any[]) => void;
|
onUpdate: (arr: any[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TreeHours = (props: PropInterface) => {
|
export const TreeHours = (props: PropInterface) => {
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<Option[]>([]);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hours = props.data;
|
const hours = props.data;
|
||||||
|
@ -22,6 +22,12 @@ interface PropInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
value: string | number;
|
||||||
|
title: string;
|
||||||
|
children?: Option[];
|
||||||
|
}
|
||||||
|
|
||||||
export const CourseUpdate: React.FC<PropInterface> = ({
|
export const CourseUpdate: React.FC<PropInterface> = ({
|
||||||
id,
|
id,
|
||||||
open,
|
open,
|
||||||
@ -36,10 +42,10 @@ export const CourseUpdate: React.FC<PropInterface> = ({
|
|||||||
const defaultThumb2 = courseDefaultThumbs[1];
|
const defaultThumb2 = courseDefaultThumbs[1];
|
||||||
const defaultThumb3 = courseDefaultThumbs[2];
|
const defaultThumb3 = courseDefaultThumbs[2];
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [departments, setDepartments] = useState<any>([]);
|
const [departments, setDepartments] = useState<Option[]>([]);
|
||||||
const [categories, setCategories] = useState<any>([]);
|
const [categories, setCategories] = useState<Option[]>([]);
|
||||||
const [thumb, setThumb] = useState<string>("");
|
const [thumb, setThumb] = useState("");
|
||||||
const [type, setType] = useState<string>("open");
|
const [type, setType] = useState("open");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInit(true);
|
setInit(true);
|
||||||
|
@ -12,7 +12,6 @@ import {
|
|||||||
Dropdown,
|
Dropdown,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import { course } from "../../api";
|
import { course } from "../../api";
|
||||||
// import styles from "./index.module.less";
|
|
||||||
import {
|
import {
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
DownOutlined,
|
DownOutlined,
|
||||||
@ -33,43 +32,46 @@ const { confirm } = Modal;
|
|||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
title: string;
|
|
||||||
created_at: string;
|
|
||||||
thumb: string;
|
|
||||||
charge: number;
|
charge: number;
|
||||||
|
class_hour: number;
|
||||||
|
created_at: string;
|
||||||
|
is_required: number;
|
||||||
is_show: number;
|
is_show: number;
|
||||||
|
short_desc: string;
|
||||||
|
thumb: string;
|
||||||
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoursePage = () => {
|
const CoursePage = () => {
|
||||||
const result = new URLSearchParams(useLocation().search);
|
const result = new URLSearchParams(useLocation().search);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [list, setList] = useState<any>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||||
const [title, setTitle] = useState<string>("");
|
const [title, setTitle] = useState("");
|
||||||
const [dep_ids, setDepIds] = useState<any>([]);
|
const [dep_ids, setDepIds] = useState<number[]>([]);
|
||||||
const [selLabel, setLabel] = useState<string>(
|
const [selLabel, setLabel] = useState<string>(
|
||||||
result.get("label") ? String(result.get("label")) : "全部分类"
|
result.get("label") ? String(result.get("label")) : "全部分类"
|
||||||
);
|
);
|
||||||
const [selDepLabel, setDepLabel] = useState<string>(
|
const [selDepLabel, setDepLabel] = useState<string>(
|
||||||
result.get("label") ? String(result.get("label")) : "全部部门"
|
result.get("label") ? String(result.get("label")) : "全部部门"
|
||||||
);
|
);
|
||||||
const [course_category_ids, setCourseCategoryIds] = useState<any>({});
|
const [course_category_ids, setCourseCategoryIds] =
|
||||||
const [course_dep_ids, setCourseDepIds] = useState<any>({});
|
useState<CategoryIdsModel>({});
|
||||||
const [categories, setCategories] = useState<any>({});
|
const [course_dep_ids, setCourseDepIds] = useState<DepIdsModel>({});
|
||||||
const [departments, setDepartments] = useState<any>({});
|
const [categories, setCategories] = useState<CategoriesModel>({});
|
||||||
|
const [departments, setDepartments] = useState<DepartmentsModel>({});
|
||||||
const [tabKey, setTabKey] = useState(result.get("did") ? "2" : "1");
|
const [tabKey, setTabKey] = useState(result.get("did") ? "2" : "1");
|
||||||
|
|
||||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
const [createVisible, setCreateVisible] = useState(false);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState(false);
|
||||||
const [updateHourVisible, setHourUpdateVisible] = useState<boolean>(false);
|
const [updateHourVisible, setHourUpdateVisible] = useState(false);
|
||||||
const [updateAttachmentVisible, setUpdateAttachmentVisible] =
|
const [updateAttachmentVisible, setUpdateAttachmentVisible] = useState(false);
|
||||||
useState<boolean>(false);
|
const [cid, setCid] = useState(0);
|
||||||
const [cid, setCid] = useState<number>(0);
|
|
||||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||||
const [did, setDid] = useState(Number(result.get("did")));
|
const [did, setDid] = useState(Number(result.get("did")));
|
||||||
|
|
||||||
|
@ -22,30 +22,61 @@ const { confirm } = Modal;
|
|||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
title: string;
|
avatar: string;
|
||||||
created_at: string;
|
create_city?: string;
|
||||||
thumb: string;
|
create_ip?: string;
|
||||||
charge: number;
|
created_at?: string;
|
||||||
is_show: number;
|
credit1?: number;
|
||||||
|
email: string;
|
||||||
|
id_card?: string;
|
||||||
|
is_active?: number;
|
||||||
|
is_lock?: number;
|
||||||
|
is_set_password?: number;
|
||||||
|
is_verify?: number;
|
||||||
|
login_at?: string;
|
||||||
|
name: string;
|
||||||
|
updated_at?: string;
|
||||||
|
verify_at?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserCourseRecordsModel = {
|
||||||
|
[key: number]: CourseRecordModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
type CourseRecordModel = {
|
||||||
|
course_id: number;
|
||||||
|
created_at: string;
|
||||||
|
finished_at?: string;
|
||||||
|
finished_count: number;
|
||||||
|
hour_count: number;
|
||||||
|
id: number;
|
||||||
|
is_finished: number;
|
||||||
|
progress: number;
|
||||||
|
updated_at: string;
|
||||||
|
user_id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type HourCountModel = {
|
||||||
|
[key: number]: string;
|
||||||
|
};
|
||||||
|
|
||||||
const CourseUserPage = () => {
|
const CourseUserPage = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const result = new URLSearchParams(useLocation().search);
|
const result = new URLSearchParams(useLocation().search);
|
||||||
const [list, setList] = useState<any>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
const [course, setCourse] = useState<any>({});
|
const [course, setCourse] = useState<CourseModel | null>(null);
|
||||||
const [records, setRecords] = useState<any>({});
|
const [records, setRecords] = useState<UserCourseRecordsModel>({});
|
||||||
const [hourCount, setHourCount] = useState<any>({});
|
const [hourCount, setHourCount] = useState<HourCountModel>({});
|
||||||
const [userDepIds, setUserDepIds] = useState<any>({});
|
const [userDepIds, setUserDepIds] = useState<DepIdsModel>({});
|
||||||
const [departments, setDepartments] = useState<any>({});
|
const [departments, setDepartments] = useState<DepartmentsModel>({});
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [name, setName] = useState<string>("");
|
const [name, setName] = useState("");
|
||||||
const [email, setEmail] = useState<string>("");
|
const [email, setEmail] = useState("");
|
||||||
const [idCard, setIdCard] = useState<string>("");
|
const [idCard, setIdCard] = useState("");
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
||||||
const [title, setTitle] = useState<string>(String(result.get("title")));
|
const [title, setTitle] = useState<string>(String(result.get("title")));
|
||||||
|
|
||||||
@ -95,7 +126,7 @@ const CourseUserPage = () => {
|
|||||||
{(records[record.id] && records[record.id].finished_count) ||
|
{(records[record.id] && records[record.id].finished_count) ||
|
||||||
0} /{" "}
|
0} /{" "}
|
||||||
{(records[record.id] && records[record.id].hour_count) ||
|
{(records[record.id] && records[record.id].hour_count) ||
|
||||||
course.class_hour}
|
course?.class_hour}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -116,11 +147,11 @@ const CourseUserPage = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "学习完成时间",
|
title: "学习完成时间",
|
||||||
dataIndex: "finished_at",
|
dataIndex: "id",
|
||||||
render: (_, record: any) => (
|
render: (_, record: any) => (
|
||||||
<>
|
<>
|
||||||
{records[record.id] ? (
|
{records[record.id] ? (
|
||||||
<span>{dateFormat(records[record.id].finished_at)}</span>
|
<span>{dateFormat(String(records[record.id].finished_at))}</span>
|
||||||
) : (
|
) : (
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
)}
|
)}
|
||||||
|
@ -12,10 +12,38 @@ import { dashboard } from "../../api/index";
|
|||||||
import { timeFormat } from "../../utils/index";
|
import { timeFormat } from "../../utils/index";
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
|
|
||||||
|
type BasicDataModel = {
|
||||||
|
admin_user_total: number;
|
||||||
|
course_total: number;
|
||||||
|
department_total: number;
|
||||||
|
resource_category_total: number;
|
||||||
|
resource_image_total: number;
|
||||||
|
resource_video_total: number;
|
||||||
|
user_learn_today: number;
|
||||||
|
user_learn_top10?: Top10Model[];
|
||||||
|
user_learn_top10_users?: Top10UserModel;
|
||||||
|
user_learn_yesterday: number;
|
||||||
|
user_today: number;
|
||||||
|
user_total: number;
|
||||||
|
user_yesterday: number;
|
||||||
|
version: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Top10Model = {
|
||||||
|
created_date: string;
|
||||||
|
duration: number;
|
||||||
|
id: number;
|
||||||
|
user_id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Top10UserModel = {
|
||||||
|
[key: number]: UserModel;
|
||||||
|
};
|
||||||
|
|
||||||
const DashboardPage = () => {
|
const DashboardPage = () => {
|
||||||
let chartRef = useRef(null);
|
let chartRef = useRef(null);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [basicData, setBasicData] = useState<any>([]);
|
const [basicData, setBasicData] = useState<BasicDataModel | null>(null);
|
||||||
|
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
dashboard.dashboardList().then((res: any) => {
|
dashboard.dashboardList().then((res: any) => {
|
||||||
@ -164,31 +192,35 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["label"]}>今日学习学员</div>
|
<div className={styles["label"]}>今日学习学员</div>
|
||||||
<div className={styles["info"]}>
|
<div className={styles["info"]}>
|
||||||
<div className={styles["num"]}>
|
<div className={styles["num"]}>
|
||||||
{basicData.user_learn_today}
|
{basicData?.user_learn_today}
|
||||||
</div>
|
|
||||||
<div className={styles["compare"]}>
|
|
||||||
<span className="mr-5">较昨日</span>
|
|
||||||
{compareNum(
|
|
||||||
basicData.user_learn_today,
|
|
||||||
basicData.user_learn_yesterday
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
{basicData && (
|
||||||
|
<div className={styles["compare"]}>
|
||||||
|
<span className="mr-5">较昨日</span>
|
||||||
|
{compareNum(
|
||||||
|
basicData.user_learn_today,
|
||||||
|
basicData.user_learn_yesterday
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["label-item"]}>
|
<div className={styles["label-item"]}>
|
||||||
<div className={styles["label"]}>总学员数</div>
|
<div className={styles["label"]}>总学员数</div>
|
||||||
<div className={styles["info"]}>
|
<div className={styles["info"]}>
|
||||||
<div className={styles["num"]}>{basicData.user_total}</div>
|
<div className={styles["num"]}>{basicData?.user_total}</div>
|
||||||
<div className={styles["compare"]}>
|
{basicData && (
|
||||||
<span className="mr-5">较昨日</span>
|
<div className={styles["compare"]}>
|
||||||
{compareNum(basicData.user_today, 0)}
|
<span className="mr-5">较昨日</span>
|
||||||
</div>
|
{compareNum(basicData.user_today, 0)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["label-item"]}>
|
<div className={styles["label-item"]}>
|
||||||
<div className={styles["label"]}>线上课数</div>
|
<div className={styles["label"]}>线上课数</div>
|
||||||
<div className={styles["info"]}>
|
<div className={styles["info"]}>
|
||||||
<div className={styles["num"]}>{basicData.course_total}</div>
|
<div className={styles["num"]}>{basicData?.course_total}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -249,7 +281,7 @@ const DashboardPage = () => {
|
|||||||
<div className="playedu-main-top mt-24" style={{ minHeight: 376 }}>
|
<div className="playedu-main-top mt-24" style={{ minHeight: 376 }}>
|
||||||
<div className={styles["large-title"]}>今日学习排行</div>
|
<div className={styles["large-title"]}>今日学习排行</div>
|
||||||
<div className={styles["rank-list"]}>
|
<div className={styles["rank-list"]}>
|
||||||
{basicData.user_learn_top10 && (
|
{basicData?.user_learn_top10 && (
|
||||||
<div className={styles["half-list"]}>
|
<div className={styles["half-list"]}>
|
||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
@ -258,15 +290,16 @@ const DashboardPage = () => {
|
|||||||
src={iconN1}
|
src={iconN1}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
{basicData.user_learn_top10[0] && (
|
{basicData.user_learn_top10[0] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[0].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[0].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[0] && (
|
{basicData.user_learn_top10[0] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -283,15 +316,16 @@ const DashboardPage = () => {
|
|||||||
src={iconN2}
|
src={iconN2}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
{basicData.user_learn_top10[1] && (
|
{basicData.user_learn_top10[1] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[1].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[1].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[1] && (
|
{basicData.user_learn_top10[1] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -308,15 +342,16 @@ const DashboardPage = () => {
|
|||||||
src={iconN3}
|
src={iconN3}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
{basicData.user_learn_top10[2] && (
|
{basicData.user_learn_top10[2] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[2].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[2].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[2] && (
|
{basicData.user_learn_top10[2] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -329,15 +364,16 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>4</div>
|
<div className={styles["item-num"]}>4</div>
|
||||||
{basicData.user_learn_top10[3] && (
|
{basicData.user_learn_top10[3] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[3].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[3].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[3] && (
|
{basicData.user_learn_top10[3] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -350,15 +386,16 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>5</div>
|
<div className={styles["item-num"]}>5</div>
|
||||||
{basicData.user_learn_top10[4] && (
|
{basicData.user_learn_top10[4] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[4].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[4].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[4] && (
|
{basicData.user_learn_top10[4] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -370,20 +407,21 @@ const DashboardPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{basicData.user_learn_top10 && (
|
{basicData?.user_learn_top10 && (
|
||||||
<div className={styles["half-list"]}>
|
<div className={styles["half-list"]}>
|
||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>6</div>
|
<div className={styles["item-num"]}>6</div>
|
||||||
{basicData.user_learn_top10[5] && (
|
{basicData.user_learn_top10[5] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[5].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[5].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[5] && (
|
{basicData.user_learn_top10[5] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -396,15 +434,16 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>7</div>
|
<div className={styles["item-num"]}>7</div>
|
||||||
{basicData.user_learn_top10[6] && (
|
{basicData.user_learn_top10[6] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[6].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[6].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[6] && (
|
{basicData.user_learn_top10[6] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -417,15 +456,16 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>8</div>
|
<div className={styles["item-num"]}>8</div>
|
||||||
{basicData.user_learn_top10[7] && (
|
{basicData.user_learn_top10[7] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[7].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[7].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[7] && (
|
{basicData.user_learn_top10[7] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -438,15 +478,16 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>9</div>
|
<div className={styles["item-num"]}>9</div>
|
||||||
{basicData.user_learn_top10[8] && (
|
{basicData.user_learn_top10[8] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[8].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[8].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[8] && (
|
{basicData.user_learn_top10[8] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -459,15 +500,16 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["rank-item"]}>
|
<div className={styles["rank-item"]}>
|
||||||
<div className={styles["left-item"]}>
|
<div className={styles["left-item"]}>
|
||||||
<div className={styles["item-num"]}>10</div>
|
<div className={styles["item-num"]}>10</div>
|
||||||
{basicData.user_learn_top10[9] && (
|
{basicData.user_learn_top10[9] &&
|
||||||
<div className={styles["item-name"]}>
|
basicData.user_learn_top10_users && (
|
||||||
{
|
<div className={styles["item-name"]}>
|
||||||
basicData.user_learn_top10_users[
|
{
|
||||||
basicData.user_learn_top10[9].user_id
|
basicData.user_learn_top10_users[
|
||||||
]?.name
|
basicData.user_learn_top10[9].user_id
|
||||||
}
|
]?.name
|
||||||
</div>
|
}
|
||||||
)}
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{basicData.user_learn_top10[9] && (
|
{basicData.user_learn_top10[9] && (
|
||||||
<div className={styles["item-time"]}>
|
<div className={styles["item-time"]}>
|
||||||
@ -489,7 +531,7 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["label"]}>部门数</div>
|
<div className={styles["label"]}>部门数</div>
|
||||||
<div className={styles["info"]}>
|
<div className={styles["info"]}>
|
||||||
<div className={styles["num"]}>
|
<div className={styles["num"]}>
|
||||||
{basicData.department_total}
|
{basicData?.department_total}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -497,7 +539,7 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["label"]}>分类数</div>
|
<div className={styles["label"]}>分类数</div>
|
||||||
<div className={styles["info"]}>
|
<div className={styles["info"]}>
|
||||||
<div className={styles["num"]}>
|
<div className={styles["num"]}>
|
||||||
{basicData.resource_category_total}
|
{basicData?.resource_category_total}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -505,7 +547,7 @@ const DashboardPage = () => {
|
|||||||
<div className={styles["label"]}>管理员</div>
|
<div className={styles["label"]}>管理员</div>
|
||||||
<div className={styles["info"]}>
|
<div className={styles["info"]}>
|
||||||
<div className={styles["num"]}>
|
<div className={styles["num"]}>
|
||||||
{basicData.admin_user_total}
|
{basicData?.admin_user_total}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,13 +23,13 @@ const DepartmentPage = () => {
|
|||||||
const permissions = useSelector(
|
const permissions = useSelector(
|
||||||
(state: any) => state.loginUser.value.permissions
|
(state: any) => state.loginUser.value.permissions
|
||||||
);
|
);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<Option[]>([]);
|
||||||
const [selectKey, setSelectKey] = useState<any>([]);
|
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||||
|
|
||||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
const [createVisible, setCreateVisible] = useState(false);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState(false);
|
||||||
const [did, setDid] = useState<number>(0);
|
const [did, setDid] = useState<number>(0);
|
||||||
const [modal, contextHolder] = Modal.useModal();
|
const [modal, contextHolder] = Modal.useModal();
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ const DepartmentPage = () => {
|
|||||||
const getData = () => {
|
const getData = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
department.departmentList().then((res: any) => {
|
department.departmentList().then((res: any) => {
|
||||||
const departments = res.data.departments;
|
const departments: DepartmentsBoxModel = res.data.departments;
|
||||||
if (JSON.stringify(departments) !== "{}") {
|
if (JSON.stringify(departments) !== "{}") {
|
||||||
const new_arr: Option[] = checkArr(departments, 0);
|
const new_arr: Option[] = checkArr(departments, 0);
|
||||||
setTreeData(new_arr);
|
setTreeData(new_arr);
|
||||||
@ -61,7 +61,7 @@ const DepartmentPage = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkArr = (departments: any[], id: number) => {
|
const checkArr = (departments: DepartmentsBoxModel, id: number) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
for (let i = 0; i < departments[id].length; i++) {
|
for (let i = 0; i < departments[id].length; i++) {
|
||||||
if (!departments[departments[id][i].id]) {
|
if (!departments[departments[id][i].id]) {
|
||||||
|
@ -28,34 +28,43 @@ const { confirm } = Modal;
|
|||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
name: string;
|
avatar: string;
|
||||||
|
create_city?: string;
|
||||||
|
create_ip?: string;
|
||||||
|
created_at?: string;
|
||||||
|
credit1?: number;
|
||||||
email: string;
|
email: string;
|
||||||
created_at: string;
|
id_card?: string;
|
||||||
credit1: number;
|
is_active?: number;
|
||||||
id_card: string;
|
is_lock?: number;
|
||||||
is_lock: number;
|
is_set_password?: number;
|
||||||
|
is_verify?: number;
|
||||||
|
login_at?: string;
|
||||||
|
name: string;
|
||||||
|
updated_at?: string;
|
||||||
|
verify_at?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MemberPage = () => {
|
const MemberPage = () => {
|
||||||
const result = new URLSearchParams(useLocation().search);
|
const result = new URLSearchParams(useLocation().search);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [list, setList] = useState<any>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
|
|
||||||
const [nickname, setNickname] = useState<string>("");
|
const [nickname, setNickname] = useState("");
|
||||||
const [email, setEmail] = useState<string>("");
|
const [email, setEmail] = useState("");
|
||||||
const [dep_ids, setDepIds] = useState<any>([]);
|
const [dep_ids, setDepIds] = useState<number[]>([]);
|
||||||
const [selLabel, setLabel] = useState<string>(
|
const [selLabel, setLabel] = useState<string>(
|
||||||
result.get("label") ? String(result.get("label")) : "全部部门"
|
result.get("label") ? String(result.get("label")) : "全部部门"
|
||||||
);
|
);
|
||||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
const [createVisible, setCreateVisible] = useState(false);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState(false);
|
||||||
const [mid, setMid] = useState<number>(0);
|
const [mid, setMid] = useState(0);
|
||||||
const [user_dep_ids, setUserDepIds] = useState<any>({});
|
const [user_dep_ids, setUserDepIds] = useState<DepIdsModel>({});
|
||||||
const [departments, setDepartments] = useState<any>({});
|
const [departments, setDepartments] = useState<DepartmentsModel>({});
|
||||||
const [did, setDid] = useState(Number(result.get("did")));
|
const [did, setDid] = useState(Number(result.get("did")));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -11,33 +11,71 @@ import { MemberLearnProgressDialog } from "./compenents/progress";
|
|||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
title: string;
|
charge: number;
|
||||||
type: string;
|
class_hour: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
total_duration: number;
|
is_required: number;
|
||||||
finished_duration: number;
|
is_show: number;
|
||||||
is_finished: boolean;
|
short_desc: string;
|
||||||
|
thumb: string;
|
||||||
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserCourseRecordsModel = {
|
||||||
|
[key: number]: UserRecordModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
type UserRecordModel = {
|
||||||
|
course_id: number;
|
||||||
|
created_at: string;
|
||||||
|
finished_at?: string;
|
||||||
|
finished_count: number;
|
||||||
|
hour_count: number;
|
||||||
|
id: number;
|
||||||
|
is_finished: number;
|
||||||
|
progress: number;
|
||||||
|
updated_at: string;
|
||||||
|
user_id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type HourCountModel = {
|
||||||
|
[key: number]: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type OptionModel = {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DepartmentsListModel = {
|
||||||
|
reated_at: string;
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
parent_chain: string;
|
||||||
|
parent_id: number;
|
||||||
|
sort: number;
|
||||||
|
updated_at: string;
|
||||||
|
};
|
||||||
|
|
||||||
const MemberLearnPage = () => {
|
const MemberLearnPage = () => {
|
||||||
let chartRef = useRef(null);
|
let chartRef = useRef(null);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const result = new URLSearchParams(useLocation().search);
|
const result = new URLSearchParams(useLocation().search);
|
||||||
const [loading2, setLoading2] = useState<boolean>(false);
|
const [loading2, setLoading2] = useState(false);
|
||||||
const [list2, setList2] = useState<any>([]);
|
const [list2, setList2] = useState<DepartmentsListModel[]>([]);
|
||||||
const [courses, setCourses] = useState<any>({});
|
const [courses, setCourses] = useState<any>({});
|
||||||
const [deps, setDeps] = useState<any>([]);
|
const [deps, setDeps] = useState<OptionModel[]>([]);
|
||||||
const [depValue, setDepValue] = useState<number>(0);
|
const [depValue, setDepValue] = useState(0);
|
||||||
const [currentCourses, setCurrentCourses] = useState<any>([]);
|
const [currentCourses, setCurrentCourses] = useState<DataType[]>([]);
|
||||||
const [openCourses, setOpenCourses] = useState<any>([]);
|
const [openCourses, setOpenCourses] = useState<CourseModel[]>([]);
|
||||||
const [records, setRecords] = useState<any>({});
|
const [records, setRecords] = useState<UserCourseRecordsModel>({});
|
||||||
const [hourCount, setHourCount] = useState<any>({});
|
const [hourCount, setHourCount] = useState<HourCountModel>({});
|
||||||
const [total2, setTotal2] = useState(0);
|
const [total2, setTotal2] = useState(0);
|
||||||
const [refresh2, setRefresh2] = useState(false);
|
const [refresh2, setRefresh2] = useState(false);
|
||||||
const [uid, setUid] = useState(Number(result.get("id")));
|
const [uid, setUid] = useState(Number(result.get("id")));
|
||||||
const [userName, setUserName] = useState<string>(String(result.get("name")));
|
const [userName, setUserName] = useState<string>(String(result.get("name")));
|
||||||
const [visiable, setVisiable] = useState(false);
|
const [visiable, setVisiable] = useState(false);
|
||||||
const [courseId, setcourseId] = useState<number>(0);
|
const [courseId, setcourseId] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setUid(Number(result.get("id")));
|
setUid(Number(result.get("id")));
|
||||||
@ -157,7 +195,7 @@ const MemberLearnPage = () => {
|
|||||||
setHourCount(res.data.user_course_hour_count);
|
setHourCount(res.data.user_course_hour_count);
|
||||||
setRecords(res.data.user_course_records);
|
setRecords(res.data.user_course_records);
|
||||||
if (res.data.departments.length > 0) {
|
if (res.data.departments.length > 0) {
|
||||||
let box: any = [];
|
let box: OptionModel[] = [];
|
||||||
res.data.departments.map((item: any) => {
|
res.data.departments.map((item: any) => {
|
||||||
box.push({
|
box.push({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
@ -223,7 +261,7 @@ const MemberLearnPage = () => {
|
|||||||
render: (_, record: any) => (
|
render: (_, record: any) => (
|
||||||
<>
|
<>
|
||||||
{records[record.id] ? (
|
{records[record.id] ? (
|
||||||
<span>{dateFormat(records[record.id].finished_at)}</span>
|
<span>{dateFormat(String(records[record.id].finished_at))}</span>
|
||||||
) : (
|
) : (
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
)}
|
)}
|
||||||
@ -232,7 +270,6 @@ const MemberLearnPage = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "学习进度",
|
title: "学习进度",
|
||||||
dataIndex: "is_finished",
|
|
||||||
render: (_, record: any) => (
|
render: (_, record: any) => (
|
||||||
<>
|
<>
|
||||||
{records[record.id] ? (
|
{records[record.id] ? (
|
||||||
|
@ -9,11 +9,9 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
Button,
|
Button,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import type { MenuProps } from "antd";
|
|
||||||
import { resource } from "../../../api";
|
import { resource } from "../../../api";
|
||||||
// import styles from "./index.module.less";
|
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons";
|
import { ExclamationCircleFilled } from "@ant-design/icons";
|
||||||
import type { ColumnsType } from "antd/es/table";
|
import type { ColumnsType } from "antd/es/table";
|
||||||
import { dateFormat } from "../../../utils/index";
|
import { dateFormat } from "../../../utils/index";
|
||||||
import { TreeCategory, UploadCoursewareButton } from "../../../compenents";
|
import { TreeCategory, UploadCoursewareButton } from "../../../compenents";
|
||||||
@ -22,34 +20,45 @@ import { CoursewareUpdateDialog } from "./compenents/update-dialog";
|
|||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
|
admin_id: number;
|
||||||
|
created_at: string;
|
||||||
|
disk: string;
|
||||||
|
extension: string;
|
||||||
|
file_id: string;
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
name: string;
|
name: string;
|
||||||
created_at: string;
|
parent_id: number;
|
||||||
|
path: string;
|
||||||
|
size: number;
|
||||||
type: string;
|
type: string;
|
||||||
number: number;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AdminUsersModel = {
|
||||||
|
[key: number]: string;
|
||||||
|
};
|
||||||
|
|
||||||
const ResourceCoursewarePage = () => {
|
const ResourceCoursewarePage = () => {
|
||||||
const result = new URLSearchParams(useLocation().search);
|
const result = new URLSearchParams(useLocation().search);
|
||||||
const [list, setList] = useState<any>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
const [adminUsers, setAdminUsers] = useState<any>({});
|
const [adminUsers, setAdminUsers] = useState<AdminUsersModel>({});
|
||||||
const [existingTypes, setExistingTypes] = useState<any>([]);
|
const [existingTypes, setExistingTypes] = useState<string[]>([]);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
||||||
const [type, setType] = useState("WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP");
|
const [type, setType] = useState("WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP");
|
||||||
const [title, setTitle] = useState<string>("");
|
const [title, setTitle] = useState("");
|
||||||
const [multiConfig, setMultiConfig] = useState<boolean>(false);
|
const [multiConfig, setMultiConfig] = useState(false);
|
||||||
const [selLabel, setLabel] = useState<string>(
|
const [selLabel, setLabel] = useState<string>(
|
||||||
result.get("label") ? String(result.get("label")) : "全部课件"
|
result.get("label") ? String(result.get("label")) : "全部课件"
|
||||||
);
|
);
|
||||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||||
const [updateId, setUpdateId] = useState(0);
|
const [updateId, setUpdateId] = useState(0);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState(false);
|
||||||
const types = [
|
const types = [
|
||||||
{ label: "全部", value: "WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP" },
|
{ label: "全部", value: "WORD,EXCEL,PPT,PDF,TXT,RAR,ZIP" },
|
||||||
{ label: "WORD", value: "WORD" },
|
{ label: "WORD", value: "WORD" },
|
||||||
|
@ -14,7 +14,7 @@ import { resource } from "../../../api";
|
|||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { UploadImageSub } from "../../../compenents/upload-image-button/upload-image-sub";
|
import { UploadImageSub } from "../../../compenents/upload-image-button/upload-image-sub";
|
||||||
import { TreeCategory, PerButton } from "../../../compenents";
|
import { TreeCategory } from "../../../compenents";
|
||||||
import { ExclamationCircleFilled, CheckOutlined } from "@ant-design/icons";
|
import { ExclamationCircleFilled, CheckOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
@ -39,14 +39,14 @@ const ResourceImagesPage = () => {
|
|||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(32);
|
const [size, setSize] = useState(32);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||||
const [selectKey, setSelectKey] = useState<any>([]);
|
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||||
const [visibleArr, setVisibleArr] = useState<any>([]);
|
const [visibleArr, setVisibleArr] = useState<boolean[]>([]);
|
||||||
const [hoverArr, setHoverArr] = useState<any>([]);
|
const [hoverArr, setHoverArr] = useState<boolean[]>([]);
|
||||||
const [selLabel, setLabel] = useState<string>(
|
const [selLabel, setLabel] = useState<string>(
|
||||||
result.get("label") ? String(result.get("label")) : "全部图片"
|
result.get("label") ? String(result.get("label")) : "全部图片"
|
||||||
);
|
);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -96,7 +96,7 @@ const ResourceImagesPage = () => {
|
|||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
setTotal(res.data.result.total);
|
setTotal(res.data.result.total);
|
||||||
setImageList(res.data.result.data);
|
setImageList(res.data.result.data);
|
||||||
let data = res.data.result.data;
|
let data: ImageItem[] = res.data.result.data;
|
||||||
let arr = [];
|
let arr = [];
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
arr.push(false);
|
arr.push(false);
|
||||||
|
@ -25,8 +25,8 @@ const ResourceCategoryPage = () => {
|
|||||||
);
|
);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [treeData, setTreeData] = useState<any>([]);
|
const [treeData, setTreeData] = useState<Option[]>([]);
|
||||||
const [selectKey, setSelectKey] = useState<any>([]);
|
const [selectKey, setSelectKey] = useState<number[]>([]);
|
||||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
||||||
const [cid, setCid] = useState<number>(0);
|
const [cid, setCid] = useState<number>(0);
|
||||||
@ -50,7 +50,7 @@ const ResourceCategoryPage = () => {
|
|||||||
const getData = () => {
|
const getData = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
resourceCategory.resourceCategoryList().then((res: any) => {
|
resourceCategory.resourceCategoryList().then((res: any) => {
|
||||||
const categories = res.data.categories;
|
const categories: CategoriesBoxModel = res.data.categories;
|
||||||
if (JSON.stringify(categories) !== "{}") {
|
if (JSON.stringify(categories) !== "{}") {
|
||||||
const new_arr: Option[] = checkArr(categories, 0);
|
const new_arr: Option[] = checkArr(categories, 0);
|
||||||
setTreeData(new_arr);
|
setTreeData(new_arr);
|
||||||
@ -59,7 +59,7 @@ const ResourceCategoryPage = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkArr = (categories: any[], id: number) => {
|
const checkArr = (categories: CategoriesBoxModel, id: number) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
for (let i = 0; i < categories[id].length; i++) {
|
for (let i = 0; i < categories[id].length; i++) {
|
||||||
if (!categories[categories[id][i].id]) {
|
if (!categories[categories[id][i].id]) {
|
||||||
|
@ -9,6 +9,12 @@ interface PropInterface {
|
|||||||
onSuccess: () => void;
|
onSuccess: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Option {
|
||||||
|
value: string | number;
|
||||||
|
title: string;
|
||||||
|
children?: Option[];
|
||||||
|
}
|
||||||
|
|
||||||
export const VideosUpdateDialog: React.FC<PropInterface> = ({
|
export const VideosUpdateDialog: React.FC<PropInterface> = ({
|
||||||
id,
|
id,
|
||||||
open,
|
open,
|
||||||
@ -16,9 +22,9 @@ export const VideosUpdateDialog: React.FC<PropInterface> = ({
|
|||||||
onSuccess,
|
onSuccess,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [init, setInit] = useState(true);
|
const [init, setInit] = useState(true);
|
||||||
const [categories, setCategories] = useState<any>([]);
|
const [categories, setCategories] = useState<Option[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInit(true);
|
setInit(true);
|
||||||
@ -33,7 +39,7 @@ export const VideosUpdateDialog: React.FC<PropInterface> = ({
|
|||||||
|
|
||||||
const getCategory = () => {
|
const getCategory = () => {
|
||||||
resourceCategory.resourceCategoryList().then((res: any) => {
|
resourceCategory.resourceCategoryList().then((res: any) => {
|
||||||
const categories = res.data.categories;
|
const categories: CategoriesBoxModel = res.data.categories;
|
||||||
if (JSON.stringify(categories) !== "{}") {
|
if (JSON.stringify(categories) !== "{}") {
|
||||||
const new_arr: any = checkArr(categories, 0, null);
|
const new_arr: any = checkArr(categories, 0, null);
|
||||||
setCategories(new_arr);
|
setCategories(new_arr);
|
||||||
@ -52,7 +58,11 @@ export const VideosUpdateDialog: React.FC<PropInterface> = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkArr = (departments: any[], id: number, counts: any) => {
|
const checkArr = (
|
||||||
|
departments: CategoriesBoxModel,
|
||||||
|
id: number,
|
||||||
|
counts: any
|
||||||
|
) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
for (let i = 0; i < departments[id].length; i++) {
|
for (let i = 0; i < departments[id].length; i++) {
|
||||||
if (!departments[departments[id][i].id]) {
|
if (!departments[departments[id][i].id]) {
|
||||||
|
@ -17,7 +17,7 @@ export const VideoPlayDialog: React.FC<PropInterface> = ({
|
|||||||
open,
|
open,
|
||||||
onCancel,
|
onCancel,
|
||||||
}) => {
|
}) => {
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && url) {
|
if (open && url) {
|
||||||
|
@ -2,7 +2,6 @@ import { useEffect, useState } from "react";
|
|||||||
import { Modal, Table, message, Space, Dropdown, Button } from "antd";
|
import { Modal, Table, message, Space, Dropdown, Button } from "antd";
|
||||||
import type { MenuProps } from "antd";
|
import type { MenuProps } from "antd";
|
||||||
import { resource } from "../../../api";
|
import { resource } from "../../../api";
|
||||||
// import styles from "./index.module.less";
|
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons";
|
import { DownOutlined, ExclamationCircleFilled } from "@ant-design/icons";
|
||||||
import type { ColumnsType } from "antd/es/table";
|
import type { ColumnsType } from "antd/es/table";
|
||||||
@ -16,32 +15,54 @@ const { confirm } = Modal;
|
|||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
name: string;
|
admin_id: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
disk: string;
|
disk: string;
|
||||||
|
extension: string;
|
||||||
|
file_id: string;
|
||||||
|
name: string;
|
||||||
|
parent_id: number;
|
||||||
|
path: string;
|
||||||
|
size: number;
|
||||||
|
type: string;
|
||||||
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VideosExtraModel = {
|
||||||
|
[key: number]: VideoModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
type VideoModel = {
|
||||||
|
duration: number;
|
||||||
|
poster: string;
|
||||||
|
rid: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type AdminUsersModel = {
|
||||||
|
[key: number]: string;
|
||||||
|
};
|
||||||
|
|
||||||
const ResourceVideosPage = () => {
|
const ResourceVideosPage = () => {
|
||||||
const result = new URLSearchParams(useLocation().search);
|
const result = new URLSearchParams(useLocation().search);
|
||||||
const [videoList, setVideoList] = useState<any>([]);
|
const [videoList, setVideoList] = useState<DataType[]>([]);
|
||||||
const [videosExtra, setVideoExtra] = useState<any>([]);
|
const [videosExtra, setVideoExtra] = useState<VideosExtraModel>({});
|
||||||
const [adminUsers, setAdminUsers] = useState<any>({});
|
const [adminUsers, setAdminUsers] = useState<AdminUsersModel>({});
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [category_ids, setCategoryIds] = useState<any>([]);
|
const [category_ids, setCategoryIds] = useState<number[]>([]);
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
||||||
const [selLabel, setLabel] = useState<string>(
|
const [selLabel, setLabel] = useState<string>(
|
||||||
result.get("label") ? String(result.get("label")) : "全部视频"
|
result.get("label") ? String(result.get("label")) : "全部视频"
|
||||||
);
|
);
|
||||||
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
const [cateId, setCateId] = useState(Number(result.get("cid")));
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState(false);
|
||||||
const [playVisible, setPlayeVisible] = useState<boolean>(false);
|
const [playVisible, setPlayeVisible] = useState(false);
|
||||||
const [multiConfig, setMultiConfig] = useState<boolean>(false);
|
const [multiConfig, setMultiConfig] = useState(false);
|
||||||
const [updateId, setUpdateId] = useState(0);
|
const [updateId, setUpdateId] = useState(0);
|
||||||
const [playUrl, setPlayUrl] = useState<string>("");
|
const [playUrl, setPlayUrl] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCateId(Number(result.get("cid")));
|
setCateId(Number(result.get("cid")));
|
||||||
@ -72,20 +93,22 @@ const ResourceVideosPage = () => {
|
|||||||
{
|
{
|
||||||
title: "视频时长",
|
title: "视频时长",
|
||||||
dataIndex: "id",
|
dataIndex: "id",
|
||||||
render: (id: string) => (
|
render: (id: number) => (
|
||||||
<DurationText duration={videosExtra[id].duration}></DurationText>
|
<DurationText duration={videosExtra[id].duration}></DurationText>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "创建人",
|
title: "创建人",
|
||||||
dataIndex: "admin_id",
|
dataIndex: "admin_id",
|
||||||
render: (text: number) =>
|
render: (admin_id: number) =>
|
||||||
JSON.stringify(adminUsers) !== "{}" && <span>{adminUsers[text]}</span>,
|
JSON.stringify(adminUsers) !== "{}" && (
|
||||||
|
<span>{adminUsers[admin_id]}</span>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
dataIndex: "created_at",
|
dataIndex: "created_at",
|
||||||
render: (text: string) => <span>{dateFormat(text)}</span>,
|
render: (created_at: string) => <span>{dateFormat(created_at)}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
|
@ -10,6 +10,11 @@ interface PropInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type selRoleModel = {
|
||||||
|
label: string;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
|
||||||
export const SystemAdministratorCreate: React.FC<PropInterface> = ({
|
export const SystemAdministratorCreate: React.FC<PropInterface> = ({
|
||||||
roleId,
|
roleId,
|
||||||
refresh,
|
refresh,
|
||||||
@ -17,8 +22,8 @@ export const SystemAdministratorCreate: React.FC<PropInterface> = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [roles, setRoles] = useState<any>([]);
|
const [roles, setRoles] = useState<selRoleModel[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
@ -43,7 +48,7 @@ export const SystemAdministratorCreate: React.FC<PropInterface> = ({
|
|||||||
const getParams = () => {
|
const getParams = () => {
|
||||||
adminUser.createAdminUser().then((res: any) => {
|
adminUser.createAdminUser().then((res: any) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
let roles = res.data.roles;
|
let roles: RoleModel[] = res.data.roles;
|
||||||
for (let i = 0; i < roles.length; i++) {
|
for (let i = 0; i < roles.length; i++) {
|
||||||
arr.push({
|
arr.push({
|
||||||
label: roles[i].name,
|
label: roles[i].name,
|
||||||
|
@ -10,6 +10,11 @@ interface PropInterface {
|
|||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type selRoleModel = {
|
||||||
|
label: string;
|
||||||
|
value: number;
|
||||||
|
};
|
||||||
|
|
||||||
export const SystemAdministratorUpdate: React.FC<PropInterface> = ({
|
export const SystemAdministratorUpdate: React.FC<PropInterface> = ({
|
||||||
id,
|
id,
|
||||||
refresh,
|
refresh,
|
||||||
@ -18,8 +23,8 @@ export const SystemAdministratorUpdate: React.FC<PropInterface> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [init, setInit] = useState(true);
|
const [init, setInit] = useState(true);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [roles, setRoles] = useState<any>([]);
|
const [roles, setRoles] = useState<selRoleModel[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
@ -40,7 +45,7 @@ export const SystemAdministratorUpdate: React.FC<PropInterface> = ({
|
|||||||
const getParams = () => {
|
const getParams = () => {
|
||||||
adminUser.createAdminUser().then((res: any) => {
|
adminUser.createAdminUser().then((res: any) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
let roles = res.data.roles;
|
let roles: RoleModel[] = res.data.roles;
|
||||||
for (let i = 0; i < roles.length; i++) {
|
for (let i = 0; i < roles.length; i++) {
|
||||||
arr.push({
|
arr.push({
|
||||||
label: roles[i].name,
|
label: roles[i].name,
|
||||||
@ -53,7 +58,7 @@ export const SystemAdministratorUpdate: React.FC<PropInterface> = ({
|
|||||||
|
|
||||||
const getDetail = () => {
|
const getDetail = () => {
|
||||||
adminUser.AdminUser(id).then((res: any) => {
|
adminUser.AdminUser(id).then((res: any) => {
|
||||||
let user = res.data.user;
|
let user: AdminUserDetailModel = res.data.user;
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
email: user.email,
|
email: user.email,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
|
@ -15,34 +15,36 @@ const { confirm } = Modal;
|
|||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
name: string;
|
created_at: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
is_ban_login: number;
|
||||||
login_at: string;
|
login_at: string;
|
||||||
login_ip: string;
|
login_ip: string;
|
||||||
is_ban_login: number;
|
login_times: number;
|
||||||
|
name: string;
|
||||||
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SystemAdministratorPage = () => {
|
const SystemAdministratorPage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [list, setList] = useState<any>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
const [roles, setRoles] = useState<any>([]);
|
const [roles, setRoles] = useState<RolesModel>({});
|
||||||
const [userRoleIds, setUserRoleIds] = useState<any>({});
|
const [userRoleIds, setUserRoleIds] = useState<RoleIdsModel>({});
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [createVisible, setCreateVisible] = useState<boolean>(false);
|
const [createVisible, setCreateVisible] = useState(false);
|
||||||
const [updateVisible, setUpdateVisible] = useState<boolean>(false);
|
const [updateVisible, setUpdateVisible] = useState(false);
|
||||||
const [createRoleVisible, setCreateRoleVisible] = useState<boolean>(false);
|
const [createRoleVisible, setCreateRoleVisible] = useState(false);
|
||||||
const [updateRoleVisible, setUpdateRoleVisible] = useState<boolean>(false);
|
const [updateRoleVisible, setUpdateRoleVisible] = useState(false);
|
||||||
const [cid, setCid] = useState<number>(0);
|
const [cid, setCid] = useState(0);
|
||||||
const [role_ids, setRoleIds] = useState<any>([]);
|
const [role_ids, setRoleIds] = useState<number[]>([]);
|
||||||
const [selLabel, setLabel] = useState<string>("全部管理员");
|
const [selLabel, setLabel] = useState("全部管理员");
|
||||||
const [roleDelSuccess, setRoleDelSuccess] = useState(false);
|
const [roleDelSuccess, setRoleDelSuccess] = useState(false);
|
||||||
const [isSuper, setIsSuper] = useState(false);
|
const [isSuper, setIsSuper] = useState(false);
|
||||||
|
const [name, setName] = useState("");
|
||||||
const [name, setName] = useState<string>("");
|
|
||||||
|
|
||||||
const columns: ColumnsType<DataType> = [
|
const columns: ColumnsType<DataType> = [
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState } from "react";
|
||||||
import { Modal, Form } from "antd";
|
import { Modal, Form } from "antd";
|
||||||
|
|
||||||
interface PropInterface {
|
interface PropInterface {
|
||||||
@ -15,7 +15,7 @@ export const AdminLogDetailDialog: React.FC<PropInterface> = ({
|
|||||||
result,
|
result,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
const onFinish = (values: any) => {};
|
const onFinish = (values: any) => {};
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Table, Typography, Input, Button, DatePicker } from "antd";
|
import { Table, Typography, Input, Button, DatePicker } from "antd";
|
||||||
import { adminLog } from "../../../api";
|
import { adminLog } from "../../../api";
|
||||||
// import styles from "./index.module.less";
|
|
||||||
import type { ColumnsType } from "antd/es/table";
|
import type { ColumnsType } from "antd/es/table";
|
||||||
import { dateWholeFormat, transUtcTime } from "../../../utils/index";
|
import { dateWholeFormat, transUtcTime } from "../../../utils/index";
|
||||||
import { AdminLogDetailDialog } from "./compenents/detail-dialog";
|
import { AdminLogDetailDialog } from "./compenents/detail-dialog";
|
||||||
@ -11,28 +10,32 @@ import moment from "moment";
|
|||||||
interface DataType {
|
interface DataType {
|
||||||
id: React.Key;
|
id: React.Key;
|
||||||
admin_id: number;
|
admin_id: number;
|
||||||
ip: string;
|
|
||||||
opt: string;
|
|
||||||
admin_name: string;
|
admin_name: string;
|
||||||
module: string;
|
|
||||||
created_at: string;
|
created_at: string;
|
||||||
title: string;
|
error_msg?: string;
|
||||||
|
ip: string;
|
||||||
ip_area: string;
|
ip_area: string;
|
||||||
|
method: string;
|
||||||
|
module: string;
|
||||||
|
opt: number;
|
||||||
param: string;
|
param: string;
|
||||||
|
request_method: string;
|
||||||
result: string;
|
result: string;
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SystemLogPage = () => {
|
const SystemLogPage = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [size, setSize] = useState(10);
|
const [size, setSize] = useState(10);
|
||||||
const [list, setList] = useState<any>([]);
|
const [list, setList] = useState<DataType[]>([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
const [title, setTitle] = useState("");
|
const [title, setTitle] = useState("");
|
||||||
const [adminId, setAdminId] = useState("");
|
const [adminId, setAdminId] = useState("");
|
||||||
const [adminName, setAdminName] = useState("");
|
const [adminName, setAdminName] = useState("");
|
||||||
const [created_at, setCreatedAt] = useState<any>([]);
|
const [created_at, setCreatedAt] = useState<string[]>([]);
|
||||||
const [createdAts, setCreatedAts] = useState<any>([]);
|
const [createdAts, setCreatedAts] = useState<any>([]);
|
||||||
const [param, setParam] = useState("");
|
const [param, setParam] = useState("");
|
||||||
const [result, setResult] = useState("");
|
const [result, setResult] = useState("");
|
||||||
|
@ -19,9 +19,9 @@ export const SystemAdminrolesCreate: React.FC<PropInterface> = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [permissions, setPermissions] = useState<any>([]);
|
const [permissions, setPermissions] = useState<Option[]>([]);
|
||||||
const [actions, setActions] = useState<any>([]);
|
const [actions, setActions] = useState<Option[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
@ -31,9 +31,9 @@ export const SystemAdminrolesUpdate: React.FC<PropInterface> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [init, setInit] = useState(true);
|
const [init, setInit] = useState(true);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [permissions, setPermissions] = useState<any>([]);
|
const [permissions, setPermissions] = useState<Option[]>([]);
|
||||||
const [actions, setActions] = useState<any>([]);
|
const [actions, setActions] = useState<Option[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
@ -20,10 +20,10 @@ import type { CheckboxChangeEvent } from "antd/es/checkbox";
|
|||||||
|
|
||||||
const SystemConfigPage = () => {
|
const SystemConfigPage = () => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [logo, setLogo] = useState<string>("");
|
const [logo, setLogo] = useState("");
|
||||||
const [thumb, setThumb] = useState<string>("");
|
const [thumb, setThumb] = useState("");
|
||||||
const [avatar, setAvatar] = useState<string>("");
|
const [avatar, setAvatar] = useState("");
|
||||||
const [tabKey, setTabKey] = useState(1);
|
const [tabKey, setTabKey] = useState(1);
|
||||||
const [nameChecked, setNameChecked] = useState(false);
|
const [nameChecked, setNameChecked] = useState(false);
|
||||||
const [emailChecked, setEmailChecked] = useState(false);
|
const [emailChecked, setEmailChecked] = useState(false);
|
||||||
|
122
src/playedu.d.ts
vendored
122
src/playedu.d.ts
vendored
@ -15,6 +15,128 @@ declare global {
|
|||||||
poster: string; //视频帧
|
poster: string; //视频帧
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UserModel {
|
||||||
|
avatar: string;
|
||||||
|
create_city?: string;
|
||||||
|
create_ip?: string;
|
||||||
|
created_at?: string;
|
||||||
|
credit1?: number;
|
||||||
|
email: string;
|
||||||
|
id: number;
|
||||||
|
id_card?: string;
|
||||||
|
is_active?: number;
|
||||||
|
is_lock?: number;
|
||||||
|
is_set_password?: number;
|
||||||
|
is_verify?: number;
|
||||||
|
login_at?: string;
|
||||||
|
name: string;
|
||||||
|
updated_at?: string;
|
||||||
|
verify_at?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdminUserDetailModel {
|
||||||
|
created_at: string;
|
||||||
|
email: string;
|
||||||
|
id: number;
|
||||||
|
is_ban_login: number;
|
||||||
|
login_at: string;
|
||||||
|
login_ip: string;
|
||||||
|
login_times: number;
|
||||||
|
name: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CourseModel {
|
||||||
|
charge: number;
|
||||||
|
class_hour: number;
|
||||||
|
created_at: string;
|
||||||
|
id: number;
|
||||||
|
is_required: number;
|
||||||
|
is_show: number;
|
||||||
|
short_desc: string;
|
||||||
|
thumb: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CategoriesBoxModel {
|
||||||
|
[key: number]: CategoriesItemModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CategoriesItemModel {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
parent_chain: string;
|
||||||
|
parent_id: number;
|
||||||
|
sort: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CategoriesModel {
|
||||||
|
[key: number]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DepartmentsModel {
|
||||||
|
[key: number]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DepIdsModel {
|
||||||
|
[key: number]: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CategoryIdsModel {
|
||||||
|
[key: number]: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DepartmentsBoxModel {
|
||||||
|
[key: number]: DepartmentsItemModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DepartmentsItemModel {
|
||||||
|
created_at: string;
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
parent_chain: string;
|
||||||
|
parent_id: number;
|
||||||
|
sort: number;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RolesModel {
|
||||||
|
[key: number]: RoleModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RoleModel {
|
||||||
|
created_at: string;
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
slug: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RoleIdsModel {
|
||||||
|
[key: number]: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CourseChaptersModel {
|
||||||
|
id?: number;
|
||||||
|
hours: CourseHourModel[];
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CourseHourModel {
|
||||||
|
id?: number;
|
||||||
|
duration: number;
|
||||||
|
name: string;
|
||||||
|
rid: number;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AttachmentDataModel {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
rid: number;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user