Commit a9d5c0db by sunbingqing

fix: 解决冲突

parents 2e7ee804 acb5ccd5
/*
* @Author: 陈剑宇
* @Date: 2020-10-28 14:27:07
* @LastEditTime: 2021-03-17 20:27:44
* @LastEditTime: 2021-03-18 10:30:41
* @LastEditors: yuananting
* @Description:
* @FilePath: /xiaomai-web-b/app/common/constants/punchClock/punchClock.js
......@@ -114,9 +114,9 @@ export const FILE_ACCEPT = {
}
export const MEDIA_FILE_ACCEPT = {
PICTURE: 'JPG,JPEG,PNG,BMP,GIF',
VIDEO: 'MP4',
VOICE: 'MP3'
PICTURE: 'image/jpg,image/jpeg,image/png,image/bmp,image/gif,JPG,JPEG,PNG,BMP,GIF',
VIDEO: 'audio/mp4,video/mp4,MP4',
VOICE: 'audio/x-mpeg,audio/mp3,audio/mpeg,audio/wav,audio/x-m4a,MP3'
}
export const QUESTION_FILE_ACCEPT = {
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-02-25 13:46:35
* @LastEditors: yuananting
* @LastEditTime: 2021-03-18 09:32:02
* @LastEditTime: 2021-03-18 14:12:22
* @Description: 助学工具-题库-题目管理-新增题目
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -12,7 +12,7 @@ import Breadcrumbs from "@/components/Breadcrumbs";
import ShowTips from "@/components/ShowTips";
import "./AddNewQuestion.less";
import NewQuestionTab from "./components/NewQuestionTab";
import { defineQuestionInfo } from "./components/model";
import { defineJudgeOptionInfo, defineOptionInfo, defineQuestionInfo } from "./components/model";
import QuestionBankService from "@/domains/question-bank-domain/QuestionBankService";
import User from "@/common/js/user";
import UploadOss from "@/core/upload";
......@@ -21,13 +21,13 @@ const { TabPane } = Tabs;
class AddNewQuestion extends Component {
constructor(props) {
super(props);
let activeKey = ""
let activeKey = "";
if (getParameterByName("type")) {
activeKey = getParameterByName("type")
activeKey = getParameterByName("type");
} else if (getParameterByName("key")) {
activeKey = getParameterByName("key")
activeKey = getParameterByName("key");
} else {
activeKey = "SINGLE_CHOICE"
activeKey = "SINGLE_CHOICE";
}
this.state = {
activeKey: activeKey,
......@@ -37,12 +37,14 @@ class AddNewQuestion extends Component {
judgeContent: defineQuestionInfo("JUDGE"), // 判断题
gapFillingContent: defineQuestionInfo("GAP_FILLING"), // 填空题
indefiniteChoiceContent: defineQuestionInfo("INDEFINITE_CHOICE"), // 不定项选择题
currentOperate: "new",
};
}
componentDidMount() {
if (getParameterByName("id")) {
// 编辑
this.setState({ currentOperate: "edit" });
this.queryQuestionDetails();
}
}
......@@ -77,6 +79,49 @@ class AddNewQuestion extends Component {
});
};
handleRest = (type) => {
this.setState({ currentOperate: "add" });
switch (type) {
case "SINGLE_CHOICE":
let singleChoiceContent = defineQuestionInfo("SINGLE_CHOICE");
for (var i = 0; i < 4; i++) {
singleChoiceContent.optionList.push(defineOptionInfo());
}
this.setState({ singleChoiceContent });
break;
case "MULTI_CHOICE":
let multiChoiceContent = defineQuestionInfo("MULTI_CHOICE");
for (var i = 0; i < 4; i++) {
multiChoiceContent.optionList.push(defineOptionInfo());
}
this.setState({ multiChoiceContent });
break;
case "JUDGE":
let judgeContent = defineQuestionInfo("JUDGE");
var judgeOptions = ["正确", "错误"];
judgeOptions.forEach(item=>{
judgeContent.optionList.push(defineJudgeOptionInfo(item));
})
this.setState({ judgeContent });
break;
case "GAP_FILLING":
this.setState({
gapFillingContent: defineQuestionInfo("GAP_FILLING"),
});
break;
case "INDEFINITE_CHOICE":
let indefiniteChoiceContent = defineQuestionInfo("INDEFINITE_CHOICE");
for (var i = 0; i < 4; i++) {
indefiniteChoiceContent.optionList.push(defineOptionInfo());
}
this.setState({ indefiniteChoiceContent });
}
};
initOption = (content) => {
chooseOptions.push(defineJudgeOptionInfo(content));
};
saveCurrentQuestion = (content, type, next) => {
content.questionStemList.map((item, index) => {
item.sort = index;
......@@ -95,8 +140,7 @@ class AddNewQuestion extends Component {
});
let params = {};
let categoryId = getParameterByName("categoryId");
if (getParameterByName("id")) {
if (getParameterByName("id") && this.state.currentOperate === "edit") {
params = {
...content,
id: getParameterByName("id"),
......@@ -109,12 +153,13 @@ class AddNewQuestion extends Component {
QuestionBankService.editQuestion(params).then((res) => {
if (res.success) {
message.success("保存成功");
if (next === 'add') {
window.RCHistory.push({
pathname: `/create-new-question?categoryId=${params.categoryId}&key=${type}`,
});
if (next === "add") {
this.handleRest(type);
// window.RCHistory.push({
// pathname: `/create-new-question?categoryId=${params.categoryId}&key=${type}`,
// });
}
if (next === 'close') {
if (next === "close") {
window.RCHistory.push({
pathname: `/question-bank-index?categoryId=${params.categoryId}`,
});
......@@ -132,12 +177,10 @@ class AddNewQuestion extends Component {
QuestionBankService.addQuestion(params).then((res) => {
if (res.success) {
message.success("保存成功");
if (next === 'add') {
window.RCHistory.push({
pathname: `/create-new-question?categoryId=${params.categoryId}&key=${type}`,
});
if (next === "add") {
this.handleRest(type);
}
if (next === 'close') {
if (next === "close") {
window.RCHistory.push({
pathname: `/question-bank-index?categoryId=${params.categoryId}`,
});
......@@ -150,16 +193,18 @@ class AddNewQuestion extends Component {
// 取消编辑并返回上一级路由
handleGoBack = () => {
Modal.confirm({
title: '确定要返回吗?',
content: '返回后,本次编辑的内容将不被保存',
okText: '确认返回',
cancelText: '留在本页',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
title: "确定要返回吗?",
content: "返回后,本次编辑的内容将不被保存",
okText: "确认返回",
cancelText: "留在本页",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe6f4;</span>
),
onOk: () => {
window.RCHistory.goBack();
}
})
}
},
});
};
confirmSaveQuestion = (next) => {
const {
......@@ -192,7 +237,11 @@ class AddNewQuestion extends Component {
break;
case "INDEFINITE_CHOICE":
if (this.indefiniteRef.checkInput() === 0) {
this.saveCurrentQuestion(indefiniteChoiceContent, "INDEFINITE_CHOICE", next);
this.saveCurrentQuestion(
indefiniteChoiceContent,
"INDEFINITE_CHOICE",
next
);
}
break;
}
......@@ -215,7 +264,7 @@ class AddNewQuestion extends Component {
return (
<div className="page add-new-question">
<Breadcrumbs
navList={getParameterByName("id") ? "编辑题目" : "新增题目"}
navList={getParameterByName("id") && this.state.currentOperate==="edit" ? "编辑题目" : "新增题目"}
goBack={() => this.handleGoBack()}
/>
<div className="box">
......@@ -240,7 +289,6 @@ class AddNewQuestion extends Component {
}}
questionInfo={singleChoiceContent}
onSetState={(newContent) => {
console.log("newContent:", newContent)
Object.assign(singleChoiceContent, newContent);
}}
onLogger={this.handleLogger}
......@@ -289,7 +337,6 @@ class AddNewQuestion extends Component {
questionInfo={gapFillingContent}
onSetState={(newContent) => {
Object.assign(gapFillingContent, newContent);
console.log("gapFillingContent:", newContent);
}}
/>
</TabPane>
......@@ -319,10 +366,20 @@ class AddNewQuestion extends Component {
</Tabs>
</div>
<div className="footer">
<Button onClick={() => { this.handleGoBack() }}>取消</Button>
<Button onClick={() => {
this.confirmSaveQuestion("add");
}}>保存并继续添加</Button>
<Button
onClick={() => {
this.handleGoBack();
}}
>
取消
</Button>
<Button
onClick={() => {
this.confirmSaveQuestion("add");
}}
>
保存并继续添加
</Button>
<Button
type="primary"
onClick={() => {
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-02-23 19:41:42
* @LastEditors: yuananting
* @LastEditTime: 2021-03-18 09:32:37
* @LastEditTime: 2021-03-18 13:58:30
* @Description: 助学工具-题库-题目分类管理样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -53,10 +53,11 @@
}
}
}
// .ant-tree-treenode-selected:hover::before,
// .ant-tree-treenode-selected::before {
// background: rgb(255 251 240);
// }
.ant-tree-treenode-selected:hover::before,
.ant-tree-treenode-selected::before {
background: #ffb714;
opacity: 0.06;
}
}
}
.xm-show-tip {
......
import React, { Component } from "react";
import { message, Button } from "antd";
import UploadOss from "@/core/upload";
import "./GapFillingStem.less";
const MEDIA_MAP = [
{
title: "音频",
icon: <React.Fragment>&#xe756;</React.Fragment>,
key: "VOICE",
},
{
title: "录音",
icon: <React.Fragment>&#xe7bb;</React.Fragment>,
key: "RECORD",
},
{
title: "图片",
icon: <React.Fragment>&#xe758;</React.Fragment>,
key: "PICTURE",
},
{
title: "视频",
icon: <React.Fragment>&#xe755;</React.Fragment>,
key: "VIDEO",
},
];
class GapFillingStem extends Component {
constructor(props) {
super(props);
this.state = {
visibleMediaBox: false,
zIndex: 9,
focusFlag: false,
isShowSingleInput: true,
contentLength: 0,
errorInput: false,
blanksList: [],
originBlanksList: [],
};
}
componentDidUpdate() {
const stemInput = document.getElementById("editor-box_content");
stemInput.addEventListener("DOMSubtreeModified", this.watchStemContent);
}
watchStemContent = () => {
var _blanksList = [];
const stemInput = document.getElementById("editor-box_content");
stemInput.childNodes.forEach((item) => {
if (item.nodeName === "SPAN" && item.id) {
_blanksList.push(item);
}
});
this.setState({blanksList:_blanksList})
this.handleStemStyle();
this.props.onChange(stemInput.innerHTML)
this.props.changeBlankCount(_blanksList);
};
/**
* 插入占位符
*
* @memberof QuestionInputItem
*/
insertBlanks = () => {
document.getElementById("editor-box_content").focus();
const _blanksList = this.state.blanksList;
console.log("888888888888:", _blanksList);
var blanks = document.createElement("span");
blanks.className = "fill-line";
blanks.innerHTML = "填空";
blanks.id = window.random_string(16); // 填空id
blanks.contentEditable = false;
_blanksList.push(blanks);
this.setState({ blanksList: _blanksList });
var sel, range;
sel = window.getSelection();
console.log("*****:", sel)
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
var el = document.createElement("div");
el.appendChild(blanks);
var frag = document.createDocumentFragment(),
node,
lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
};
// 输入框样式
handleStemStyle = () => {
const stemInput = document.getElementById("editor-box_content");
const textLength = stemInput.innerText.replace(/\&nbsp\;/gi, " ").length;
const imgLength = stemInput.innerHTML.match(/<img/g)
? stemInput.innerHTML.match(/<img/g).length * 2
: 0;
const contentLength = imgLength + textLength;
this.setState({ contentLength });
const divHeight = document.getElementById("editor-box_content")
.offsetHeight;
if (divHeight > 22 || imgLength > 0) {
this.setState({ isShowSingleInput: false });
} else {
this.setState({ isShowSingleInput: true });
}
};
handleUploadMedia = (key) => {
this.props.onUploadMedia && this.props.onUploadMedia(key);
};
render() {
const {
visibleMediaBox,
zIndex,
focusFlag,
contentLength,
isShowSingleInput,
errorInput,
} = this.state;
const {
mediaBtn = ["VOICE", "RECORD", "PICTURE", "VIDEO"],
limitLength = 1000,
} = this.props;
return (
<div
className="gap-question-edtior_box"
style={{ zIndex }}
onMouseEnter={() => {
if (visibleMediaBox || focusFlag) return;
const setZIndex = 101;
this.setState({
visibleMediaBox: true,
zIndex: setZIndex,
});
}}
onMouseLeave={() => {
if (!visibleMediaBox || focusFlag) return;
this.setState({
visibleMediaBox: false,
zIndex: 9,
});
}}
>
<div
className={
isShowSingleInput ? "editor-box-single " : "editor-box-multiple"
}
style={{
border:
this.props.validateStatus === "error" ? "1px solid red" : "",
}}
>
<div
placeholder="示例:党章规定,凡事有&nbsp;&nbsp;填空1&nbsp;&nbsp;
人以上的&nbsp;&nbsp;填空2&nbsp;&nbsp;
,都应该成立党的基层组织"
contentEditable
suppressContentEditableWarning
className="editor-box_content"
id="editor-box_content"
></div>
<div className="editor-limit">
<span style={{ color: errorInput ? "red" : "" }}>
{contentLength}
</span>
/{limitLength}
</div>
</div>
<div className="editor-fill-info" style={{ top: this.props.validateStatus === "error" ? "56px" : "36px" }}>
在需要填写答案的地方
<Button
type="link"
className="editor-fill-info_icon icon iconfont"
onClick={this.insertBlanks}
>
&#xe7fd; 插入占位符
</Button>
</div>
<div
className={`editor-limit-tip${
contentLength > limitLength ? " mt6" : ""
}`}
style={{ height: contentLength > limitLength ? 20 : 0 }}
>
最多只能输入1000字
</div>
{visibleMediaBox && !_.isEmpty(mediaBtn) && (
<div className="edtior-media_box">
<div className="edtior-media_list">
{_.map(mediaBtn, (mediaItem) => {
const mediaBtnMap = _.find(
MEDIA_MAP,
(mapItem) => mapItem.key === mediaItem
);
return (
mediaBtnMap && (
<div
className="edtior-media_item"
key={mediaItem}
onClick={() => this.handleUploadMedia(mediaItem)}
>
<div className="edtior-media_item__icon icon iconfont">
{mediaBtnMap.icon}
</div>
<div className="edtior-media_item__name">
{mediaBtnMap.title}
</div>
</div>
)
);
})}
</div>
</div>
)}
</div>
);
}
}
export default GapFillingStem;
.gap-question-edtior_box {
position: relative;
.editor-box-single {
border-radius: 4px;
padding: 4px 0 4px 10px;
border: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
.editor-box_content {
width: calc(100% - 80px);
.fill-line {
padding: 0 10px;
border-bottom: 1px solid;
}
}
.editor-limit {
padding-right: 12px;
line-height: 22px;
font-size: 12px;
color: #cccccc;
}
}
.editor-box-multiple {
border-radius: 4px;
padding: 4px 0 4px 10px;
border: 1px solid #e8e8e8;
.editor-box_content {
display: inline-block;
overflow-y: scroll;
max-height: 110px;
width: 100%;
.fill-line {
padding: 0 10px;
border-bottom: 1px solid;
}
}
.editor-limit {
text-align: right;
padding-right: 12px;
line-height: 22px;
font-size: 12px;
color: #cccccc;
padding-top: 3px;
}
}
.editor-box_content:empty:before {
content: attr(placeholder);
color: #ddd;
}
.editor-box_content:focus {
border: none;
outline: none;
}
.editor-fill-info {
// position: absolute;
height: 20px;
font-size: 14px;
line-height: 20px;
color: #999999;
margin-top: 8px;
.editor-fill-info_icon {
color: #5289fa;
font-size: 14px;
padding-left: 9px;
cursor: pointer;
}
}
.editor-limit-tip {
height: 20px;
text-align: right;
color: #ec4b35;
transition: height 0.5s ease-in-out;
overflow: hidden;
}
.editor-placehold {
position: absolute;
top: 0;
left: 0;
right: 0;
font-size: 14px;
color: #cccccc;
line-height: 22px;
margin: 6px 12px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.edtior-media_box {
position: absolute;
top: 100%;
left: 0;
padding-top: 9px;
&::before {
content: "";
border: 6px solid transparent;
border-bottom-color: #ffffff;
position: absolute;
top: -3px;
left: 50%;
margin-left: -3px;
filter: drop-shadow(-2px -2px 4px rgba(0, 0, 0, 0.06));
}
.edtior-media_list {
background: #ffffff;
box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.06);
border-radius: 4px;
display: flex;
align-items: center;
padding: 12px 24px;
}
.edtior-media_item {
margin-right: 24px;
cursor: pointer;
&:hover {
.edtior-media_item__icon {
color: #ffb714;
}
}
&:last-child {
margin-right: 0;
}
.edtior-media_item__icon {
color: #999999;
text-align: center;
font-size: 20px;
}
.edtior-media_item__name {
text-align: center;
font-size: 12px;
color: #999999;
line-height: 17px;
}
}
}
}
/*
* @Author: yuananting
* @Date: 2021-02-25 14:34:29
<<<<<<< HEAD
* @LastEditors: sunbingqing
* @LastEditTime: 2021-03-18 14:49:27
* @LastEditTime: 2021-03-18 14:53:01
=======
* @LastEditors: yuananting
* @LastEditTime: 2021-03-18 14:11:46
>>>>>>> acb5ccd546aa59474df75f3b0397b7308f9d5b12
* @Description: 助学工具-题库-题目管理-新建题目Tab
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -23,7 +28,6 @@ import XMRecord from "./XMRecord";
import ScanFileModal from "@/modules/resource-disk/modal/ScanFileModal";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import _ from "lodash";
import UploadOss from "@/core/upload";
class NewQuestionTab extends Component {
constructor(props) {
......@@ -222,7 +226,7 @@ class NewQuestionTab extends Component {
if (
optionContent.length === 1 &&
optionContent[0].type === "RICH_TEXT" &&
optionContent[0].content.length === 0
optionContent[0].textLength === 0
) {
this.setState({ [`optionsValidate_${index}`]: "error" });
this.setState({ [`optionsText_${index}`]: "请输入选项" });
......@@ -326,14 +330,15 @@ class NewQuestionTab extends Component {
*/
handleChangeMedia = (key, uploadItemTarget, contentType) => {
this.setState({ contentType });
this.setState({ mediaType: key });
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 audioMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "AUDIO";
});
const videodMediaArr = _.filter(uploadItemTarget, (mediaItem) => {
return mediaItem.type === "VIDEO";
......@@ -347,8 +352,8 @@ class NewQuestionTab extends Component {
if (voiceMediaArr.length > 0) {
existType.push("VOICE");
}
if (recordMediaArr.length > 0) {
existType.push("RECORD");
if (audioMediaArr.length > 0) {
existType.push("AUDIO");
}
if (videodMediaArr.length > 0) {
existType.push("VIDEO");
......@@ -375,8 +380,8 @@ class NewQuestionTab extends Component {
if (voiceMediaArr.length > 0) {
existType.push("VOICE");
}
if (recordMediaArr.length > 0) {
existType.push("RECORD");
if (audioMediaArr.length > 0) {
existType.push("AUDIO");
}
if (videodMediaArr.length > 0) {
existType.push("VIDEO");
......@@ -393,8 +398,8 @@ class NewQuestionTab extends Component {
if (voiceMediaArr.length > 0) {
existType.push("VOICE");
}
if (recordMediaArr.length > 0) {
existType.push("RECORD");
if (audioMediaArr.length > 0) {
existType.push("AUDIO");
}
if (videodMediaArr.length > 0) {
existType.push("VIDEO");
......@@ -408,7 +413,7 @@ class NewQuestionTab extends Component {
if (key === "VOICE" && voiceMediaArr.length > 2) {
return message.warning("只能添加3个音频");
}
if (key === "RECORD" && recordMediaArr.length > 2) {
if (key === "AUDIO" && audioMediaArr.length > 2) {
return message.warning("只能添加3个录音");
}
if (key === "VIDEO" && videodMediaArr.length > 2) {
......@@ -431,13 +436,13 @@ class NewQuestionTab extends Component {
},
() => {
this.uploadInput.current.value = "";
this.setState({ showSelectFileModal: key !== "RECORD" });
this.setState({ showSelectFileModal: key !== "AUDIO" });
// this.uploadInput.current.click();
}
);
// 录音
if (key === "RECORD") {
if (key === "AUDIO") {
this.setState({
showRecord: true,
});
......@@ -675,8 +680,8 @@ class NewQuestionTab extends Component {
renderJudgeOption = (judgeOptions) => {
return (
<div dangerouslySetInnerHTML={{ __html: judgeOptions[0].content }}/>
)
<div dangerouslySetInnerHTML={{ __html: judgeOptions[0].content }} />
);
};
/**
* 渲染输入内容
......@@ -702,8 +707,8 @@ class NewQuestionTab extends Component {
const voiceMediaList = _.filter(contentList, (mediaItem) => {
return mediaItem.type === "VOICE";
});
const recordMediaList = _.filter(contentList, (mediaItem) => {
return mediaItem.type === "RECORD";
const audioMediaList = _.filter(contentList, (mediaItem) => {
return mediaItem.type === "AUDIO";
});
const videoMediaList = _.filter(contentList, (mediaItem) => {
return mediaItem.type === "VIDEO";
......@@ -785,26 +790,26 @@ class NewQuestionTab extends Component {
})}
</div>
)}
{recordMediaList.length > 0 && (
{audioMediaList.length > 0 && (
<div className="desc-audio-box">
{_.map(recordMediaList, (recordItem, recordIndex) => {
let { content, status, size } = recordItem;
{_.map(audioMediaList, (audioItem, audioIndex) => {
let { content, status, size } = audioItem;
if (["init", "fail"].includes(status)) {
return (
<div className="mt12" key={recordIndex}>
<div className="mt12" key={audioIndex}>
<UploadingProgress
fileDesc={recordItem}
fileDesc={audioItem}
canCancelUpload
onReupload={() => this.handleReupload(recordItem)}
onReupload={() => this.handleReupload(audioItem)}
onAbort={() =>
this.handleAbort(recordItem, recordIndex)
this.handleAbort(audioItem, audioIndex)
}
/>
</div>
);
} else {
return (
<div className="audio-box" key={recordIndex}>
<div className="audio-box" key={audioIndex}>
<XMAudio
forbidParse
url={content}
......@@ -812,14 +817,14 @@ class NewQuestionTab extends Component {
size = durationSize;
this.setState({});
}}
index={recordIndex}
index={audioIndex}
size={size || 1000}
/>
<span
className="icon_sider iconfont"
onClick={() => {
contentList.map((item, index) => {
if (item.contentName === recordItem.contentName) {
if (item.contentName === audioItem.contentName) {
contentList.splice(index, 1);
return item;
}
......@@ -979,7 +984,7 @@ class NewQuestionTab extends Component {
</div>
);
break;
case "RECORD":
case "AUDIO":
dom = (
<div className="audio-box">
<XMAudio
......@@ -1105,7 +1110,7 @@ class NewQuestionTab extends Component {
const { uploadItemTarget, contentType } = this.state;
uploadItemTarget.push({
contentType,
type: "RECORD",
type: "AUDIO",
contentName: `${window.random_string(16)}.${originType}`, // 文件名
fileType: originType, // 文件后缀
content: mp3URL,
......@@ -1147,7 +1152,10 @@ class NewQuestionTab extends Component {
} = this.state;
const { stemValidate, stemText, radioValidate, radioText } = this.state;
const isJudge = this.props.questionTypeKey === "JUDGE";
<<<<<<< HEAD
=======
>>>>>>> acb5ccd546aa59474df75f3b0397b7308f9d5b12
const isGapFilling = this.props.questionTypeKey === "GAP_FILLING";
const placehold = isGapFilling ? (
<span>
......@@ -1162,21 +1170,24 @@ class NewQuestionTab extends Component {
);
let acceptType = "";
let selectTypeList = [];
console.log("mediaType", mediaType);
switch (mediaType) {
case "PICTURE":
acceptType = "image/png,image/jpg";
selectTypeList = ["JPG", "PNG"];
acceptType = MEDIA_FILE_ACCEPT.PICTURE;
selectTypeList = ["jpg", "png", "jpeg"];
break;
case "VOICE":
acceptType = "audio/mp3";
selectTypeList = ["MP3"];
acceptType = MEDIA_FILE_ACCEPT.VOICE;
selectTypeList = ["mp3", "mpeg"];
break;
case "VIDEO":
acceptType = "video/mp4";
selectTypeList = ["MP4"];
acceptType = MEDIA_FILE_ACCEPT.VIDEO;
selectTypeList = ["mp4"];
break;
}
console.log(acceptType, selectTypeList);
return (
<div className="question-input-item_wrapper">
{/* 题干 */}
......@@ -1191,7 +1202,7 @@ class NewQuestionTab extends Component {
{this.renderContent(
stemContent,
placehold,
["VOICE", "RECORD", "PICTURE"],
["VOICE", "AUDIO", "PICTURE"],
"QUESTION_STEM",
stemValidate
)}
......@@ -1246,8 +1257,15 @@ class NewQuestionTab extends Component {
questionOptionContentList,
isCorrectAnswer,
} = optionItem;
<<<<<<< HEAD
=======
console.log(
"questionOptionContentList:",
questionOptionContentList
);
>>>>>>> acb5ccd546aa59474df75f3b0397b7308f9d5b12
optionItem.optionSort = optionIndex;
const mediaBtn = ["VOICE", "RECORD", "PICTURE"];
const mediaBtn = ["VOICE", "AUDIO", "PICTURE"];
const placeHold =
"必填(1000字以内,可粘贴小图;可以不输入文字,只添加音频或图片)";
return (
......@@ -1268,30 +1286,30 @@ class NewQuestionTab extends Component {
{["SINGLE_CHOICE", "JUDGE"].includes(
this.props.questionTypeKey
) && (
<Radio
checked={isCorrectAnswer}
onClick={() => {
_.each(chooseOptions, (o) => {
o.isCorrectAnswer = 0;
});
optionItem.isCorrectAnswer = 1;
this._onSetState();
}}
/>
)}
<Radio
checked={isCorrectAnswer}
onClick={() => {
_.each(chooseOptions, (o) => {
o.isCorrectAnswer = 0;
});
optionItem.isCorrectAnswer = 1;
this._onSetState();
}}
/>
)}
{/* 多选 or 不定项 */}
{["INDEFINITE_CHOICE", "MULTI_CHOICE"].includes(
this.props.questionTypeKey
) && (
<Checkbox
checked={isCorrectAnswer === 1}
onChange={(e) => {
const checked = e.target.checked ? 1 : 0;
optionItem.isCorrectAnswer = checked;
this._onSetState();
}}
/>
)}
<Checkbox
checked={isCorrectAnswer === 1}
onChange={(e) => {
const checked = e.target.checked ? 1 : 0;
optionItem.isCorrectAnswer = checked;
this._onSetState();
}}
/>
)}
</Form.Item>
</div>
<div className="question-item_options__sort mr12">
......@@ -1307,12 +1325,12 @@ class NewQuestionTab extends Component {
{isJudge
? this.renderJudgeOption(questionOptionContentList)
: this.renderContent(
questionOptionContentList,
placeHold,
mediaBtn,
"QUESTION_OPTION",
this.state[`optionsValidate_${optionIndex}`]
)}
questionOptionContentList,
placeHold,
mediaBtn,
"QUESTION_OPTION",
this.state[`optionsValidate_${optionIndex}`]
)}
</Form.Item>
</div>
{[
......@@ -1320,41 +1338,41 @@ class NewQuestionTab extends Component {
"MULTI_CHOICE",
"SINGLE_CHOICE",
].includes(this.props.questionTypeKey) && (
<div className="question-item_options__extra">
<React.Fragment>
<div className="question-item_options__extra">
<React.Fragment>
<span
className="option-operate_item__icon icon iconfont"
onClick={() => this.handleDelOption(optionIndex)}
>
&#xe81a;
</span>
{optionIndex > 0 && (
<span
className="option-operate_item__icon icon iconfont"
onClick={() => this.handleDelOption(optionIndex)}
onClick={() =>
this.handleMoveOption(optionIndex, -1)
}
>
&#xe81a;
</span>
{optionIndex > 0 && (
<span
className="option-operate_item__icon icon iconfont"
onClick={() =>
this.handleMoveOption(optionIndex, -1)
}
>
&#xe74a;
</span>
)}
{optionIndex < chooseOptions.length - 1 && (
<span
className="option-operate_item__icon icon iconfont"
style={{
transform: "rotate(180deg)",
display: "inline-block",
}}
onClick={() =>
this.handleMoveOption(optionIndex, 1)
}
>
&#xe74a;
</span>
)}
</React.Fragment>
</div>
)}
&#xe74a;
</span>
)}
{optionIndex < chooseOptions.length - 1 && (
<span
className="option-operate_item__icon icon iconfont"
style={{
transform: "rotate(180deg)",
display: "inline-block",
}}
onClick={() =>
this.handleMoveOption(optionIndex, 1)
}
>
&#xe74a;
</span>
)}
</React.Fragment>
</div>
)}
</div>
);
})}
......@@ -1376,7 +1394,7 @@ class NewQuestionTab extends Component {
{this.renderContent(
questionAnswerDesc,
"1000字以内,可粘贴小图",
["VOICE", "RECORD", "PICTURE", "VIDEO"],
["VOICE", "AUDIO", "PICTURE", "VIDEO"],
"QUESTION_ANSWER_DESC"
)}
</div>
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-02-22 12:02:34
* @LastEditors: yuananting
* @LastEditTime: 2021-03-18 09:34:06
* @LastEditTime: 2021-03-18 13:59:24
* @Description: 助学工具-题库-题库主页面侧边栏样式
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -54,6 +54,11 @@
color: #666666;
}
}
.ant-tree-treenode-selected:hover::before,
.ant-tree-treenode-selected::before {
background: #ffb714;
opacity: 0.06;
}
}
}
}
......@@ -12,7 +12,7 @@ const MEDIA_MAP = [
{
title: "录音",
icon: <React.Fragment>&#xe7bb;</React.Fragment>,
key: "RECORD",
key: "AUDIO",
},
{
title: "图片",
......@@ -240,7 +240,7 @@ class QuestionEditor extends Component {
} = this.state;
const {
placehold,
mediaBtn = ["VOICE", "RECORD", "PICTURE", "VIDEO"],
mediaBtn = ["VOICE", "AUDIO", "PICTURE", "VIDEO"],
limitLength = 1000,
markKey,
} = this.props;
......
......@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting
* @LastEditTime: 2021-03-18 09:35:03
* @LastEditTime: 2021-03-18 14:21:22
* @Description: 助学工具-题库-题目管理主页面列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
......@@ -69,7 +69,7 @@ class QuestionManageContent extends Component {
query: {
current: 1,
size: 10,
order: "ACCURACY_DESC", // 排序规则[ ACCURACY_DESC, ACCURACY_ASC, CREATED_DESC, CREATED_ASC, UPDATED_DESC, UPDATED_ASC ]
order: "UPDATED_DESC", // 排序规则[ ACCURACY_DESC, ACCURACY_ASC, CREATED_DESC, CREATED_ASC, UPDATED_DESC, UPDATED_ASC ]
categoryId: null, // 当前题库分类Id
questionName: null, // 题目名称
questionType: null, // 题目类型
......@@ -212,7 +212,6 @@ class QuestionManageContent extends Component {
// 表头设置
parseColumns = () => {
const isPermiss = ["CloudManager", "StoreManager"].includes(User.getUserRole());
console.log(isPermiss, User.getUserRole())
const columns = [
{
title: "题目",
......
......@@ -50,6 +50,13 @@ class QuestionPreviewModal extends Component {
});
};
transferStemDocument = (txt) => {
const template = `<p class='content'>${txt}</p>`;
let doc = new DOMParser().parseFromString(template, "text/html");
let p = doc.querySelector(".content");
return p;
};
render() {
const {
showScanFile,
......@@ -80,8 +87,8 @@ class QuestionPreviewModal extends Component {
const voiceDescList = _.filter(questionAnswerDescList, (descItem) => {
return descItem.type === "VOICE";
});
const recordDescList = _.filter(questionAnswerDescList, (descItem) => {
return descItem.type === "RECORD";
const audioDescList = _.filter(questionAnswerDescList, (descItem) => {
return descItem.type === "AUDIO";
});
const videoDeacList = _.filter(questionAnswerDescList, (descItem) => {
return descItem.type === "VIDEO";
......@@ -111,6 +118,18 @@ class QuestionPreviewModal extends Component {
let { type, content, size } = item;
switch (type) {
case "RICH_TEXT":
if (questionTypeEnum === "GAP_FILLING") {
content = content.replace(
/_/g,
`<input
class="add-fill-line"
disabled
answerTagList=""
id=${window.random_string(16)}
value="填空"
/>`
);
}
dom = (
<div
key={index}
......@@ -262,12 +281,15 @@ class QuestionPreviewModal extends Component {
{_.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 className="gap-label">填空{index + 1}.</div>
<div className="gap-content" key={index}>
{_.map(
item.correctAnswerList,
(childItem, childIndex) => {
return <span>{childItem}</span>;
}
)}
</div>
</div>
);
})}
......@@ -305,12 +327,12 @@ class QuestionPreviewModal extends Component {
})}
</div>
)}
{recordDescList.length > 0 && (
{audioDescList.length > 0 && (
<div className="desc-audio-box">
{_.map(recordDescList, (recordItem, recordIndex) => {
let { content, size } = recordItem;
{_.map(audioDescList, (audioItem, audioIndex) => {
let { content, size } = audioItem;
return (
<div className="audio-box" key={recordIndex}>
<div className="audio-box" key={audioIndex}>
<XMAudio
forbidParse
url={content}
......@@ -318,7 +340,7 @@ class QuestionPreviewModal extends Component {
size = durationSize;
this.setState({});
}}
index={recordIndex}
index={audioIndex}
size={size || 1000}
/>
</div>
......
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