feat: 刷题页面
This commit is contained in:
360
src/views/upload-questions/components/brief-questions/index.jsx
Normal file
360
src/views/upload-questions/components/brief-questions/index.jsx
Normal file
@@ -0,0 +1,360 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Input, Modal, message, Spin } from 'antd';
|
||||
|
||||
import req from '@utils/request';
|
||||
import { debounce } from '@utils';
|
||||
import KindEditor from '../kind-editor';
|
||||
import RankLabelBox from '../rank-label-box';
|
||||
import RepeatContentBox from '../repeat-content-box';
|
||||
import { apiName } from '../../constant';
|
||||
import './index.less';
|
||||
|
||||
export default class BriefQuestions extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
subjectName: '', // 题目
|
||||
isDisabledSubmit: true, //是否禁止输入
|
||||
isShowModalBox: false, // 是否展示重复率弹框
|
||||
isSubmit: true, // 是否支持提交
|
||||
};
|
||||
}
|
||||
kindEditor = KindEditor | null;
|
||||
rankLabelBox = RankLabelBox | null;
|
||||
rankId = 1; //职级
|
||||
subjectAnswer = ''; // 答案
|
||||
firstCategoryValue = ''; // 一级分类的值
|
||||
secondCategoryValue = []; // 二级分类的值
|
||||
thirdCategoryValue = []; // 三级标签的值
|
||||
repeatInfo = {}; // 重复率
|
||||
|
||||
/**
|
||||
* 输入题目
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeSubjectName = (e) => {
|
||||
let str = e.target.value.trim();
|
||||
this.setState(
|
||||
{
|
||||
subjectName: str,
|
||||
},
|
||||
() => {
|
||||
this.rankLabelBox.getThirdCategoryList();
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 富文本编辑器
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeEditor = (e) => {
|
||||
this.subjectAnswer = e;
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 一次确认录入
|
||||
*/
|
||||
onSubmit = debounce(() => {
|
||||
const { subjectName, isDisabledSubmit, isSubmit } = this.state;
|
||||
if (isDisabledSubmit || !isSubmit) {
|
||||
return;
|
||||
}
|
||||
// if (!isSubmit) {
|
||||
// return;
|
||||
// }
|
||||
if (!!!subjectName) {
|
||||
message.warning('请输入题目名称');
|
||||
return;
|
||||
}
|
||||
if (!!!this.subjectAnswer) {
|
||||
message.warning('请输入题目答案');
|
||||
return;
|
||||
}
|
||||
if (!!!this.firstCategoryValue) {
|
||||
message.warning('请选择一级分类');
|
||||
return;
|
||||
}
|
||||
if (this.secondCategoryValue.length <= 0) {
|
||||
message.warning('请选择二级分类');
|
||||
return;
|
||||
}
|
||||
if (this.thirdCategoryValue.length <= 0) {
|
||||
message.warning('请选择三级标签');
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
isSubmit: false,
|
||||
});
|
||||
let params = {
|
||||
subjectName: subjectName,
|
||||
difficulty: this.rankId,
|
||||
subjectType: 4,
|
||||
subjectScore: 1,
|
||||
subjectAnswer: this.subjectAnswer,
|
||||
categoryIds: this.secondCategoryValue,
|
||||
labelIds: this.thirdCategoryValue,
|
||||
};
|
||||
console.log('录入 ----', params);
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
this.repeatInfo = {};
|
||||
if (res.data && res.data.insertStatus) {
|
||||
this.setState(
|
||||
{
|
||||
isSubmit: true,
|
||||
},
|
||||
() => {
|
||||
this.successModalConfirm();
|
||||
}
|
||||
);
|
||||
} else if (!res.data.insertStatus) {
|
||||
this.repeatInfo = {
|
||||
repeatDocId: res.data.docId, // 重复题目id
|
||||
repeatRate: res.data.repeatRate, // 重复率
|
||||
repeatSubjectName: res.data.subjectName, // 重复题目
|
||||
repeatSubjectAnswe: res.data.subjectAnswer, // 重复答案
|
||||
repeatSetterErp: res.data.subjectSetterErp, // 出题人erp
|
||||
repeatSetterName: res.data.subjectSetterName, // 出题人姓名
|
||||
};
|
||||
this.setState({
|
||||
isShowModalBox: true,
|
||||
isSubmit: true,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({
|
||||
isSubmit: true,
|
||||
});
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 校验是否支持点击按钮
|
||||
* @returns
|
||||
*/
|
||||
checkData = () => {
|
||||
const { subjectName } = this.state;
|
||||
let isDisabledSubmit = false;
|
||||
if (
|
||||
!!!subjectName ||
|
||||
!!!this.subjectAnswer ||
|
||||
!!!this.firstCategoryValue ||
|
||||
this.secondCategoryValue.length <= 0 ||
|
||||
this.thirdCategoryValue.length <= 0
|
||||
) {
|
||||
isDisabledSubmit = true;
|
||||
}
|
||||
return isDisabledSubmit;
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
onCancel = () => {
|
||||
this.subjectAnswer = ''; // 答案
|
||||
this.rankId = 1;
|
||||
this.firstCategoryValue = '';
|
||||
this.secondCategoryValue = [];
|
||||
this.thirdCategoryValue = [];
|
||||
this.repeatInfo = {};
|
||||
this.kindEditor.onClear();
|
||||
this.rankLabelBox.initRankLabel();
|
||||
this.setState({
|
||||
subjectName: '',
|
||||
isShowModalBox: false,
|
||||
isSubmit: true, // 是否支持提交
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 重复率弹框-确认录入
|
||||
*/
|
||||
onSubmitRepeatModal = debounce(
|
||||
() => {
|
||||
let params = {
|
||||
docId: this.repeatInfo.repeatDocId,
|
||||
};
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addRepeatInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data) {
|
||||
this.successModalConfirm();
|
||||
} else {
|
||||
message.info('请再次确认');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
message.error('请再次确认');
|
||||
});
|
||||
},
|
||||
300,
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* 重复率弹框-取消录入
|
||||
*/
|
||||
onCancelRepeatModal = () => {
|
||||
this.repeatInfo = {};
|
||||
this.setState({
|
||||
isShowModalBox: false,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功的弹框
|
||||
*/
|
||||
successModalConfirm = () => {
|
||||
Modal.confirm({
|
||||
title: (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
color: 'rgba(60, 110, 238, 1)',
|
||||
fontSize: 16,
|
||||
}}>
|
||||
录入成功!贡献榜火力值 + 1
|
||||
</div>
|
||||
),
|
||||
closable: false,
|
||||
maskClosable: false,
|
||||
icon: ' ',
|
||||
onOk: this.onAgainSuccessModal,
|
||||
onCancel: this.onGoHomeSuccessModal,
|
||||
okText: '再录一题',
|
||||
cancelText: '去首页',
|
||||
className: 'questions-success-modal-confirm',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-再来一题
|
||||
*/
|
||||
onAgainSuccessModal = () => {
|
||||
this.onCancel();
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-去首页
|
||||
*/
|
||||
onGoHomeSuccessModal = () => {
|
||||
window.location.href = '/cms-supplier/question-bank';
|
||||
};
|
||||
|
||||
/**
|
||||
* 分类选择
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeRankLabel = (firstCategoryValue, secondCategoryValue, thirdCategoryValue) => {
|
||||
this.firstCategoryValue = firstCategoryValue; // 一级分类的值
|
||||
this.secondCategoryValue = secondCategoryValue; // 二级分类的值
|
||||
this.thirdCategoryValue = thirdCategoryValue; // 三级标签的值
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 职级选择
|
||||
* @param {*} list
|
||||
*/
|
||||
handleChangeRank = (list) => {
|
||||
this.rankId = list[0];
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { subjectName, isDisabledSubmit, isSubmit, isShowModalBox } = this.state;
|
||||
const { questionsType } = this.props;
|
||||
// this.successModalConfirm();
|
||||
|
||||
return (
|
||||
<Spin spinning={!isSubmit}>
|
||||
<Fragment>
|
||||
<div className="brief-questions-container">
|
||||
<div className="brief-questions-title">题目名称:</div>
|
||||
<div className="brief-questions-main">
|
||||
<Input
|
||||
placeholder="输入题目"
|
||||
className="brief-questions-input"
|
||||
value={subjectName}
|
||||
maxLength={64}
|
||||
onChange={this.onChangeSubjectName}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="brief-questions-container">
|
||||
<div className="brief-questions-title">题目答案:</div>
|
||||
{this.reanderAnser()}
|
||||
</div>
|
||||
<RankLabelBox
|
||||
ref={(ref) => {
|
||||
this.rankLabelBox = ref;
|
||||
}}
|
||||
subjectName={subjectName}
|
||||
onChangeRankLabel={this.onChangeRankLabel}
|
||||
handleChangeRank={this.handleChangeRank}
|
||||
/>
|
||||
<div className="brief-questions-btns-container">
|
||||
<div className="brief-questions-btn" onClick={this.onCancel}>
|
||||
清空
|
||||
</div>
|
||||
<div
|
||||
className={`brief-questions-btn brief-questions-submit ${isDisabledSubmit && 'brief-questions-disabled-submit'
|
||||
}`}
|
||||
onClick={this.onSubmit}>
|
||||
提交
|
||||
</div>
|
||||
</div>
|
||||
<RepeatContentBox
|
||||
isShowModalBox={isShowModalBox}
|
||||
repeatQuestionsType={questionsType}
|
||||
repeatInfo={this.repeatInfo}
|
||||
handleSubmitRepeatModal={this.onSubmitRepeatModal}
|
||||
handleCancelRepeatModal={this.onCancelRepeatModal}
|
||||
/>
|
||||
</Fragment>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 问答题-答案
|
||||
*/
|
||||
reanderAnser = () => {
|
||||
return (
|
||||
<div className="brief-questions-main">
|
||||
<KindEditor
|
||||
onChange={this.onChangeEditor}
|
||||
ref={(ref) => {
|
||||
this.kindEditor = ref;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@@ -0,0 +1,58 @@
|
||||
.brief-questions-container {
|
||||
width: 1000px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
padding-top: 36px;
|
||||
.brief-questions-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
color: #f5222d;
|
||||
font-size: 16px;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
.brief-questions-main {
|
||||
width: 100%;
|
||||
// 题目输入框
|
||||
.brief-questions-input {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.brief-questions-btns-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px auto;
|
||||
width: 952px;
|
||||
.brief-questions-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 150px;
|
||||
height: 40px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.brief-questions-submit {
|
||||
margin-left: 40px;
|
||||
background-color: #4390f7;
|
||||
color: #fff;
|
||||
border: 1px solid #4390f7;
|
||||
}
|
||||
.brief-questions-disabled-submit {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
327
src/views/upload-questions/components/judge-questions/index.jsx
Normal file
327
src/views/upload-questions/components/judge-questions/index.jsx
Normal file
@@ -0,0 +1,327 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Input, Modal, message, Spin } from 'antd';
|
||||
import req from '@utils/request';
|
||||
import { debounce } from '@utils';
|
||||
import RankLabelBox from '../rank-label-box';
|
||||
import OptionInputBox from '../option-input-box';
|
||||
import RepeatContentBox from '../repeat-content-box';
|
||||
import { apiName } from '../../constant';
|
||||
import './index.less';
|
||||
export default class JudgeQuestions extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
subjectName: '', // 题目
|
||||
isDisabledSubmit: true, //是否禁止输入
|
||||
isShowModalBox: false, // 是否展示重复率弹框
|
||||
isSubmit: true, // 是否支持提交
|
||||
};
|
||||
}
|
||||
rankLabelBox = RankLabelBox | null;
|
||||
optionInputBox = OptionInputBox | null;
|
||||
currentActive = []; // 当前选中的项
|
||||
scoreValue = ''; // 分数
|
||||
subjectAnalysis = ''; //试题解析
|
||||
rankId = 1; //职级
|
||||
firstCategoryValue = ''; // 一级分类的值
|
||||
secondCategoryValue = []; // 二级分类的值
|
||||
thirdCategoryValue = []; // 三级标签的值
|
||||
repeatInfo = {}; // 重复率
|
||||
|
||||
/**
|
||||
* 输入题目
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeSubjectName = (e) => {
|
||||
let str = e.target.value.trim();
|
||||
this.setState(
|
||||
{
|
||||
subjectName: str,
|
||||
},
|
||||
() => {
|
||||
this.rankLabelBox.getThirdCategoryList();
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 一次确认录入
|
||||
*/
|
||||
onSubmit = debounce(() => {
|
||||
const { subjectName, isDisabledSubmit, isSubmit } = this.state;
|
||||
if (isDisabledSubmit || !isSubmit) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
isSubmit: false,
|
||||
});
|
||||
let params = {
|
||||
subjectName: subjectName,
|
||||
difficulty: this.rankId,
|
||||
subjectType: 3,
|
||||
subjectScore: this.scoreValue,
|
||||
subjectParse: this.subjectAnalysis,
|
||||
isCorrect: this.currentActive[0],
|
||||
categoryIds: this.secondCategoryValue,
|
||||
labelIds: this.thirdCategoryValue,
|
||||
};
|
||||
console.log('判断录入 ----', params);
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
this.repeatInfo = {};
|
||||
if (res.data && res.data.insertStatus) {
|
||||
this.setState(
|
||||
{
|
||||
isSubmit: true,
|
||||
},
|
||||
() => {
|
||||
this.successModalConfirm();
|
||||
}
|
||||
);
|
||||
} else if (!res.data.insertStatus) {
|
||||
this.repeatInfo = {
|
||||
repeatDocId: res.data.docId, // 重复题目id
|
||||
repeatRate: res.data.repeatRate, // 重复率
|
||||
repeatIsCorrect: res.data.isCorrect, // 答案
|
||||
repeatSubjectName: res.data.subjectName, // 重复题目
|
||||
repeatSetterErp: res.data.subjectSetterErp, // 出题人erp
|
||||
repeatSetterName: res.data.subjectSetterName, // 出题人姓名
|
||||
};
|
||||
this.setState({
|
||||
isShowModalBox: true,
|
||||
isSubmit: true,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({
|
||||
isSubmit: true,
|
||||
});
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 校验是否支持点击按钮
|
||||
* @returns
|
||||
*/
|
||||
checkData = () => {
|
||||
const { subjectName } = this.state;
|
||||
let isDisabledSubmit = false;
|
||||
if (
|
||||
!!!subjectName ||
|
||||
this.currentActive?.length <= 0 ||
|
||||
!!!this.firstCategoryValue ||
|
||||
this.secondCategoryValue.length <= 0 ||
|
||||
this.thirdCategoryValue.length <= 0 ||
|
||||
!!!this.scoreValue
|
||||
) {
|
||||
isDisabledSubmit = true;
|
||||
}
|
||||
return isDisabledSubmit;
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
onCancel = () => {
|
||||
this.currentActive = []; // 选项列表
|
||||
this.scoreValue = ''; // 分数
|
||||
this.subjectAnalysis = ''; //试题解析
|
||||
this.rankId = 1;
|
||||
this.firstCategoryValue = ''; // 一级分类的值
|
||||
this.secondCategoryValue = []; // 二级分类的值
|
||||
this.thirdCategoryValue = []; // 三级标签的值
|
||||
this.repeatInfo = {};
|
||||
this.rankLabelBox.initRankLabel();
|
||||
this.optionInputBox.handleClearOption();
|
||||
this.setState({
|
||||
subjectName: '',
|
||||
isShowModalBox: false,
|
||||
isSubmit: true, // 是否支持提交
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 重复率弹框-确认录入
|
||||
*/
|
||||
onSubmitRepeatModal = debounce(
|
||||
() => {
|
||||
let params = {
|
||||
docId: this.repeatInfo.repeatDocId,
|
||||
};
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addRepeatInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data) {
|
||||
this.successModalConfirm();
|
||||
} else {
|
||||
message.info('请再次确认');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
message.error('请再次确认');
|
||||
});
|
||||
},
|
||||
300,
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* 重复率弹框-取消录入
|
||||
*/
|
||||
onCancelRepeatModal = () => {
|
||||
this.repeatInfo = {};
|
||||
this.setState({
|
||||
isShowModalBox: false,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功的弹框
|
||||
*/
|
||||
successModalConfirm = () => {
|
||||
Modal.confirm({
|
||||
title: (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
color: 'rgba(60, 110, 238, 1)',
|
||||
fontSize: 16,
|
||||
}}>
|
||||
录入成功!贡献榜火力值 + 1
|
||||
</div>
|
||||
),
|
||||
closable: false,
|
||||
maskClosable: false,
|
||||
icon: ' ',
|
||||
onOk: this.onAgainSuccessModal,
|
||||
onCancel: this.onGoHomeSuccessModal,
|
||||
okText: '再录一题',
|
||||
cancelText: '去首页',
|
||||
className: 'questions-success-modal-confirm',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-再来一题
|
||||
*/
|
||||
onAgainSuccessModal = () => {
|
||||
this.onCancel();
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-去首页
|
||||
*/
|
||||
onGoHomeSuccessModal = () => {
|
||||
// this.onCancel();
|
||||
window.location.href = '/cms-supplier/question-bank';
|
||||
};
|
||||
|
||||
/**
|
||||
* 分类选择
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeRankLabel = (firstCategoryValue, secondCategoryValue, thirdCategoryValue) => {
|
||||
this.firstCategoryValue = firstCategoryValue; // 一级分类的值
|
||||
this.secondCategoryValue = secondCategoryValue; // 二级分类的值
|
||||
this.thirdCategoryValue = thirdCategoryValue; // 三级标签的值
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 职级选择
|
||||
* @param {*} list
|
||||
*/
|
||||
handleChangeRank = (list) => {
|
||||
this.rankId = list[0];
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 选项操作
|
||||
* @param {*} currentActive 选项列表
|
||||
* @param {*} scoreValue 分值
|
||||
* @param {*} subjectAnalysis 解析
|
||||
*/
|
||||
handleChangeOption = (currentActive, scoreValue, subjectAnalysis) => {
|
||||
this.currentActive = currentActive;
|
||||
this.scoreValue = scoreValue;
|
||||
this.subjectAnalysis = subjectAnalysis;
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { subjectName, isDisabledSubmit, isSubmit, isShowModalBox } = this.state;
|
||||
const { questionsType } = this.props;
|
||||
return (
|
||||
<Spin spinning={!isSubmit}>
|
||||
<Fragment>
|
||||
<div className="judge-questions-container">
|
||||
<div className="judge-questions-title">题目名称:</div>
|
||||
<Input
|
||||
placeholder="输入题目"
|
||||
style={{ height: 48, width: '100%' }}
|
||||
value={subjectName}
|
||||
maxLength={64}
|
||||
onChange={(e) => this.onChangeSubjectName(e)}
|
||||
/>
|
||||
</div>
|
||||
<OptionInputBox
|
||||
ref={(ref) => {
|
||||
this.optionInputBox = ref;
|
||||
}}
|
||||
isJudge={true}
|
||||
handleChangeOption={this.handleChangeOption}
|
||||
/>
|
||||
<RankLabelBox
|
||||
ref={(ref) => {
|
||||
this.rankLabelBox = ref;
|
||||
}}
|
||||
subjectName={subjectName}
|
||||
onChangeRankLabel={this.onChangeRankLabel}
|
||||
handleChangeRank={this.handleChangeRank}
|
||||
/>
|
||||
<div className="judge-questions-btns-container">
|
||||
<div className="judge-questions-btn" onClick={this.onCancel}>
|
||||
清空
|
||||
</div>
|
||||
<div
|
||||
className={`judge-questions-btn judge-questions-submit ${isDisabledSubmit && 'judge-questions-disabled-submit'
|
||||
}`}
|
||||
onClick={this.onSubmit}>
|
||||
提交
|
||||
</div>
|
||||
</div>
|
||||
<RepeatContentBox
|
||||
isShowModalBox={isShowModalBox}
|
||||
repeatQuestionsType={questionsType}
|
||||
repeatInfo={this.repeatInfo}
|
||||
handleSubmitRepeatModal={this.onSubmitRepeatModal}
|
||||
handleCancelRepeatModal={this.onCancelRepeatModal}
|
||||
/>
|
||||
</Fragment>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
.judge-questions-container {
|
||||
width: 1000px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
padding-top: 36px;
|
||||
// label名字title
|
||||
.judge-questions-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
color: #f5222d;
|
||||
font-size: 16px;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
}
|
||||
.judge-questions-btns-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px auto;
|
||||
width: 952px;
|
||||
.judge-questions-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 150px;
|
||||
height: 40px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.judge-questions-submit {
|
||||
margin-left: 40px;
|
||||
background-color: #4390f7;
|
||||
color: #fff;
|
||||
border: 1px solid #4390f7;
|
||||
}
|
||||
.judge-questions-disabled-submit {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
153
src/views/upload-questions/components/kind-editor/index.jsx
Normal file
153
src/views/upload-questions/components/kind-editor/index.jsx
Normal file
@@ -0,0 +1,153 @@
|
||||
import React, { Component } from 'react';
|
||||
import './index.less';
|
||||
|
||||
import Editor from 'wangeditor';
|
||||
|
||||
export default class KindEditor extends Component {
|
||||
defaultValueHead = `<div style='font-size:14px !important;line-height:22px !important;margin-bottom: -15px !important;word-break: break-word !important;'>`;
|
||||
defaultValueFoot = '</div>';
|
||||
editor = Editor;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { editorContent: '', isActive: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空内容
|
||||
*/
|
||||
onClear = () => {
|
||||
this.editor.txt.clear();
|
||||
this.editor.config.focus = false;
|
||||
this.setState({
|
||||
isActive: false,
|
||||
editorContent: '',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 回现代码
|
||||
*/
|
||||
onCashBack = () => {
|
||||
let { cashBackText } = this.props;
|
||||
if (!!!cashBackText) {
|
||||
return;
|
||||
}
|
||||
this.editor.txt.html(`${cashBackText}`);
|
||||
this.editor.config.focus = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获得焦点
|
||||
*/
|
||||
onFocus = () => {
|
||||
this.editor.config.focus = true;
|
||||
this.setState({
|
||||
isActive: true,
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const elemMenu = this.refs.editorElemMenu;
|
||||
const elemBody = this.refs.editorElemBody;
|
||||
this.editor = new Editor(elemMenu, elemBody);
|
||||
// // 使用 onchange 函数监听内容的变化,并实时更新到 state 中
|
||||
this.editor.config.onchange = (html) => {
|
||||
let htmlStr = this.editor.txt.html();
|
||||
// console.log('htmlStr ---', htmlStr);
|
||||
if (htmlStr?.indexOf('<div style=') < 0) {
|
||||
htmlStr = this.defaultValueHead + htmlStr + this.defaultValueFoot;
|
||||
}
|
||||
let isActive = false;
|
||||
if (this.state.editorContent) {
|
||||
isActive = true;
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
// editorContent: editor.txt.text()
|
||||
editorContent: htmlStr,
|
||||
isActive: isActive,
|
||||
},
|
||||
() => {
|
||||
this.props.onChange(htmlStr);
|
||||
}
|
||||
);
|
||||
};
|
||||
this.editor.config.onfocus = () => {
|
||||
this.setState({
|
||||
isActive: true,
|
||||
});
|
||||
};
|
||||
this.editor.config.onblur = () => {
|
||||
this.setState({
|
||||
isActive: false,
|
||||
});
|
||||
};
|
||||
|
||||
this.editor.config.menus = [
|
||||
// 'head', // 标题
|
||||
// 'bold', // 粗体
|
||||
// 'fontSize', // 字号
|
||||
// 'fontName', // 字体
|
||||
// 'italic', // 斜体
|
||||
// 'underline', // 下划线
|
||||
// 'strikeThrough', // 删除线
|
||||
'foreColor', // 文字颜色
|
||||
// 'backColor', // 背景颜色
|
||||
// 'link', // 插入链接
|
||||
'list', // 列表
|
||||
// 'justify', // 对齐方式
|
||||
// 'quote', // 引用
|
||||
// 'emoticon', // 表情
|
||||
// 'image', // 插入图片
|
||||
// 'table', // 表格
|
||||
// 'video', // 插入视频
|
||||
'code', // 插入代码
|
||||
'undo', // 撤销
|
||||
// 'redo', // 重复
|
||||
];
|
||||
// this.editor.customConfig.uploadImgShowBase64 = true;
|
||||
// 取消自动 focus
|
||||
this.editor.config.focus = false;
|
||||
this.editor.config.pasteFilterStyle = true; // 样式过滤
|
||||
this.editor.config.pasteIgnoreImg = true; // 如果复制的内容有图片又有文字,则只粘贴文字,不粘贴图片
|
||||
this.editor.config.placeholder = '请输入';
|
||||
this.editor.create();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isActive } = this.state;
|
||||
const { bodyHeight, bodyWidth, borderRadius } = this.props;
|
||||
return (
|
||||
<div
|
||||
className={`text-area ${isActive && 'kind-editor-active-box'}`}
|
||||
style={{
|
||||
borderRadius: borderRadius,
|
||||
}}>
|
||||
<div
|
||||
ref="editorElemMenu"
|
||||
className="editorelem-menu"
|
||||
style={{
|
||||
width: bodyWidth,
|
||||
borderTopLeftRadius: borderRadius,
|
||||
borderTopRightRadius: borderRadius,
|
||||
}}></div>
|
||||
<div
|
||||
ref="editorElemBody"
|
||||
className="editorelem-body"
|
||||
style={{
|
||||
height: bodyHeight,
|
||||
width: bodyWidth,
|
||||
borderBottomLeftRadius: borderRadius,
|
||||
borderBottomRightRadius: borderRadius,
|
||||
}}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
KindEditor.defaultProps = {
|
||||
bodyHeight: 320,
|
||||
bodyWidth: '100%',
|
||||
borderRadius: '4px',
|
||||
};
|
32
src/views/upload-questions/components/kind-editor/index.less
Normal file
32
src/views/upload-questions/components/kind-editor/index.less
Normal file
@@ -0,0 +1,32 @@
|
||||
.text-area {
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
.editorelem-menu {
|
||||
border: 1px solid #d9d9d9;
|
||||
.w-e-menu-tooltip {
|
||||
padding: 0px 6px;
|
||||
line-height: 28px;
|
||||
}
|
||||
.w-e-toolbar {
|
||||
z-index: 2 !important;
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
.editorelem-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 10px 10px;
|
||||
overflow-y: scroll;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-top: none;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
}
|
||||
.w-e-text-container {
|
||||
z-index: 1 !important;
|
||||
}
|
||||
.kind-editor-active-box {
|
||||
border: 1px solid #40a9ff;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
}
|
@@ -0,0 +1,343 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Input, Modal, message, Spin } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import req from '@utils/request';
|
||||
import { debounce } from '@utils';
|
||||
import KindEditor from '../kind-editor';
|
||||
import RankLabelBox from '../rank-label-box';
|
||||
import OptionInputBox from '../option-input-box';
|
||||
import RepeatContentBox from '../repeat-content-box';
|
||||
import { apiName } from '../../constant';
|
||||
import './index.less';
|
||||
|
||||
const defalutLabel = '请使用富文本编辑器输入选项内容';
|
||||
export default class MultipleQuestions extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
subjectName: '', // 题目
|
||||
isDisabledSubmit: true, //是否禁止输入
|
||||
isShowModalBox: false, // 是否展示重复率弹框
|
||||
isSubmit: true, // 是否支持提交
|
||||
};
|
||||
}
|
||||
kindEditor = KindEditor | null;
|
||||
rankLabelBox = RankLabelBox | null;
|
||||
optionInputBox = OptionInputBox | null;
|
||||
currentActive = []; // 选项列表
|
||||
scoreValue = ''; // 分数
|
||||
subjectAnalysis = ''; //试题解析
|
||||
rankId = 1; //职级
|
||||
subjectAnswer = ''; // 选项内容
|
||||
firstCategoryValue = ''; // 一级分类的值
|
||||
secondCategoryValue = []; // 二级分类的值
|
||||
thirdCategoryValue = []; // 三级标签的值
|
||||
repeatInfo = {}; // 重复率
|
||||
|
||||
/**
|
||||
* 输入题目
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeSubjectName = (e) => {
|
||||
let str = e.target.value.trim();
|
||||
this.setState(
|
||||
{
|
||||
subjectName: str,
|
||||
},
|
||||
() => {
|
||||
this.rankLabelBox.getThirdCategoryList();
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 一次确认录入
|
||||
*/
|
||||
onSubmit = debounce(() => {
|
||||
const { subjectName, isDisabledSubmit, isSubmit } = this.state;
|
||||
if (isDisabledSubmit || !isSubmit) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
isSubmit: false,
|
||||
});
|
||||
let params = {
|
||||
subjectName: subjectName,
|
||||
difficulty: this.rankId,
|
||||
subjectType: 2,
|
||||
subjectScore: this.scoreValue,
|
||||
subjectParse: this.subjectAnalysis,
|
||||
categoryIds: this.secondCategoryValue,
|
||||
labelIds: this.thirdCategoryValue,
|
||||
optionList: this.currentActive,
|
||||
};
|
||||
console.log('多选录入 ----', params);
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
this.repeatInfo = {};
|
||||
if (res.data && res.data.insertStatus) {
|
||||
this.setState(
|
||||
{
|
||||
isSubmit: true,
|
||||
},
|
||||
() => {
|
||||
this.successModalConfirm();
|
||||
}
|
||||
);
|
||||
} else if (!res.data.insertStatus) {
|
||||
this.repeatInfo = {
|
||||
repeatDocId: res.data.docId, // 重复题目id
|
||||
repeatRate: res.data.repeatRate, // 重复率
|
||||
repeatSubjectName: res.data.subjectName, // 重复题目
|
||||
repeatOptionList: res.data.optionList, // 重复列表项
|
||||
repeatSetterErp: res.data.subjectSetterErp, // 出题人erp
|
||||
repeatSetterName: res.data.subjectSetterName, // 出题人姓名
|
||||
};
|
||||
this.setState({
|
||||
isShowModalBox: true,
|
||||
isSubmit: true,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({
|
||||
isSubmit: true,
|
||||
});
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 校验是否支持点击按钮
|
||||
* @returns
|
||||
*/
|
||||
/**
|
||||
* 校验是否支持点击按钮
|
||||
* @returns
|
||||
*/
|
||||
checkData = () => {
|
||||
const { subjectName } = this.state;
|
||||
let list = this.currentActive.filter((item) => item.optionContent === defalutLabel);
|
||||
let isDisabledSubmit = false;
|
||||
if (
|
||||
!!!subjectName ||
|
||||
list.length > 0 ||
|
||||
!!!this.firstCategoryValue ||
|
||||
this.secondCategoryValue.length <= 0 ||
|
||||
this.thirdCategoryValue.length <= 0 ||
|
||||
!!!this.scoreValue
|
||||
) {
|
||||
isDisabledSubmit = true;
|
||||
}
|
||||
return isDisabledSubmit;
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
onCancel = () => {
|
||||
this.currentActive = []; // 选项列表
|
||||
this.scoreValue = ''; // 分数
|
||||
this.subjectAnalysis = ''; //试题解析
|
||||
this.rankId = 1;
|
||||
this.subjectAnswer = ''; // 选项内容
|
||||
this.firstCategoryValue = ''; // 一级分类的值
|
||||
this.secondCategoryValue = []; // 二级分类的值
|
||||
this.thirdCategoryValue = []; // 三级标签的值
|
||||
this.repeatInfo = {};
|
||||
this.kindEditor && this.kindEditor.onClear();
|
||||
this.rankLabelBox.initRankLabel();
|
||||
this.optionInputBox.handleClearOption();
|
||||
this.setState({
|
||||
subjectName: '',
|
||||
isShowModalBox: false,
|
||||
isSubmit: true, // 是否支持提交
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 重复率弹框-确认录入
|
||||
*/
|
||||
onSubmitRepeatModal = debounce(
|
||||
() => {
|
||||
let params = {
|
||||
docId: this.repeatInfo.repeatDocId,
|
||||
};
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addRepeatInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data) {
|
||||
this.successModalConfirm();
|
||||
} else {
|
||||
message.info('请再次确认');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
message.error('请再次确认');
|
||||
});
|
||||
},
|
||||
300,
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* 重复率弹框-取消录入
|
||||
*/
|
||||
onCancelRepeatModal = () => {
|
||||
this.repeatInfo = {};
|
||||
this.setState({
|
||||
isShowModalBox: false,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功的弹框
|
||||
*/
|
||||
successModalConfirm = () => {
|
||||
Modal.confirm({
|
||||
title: (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
color: 'rgba(60, 110, 238, 1)',
|
||||
fontSize: 16,
|
||||
}}>
|
||||
录入成功!贡献榜火力值 + 1
|
||||
</div>
|
||||
),
|
||||
closable: false,
|
||||
maskClosable: false,
|
||||
icon: ' ',
|
||||
onOk: this.onAgainSuccessModal,
|
||||
onCancel: this.onGoHomeSuccessModal,
|
||||
okText: '再录一题',
|
||||
cancelText: '去首页',
|
||||
className: 'questions-success-modal-confirm',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-再来一题
|
||||
*/
|
||||
onAgainSuccessModal = () => {
|
||||
this.onCancel();
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-去首页
|
||||
*/
|
||||
onGoHomeSuccessModal = () => {
|
||||
// this.onCancel();
|
||||
window.location.href = '/cms-supplier/question-bank';
|
||||
};
|
||||
|
||||
/**
|
||||
* 分类选择
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeRankLabel = (firstCategoryValue, secondCategoryValue, thirdCategoryValue) => {
|
||||
this.firstCategoryValue = firstCategoryValue; // 一级分类的值
|
||||
this.secondCategoryValue = secondCategoryValue; // 二级分类的值
|
||||
this.thirdCategoryValue = thirdCategoryValue; // 三级标签的值
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 职级选择
|
||||
* @param {*} list
|
||||
*/
|
||||
handleChangeRank = (list) => {
|
||||
this.rankId = list[0];
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 选项操作
|
||||
* @param {*} currentActive 选项列表
|
||||
* @param {*} scoreValue 分值
|
||||
* @param {*} subjectAnalysis 解析
|
||||
*/
|
||||
handleChangeOption = (currentActive, scoreValue, subjectAnalysis) => {
|
||||
this.currentActive = currentActive;
|
||||
this.scoreValue = scoreValue;
|
||||
this.subjectAnalysis = subjectAnalysis;
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { subjectName, isDisabledSubmit, isSubmit, isShowModalBox } = this.state;
|
||||
const { questionsType } = this.props;
|
||||
return (
|
||||
<Spin spinning={!isSubmit}>
|
||||
<Fragment>
|
||||
<div className="multiple-questions-container">
|
||||
<div className="multiple-questions-title">题目名称:</div>
|
||||
<Input
|
||||
placeholder="输入题目"
|
||||
style={{ height: 48, width: '100%' }}
|
||||
value={subjectName}
|
||||
maxLength={64}
|
||||
onChange={(e) => this.onChangeSubjectName(e)}
|
||||
/>
|
||||
</div>
|
||||
<OptionInputBox
|
||||
key="multiple-option-input"
|
||||
ref={(ref) => {
|
||||
this.optionInputBox = ref;
|
||||
}}
|
||||
isMultiple={true}
|
||||
handleChangeOption={this.handleChangeOption}
|
||||
/>
|
||||
<RankLabelBox
|
||||
ref={(ref) => {
|
||||
this.rankLabelBox = ref;
|
||||
}}
|
||||
subjectName={subjectName}
|
||||
onChangeRankLabel={this.onChangeRankLabel}
|
||||
handleChangeRank={this.handleChangeRank}
|
||||
/>
|
||||
<div className="multiple-questions-btns-container">
|
||||
<div className="multiple-questions-btn" onClick={this.onCancel}>
|
||||
清空
|
||||
</div>
|
||||
<div
|
||||
className={`multiple-questions-btn multiple-questions-submit ${isDisabledSubmit && 'multiple-questions-disabled-submit'
|
||||
}`}
|
||||
onClick={this.onSubmit}>
|
||||
提交
|
||||
</div>
|
||||
</div>
|
||||
<RepeatContentBox
|
||||
isShowModalBox={isShowModalBox}
|
||||
repeatQuestionsType={questionsType}
|
||||
repeatInfo={this.repeatInfo}
|
||||
handleSubmitRepeatModal={this.onSubmitRepeatModal}
|
||||
handleCancelRepeatModal={this.onCancelRepeatModal}
|
||||
/>
|
||||
</Fragment>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,52 @@
|
||||
.multiple-questions-container {
|
||||
width: 1000px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
padding-top: 36px;
|
||||
// label名字title
|
||||
.multiple-questions-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
color: #f5222d;
|
||||
font-size: 16px;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
}
|
||||
.multiple-questions-btns-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px auto;
|
||||
width: 952px;
|
||||
.multiple-questions-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 150px;
|
||||
height: 40px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.multiple-questions-submit {
|
||||
margin-left: 40px;
|
||||
background-color: #4390f7;
|
||||
color: #fff;
|
||||
border: 1px solid #4390f7;
|
||||
}
|
||||
.multiple-questions-disabled-submit {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
438
src/views/upload-questions/components/option-input-box/index.jsx
Normal file
438
src/views/upload-questions/components/option-input-box/index.jsx
Normal file
@@ -0,0 +1,438 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Input, message, Tooltip, Select } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { debounce } from '@utils';
|
||||
import { optionLetter } from '../../constant';
|
||||
import KindEditor from '../kind-editor';
|
||||
import './index.less';
|
||||
const { TextArea } = Input;
|
||||
const { Option } = Select;
|
||||
const defalutLabel = '请使用富文本编辑器输入选项内容';
|
||||
// 判断题
|
||||
const judgeList = [
|
||||
{
|
||||
label: '错误',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '正确',
|
||||
value: 1,
|
||||
},
|
||||
];
|
||||
const optionLetterLength = 7; // ABCD的长度
|
||||
const showDeleteLength = 3; // 展示删除icon的最短长度
|
||||
export default class OptionInputBox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
optionList: [
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 3,
|
||||
},
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 4,
|
||||
},
|
||||
], // 选项列表
|
||||
currentActiveList: [], // 当前选中的项
|
||||
scoreValue: '', // 分数
|
||||
subjectAnalysis: '', //试题解析
|
||||
};
|
||||
}
|
||||
|
||||
kindEditor = KindEditor | null;
|
||||
subjectAnswer = ''; // 选项内容
|
||||
|
||||
/**
|
||||
* 新增/删除
|
||||
* @param {*} len
|
||||
* @param {*} type add-新增 / del-删除
|
||||
* @returns
|
||||
*/
|
||||
onChangeAddOption = (len, type) => () => {
|
||||
let { optionList, currentActiveList } = this.state;
|
||||
let list = [];
|
||||
// 新增
|
||||
if (type === 'add') {
|
||||
if (len === optionLetterLength) {
|
||||
return;
|
||||
}
|
||||
optionList.push({ label: defalutLabel, value: optionLetter[len].value });
|
||||
} else {
|
||||
// 删除
|
||||
currentActiveList = [];
|
||||
optionList.splice(len, 1);
|
||||
// 重新初始化ABCD对应的id
|
||||
list = optionList.map((item, index) => {
|
||||
return {
|
||||
label: item.label,
|
||||
value: optionLetter[index].value,
|
||||
};
|
||||
});
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
optionList: type === 'add' ? optionList : list,
|
||||
currentActiveList,
|
||||
},
|
||||
() => {
|
||||
this.handleChangeOption();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 确认/取消 编辑框
|
||||
* @param {*} index
|
||||
* @param {*} type submit/cancel
|
||||
* @returns
|
||||
*/
|
||||
onChangeOptEditor = (index, type) => () => {
|
||||
let { optionList } = this.state;
|
||||
this.kindEditor && this.kindEditor.onClear();
|
||||
if (type === 'submit') {
|
||||
_.set(
|
||||
optionList,
|
||||
[index, 'label'],
|
||||
!!this.subjectAnswer ? this.subjectAnswer : defalutLabel
|
||||
);
|
||||
}
|
||||
_.set(optionList, [index, 'isShowEditor'], false);
|
||||
this.subjectAnswer = '';
|
||||
this.setState(
|
||||
{
|
||||
optionList,
|
||||
},
|
||||
() => {
|
||||
this.handleChangeOption();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 展开 编辑项
|
||||
* @param {*} index
|
||||
* @returns
|
||||
*/
|
||||
onChangeShowEditor = (index) =>
|
||||
debounce(() => {
|
||||
let { optionList } = this.state;
|
||||
if (optionList.filter((item) => item.isShowEditor).length > 0) {
|
||||
return message.info('请先确认正在编辑的选项内容');
|
||||
}
|
||||
_.set(optionList, [index, 'isShowEditor'], true);
|
||||
this.setState(
|
||||
{
|
||||
optionList,
|
||||
},
|
||||
() => {
|
||||
this.kindEditor && this.kindEditor.onCashBack();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 富文本编辑器
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeEditor = (index) => (e) => {
|
||||
this.subjectAnswer = e;
|
||||
};
|
||||
|
||||
/**
|
||||
* 正确选项
|
||||
* @param {*} value
|
||||
*/
|
||||
onChangeSelect = (value) => {
|
||||
const { isMultiple } = this.props;
|
||||
let str = value;
|
||||
if (!isMultiple) {
|
||||
// 单选,格式化成数组
|
||||
str = [value];
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
currentActiveList: str,
|
||||
},
|
||||
() => {
|
||||
this.handleChangeOption();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 本题分值
|
||||
*/
|
||||
onChangeScore = (e) => {
|
||||
this.setState(
|
||||
{
|
||||
scoreValue: e.target.value.trim(),
|
||||
},
|
||||
() => {
|
||||
this.handleChangeOption();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 试题解析
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeSubjectAnalysis = (e) => {
|
||||
this.setState(
|
||||
{
|
||||
subjectAnalysis: e.target.value.trim(),
|
||||
},
|
||||
() => {
|
||||
this.handleChangeOption();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 清空
|
||||
*/
|
||||
handleClearOption = () => {
|
||||
this.subjectAnswer = ''; // 选项内容
|
||||
this.setState({
|
||||
optionList: [
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 3,
|
||||
},
|
||||
{
|
||||
label: defalutLabel,
|
||||
value: 4,
|
||||
},
|
||||
], // 选项列表
|
||||
currentActiveList: [], // 当前选中的项
|
||||
scoreValue: '', // 分数
|
||||
subjectAnalysis: '', //试题解析
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 向父组件传值
|
||||
*/
|
||||
handleChangeOption = () => {
|
||||
let { currentActiveList, scoreValue, subjectAnalysis, optionList } = this.state;
|
||||
const { isJudge } = this.props;
|
||||
let activeList = [];
|
||||
if (!isJudge) {
|
||||
// 单选/多选
|
||||
activeList = optionList.map((item) => {
|
||||
let flag = 0;
|
||||
if (currentActiveList.includes(item.value)) {
|
||||
flag = 1;
|
||||
}
|
||||
return {
|
||||
optionType: item.value,
|
||||
optionContent: item.label,
|
||||
isCorrect: flag,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
// 判断
|
||||
activeList = currentActiveList;
|
||||
}
|
||||
console.log('向父组件传值', activeList, scoreValue, subjectAnalysis);
|
||||
// this.props.handleChangeOption(activeList, scoreValue, subjectAnalysis);
|
||||
this.props.handleChangeOption(activeList, 1, subjectAnalysis);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { subjectAnalysis } = this.state;
|
||||
const { isJudge } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
{!isJudge && this.renderOption()}
|
||||
{this.renderOptionBtn()}
|
||||
<div className="option-input-container">
|
||||
<div className="option-input-title">试题解析:</div>
|
||||
<TextArea
|
||||
placeholder="试题解析(非必填 限500字)"
|
||||
value={subjectAnalysis}
|
||||
style={{ height: 48, width: '100%' }}
|
||||
maxLength={500}
|
||||
autoSize={{ minRows: 3, maxRows: 4 }}
|
||||
onChange={(e) => this.onChangeSubjectAnalysis(e)}
|
||||
/>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 选项模块
|
||||
* @returns
|
||||
*/
|
||||
renderOption = () => {
|
||||
const { optionList } = this.state;
|
||||
let listLen = optionList.length;
|
||||
return (
|
||||
<Fragment>
|
||||
{optionList.length > 0 &&
|
||||
optionList.map((item, index) => {
|
||||
const isShowTip = item.label === defalutLabel;
|
||||
return (
|
||||
<div
|
||||
className="option-input-container"
|
||||
style={{ flexDirection: 'column' }}
|
||||
key={`option_input_${index}`}>
|
||||
<div className="option-input-main">
|
||||
<div className="option-input-title-option">
|
||||
{optionLetter[item.value - 1].label}
|
||||
</div>
|
||||
<div
|
||||
className="option-input-item"
|
||||
key={`option_id_${item.value}`}>
|
||||
<Tooltip
|
||||
title="点击可输入该选项内容"
|
||||
onClick={this.onChangeShowEditor(index)}>
|
||||
<div
|
||||
className="option-input-item-header"
|
||||
style={
|
||||
isShowTip
|
||||
? {
|
||||
color: 'rgba(51,51,51,0.3)',
|
||||
}
|
||||
: {
|
||||
color: 'rgba(51,51,51,0.9)',
|
||||
}
|
||||
}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.label,
|
||||
}}></div>
|
||||
</Tooltip>
|
||||
<div className="option-input-item-delete">
|
||||
{listLen > showDeleteLength && (
|
||||
<Tooltip
|
||||
title="删除选项"
|
||||
onClick={this.onChangeAddOption(index, 'del')}>
|
||||
<img
|
||||
className="option-input-item-delete-icon"
|
||||
src="https://img14.360buyimg.com/imagetools/jfs/t1/212738/17/4123/399/618dd36bEd53475f5/38e899e92bbd5d5e.png"
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{item.isShowEditor && (
|
||||
<div
|
||||
key={`option_editor_${index}`}
|
||||
className="option-input-main"
|
||||
style={{ marginTop: 19 }}>
|
||||
<div className="option-input-editor">
|
||||
<KindEditor
|
||||
ref={(ref) => {
|
||||
this.kindEditor = ref;
|
||||
}}
|
||||
bodyHeight={145}
|
||||
borderRadius={12}
|
||||
onChange={this.onChangeEditor(index)}
|
||||
cashBackText={isShowTip ? '' : item.label}
|
||||
/>
|
||||
<div className="option-input-editor-btns">
|
||||
<Tooltip title="取消后内容将不会更新到选项框内">
|
||||
<div
|
||||
className="option-input-editor-btn"
|
||||
onClick={this.onChangeOptEditor(
|
||||
index,
|
||||
'cancel'
|
||||
)}>
|
||||
取消
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title="确定后内容将会更新到选项框内">
|
||||
<div
|
||||
className="option-input-editor-btn option-input-editor-submit-btn"
|
||||
onClick={this.onChangeOptEditor(
|
||||
index,
|
||||
'submit'
|
||||
)}>
|
||||
确定
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 选项模块-操作按钮
|
||||
* @returns
|
||||
*/
|
||||
renderOptionBtn = () => {
|
||||
const { optionList, scoreValue, currentActiveList } = this.state;
|
||||
const { isMultiple, isJudge } = this.props;
|
||||
let listLen = optionList.length;
|
||||
return (
|
||||
<div className="option-input-container">
|
||||
<div className="option-input-title option-input-title-required">题目操作:</div>
|
||||
<div style={{ display: 'flex', width: '100%' }}>
|
||||
{!isJudge && (
|
||||
<div
|
||||
className="option-input-option-btn"
|
||||
onClick={this.onChangeAddOption(listLen, 'add')}>
|
||||
添加选项
|
||||
</div>
|
||||
)}
|
||||
<div className="option-input-option-btn option-input-option-input">
|
||||
正确选项
|
||||
<Select
|
||||
mode={isMultiple && 'multiple'}
|
||||
defaultActiveFirstOption={false}
|
||||
value={currentActiveList}
|
||||
placeholder="请选择"
|
||||
style={{ minWidth: isMultiple ? '64px' : '68px', marginLeft: 4 }}
|
||||
onChange={this.onChangeSelect}>
|
||||
{isJudge
|
||||
? judgeList.map((item, index) => {
|
||||
return (
|
||||
<Option
|
||||
key={`option_select_${item.value}`}
|
||||
value={item.value}>
|
||||
{item.label}
|
||||
</Option>
|
||||
);
|
||||
})
|
||||
: optionList.map((item, index) => {
|
||||
return (
|
||||
<Option
|
||||
key={`option_select_${item.value}`}
|
||||
value={item.value}>
|
||||
{optionLetter[index].label}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
.option-input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
padding-top: 19px;
|
||||
// 选项模块
|
||||
.option-input-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
// 选项label-abcd...
|
||||
.option-input-title-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
.option-input-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
transition: all 0.5s;
|
||||
cursor: pointer;
|
||||
.option-input-item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 4px 10px;
|
||||
width: 100%;
|
||||
min-height: 48px;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 7px;
|
||||
}
|
||||
.option-input-item-delete {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 19px;
|
||||
width: 19px;
|
||||
.option-input-item-delete-icon {
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 编辑器
|
||||
.option-input-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 38px;
|
||||
margin-left: 124px;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
transition: all 0.5s;
|
||||
.option-input-editor-btns {
|
||||
display: flex;
|
||||
margin-top: 19px;
|
||||
.option-input-editor-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 115px;
|
||||
height: 43px;
|
||||
font-size: 14px;
|
||||
color: rgba(24, 24, 29, 1);
|
||||
cursor: pointer;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
border: 1px solid rgba(208, 212, 222, 1);
|
||||
border-radius: 22px;
|
||||
}
|
||||
.option-input-editor-submit-btn {
|
||||
margin-left: 19px;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-weight: 500;
|
||||
background: rgba(60, 110, 238, 1);
|
||||
border: 2px solid rgba(60, 110, 238, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 必填项
|
||||
.option-input-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
// 非必填项
|
||||
.option-input-title-required {
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
color: #f5222d;
|
||||
font-size: 16px;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
// 选项模块-操作按钮
|
||||
.option-input-option-btn {
|
||||
margin-right: 8px;
|
||||
padding: 0 32px;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
line-height: 48px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: rgba(60, 110, 238, 1);
|
||||
cursor: pointer;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
border: 1px solid rgba(240, 240, 240, 1);
|
||||
border-radius: 7px;
|
||||
}
|
||||
// 选项模块-操作按钮-输入框
|
||||
.option-input-option-input {
|
||||
padding-left: 14px;
|
||||
padding-right: 4px;
|
||||
color: #333;
|
||||
.ant-select,
|
||||
.ant-select-open,
|
||||
.ant-select-focused,
|
||||
.ant-select-enabled {
|
||||
box-shadow: none !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
}
|
||||
// 正确选项:去除两边外边距
|
||||
.ant-select-selection--single .ant-select-selection__rendered {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
// 正确选项:去除边框
|
||||
.ant-select-selection {
|
||||
border: none;
|
||||
}
|
||||
// 正确选项:值的位置优化
|
||||
.ant-select-selection-selected-value {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.ant-input {
|
||||
padding: 4px;
|
||||
}
|
||||
// 正确选项:距离右边的位置
|
||||
.ant-select-selection__rendered {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
350
src/views/upload-questions/components/rank-label-box/index.jsx
Normal file
350
src/views/upload-questions/components/rank-label-box/index.jsx
Normal file
@@ -0,0 +1,350 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import req from '@utils/request';
|
||||
import TagsEditor from '@components/tags-editor';
|
||||
import { apiName, ModuleType, starList } from '../../constant';
|
||||
import './index.less';
|
||||
export default class RankLabelBox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
firstCategoryList: [],
|
||||
secondCategoryList: [],
|
||||
thirdCategoryList: [],
|
||||
rankList: starList,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.geFirstCategoryList();
|
||||
}
|
||||
|
||||
firstValue = ''; // 一级分类id
|
||||
|
||||
firstCategoryValue = ''; // 一级分类的值
|
||||
secondCategoryValue = []; // 二级分类的值
|
||||
thirdCategoryValue = []; // 三级标签的值
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
initRankLabel = () => {
|
||||
this.firstCategoryValue = ''; // 一级分类的值
|
||||
this.secondCategoryValue = []; // 二级分类的值
|
||||
this.thirdCategoryValue = []; // 三级标签的值
|
||||
this.firstValue = '';
|
||||
this.setState(
|
||||
{
|
||||
firstCategoryList: [],
|
||||
secondCategoryList: [],
|
||||
thirdCategoryList: [],
|
||||
rankList: starList,
|
||||
},
|
||||
() => {
|
||||
this.geFirstCategoryList();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获得一级分类数据
|
||||
*/
|
||||
geFirstCategoryList() {
|
||||
const params = { categoryType: 1 };
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.getInterviewCategory,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
let list = res.data.map((item, index) => {
|
||||
return {
|
||||
...item,
|
||||
active: index == 0 ? true : false,
|
||||
};
|
||||
});
|
||||
this.setState(
|
||||
{
|
||||
firstCategoryList: list,
|
||||
secondCategoryList: [],
|
||||
thirdCategoryList: [],
|
||||
},
|
||||
() => {
|
||||
this.firstValue = list[0].categoryId;
|
||||
this.getSecondCategoryList(this.firstValue);
|
||||
this.getThirdCategoryList(this.firstValue);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.setState({
|
||||
firstCategoryList: [],
|
||||
secondCategoryList: [],
|
||||
thirdCategoryList: [],
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得二级分类数据
|
||||
* @param {*} id 一级分类id
|
||||
*/
|
||||
getSecondCategoryList(id) {
|
||||
const params = { parentId: id, categoryType: 2 };
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.getInterviewCategory,
|
||||
})
|
||||
.then((res) => {
|
||||
this.firstCategoryValue = id;
|
||||
this.secondCategoryValue = [];
|
||||
this.thirdCategoryValue = [];
|
||||
if (res.data && res.data.length > 0) {
|
||||
this.setState({
|
||||
secondCategoryList: res.data,
|
||||
});
|
||||
} else {
|
||||
// 若需要新增时,则需要将数组第一个item,重置如下
|
||||
this.setState({
|
||||
secondCategoryList: [{ categoryName: '空', categoryId: -9999 }],
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得三级分类数据
|
||||
* @param {*} id 二级分类id
|
||||
*/
|
||||
getThirdCategoryList(id) {
|
||||
const { subjectName } = this.props;
|
||||
const params = {
|
||||
primaryCategoryId: id || this.firstValue,
|
||||
subjectName: subjectName,
|
||||
};
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.getRecommendLabel,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
let list = res.data.map((item) => {
|
||||
return {
|
||||
categoryName: item.labelName,
|
||||
categoryId: item.labelId,
|
||||
active: item?.isRecommend === 1 ? true : false,
|
||||
};
|
||||
});
|
||||
this.thirdCategoryValue = this.formatList(list);
|
||||
if (this.thirdCategoryValue.length >= 0) {
|
||||
this.onChangeRankLabel();
|
||||
}
|
||||
this.setState({
|
||||
thirdCategoryList: list,
|
||||
});
|
||||
} else {
|
||||
// 若需要新增时,则需要将数组第一个item,重置如下
|
||||
this.setState({
|
||||
thirdCategoryList: [{ categoryName: '空', categoryId: -9999 }],
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择职级-单选
|
||||
* @param {*} handleStatusList
|
||||
* @param {*} selectList
|
||||
*/
|
||||
onHandleChangeRank = (handleStatusList, selectList) => {
|
||||
this.setState({ rankList: handleStatusList });
|
||||
this.props.handleChangeRank(selectList);
|
||||
};
|
||||
|
||||
/**
|
||||
* 选择一级分类-单选
|
||||
* @param {*} handleStatusList 带有是否选中状态的原数组
|
||||
* @param {*} selectList 选中id的数组
|
||||
*/
|
||||
onChangeFirst = (handleStatusList, selectList) => {
|
||||
this.setState({ firstCategoryList: handleStatusList });
|
||||
this.firstValue = selectList[0];
|
||||
// 获得二级分类
|
||||
this.getSecondCategoryList(this.firstValue);
|
||||
// 获得三级标签
|
||||
this.getThirdCategoryList(this.firstValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* 选择二级分类
|
||||
* @param {*} handleStatusList 带有是否选中状态的原数组
|
||||
* @param {*} selectList 选中id的数组
|
||||
*/
|
||||
onChangeSecondTags = (handleStatusList, selectList) => {
|
||||
this.secondCategoryValue = selectList;
|
||||
this.setState({ secondCategoryList: handleStatusList });
|
||||
this.onChangeRankLabel();
|
||||
};
|
||||
|
||||
/**
|
||||
* 选择三级标签
|
||||
* @param {*} handleStatusList 带有是否选中状态的原数组
|
||||
* @param {*} selectList 选中id的数组
|
||||
*/
|
||||
onChangeThirdTags = (handleStatusList, selectList) => {
|
||||
this.thirdCategoryValue = selectList;
|
||||
this.setState({ thirdCategoryList: handleStatusList });
|
||||
this.onChangeRankLabel();
|
||||
};
|
||||
|
||||
/**
|
||||
* 格式化数据-获得选中项id列表
|
||||
* @param {*} list
|
||||
* @returns
|
||||
*/
|
||||
formatList = (list) => {
|
||||
let labelList = [];
|
||||
list.forEach((item) => {
|
||||
if (item.active) {
|
||||
labelList.push(item.categoryId);
|
||||
}
|
||||
});
|
||||
return labelList;
|
||||
};
|
||||
|
||||
/**
|
||||
* 向父组件传递
|
||||
*/
|
||||
onChangeRankLabel = () => {
|
||||
console.log(
|
||||
'问答题 -------',
|
||||
this.firstCategoryValue,
|
||||
this.secondCategoryValue,
|
||||
this.thirdCategoryValue
|
||||
);
|
||||
this.props.onChangeRankLabel(
|
||||
this.firstCategoryValue,
|
||||
this.secondCategoryValue,
|
||||
this.thirdCategoryValue
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { firstCategoryList, secondCategoryList, thirdCategoryList, rankList } = this.state;
|
||||
return (
|
||||
<Fragment>
|
||||
{this.rendeRrankModule(rankList)}
|
||||
{this.renderFirstModule(firstCategoryList)}
|
||||
{secondCategoryList?.length > 0 && (
|
||||
<Fragment>
|
||||
{this.renderSecondModule(secondCategoryList)}
|
||||
{thirdCategoryList?.length > 0 && this.renderThirdModule(thirdCategoryList)}
|
||||
</Fragment>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 职级选择
|
||||
* @param {*} rankList
|
||||
* @returns
|
||||
*/
|
||||
rendeRrankModule = (rankList) => {
|
||||
return (
|
||||
<div className="upload-single-container">
|
||||
<div className="upload-single-title">职级选择:</div>
|
||||
<div className="upload-single-main">
|
||||
<TagsEditor
|
||||
categoryList={rankList}
|
||||
isSingleChoice={true}
|
||||
onChangeLabel={this.onHandleChangeRank}
|
||||
isDisabledReverseSelection={true}
|
||||
/>
|
||||
<span style={{ marginLeft: '8px', color: 'red' }}>
|
||||
注:所选职级应为熟练掌握该题的最低职级
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 一级分类选择
|
||||
* @param {*} firstCategoryList
|
||||
* @returns
|
||||
*/
|
||||
renderFirstModule = (firstCategoryList) => {
|
||||
return (
|
||||
<Fragment>
|
||||
{firstCategoryList?.length > 0 && (
|
||||
<div className="upload-single-container">
|
||||
<div className="upload-single-title">一级分类:</div>
|
||||
<div className="upload-single-main">
|
||||
<TagsEditor
|
||||
categoryList={firstCategoryList}
|
||||
isSingleChoice={true}
|
||||
onChangeLabel={this.onChangeFirst}
|
||||
isDisabledReverseSelection={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 二级分类选择
|
||||
* @param {*} secondCategoryList
|
||||
* @returns
|
||||
*/
|
||||
renderSecondModule = (secondCategoryList) => {
|
||||
return (
|
||||
<div className="upload-single-container">
|
||||
<div className="upload-single-title">二级分类:</div>
|
||||
<div className="upload-single-main">
|
||||
<TagsEditor
|
||||
moduleType={ModuleType.second}
|
||||
categoryList={secondCategoryList}
|
||||
isSingleChoice={false}
|
||||
onChangeLabel={this.onChangeSecondTags}
|
||||
// parentCategoryValue={[this.firstCategoryValue]}
|
||||
// isAddTag={true}
|
||||
// isDeleteTag={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 三级标签选择
|
||||
* @param {*} thirdCategoryList
|
||||
* @returns
|
||||
*/
|
||||
renderThirdModule = (thirdCategoryList) => {
|
||||
return (
|
||||
<div className="upload-single-container">
|
||||
<div className="upload-single-title">三级标签:</div>
|
||||
<div className="upload-single-main">
|
||||
<TagsEditor
|
||||
moduleType={ModuleType.third}
|
||||
categoryList={thirdCategoryList}
|
||||
isSingleChoice={false}
|
||||
onChangeLabel={this.onChangeThirdTags}
|
||||
// parentCategoryValue={[this.firstCategoryValue]}
|
||||
// isAddTag={true}
|
||||
// isDeleteTag={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@@ -0,0 +1,44 @@
|
||||
.upload-single-container {
|
||||
width: 1000px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 0 24px;
|
||||
padding-top: 36px;
|
||||
.upload-single-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
color: #f5222d;
|
||||
font-size: 16px;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
.upload-single-main {
|
||||
width: 100%;
|
||||
// 题目输入框
|
||||
.upload-single-input {
|
||||
height: 40px;
|
||||
}
|
||||
// 一级大类
|
||||
.ant-radio-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
height: 40px;
|
||||
}
|
||||
.tag-active {
|
||||
@include box-backgroundColor(0.1);
|
||||
@include box-border();
|
||||
@include font-color();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,234 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { Modal, Tooltip } from 'antd';
|
||||
import { letterList, judgeList } from '../../constant';
|
||||
import './index.less';
|
||||
export default function RepeatContentBox(props) {
|
||||
const { isShowModalBox, repeatInfo, repeatQuestionsType } = props;
|
||||
// const { isShowModalBox, repeatQuestionsType } = props;
|
||||
// const repeatInfo = {
|
||||
// repeatSubjectName:
|
||||
// 'Chrome如Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?何支持小于12px的字?',
|
||||
// repeatSubjectAnswe:
|
||||
// 'Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?',
|
||||
// repeatSetterErp: 'suchunping3',
|
||||
// repeatSetterName: '苏春萍',
|
||||
// };
|
||||
|
||||
// const repeatInfo = {
|
||||
// repeatSubjectName:
|
||||
// 'Chrome如Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?Chrome如何支持小于12px的字?何支持小于12px的字?',
|
||||
// repeatOptionList: [
|
||||
// {
|
||||
// isCorrect: '',
|
||||
// optionContent: 'Chrome如何支持小于12px的字?Chrome如何支持小于12px的',
|
||||
// optionType: 1,
|
||||
// },
|
||||
// {
|
||||
// isCorrect: '',
|
||||
// optionContent: 'Chrome如何支持小于12px的字?Chrome如何支持小于12px的',
|
||||
// optionType: 2,
|
||||
// },
|
||||
// {
|
||||
// isCorrect: 1,
|
||||
// optionContent: 'Chrome如何支持小于12px的字?Chrome如何支持小于12px的',
|
||||
// optionType: 3,
|
||||
// },
|
||||
// ],
|
||||
// repeatSetterErp: 'suchunping3',
|
||||
// repeatSetterName: '苏春萍',
|
||||
// };
|
||||
/**
|
||||
* 确认录入
|
||||
*/
|
||||
const onSubmitRepeatModal = (e) => {
|
||||
props.handleSubmitRepeatModal && props.handleSubmitRepeatModal();
|
||||
};
|
||||
/**
|
||||
* 取消录入
|
||||
*/
|
||||
const onCancelRepeatModal = () => {
|
||||
props.handleCancelRepeatModal && props.handleCancelRepeatModal();
|
||||
};
|
||||
|
||||
const renderRepeat = (type, repeatInfo) => {
|
||||
switch (type) {
|
||||
case 1:
|
||||
return renderBriefQuestions(repeatInfo);
|
||||
case 2:
|
||||
case 3:
|
||||
return renderSelectQuestions(type, repeatInfo);
|
||||
case 4:
|
||||
return renderJudgeQuestions(repeatInfo);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 展示重复内容-问答型
|
||||
* @returns
|
||||
*/
|
||||
const renderBriefQuestions = (repeatInfo) => {
|
||||
return (
|
||||
<div className="repeat-content-box">
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">问答题</div>
|
||||
<div className="repeat-subject-text">{repeatInfo.repeatSubjectName}</div>
|
||||
</div>
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">参考答案</div>
|
||||
<div
|
||||
className="repeat-subject-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: repeatInfo.repeatSubjectAnswe,
|
||||
}}></div>
|
||||
</div>
|
||||
<div className="repeat-subject-box repeat-subject-info-box">
|
||||
<div className="repeat-subject-title">来自</div>
|
||||
<Tooltip
|
||||
title={repeatInfo.repeatSetterErp}
|
||||
placement="right"
|
||||
style={{ fontSize: 14 }}>
|
||||
{repeatInfo.repeatSetterName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 展示重复内容-单选/多选
|
||||
* @returns
|
||||
*/
|
||||
const renderSelectQuestions = (type, repeatInfo) => {
|
||||
// 过滤获得正确选项
|
||||
let repeatRightKey = repeatInfo?.repeatOptionList?.filter((item) => item.isCorrect === 1);
|
||||
return (
|
||||
<div className="repeat-content-box">
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">{type === 2 ? '单选题' : '多选题'}</div>
|
||||
<div className="repeat-subject-text">{repeatInfo.repeatSubjectName}</div>
|
||||
</div>
|
||||
{repeatInfo?.repeatOptionList?.length > 0 && (
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">选项内容</div>
|
||||
<div className="repeat-subject-list">
|
||||
{repeatInfo.repeatOptionList.map((item, index) => {
|
||||
return (
|
||||
<div
|
||||
className="repeat-subject-item"
|
||||
key={`repeat_option_${index}`}>
|
||||
{/* <div className="repeat-subject-label">
|
||||
{letterList[item.optionType]}
|
||||
</div> */}
|
||||
<div
|
||||
className="repeat-subject-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.optionContent,
|
||||
}}></div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{repeatRightKey?.length > 0 && (
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">答案</div>
|
||||
<div className="repeat-subject-list">
|
||||
{repeatRightKey.map((item, index) => {
|
||||
return (
|
||||
<span key={`repeat_answe_${index}`}>
|
||||
{letterList[item.optionType]}{' '}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!!repeatInfo.repeatSubjectAnswe && (
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">题目解析</div>
|
||||
<div
|
||||
className="repeat-subject-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: repeatInfo.repeatSubjectAnswe,
|
||||
}}></div>
|
||||
</div>
|
||||
)}
|
||||
<div className="repeat-subject-box repeat-subject-info-box">
|
||||
<div className="repeat-subject-title">来自</div>
|
||||
<Tooltip
|
||||
title={repeatInfo.repeatSetterErp}
|
||||
placement="right"
|
||||
style={{ fontSize: 14 }}>
|
||||
{repeatInfo.repeatSetterName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 展示重复内容-判断
|
||||
* @returns
|
||||
*/
|
||||
const renderJudgeQuestions = (repeatInfo) => {
|
||||
return (
|
||||
<div className="repeat-content-box">
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">判断题</div>
|
||||
<div className="repeat-subject-text">{repeatInfo.repeatSubjectName}</div>
|
||||
</div>
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">答案</div>
|
||||
<div className="repeat-subject-list">
|
||||
{judgeList[repeatInfo.repeatIsCorrect]}
|
||||
</div>
|
||||
</div>
|
||||
{!!repeatInfo.repeatSubjectAnswe && (
|
||||
<div className="repeat-subject-box">
|
||||
<div className="repeat-subject-title">题目解析</div>
|
||||
<div
|
||||
className="repeat-subject-text"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: repeatInfo.repeatSubjectAnswe,
|
||||
}}></div>
|
||||
</div>
|
||||
)}
|
||||
<div className="repeat-subject-box repeat-subject-info-box">
|
||||
<div className="repeat-subject-title">来自</div>
|
||||
<Tooltip
|
||||
title={repeatInfo.repeatSetterErp}
|
||||
placement="right"
|
||||
style={{ fontSize: 14 }}>
|
||||
{repeatInfo.repeatSetterName}
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className="repeat-content-repeat-box"
|
||||
visible={isShowModalBox}
|
||||
title={
|
||||
<Fragment>
|
||||
<span
|
||||
style={{
|
||||
color: 'rgba(60, 110, 238, 0.8)',
|
||||
fontSize: 50,
|
||||
marginRight: 10,
|
||||
}}>
|
||||
{repeatInfo.repeatRate || '10%'}
|
||||
</span>
|
||||
重复率
|
||||
</Fragment>
|
||||
}
|
||||
onOk={onSubmitRepeatModal}
|
||||
onCancel={onCancelRepeatModal}
|
||||
okText="确认录入"
|
||||
cancelText="取消录入">
|
||||
{renderRepeat(repeatQuestionsType, repeatInfo)}
|
||||
</Modal>
|
||||
);
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
.repeat-content-box {
|
||||
font-size: 14px;
|
||||
.repeat-subject-box {
|
||||
padding-bottom: 14px;
|
||||
margin-bottom: 14px;
|
||||
line-height: 22px;
|
||||
border-bottom: 1px dotted #e4e4e4;
|
||||
.repeat-subject-title {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #3c6eee;
|
||||
line-height: 22px;
|
||||
}
|
||||
.repeat-subject-text {
|
||||
flex: 1;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgba(51, 51, 51, 0.8);
|
||||
}
|
||||
.repeat-subject-list {
|
||||
.repeat-subject-item {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
padding: 12px 10px 13px;
|
||||
background: #fff;
|
||||
border: 1px solid #d4d4d4;
|
||||
border-radius: 4px;
|
||||
// .repeat-subject-label {
|
||||
// margin-right: 4px;
|
||||
// width: 20px;
|
||||
// height: 20px;
|
||||
// line-height: 20px;
|
||||
// text-align: center;
|
||||
// color: rgba(51, 51, 51, 0.8);
|
||||
// border-radius: 50%;
|
||||
// @include box-backgroundColor(0.3);
|
||||
// }
|
||||
.repeat-subject-text {
|
||||
line-height: 22px;
|
||||
font-size: 14px;
|
||||
color: rgba(51, 51, 51, 0.8);
|
||||
}
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.repeat-subject-info-box {
|
||||
display: flex;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.repeat-content-repeat-box {
|
||||
// 弹框宽度
|
||||
.ant-modal-content {
|
||||
width: 630px;
|
||||
// 提示框-头部title位置
|
||||
.ant-modal-header {
|
||||
border-bottom: none;
|
||||
.ant-modal-title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: baseline;
|
||||
margin-top: 10px;
|
||||
font-size: 13px;
|
||||
line-height: 40px;
|
||||
color: rgba(51, 51, 51, 0.8);
|
||||
}
|
||||
}
|
||||
// 提示框-两个按钮
|
||||
.ant-modal-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 14px 0;
|
||||
border-top: none;
|
||||
.ant-btn {
|
||||
border-radius: 18px;
|
||||
}
|
||||
.ant-btn-primary {
|
||||
background: rgba(60, 110, 238, 1);
|
||||
margin-left: 60px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
338
src/views/upload-questions/components/single-questions/index.jsx
Normal file
338
src/views/upload-questions/components/single-questions/index.jsx
Normal file
@@ -0,0 +1,338 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Input, Modal, message, Spin } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import req from '@utils/request';
|
||||
import { debounce } from '@utils';
|
||||
import KindEditor from '../kind-editor';
|
||||
import RankLabelBox from '../rank-label-box';
|
||||
import OptionInputBox from '../option-input-box';
|
||||
import RepeatContentBox from '../repeat-content-box';
|
||||
import { apiName } from '../../constant';
|
||||
import './index.less';
|
||||
const defalutLabel = '请使用富文本编辑器输入选项内容';
|
||||
export default class SingleQuestions extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
subjectName: '', // 题目
|
||||
isDisabledSubmit: true, //是否禁止输入
|
||||
isShowModalBox: false, // 是否展示重复率弹框
|
||||
isSubmit: true, // 是否支持提交
|
||||
};
|
||||
}
|
||||
kindEditor = KindEditor | null;
|
||||
rankLabelBox = RankLabelBox | null;
|
||||
optionInputBox = OptionInputBox | null;
|
||||
|
||||
currentActive = []; // 选项列表
|
||||
scoreValue = ''; // 分数
|
||||
subjectAnalysis = ''; //试题解析
|
||||
rankId = 1; //职级
|
||||
subjectAnswer = ''; // 选项内容
|
||||
|
||||
firstCategoryValue = ''; // 一级分类的值
|
||||
secondCategoryValue = []; // 二级分类的值
|
||||
thirdCategoryValue = []; // 三级标签的值
|
||||
repeatInfo = {}; // 重复率
|
||||
|
||||
/**
|
||||
* 输入题目
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeSubjectName = (e) => {
|
||||
let str = e.target.value.trim();
|
||||
this.setState(
|
||||
{
|
||||
subjectName: str,
|
||||
},
|
||||
() => {
|
||||
this.rankLabelBox.getThirdCategoryList();
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 一次确认录入
|
||||
*/
|
||||
onSubmit = debounce(() => {
|
||||
const { subjectName, isDisabledSubmit, isSubmit } = this.state;
|
||||
if (isDisabledSubmit || !isSubmit) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
isSubmit: false,
|
||||
});
|
||||
let params = {
|
||||
subjectName: subjectName,
|
||||
difficulty: this.rankId,
|
||||
subjectType: 1,
|
||||
subjectScore: this.scoreValue,
|
||||
subjectParse: this.subjectAnalysis,
|
||||
categoryIds: this.secondCategoryValue,
|
||||
labelIds: this.thirdCategoryValue,
|
||||
optionList: this.currentActive,
|
||||
};
|
||||
console.log('单选题录入 ----', params);
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
this.repeatInfo = {};
|
||||
if (res.data && res.data.insertStatus) {
|
||||
this.setState(
|
||||
{
|
||||
isSubmit: true,
|
||||
},
|
||||
() => {
|
||||
this.successModalConfirm();
|
||||
}
|
||||
);
|
||||
} else if (!res.data.insertStatus) {
|
||||
this.repeatInfo = {
|
||||
repeatDocId: res.data.docId, // 重复题目id
|
||||
repeatRate: res.data.repeatRate, // 重复率
|
||||
repeatSubjectName: res.data.subjectName, // 重复题目
|
||||
repeatOptionList: res.data.optionList, // 重复列表项
|
||||
repeatSetterErp: res.data.subjectSetterErp, // 出题人erp
|
||||
repeatSetterName: res.data.subjectSetterName, // 出题人姓名
|
||||
};
|
||||
this.setState({
|
||||
isShowModalBox: true,
|
||||
isSubmit: true,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setState({
|
||||
isSubmit: true,
|
||||
});
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 校验是否支持点击按钮
|
||||
* @returns
|
||||
*/
|
||||
checkData = () => {
|
||||
const { subjectName } = this.state;
|
||||
let list = this.currentActive.filter((item) => item.optionContent === defalutLabel);
|
||||
let isDisabledSubmit = false;
|
||||
if (
|
||||
!!!subjectName ||
|
||||
list.length > 0 ||
|
||||
!!!this.firstCategoryValue ||
|
||||
this.secondCategoryValue.length <= 0 ||
|
||||
this.thirdCategoryValue.length <= 0 ||
|
||||
!!!this.scoreValue
|
||||
) {
|
||||
isDisabledSubmit = true;
|
||||
}
|
||||
return isDisabledSubmit;
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消
|
||||
*/
|
||||
onCancel = () => {
|
||||
this.currentActive = []; // 选项列表
|
||||
this.scoreValue = ''; // 分数
|
||||
this.subjectAnalysis = ''; //试题解析
|
||||
this.rankId = 1;
|
||||
this.subjectAnswer = ''; // 选项内容
|
||||
this.firstCategoryValue = ''; // 一级分类的值
|
||||
this.secondCategoryValue = []; // 二级分类的值
|
||||
this.thirdCategoryValue = []; // 三级标签的值
|
||||
this.kindEditor && this.kindEditor.onClear();
|
||||
this.rankLabelBox.initRankLabel();
|
||||
this.optionInputBox.handleClearOption();
|
||||
this.repeatInfo = {};
|
||||
this.setState({
|
||||
subjectName: '',
|
||||
isShowModalBox: false,
|
||||
isSubmit: true, // 是否支持提交
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 重复率弹框-确认录入
|
||||
*/
|
||||
onSubmitRepeatModal = debounce(
|
||||
() => {
|
||||
let params = {
|
||||
docId: this.repeatInfo.repeatDocId,
|
||||
};
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: apiName.addRepeatInterviewSubject,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data) {
|
||||
this.successModalConfirm();
|
||||
} else {
|
||||
message.info('请再次确认');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
message.error('请再次确认');
|
||||
});
|
||||
},
|
||||
300,
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* 重复率弹框-取消录入
|
||||
*/
|
||||
onCancelRepeatModal = () => {
|
||||
this.repeatInfo = {};
|
||||
this.setState({
|
||||
isShowModalBox: false,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功的弹框
|
||||
*/
|
||||
successModalConfirm = () => {
|
||||
Modal.confirm({
|
||||
title: (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
color: 'rgba(60, 110, 238, 1)',
|
||||
fontSize: 16,
|
||||
}}>
|
||||
录入成功!贡献榜火力值 + 1
|
||||
</div>
|
||||
),
|
||||
closable: false,
|
||||
maskClosable: false,
|
||||
icon: ' ',
|
||||
onOk: this.onAgainSuccessModal,
|
||||
onCancel: this.onGoHomeSuccessModal,
|
||||
okText: '再录一题',
|
||||
cancelText: '去首页',
|
||||
className: 'questions-success-modal-confirm',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-再来一题
|
||||
*/
|
||||
onAgainSuccessModal = () => {
|
||||
this.onCancel();
|
||||
};
|
||||
|
||||
/**
|
||||
* 录入成功弹框-去首页
|
||||
*/
|
||||
onGoHomeSuccessModal = () => {
|
||||
window.location.href = '/cms-supplier/question-bank';
|
||||
};
|
||||
|
||||
/**
|
||||
* 分类选择
|
||||
* @param {*} e
|
||||
*/
|
||||
onChangeRankLabel = (firstCategoryValue, secondCategoryValue, thirdCategoryValue) => {
|
||||
this.firstCategoryValue = firstCategoryValue; // 一级分类的值
|
||||
this.secondCategoryValue = secondCategoryValue; // 二级分类的值
|
||||
this.thirdCategoryValue = thirdCategoryValue; // 三级标签的值
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 职级选择
|
||||
* @param {*} list
|
||||
*/
|
||||
handleChangeRank = (list) => {
|
||||
this.rankId = list[0];
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 选项操作
|
||||
* @param {*} currentActive 选项列表
|
||||
* @param {*} scoreValue 分值
|
||||
* @param {*} subjectAnalysis 解析
|
||||
*/
|
||||
handleChangeOption = (currentActive, scoreValue, subjectAnalysis) => {
|
||||
this.currentActive = currentActive;
|
||||
this.scoreValue = scoreValue;
|
||||
this.subjectAnalysis = subjectAnalysis;
|
||||
let isDisabledSubmit = this.checkData();
|
||||
this.setState({
|
||||
isDisabledSubmit,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { subjectName, isDisabledSubmit, isSubmit, isShowModalBox } = this.state;
|
||||
const { questionsType } = this.props;
|
||||
return (
|
||||
<Spin spinning={!isSubmit}>
|
||||
<Fragment>
|
||||
<div className="single-questions-container">
|
||||
<div className="single-questions-title">题目名称:</div>
|
||||
<Input
|
||||
placeholder="输入题目"
|
||||
style={{ height: 48, width: '100%' }}
|
||||
value={subjectName}
|
||||
maxLength={64}
|
||||
onChange={(e) => this.onChangeSubjectName(e)}
|
||||
/>
|
||||
</div>
|
||||
<OptionInputBox
|
||||
key="single-option-input"
|
||||
ref={(ref) => {
|
||||
this.optionInputBox = ref;
|
||||
}}
|
||||
handleChangeOption={this.handleChangeOption}
|
||||
/>
|
||||
<RankLabelBox
|
||||
ref={(ref) => {
|
||||
this.rankLabelBox = ref;
|
||||
}}
|
||||
subjectName={subjectName}
|
||||
onChangeRankLabel={this.onChangeRankLabel}
|
||||
handleChangeRank={this.handleChangeRank}
|
||||
/>
|
||||
<div className="single-questions-btns-container">
|
||||
<div className="single-questions-btn" onClick={this.onCancel}>
|
||||
清空
|
||||
</div>
|
||||
<div
|
||||
className={`single-questions-btn single-questions-submit ${isDisabledSubmit && 'single-questions-disabled-submit'
|
||||
}`}
|
||||
onClick={this.onSubmit}>
|
||||
提交
|
||||
</div>
|
||||
</div>
|
||||
<RepeatContentBox
|
||||
isShowModalBox={isShowModalBox}
|
||||
repeatQuestionsType={questionsType}
|
||||
repeatInfo={this.repeatInfo}
|
||||
handleSubmitRepeatModal={this.onSubmitRepeatModal}
|
||||
handleCancelRepeatModal={this.onCancelRepeatModal}
|
||||
/>
|
||||
</Fragment>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,53 @@
|
||||
.single-questions-container {
|
||||
width: 1000px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
padding-top: 36px;
|
||||
// label名字title
|
||||
.single-questions-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 140px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
color: #f5222d;
|
||||
font-size: 16px;
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.single-questions-btns-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px auto;
|
||||
width: 952px;
|
||||
.single-questions-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 150px;
|
||||
height: 40px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.single-questions-submit {
|
||||
margin-left: 40px;
|
||||
background-color: #4390f7;
|
||||
color: #fff;
|
||||
border: 1px solid #4390f7;
|
||||
}
|
||||
.single-questions-disabled-submit {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { Affix } from 'antd';
|
||||
import { RightOutlined } from '@ant-design/icons';
|
||||
import './index.less';
|
||||
|
||||
export default function UploadLeftLayout(props) {
|
||||
return (
|
||||
<Affix offsetTop={150}>
|
||||
<div className="upload-left-layout">
|
||||
{props.layoutList.map((item, index) => {
|
||||
return (
|
||||
<div
|
||||
className={`upload-left-layout-item ${item.active ? 'upload-left-layout-item-active' : ''
|
||||
}`}
|
||||
onClick={() => {
|
||||
props.onChange(index);
|
||||
}}
|
||||
key={`upload_left_layout_${item.id}`}>
|
||||
{item.title}
|
||||
<RightOutlined style={{ marginLeft: 54 }} />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Affix>
|
||||
);
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
.upload-left-layout {
|
||||
width: 233px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 26px;
|
||||
|
||||
.upload-left-layout-item {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-right: 10px;
|
||||
margin-bottom: 20px;
|
||||
width: 207px;
|
||||
height: 48px;
|
||||
font-size: 16px;
|
||||
color: rgba(57, 60, 76, 1);
|
||||
transition: all 0.3s;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
border: 1px solid rgba(208, 212, 222, 1);
|
||||
border-radius: 12px;
|
||||
&:hover {
|
||||
@include font-color(0.9);
|
||||
@include box-backgroundColor(0.3);
|
||||
}
|
||||
}
|
||||
.upload-left-layout-item-active {
|
||||
color: rgba(60, 110, 238, 1);
|
||||
font-weight: bold;
|
||||
background: rgba(60, 110, 238, 0.1);
|
||||
border: 1px solid rgba(60, 110, 238, 1);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user