1235 lines
42 KiB
TypeScript
1235 lines
42 KiB
TypeScript
import { useEffect, useState } from 'react';
|
||
import styles from './paper.module.less';
|
||
import { message, Button, Table, InputNumber, Spin, Modal, Select } from 'antd';
|
||
import { paper, question } from '../../../../api';
|
||
import type { ColumnsType } from 'antd/es/table';
|
||
import { PlusOutlined } from '@ant-design/icons';
|
||
import { useLocation, useNavigate } from 'react-router-dom';
|
||
import { BackBartment, SelectQuestion } from '../../../../compenents';
|
||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||
import { useTranslation } from 'react-i18next';
|
||
const { confirm } = Modal;
|
||
|
||
// 难度选项
|
||
const levelOptions = [
|
||
{ value: null, label: '不限' },
|
||
{ value: 1, label: '简单' },
|
||
{ value: 2, label: '中等' },
|
||
{ value: 3, label: '困难' },
|
||
];
|
||
|
||
interface DataType {
|
||
id: React.Key;
|
||
admin_id: number;
|
||
category_id: number;
|
||
created_at: string;
|
||
deleted: number;
|
||
name: string;
|
||
q1: number;
|
||
q2: number;
|
||
q3: number;
|
||
q4: number;
|
||
q5: number;
|
||
q6: number;
|
||
sort: number;
|
||
updated_at: string;
|
||
}
|
||
|
||
interface PropInterface {
|
||
type: string;
|
||
}
|
||
|
||
export const RendomPaper: React.FC<PropInterface> = ({ type }) => {
|
||
const { t } = useTranslation();
|
||
const navigate = useNavigate();
|
||
const result = new URLSearchParams(useLocation().search);
|
||
const [spinInit, setSpinInit] = useState(false);
|
||
const [init, setInit] = useState(false);
|
||
const [loading, setLoading] = useState(false);
|
||
const [score, setScore] = useState(0);
|
||
const [passScore, setPassScore] = useState(0);
|
||
const [addQuestion, setAddQuestion] = useState(false);
|
||
const [list, setList] = useState<DataType[]>([]);
|
||
const [questions, setQuestions] = useState([]);
|
||
const [title, setTitle] = useState(String(result.get('title')));
|
||
const [cateId, setCateId] = useState(Number(result.get('cid')));
|
||
const [id, setId] = useState(Number(result.get('id')));
|
||
const [q1, setQ1] = useState(0);
|
||
const [q2, setQ2] = useState(0);
|
||
const [q3, setQ3] = useState(0);
|
||
const [q4, setQ4] = useState(0);
|
||
const [q5, setQ5] = useState(0);
|
||
const [q6, setQ6] = useState(0);
|
||
const [q1Score, setQ1Score] = useState(0);
|
||
const [q2Score, setQ2Score] = useState(0);
|
||
const [q3Score, setQ3Score] = useState(0);
|
||
const [q4Score, setQ4Score] = useState(0);
|
||
const [q5Score, setQ5Score] = useState(0);
|
||
const [q6Score, setQ6Score] = useState(0);
|
||
const [choice, setChoice] = useState({
|
||
number: 0,
|
||
score: 0,
|
||
level: null as number | null,
|
||
knowledge_codes: '' as string,
|
||
});
|
||
const [select, setSelect] = useState({
|
||
number: 0,
|
||
score: 0,
|
||
missed_score: 0,
|
||
level: null as number | null,
|
||
knowledge_codes: '' as string,
|
||
});
|
||
const [input, setInput] = useState({
|
||
number: 0,
|
||
score: 0,
|
||
level: null as number | null,
|
||
knowledge_codes: '' as string,
|
||
});
|
||
const [judge, setJudge] = useState({
|
||
number: 0,
|
||
score: 0,
|
||
level: null as number | null,
|
||
knowledge_codes: '' as string,
|
||
});
|
||
const [qa, setQa] = useState({
|
||
number: 0,
|
||
score: 0,
|
||
level: null as number | null,
|
||
knowledge_codes: '' as string,
|
||
});
|
||
const [cap, setCap] = useState({
|
||
number: 0,
|
||
score: 0,
|
||
missed_score: 0,
|
||
level: null as number | null,
|
||
knowledge_codes: '' as string,
|
||
});
|
||
// 各题型的知识点选项
|
||
const [knowledgeOptions, setKnowledgeOptions] = useState<Record<number, any[]>>({
|
||
1: [],
|
||
2: [],
|
||
3: [],
|
||
4: [],
|
||
5: [],
|
||
6: [],
|
||
});
|
||
|
||
useEffect(() => {
|
||
setCateId(Number(result.get('cid')));
|
||
setTitle(String(result.get('title')));
|
||
setId(Number(result.get('id')));
|
||
}, [result.get('cid'), result.get('title'), result.get('id')]);
|
||
|
||
// 根据题库、题型、难度加载知识点列表
|
||
const loadKnowledgeCodes = async (type: number, level: number | null) => {
|
||
if (questions.length === 0) return;
|
||
try {
|
||
const res: any = await question.getKnowledgeCodes(questions.join(','), type, level);
|
||
const items = res.data || [];
|
||
// 后端返回 [{code: "xxx", name: "yyy"}, ...]
|
||
const options = items.map((item: { code: string; name: string }) => ({
|
||
value: item.code,
|
||
label: item.name,
|
||
}));
|
||
setKnowledgeOptions((prev) => ({ ...prev, [type]: options }));
|
||
} catch (e) {
|
||
console.error('加载知识点失败', e);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
if (id === 0) {
|
||
return;
|
||
}
|
||
if (id > 0) {
|
||
setSpinInit(true);
|
||
getDetail();
|
||
}
|
||
}, [id]);
|
||
|
||
useEffect(() => {
|
||
getQuestionList();
|
||
}, [questions]);
|
||
|
||
useEffect(() => {
|
||
if (list.length > 0) {
|
||
let num1 = 0;
|
||
let num2 = 0;
|
||
let num3 = 0;
|
||
let num4 = 0;
|
||
let num5 = 0;
|
||
let num6 = 0;
|
||
list.map((item: any) => {
|
||
num1 += Number(item.q1);
|
||
num2 += Number(item.q2);
|
||
num3 += Number(item.q3);
|
||
num4 += Number(item.q4);
|
||
num5 += Number(item.q5);
|
||
num6 += Number(item.q6);
|
||
});
|
||
setQ1(num1);
|
||
setQ2(num2);
|
||
setQ3(num3);
|
||
setQ4(num4);
|
||
setQ5(num5);
|
||
setQ6(num6);
|
||
}
|
||
}, [list]);
|
||
|
||
useEffect(() => {
|
||
if (choice.number > 0 && choice.score > 0) {
|
||
const value = choice.number * choice.score;
|
||
setQ1Score(value);
|
||
} else {
|
||
setQ1Score(0);
|
||
}
|
||
if (select.number > 0 && select.score > 0) {
|
||
const value = select.number * select.score;
|
||
setQ2Score(value);
|
||
} else {
|
||
setQ2Score(0);
|
||
}
|
||
if (input.number > 0 && input.score > 0) {
|
||
const value = input.number * input.score;
|
||
setQ3Score(value);
|
||
} else {
|
||
setQ3Score(0);
|
||
}
|
||
if (judge.number > 0 && judge.score > 0) {
|
||
const value = judge.number * judge.score;
|
||
setQ4Score(value);
|
||
} else {
|
||
setQ4Score(0);
|
||
}
|
||
if (qa.number > 0 && qa.score > 0) {
|
||
const value = qa.number * qa.score;
|
||
setQ5Score(value);
|
||
} else {
|
||
setQ5Score(0);
|
||
}
|
||
if (cap.number > 0 && cap.score > 0) {
|
||
const value = cap.number * cap.score;
|
||
setQ6Score(value);
|
||
} else {
|
||
setQ6Score(0);
|
||
}
|
||
}, [choice, select, input, judge, qa, cap]);
|
||
|
||
useEffect(() => {
|
||
const value = q1Score + q2Score + q3Score + q4Score + q5Score + q6Score;
|
||
setScore(value);
|
||
}, [q1Score, q2Score, q3Score, q4Score, q5Score, q6Score]);
|
||
|
||
const getDetail = () => {
|
||
paper.detail(id).then((res: any) => {
|
||
setPassScore(res.data.result.pass_score);
|
||
const data = JSON.parse(res.data.result.extra);
|
||
const arr = data.d.random_rules.source.category_ids;
|
||
if (arr.length > 0) {
|
||
setQuestions(arr);
|
||
}
|
||
const score = data.d.random_rules.score;
|
||
if (score[1]) {
|
||
setChoice({
|
||
number: score[1].number,
|
||
score: score[1].score,
|
||
level: score[1].level || null,
|
||
knowledge_codes: score[1].knowledge_codes || '',
|
||
});
|
||
}
|
||
if (score[2]) {
|
||
setSelect({
|
||
number: score[2].number,
|
||
score: score[2].score,
|
||
missed_score: score[2].missed_score,
|
||
level: score[2].level || null,
|
||
knowledge_codes: score[2].knowledge_codes || '',
|
||
});
|
||
}
|
||
if (score[3]) {
|
||
setInput({
|
||
number: score[3].number,
|
||
score: score[3].score,
|
||
level: score[3].level || null,
|
||
knowledge_codes: score[3].knowledge_codes || '',
|
||
});
|
||
}
|
||
if (score[4]) {
|
||
setJudge({
|
||
number: score[4].number,
|
||
score: score[4].score,
|
||
level: score[4].level || null,
|
||
knowledge_codes: score[4].knowledge_codes || '',
|
||
});
|
||
}
|
||
if (score[5]) {
|
||
setQa({
|
||
number: score[5].number,
|
||
score: score[5].score,
|
||
level: score[5].level || null,
|
||
knowledge_codes: score[5].knowledge_codes || '',
|
||
});
|
||
}
|
||
if (score[6]) {
|
||
setCap({
|
||
number: score[6].number,
|
||
score: score[6].score,
|
||
missed_score: 0,
|
||
level: score[6].level || null,
|
||
knowledge_codes: score[6].knowledge_codes || '',
|
||
});
|
||
}
|
||
setSpinInit(false);
|
||
setInit(false);
|
||
|
||
// 预加载各题型的知识点选项(用于回显)
|
||
if (arr.length > 0) {
|
||
const categoryIds = arr.join(',');
|
||
[1, 2, 3, 4, 5, 6].forEach((type) => {
|
||
const typeScore = score[type];
|
||
if (typeScore && typeScore.knowledge_codes) {
|
||
question
|
||
.getKnowledgeCodes(categoryIds, type, typeScore.level || null)
|
||
.then((res: any) => {
|
||
const items = res.data || [];
|
||
const options = items.map((item: { code: string; name: string }) => ({
|
||
value: item.code,
|
||
label: item.name,
|
||
}));
|
||
setKnowledgeOptions((prev) => ({ ...prev, [type]: options }));
|
||
})
|
||
.catch(() => {});
|
||
}
|
||
});
|
||
}
|
||
});
|
||
};
|
||
|
||
const getQuestionList = () => {
|
||
if (init) {
|
||
return;
|
||
}
|
||
if (questions.length === 0) {
|
||
return;
|
||
}
|
||
setInit(true);
|
||
paper
|
||
.checkQuestionList(questions.join(','))
|
||
.then((res: any) => {
|
||
setList(res.data.result);
|
||
setInit(false);
|
||
})
|
||
.catch((e) => {
|
||
setInit(false);
|
||
});
|
||
};
|
||
|
||
const columns: ColumnsType<DataType> = [
|
||
{
|
||
title: t('exam.question.columns.title1'),
|
||
render: (_, record: any) => (
|
||
<div className="d-flex ">
|
||
<i
|
||
className="iconfont c-file icon-icon-file"
|
||
style={{
|
||
fontSize: 16,
|
||
color: '#ffa816',
|
||
}}
|
||
/>
|
||
<span className="ml-8">{record.name}</span>
|
||
</div>
|
||
),
|
||
},
|
||
{
|
||
title: t('exam.question.choice.label'),
|
||
width: 120,
|
||
render: (_, record: any) => <span>{record.q1}</span>,
|
||
},
|
||
{
|
||
title: t('exam.question.select.label'),
|
||
width: 120,
|
||
render: (_, record: any) => <span>{record.q2}</span>,
|
||
},
|
||
{
|
||
title: t('exam.question.input.label'),
|
||
width: 120,
|
||
render: (_, record: any) => <span>{record.q3}</span>,
|
||
},
|
||
{
|
||
title: t('exam.question.judge.label'),
|
||
width: 120,
|
||
render: (_, record: any) => <span>{record.q4}</span>,
|
||
},
|
||
{
|
||
title: t('exam.question.qa.label'),
|
||
width: 120,
|
||
render: (_, record: any) => <span>{record.q5}</span>,
|
||
},
|
||
{
|
||
title: t('exam.question.cap.label'),
|
||
width: 120,
|
||
render: (_, record: any) => <span>{record.q6}</span>,
|
||
},
|
||
{
|
||
title: t('exam.question.columns.title4'),
|
||
key: 'action',
|
||
fixed: 'right',
|
||
width: 120,
|
||
render: (_, record) => (
|
||
<Button type="link" className="b-link c-red" onClick={() => delQuestion(Number(record.id))}>
|
||
{t('commen.del')}
|
||
</Button>
|
||
),
|
||
},
|
||
];
|
||
|
||
const delQuestion = (qid: number) => {
|
||
confirm({
|
||
title: t('commen.confirmError'),
|
||
icon: <ExclamationCircleFilled />,
|
||
content: t('exam.paper.compose.delText2'),
|
||
centered: true,
|
||
okText: t('commen.okText'),
|
||
cancelText: t('commen.cancelText'),
|
||
onOk() {
|
||
const arr = [...questions];
|
||
const arr2 = [...list];
|
||
const key = arr.findIndex((i: any) => i === qid);
|
||
if (key >= 0) {
|
||
arr.splice(key, 1);
|
||
arr2.splice(key, 1);
|
||
}
|
||
setQuestions(arr);
|
||
setList(arr2);
|
||
},
|
||
onCancel() {
|
||
console.log('Cancel');
|
||
},
|
||
});
|
||
};
|
||
|
||
const selectQuestionData = (arr: any, data: any) => {
|
||
setQuestions(arr);
|
||
setAddQuestion(false);
|
||
};
|
||
|
||
const submitHandle = () => {
|
||
if (loading) {
|
||
return;
|
||
}
|
||
if (questions.length === 0) {
|
||
message.error(t('exam.paper.compose.errorText7'));
|
||
return;
|
||
}
|
||
if (
|
||
choice.number === 0 &&
|
||
select.number === 0 &&
|
||
input.number === 0 &&
|
||
judge.number === 0 &&
|
||
qa.number === 0 &&
|
||
cap.number === 0
|
||
) {
|
||
message.error(t('exam.paper.compose.errorText8'));
|
||
return;
|
||
}
|
||
if (choice.number > 0 && q1Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText9'));
|
||
return;
|
||
}
|
||
if (select.number > 0 && q2Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText10'));
|
||
return;
|
||
}
|
||
if (input.number > 0 && q3Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText11'));
|
||
return;
|
||
}
|
||
if (judge.number > 0 && q4Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText12'));
|
||
return;
|
||
}
|
||
if (qa.number > 0 && q5Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText13'));
|
||
return;
|
||
}
|
||
if (cap.number > 0 && q6Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText14'));
|
||
return;
|
||
}
|
||
if (score === 0) {
|
||
message.error(t('exam.paper.compose.errorText15'));
|
||
return;
|
||
}
|
||
if (passScore === 0) {
|
||
message.error(t('exam.paper.compose.errorText3'));
|
||
return;
|
||
}
|
||
const obj: any = {};
|
||
if (q1Score > 0) {
|
||
obj[1] = choice;
|
||
}
|
||
if (q2Score > 0) {
|
||
obj[2] = select;
|
||
}
|
||
if (q3Score > 0) {
|
||
obj[3] = input;
|
||
}
|
||
if (q4Score > 0) {
|
||
obj[4] = judge;
|
||
}
|
||
if (q5Score > 0) {
|
||
obj[5] = qa;
|
||
}
|
||
if (q6Score > 0) {
|
||
obj[6] = cap;
|
||
}
|
||
|
||
const params = {
|
||
v: 'v1',
|
||
d: {
|
||
random_rules: {
|
||
source: {
|
||
category_ids: questions,
|
||
},
|
||
score: obj,
|
||
},
|
||
},
|
||
};
|
||
const extra = JSON.stringify(params);
|
||
setLoading(true);
|
||
paper.store(cateId, title, score, passScore, 1, extra).then((res: any) => {
|
||
setLoading(false);
|
||
message.success(t('commen.saveSuccess'));
|
||
navigate(-1);
|
||
});
|
||
};
|
||
|
||
const submitUpdateHandle = () => {
|
||
if (loading) {
|
||
return;
|
||
}
|
||
if (questions.length === 0) {
|
||
message.error(t('exam.paper.compose.errorText7'));
|
||
return;
|
||
}
|
||
if (
|
||
choice.number === 0 &&
|
||
select.number === 0 &&
|
||
input.number === 0 &&
|
||
judge.number === 0 &&
|
||
qa.number === 0 &&
|
||
cap.number === 0
|
||
) {
|
||
message.error(t('exam.paper.compose.errorText8'));
|
||
return;
|
||
}
|
||
if (choice.number > 0 && q1Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText9'));
|
||
return;
|
||
}
|
||
if (select.number > 0 && q2Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText10'));
|
||
return;
|
||
}
|
||
if (input.number > 0 && q3Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText11'));
|
||
return;
|
||
}
|
||
if (judge.number > 0 && q4Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText12'));
|
||
return;
|
||
}
|
||
if (qa.number > 0 && q5Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText13'));
|
||
return;
|
||
}
|
||
if (cap.number > 0 && q6Score === 0) {
|
||
message.error(t('exam.paper.compose.errorText14'));
|
||
return;
|
||
}
|
||
if (score === 0) {
|
||
message.error(t('exam.paper.compose.errorText15'));
|
||
return;
|
||
}
|
||
if (passScore === 0) {
|
||
message.error(t('exam.paper.compose.errorText3'));
|
||
return;
|
||
}
|
||
const obj: any = {};
|
||
if (q1Score > 0) {
|
||
obj[1] = choice;
|
||
}
|
||
if (q2Score > 0) {
|
||
obj[2] = select;
|
||
}
|
||
if (q3Score > 0) {
|
||
obj[3] = input;
|
||
}
|
||
if (q4Score > 0) {
|
||
obj[4] = judge;
|
||
}
|
||
if (q5Score > 0) {
|
||
obj[5] = qa;
|
||
}
|
||
if (q6Score > 0) {
|
||
obj[6] = cap;
|
||
}
|
||
|
||
const params = {
|
||
v: 'v1',
|
||
d: {
|
||
random_rules: {
|
||
source: {
|
||
category_ids: questions,
|
||
},
|
||
score: obj,
|
||
},
|
||
},
|
||
};
|
||
const extra = JSON.stringify(params);
|
||
setLoading(true);
|
||
paper.questionUpdate(id, cateId, title, score, passScore, 1, extra).then((res: any) => {
|
||
setLoading(false);
|
||
message.success(t('commen.saveSuccess'));
|
||
navigate(-1);
|
||
});
|
||
};
|
||
|
||
return (
|
||
<div className="float-left" style={{ height: '100%', backgroundColor: '#F6F6F6' }}>
|
||
<div className={styles['paper-header']}>
|
||
<div className="d-flex">
|
||
<BackBartment title={title}></BackBartment>
|
||
</div>
|
||
<div className="d-flex">
|
||
<div className={styles['total-score']}>
|
||
{t('exam.paper.compose.score')}
|
||
{score}
|
||
</div>
|
||
<Button
|
||
type="primary"
|
||
className="ml-24"
|
||
loading={loading}
|
||
onClick={() => {
|
||
if (type === 'create') {
|
||
submitHandle();
|
||
return;
|
||
}
|
||
submitUpdateHandle();
|
||
}}
|
||
>
|
||
{t('exam.paper.compose.save')}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
<div className={styles['random-paper-content']}>
|
||
<div className="float-left">
|
||
<Button type="primary" icon={<PlusOutlined />} onClick={() => setAddQuestion(true)}>
|
||
{t('exam.paper.compose.addQuestions')}
|
||
</Button>
|
||
</div>
|
||
{spinInit && (
|
||
<div className="float-left text-center mt-30">
|
||
<Spin></Spin>
|
||
</div>
|
||
)}
|
||
{!spinInit && list.length > 0 ? (
|
||
<>
|
||
<div className="float-left mt-24">
|
||
<Table
|
||
columns={columns}
|
||
dataSource={list}
|
||
loading={init}
|
||
pagination={false}
|
||
rowKey={(record) => record.id}
|
||
/>
|
||
</div>
|
||
<div className="float-left mt-50">
|
||
{q1 > 0 && (
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex">
|
||
<div className={styles['label']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.question.choice.label')}({t('exam.paper.compose.text1')}
|
||
{q1}
|
||
{t('exam.paper.compose.text2')}):
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
{t('exam.paper.compose.text3')}
|
||
<InputNumber
|
||
max={q1}
|
||
min={0}
|
||
defaultValue={choice.number}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...choice };
|
||
obj.number = Number(value);
|
||
setChoice(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text2')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<InputNumber
|
||
min={0}
|
||
defaultValue={choice.score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...choice };
|
||
obj.score = Number(value);
|
||
setChoice(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text4')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
难度
|
||
<Select
|
||
style={{ width: 100, marginLeft: 8 }}
|
||
size="large"
|
||
options={levelOptions}
|
||
value={choice.level}
|
||
onChange={(value) => {
|
||
const obj = { ...choice };
|
||
obj.level = value;
|
||
obj.knowledge_codes = '';
|
||
setChoice(obj);
|
||
loadKnowledgeCodes(1, value);
|
||
}}
|
||
allowClear
|
||
placeholder="不限"
|
||
/>
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
知识点
|
||
<Select
|
||
style={{ width: 200, marginLeft: 8 }}
|
||
size="large"
|
||
mode="multiple"
|
||
options={knowledgeOptions[1]}
|
||
value={choice.knowledge_codes ? choice.knowledge_codes.split(',') : []}
|
||
onChange={(values: string[]) => {
|
||
const obj = { ...choice };
|
||
obj.knowledge_codes = values.join(',');
|
||
setChoice(obj);
|
||
}}
|
||
maxTagCount="responsive"
|
||
placeholder="不限"
|
||
onFocus={() => loadKnowledgeCodes(1, choice.level)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.text1')}
|
||
{q1Score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
)}
|
||
{q2 > 0 && (
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex" style={{ flexWrap: 'wrap', gap: '8px 0' }}>
|
||
<div className={styles['label']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.question.select.label')}({t('exam.paper.compose.text1')}
|
||
{q2}
|
||
{t('exam.paper.compose.text2')}):
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
{t('exam.paper.compose.text3')}
|
||
<InputNumber
|
||
max={q2}
|
||
min={0}
|
||
defaultValue={select.number}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...select };
|
||
obj.number = Number(value);
|
||
setSelect(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text2')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<InputNumber
|
||
min={0}
|
||
defaultValue={select.score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...select };
|
||
obj.score = Number(value);
|
||
setSelect(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text4')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<span className="c-red">*</span>
|
||
{t('exam.paper.compose.text6')}
|
||
<InputNumber
|
||
min={0}
|
||
max={select.score}
|
||
defaultValue={select.missed_score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...select };
|
||
obj.missed_score = Number(value);
|
||
setSelect(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
难度
|
||
<Select
|
||
style={{ width: 100, marginLeft: 8 }}
|
||
size="large"
|
||
options={levelOptions}
|
||
value={select.level}
|
||
onChange={(value) => {
|
||
const obj = { ...select };
|
||
obj.level = value;
|
||
obj.knowledge_codes = '';
|
||
setSelect(obj);
|
||
loadKnowledgeCodes(2, value);
|
||
}}
|
||
allowClear
|
||
placeholder="不限"
|
||
/>
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
知识点
|
||
<Select
|
||
style={{ width: 200, marginLeft: 8 }}
|
||
size="large"
|
||
mode="multiple"
|
||
options={knowledgeOptions[2]}
|
||
value={select.knowledge_codes ? select.knowledge_codes.split(',') : []}
|
||
onChange={(values: string[]) => {
|
||
const obj = { ...select };
|
||
obj.knowledge_codes = values.join(',');
|
||
setSelect(obj);
|
||
}}
|
||
maxTagCount="responsive"
|
||
placeholder="不限"
|
||
onFocus={() => loadKnowledgeCodes(2, select.level)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.text1')}
|
||
{q2Score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
)}
|
||
{q3 > 0 && (
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex" style={{ flexWrap: 'wrap', gap: '8px 0' }}>
|
||
<div className={styles['label']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.question.input.label')}({t('exam.paper.compose.text1')}
|
||
{q3}
|
||
{t('exam.paper.compose.text2')}):
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
{t('exam.paper.compose.text3')}
|
||
<InputNumber
|
||
max={q3}
|
||
min={0}
|
||
defaultValue={input.number}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...input };
|
||
obj.number = Number(value);
|
||
setInput(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text2')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<InputNumber
|
||
min={0}
|
||
defaultValue={input.score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...input };
|
||
obj.score = Number(value);
|
||
setInput(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text4')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
难度
|
||
<Select
|
||
style={{ width: 100, marginLeft: 8 }}
|
||
size="large"
|
||
options={levelOptions}
|
||
value={input.level}
|
||
onChange={(value) => {
|
||
const obj = { ...input };
|
||
obj.level = value;
|
||
obj.knowledge_codes = '';
|
||
setInput(obj);
|
||
loadKnowledgeCodes(3, value);
|
||
}}
|
||
allowClear
|
||
placeholder="不限"
|
||
/>
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
知识点
|
||
<Select
|
||
style={{ width: 200, marginLeft: 8 }}
|
||
size="large"
|
||
mode="multiple"
|
||
options={knowledgeOptions[3]}
|
||
value={input.knowledge_codes ? input.knowledge_codes.split(',') : []}
|
||
onChange={(values: string[]) => {
|
||
const obj = { ...input };
|
||
obj.knowledge_codes = values.join(',');
|
||
setInput(obj);
|
||
}}
|
||
maxTagCount="responsive"
|
||
placeholder="不限"
|
||
onFocus={() => loadKnowledgeCodes(3, input.level)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.text1')}
|
||
{q3Score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
)}
|
||
{q4 > 0 && (
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex" style={{ flexWrap: 'wrap', gap: '8px 0' }}>
|
||
<div className={styles['label']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.question.judge.label')}({t('exam.paper.compose.text1')}
|
||
{q4}
|
||
{t('exam.paper.compose.text2')}):
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
{t('exam.paper.compose.text3')}
|
||
<InputNumber
|
||
max={q4}
|
||
min={0}
|
||
defaultValue={judge.number}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...judge };
|
||
obj.number = Number(value);
|
||
setJudge(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text2')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<InputNumber
|
||
min={0}
|
||
defaultValue={judge.score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...judge };
|
||
obj.score = Number(value);
|
||
setJudge(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text4')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
难度
|
||
<Select
|
||
style={{ width: 100, marginLeft: 8 }}
|
||
size="large"
|
||
options={levelOptions}
|
||
value={judge.level}
|
||
onChange={(value) => {
|
||
const obj = { ...judge };
|
||
obj.level = value;
|
||
obj.knowledge_codes = '';
|
||
setJudge(obj);
|
||
loadKnowledgeCodes(4, value);
|
||
}}
|
||
allowClear
|
||
placeholder="不限"
|
||
/>
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
知识点
|
||
<Select
|
||
style={{ width: 200, marginLeft: 8 }}
|
||
size="large"
|
||
mode="multiple"
|
||
options={knowledgeOptions[4]}
|
||
value={judge.knowledge_codes ? judge.knowledge_codes.split(',') : []}
|
||
onChange={(values: string[]) => {
|
||
const obj = { ...judge };
|
||
obj.knowledge_codes = values.join(',');
|
||
setJudge(obj);
|
||
}}
|
||
maxTagCount="responsive"
|
||
placeholder="不限"
|
||
onFocus={() => loadKnowledgeCodes(4, judge.level)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.text1')}
|
||
{q4Score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
)}
|
||
{q5 > 0 && (
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex" style={{ flexWrap: 'wrap', gap: '8px 0' }}>
|
||
<div className={styles['label']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.question.qa.label')}({t('exam.paper.compose.text1')}
|
||
{q5}
|
||
{t('exam.paper.compose.text2')}):
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
{t('exam.paper.compose.text3')}
|
||
<InputNumber
|
||
max={q5}
|
||
min={0}
|
||
defaultValue={qa.number}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...qa };
|
||
obj.number = Number(value);
|
||
setQa(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text2')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<InputNumber
|
||
min={0}
|
||
defaultValue={qa.score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...qa };
|
||
obj.score = Number(value);
|
||
setQa(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text4')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
难度
|
||
<Select
|
||
style={{ width: 100, marginLeft: 8 }}
|
||
size="large"
|
||
options={levelOptions}
|
||
value={qa.level}
|
||
onChange={(value) => {
|
||
const obj = { ...qa };
|
||
obj.level = value;
|
||
obj.knowledge_codes = '';
|
||
setQa(obj);
|
||
loadKnowledgeCodes(5, value);
|
||
}}
|
||
allowClear
|
||
placeholder="不限"
|
||
/>
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
知识点
|
||
<Select
|
||
style={{ width: 200, marginLeft: 8 }}
|
||
size="large"
|
||
mode="multiple"
|
||
options={knowledgeOptions[5]}
|
||
value={qa.knowledge_codes ? qa.knowledge_codes.split(',') : []}
|
||
onChange={(values: string[]) => {
|
||
const obj = { ...qa };
|
||
obj.knowledge_codes = values.join(',');
|
||
setQa(obj);
|
||
}}
|
||
maxTagCount="responsive"
|
||
placeholder="不限"
|
||
onFocus={() => loadKnowledgeCodes(5, qa.level)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.text1')}
|
||
{q5Score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
)}
|
||
{q6 > 0 && (
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex" style={{ flexWrap: 'wrap', gap: '8px 0' }}>
|
||
<div className={styles['label']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.question.cap.label')}({t('exam.paper.compose.text1')}
|
||
{q6}
|
||
{t('exam.paper.compose.text2')}):
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
{t('exam.paper.compose.text3')}
|
||
<InputNumber
|
||
max={q6}
|
||
min={0}
|
||
defaultValue={cap.number}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...cap };
|
||
obj.number = Number(value);
|
||
setCap(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text2')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
<InputNumber
|
||
min={0}
|
||
defaultValue={cap.score}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
const obj = { ...cap };
|
||
obj.score = Number(value);
|
||
setCap(obj);
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text4')}
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
难度
|
||
<Select
|
||
style={{ width: 100, marginLeft: 8 }}
|
||
size="large"
|
||
options={levelOptions}
|
||
value={cap.level}
|
||
onChange={(value) => {
|
||
const obj = { ...cap };
|
||
obj.level = value;
|
||
obj.knowledge_codes = '';
|
||
setCap(obj);
|
||
loadKnowledgeCodes(6, value);
|
||
}}
|
||
allowClear
|
||
placeholder="不限"
|
||
/>
|
||
</div>
|
||
<div className="d-flex ml-30">
|
||
知识点
|
||
<Select
|
||
style={{ width: 200, marginLeft: 8 }}
|
||
size="large"
|
||
mode="multiple"
|
||
options={knowledgeOptions[6]}
|
||
value={cap.knowledge_codes ? cap.knowledge_codes.split(',') : []}
|
||
onChange={(values: string[]) => {
|
||
const obj = { ...cap };
|
||
obj.knowledge_codes = values.join(',');
|
||
setCap(obj);
|
||
}}
|
||
maxTagCount="responsive"
|
||
placeholder="不限"
|
||
onFocus={() => loadKnowledgeCodes(6, cap.level)}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.text1')}
|
||
{q6Score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
<div className={styles['line']}></div>
|
||
<div className="float-left mt-24 mb-24">
|
||
<div className={styles['config-item']}>
|
||
<div className="d-flex">
|
||
<div className={styles['title']}>
|
||
<span className="c-red">*</span>
|
||
{t('exam.paper.compose.text7')}
|
||
</div>
|
||
<InputNumber
|
||
max={score}
|
||
min={0}
|
||
defaultValue={passScore}
|
||
placeholder={t('commen.inputNumber')}
|
||
onChange={(value) => {
|
||
setPassScore(Number(value));
|
||
}}
|
||
precision={0}
|
||
size="large"
|
||
className={styles['input']}
|
||
></InputNumber>
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
<div className="d-flex">
|
||
{t('exam.paper.compose.score')}
|
||
{score}
|
||
{t('exam.paper.compose.text5')}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</>
|
||
) : null}
|
||
</div>
|
||
<SelectQuestion
|
||
defaultKeys={questions}
|
||
open={addQuestion}
|
||
onCancel={() => {
|
||
setAddQuestion(false);
|
||
}}
|
||
onSelected={(arr: any, videos: any) => {
|
||
selectQuestionData(arr, videos);
|
||
}}
|
||
></SelectQuestion>
|
||
</div>
|
||
);
|
||
};
|