Commit 462c5b38 by yuananting

feat:填空修改暂存

parent 96b7a4c4
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-03-03 15:13:12 * @Date: 2021-03-03 15:13:12
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 19:44:31 * @LastEditTime: 2021-03-16 15:11:25
* @Description: 助学工具接口 * @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -52,3 +52,7 @@ export function queryQuestionDetails(params: object) { ...@@ -52,3 +52,7 @@ export function queryQuestionDetails(params: object) {
export function editQuestion(params: object) { export function editQuestion(params: object) {
return Service.Hades("anon/hades/question/editQuestion", params); return Service.Hades("anon/hades/question/editQuestion", params);
} }
export function batchImport(params: object) {
return Service.Hades("anon/hades/question/batchImport", params);
}
\ No newline at end of file
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-03-11 11:34:37 * @Date: 2021-03-11 11:34:37
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 19:45:10 * @LastEditTime: 2021-03-16 15:12:09
* @Description: 描述一下咯 * @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import { queryCategoryTree, addCategory, delCategory, editCategory, editCategoryTree, queryQuestionCategoryTree, addQuestion, queryQuestionPageList, deleteQuestion, queryQuestionDetails, editQuestion } from '@/data-source/questionBank/request-apis'; import { queryCategoryTree, addCategory, delCategory, editCategory, editCategoryTree, queryQuestionCategoryTree, addQuestion, queryQuestionPageList, deleteQuestion, queryQuestionDetails, editQuestion, batchImport } from '@/data-source/questionBank/request-apis';
export default class QuestionBankService { export default class QuestionBankService {
// 获取题目分类树 // 获取题目分类树
static queryCategoryTree(params: any) { static queryCategoryTree(params: any) {
...@@ -62,4 +62,9 @@ export default class QuestionBankService { ...@@ -62,4 +62,9 @@ export default class QuestionBankService {
static editQuestion(params: any) { static editQuestion(params: any) {
return editQuestion(params); return editQuestion(params);
} }
// 批量导入
static batchImport(params: any) {
return batchImport(params);
}
} }
\ No newline at end of file
/* /*
* @Author: wufan * @Author: wufan
* @Date: 2020-11-30 10:47:38 * @Date: 2020-11-30 10:47:38
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-01-18 14:59:57 * @LastEditTime: 2021-03-16 15:28:55
* @Description: web店铺banner页面 * @Description: web店铺banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 13:46:35 * @Date: 2021-02-25 13:46:35
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 21:14:47 * @LastEditTime: 2021-03-16 16:44:23
* @Description: 助学工具-题库-题目管理-新增题目 * @Description: 助学工具-题库-题目管理-新增题目
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -15,6 +15,7 @@ import NewQuestionTab from "./components/NewQuestionTab"; ...@@ -15,6 +15,7 @@ import NewQuestionTab from "./components/NewQuestionTab";
import { defineQuestionInfo } from "./components/model"; import { defineQuestionInfo } from "./components/model";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService"; import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
import User from "@/common/js/user"; import User from "@/common/js/user";
import UploadOss from "@/core/upload";
const { TabPane } = Tabs; const { TabPane } = Tabs;
class AddNewQuestion extends Component { class AddNewQuestion extends Component {
...@@ -144,10 +145,14 @@ class AddNewQuestion extends Component { ...@@ -144,10 +145,14 @@ class AddNewQuestion extends Component {
} }
break; break;
case "JUDGE": case "JUDGE":
this.judgeRef.checkInput(); if (this.judgeRef.checkInput() === 0) {
this.saveCurrentQuestion(judgeContent);
}
break; break;
case "GAP_FILLING": case "GAP_FILLING":
this.CompletionRef.checkInput(); if (this.gapRef.checkInput() === 0) {
// this.saveCurrentQuestion(gapFillingContent);
}
break; break;
case "INDEFINITE_CHOICE": case "INDEFINITE_CHOICE":
if (this.indefiniteRef.checkInput() === 0) { if (this.indefiniteRef.checkInput() === 0) {
...@@ -242,10 +247,11 @@ class AddNewQuestion extends Component { ...@@ -242,10 +247,11 @@ class AddNewQuestion extends Component {
<NewQuestionTab <NewQuestionTab
questionTypeKey="GAP_FILLING" questionTypeKey="GAP_FILLING"
onRef={(ref) => { onRef={(ref) => {
this.CompletionRef = ref; this.gapRef = ref;
}} }}
questionInfo={gapFillingContent} questionInfo={gapFillingContent}
onSetState={(newContent) => { onSetState={(newContent) => {
console.log("gapFillingContent:", newContent);
Object.assign(gapFillingContent, newContent); Object.assign(gapFillingContent, newContent);
}} }}
/> />
......
import React, { Component } from "react"; import React, { Component } from "react";
import { message, Button } from "antd"; import { message, Button } from "antd";
import UploadOss from "@/core/upload"; import UploadOss from "@/core/upload";
import "./CompletionStem.less"; import "./GapFillingStem.less";
const MEDIA_MAP = [ const MEDIA_MAP = [
{ {
title: "音频", title: "音频",
...@@ -24,7 +24,7 @@ const MEDIA_MAP = [ ...@@ -24,7 +24,7 @@ const MEDIA_MAP = [
key: "VIDEO", key: "VIDEO",
}, },
]; ];
class CompletionStem extends Component { class GapFillingStem extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
...@@ -48,13 +48,14 @@ class CompletionStem extends Component { ...@@ -48,13 +48,14 @@ class CompletionStem extends Component {
var _blanksList = []; var _blanksList = [];
const stemInput = document.getElementById("editor-box_content"); const stemInput = document.getElementById("editor-box_content");
stemInput.childNodes.forEach((item) => { stemInput.childNodes.forEach((item) => {
if (item.nodeName === "SPAN") { if (item.nodeName === "SPAN" && item.id) {
_blanksList.push(item); _blanksList.push(item);
} }
}); });
this.setState({blanksList:_blanksList}) this.setState({blanksList:_blanksList})
this.handleStemStyle(); this.handleStemStyle();
this.props.changeBlankCount(this.state.blanksList); this.props.onChange(stemInput.innerHTML)
this.props.changeBlankCount(_blanksList);
}; };
/** /**
...@@ -66,6 +67,7 @@ class CompletionStem extends Component { ...@@ -66,6 +67,7 @@ class CompletionStem extends Component {
insertBlanks = () => { insertBlanks = () => {
document.getElementById("editor-box_content").focus(); document.getElementById("editor-box_content").focus();
const _blanksList = this.state.blanksList; const _blanksList = this.state.blanksList;
console.log("888888888888:", _blanksList);
var blanks = document.createElement("span"); var blanks = document.createElement("span");
blanks.className = "fill-line"; blanks.className = "fill-line";
blanks.innerHTML = "填空"; blanks.innerHTML = "填空";
...@@ -75,6 +77,7 @@ class CompletionStem extends Component { ...@@ -75,6 +77,7 @@ class CompletionStem extends Component {
this.setState({ blanksList: _blanksList }); this.setState({ blanksList: _blanksList });
var sel, range; var sel, range;
sel = window.getSelection(); sel = window.getSelection();
console.log("*****:", sel)
if (sel.getRangeAt && sel.rangeCount) { if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0); range = sel.getRangeAt(0);
range.deleteContents(); range.deleteContents();
...@@ -134,7 +137,7 @@ class CompletionStem extends Component { ...@@ -134,7 +137,7 @@ class CompletionStem extends Component {
} = this.props; } = this.props;
return ( return (
<div <div
className="completion-question-edtior_box" className="gap-question-edtior_box"
style={{ zIndex }} style={{ zIndex }}
onMouseEnter={() => { onMouseEnter={() => {
if (visibleMediaBox || focusFlag) return; if (visibleMediaBox || focusFlag) return;
...@@ -177,7 +180,7 @@ class CompletionStem extends Component { ...@@ -177,7 +180,7 @@ class CompletionStem extends Component {
/{limitLength} /{limitLength}
</div> </div>
</div> </div>
<div className="editor-fill-info"> <div className="editor-fill-info" style={{ top: this.props.validateStatus === "error" ? "56px" : "36px" }}>
在需要填写答案的地方 在需要填写答案的地方
<Button <Button
type="link" type="link"
...@@ -227,4 +230,4 @@ class CompletionStem extends Component { ...@@ -227,4 +230,4 @@ class CompletionStem extends Component {
); );
} }
} }
export default CompletionStem; export default GapFillingStem;
.completion-question-edtior_box { .gap-question-edtior_box {
position: relative; position: relative;
.editor-box-single { .editor-box-single {
border-radius: 4px; border-radius: 4px;
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
} }
.editor-fill-info { .editor-fill-info {
// position: absolute;
height: 20px; height: 20px;
font-size: 14px; font-size: 14px;
line-height: 20px; line-height: 20px;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 14:34:29 * @Date: 2021-02-25 14:34:29
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 21:12:14 * @LastEditTime: 2021-03-16 17:23:02
* @Description: 助学工具-题库-题目管理-新建题目Tab * @Description: 助学工具-题库-题目管理-新建题目Tab
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -11,7 +11,7 @@ import { Form, Radio, message, Checkbox, Tag, Tooltip, Input } from "antd"; ...@@ -11,7 +11,7 @@ import { Form, Radio, message, Checkbox, Tag, Tooltip, Input } from "antd";
import "./NewQuestionTab.less"; import "./NewQuestionTab.less";
import Upload from "@/core/upload"; import Upload from "@/core/upload";
import QuestionEditor from "./QuestionEditor"; import QuestionEditor from "./QuestionEditor";
import CompletionStem from "./CompletionStem"; import GapFillingStem from "./GapFillingStem";
import { PlusOutlined, CloseOutlined } from "@ant-design/icons"; import { PlusOutlined, CloseOutlined } from "@ant-design/icons";
import { import {
NUM_TO_WORD_MAP, NUM_TO_WORD_MAP,
...@@ -22,7 +22,8 @@ import UploadingProgress from "./UploadingProgress"; ...@@ -22,7 +22,8 @@ import UploadingProgress from "./UploadingProgress";
import XMAudio from "./XMAudio"; import XMAudio from "./XMAudio";
import XMRecord from "./XMRecord"; import XMRecord from "./XMRecord";
import ScanFileModal from "@/modules/resource-disk/modal/ScanFileModal"; import ScanFileModal from "@/modules/resource-disk/modal/ScanFileModal";
import _ from 'lodash'; import _ from "lodash";
import UploadOss from "@/core/upload";
class NewQuestionTab extends Component { class NewQuestionTab extends Component {
constructor(props) { constructor(props) {
...@@ -30,33 +31,22 @@ class NewQuestionTab extends Component { ...@@ -30,33 +31,22 @@ class NewQuestionTab extends Component {
const { questionInfo = {} } = props; const { questionInfo = {} } = props;
const { const {
questionStemList, questionStemList,
gapFillingAnswerList,
optionList, optionList,
questionAnswerDescList, questionAnswerDescList,
showBox, showBox,
} = questionInfo; } = questionInfo;
this.state = { this.state = {
stemContent: JSON.parse(JSON.stringify(questionStemList)), // 题干内容 stemContent: JSON.parse(JSON.stringify(questionStemList)), // 题干内容
chooseOptions: JSON.parse(JSON.stringify(optionList)), // 单选多选不定项-选项列表 gapFillingAnswer: JSON.parse(JSON.stringify(gapFillingAnswerList)), // 填空题-选项列表
chooseOptions: JSON.parse(JSON.stringify(optionList)), // 单选多选不定项判断-选项列表
questionAnswerDesc: JSON.parse(JSON.stringify(questionAnswerDescList)), // 答案解析 questionAnswerDesc: JSON.parse(JSON.stringify(questionAnswerDescList)), // 答案解析
accept: QUESTION_FILE_ACCEPT["PICTURE"], // 上传媒体类型 accept: QUESTION_FILE_ACCEPT["PICTURE"], // 上传媒体类型
fileType: "PICTURE", // 媒体枚举 fileType: "PICTURE", // 媒体枚举
showRecord: false, // 录音弹窗 showRecord: false, // 录音弹窗
showBox: showBox, showBox: showBox,
completionOptions: [], gapFillingOptions: [],
blanksList: [], // 填空列表 blanksList: [], // 填空列表
judgeOptions: [
{
// 判断-选项列表
label: "正确",
value: true,
isCorrectAnswer: null,
},
{
label: "错误",
value: false,
isCorrectAnswer: null,
},
],
}; };
this.uploadInput = React.createRef(); this.uploadInput = React.createRef();
this.markKey = window.random_string(16); this.markKey = window.random_string(16);
...@@ -64,6 +54,11 @@ class NewQuestionTab extends Component { ...@@ -64,6 +54,11 @@ class NewQuestionTab extends Component {
componentDidMount() { componentDidMount() {
const { chooseOptions } = this.state; const { chooseOptions } = this.state;
if (
["INDEFINITE_CHOICE", "MULTI_CHOICE", "SINGLE_CHOICE"].includes(
this.props.questionTypeKey
)
) {
if (chooseOptions.length === 0) { if (chooseOptions.length === 0) {
// 选择题(单选 多选 不定项)-插入4条默认选项 // 选择题(单选 多选 不定项)-插入4条默认选项
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
...@@ -72,6 +67,7 @@ class NewQuestionTab extends Component { ...@@ -72,6 +67,7 @@ class NewQuestionTab extends Component {
this.setState({ [`optionsText_${i}`]: "" }); this.setState({ [`optionsText_${i}`]: "" });
} }
} }
}
this.props.onRef(this); this.props.onRef(this);
} }
...@@ -96,37 +92,98 @@ class NewQuestionTab extends Component { ...@@ -96,37 +92,98 @@ class NewQuestionTab extends Component {
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { questionInfo } = nextProps; const { questionInfo } = nextProps;
if (this.props.questionInfo !== questionInfo) { if (this.props.questionInfo !== questionInfo) {
this.setState({stemContent: JSON.parse(JSON.stringify(questionInfo.questionStemList))}); // 题干内容 this.setState({
this.setState({chooseOptions: JSON.parse(JSON.stringify(questionInfo.optionList))}); // 单选多选不定项-选项列表 stemContent: JSON.parse(JSON.stringify(questionInfo.questionStemList)),
this.setState({questionAnswerDesc: JSON.parse(JSON.stringify(questionInfo.questionAnswerDescList))}); // 答案解析 }); // 题干内容
this._onSetState() this.setState({
chooseOptions: JSON.parse(JSON.stringify(questionInfo.optionList)),
}); // 单选多选不定项-选项列表
this.setState({
questionAnswerDesc: JSON.parse(
JSON.stringify(questionInfo.questionAnswerDescList)
),
}); // 答案解析
this._onSetState();
} }
return true; return true;
} }
_onSetState = (params = {}) => { _onSetState = (params = {}) => {
this.setState({ ...params, updateKey: window.random_string(16) }, this.setState({ ...params, updateKey: window.random_string(16) }, () => {
() => {
this.props.onSetState({ this.props.onSetState({
questionStemList: JSON.parse(JSON.stringify(this.state.stemContent)), questionStemList: JSON.parse(JSON.stringify(this.state.stemContent)),
gapFillingAnswerList: JSON.parse(
JSON.stringify(this.state.gapFillingAnswer)
),
optionList: JSON.parse(JSON.stringify(this.state.chooseOptions)), optionList: JSON.parse(JSON.stringify(this.state.chooseOptions)),
questionAnswerDescList: JSON.parse( questionAnswerDescList: JSON.parse(
JSON.stringify(this.state.questionAnswerDesc) JSON.stringify(this.state.questionAnswerDesc)
), ),
}); });
});
};
dataURItoBlob = (dataURI) => {
var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]; // mime类型
var byteString = atob(dataURI.split(",")[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图
for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
} }
); return new Blob([intArray], { type: mimeString });
}; };
// 保存校验 // 保存校验
checkInput = () => { checkInput = async () => {
let validateError = 0; let validateError = 0;
// 题干校验 // 题干校验
const stemContent = _.find( let stemContent = _.find(
this.state.stemContent, this.state.stemContent,
(contentItem) => contentItem.type === "RICH_TEXT" (contentItem) => contentItem.type === "RICH_TEXT"
); );
const stem = stemContent.content.replace(/<[^>]+>/g, ""); const stem = stemContent.content.replace(/<[^>]+>/g, "");
if (this.props.questionTypeKey === "GAP_FILLING") {
// stemContent.content.replace(
// /<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
// (match, capture) => {
// let blob = this.dataURItoBlob(capture);
// const imageUrl = await UploadOss.uploadBlobToOSS(
// blob,
// window.random_string(16) + ".png"
// );
// newImgHtml = `<img src=${imageUrl} alt="" />`;
// console.log("newImgHtml:", newImgHtml);
// }
// );
// console.log("修改:", stemContent);
// this._onSetState();
if (this.state.blanksList.length === 0) {
this.setState({ stemValidate: "error" });
this.setState({
stemText: (
<div style={{ marginTop: 8, minWidth: "523px" }}>
请输入正确格式,示例:党章规定,凡事有
<span style={{ padding: "0 10px", borderBottom: "1px solid" }}>
填空1
</span>
人以上的
<span style={{ padding: "0 10px", borderBottom: "1px solid" }}>
填空2
</span>
,都应该成立党的基层组织
</div>
),
});
validateError++;
} else {
this.setState({ stemValidate: "success" });
this.setState({ stemText: "" });
}
} else {
if (stem.length === 0) { if (stem.length === 0) {
this.setState({ stemValidate: "error" }); this.setState({ stemValidate: "error" });
this.setState({ stemText: "请输入题干" }); this.setState({ stemText: "请输入题干" });
...@@ -135,23 +192,21 @@ class NewQuestionTab extends Component { ...@@ -135,23 +192,21 @@ class NewQuestionTab extends Component {
this.setState({ stemValidate: "success" }); this.setState({ stemValidate: "success" });
this.setState({ stemText: "" }); this.setState({ stemText: "" });
} }
}
// 选项校验 // 选项校验
let optionUnChecked = 0; let optionUnChecked = 0;
const { chooseOptions, judgeOptions } = this.state; const { chooseOptions } = this.state;
const { questionTypeKey } = this.props; if (this.props.questionTypeKey === "GAP_FILLING") {
if (questionTypeKey === "JUDGE") { this.state.blanksList.forEach((item, index) => {
optionUnChecked = judgeOptions.filter( if (item.answerTagList.length === 0) {
(item) => item.isCorrectAnswer === null this.setState({ [`optionsValidate_${index}`]: "error" });
).length; this.setState({ [`optionsText_${index}`]: "请输入答案" });
if (optionUnChecked === judgeOptions.length) {
this.setState({ radioValidate: "error" });
this.setState({ radioText: "请选择正确答案" });
validateError++; validateError++;
} else { } else {
this.setState({ radioValidate: "success" }); this.setState({ [`optionsValidate_${index}`]: "success" });
this.setState({ radioText: "" }); this.setState({ [`optionsText_${index}`]: "" });
} }
});
} else { } else {
chooseOptions.forEach((item, index) => { chooseOptions.forEach((item, index) => {
const optionContent = item.questionOptionContentList; const optionContent = item.questionOptionContentList;
...@@ -219,7 +274,6 @@ class NewQuestionTab extends Component { ...@@ -219,7 +274,6 @@ class NewQuestionTab extends Component {
} }
}; };
/** /**
* 删除选项 * 删除选项
* *
...@@ -254,7 +308,7 @@ class NewQuestionTab extends Component { ...@@ -254,7 +308,7 @@ class NewQuestionTab extends Component {
* @memberof QuestionInputItem * @memberof QuestionInputItem
*/ */
handleChangeMedia = (key, uploadItemTarget, contentType) => { handleChangeMedia = (key, uploadItemTarget, contentType) => {
this.setState({ contentType }) this.setState({ contentType });
const { mediaFirstType } = this.state; const { mediaFirstType } = this.state;
const mediaArr = _.filter(uploadItemTarget, (mediaItem) => { const mediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type !== "RICH_TEXT"; return mediaItem.type !== "RICH_TEXT";
...@@ -293,16 +347,16 @@ class NewQuestionTab extends Component { ...@@ -293,16 +347,16 @@ class NewQuestionTab extends Component {
return mediaItem.type === "VIDEO"; return mediaItem.type === "VIDEO";
}); });
if (pictureMediaArr.length > 0) { if (pictureMediaArr.length > 0) {
existType.push("PICTURE") existType.push("PICTURE");
} }
if (voiceMediaArr.length > 0) { if (voiceMediaArr.length > 0) {
existType.push("VOICE") existType.push("VOICE");
} }
if (recordMediaArr.length > 0) { if (recordMediaArr.length > 0) {
existType.push("RECORD") existType.push("RECORD");
} }
if (videodMediaArr.length > 0) { if (videodMediaArr.length > 0) {
existType.push("VIDEO") existType.push("VIDEO");
} }
if (existType.length > 2 && !existType.includes(key)) { if (existType.length > 2 && !existType.includes(key)) {
return message.warning("只能添加3种类型的多媒体文件"); return message.warning("只能添加3种类型的多媒体文件");
...@@ -433,7 +487,9 @@ class NewQuestionTab extends Component { ...@@ -433,7 +487,9 @@ class NewQuestionTab extends Component {
changeBlankCount = (data) => { changeBlankCount = (data) => {
data.map((item) => { data.map((item) => {
if (!item.answerTagList) {
item.answerTagList = []; item.answerTagList = [];
}
item.inputVisible = false; item.inputVisible = false;
item.errorHold = false; item.errorHold = false;
item.editInput = false; item.editInput = false;
...@@ -454,7 +510,9 @@ class NewQuestionTab extends Component { ...@@ -454,7 +510,9 @@ class NewQuestionTab extends Component {
handleInputConfirm = (optionItem, val) => { handleInputConfirm = (optionItem, val) => {
const _blanksList = this.state.blanksList; const _blanksList = this.state.blanksList;
var gapFillingAnswer = [];
_blanksList.forEach((item) => { _blanksList.forEach((item) => {
gapFillingAnswer.push({ correctAnswerList: item.answerTagList });
if (item.id === optionItem.id) { if (item.id === optionItem.id) {
if (val) { if (val) {
optionItem.answerTagList.push(val); optionItem.answerTagList.push(val);
...@@ -464,6 +522,7 @@ class NewQuestionTab extends Component { ...@@ -464,6 +522,7 @@ class NewQuestionTab extends Component {
} }
} }
}); });
this.setState({ gapFillingAnswer }, () => this._onSetState());
this.setState({ blanksList: _blanksList }); this.setState({ blanksList: _blanksList });
}; };
...@@ -489,14 +548,14 @@ class NewQuestionTab extends Component { ...@@ -489,14 +548,14 @@ class NewQuestionTab extends Component {
this.setState({ blanksList: _blanksList }); this.setState({ blanksList: _blanksList });
}; };
renderCompletionAnswer = (optionItem, optionIndex) => { renderGapFillingAnswer = (optionItem, optionIndex) => {
return ( return (
<div className="completion-answer-box"> <div className="gap-answer-box" key={optionIndex}>
<span className="completion-answer-label"> <span className="gap-answer-label">
{optionItem.innerHTML} {optionItem.innerHTML}
{optionIndex + 1}. {optionIndex + 1}.
</span> </span>
<div className="completion-answer-content"> <div className="gap-answer-content">
{optionItem.answerTagList.map((tag, index) => { {optionItem.answerTagList.map((tag, index) => {
return optionItem.editInput ? ( return optionItem.editInput ? (
<Input <Input
...@@ -557,6 +616,13 @@ class NewQuestionTab extends Component { ...@@ -557,6 +616,13 @@ class NewQuestionTab extends Component {
); );
}; };
renderJudgeOption = (judgeOptions) => {
return (
<React.Fragment>
<div>{judgeOptions[0].content}</div>
</React.Fragment>
);
};
/** /**
* 渲染输入内容 * 渲染输入内容
* *
...@@ -569,7 +635,7 @@ class NewQuestionTab extends Component { ...@@ -569,7 +635,7 @@ class NewQuestionTab extends Component {
contentType, contentType,
validateStatus validateStatus
) => { ) => {
const isCompletion = this.props.questionTypeKey === "COMPLETION"; const isGapFilling = this.props.questionTypeKey === "GAP_FILLING";
const editorContent = _.find( const editorContent = _.find(
contentList, contentList,
(contentItem) => contentItem.type === "RICH_TEXT" (contentItem) => contentItem.type === "RICH_TEXT"
...@@ -590,13 +656,17 @@ class NewQuestionTab extends Component { ...@@ -590,13 +656,17 @@ class NewQuestionTab extends Component {
return ( return (
<React.Fragment> <React.Fragment>
<div> <div>
{isCompletion && contentType === "QUESTION_STEM" ? ( {isGapFilling && contentType === "QUESTION_STEM" ? (
<CompletionStem <GapFillingStem
placehold={placehold} placehold={placehold}
validateStatus={validateStatus} validateStatus={validateStatus}
detail={contentList} detailInfo={contentList}
mediaBtn={mediaBtn} mediaBtn={mediaBtn}
changeBlankCount={this.changeBlankCount.bind(this)} changeBlankCount={this.changeBlankCount.bind(this)}
onChange={(html) => {
editorContent.content = html;
this._onSetState();
}}
onUploadMedia={(key) => { onUploadMedia={(key) => {
this.handleChangeMedia(key, contentList, contentType); this.handleChangeMedia(key, contentList, contentType);
}} }}
...@@ -623,9 +693,10 @@ class NewQuestionTab extends Component { ...@@ -623,9 +693,10 @@ class NewQuestionTab extends Component {
/> />
)} )}
</div> </div>
{contentType === "QUESTION_ANSWER_DESC" ? {contentType === "QUESTION_ANSWER_DESC" ? (
<div className="question-desc-box"> <div className="question-desc-box">
{pictureMediaList.length > 0 && <div className="desc-picture-box"> {pictureMediaList.length > 0 && (
<div className="desc-picture-box">
{_.map(pictureMediaList, (pictureItem, pictureIndex) => { {_.map(pictureMediaList, (pictureItem, pictureIndex) => {
let { content, status } = pictureItem; let { content, status } = pictureItem;
if (["init", "fail"].includes(status)) { if (["init", "fail"].includes(status)) {
...@@ -635,7 +706,9 @@ class NewQuestionTab extends Component { ...@@ -635,7 +706,9 @@ class NewQuestionTab extends Component {
fileDesc={pictureItem} fileDesc={pictureItem}
canCancelUpload canCancelUpload
onReupload={() => this.handleReupload(pictureItem)} onReupload={() => this.handleReupload(pictureItem)}
onAbort={() => this.handleAbort(pictureItem, pictureIndex)} onAbort={() =>
this.handleAbort(pictureItem, pictureIndex)
}
/> />
</div> </div>
); );
...@@ -651,22 +724,26 @@ class NewQuestionTab extends Component { ...@@ -651,22 +724,26 @@ class NewQuestionTab extends Component {
className="icon_arrow iconfont" className="icon_arrow iconfont"
onClick={() => { onClick={() => {
contentList.map((item, index) => { contentList.map((item, index) => {
if (item.contentName === pictureItem.contentName) { if (
item.contentName === pictureItem.contentName
) {
contentList.splice(index, 1); contentList.splice(index, 1);
return item return item;
} }
}) });
this._onSetState(); this._onSetState();
}} }}
> >
&#xe717; &#xe717;
</span> </span>
</div> </div>
) );
} }
})} })}
</div>} </div>
{recordMediaList.length > 0 && <div className="desc-audio-box"> )}
{recordMediaList.length > 0 && (
<div className="desc-audio-box">
{_.map(recordMediaList, (recordItem, recordIndex) => { {_.map(recordMediaList, (recordItem, recordIndex) => {
let { content, status, size } = recordItem; let { content, status, size } = recordItem;
if (["init", "fail"].includes(status)) { if (["init", "fail"].includes(status)) {
...@@ -676,7 +753,9 @@ class NewQuestionTab extends Component { ...@@ -676,7 +753,9 @@ class NewQuestionTab extends Component {
fileDesc={recordItem} fileDesc={recordItem}
canCancelUpload canCancelUpload
onReupload={() => this.handleReupload(recordItem)} onReupload={() => this.handleReupload(recordItem)}
onAbort={() => this.handleAbort(recordItem, recordIndex)} onAbort={() =>
this.handleAbort(recordItem, recordIndex)
}
/> />
</div> </div>
); );
...@@ -699,20 +778,22 @@ class NewQuestionTab extends Component { ...@@ -699,20 +778,22 @@ class NewQuestionTab extends Component {
contentList.map((item, index) => { contentList.map((item, index) => {
if (item.contentName === recordItem.contentName) { if (item.contentName === recordItem.contentName) {
contentList.splice(index, 1); contentList.splice(index, 1);
return item return item;
} }
}) });
this._onSetState(); this._onSetState();
}} }}
> >
&#xe717; &#xe717;
</span> </span>
</div> </div>
) );
} }
})} })}
</div>} </div>
{voiceMediaList.length > 0 && <div className="desc-audio-box"> )}
{voiceMediaList.length > 0 && (
<div className="desc-audio-box">
{_.map(voiceMediaList, (voiceItem, voiceIndex) => { {_.map(voiceMediaList, (voiceItem, voiceIndex) => {
let { content, status, size } = voiceItem; let { content, status, size } = voiceItem;
if (["init", "fail"].includes(status)) { if (["init", "fail"].includes(status)) {
...@@ -722,7 +803,9 @@ class NewQuestionTab extends Component { ...@@ -722,7 +803,9 @@ class NewQuestionTab extends Component {
fileDesc={voiceItem} fileDesc={voiceItem}
canCancelUpload canCancelUpload
onReupload={() => this.handleReupload(voiceItem)} onReupload={() => this.handleReupload(voiceItem)}
onAbort={() => this.handleAbort(voiceItem, voiceIndex)} onAbort={() =>
this.handleAbort(voiceItem, voiceIndex)
}
/> />
</div> </div>
); );
...@@ -745,20 +828,22 @@ class NewQuestionTab extends Component { ...@@ -745,20 +828,22 @@ class NewQuestionTab extends Component {
contentList.map((item, index) => { contentList.map((item, index) => {
if (item.contentName === voiceItem.contentName) { if (item.contentName === voiceItem.contentName) {
contentList.splice(index, 1); contentList.splice(index, 1);
return item return item;
} }
}) });
this._onSetState(); this._onSetState();
}} }}
> >
&#xe717; &#xe717;
</span> </span>
</div> </div>
) );
} }
})} })}
</div>} </div>
{videoMediaList.length > 0 && <div className="desc-video-box"> )}
{videoMediaList.length > 0 && (
<div className="desc-video-box">
{_.map(videoMediaList, (videoItem, videoIndex) => { {_.map(videoMediaList, (videoItem, videoIndex) => {
let { content, status } = videoItem; let { content, status } = videoItem;
if (["init", "fail"].includes(status)) { if (["init", "fail"].includes(status)) {
...@@ -768,16 +853,15 @@ class NewQuestionTab extends Component { ...@@ -768,16 +853,15 @@ class NewQuestionTab extends Component {
fileDesc={videoItem} fileDesc={videoItem}
canCancelUpload canCancelUpload
onReupload={() => this.handleReupload(videoItem)} onReupload={() => this.handleReupload(videoItem)}
onAbort={() => this.handleAbort(videoItem, videoIndex)} onAbort={() =>
this.handleAbort(videoItem, videoIndex)
}
/> />
</div> </div>
); );
} else { } else {
return ( return (
<div <div className="video-box" key={videoIndex}>
className="video-box"
key={videoIndex}
>
<img <img
className="video-box_content" className="video-box_content"
src={`${content}?x-oss-process=video/snapshot,t_0,m_fast`} src={`${content}?x-oss-process=video/snapshot,t_0,m_fast`}
...@@ -793,21 +877,23 @@ class NewQuestionTab extends Component { ...@@ -793,21 +877,23 @@ class NewQuestionTab extends Component {
contentList.map((item, index) => { contentList.map((item, index) => {
if (item.contentName === videoItem.contentName) { if (item.contentName === videoItem.contentName) {
contentList.splice(index, 1); contentList.splice(index, 1);
return item return item;
} }
}) });
this._onSetState(); this._onSetState();
}} }}
> >
&#xe717; &#xe717;
</span> </span>
</div> </div>
) );
} }
})} })}
</div>}
</div> </div>
: _.map(contentList, (contentItem, index) => { )}
</div>
) : (
_.map(contentList, (contentItem, index) => {
const { type, content, status } = contentItem; const { type, content, status } = contentItem;
let dom = ""; let dom = "";
if (["init", "fail"].includes(status)) { if (["init", "fail"].includes(status)) {
...@@ -910,7 +996,8 @@ class NewQuestionTab extends Component { ...@@ -910,7 +996,8 @@ class NewQuestionTab extends Component {
</span> </span>
</div> </div>
) : null; ) : null;
})} })
)}
</React.Fragment> </React.Fragment>
); );
}; };
...@@ -992,7 +1079,6 @@ class NewQuestionTab extends Component { ...@@ -992,7 +1079,6 @@ class NewQuestionTab extends Component {
const { const {
stemContent, stemContent,
chooseOptions, chooseOptions,
judgeOptions,
questionAnswerDesc, questionAnswerDesc,
accept, accept,
showRecord, showRecord,
...@@ -1003,8 +1089,8 @@ class NewQuestionTab extends Component { ...@@ -1003,8 +1089,8 @@ class NewQuestionTab extends Component {
} = this.state; } = this.state;
const { stemValidate, stemText, radioValidate, radioText } = this.state; const { stemValidate, stemText, radioValidate, radioText } = this.state;
const isJudge = this.props.questionTypeKey === "JUDGE"; const isJudge = this.props.questionTypeKey === "JUDGE";
const isCompletion = this.props.questionTypeKey === "COMPLETION"; const isGapFilling = this.props.questionTypeKey === "GAP_FILLING";
const placehold = isCompletion ? ( const placehold = isGapFilling ? (
<span> <span>
示例:党章规定,凡事有 示例:党章规定,凡事有
<span className="fill-line">&nbsp;&nbsp;填空1&nbsp;&nbsp;</span> <span className="fill-line">&nbsp;&nbsp;填空1&nbsp;&nbsp;</span>
...@@ -1034,7 +1120,7 @@ class NewQuestionTab extends Component { ...@@ -1034,7 +1120,7 @@ class NewQuestionTab extends Component {
stemValidate stemValidate
)} )}
</Form.Item> </Form.Item>
{isCompletion ? ( {isGapFilling ? (
<Form.Item <Form.Item
name="answer" name="answer"
label={ label={
...@@ -1057,7 +1143,14 @@ class NewQuestionTab extends Component { ...@@ -1057,7 +1143,14 @@ class NewQuestionTab extends Component {
<span className="answer-tip">请在题干中插入答案占位符</span> <span className="answer-tip">请在题干中插入答案占位符</span>
) : ( ) : (
_.map(blanksList, (item, index) => { _.map(blanksList, (item, index) => {
return this.renderCompletionAnswer(item, index); return (
<Form.Item
validateStatus={this.state[`optionsValidate_${index}`]}
help={this.state[`optionsText_${index}`]}
>
{this.renderGapFillingAnswer(item, index)}
</Form.Item>
);
}) })
)} )}
</Form.Item> </Form.Item>
...@@ -1072,42 +1165,7 @@ class NewQuestionTab extends Component { ...@@ -1072,42 +1165,7 @@ class NewQuestionTab extends Component {
className="question-item_options__list" className="question-item_options__list"
data-label="正确答案" data-label="正确答案"
> >
{isJudge {_.map(chooseOptions, (optionItem, optionIndex) => {
? _.map(judgeOptions, (optionItem, optionIndex) => {
return (
<div className="question-item_options__content">
<div className="question-item_options__setting">
<Form.Item
validateStatus={radioValidate}
help={
optionIndex === judgeOptions.length - 1
? radioText
: ""
}
>
{/* 判断 */}
<Radio
checked={optionItem.isCorrectAnswer === 1}
onClick={() => {
_.each(judgeOptions, (item) => {
item.isCorrectAnswer = 0;
});
optionItem.isCorrectAnswer = 1;
this._onSetState();
}}
/>
</Form.Item>
</div>
<div className="question-item_options__sort mr12">
{NUM_TO_WORD_MAP[optionIndex]}.
</div>
<div className="question-item_options__input">
{optionItem.label}
</div>
</div>
);
})
: _.map(chooseOptions, (optionItem, optionIndex) => {
const { const {
questionOptionContentList, questionOptionContentList,
isCorrectAnswer, isCorrectAnswer,
...@@ -1117,7 +1175,10 @@ class NewQuestionTab extends Component { ...@@ -1117,7 +1175,10 @@ class NewQuestionTab extends Component {
const placeHold = const placeHold =
"必填(1000字以内,可粘贴小图;可以不输入文字,只添加音频或图片)"; "必填(1000字以内,可粘贴小图;可以不输入文字,只添加音频或图片)";
return ( return (
<div className="question-item_options__content" key={optionIndex}> <div
className="question-item_options__content"
key={optionIndex}
>
<div className="question-item_options__setting"> <div className="question-item_options__setting">
<Form.Item <Form.Item
validateStatus={radioValidate} validateStatus={radioValidate}
...@@ -1127,9 +1188,10 @@ class NewQuestionTab extends Component { ...@@ -1127,9 +1188,10 @@ class NewQuestionTab extends Component {
: "" : ""
} }
> >
{/* 单选 */} {/* 单选 or 判断*/}
{this.props.questionTypeKey === {["SINGLE_CHOICE", "JUDGE"].includes(
"SINGLE_CHOICE" && ( this.props.questionTypeKey
) && (
<Radio <Radio
checked={isCorrectAnswer} checked={isCorrectAnswer}
onClick={() => { onClick={() => {
...@@ -1166,7 +1228,9 @@ class NewQuestionTab extends Component { ...@@ -1166,7 +1228,9 @@ class NewQuestionTab extends Component {
} }
help={this.state[`optionsText_${optionIndex}`]} help={this.state[`optionsText_${optionIndex}`]}
> >
{this.renderContent( {isJudge
? this.renderJudgeOption(questionOptionContentList)
: this.renderContent(
questionOptionContentList, questionOptionContentList,
placeHold, placeHold,
mediaBtn, mediaBtn,
...@@ -1175,13 +1239,16 @@ class NewQuestionTab extends Component { ...@@ -1175,13 +1239,16 @@ class NewQuestionTab extends Component {
)} )}
</Form.Item> </Form.Item>
</div> </div>
{[
"INDEFINITE_CHOICE",
"MULTI_CHOICE",
"SINGLE_CHOICE",
].includes(this.props.questionTypeKey) && (
<div className="question-item_options__extra"> <div className="question-item_options__extra">
<React.Fragment> <React.Fragment>
<span <span
className="option-operate_item__icon icon iconfont" className="option-operate_item__icon icon iconfont"
onClick={() => onClick={() => this.handleDelOption(optionIndex)}
this.handleDelOption(optionIndex)
}
> >
&#xe81a; &#xe81a;
</span> </span>
...@@ -1211,6 +1278,7 @@ class NewQuestionTab extends Component { ...@@ -1211,6 +1278,7 @@ class NewQuestionTab extends Component {
)} )}
</React.Fragment> </React.Fragment>
</div> </div>
)}
</div> </div>
); );
})} })}
......
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
// display: flex; // display: flex;
// justify-content: space-between; // justify-content: space-between;
.fill-line { .fill-line {
text-decoration: underline; padding: 0 10px;
border-bottom: 1px solid;
} }
} }
.editor-fill-box_single:focus { .editor-fill-box_single:focus {
...@@ -369,16 +370,16 @@ ...@@ -369,16 +370,16 @@
} }
} }
.completion-answer-box { .gap-answer-box {
display: inline-flex; display: inline-flex;
width: 100%; width: 100%;
padding: 6px 0; padding: 6px 0;
.completion-answer-label { .gap-answer-label {
margin-right: 16px; margin-right: 16px;
padding-top: 6px; padding-top: 6px;
width: 50px; width: 50px;
} }
.completion-answer-content { .gap-answer-content {
display: flex; display: flex;
background: #ffffff; background: #ffffff;
border-radius: 4px; border-radius: 4px;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 11:23:47 * @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 21:08:28 * @LastEditTime: 2021-03-16 15:34:57
* @Description: 助学工具-题库-题目管理主页面列表数据 * @Description: 助学工具-题库-题目管理主页面列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -27,6 +27,8 @@ import User from "@/common/js/user"; ...@@ -27,6 +27,8 @@ import User from "@/common/js/user";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService"; import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
import _ from "underscore"; import _ from "underscore";
import QuestionPreviewModal from "../modal/QuestionPreviewModal"; import QuestionPreviewModal from "../modal/QuestionPreviewModal";
import BatchImportQuestionModal from "../modal/BatchImportQuestionModal";
const { Search } = Input; const { Search } = Input;
const questionTypeEnum = { const questionTypeEnum = {
...@@ -273,7 +275,9 @@ class QuestionManageContent extends Component { ...@@ -273,7 +275,9 @@ class QuestionManageContent extends Component {
<span className="record-operate__item split"> | </span> <span className="record-operate__item split"> | </span>
<div <div
className="record-operate__item" className="record-operate__item"
onClick={() => this.toEditQuetion(record.id, record.questionTypeEnum)} onClick={() =>
this.toEditQuetion(record.id, record.questionTypeEnum)
}
> >
编辑 编辑
</div> </div>
...@@ -346,6 +350,29 @@ class QuestionManageContent extends Component { ...@@ -346,6 +350,29 @@ class QuestionManageContent extends Component {
); );
}; };
batchImportQuestion = () => {
const ImportQuestionModal = <BatchImportQuestionModal
close={() => {
this.setState({ ImportQuestionModal: null });
}}
onEdit={(record) => {
this.handleEditRecord(record);
}}
showTip={() => {
Modal.confirm({
title: `提醒`,
content: '系统拼命处理中,为避免你等待时间过长,请前往“任务中心”查看导入结果',
onOk: () => {
RCHistory.push(`/download_center/import_record`);
},
okText: '前往任务中心',
cancelText: '关闭',
});
}}
/>;
this.setState({ ImportQuestionModal });
}
render() { render() {
const { dataSource = [], total, query } = this.state; const { dataSource = [], total, query } = this.state;
const { current, size, categoryId, questionName, questionType } = query; const { current, size, categoryId, questionName, questionType } = query;
...@@ -417,13 +444,7 @@ class QuestionManageContent extends Component { ...@@ -417,13 +444,7 @@ class QuestionManageContent extends Component {
<Button type="primary" onClick={this.handleCreateQuestionBank}> <Button type="primary" onClick={this.handleCreateQuestionBank}>
新建题目 新建题目
</Button> </Button>
<Button <Button onClick={this.batchImportQuestion}>批量导入</Button>
onClick={() => {
console.log("批量导入");
}}
>
批量导入
</Button>
</Space> </Space>
)} )}
<div className="question-manage-list"> <div className="question-manage-list">
...@@ -455,6 +476,7 @@ class QuestionManageContent extends Component { ...@@ -455,6 +476,7 @@ class QuestionManageContent extends Component {
</div> </div>
)} )}
{this.state.QuestionPreviewModal} {this.state.QuestionPreviewModal}
{this.state.ImportQuestionModal}
</div> </div>
</div> </div>
); );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 11:26:28 * @Date: 2021-02-25 11:26:28
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 09:42:30 * @LastEditTime: 2021-03-16 11:14:55
* @Description: 助学工具-题库-题目管理右侧内容样式 * @Description: 助学工具-题库-题目管理右侧内容样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -77,3 +77,8 @@ ...@@ -77,3 +77,8 @@
} }
} }
} }
.fill-line {
padding: 0 10px;
border-bottom: 1px solid;
}
/*
* @Author: zhangyi
* @Date: 2019-12-09 10:29:55
* @Last Modified by: mikey.wanghaofeng
* @Last Modified time: 2020-09-25 11:03:47
*/
import React, { Component } from "react";
import { Modal, Button, Upload, message } from "antd";
import "./BatchImportQuestionModal.less";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
class BatchImportQuestionModal extends Component {
constructor(props) {
super(props);
this.state = {
showSelectFileModal: false, // 云盘列表弹窗显隐
diskList: [], // 资料云盘文件列表
fileList: [], // 上传的文件列表
uploadBtnType: "add", // 上传按钮类型(上传文件 | 重新上传)
uploadBlob: null, // 上传的文件
uploadProps: {
accept: "application/vnd.ms-excel",
beforeUpload(file) {
this.setState({ uploadBtnType: "reAdd" });
this.setState({ uploadBlob: file });
return false;
},
onChange(info) {
let fileList = [...info.fileList];
fileList = fileList.slice(-1);
this.setState({ fileList });
},
onRemove() {
this.setState({ uploadBtnType: "add" });
},
},
};
}
// 下载题目模板
handleDownTemplate = () => {
console.log("下载");
const a = document.createElement("a");
a.href = "https://image.xiaomaiketang.com/xm/question_template.xlsx";
a.click();
};
render() {
const {
diskList,
showSelectFileModal,
uploadBtnType,
uploadProps,
} = this.state;
return (
<div>
<Modal
className="import-score-modal"
title="导入题目信息"
visible={true}
width={560}
maskClosable={false}
footer={[
<Button onClick={this.props.close}>取消</Button>,
<Button type="primary" onClick={this.handleImport}>
导入
</Button>,
]}
onCancel={() => {
this.props.close();
}}
>
<div className="step-section">
<h4 className="step-title">1.下载导入模板,按要求填写信息</h4>
<div
className="down-btn"
style={{ fontSize: "14px" }}
onClick={this.handleDownTemplate}
>
下载题目导入模板
</div>
</div>
<div className="step-section">
<h4 className="step-title">2.选择需要导入的Excel文件</h4>
<Button type="primary" className="add-btn" onClick={() => this.setState({showSelectFileModal: true})}>
{uploadBtnType == "reAdd" ? "重新添加" : "添加文件"}
</Button>
</div>
</Modal>
<SelectPrepareFileModal
operateType="select"
accept="image/jpeg,image/png,image/jpg"
selectTypeList={["JPG", "JPEG", "PNG"]}
tooltip="支持文件类型:jpg、jpeg、png"
isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
this.setState({ showSelectFileModal: false });
}}
onSelect={this.handleSelectImg}
/>
</div>
);
}
}
export default BatchImportQuestionModal;
@import '../../../core/mixins.less';
.import-score-modal {
.step-section {
margin-bottom: 24px;
.step-title {
font-size: 16px;
font-weight: 400;
margin-bottom: 16px;
color: #333;
}
.tip-box {
border: 1px dashed #e8e8e8;
padding: 8px;
margin-bottom: 16px;
.tip-title {
margin-bottom: 4px;
}
.tip-content {
font-size: 12px;
}
}
.add-btn {
border-radius: 2px;
font-size: 14px;
box-shadow: none;
text-shadow: none;
span {
font-weight: 400;
}
}
.remark-input {
width: 304px;
margin-bottom: 8px;
}
.remark-tip {
color: #999;
font-size: 12px;
}
.down-btn {
text-align: left;
color: #FC9C6B;
font-size: 12px;
display: block;
margin-top: 8px;
cursor: pointer;
}
.upload-box {
width: 200px;
.ant-upload-list-item-name {
.text-overflow-ellipsis();
width:70%;
}
}
}
.import-status-box {
height:430px;
overflow: hidden;
.status-content {
margin:auto;
text-align: center;
margin-top:100px;
>img {
width: 76px;
}
.status {
font-size: 16px;
font-weight: 500;
margin: 18px 0 16px;
}
.status-tip {
line-height: 20px;
.num {
color: #FC9C6B;
}
}
.down-btn {
margin-top: 16px;
}
}
}
}
\ No newline at end of file
...@@ -60,6 +60,7 @@ class QuestionPreviewModal extends Component { ...@@ -60,6 +60,7 @@ class QuestionPreviewModal extends Component {
const { const {
questionTypeEnum, questionTypeEnum,
questionStemList, questionStemList,
gapFillingAnswerList,
optionList, optionList,
questionAnswerDescList, questionAnswerDescList,
} = questionInfo; } = questionInfo;
...@@ -152,6 +153,12 @@ class QuestionPreviewModal extends Component { ...@@ -152,6 +153,12 @@ class QuestionPreviewModal extends Component {
</div> </div>
</div> </div>
<hr style={{ margin: "16px 0", color: "#E8E8E8", height: "1px" }} /> <hr style={{ margin: "16px 0", color: "#E8E8E8", height: "1px" }} />
{[
"INDEFINITE_CHOICE",
"MULTI_CHOICE",
"SINGLE_CHOICE",
"JUDGE",
].includes(questionTypeEnum) && (
<div className="question-option"> <div className="question-option">
<div className="question-option__title">选项:</div> <div className="question-option__title">选项:</div>
<div className="question-option__content"> <div className="question-option__content">
...@@ -169,14 +176,29 @@ class QuestionPreviewModal extends Component { ...@@ -169,14 +176,29 @@ class QuestionPreviewModal extends Component {
<div className="option-sort"> <div className="option-sort">
{NUM_TO_WORD_MAP[optionIndex]}. {NUM_TO_WORD_MAP[optionIndex]}.
</div> </div>
{[
"INDEFINITE_CHOICE",
"MULTI_CHOICE",
"SINGLE_CHOICE",
].includes(questionTypeEnum) && (
<div <div
className="input-box" className="input-box"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: inputcontent[0].content, __html: inputcontent[0].content,
}} }}
/> />
)}
{["JUDGE"].includes(questionTypeEnum) &&
_.map(questionOptionContentList, (item, index) => {
return <span key={index}>{item.content}</span>;
})}
</div> </div>
{_.map(questionOptionContentList, (item, index) => { {[
"INDEFINITE_CHOICE",
"MULTI_CHOICE",
"SINGLE_CHOICE",
].includes(questionTypeEnum) &&
_.map(questionOptionContentList, (item, index) => {
let dom = ""; let dom = "";
let { type, content, size } = item; let { type, content, size } = item;
switch (type) { switch (type) {
...@@ -216,8 +238,15 @@ class QuestionPreviewModal extends Component { ...@@ -216,8 +238,15 @@ class QuestionPreviewModal extends Component {
})} })}
</div> </div>
</div> </div>
)}
<div className="question-answer"> <div className="question-answer">
<div className="question-answer__title">答案:</div> <div className="question-answer__title">答案:</div>
{[
"INDEFINITE_CHOICE",
"MULTI_CHOICE",
"SINGLE_CHOICE",
"JUDGE",
].includes(questionTypeEnum) && (
<div className="question-answer__content"> <div className="question-answer__content">
{_.map(rightAnswerSort, (item, index) => { {_.map(rightAnswerSort, (item, index) => {
return ( return (
...@@ -227,6 +256,23 @@ class QuestionPreviewModal extends Component { ...@@ -227,6 +256,23 @@ class QuestionPreviewModal extends Component {
); );
})} })}
</div> </div>
)}
{questionTypeEnum === "GAP_FILLING" && (
<div className="question-gap-answer">
{_.map(gapFillingAnswerList, (item, index) => {
return (
<div>
<div className="gap-label">填空{index+1}.</div>
<div className="gap-content" key={index}>
{_.map(item.correctAnswerList, (childItem, childIndex) => {
return <span>{childItem}</span>
})}
</div>
</div>
);
})}
</div>
)}
</div> </div>
<hr style={{ margin: "16px 0", color: "#E8E8E8", height: "1px" }} /> <hr style={{ margin: "16px 0", color: "#E8E8E8", height: "1px" }} />
<div className="question-desc"> <div className="question-desc">
......
...@@ -117,6 +117,25 @@ ...@@ -117,6 +117,25 @@
margin-right: 8px; margin-right: 8px;
} }
} }
.question-gap-answer {
margin-bottom: 8px;
.gap-label {
display: inline-block;
width: 48px;
height: 20px;
color: #666666;
line-height: 20px;
}
.gap-content {
display: inline-block;
span {
background: #F7F8F9;
border-radius: 2px;
padding: 2px 12px;
margin-right: 8px;
}
}
}
} }
.question-desc { .question-desc {
margin-bottom: 16px; margin-bottom: 16px;
...@@ -195,3 +214,7 @@ ...@@ -195,3 +214,7 @@
.question-preview-modal.ant-modal { .question-preview-modal.ant-modal {
max-height: 60% !important; max-height: 60% !important;
} }
.fill-line {
padding: 0 10px;
border-bottom: 1px solid;
}
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