Commit b42c48d7 by yuananting

feat:新增快捷排序

parent 604913f8
/*
* @Author: yuananting
* @Date: 2021-03-27 16:15:13
* @LastEditors: wufan
* @LastEditTime: 2021-05-30 16:56:15
* @LastEditors: yuananting
* @LastEditTime: 2021-06-07 16:53:03
* @Description: 助学工具-新建/复制/编辑试卷
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -19,6 +19,8 @@ import {
message,
Modal,
Spin,
Space,
Radio,
} from "antd";
import { PlusOutlined } from "@ant-design/icons";
import ShowTips from "@/components/ShowTips";
......@@ -29,6 +31,7 @@ import PaperPreviewModal from "./modal/PreviewPaperModal";
import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import Bus from "@/core/bus";
import _ from "underscore";
const questionTypeEnum = {
SINGLE_CHOICE: "单选题",
......@@ -66,12 +69,38 @@ class OperatePaper extends Component {
},
selectQuestionModal: null,
paperPreviewModal: null,
quickSortModalVisible: false,
selectQuestionList: [],
currentOperate: "",
currentNav: "",
currentCategoryPapers: [],
loading: false,
check: false,
sorterMethod: "default",
sorterBy: [
"SINGLE_CHOICE",
"MULTI_CHOICE",
"JUDGE",
"GAP_FILLING",
"INDEFINITE_CHOICE",
],
sorterTypeList: [
{
typeKey: "SINGLE_CHOICE",
},
{
typeKey: "MULTI_CHOICE",
},
{
typeKey: "JUDGE",
},
{
typeKey: "GAP_FILLING",
},
{
typeKey: "INDEFINITE_CHOICE",
},
],
};
}
......@@ -124,12 +153,10 @@ class OperatePaper extends Component {
};
const res = await AidToolService.queryPaperDetail(query);
const { result } = res;
const { paperName, passRate } = result;
const { paperName, passRate, questionList } = result;
this.setState(
{
selectQuestionList: result.questionList.sort(
(a, b) => b.updateTime - a.updateTime
),
selectQuestionList: questionList,
formData: {
...result,
paperName:
......@@ -142,7 +169,11 @@ class OperatePaper extends Component {
paperName: this.state.formData.paperName,
passRate,
});
this.setFormData(result.questionList);
questionList.map((item, index) => {
item.sorterIndex = index;
return item;
});
this.setFormData(questionList);
}
);
};
......@@ -206,35 +237,8 @@ class OperatePaper extends Component {
return prev + Number(cur.score) || 0;
}, 0);
const sortedTableData = [
...singleQuestion,
...multiQuestion,
...indefiniteQuestion,
...judgeQuestion,
...gapQuestion,
];
let currentQuestionList = [];
switch (sorter) {
case "ascend":
currentQuestionList = sortedTableData;
break;
case "descend":
currentQuestionList = sortedTableData.reverse();
break;
case "default":
currentQuestionList = _selectQuestionList.sort(
(a, b) => b.updateTime - a.updateTime
);
break;
default:
currentQuestionList = _selectQuestionList;
break;
}
const passScore = Math.round(totalScore * formData.passRate * 0.01);
this.setState({
selectQuestionList: currentQuestionList,
formData: {
...formData,
singleChoiceCnt: singleQuestion.length,
......@@ -256,12 +260,14 @@ class OperatePaper extends Component {
// 选择题目
chooseQuestion = () => {
const { selectQuestionList, sorterMethod, sorterBy } = this.state;
const m = (
<SelectQuestionModal
getSelectedQuestion={this.state.selectQuestionList}
getSelectedQuestion={selectQuestionList}
setSelectedQuestion={(list) => {
this.setState({ selectQuestionModal: null }, () => {
this.setFormData(list.sort((a, b) => b.updateTime - a.updateTime));
this.setFormData(list);
this.quickSorter(list, sorterMethod, sorterBy);
});
}}
close={() => {
......@@ -276,7 +282,7 @@ class OperatePaper extends Component {
// 移动已选题目
handleMoveItem = (index, moveLength) => {
const { selectQuestionList } = this.state;
const selectQuestionList = [...this.state.selectQuestionList];
const item = selectQuestionList.splice(index + moveLength, 1);
selectQuestionList.splice(index, 0, item[0]);
this.setState({ selectQuestionList }, () =>
......@@ -465,14 +471,6 @@ class OperatePaper extends Component {
});
};
// 题型排序
sortByQuestionType = (pagination, filters, sorter) => {
const { columnKey, order } = sorter;
if (columnKey === "questionType") {
this.setFormData(this.state.selectQuestionList, order || "default");
}
};
// 表头设置
parseColumns = () => {
const { selectQuestionList } = this.state;
......@@ -491,8 +489,6 @@ class OperatePaper extends Component {
dataIndex: "questionType",
key: "questionType",
width: "12%",
sorter: true,
showSorterTooltip: false,
filters: [
{
text: "单选题",
......@@ -552,8 +548,7 @@ class OperatePaper extends Component {
<Tooltip title="多选题和填空题的漏选/半对得分不能高于题目本身分值">
<span
className="icon iconfont"
style={{ color: "#BFBFBF", fontSize: 14,fontWeight:"400"
}}
style={{ color: "#BFBFBF", fontSize: 14, fontWeight: "400" }}
>
&#xe7c4;
</span>
......@@ -672,11 +667,37 @@ class OperatePaper extends Component {
return columns;
};
// 上下移题型
handleMoveTypeSorter = (index, moveLength) => {
const sorterTypeList = [...this.state.sorterTypeList];
const item = sorterTypeList.splice(index + moveLength, 1);
sorterTypeList.splice(index, 0, item[0]);
const sorterBy = _.pluck(sorterTypeList, "typeKey");
this.setState({ sorterTypeList, sorterBy });
};
// 快捷排序
quickSorter = (list, sorterMethod, sorterBy) => {
this.setState({
selectQuestionList:
sorterMethod === "default"
? list.sort((a, b) => a.sorterIndex - b.sorterIndex)
: list.sort(
(a, b) =>
sorterBy.indexOf(a.questionTypeEnum || a.questionType) -
sorterBy.indexOf(b.questionTypeEnum || b.questionType)
),
});
};
render() {
const {
selectQuestionModal,
paperPreviewModal,
selectQuestionList,
quickSortModalVisible,
sorterMethod,
sorterTypeList,
sorterBy,
currentNav,
formData,
loading,
......@@ -700,120 +721,214 @@ class OperatePaper extends Component {
totalScore,
} = formData;
const selectQuestionList = [...this.state.selectQuestionList];
const questionTypeEnum = {
SINGLE_CHOICE: "单选题",
MULTI_CHOICE: "多选题",
JUDGE: "判断题",
GAP_FILLING: "填空题",
INDEFINITE_CHOICE: "不定项选择题",
};
const columns = [
{
title: "题型",
dataIndex: "typeKey",
key: "typeKey",
render: (text, record, index) => questionTypeEnum[text],
},
{
title: "操作",
key: "action",
render: (text, record, index) => (
<Space size="middle">
<span
onClick={() => {
index > 0 && this.handleMoveTypeSorter(index, -1);
}}
>
上移
</span>
<span
onClick={() => {
index < 4 && this.handleMoveTypeSorter(index, 1);
}}
>
下移
</span>
</Space>
),
},
];
return (
<div className="page operate-paper-page">
<Breadcrumbs navList={currentNav} goBack={() => this.handleGoBack()} />
<Spin spinning={loading}>
<div className="box">
<div className="show-tips">
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利" />
</div>
<Form ref={this.formRef} style={{ marginTop: 24, marginBottom: '85px' }}>
<Form.Item
name="paperName"
label="试卷名称:"
required
validateStatus={this.validatePaperName(paperName) ? "error" : ""}
help={this.validatePaperName(paperName)}
<div className="box">
<div className="show-tips">
<ShowTips message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利" />
</div>
<Form
ref={this.formRef}
style={{ marginTop: 24, marginBottom: "85px" }}
>
<Input
value={paperName}
autoComplete="off"
maxLength={40}
style={{ width: 300 }}
placeholder="请输入试卷名称(40字以内)"
onChange={(e) => {
this.setState({
formData: {
...formData,
paperName: e.target.value.trim(),
},
});
}}
/>
</Form.Item>
<Form.Item
name="paperName"
label="试卷名称:"
required
validateStatus={
this.validatePaperName(paperName) ? "error" : ""
}
help={this.validatePaperName(paperName)}
>
<Input
value={paperName}
autoComplete="off"
maxLength={40}
style={{ width: 300 }}
placeholder="请输入试卷名称(40字以内)"
onChange={(e) => {
this.setState({
formData: {
...formData,
paperName: e.target.value.trim(),
},
});
}}
/>
</Form.Item>
<Form.Item
name="passRate"
label="及格线:"
required
validateStatus={check && !passRate ? "error" : ""}
help={check && !passRate && "请输入及格线"}
>
<div>
<InputNumber
min={1}
max={100}
value={passRate}
onChange={(value) => {
this.setState(
{
formData: {
...formData,
passRate: parseInt(value) || undefined,
<Form.Item
name="passRate"
label="及格线:"
required
validateStatus={check && !passRate ? "error" : ""}
help={check && !passRate && "请输入及格线"}
>
<div>
<InputNumber
min={1}
max={100}
value={passRate}
onChange={(value) => {
this.setState(
{
formData: {
...formData,
passRate: parseInt(value) || undefined,
},
},
},
() => this.setFormData(selectQuestionList)
);
() => this.setFormData(selectQuestionList)
);
}}
/>{" "}
%
<span className="score-info">
总分({Number(totalScore) || 0})*及格线(
{Number(passRate) || 0}
%)=及格分数(
{Number(passScore) || 0}
</span>
</div>
</Form.Item>
<Space size={16}>
<Button
className="choose-btn"
type="primary"
icon={<PlusOutlined />}
onClick={this.chooseQuestion}
>
自选题目
</Button>
<Button
className="choose-btn"
onClick={() => {
this.setState({
quickSortModalVisible: true,
});
}}
/>{" "}
%
<span className="score-info">
总分({Number(totalScore) || 0})*及格线(
{Number(passRate) || 0}
%)=及格分数(
{Number(passScore) || 0}
</span>
</div>
</Form.Item>
>
快捷排序
</Button>
</Space>
{questionCnt > 0 && (
<div
className="paper-info-tip"
style={{ margin: "0 auto 12px" }}
>
总计<span>{totalScore}</span>分,共<span>{questionCnt}</span>
题。{" "}
{singleChoiceCnt > 0 &&
`单选题${singleChoiceCnt}题,共${singleChoiceScore}分;`}
{multiChoiceCnt > 0 &&
`多选题${multiChoiceCnt}题,共${multiChoiceScore}分;`}
{judgeCnt > 0 && `判断题${judgeCnt}题,共${judgeScore}分,`}
{gapFillingCnt > 0 &&
`填空题${gapFillingCnt}题,共${gapFillingScore}分,`}
{indefiniteChoiceCnt > 0 &&
`不定项选择题${indefiniteChoiceCnt}题,共${indefiniteChoiceScore}分`}
</div>
)}
<Button
className="choose-btn"
type="primary"
icon={<PlusOutlined />}
onClick={this.chooseQuestion}
>
自选题目
<ConfigProvider renderEmpty={this.customizeRenderEmpty}>
<Table
className="table-style"
scroll={{ y: 350 }}
columns={this.parseColumns()}
dataSource={selectQuestionList}
pagination={false}
selections={false}
/>
</ConfigProvider>
</Form>
</div>
<div className="footer shrink-footer">
<Button onClick={this.handleGoBack}>取消</Button>
<Button onClick={this.previewPaper}>预览</Button>
<Button type="primary" onClick={this.savePaper}>
保存
</Button>
{questionCnt > 0 && (
<div className="paper-info-tip" style={{ margin: "0 auto 12px" }}>
总计<span>{totalScore}</span>分,共<span>{questionCnt}</span>
题。{" "}
{singleChoiceCnt > 0 &&
`单选题${singleChoiceCnt}题,共${singleChoiceScore}分;`}
{multiChoiceCnt > 0 &&
`多选题${multiChoiceCnt}题,共${multiChoiceScore}分;`}
{judgeCnt > 0 && `判断题${judgeCnt}题,共${judgeScore}分,`}
{gapFillingCnt > 0 &&
`填空题${gapFillingCnt}题,共${gapFillingScore}分,`}
{indefiniteChoiceCnt > 0 &&
`不定项选择题${indefiniteChoiceCnt}题,共${indefiniteChoiceScore}分`}
</div>
)}
<ConfigProvider renderEmpty={this.customizeRenderEmpty}>
<Table
className="table-style"
scroll={{ y: 350 }}
columns={this.parseColumns()}
dataSource={selectQuestionList}
pagination={false}
onChange={this.sortByQuestionType}
selections={false}
/>
</ConfigProvider>
</Form>
</div>
<div className="footer shrink-footer">
<Button onClick={this.handleGoBack}>取消</Button>
<Button onClick={this.previewPaper}>预览</Button>
<Button type="primary" onClick={this.savePaper}>
保存
</Button>
</div>
</div>
</Spin>
{selectQuestionModal}
{paperPreviewModal}
<Modal
maskClosable={false}
title="快捷排序"
visible={quickSortModalVisible}
onOk={() => {
this.setState(
{
quickSortModalVisible: false,
},
() => this.quickSorter(selectQuestionList, sorterMethod, sorterBy)
);
}}
onCancel={() => {
this.setState({ quickSortModalVisible: false });
}}
>
<Radio.Group
onChange={(e) =>
this.setState({
sorterMethod: e.target.value,
})
}
value={sorterMethod}
>
<Radio value={"default"}>默认排序</Radio>
<Radio value={"questionType"}>按题型排序</Radio>
</Radio.Group>
{sorterMethod === "questionType" && (
<Table
columns={columns}
dataSource={sorterTypeList}
pagination={false}
/>
)}
</Modal>
</div>
);
}
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-03-29 10:52:26
* @LastEditors: yuananting
* @LastEditTime: 2021-05-08 16:11:27
* @LastEditTime: 2021-06-07 14:45:02
* @Description: 助学工具-试卷-新建选择题目弹窗
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -42,7 +42,8 @@ class SelectQuestionModal extends Component {
width={1080}
onOk={() => {
this.props.setSelectedQuestion(
this.listRef.current.state.selectQuestionKeys.map((item) => {
this.listRef.current.state.selectQuestionKeys.map((item, index) => {
item.sorterIndex = index;
item.questionId = item.id || item.questionId;
item.questionType = item.questionTypeEnum || item.questionType;
item.score = item.score || 2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment