safety-eval-service-frontend/src/pages/Container/EduTraining/ClassManage/index.js

279 lines
7.5 KiB
JavaScript
Raw Normal View History

2026-08-21 15:45:34 +08:00
import { useEffect } from "react";
import { Badge, Button, Form, Input, Modal, Table, message } from "antd";
import dayjs from "dayjs";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
import SearchForm from "~/components/SearchForm";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { tools } from "@cqsjjb/jjb-common-lib";
import { NS_COURSEWARE } from "~/enumerate/namespace";
import {
CLASS_STATUS_MAP,
CLASS_STATUS_OPTIONS,
COURSEWARE_TRAINING_TYPE_MAP,
COURSEWARE_TRAINING_TYPE_OPTIONS,
} from "~/enumerate/constant";
const { router } = tools;
/** 涉及学员人员数 / 完成人员数:学员统计接口未接入,暂用假数据 */
const MOCK_STUDENT_COUNT = 10;
const MOCK_COMPLETED_COUNT = 5;
/** 班级总人次:同上,暂用假数据 */
const MOCK_TOTAL_PERSON_TIMES = 93;
/** 搜索表单值 → 查询参数培训时间范围拆为后端字段yyyy-MM-dd */
const buildQuery = (value) => {
const { trainingDateRange, ...rest } = value || {};
return {
...rest,
...(trainingDateRange?.[0]
? { startDateBegin: trainingDateRange[0].format("YYYY-MM-DD") }
: {}),
...(trainingDateRange?.[1]
? { endDateEnd: trainingDateRange[1].format("YYYY-MM-DD") }
: {}),
current: 1,
size: 10,
};
};
/** 教育培训 — 班级管理 */
function ClassManagePage(props) {
const [searchForm] = Form.useForm();
const { courseware } = props;
const { classList, classTotal: total, classLoading: loading } =
courseware || {};
const handleSearch = () => {
props.classPage(router.query);
};
useEffect(() => {
const { startDateBegin, endDateEnd, ...rest } = router.query;
searchForm.setFieldsValue({
...rest,
...(startDateBegin && endDateEnd
? { trainingDateRange: [dayjs(startDateBegin), dayjs(endDateEnd)] }
: {}),
});
handleSearch();
}, []);
const onDelete = (record) => {
Modal.confirm({
title: "提示",
content: "数据将会删除,您是否确认删除?",
okText: "是",
cancelText: "否",
onOk: () => {
message.info(`班级「${record.className}」删除接口待接入`);
},
});
};
const columns = [
{
title: "序号",
width: 70,
fixed: "left",
render: (_, __, index) => {
const current = Number(router.query.current) || 1;
const size = Number(router.query.size) || 10;
return (current - 1) * size + index + 1;
},
},
{
title: "参训单位",
dataIndex: "unitName",
width: 180,
ellipsis: true,
render: (v) => v || "-",
},
{
title: "班级名称",
dataIndex: "className",
width: 180,
ellipsis: true,
},
{
title: "班级编码",
dataIndex: "classCode",
width: 180,
},
{
title: "培训类型",
dataIndex: "trainingType",
width: 160,
ellipsis: true,
render: (v) => COURSEWARE_TRAINING_TYPE_MAP[v] ?? (v || "-"),
},
{
title: "培训开始时间",
dataIndex: "startDate",
width: 120,
render: (v) => v || "-",
},
{
title: "结束时间",
dataIndex: "endDate",
width: 120,
render: (v) => v || "-",
},
{
title: "涉及学员人员数",
dataIndex: "studentCount",
width: 120,
render: () => MOCK_STUDENT_COUNT,
},
{
title: "完成人员数",
dataIndex: "completedCount",
width: 100,
render: () => MOCK_COMPLETED_COUNT,
},
{
title: "班级状态",
dataIndex: "status",
width: 100,
render: (v) => {
const item = CLASS_STATUS_MAP[v];
return item ? <Badge status={item.status} text={item.label} /> : "-";
},
},
{
title: "操作",
width: 240,
fixed: "right",
render: (_, record) => (
<TableAction>
<Button
type="link"
size="small"
onClick={() => message.info("班级编辑接口待接入")}
>
编辑
</Button>
<Button
type="link"
size="small"
onClick={() => message.info("学员列表功能待接入")}
>
学员列表
</Button>
<Button
type="link"
size="small"
onClick={() => message.info("课程列表功能待接入")}
>
课程列表
</Button>
{record.status === 2 && (
<Button
type="link"
size="small"
onClick={() => message.info("班级延期接口待接入")}
>
延期
</Button>
)}
<Button
danger
type="link"
size="small"
onClick={() => onDelete(record)}
>
删除
</Button>
</TableAction>
),
},
];
return (
<PageLayout title="班级管理">
<SearchForm
style={{ marginBottom: 24 }}
form={searchForm}
loading={loading}
formLine={[
<Form.Item key="classCode" name="classCode">
<ControlWrapper.Input
label="班级编码"
placeholder="请输入"
allowClear
maxLength={50}
/>
</Form.Item>,
<Form.Item key="className" name="className">
<ControlWrapper.Input
label="班级名称"
placeholder="请输入"
allowClear
maxLength={50}
/>
</Form.Item>,
<Form.Item key="trainingType" name="trainingType">
<ControlWrapper.Select
label="培训类型"
placeholder="请选择"
allowClear
style={{ width: "100%" }}
options={COURSEWARE_TRAINING_TYPE_OPTIONS}
/>
</Form.Item>,
<Form.Item key="status" name="status">
<ControlWrapper.Select
label="班级状态"
placeholder="请选择"
allowClear
style={{ width: "100%" }}
options={CLASS_STATUS_OPTIONS}
/>
</Form.Item>,
<Form.Item key="trainingDateRange" name="trainingDateRange">
<ControlWrapper.DatePicker.RangePicker label="培训时间" />
</Form.Item>,
]}
onReset={(value) => {
router.query = buildQuery(value);
handleSearch();
}}
onFinish={(value) => {
router.query = buildQuery(value);
handleSearch();
}}
/>
<Table
rowKey="id"
columns={columns}
dataSource={Array.isArray(classList) ? classList : []}
scroll={{ x: 1800, y: props.scrollY }}
loading={loading}
pagination={{
total,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (t) => `${t}`,
current: Number(router.query.current) || 1,
pageSize: Number(router.query.size) || 10,
onChange: (page, pageSize) => {
router.query = { ...router.query, current: page, size: pageSize };
handleSearch();
},
}}
/>
</PageLayout>
);
}
export default Connect(
[NS_COURSEWARE],
true,
)(AntdTableFuncControl(ClassManagePage));