ai-course/app/backend/src/pages/exam/papers/compenents/random-paper.tsx

1235 lines
42 KiB
TypeScript
Raw Normal View History

2025-11-18 13:32:46 +08:00
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';
2025-11-18 13:32:46 +08:00
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: '困难' },
];
2025-11-18 13:32:46 +08:00
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,
2025-11-18 13:32:46 +08:00
});
const [select, setSelect] = useState({
number: 0,
score: 0,
missed_score: 0,
level: null as number | null,
knowledge_codes: '' as string,
2025-11-18 13:32:46 +08:00
});
const [input, setInput] = useState({
number: 0,
score: 0,
level: null as number | null,
knowledge_codes: '' as string,
2025-11-18 13:32:46 +08:00
});
const [judge, setJudge] = useState({
number: 0,
score: 0,
level: null as number | null,
knowledge_codes: '' as string,
2025-11-18 13:32:46 +08:00
});
const [qa, setQa] = useState({
number: 0,
score: 0,
level: null as number | null,
knowledge_codes: '' as string,
2025-11-18 13:32:46 +08:00
});
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: [],
2025-11-18 13:32:46 +08:00
});
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);
}
};
2025-11-18 13:32:46 +08:00
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 || '',
2025-11-18 13:32:46 +08:00
});
}
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 || '',
2025-11-18 13:32:46 +08:00
});
}
if (score[3]) {
setInput({
number: score[3].number,
score: score[3].score,
level: score[3].level || null,
knowledge_codes: score[3].knowledge_codes || '',
2025-11-18 13:32:46 +08:00
});
}
if (score[4]) {
setJudge({
number: score[4].number,
score: score[4].score,
level: score[4].level || null,
knowledge_codes: score[4].knowledge_codes || '',
2025-11-18 13:32:46 +08:00
});
}
if (score[5]) {
setQa({
number: score[5].number,
score: score[5].score,
level: score[5].level || null,
knowledge_codes: score[5].knowledge_codes || '',
2025-11-18 13:32:46 +08:00
});
}
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 || '',
2025-11-18 13:32:46 +08:00
});
}
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(() => {});
}
});
}
2025-11-18 13:32:46 +08:00
});
};
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>
2025-11-18 13:32:46 +08:00
</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' }}>
2025-11-18 13:32:46 +08:00
<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>
2025-11-18 13:32:46 +08:00
</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' }}>
2025-11-18 13:32:46 +08:00
<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>
2025-11-18 13:32:46 +08:00
</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' }}>
2025-11-18 13:32:46 +08:00
<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>
2025-11-18 13:32:46 +08:00
</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' }}>
2025-11-18 13:32:46 +08:00
<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>
2025-11-18 13:32:46 +08:00
</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' }}>
2025-11-18 13:32:46 +08:00
<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>
2025-11-18 13:32:46 +08:00
</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>
);
};