fix
parent
2841ec6b90
commit
8dfff0c4a1
|
|
@ -1,10 +1,11 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Button, Form, Table, message } from "antd";
|
import { Badge, Button, Form, Input, Modal, Table, message } from "antd";
|
||||||
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
import SearchForm from "~/components/SearchForm";
|
import SearchForm from "~/components/SearchForm";
|
||||||
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
import { NS_COURSEWARE } from "~/enumerate/namespace";
|
||||||
|
import { COURSEWARE_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
|
||||||
/** 视频累计时长(小时)→ “X分钟Y秒” */
|
/** 视频累计时长(小时)→ “X分钟Y秒” */
|
||||||
const formatVideoDuration = (hours) => {
|
const formatVideoDuration = (hours) => {
|
||||||
|
|
@ -18,11 +19,18 @@ function ClassCourseTab(props) {
|
||||||
const { classId } = props;
|
const { classId } = props;
|
||||||
const [searchForm] = Form.useForm();
|
const [searchForm] = Form.useForm();
|
||||||
const [query, setQuery] = useState({ current: 1, size: 10 });
|
const [query, setQuery] = useState({ current: 1, size: 10 });
|
||||||
|
const [selectOpen, setSelectOpen] = useState(false);
|
||||||
|
// 本地暂存:接口未就绪,确认选择的课程先追加到表格展示
|
||||||
|
const [pendingCourses, setPendingCourses] = useState([]);
|
||||||
const {
|
const {
|
||||||
classCourseList: dataSource,
|
classCourseList: dataSource,
|
||||||
classCourseTotal: total,
|
classCourseTotal: total,
|
||||||
classCourseLoading: loading,
|
classCourseLoading: loading,
|
||||||
} = props.courseware || {};
|
} = props.courseware || {};
|
||||||
|
const tableSource = Array.isArray(dataSource) ? dataSource : [];
|
||||||
|
// 本地暂存行仅在第一页合并展示,避免翻页重复
|
||||||
|
const mergedSource =
|
||||||
|
query.current === 1 ? [...pendingCourses, ...tableSource] : tableSource;
|
||||||
|
|
||||||
const handleSearch = (params = query) => {
|
const handleSearch = (params = query) => {
|
||||||
props.classCoursePage({ ...params, classId });
|
props.classCoursePage({ ...params, classId });
|
||||||
|
|
@ -128,7 +136,7 @@ function ClassCourseTab(props) {
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
style={{ marginBottom: 12 }}
|
style={{ marginBottom: 12 }}
|
||||||
onClick={() => message.info("选择课程功能待接入")}
|
onClick={() => setSelectOpen(true)}
|
||||||
>
|
>
|
||||||
选择课程
|
选择课程
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -136,11 +144,11 @@ function ClassCourseTab(props) {
|
||||||
<Table
|
<Table
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={Array.isArray(dataSource) ? dataSource : []}
|
dataSource={mergedSource}
|
||||||
scroll={{ x: 1000 }}
|
scroll={{ x: 1000 }}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
pagination={{
|
pagination={{
|
||||||
total,
|
total: total + pendingCourses.length,
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
showQuickJumper: true,
|
showQuickJumper: true,
|
||||||
showTotal: (t) => `共 ${t} 条`,
|
showTotal: (t) => `共 ${t} 条`,
|
||||||
|
|
@ -153,8 +161,140 @@ function ClassCourseTab(props) {
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<CourseSelectModal
|
||||||
|
open={selectOpen}
|
||||||
|
loading={props.courseware?.courseLoading}
|
||||||
|
dataSource={props.courseware?.courseList}
|
||||||
|
total={props.courseware?.courseTotal}
|
||||||
|
requestPage={props.coursePage}
|
||||||
|
selectedIds={[
|
||||||
|
...tableSource.map((item) => item.courseId),
|
||||||
|
...pendingCourses.map((item) => item.courseId),
|
||||||
|
]}
|
||||||
|
onOk={(rows) => {
|
||||||
|
// 班级添加课程接口待接入:先本地暂存并填充表格,接入后改为提交请求 + handleSearch() 刷新
|
||||||
|
setPendingCourses((prev) => [
|
||||||
|
...prev,
|
||||||
|
...rows.map(({ id, courseName, classHourDuration }) => ({
|
||||||
|
id,
|
||||||
|
courseId: id,
|
||||||
|
courseName,
|
||||||
|
requiredTotalHours: classHourDuration,
|
||||||
|
})),
|
||||||
|
]);
|
||||||
|
setSelectOpen(false);
|
||||||
|
}}
|
||||||
|
onCancel={() => setSelectOpen(false)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 选择课程弹窗:数据源同培训课程管理列表 */
|
||||||
|
function CourseSelectModal({
|
||||||
|
open,
|
||||||
|
loading,
|
||||||
|
dataSource,
|
||||||
|
total,
|
||||||
|
requestPage,
|
||||||
|
selectedIds,
|
||||||
|
onOk,
|
||||||
|
onCancel,
|
||||||
|
}) {
|
||||||
|
const [query, setQuery] = useState({ current: 1, size: 10 });
|
||||||
|
const [keyword, setKeyword] = useState("");
|
||||||
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
|
|
||||||
|
const handleSearch = (params) => {
|
||||||
|
setQuery(params);
|
||||||
|
requestPage(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
setKeyword("");
|
||||||
|
setSelectedRows([]);
|
||||||
|
handleSearch({ current: 1, size: 10 });
|
||||||
|
}
|
||||||
|
}, [open]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={open}
|
||||||
|
title="选择课程"
|
||||||
|
width={860}
|
||||||
|
loading={loading}
|
||||||
|
destroyOnHidden
|
||||||
|
okText={`确定${selectedRows.length ? `(已选 ${selectedRows.length})` : ""}`}
|
||||||
|
okButtonProps={{ disabled: !selectedRows.length }}
|
||||||
|
onOk={() => onOk(selectedRows)}
|
||||||
|
onCancel={onCancel}
|
||||||
|
|
||||||
|
>
|
||||||
|
<Input.Search
|
||||||
|
placeholder="请输入课程名称"
|
||||||
|
allowClear
|
||||||
|
style={{ width: 280, marginBottom: 12 }}
|
||||||
|
value={keyword}
|
||||||
|
onChange={(e) => setKeyword(e.target.value)}
|
||||||
|
onSearch={(value) =>
|
||||||
|
handleSearch({ current: 1, size: query.size, courseName: value })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
size="small"
|
||||||
|
columns={[
|
||||||
|
{ title: "课程名称", dataIndex: "courseName", ellipsis: true },
|
||||||
|
{
|
||||||
|
title: "课程描述",
|
||||||
|
dataIndex: "courseDescription",
|
||||||
|
width: 260,
|
||||||
|
ellipsis: true,
|
||||||
|
render: (v) => v || "-",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "课程状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
width: 90,
|
||||||
|
render: (v) => {
|
||||||
|
const item = COURSEWARE_STATUS_MAP[v];
|
||||||
|
return item ? <Badge status={item.status} text={item.label} /> : "-";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "总课时",
|
||||||
|
dataIndex: "classHourDuration",
|
||||||
|
width: 90,
|
||||||
|
render: (v) => (v == null ? "-" : v),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={Array.isArray(dataSource) ? dataSource : []}
|
||||||
|
rowSelection={{
|
||||||
|
preserveSelectedRowKeys: true,
|
||||||
|
selectedRowKeys: selectedRows.map((r) => r.id),
|
||||||
|
getCheckboxProps: (record) => ({
|
||||||
|
disabled: selectedIds.includes(record.id),
|
||||||
|
}),
|
||||||
|
onChange: (_, rows) => setSelectedRows(rows),
|
||||||
|
}}
|
||||||
|
pagination={{
|
||||||
|
total,
|
||||||
|
size: "small",
|
||||||
|
showTotal: (t) => `共 ${t} 条`,
|
||||||
|
current: Number(query.current) || 1,
|
||||||
|
pageSize: Number(query.size) || 10,
|
||||||
|
onChange: (page, pageSize) =>
|
||||||
|
handleSearch({
|
||||||
|
current: page,
|
||||||
|
size: pageSize,
|
||||||
|
courseName: query.courseName,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default Connect([NS_COURSEWARE], true)(ClassCourseTab);
|
export default Connect([NS_COURSEWARE], true)(ClassCourseTab);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue