学员线上课学习进度

This commit is contained in:
禺狨 2023-04-23 14:54:23 +08:00
parent 1aa209640d
commit c7fa24021b
4 changed files with 307 additions and 82 deletions

View File

@ -121,3 +121,25 @@ export function departmentProgress(
...params,
});
}
export function learnCoursesProgress(
id: number,
courseId: number,
params: any
) {
return client.get(`/backend/v1/user/${id}/learn-course/${courseId} `, params);
}
export function destroyAllUserLearned(id: number, courseId: number) {
return client.destroy(`/backend/v1/user/${id}/learn-course/${courseId}`);
}
export function destroyUserLearned(
id: number,
courseId: number,
hourId: number
) {
return client.destroy(
`/backend/v1/user/${id}/learn-course/${courseId}/hour/${hourId}`
);
}

View File

@ -0,0 +1,252 @@
import { useState, useEffect } from "react";
import styles from "./progrss.module.less";
import { Table, Modal, message } from "antd";
import { PerButton, DurationText } from "../../../compenents";
import { user as member } from "../../../api/index";
import type { ColumnsType } from "antd/es/table";
import { dateFormat } from "../../../utils/index";
import { ExclamationCircleFilled } from "@ant-design/icons";
const { confirm } = Modal;
interface DataType {
id: React.Key;
title: string;
type: string;
created_at: string;
duration: number;
finished_duration: number;
is_finished: boolean;
finished_at: boolean;
}
interface PropInterface {
open: boolean;
uid: number;
id: number;
onCancel: () => void;
}
export const MemberLearnProgressDialog: React.FC<PropInterface> = ({
open,
uid,
id,
onCancel,
}) => {
const [loading, setLoading] = useState<boolean>(false);
const [list, setList] = useState<any>([]);
const [records, setRecords] = useState<any>({});
const [refresh, setRefresh] = useState(false);
useEffect(() => {
if (open) {
getData();
}
}, [uid, id, open, refresh]);
const getData = () => {
if (loading) {
return;
}
setLoading(true);
member.learnCoursesProgress(uid, id, {}).then((res: any) => {
setList(res.data.hours);
setRecords(res.data.learn_records);
setLoading(false);
});
};
const column: ColumnsType<DataType> = [
{
title: "课时标题",
dataIndex: "title",
render: (title: string) => (
<>
<span>{title}</span>
</>
),
},
{
title: "总时长",
width: 120,
dataIndex: "duration",
render: (duration: number) => (
<>
<DurationText duration={duration}></DurationText>
</>
),
},
{
title: "已学习时长",
width: 120,
dataIndex: "finished_duration",
render: (_, record: any) => (
<>
{records && records[record.id] ? (
<span>
<DurationText
duration={records[record.id].finished_duration || 0}
></DurationText>
</span>
) : (
<span>-</span>
)}
</>
),
},
{
title: "是否学完",
width: 100,
dataIndex: "is_finished",
render: (_, record: any) => (
<>
{records &&
records[record.id] &&
records[record.id].is_finished === 1 ? (
<span className="c-green"></span>
) : (
<span className="c-red"></span>
)}
</>
),
},
{
title: "开始时间",
width: 150,
dataIndex: "created_at",
render: (_, record: any) => (
<>
{records && records[record.id] ? (
<span>{dateFormat(records[record.id].created_at)}</span>
) : (
<span>-</span>
)}
</>
),
},
{
title: "学完时间",
width: 150,
dataIndex: "finished_at",
render: (_, record: any) => (
<>
{records && records[record.id] ? (
<span>{dateFormat(records[record.id].finished_at)}</span>
) : (
<span>-</span>
)}
</>
),
},
{
title: "操作",
key: "action",
fixed: "right",
width: 70,
render: (_, record: any) => (
<>
{records && records[record.id] ? (
<PerButton
type="link"
text="删除"
class="b-link c-red"
icon={null}
p="user-learn-destroy"
onClick={() => {
clearSingleProgress(records[record.id].hour_id);
}}
disabled={null}
/>
) : (
<span>-</span>
)}
</>
),
},
];
const clearProgress = () => {
confirm({
title: "操作确认",
icon: <ExclamationCircleFilled />,
content: "确认删除此课程下所有课时的学习记录?",
centered: true,
okText: "确认",
cancelText: "取消",
onOk() {
member.destroyAllUserLearned(uid, id).then((res: any) => {
message.success("操作成功");
setRefresh(!refresh);
});
},
onCancel() {
console.log("Cancel");
},
});
};
const clearSingleProgress = (hour_id: number) => {
if (hour_id === 0) {
return;
}
confirm({
title: "操作确认",
icon: <ExclamationCircleFilled />,
content: "确认删除此课时的学习记录?",
centered: true,
okText: "确认",
cancelText: "取消",
onOk() {
member.destroyUserLearned(uid, id, hour_id).then((res: any) => {
message.success("操作成功");
setRefresh(!refresh);
});
},
onCancel() {
console.log("Cancel");
},
});
};
return (
<>
<Modal
title="课时学习进度"
centered
forceRender
open={open}
width={1000}
onOk={() => onCancel()}
onCancel={() => onCancel()}
maskClosable={false}
footer={null}
>
<div className="d-flex mt-24">
<PerButton
type="primary"
text="清空"
class="c-white"
icon={null}
p="user-learn-destroy"
onClick={() => {
clearProgress();
}}
disabled={null}
/>
</div>
<div
className="d-flex mt-24"
style={{ maxHeight: 800, overflowY: "auto" }}
>
<Table
columns={column}
dataSource={list}
loading={loading}
rowKey={(record) => record.id}
pagination={false}
/>
</div>
</Modal>
</>
);
};

