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

319 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { useEffect, useState } from "react";
import {
Button,
Col,
DatePicker,
Form,
Input,
InputNumber,
Modal,
Radio,
Row,
Select,
Space,
Spin,
Tabs,
message,
} from "antd";
import dayjs from "dayjs";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { tools } from "@cqsjjb/jjb-common-lib";
import { NS_COURSEWARE, NS_ORG_INFO } from "~/enumerate/namespace";
import {
CLASS_UNIT_TYPE_OPTIONS,
CLASS_YES_NO_OPTIONS,
COURSEWARE_TRAINING_TYPE_OPTIONS,
} from "~/enumerate/constant";
import StudentTab from "./StudentTab";
import CourseTab from "./CourseTab";
const { router } = tools;
const { RangePicker } = DatePicker;
/** 教育培训 — 新增/编辑班级 */
function ClassAddPage(props) {
const [form] = Form.useForm();
/** 已保存的班级 id有值时解锁学员/课程 Tab */
const [savedClassId, setSavedClassId] = useState(router.query.classId);
const [orgOptions, setOrgOptions] = useState([]);
const [activeTab, setActiveTab] = useState("base");
const isEdit = !!router.query.classId;
const unlocked = !!savedClassId;
const confirmLoading = props.courseware?.classConfirmLoading;
const completeLoading = props.courseware?.classCompleteLoading;
const detailLoading = props.courseware?.classDetailLoading;
const {
classDetailData,
} = props.courseware || {};
/** 是否开启考试:选否时隐藏其余考试相关字段 */
const openExam = Form.useWatch("openExam", form);
const handleUnitChange = (unitId) => {
const target = orgOptions.find((item) => item.value === unitId);
form.setFieldValue("unitName", target?.label);
};
useEffect(() => {
(async () => {
props.registeredOrgList({ current: 1, size: 200, state: 0 }).then(orgRes => {
const list = orgRes?.data || [];
const options = list.map((item) => ({
label: item.unitName,
value: item.id,
}));
setOrgOptions(options);
})
if (!isEdit) return;
const res = await props.classDetail({ id: router.query.classId });
if (res?.success !== false && res?.data) {
const data = res.data;
let unitId = data.unitId;
form.setFieldsValue({
...data,
unitId,
trainingDateRange:
data.startDate && data.endDate
? [dayjs(data.startDate), dayjs(data.endDate)]
: undefined,
});
} else {
props.history.goBack();
}
})();
}, []);
const handleSubmit = async () => {
try {
const values = await form.validateFields();
// 培训日期范围拆为后端 startDate/endDateyyyy-MM-dd
const { trainingDateRange, ...rest } = values;
const payload = {
...rest,
startDate: trainingDateRange?.[0]?.format("YYYY-MM-DD"),
endDate: trainingDateRange?.[1]?.format("YYYY-MM-DD"),
...(isEdit ? { id: router.query.classId } : {}),
};
const res = await (isEdit
? props.classModify(payload)
: props.classAdd(payload));
if (res?.success === false) return;
message.success("保存成功");
if (isEdit) return;
// 新增save 接口返回新班级 id同步 URL 并解锁学员/课程 Tab
const newId = res?.data;
if (newId) {
router.query = { ...router.query, classId: newId };
setSavedClassId(newId);
}
} catch {
// 表单校验失败或请求异常,由 antd / http 层提示
}
};
const handleComplete = () => {
Modal.confirm({
title: "提示",
content: "完成之后将开班,不能再进行其它更改,确认继续吗?",
okText: "确定",
cancelText: "取消",
onOk: async () => {
const res = await props.classComplete({ id: savedClassId });
if (res?.success === false) return;
message.success("完成成功");
props.history.goBack();
},
});
};
return (
<PageLayout
title={isEdit ? "编辑班级" : "新增班级"}
history={props.history}
previous
footer={
<Space>
<Button onClick={() => props.history.goBack()}>取消</Button>
<Button type="primary" loading={confirmLoading} onClick={handleSubmit}>
保存
</Button>
{activeTab === "course" && unlocked && classDetailData?.status === 0 && (
<Button type="primary" loading={completeLoading} onClick={handleComplete}>
完成
</Button>
)}
</Space>
}
>
<Tabs
activeKey={activeTab}
onChange={setActiveTab}
items={[
{
key: "base",
label: "基础信息",
children: (
<Spin spinning={isEdit && !!detailLoading}>
<Form
form={form}
disabled={classDetailData?.status === 2}
layout="vertical"
scrollToFirstError
initialValues={{
openExam: 0,
examFaceRecognition: 0,
faceRecognition: 0,
shuffleQuestions: 0,
}}
>
<h3>基本信息</h3>
<Row gutter={24}>
<Col span={12}>
<Form.Item label="参训单位类型" name="unitType">
<Select
placeholder="请选择"
allowClear
options={CLASS_UNIT_TYPE_OPTIONS}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="班级名称"
name="className"
rules={[{ required: true, message: "请输入班级名称" }]}
>
<Input placeholder="请输入班级名称" allowClear maxLength={50} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="参训单位"
name="unitId"
rules={[{ required: true, message: "请选择参训单位" }]}
>
<Select
placeholder="请选择参训单位"
allowClear
showSearch
optionFilterProp="label"
options={orgOptions}
onChange={handleUnitChange}
/>
</Form.Item>
<Form.Item name="unitName" hidden>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="培训日期"
name="trainingDateRange"
rules={[{ required: true, message: "请选择培训日期" }]}
>
<RangePicker style={{ width: "100%" }} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="培训类型"
name="trainingType"
rules={[{ required: true, message: "请选择培训类型" }]}
>
<Select
placeholder="请选择培训类型"
allowClear
options={COURSEWARE_TRAINING_TYPE_OPTIONS}
/>
</Form.Item>
</Col>
</Row>
<h3>基本设置</h3>
<Row gutter={24}>
<Col span={12}>
<Form.Item label="是否开启考试" name="openExam" extra='不考试的班级,学员学习完所有课程,即为完成学业。'>
<Radio.Group options={CLASS_YES_NO_OPTIONS} />
</Form.Item>
</Col>
{openExam === 1 && (
<>
<Col span={12}>
<Form.Item label="考试次数" name="examCount">
<InputNumber
placeholder="请输入考试次数"
min={1}
max={10}
precision={0}
style={{ width: "100%" }}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="考试前人脸识别" name="examFaceRecognition">
<Radio.Group options={CLASS_YES_NO_OPTIONS} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="考试中人脸识别" name="faceRecognition">
<Radio.Group options={CLASS_YES_NO_OPTIONS} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="人脸识别时间(分钟)" name="faceRecognitionTime">
<InputNumber
placeholder="请输入人脸识别时间"
min={1}
max={60}
precision={0}
style={{ width: "100%" }}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="是否打乱试题顺序" name="shuffleQuestions">
<Radio.Group options={CLASS_YES_NO_OPTIONS} />
</Form.Item>
</Col>
</>
)}
</Row>
</Form>
</Spin>
),
},
{
key: "student",
label: "学员",
disabled: !unlocked,
children: unlocked ? (
<StudentTab classId={savedClassId} history={props.history} form={form} />
) : null,
},
{
key: "course",
label: "课程",
disabled: !unlocked,
children: unlocked ? (
<CourseTab classId={savedClassId} history={props.history} />
) : null,
},
]}
/>
</PageLayout>
);
}
export default Connect([NS_COURSEWARE, NS_ORG_INFO], true)(ClassAddPage);