Commit 0e1a2057 by yuananting

feat:云盘上传文件

parent 83229b62
/* /*
* @Author: 陈剑宇 * @Author: 陈剑宇
* @Date: 2020-10-28 14:27:07 * @Date: 2020-10-28 14:27:07
* @LastEditTime: 2021-02-28 14:22:13 * @LastEditTime: 2021-03-17 20:27:44
* @LastEditors: yuananting * @LastEditors: yuananting
* @Description: * @Description:
* @FilePath: /xiaomai-web-b/app/common/constants/punchClock/punchClock.js * @FilePath: /xiaomai-web-b/app/common/constants/punchClock/punchClock.js
...@@ -113,6 +113,12 @@ export const FILE_ACCEPT = { ...@@ -113,6 +113,12 @@ export const FILE_ACCEPT = {
VOICE: 'audio/x-mpeg,audio/mp3,audio/mpeg,audio/wav,audio/x-m4a' VOICE: 'audio/x-mpeg,audio/mp3,audio/mpeg,audio/wav,audio/x-m4a'
} }
export const MEDIA_FILE_ACCEPT = {
PICTURE: 'JPG,JPEG,PNG,BMP,GIF',
VIDEO: 'MP4',
VOICE: 'MP3'
}
export const QUESTION_FILE_ACCEPT = { export const QUESTION_FILE_ACCEPT = {
PICTURE: 'image/jpg,image/jpeg,image/png,image/gif', PICTURE: 'image/jpg,image/jpeg,image/png,image/gif',
VIDEO: 'audio/mp4,video/mp4', VIDEO: 'audio/mp4,video/mp4',
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
* @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-17 10:45:10 * @LastEditTime: 2021-03-18 09:32:02
* @Description: 助学工具-题库-题目管理-新增题目 * @Description: 助学工具-题库-题目管理-新增题目
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React, { Component } from "react"; import React, { Component } from "react";
import { Tabs, Button, Tooltip, message } from "antd"; import { Tabs, Button, Tooltip, message, Modal } from "antd";
import Breadcrumbs from "@/components/Breadcrumbs"; import Breadcrumbs from "@/components/Breadcrumbs";
import ShowTips from "@/components/ShowTips"; import ShowTips from "@/components/ShowTips";
import "./AddNewQuestion.less"; import "./AddNewQuestion.less";
...@@ -21,8 +21,16 @@ const { TabPane } = Tabs; ...@@ -21,8 +21,16 @@ const { TabPane } = Tabs;
class AddNewQuestion extends Component { class AddNewQuestion extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
let activeKey = ""
if (getParameterByName("type")) {
activeKey = getParameterByName("type")
} else if (getParameterByName("key")) {
activeKey = getParameterByName("key")
} else {
activeKey = "SINGLE_CHOICE"
}
this.state = { this.state = {
activeKey: getParameterByName("type") || "SINGLE_CHOICE", activeKey: activeKey,
// 构建题目基本结构 // 构建题目基本结构
singleChoiceContent: defineQuestionInfo("SINGLE_CHOICE"), // 单选题 singleChoiceContent: defineQuestionInfo("SINGLE_CHOICE"), // 单选题
multiChoiceContent: defineQuestionInfo("MULTI_CHOICE"), // 多选题 multiChoiceContent: defineQuestionInfo("MULTI_CHOICE"), // 多选题
...@@ -69,7 +77,7 @@ class AddNewQuestion extends Component { ...@@ -69,7 +77,7 @@ class AddNewQuestion extends Component {
}); });
}; };
saveCurrentQuestion = (content) => { saveCurrentQuestion = (content, type, next) => {
content.questionStemList.map((item, index) => { content.questionStemList.map((item, index) => {
item.sort = index; item.sort = index;
return item; return item;
...@@ -101,9 +109,16 @@ class AddNewQuestion extends Component { ...@@ -101,9 +109,16 @@ class AddNewQuestion extends Component {
QuestionBankService.editQuestion(params).then((res) => { QuestionBankService.editQuestion(params).then((res) => {
if (res.success) { if (res.success) {
message.success("保存成功"); message.success("保存成功");
window.RCHistory.push({ if (next === 'add') {
pathname: `/question-bank-index?categoryId=${params.categoryId}`, window.RCHistory.push({
}); pathname: `/create-new-question?categoryId=${params.categoryId}&key=${type}`,
});
}
if (next === 'close') {
window.RCHistory.push({
pathname: `/question-bank-index?categoryId=${params.categoryId}`,
});
}
} }
}); });
} else { } else {
...@@ -117,15 +132,36 @@ class AddNewQuestion extends Component { ...@@ -117,15 +132,36 @@ class AddNewQuestion extends Component {
QuestionBankService.addQuestion(params).then((res) => { QuestionBankService.addQuestion(params).then((res) => {
if (res.success) { if (res.success) {
message.success("保存成功"); message.success("保存成功");
window.RCHistory.push({ if (next === 'add') {
pathname: `/question-bank-index?categoryId=${params.categoryId}`, window.RCHistory.push({
}); pathname: `/create-new-question?categoryId=${params.categoryId}&key=${type}`,
});
}
if (next === 'close') {
window.RCHistory.push({
pathname: `/question-bank-index?categoryId=${params.categoryId}`,
});
}
} }
}); });
} }
}; };
confirmSaveQuestion = () => { // 取消编辑并返回上一级路由
handleGoBack = () => {
Modal.confirm({
title: '确定要返回吗?',
content: '返回后,本次编辑的内容将不被保存',
okText: '确认返回',
cancelText: '留在本页',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => {
window.RCHistory.goBack();
}
})
}
confirmSaveQuestion = (next) => {
const { const {
singleChoiceContent, singleChoiceContent,
multiChoiceContent, multiChoiceContent,
...@@ -136,27 +172,27 @@ class AddNewQuestion extends Component { ...@@ -136,27 +172,27 @@ class AddNewQuestion extends Component {
switch (this.state.activeKey) { switch (this.state.activeKey) {
case "SINGLE_CHOICE": case "SINGLE_CHOICE":
if (this.singleChoiceRef.checkInput() === 0) { if (this.singleChoiceRef.checkInput() === 0) {
this.saveCurrentQuestion(singleChoiceContent); this.saveCurrentQuestion(singleChoiceContent, "SINGLE_CHOICE", next);
} }
break; break;
case "MULTI_CHOICE": case "MULTI_CHOICE":
if (this.multiChoiceRef.checkInput() === 0) { if (this.multiChoiceRef.checkInput() === 0) {
this.saveCurrentQuestion(multiChoiceContent); this.saveCurrentQuestion(multiChoiceContent, "MULTI_CHOICE", next);
} }
break; break;
case "JUDGE": case "JUDGE":
if (this.judgeRef.checkInput() === 0) { if (this.judgeRef.checkInput() === 0) {
this.saveCurrentQuestion(judgeContent); this.saveCurrentQuestion(judgeContent, "JUDGE", next);
} }
break; break;
case "GAP_FILLING": case "GAP_FILLING":
if (this.gapRef.checkInput() === 0) { // if (this.gapRef.checkInput() === 0) {
this.saveCurrentQuestion(gapFillingContent); this.saveCurrentQuestion(gapFillingContent, "GAP_FILLING", next);
} // }
break; break;
case "INDEFINITE_CHOICE": case "INDEFINITE_CHOICE":
if (this.indefiniteRef.checkInput() === 0) { if (this.indefiniteRef.checkInput() === 0) {
this.saveCurrentQuestion(indefiniteChoiceContent); this.saveCurrentQuestion(indefiniteChoiceContent, "INDEFINITE_CHOICE", next);
} }
break; break;
} }
...@@ -180,7 +216,7 @@ class AddNewQuestion extends Component { ...@@ -180,7 +216,7 @@ class AddNewQuestion extends Component {
<div className="page add-new-question"> <div className="page add-new-question">
<Breadcrumbs <Breadcrumbs
navList={getParameterByName("id") ? "编辑题目" : "新增题目"} navList={getParameterByName("id") ? "编辑题目" : "新增题目"}
goBack={() => RCHistory.goBack()} goBack={() => this.handleGoBack()}
/> />
<div className="box"> <div className="box">
<div className="show-tips"> <div className="show-tips">
...@@ -198,12 +234,13 @@ class AddNewQuestion extends Component { ...@@ -198,12 +234,13 @@ class AddNewQuestion extends Component {
key="SINGLE_CHOICE" key="SINGLE_CHOICE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="SINGLE_CHOICE" questionTypeKey={activeKey}
onRef={(ref) => { onRef={(ref) => {
this.singleChoiceRef = ref; this.singleChoiceRef = ref;
}} }}
questionInfo={singleChoiceContent} questionInfo={singleChoiceContent}
onSetState={(newContent) => { onSetState={(newContent) => {
console.log("newContent:", newContent)
Object.assign(singleChoiceContent, newContent); Object.assign(singleChoiceContent, newContent);
}} }}
onLogger={this.handleLogger} onLogger={this.handleLogger}
...@@ -214,7 +251,7 @@ class AddNewQuestion extends Component { ...@@ -214,7 +251,7 @@ class AddNewQuestion extends Component {
key="MULTI_CHOICE" key="MULTI_CHOICE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="MULTI_CHOICE" questionTypeKey={activeKey}
onRef={(ref) => { onRef={(ref) => {
this.multiChoiceRef = ref; this.multiChoiceRef = ref;
}} }}
...@@ -230,7 +267,7 @@ class AddNewQuestion extends Component { ...@@ -230,7 +267,7 @@ class AddNewQuestion extends Component {
key="JUDGE" key="JUDGE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="JUDGE" questionTypeKey={activeKey}
onRef={(ref) => { onRef={(ref) => {
this.judgeRef = ref; this.judgeRef = ref;
}} }}
...@@ -245,14 +282,14 @@ class AddNewQuestion extends Component { ...@@ -245,14 +282,14 @@ class AddNewQuestion extends Component {
key="GAP_FILLING" key="GAP_FILLING"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="GAP_FILLING" questionTypeKey={activeKey}
onRef={(ref) => { onRef={(ref) => {
this.gapRef = ref; this.gapRef = ref;
}} }}
questionInfo={gapFillingContent} questionInfo={gapFillingContent}
onSetState={(newContent) => { onSetState={(newContent) => {
Object.assign(gapFillingContent, newContent); Object.assign(gapFillingContent, newContent);
console.log("gapFillingContent:", gapFillingContent); console.log("gapFillingContent:", newContent);
}} }}
/> />
</TabPane> </TabPane>
...@@ -268,7 +305,7 @@ class AddNewQuestion extends Component { ...@@ -268,7 +305,7 @@ class AddNewQuestion extends Component {
key="INDEFINITE_CHOICE" key="INDEFINITE_CHOICE"
> >
<NewQuestionTab <NewQuestionTab
questionTypeKey="INDEFINITE_CHOICE" questionTypeKey={activeKey}
onRef={(ref) => { onRef={(ref) => {
this.indefiniteRef = ref; this.indefiniteRef = ref;
}} }}
...@@ -282,12 +319,14 @@ class AddNewQuestion extends Component { ...@@ -282,12 +319,14 @@ class AddNewQuestion extends Component {
</Tabs> </Tabs>
</div> </div>
<div className="footer"> <div className="footer">
<Button>取消</Button> <Button onClick={() => { this.handleGoBack() }}>取消</Button>
<Button>保存并继续添加</Button> <Button onClick={() => {
this.confirmSaveQuestion("add");
}}>保存并继续添加</Button>
<Button <Button
type="primary" type="primary"
onClick={() => { onClick={() => {
this.confirmSaveQuestion(); this.confirmSaveQuestion("close");
}} }}
> >
保存 保存
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 13:52:01 * @Date: 2021-02-25 13:52:01
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-08 19:07:56 * @LastEditTime: 2021-03-18 09:32:11
* @Description: 助学工具-题库-题目管理-新增题目样式 * @Description: 助学工具-题库-题目管理-新增题目样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
.add-new-question { .add-new-question {
position: relative !important; position: relative !important;
.box { .box {
margin-bottom: 66px !important; margin-bottom: 66px !important;
......
...@@ -33,7 +33,7 @@ class QuestionBankIndex extends Component { ...@@ -33,7 +33,7 @@ class QuestionBankIndex extends Component {
} }
}; };
updatedSiderTreeFromList = (updatedCategoryId) => { updatedSiderTreeFromList = (updatedCategoryId) => {
this.setState({updatedCategoryId}); this.setState({updatedCategoryId});
}; };
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-21 18:27:43 * @Date: 2021-02-21 18:27:43
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-11 19:10:44 * @LastEditTime: 2021-03-18 09:32:24
* @Description: 助学工具-题库-题库主页面样式 * @Description: 助学工具-题库-题库主页面样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
.question-bank-index { .question-bank-index {
.content-body { .content-body {
display: flex; display: flex;
.site-layout-background { .site-layout-background {
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-23 19:41:42 * @Date: 2021-02-23 19:41:42
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-05 09:34:00 * @LastEditTime: 2021-03-18 09:32:37
* @Description: 助学工具-题库-题目分类管理样式 * @Description: 助学工具-题库-题目分类管理样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
.question-category-manage { .question-category-manage {
position: relative; position: relative;
.search-condition { .search-condition {
width: 30%; width: 30%;
......
...@@ -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-16 17:23:02 * @LastEditTime: 2021-03-18 09:33:34
* @Description: 助学工具-题库-题目管理-新建题目Tab * @Description: 助学工具-题库-题目管理-新建题目Tab
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -11,17 +11,17 @@ import { Form, Radio, message, Checkbox, Tag, Tooltip, Input } from "antd"; ...@@ -11,17 +11,17 @@ 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 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,
QUESTION_FILE_ACCEPT, MEDIA_FILE_ACCEPT,
} from "@/common/constants/punchClock/punchClock"; } from "@/common/constants/punchClock/punchClock";
import { defineOptionInfo } from "./model"; import { defineOptionInfo, defineJudgeOptionInfo } from "./model";
import UploadingProgress from "./UploadingProgress"; 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 SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import _ from "lodash"; import _ from "lodash";
import UploadOss from "@/core/upload"; import UploadOss from "@/core/upload";
...@@ -41,13 +41,17 @@ class NewQuestionTab extends Component { ...@@ -41,13 +41,17 @@ class NewQuestionTab extends Component {
gapFillingAnswer: JSON.parse(JSON.stringify(gapFillingAnswerList)), // 填空题-选项列表 gapFillingAnswer: JSON.parse(JSON.stringify(gapFillingAnswerList)), // 填空题-选项列表
chooseOptions: JSON.parse(JSON.stringify(optionList)), // 单选多选不定项判断-选项列表 chooseOptions: JSON.parse(JSON.stringify(optionList)), // 单选多选不定项判断-选项列表
questionAnswerDesc: JSON.parse(JSON.stringify(questionAnswerDescList)), // 答案解析 questionAnswerDesc: JSON.parse(JSON.stringify(questionAnswerDescList)), // 答案解析
accept: QUESTION_FILE_ACCEPT["PICTURE"], // 上传媒体类型 accept: MEDIA_FILE_ACCEPT["PICTURE"], // 上传媒体类型
fileType: "PICTURE", // 媒体枚举 fileType: "PICTURE", // 媒体枚举
showRecord: false, // 录音弹窗 showRecord: false, // 录音弹窗
showBox: showBox, showBox: showBox,
gapFillingOptions: [], gapFillingOptions: [],
blanksList: [], // 填空列表 blanksList: [], // 填空列表
showSelectFileModal: false,
mediaType: "",
diskList: [], // 资料云盘文件列表
}; };
this.uploadInput = React.createRef(); this.uploadInput = React.createRef();
this.markKey = window.random_string(16); this.markKey = window.random_string(16);
} }
...@@ -67,6 +71,9 @@ class NewQuestionTab extends Component { ...@@ -67,6 +71,9 @@ class NewQuestionTab extends Component {
this.setState({ [`optionsText_${i}`]: "" }); this.setState({ [`optionsText_${i}`]: "" });
} }
} }
} else if (this.props.questionTypeKey === "JUDGE") {
this.initJudgeOption("正确");
this.initJudgeOption("错误");
} }
this.props.onRef(this); this.props.onRef(this);
} }
...@@ -92,9 +99,21 @@ class NewQuestionTab extends Component { ...@@ -92,9 +99,21 @@ 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({ this.setState(
stemContent: JSON.parse(JSON.stringify(questionInfo.questionStemList)), {
}); // 题干内容 stemContent: JSON.parse(
JSON.stringify(questionInfo.questionStemList)
),
},
() => {
const editorHtml = this.transferStemDocument(
questionInfo.questionStemList[0].content
);
const _blanksList = editorHtml.getElementsByClassName("fill-line");
// this.setState({blanksList:_blanksList})
console.log("转:", editorHtml.getElementsByClassName("fill-line"));
}
); // 题干内容
this.setState({ this.setState({
chooseOptions: JSON.parse(JSON.stringify(questionInfo.optionList)), chooseOptions: JSON.parse(JSON.stringify(questionInfo.optionList)),
}); // 单选多选不定项-选项列表 }); // 单选多选不定项-选项列表
...@@ -123,20 +142,15 @@ class NewQuestionTab extends Component { ...@@ -123,20 +142,15 @@ class NewQuestionTab extends Component {
}); });
}; };
dataURItoBlob = (dataURI) => { transferStemDocument = (txt) => {
var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]; // mime类型 const template = `<div class='stem'>${txt}</div>`;
var byteString = atob(dataURI.split(",")[1]); //base64 解码 let doc = new DOMParser().parseFromString(template, "text/html");
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组 let div = doc.querySelector(".stem");
var intArray = new Uint8Array(arrayBuffer); //创建视图 return div;
for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], { type: mimeString });
}; };
// 保存校验 // 保存校验
checkInput = async () => { checkInput = () => {
let validateError = 0; let validateError = 0;
// 题干校验 // 题干校验
let stemContent = _.find( let stemContent = _.find(
...@@ -144,23 +158,8 @@ class NewQuestionTab extends Component { ...@@ -144,23 +158,8 @@ class NewQuestionTab extends Component {
(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="" />`; if (this.props.questionTypeKey === "GAP_FILLING") {
// console.log("newImgHtml:", newImgHtml);
// }
// );
// console.log("修改:", stemContent);
// this._onSetState();
if (this.state.blanksList.length === 0) { if (this.state.blanksList.length === 0) {
this.setState({ stemValidate: "error" }); this.setState({ stemValidate: "error" });
this.setState({ this.setState({
...@@ -275,6 +274,17 @@ class NewQuestionTab extends Component { ...@@ -275,6 +274,17 @@ class NewQuestionTab extends Component {
}; };
/** /**
* 初始化判断选项
*
* @memberof QuestionInputItem
*/
initJudgeOption = (content) => {
const { chooseOptions } = this.state;
chooseOptions.push(defineJudgeOptionInfo(content));
this._onSetState();
};
/**
* 删除选项 * 删除选项
* *
* @memberof QuestionInputItem * @memberof QuestionInputItem
...@@ -309,43 +319,67 @@ class NewQuestionTab extends Component { ...@@ -309,43 +319,67 @@ class NewQuestionTab extends Component {
*/ */
handleChangeMedia = (key, uploadItemTarget, contentType) => { handleChangeMedia = (key, uploadItemTarget, contentType) => {
this.setState({ contentType }); this.setState({ contentType });
const { mediaFirstType } = this.state; const pictureMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
const mediaArr = _.filter(uploadItemTarget, (mediaItem) => { return mediaItem.type === "PICTURE";
return mediaItem.type !== "RICH_TEXT"; });
const voiceMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "VOICE";
});
const recordMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "RECORD";
});
const videodMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "VIDEO";
}); });
if (mediaArr.length === 0) {
this.setState({ mediaFirstType: key });
}
switch (contentType) { switch (contentType) {
case "QUESTION_STEM": case "QUESTION_STEM":
case "QUESTION_OPTION": var existType = [];
if (mediaArr.length > 0 && key !== mediaFirstType) { if (pictureMediaArr.length > 0) {
existType.push("PICTURE");
}
if (voiceMediaArr.length > 0) {
existType.push("VOICE");
}
if (recordMediaArr.length > 0) {
existType.push("RECORD");
}
if (videodMediaArr.length > 0) {
existType.push("VIDEO");
}
if (existType.length > 0 && !existType.includes(key)) {
return message.warning("只能添加1种类型的多媒体文件"); return message.warning("只能添加1种类型的多媒体文件");
} else {
if (key === "PICTURE" && pictureMediaArr.length > 8) {
return message.warning("只能添加9张图片");
}
if (key === "VOICE" && voiceMediaArr.length > 2) {
return message.warning("只能添加3个音频");
}
if (key === "VIDEO" && videodMediaArr.length > 2) {
return message.warning("只能添加3个视频");
}
} }
if (mediaFirstType === "PICTURE" && mediaArr.length > 8) { break;
return message.warning("只能添加9张图片"); case "QUESTION_OPTION":
var existType = [];
if (pictureMediaArr.length > 0) {
existType.push("PICTURE");
} }
if (mediaFirstType === "VOICE" && mediaArr.length > 2) { if (voiceMediaArr.length > 0) {
return message.warning("只能添加3个音频"); existType.push("VOICE");
}
if (recordMediaArr.length > 0) {
existType.push("RECORD");
}
if (videodMediaArr.length > 0) {
existType.push("VIDEO");
} }
if (mediaFirstType === "RECORD" && mediaArr.length > 2) { if (existType.length > 0) {
return message.warning("只能添加3个录音"); return message.warning("只能添加1个多媒体文件");
} }
break; break;
case "QUESTION_ANSWER_DESC": case "QUESTION_ANSWER_DESC":
var existType = []; var existType = [];
const pictureMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "PICTURE";
});
const voiceMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "VOICE";
});
const recordMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "RECORD";
});
const videodMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "VIDEO";
});
if (pictureMediaArr.length > 0) { if (pictureMediaArr.length > 0) {
existType.push("PICTURE"); existType.push("PICTURE");
} }
...@@ -375,8 +409,6 @@ class NewQuestionTab extends Component { ...@@ -375,8 +409,6 @@ class NewQuestionTab extends Component {
} }
} }
break; break;
default:
break;
} }
this.setState( this.setState(
...@@ -384,15 +416,16 @@ class NewQuestionTab extends Component { ...@@ -384,15 +416,16 @@ class NewQuestionTab extends Component {
uploadItemTarget, uploadItemTarget,
}, },
() => { () => {
QUESTION_FILE_ACCEPT[key] && MEDIA_FILE_ACCEPT[key] &&
this.setState( this.setState(
{ {
accept: QUESTION_FILE_ACCEPT[key], accept: MEDIA_FILE_ACCEPT[key],
fileType: key, fileType: key,
}, },
() => { () => {
this.uploadInput.current.value = ""; this.uploadInput.current.value = "";
this.uploadInput.current.click(); this.setState({ showSelectFileModal: key !== "RECORD" });
// this.uploadInput.current.click();
} }
); );
...@@ -406,60 +439,65 @@ class NewQuestionTab extends Component { ...@@ -406,60 +439,65 @@ class NewQuestionTab extends Component {
); );
}; };
async uploadFile(event) { async uploadFile(mediaFile) {
const { fileType, uploadItemTarget, contentType } = this.state; const { fileType, uploadItemTarget, contentType } = this.state;
const mediaFile = event.target.files[0];
if (!mediaFile) return; if (!mediaFile) return;
if (fileType === "VOICE") { if (fileType === "VOICE") {
if (!QUESTION_FILE_ACCEPT.VOICE.split(",").includes(mediaFile.type)) { if (
!MEDIA_FILE_ACCEPT.VOICE.split(",").includes(mediaFile.folderFormat)
) {
message.warning("文件格式不正确"); message.warning("文件格式不正确");
return; return;
} }
if (mediaFile.size > 30 * 1024 * 1024) { if (mediaFile.size > 20 * 1024 * 1024) {
Modal.warning({ Modal.warning({
title: "音频过大", title: "音频过大",
content: "音频大小超过30M,请压缩后上传", content: "音频大小超过20M,请压缩后上传",
}); });
return; return;
} }
} }
if (fileType === "PICTURE") { if (fileType === "PICTURE") {
if (!QUESTION_FILE_ACCEPT.PICTURE.split(",").includes(mediaFile.type)) { if (
!MEDIA_FILE_ACCEPT.PICTURE.split(",").includes(mediaFile.folderFormat)
) {
message.warning("文件格式不正确"); message.warning("文件格式不正确");
return; return;
} }
if (mediaFile.size > 8 * 1024 * 1024) { if (mediaFile.folderSize > 1 * 1024 * 1024) {
Modal.warning({ Modal.warning({
title: "图片过大", title: "图片过大",
content: "图片大小超过8M,请压缩后上传", content: "图片大小超过1M,请压缩后上传",
}); });
return; return;
} }
} }
if (fileType === "VIDEO") { if (fileType === "VIDEO") {
if (!QUESTION_FILE_ACCEPT.VIDEO.split(",").includes(mediaFile.type)) { if (
!MEDIA_FILE_ACCEPT.VIDEO.split(",").includes(mediaFile.folderFormat)
) {
message.warning("文件格式不正确"); message.warning("文件格式不正确");
return; return;
} }
if (mediaFile.size > 1024 * 1024 * 1024) { if (mediaFile.folderSize > 500 * 1024 * 1024) {
Modal.warning({ Modal.warning({
title: "视频过大", title: "视频过大",
content: "视频大小超过1G,请压缩后上传", content: "视频大小超过500G,请压缩后上传",
}); });
return; return;
} }
} }
const originArr = mediaFile.name.split("."); const originArr = mediaFile.folderName.split(".");
const originType = originArr[originArr.length - 1]; const originType = originArr[originArr.length - 1];
const uploadObj = { const uploadObj = {
contentType, contentType,
type: fileType, type: fileType,
contentName: `${window.random_string(16)}.${originType}`, // 文件名 contentName: `${window.random_string(16)}.${originType}`, // 文件名
fileType: originType, // 文件后缀 fileType: mediaFile.folderFormat, // 文件后缀
mediaFile, // url content: mediaFile.ossUrl, // url
}; };
if (["VIDEO", "VOICE"].includes(fileType)) { if (["VIDEO", "VOICE"].includes(fileType)) {
try { try {
...@@ -476,17 +514,18 @@ class NewQuestionTab extends Component { ...@@ -476,17 +514,18 @@ class NewQuestionTab extends Component {
console.log(error); console.log(error);
} }
} else if (fileType === "PICTURE") { } else if (fileType === "PICTURE") {
uploadObj.size = mediaFile.size; uploadObj.size = mediaFile.folderSize;
} }
uploadItemTarget.push(uploadObj); uploadItemTarget.push(uploadObj);
this.setState({}, () => { this.setState({}, () => {
this.handleReupload(uploadObj); this._onSetState();
this.uploadInput.current.value = ""; this.uploadInput.current.value = "";
}); });
} }
changeBlankCount = (data) => { changeBlankCount = (data) => {
data.map((item) => { console.log("data:", data);
data.forEach((item) => {
if (!item.answerTagList) { if (!item.answerTagList) {
item.answerTagList = []; item.answerTagList = [];
} }
...@@ -552,7 +591,7 @@ class NewQuestionTab extends Component { ...@@ -552,7 +591,7 @@ class NewQuestionTab extends Component {
return ( return (
<div className="gap-answer-box" key={optionIndex}> <div className="gap-answer-box" key={optionIndex}>
<span className="gap-answer-label"> <span className="gap-answer-label">
{optionItem.innerHTML} 填空
{optionIndex + 1}. {optionIndex + 1}.
</span> </span>
<div className="gap-answer-content"> <div className="gap-answer-content">
...@@ -618,10 +657,8 @@ class NewQuestionTab extends Component { ...@@ -618,10 +657,8 @@ class NewQuestionTab extends Component {
renderJudgeOption = (judgeOptions) => { renderJudgeOption = (judgeOptions) => {
return ( return (
<React.Fragment> <div dangerouslySetInnerHTML={{ __html: judgeOptions[0].content }}/>
<div>{judgeOptions[0].content}</div> )
</React.Fragment>
);
}; };
/** /**
* 渲染输入内容 * 渲染输入内容
...@@ -656,42 +693,28 @@ class NewQuestionTab extends Component { ...@@ -656,42 +693,28 @@ class NewQuestionTab extends Component {
return ( return (
<React.Fragment> <React.Fragment>
<div> <div>
{isGapFilling && contentType === "QUESTION_STEM" ? ( <QuestionEditor
<GapFillingStem markKey={this.markKey}
placehold={placehold} placehold={placehold}
validateStatus={validateStatus} validateStatus={validateStatus}
detailInfo={contentList} detailInfo={editorContent}
mediaBtn={mediaBtn} isGapFilling={isGapFilling}
changeBlankCount={this.changeBlankCount.bind(this)} contentType={contentType}
onChange={(html) => { mediaBtn={mediaBtn}
editorContent.content = html; changeBlankCount={this.changeBlankCount.bind(this)}
this._onSetState(); bindChangeContent={(cb, textElemId) => {
}} this.setState({ textElemId });
onUploadMedia={(key) => { editorContent.handleChangeContent = cb;
this.handleChangeMedia(key, contentList, contentType); }}
}} onChange={(content, textLength) => {
/> editorContent.content = content;
) : ( editorContent.textLength = textLength;
<QuestionEditor this._onSetState();
markKey={this.markKey} }}
placehold={placehold} onUploadMedia={(key) => {
validateStatus={validateStatus} this.handleChangeMedia(key, contentList, contentType);
detailInfo={editorContent} }}
mediaBtn={mediaBtn} />
bindChangeContent={(cb, textElemId) => {
this.setState({ textElemId });
editorContent.handleChangeContent = cb;
}}
onChange={(content, textLength) => {
editorContent.content = content;
editorContent.textLength = textLength;
this._onSetState();
}}
onUploadMedia={(key) => {
this.handleChangeMedia(key, contentList, contentType);
}}
/>
)}
</div> </div>
{contentType === "QUESTION_ANSWER_DESC" ? ( {contentType === "QUESTION_ANSWER_DESC" ? (
<div className="question-desc-box"> <div className="question-desc-box">
...@@ -1008,6 +1031,7 @@ class NewQuestionTab extends Component { ...@@ -1008,6 +1031,7 @@ class NewQuestionTab extends Component {
* @memberof QuestionInputItem * @memberof QuestionInputItem
*/ */
handleReupload = (uploadItem) => { handleReupload = (uploadItem) => {
console.log("uploadItem:", uploadItem);
uploadItem.status = "init"; uploadItem.status = "init";
Upload.uploadToOSSEvent( Upload.uploadToOSSEvent(
uploadItem.mediaFile, uploadItem.mediaFile,
...@@ -1056,10 +1080,15 @@ class NewQuestionTab extends Component { ...@@ -1056,10 +1080,15 @@ class NewQuestionTab extends Component {
* @memberof QuestionInputItem * @memberof QuestionInputItem
*/ */
handleFinishRecord = (mp3URL, duration) => { handleFinishRecord = (mp3URL, duration) => {
const originArr = mp3URL.split(".");
const originType = originArr[originArr.length - 1];
const { uploadItemTarget, contentType } = this.state; const { uploadItemTarget, contentType } = this.state;
uploadItemTarget.push({ uploadItemTarget.push({
contentType, contentType,
type: "RECORD", type: "RECORD",
contentName: `${window.random_string(16)}.${originType}`, // 文件名
fileType: originType, // 文件后缀
content: mp3URL, content: mp3URL,
size: duration, size: duration,
}); });
...@@ -1075,6 +1104,13 @@ class NewQuestionTab extends Component { ...@@ -1075,6 +1104,13 @@ class NewQuestionTab extends Component {
this.setState({ showRecord: false }); this.setState({ showRecord: false });
}; };
handleSelectMedia = (file) => {
this.uploadFile(file);
this.setState({
showSelectFileModal: false,
});
};
render() { render() {
const { const {
stemContent, stemContent,
...@@ -1086,9 +1122,14 @@ class NewQuestionTab extends Component { ...@@ -1086,9 +1122,14 @@ class NewQuestionTab extends Component {
scanFileType, scanFileType,
scanFileAddress, scanFileAddress,
blanksList, blanksList,
showSelectFileModal,
mediaType,
diskList,
} = 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";
console.log("this.props.questionTypeKey:", this.props.questionTypeKey)
console.log("判断:", isJudge)
const isGapFilling = this.props.questionTypeKey === "GAP_FILLING"; const isGapFilling = this.props.questionTypeKey === "GAP_FILLING";
const placehold = isGapFilling ? ( const placehold = isGapFilling ? (
<span> <span>
...@@ -1101,6 +1142,23 @@ class NewQuestionTab extends Component { ...@@ -1101,6 +1142,23 @@ class NewQuestionTab extends Component {
) : ( ) : (
"必填(1000字以内,可粘贴小图)" "必填(1000字以内,可粘贴小图)"
); );
let acceptType = "";
let selectTypeList = [];
switch (mediaType) {
case "PICTURE":
acceptType = "image/png,image/jpg";
selectTypeList = ["JPG", "PNG"];
break;
case "VOICE":
acceptType = "audio/mp3";
selectTypeList = ["MP3"];
break;
case "VIDEO":
acceptType = "video/mp4";
selectTypeList = ["MP4"];
break;
}
return ( return (
<div className="question-input-item_wrapper"> <div className="question-input-item_wrapper">
{/* 题干 */} {/* 题干 */}
...@@ -1170,6 +1228,7 @@ class NewQuestionTab extends Component { ...@@ -1170,6 +1228,7 @@ class NewQuestionTab extends Component {
questionOptionContentList, questionOptionContentList,
isCorrectAnswer, isCorrectAnswer,
} = optionItem; } = optionItem;
console.log("questionOptionContentList:", questionOptionContentList)
optionItem.optionSort = optionIndex; optionItem.optionSort = optionIndex;
const mediaBtn = ["VOICE", "RECORD", "PICTURE"]; const mediaBtn = ["VOICE", "RECORD", "PICTURE"];
const placeHold = const placeHold =
...@@ -1192,30 +1251,30 @@ class NewQuestionTab extends Component { ...@@ -1192,30 +1251,30 @@ class NewQuestionTab extends Component {
{["SINGLE_CHOICE", "JUDGE"].includes( {["SINGLE_CHOICE", "JUDGE"].includes(
this.props.questionTypeKey this.props.questionTypeKey
) && ( ) && (
<Radio <Radio
checked={isCorrectAnswer} checked={isCorrectAnswer}
onClick={() => { onClick={() => {
_.each(chooseOptions, (o) => { _.each(chooseOptions, (o) => {
o.isCorrectAnswer = 0; o.isCorrectAnswer = 0;
}); });
optionItem.isCorrectAnswer = 1; optionItem.isCorrectAnswer = 1;
this._onSetState(); this._onSetState();
}} }}
/> />
)} )}
{/* 多选 or 不定项 */} {/* 多选 or 不定项 */}
{["INDEFINITE_CHOICE", "MULTI_CHOICE"].includes( {["INDEFINITE_CHOICE", "MULTI_CHOICE"].includes(
this.props.questionTypeKey this.props.questionTypeKey
) && ( ) && (
<Checkbox <Checkbox
checked={isCorrectAnswer === 1} checked={isCorrectAnswer === 1}
onChange={(e) => { onChange={(e) => {
const checked = e.target.checked ? 1 : 0; const checked = e.target.checked ? 1 : 0;
optionItem.isCorrectAnswer = checked; optionItem.isCorrectAnswer = checked;
this._onSetState(); this._onSetState();
}} }}
/> />
)} )}
</Form.Item> </Form.Item>
</div> </div>
<div className="question-item_options__sort mr12"> <div className="question-item_options__sort mr12">
...@@ -1231,12 +1290,12 @@ class NewQuestionTab extends Component { ...@@ -1231,12 +1290,12 @@ class NewQuestionTab extends Component {
{isJudge {isJudge
? this.renderJudgeOption(questionOptionContentList) ? this.renderJudgeOption(questionOptionContentList)
: this.renderContent( : this.renderContent(
questionOptionContentList, questionOptionContentList,
placeHold, placeHold,
mediaBtn, mediaBtn,
"QUESTION_OPTION", "QUESTION_OPTION",
this.state[`optionsValidate_${optionIndex}`] this.state[`optionsValidate_${optionIndex}`]
)} )}
</Form.Item> </Form.Item>
</div> </div>
{[ {[
...@@ -1244,41 +1303,41 @@ class NewQuestionTab extends Component { ...@@ -1244,41 +1303,41 @@ class NewQuestionTab extends Component {
"MULTI_CHOICE", "MULTI_CHOICE",
"SINGLE_CHOICE", "SINGLE_CHOICE",
].includes(this.props.questionTypeKey) && ( ].includes(this.props.questionTypeKey) && (
<div className="question-item_options__extra"> <div className="question-item_options__extra">
<React.Fragment> <React.Fragment>
<span
className="option-operate_item__icon icon iconfont"
onClick={() => this.handleDelOption(optionIndex)}
>
&#xe81a;
</span>
{optionIndex > 0 && (
<span <span
className="option-operate_item__icon icon iconfont" className="option-operate_item__icon icon iconfont"
onClick={() => onClick={() => this.handleDelOption(optionIndex)}
this.handleMoveOption(optionIndex, -1)
}
> >
&#xe74a; &#xe81a;
</span> </span>
)} {optionIndex > 0 && (
{optionIndex < chooseOptions.length - 1 && ( <span
<span className="option-operate_item__icon icon iconfont"
className="option-operate_item__icon icon iconfont" onClick={() =>
style={{ this.handleMoveOption(optionIndex, -1)
transform: "rotate(180deg)", }
display: "inline-block", >
}} &#xe74a;
onClick={() => </span>
this.handleMoveOption(optionIndex, 1) )}
} {optionIndex < chooseOptions.length - 1 && (
> <span
&#xe74a; className="option-operate_item__icon icon iconfont"
</span> style={{
)} transform: "rotate(180deg)",
</React.Fragment> display: "inline-block",
</div> }}
)} onClick={() =>
this.handleMoveOption(optionIndex, 1)
}
>
&#xe74a;
</span>
)}
</React.Fragment>
</div>
)}
</div> </div>
); );
})} })}
...@@ -1335,6 +1394,17 @@ class NewQuestionTab extends Component { ...@@ -1335,6 +1394,17 @@ class NewQuestionTab extends Component {
}} }}
/> />
)} )}
<SelectPrepareFileModal
operateType="select"
accept={acceptType}
selectTypeList={selectTypeList}
isOpen={showSelectFileModal}
diskList={diskList}
onClose={() => {
this.setState({ showSelectFileModal: false });
}}
onSelect={this.handleSelectMedia}
/>
</div> </div>
); );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 10:59:43 * @Date: 2021-02-22 10:59:43
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 15:22:13 * @LastEditTime: 2021-03-18 09:33:50
* @Description: 助学工具-题库-题库主页面侧边栏 * @Description: 助学工具-题库-题库主页面侧边栏
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 12:02:34 * @Date: 2021-02-22 12:02:34
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-11 20:29:44 * @LastEditTime: 2021-03-18 09:34:06
* @Description: 助学工具-题库-题库主页面侧边栏样式 * @Description: 助学工具-题库-题库主页面侧边栏样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
.question-bank-sider { .question-bank-sider {
position: relative; position: relative;
.sider-title { .sider-title {
height: 22px; height: 22px;
......
...@@ -49,9 +49,15 @@ class QuestionEditor extends Component { ...@@ -49,9 +49,15 @@ class QuestionEditor extends Component {
this.renderEditor(); this.renderEditor();
} }
static getDerivedStateFromProps(nextProps, prevState) {
return {
detailInfo: nextProps.detailInfo
}
}
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { detailInfo } = nextProps; const { detailInfo } = nextProps;
if (this.props.detailInfo !== detailInfo) { if (this.state.detailInfo !== detailInfo) {
this.setState({ detailInfo: nextProps.detailInfo }, () => { this.setState({ detailInfo: nextProps.detailInfo }, () => {
this.renderEditor(); this.renderEditor();
}); });
...@@ -127,7 +133,6 @@ class QuestionEditor extends Component { ...@@ -127,7 +133,6 @@ class QuestionEditor extends Component {
}; };
editorRoot.customConfig.onchange = (html) => { editorRoot.customConfig.onchange = (html) => {
console.log("触发:+——+++++++", this.state.blanksList);
const { focusFlag } = this.state; const { focusFlag } = this.state;
const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ") const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ")
.length; .length;
...@@ -174,27 +179,27 @@ class QuestionEditor extends Component { ...@@ -174,27 +179,27 @@ class QuestionEditor extends Component {
editorRoot.create(); editorRoot.create();
this.editorRoot = editorRoot; this.editorRoot = editorRoot;
if (detailInfo.content) { // if (detailInfo && detailInfo.content) {
const contentHtml = /^\<p/.test(detailInfo.content) const contentHtml = /^\<p/.test(detailInfo.content)
? detailInfo.content ? detailInfo.content
: `<p>${detailInfo.content}</p>`; : `<p>${detailInfo.content}</p>`;
editorRoot.txt.html(detailInfo.content); editorRoot.txt.html(detailInfo.content);
const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ") const textLength = editorRoot.txt.text().replace(/\&nbsp\;/gi, " ")
.length; .length;
const imgLength = contentHtml.match(/<img/g) const imgLength = contentHtml.match(/<img/g)
? contentHtml.match(/<img/g).length * 2 ? contentHtml.match(/<img/g).length * 2
: 0; : 0;
const contentLength = imgLength + textLength; const contentLength = imgLength + textLength;
this.setState( this.setState(
{ {
contentLength, contentLength,
visiblePlacehold: contentLength === 0 && !this.state.focusFlag, visiblePlacehold: contentLength === 0 && !this.state.focusFlag,
}, },
() => { () => {
onChange && onChange(contentHtml, this.state.contentLength); onChange && onChange(contentHtml, this.state.contentLength);
} }
); );
} // }
bindChangeContent && bindChangeContent(this.handleChangeContent); bindChangeContent && bindChangeContent(this.handleChangeContent);
} }
...@@ -207,6 +212,9 @@ class QuestionEditor extends Component { ...@@ -207,6 +212,9 @@ class QuestionEditor extends Component {
var _blanksList = []; var _blanksList = [];
_blanksList = document.getElementsByClassName("add-fill-line"); _blanksList = document.getElementsByClassName("add-fill-line");
this.setState({ blanksList: _blanksList }); this.setState({ blanksList: _blanksList });
this.setState({
visiblePlacehold: false,
});
// this.props.changeBlankCount(_blanksList); // this.props.changeBlankCount(_blanksList);
}; };
...@@ -288,9 +296,8 @@ class QuestionEditor extends Component { ...@@ -288,9 +296,8 @@ class QuestionEditor extends Component {
</div> </div>
)} )}
<div <div
className={`editor-limit-tip${ className={`editor-limit-tip${contentLength > limitLength ? " mt6" : ""
contentLength > limitLength ? " mt6" : "" }`}
}`}
style={{ height: contentLength > limitLength ? 20 : 0 }} style={{ height: contentLength > limitLength ? 20 : 0 }}
> >
最多只能输入1000字 最多只能输入1000字
......
...@@ -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-17 12:43:53 * @LastEditTime: 2021-03-18 09:35:03
* @Description: 助学工具-题库-题目管理主页面列表数据 * @Description: 助学工具-题库-题目管理主页面列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -84,7 +84,7 @@ class QuestionManageContent extends Component { ...@@ -84,7 +84,7 @@ class QuestionManageContent extends Component {
}; };
} }
componentDidMount() {} componentDidMount() { }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { selectedCategoryId } = nextProps; const { selectedCategoryId } = nextProps;
...@@ -211,6 +211,8 @@ class QuestionManageContent extends Component { ...@@ -211,6 +211,8 @@ class QuestionManageContent extends Component {
// 表头设置 // 表头设置
parseColumns = () => { parseColumns = () => {
const isPermiss = ["CloudManager", "StoreManager"].includes(User.getUserRole());
console.log(isPermiss, User.getUserRole())
const columns = [ const columns = [
{ {
title: "题目", title: "题目",
...@@ -273,22 +275,22 @@ class QuestionManageContent extends Component { ...@@ -273,22 +275,22 @@ class QuestionManageContent extends Component {
> >
预览 预览
</div> </div>
<span className="record-operate__item split"> | </span> {isPermiss && <span className="record-operate__item split"> | </span>}
<div {isPermiss && <div
className="record-operate__item" className="record-operate__item"
onClick={() => onClick={() =>
this.toEditQuetion(record.id, record.questionTypeEnum) this.toEditQuetion(record.id, record.questionTypeEnum)
} }
> >
编辑 编辑
</div> </div>}
<span className="record-operate__item split"> | </span> {isPermiss && <span className="record-operate__item split"> | </span>}
<div {isPermiss && <div
className="record-operate__item" className="record-operate__item"
onClick={() => this.delCategoryConfirm(record)} onClick={() => this.delCategoryConfirm(record)}
> >
删除 删除
</div> </div>}
</div> </div>
); );
}, },
...@@ -311,9 +313,7 @@ class QuestionManageContent extends Component { ...@@ -311,9 +313,7 @@ class QuestionManageContent extends Component {
<span <span
className="empty-list-tip" className="empty-list-tip"
onClick={() => { onClick={() => {
window.RCHistory.push({ this.handleCreateQuestionBank()
pathname: "/create-question-bank",
});
}} }}
> >
新建一个 新建一个
...@@ -356,7 +356,7 @@ class QuestionManageContent extends Component { ...@@ -356,7 +356,7 @@ class QuestionManageContent extends Component {
const ImportQuestionModal = ( const ImportQuestionModal = (
<BatchImportQuestionModal <BatchImportQuestionModal
close={() => { close={() => {
this.setState({ ImportQuestionModal: null }); this.setState({ ImportQuestionModal: null }, () => { this.queryQuestionPageList(); this.props.updatedSiderTree(this.props.selectedCategoryId) });
}} }}
categoryId={categoryId} categoryId={categoryId}
/> />
...@@ -430,7 +430,7 @@ class QuestionManageContent extends Component { ...@@ -430,7 +430,7 @@ class QuestionManageContent extends Component {
</div> </div>
</Row> </Row>
</div> </div>
{!["0", null].includes(categoryId) && ( {(["CloudManager", "StoreManager"].includes(User.getUserRole()) && !["0", null].includes(categoryId)) && (
<Space size="large"> <Space size="large">
<Button type="primary" onClick={this.handleCreateQuestionBank}> <Button type="primary" onClick={this.handleCreateQuestionBank}>
新建题目 新建题目
......
/* /*
* @Author: chenjianyu * @Author: chenjianyu
* @Date: 2020-09-12 17:00:44 * @Date: 2020-09-12 17:00:44
* @LastEditTime: 2021-03-15 13:00:10 * @LastEditTime: 2021-03-18 09:33:26
* @LastEditors: yuananting * @LastEditors: yuananting
* @Description: 答题模式模板 * @Description: 答题模式模板
* @Copyright © 2020 杭州杰竞科技有限公司 版权所有 * @Copyright © 2020 杭州杰竞科技有限公司 版权所有
...@@ -54,7 +54,7 @@ export function defineQuestionInfo(questionType) { ...@@ -54,7 +54,7 @@ export function defineQuestionInfo(questionType) {
type: "RICH_TEXT", // 内容项形式(0:富文本 1:文字 2:图片 3:语音 4:视频 5文件 6.课件) type: "RICH_TEXT", // 内容项形式(0:富文本 1:文字 2:图片 3:语音 4:视频 5文件 6.课件)
} }
], // 题干 ], // 题干
optionList: [], // 非填空题选项 optionList: questionType === "JUDGE" ? [] : [], // 非填空题选项
gapFillingAnswerList: [ gapFillingAnswerList: [
{ {
correctAnswerList: [] correctAnswerList: []
...@@ -84,6 +84,19 @@ export function defineOptionInfo() { ...@@ -84,6 +84,19 @@ export function defineOptionInfo() {
} }
} }
export function defineJudgeOptionInfo(content) {
return {
isCorrectAnswer: 0, // 是否为正确答案选项
questionOptionContentList: [ // 选项内容
{
contentType: "QUESTION_OPTION", // 内容类型(默认选项)
content, // 内容
type: "RICH_TEXT",
}
]
}
}
export function defineOptionData(content = '') { export function defineOptionData(content = '') {
return { return {
itemContentVOList: [{ itemContentVOList: [{
......
...@@ -101,6 +101,7 @@ class BatchImportQuestionModal extends Component { ...@@ -101,6 +101,7 @@ class BatchImportQuestionModal extends Component {
return ( return (
<div> <div>
<Modal <Modal
closable={status !== "uploading"}
className="import-score-modal" className="import-score-modal"
title="导入题目信息" title="导入题目信息"
visible={true} visible={true}
...@@ -218,7 +219,11 @@ class BatchImportQuestionModal extends Component { ...@@ -218,7 +219,11 @@ class BatchImportQuestionModal extends Component {
<Button <Button
type="primary" type="primary"
className="down-btn" className="down-btn"
// onClick={} onClick={() => {
this.setState({ status: "init" })
this.setState({ uploadFile: null })
this.setState({ showSelectFileModal: true })
}}
> >
重新上传文件 重新上传文件
</Button> </Button>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-22 17:51:28 * @Date: 2021-02-22 17:51:28
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-03-15 09:56:59 * @LastEditTime: 2021-03-18 09:32:59
* @Description: 助学工具-题库-题库新建或编辑题库分类模态框 * @Description: 助学工具-题库-题库新建或编辑题库分类模态框
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
......
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