View File

@ -1,13 +1,13 @@
import { useState, useEffect, useRef } from "react";
import styles from "./learn.module.less";
import { Row, Image, Table } from "antd";
import { useLocation } from "react-router-dom";
import { Row, Image, Table, Button } from "antd";
import { useLocation, useNavigate } from "react-router-dom";
import { BackBartment, DurationText } from "../../compenents";
import { dateFormat } from "../../utils/index";
import { user as member } from "../../api/index";
import * as echarts from "echarts";
import type { ColumnsType } from "antd/es/table";
import { duration } from "moment";
import { MemberLearnProgressDialog } from "./compenents/progress";
interface DataType {
id: React.Key;
@ -21,6 +21,7 @@ interface DataType {
const MemberLearnPage = () => {
let chartRef = useRef(null);
const navigate = useNavigate();
const result = new URLSearchParams(useLocation().search);
const [loading, setLoading] = useState<boolean>(false);
const [page, setPage] = useState(1);
@ -37,6 +38,8 @@ const MemberLearnPage = () => {
const [total2, setTotal2] = useState(0);
const [refresh2, setRefresh2] = useState(false);
const [uid, setUid] = useState(Number(result.get("id")));
const [visiable, setVisiable] = useState(false);
const [courseId, setcourseId] = useState<number>(0);
useEffect(() => {
setUid(Number(result.get("id")));
@ -169,20 +172,6 @@ const MemberLearnPage = () => {
});
};
const paginationProps = {
current: page, //当前页码
pageSize: size,
total: total, // 总条数
onChange: (page: number, pageSize: number) =>
handlePageChange(page, pageSize), //改变页码的函数
showSizeChanger: true,
};
const handlePageChange = (page: number, pageSize: number) => {
setPage(page);
setSize(pageSize);
};
const paginationProps2 = {
current: page2, //当前页码
pageSize: size2,
@ -197,59 +186,6 @@ const MemberLearnPage = () => {
setSize2(pageSize);
};
const columns: ColumnsType<DataType> = [
{
title: "课时标题",
dataIndex: "title",
render: (_, record: any) => (
<>
<span>{hours[record.hour_id].title}</span>
</>
),
},
{
title: "课时类型",
dataIndex: "type",
render: (_, record: any) => (
<>
<span>{hours[record.hour_id].type}</span>
</>
),
},
{
title: "总时长",
dataIndex: "total_duration",
render: (_, record: any) => (
<>
<DurationText duration={record.total_duration}></DurationText>
</>
),
},
{
title: "已学习时长",
dataIndex: "finished_duration",
render: (_, record: any) => (
<>
<DurationText duration={record.finished_duration || 0}></DurationText>
</>
),
},
{
title: "状态",
dataIndex: "is_finished",
render: (_, record: any) => (
<>
{record.is_finished === 1 ? <span></span> : <span></span>}
</>
),
},
{
title: "时间",
dataIndex: "created_at",
render: (text: string) => <span>{dateFormat(text)}</span>,
},
];
const column2: ColumnsType<DataType> = [
{
title: "课程名称",
@ -306,11 +242,38 @@ const MemberLearnPage = () => {
</>
),
},
{
title: "操作",
key: "action",
fixed: "right",
width: 100,
render: (_, record: any) => (
<Button
type="link"
className="b-link c-red"
onClick={() => {
setcourseId(record.course_id);
setVisiable(true);
}}
>
</Button>
),
},
];
return (
<>
<Row className="playedu-main-top mb-24">
<MemberLearnProgressDialog
open={visiable}
uid={uid}
id={courseId}
onCancel={() => {
setVisiable(false);
setRefresh2(!refresh2);
}}
></MemberLearnProgressDialog>
<div className="float-left mb-24">
<BackBartment title="学员学习" />
</div>
@ -334,18 +297,6 @@ const MemberLearnPage = () => {
/>
</div>
</Row>
{/* <div className="playedu-main-top mb-24">
<div className={styles["large-title"]}></div>
<div className="float-left mt-24">
<Table
columns={columns}
dataSource={list}
loading={loading}
pagination={paginationProps}
rowKey={(record) => record.id}
/>
</div>
</div> */}
</>
);
};