|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
|
import { history, useParams, useRequest } from 'umi';
|
|
|
import type { ProFormInstance } from '@ant-design/pro-form';
|
|
|
import { ModalForm } from '@ant-design/pro-form';
|
|
|
import { ProFormRadio } from '@ant-design/pro-form';
|
|
|
import ProForm, {StepsForm, ProFormText, ProFormDatePicker, ProFormSelect, ProFormTextArea, ProFormCheckbox, ProFormDateRangePicker,} from '@ant-design/pro-form';
|
|
|
import ProCard from '@ant-design/pro-card';
|
|
|
import { Button, Checkbox, Col, Divider, Dropdown, Form, Input, List, Menu, message, Modal, Radio, Row, Space, Table, Typography, Upload, Empty, Tooltip, Popconfirm } from 'antd';
|
|
|
import { PageContainer } from '@ant-design/pro-layout';
|
|
|
import ProDescriptions from '@ant-design/pro-descriptions';
|
|
|
import styles from './index.less'
|
|
|
import { saveRules, querySubjectList, queryRulesView, queryTempQuestionList, saveQuestionTypeScore, queryRulesPaper, updateScore, delTempQuestion, exchangeSortNum } from '../../service';
|
|
|
import { queryCourseView } from '@/pages/course/option/service';
|
|
|
import { queryQuestionList, queryQuestionById, queryQuestionType } from '@/pages/questionbank/service';
|
|
|
import { PlusOutlined, DownOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EyeInvisibleOutlined, EyeOutlined, EditOutlined, ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
|
|
|
import ProList from '@ant-design/pro-list';
|
|
|
|
|
|
import { autoPaper, manualPaper, updatePaper } from '../service';
|
|
|
import ProTable, { EditableProTable } from '@ant-design/pro-table';
|
|
|
|
|
|
import QuestionSelector from '../../components/QuestionSelector';
|
|
|
import ScoreSetter from '../../components/ScoreSetter';
|
|
|
import AutoSelector from '../components/AutoSelector';
|
|
|
import { ConsoleMessage } from 'puppeteer-core';
|
|
|
import { getSubjectInfo } from '@/pages/course/subject/service';
|
|
|
import { forEach } from 'lodash';
|
|
|
|
|
|
/**
|
|
|
* 保存选题
|
|
|
*
|
|
|
* @param values
|
|
|
*/
|
|
|
const handleAppend = async (rules_id: number, rows: any[]) => {
|
|
|
const hide = message.loading('正在添加');
|
|
|
try {
|
|
|
const questions: { question_id: any; }[] = [];
|
|
|
rows?.forEach((item) => {
|
|
|
questions.push({ question_id: item?.id })
|
|
|
})
|
|
|
const _data = await manualPaper({
|
|
|
question_count: questions?.length || 0,
|
|
|
questions: JSON.stringify(questions),
|
|
|
rules_id: Number(rules_id)
|
|
|
});
|
|
|
hide();
|
|
|
message.success('添加成功');
|
|
|
return _data;
|
|
|
} catch (error) {
|
|
|
hide();
|
|
|
message.error('添加失败请重试!');
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 保存选题试卷
|
|
|
*
|
|
|
* @param values
|
|
|
*/
|
|
|
const handleUpdatePaper = async (rules_id: number, paper_uuid: number, paper_id: number) => {
|
|
|
const hide = message.loading('正在保存');
|
|
|
try {
|
|
|
const _data = {
|
|
|
rules_id: Number(rules_id),
|
|
|
paper_uuid: paper_uuid,
|
|
|
paper_id: paper_id
|
|
|
}
|
|
|
if (paper_id === 0) {
|
|
|
delete _data.paper_id;
|
|
|
}
|
|
|
await updatePaper(_data);
|
|
|
hide();
|
|
|
message.success('保存成功');
|
|
|
return true;
|
|
|
} catch (error) {
|
|
|
hide();
|
|
|
message.error('保存失败请重试!');
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 删除临时表试题(接口不支持批量)
|
|
|
* 参数为记录数组
|
|
|
* @param ids
|
|
|
*/
|
|
|
const handleRemoveTempQuestion = async (paper_uuid: number, question_ids: [{question_id: number}]) => {
|
|
|
const hide = message.loading('正在删除');
|
|
|
console.log('uuidPaper', paper_uuid)
|
|
|
if (!question_ids || !paper_uuid) return true;
|
|
|
try {
|
|
|
const {code, msg} = await delTempQuestion({
|
|
|
paper_uuid: paper_uuid,
|
|
|
question_ids: JSON.stringify(question_ids)
|
|
|
});
|
|
|
hide();
|
|
|
if(code === 2000 ){
|
|
|
message.success('删除成功,即将刷新');
|
|
|
}else{
|
|
|
message.warning(msg);
|
|
|
}
|
|
|
return true;
|
|
|
} catch (error) {
|
|
|
hide();
|
|
|
message.error('删除失败,请重试');
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 组卷交换临时表试题顺序
|
|
|
* @param paper_uuid
|
|
|
* @param question_ids
|
|
|
* @param rules_id
|
|
|
* @returns bool
|
|
|
*/
|
|
|
const handleExchangeSortNum = async (paper_uuid: number, question_ids: string, rules_id: number) => {
|
|
|
const hide = message.loading('正在保存修改');
|
|
|
try {
|
|
|
const data = {
|
|
|
rules_id: Number(rules_id),
|
|
|
paper_uuid: paper_uuid,
|
|
|
question_ids: question_ids
|
|
|
}
|
|
|
const success = await exchangeSortNum(data);
|
|
|
hide();
|
|
|
if(success){
|
|
|
message.success('修改成功');
|
|
|
}
|
|
|
return true;
|
|
|
} catch (error) {
|
|
|
hide();
|
|
|
message.error('修改失败请重试!');
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
|
|
|
// 模拟考试规则维护
|
|
|
export default () => {
|
|
|
|
|
|
const [selectorModalVisible, handleSelectorModalVisible] = useState<boolean>(false);
|
|
|
const [scoreModalVisible, handleScoreModalVisible] = useState<boolean>(false);
|
|
|
const [autoModalVisible, handleAutoModalVisible] = useState<boolean>(false);
|
|
|
|
|
|
const [subjectId, setSubjectId] = useState<number>(0); // 关联主题id
|
|
|
const [subjectName, setSubjectName] = useState(''); // 关联主题name
|
|
|
|
|
|
const [questionTypeValues, setQuestionTypeValues] = useState([]); // 题型数据[{count:0, score:0, score_harf:0}]
|
|
|
|
|
|
const [uuidPaper, setUuidPaper] = useState<number>(0);
|
|
|
const [createType, setCreateType] = useState<number>(1); // 组卷类型
|
|
|
const [rulesName, setRulesName] = useState<string>(''); // 组卷类型
|
|
|
const [sumScore, setSumScore] = useState<number>(0); // 总分
|
|
|
const [passScore, setPassScore] = useState<number>(0); // 通过分数线
|
|
|
|
|
|
const [typeQuestionCount, setTypeQuestionCount] = useState([0, 0, 0]); // 临时卷 各题型数量
|
|
|
|
|
|
const [rulesId, setRulesId] = useState(0); // 规则id, 保存新建的rules_id
|
|
|
|
|
|
const formRef = useRef<ProFormInstance>();
|
|
|
|
|
|
const selectorRef = useRef();
|
|
|
const setterRef = useRef();
|
|
|
const autoRef = useRef();
|
|
|
|
|
|
const [currentStep, setCurrentStep] = useState(0);
|
|
|
|
|
|
const params = useParams();
|
|
|
|
|
|
const [questionType, setQuestionType] = useState([]); // 题型
|
|
|
const [scoreValues, setScoreValues] = useState([]); // 分值 [{"question_type": "0","score": "3","score_harf": "0"},]
|
|
|
const [paperInfo, setPaperInfo] = useState({})
|
|
|
|
|
|
/** 获取题型 */
|
|
|
const { data: questionTypeData } = useRequest(() => {
|
|
|
return queryQuestionType();
|
|
|
}, {
|
|
|
formatResult: (result) => {
|
|
|
return result.list;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
useEffect(() => {
|
|
|
setQuestionType(questionTypeData || []);
|
|
|
return () => {
|
|
|
/** 退出当前页面清空Map */
|
|
|
//parsingMap.clear();
|
|
|
}
|
|
|
}, [questionTypeData]);
|
|
|
|
|
|
/** 组卷,查询试题临时表(当前选题列表) */
|
|
|
const { data: questions, run } = useRequest(async (params) => {
|
|
|
console.log('questions', questions)
|
|
|
const _data = await queryTempQuestionList(params);
|
|
|
return _data;
|
|
|
}, {
|
|
|
manual: true,
|
|
|
formatResult: (result) => {
|
|
|
return result?.table_List;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
/** 从临时表中计算各题型数量 */
|
|
|
useEffect(() => {
|
|
|
const _data = [0, 0, 0]; // 当前仅支持 单选 / 多选 / 判断 的顺序
|
|
|
console.log('questions-info', questions)
|
|
|
questions?.forEach((item) => {
|
|
|
_data[Number(item?.question_type)] += 1
|
|
|
})
|
|
|
|
|
|
setTypeQuestionCount(_data);
|
|
|
return () => {
|
|
|
/** 退出当前页面清空Map */
|
|
|
//parsingMap.clear();
|
|
|
}
|
|
|
}, [questions]);
|
|
|
//
|
|
|
const { data: paperData, run: runPaper } = useRequest(async (params) => {
|
|
|
console.log('paperData', paperData)
|
|
|
/**
|
|
|
* rules_id: params?.id,
|
|
|
page_number: value.current,
|
|
|
page_size: value.pageSize
|
|
|
*/
|
|
|
return queryRulesPaper(params);
|
|
|
}, {
|
|
|
manual: true,
|
|
|
formatResult: (result) => {
|
|
|
return result?.question_list;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
useEffect(() => {
|
|
|
console.log('paperData2', paperData)
|
|
|
if (paperData?.length > 0) {
|
|
|
console.log('paperData[0]', paperData[0])
|
|
|
setPaperInfo(paperData[0])
|
|
|
}
|
|
|
console.log('PaperInfo', paperInfo)
|
|
|
}, [paperData]);
|
|
|
|
|
|
console.log(params, 'params');
|
|
|
|
|
|
let ruleData = {}
|
|
|
//
|
|
|
if (params?.id) {
|
|
|
//console.log(JSON.stringify(params), "878");
|
|
|
const { data } = useRequest(async () => {
|
|
|
return queryRulesView(params);
|
|
|
}, {
|
|
|
formatResult: (result) => {
|
|
|
return result?.bean;
|
|
|
}
|
|
|
});
|
|
|
ruleData = data
|
|
|
}
|
|
|
console.log(ruleData, 'ruleData');
|
|
|
|
|
|
return (
|
|
|
<PageContainer content={''} extraContent={''}>
|
|
|
<ProCard className={styles.examinationrules}>
|
|
|
<StepsForm<{
|
|
|
name: string;
|
|
|
}>
|
|
|
formRef={formRef}
|
|
|
onFinish={async (e) => {
|
|
|
message.success('提交成功');
|
|
|
}}
|
|
|
formProps={{
|
|
|
layout: "horizontal",
|
|
|
labelCol: { span: 7 },
|
|
|
wrapperCol: { span: 12 },
|
|
|
validateMessages: {
|
|
|
required: '此项为必填项',
|
|
|
},
|
|
|
}}
|
|
|
>
|
|
|
<StepsForm.StepForm<{
|
|
|
name: string;
|
|
|
}>
|
|
|
name="base"
|
|
|
title="模拟考试基本信息"
|
|
|
stepProps={{
|
|
|
description: false,
|
|
|
}}
|
|
|
onFinish={async (fileds) => {
|
|
|
if (params?.id) {
|
|
|
fileds = { ...fileds, id: (params.id || rulesId) }
|
|
|
}
|
|
|
const { data } = await saveRules({
|
|
|
...fileds,
|
|
|
b_use: 0,
|
|
|
rules_type: 0,
|
|
|
});
|
|
|
|
|
|
setRulesId(data?.rules_id) // 保存规则id
|
|
|
//run({paper_uuid:1}); // 获取当前选题列表
|
|
|
// console.log('模拟考试基本信息', fileds)
|
|
|
setSubjectId(fileds?.subject_id) // 设置当前关联主题
|
|
|
setRulesName(fileds?.rules_name) // 设置模拟考试规则名称
|
|
|
console.log('fileds', fileds)
|
|
|
console.log('formRef', formRef.current?.getFieldValue(''))
|
|
|
// await waitTime(2000);
|
|
|
setCurrentStep(1) // 设置步骤号
|
|
|
return true;
|
|
|
|
|
|
}}
|
|
|
>
|
|
|
<Row gutter={24}>
|
|
|
<Col lg={24} md={24} sm={24}>
|
|
|
{ruleData && (
|
|
|
<>
|
|
|
<ProFormText
|
|
|
name="rules_name"
|
|
|
label="考试名称"
|
|
|
width="lg"
|
|
|
initialValue={ruleData?.rules_name}
|
|
|
// tooltip="最长为 6 位汉字,需要与考生身份证一致"
|
|
|
placeholder="请输入名称"
|
|
|
fieldProps={{
|
|
|
type: 'text',
|
|
|
allowClear: false,
|
|
|
width: 'large',
|
|
|
onInput:(e)=>{
|
|
|
const val = `${e.currentTarget?.value}`;
|
|
|
if(val.length > 50) {
|
|
|
e.currentTarget.value = val.slice(0,50)
|
|
|
}
|
|
|
}
|
|
|
//style:{width: '100%'}
|
|
|
}}
|
|
|
rules={[
|
|
|
{ required: true, message: '请输入考试名称' },
|
|
|
{
|
|
|
pattern: /^[^\s]*$/,
|
|
|
message: '禁止输入空格'
|
|
|
}
|
|
|
]}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<ProFormSelect
|
|
|
width="lg"
|
|
|
initialValue={ruleData?.subject_id}
|
|
|
key='value'
|
|
|
request={async () => {
|
|
|
return querySubjectList().then(({ data }) => {
|
|
|
console.log(data, 'querySubjectList')
|
|
|
return data.list.map((item) => {
|
|
|
if (item?.subject_id === ruleData?.subject_id) {
|
|
|
setSubjectName(item?.subject_name) // 设置关联主题名称
|
|
|
console.log('label::', item?.subject_name)
|
|
|
}
|
|
|
return {
|
|
|
label: item?.subject_name,
|
|
|
value: item?.subject_id,
|
|
|
};
|
|
|
});
|
|
|
});
|
|
|
}}
|
|
|
onChange={(value) => {
|
|
|
console.log('on change', value)
|
|
|
}}
|
|
|
rules={[{ required: true, message: '请选择主题' }]}
|
|
|
name="subject_id"
|
|
|
label="关联主题"
|
|
|
/>
|
|
|
<ProFormText
|
|
|
width="lg"
|
|
|
addonAfter={`分钟`}
|
|
|
name="examination_time"
|
|
|
label="考试时长"
|
|
|
|
|
|
fieldProps={{
|
|
|
type: 'number',
|
|
|
min:1,
|
|
|
max:999,
|
|
|
allowClear: false,
|
|
|
width: 'large',
|
|
|
onInput:(e)=>{
|
|
|
const val = `${e.currentTarget?.value}`;
|
|
|
e.currentTarget.value = val.replace(/[^\d]|[0]/,'')
|
|
|
if(val.length > 3) {
|
|
|
e.currentTarget.value = val.slice(0,3)
|
|
|
}
|
|
|
}
|
|
|
//style:{width: '100%'}
|
|
|
}}
|
|
|
initialValue={ruleData?.examination_time}
|
|
|
rules={[
|
|
|
{
|
|
|
required: true,
|
|
|
message: '请输入考试时长'
|
|
|
},
|
|
|
{
|
|
|
pattern: /^[^\s]*$/,
|
|
|
message: '禁止输入空格'
|
|
|
}]}
|
|
|
/>
|
|
|
</>
|
|
|
)}
|
|
|
</Col>
|
|
|
</Row>
|
|
|
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
|
<StepsForm.StepForm<{
|
|
|
checkbox: string;
|
|
|
}>
|
|
|
name="object"
|
|
|
title="组卷"
|
|
|
stepProps={{
|
|
|
description: false,
|
|
|
}}
|
|
|
onFinish={async () => {
|
|
|
console.log(formRef.current?.getFieldsValue());
|
|
|
setCurrentStep(2) // 设置步骤号
|
|
|
//alert(params?.id || rulesId)
|
|
|
let msg = '操作成功'
|
|
|
if(!questions){
|
|
|
msg = '请选择试题'
|
|
|
message.error(msg);
|
|
|
return false;
|
|
|
}
|
|
|
// question 请选择试题 请选择试题
|
|
|
|
|
|
|
|
|
runPaper({ rules_id: params?.id || rulesId })
|
|
|
return true;
|
|
|
}}
|
|
|
>
|
|
|
<div style={{ margin: '0' }}>
|
|
|
|
|
|
<Typography style={{ padding: 24, fontSize: 24, textAlign: 'center' }}>{rulesName}</Typography>
|
|
|
{/** 一旦录入另一项将禁用,清空组卷后可选另一项 */}
|
|
|
<Row>
|
|
|
<Col span={12} style={{padding:5}}><Button size="large" onClick={()=>{handleSelectorModalVisible(true)}} value={1} style={{ display:'block', textAlign: 'center', width:'100%'}}>手动组卷</Button></Col>
|
|
|
<Col span={12} style={{padding:5}}><Button size="large" onClick={()=>{handleAutoModalVisible(true)}} value={2} style={{ display:'block', textAlign: 'center', width:'100%'}}>系统组卷</Button></Col>
|
|
|
</Row>
|
|
|
<Divider style={{ margin: '6px 0', opacity: 0.5 }} />
|
|
|
|
|
|
<Row>
|
|
|
<Col span={18} style={{ background: '#ffffff', padding: 0 }}>
|
|
|
{questions &&
|
|
|
<ProCard
|
|
|
title=""
|
|
|
extra={false}
|
|
|
split='vertical'
|
|
|
bordered
|
|
|
headerBordered
|
|
|
>
|
|
|
<Space direction="vertical" style={{ width: '100%', padding: '24px 48px' }}>
|
|
|
{questions && questions.map((item, idx) => (
|
|
|
item &&
|
|
|
<div style={{ border: 'none' }}>
|
|
|
<Typography style={{ marginBottom: 16, fontSize: 14, padding: '15px 15px 0 15px' }}>
|
|
|
{idx + 1}. {item?.question_stem}
|
|
|
</Typography>
|
|
|
{(item?.question_type === 0) && // 单选题
|
|
|
<div style={{ padding: '0 15px 15px 15px' }}>
|
|
|
{item?.answers && item?.answers.map((anster, k) => (
|
|
|
<div value={k} checked style={{ width: '100%', padding: 5, fontSize: 14 }}>
|
|
|
{anster?.is_true === '0' && <span style={{ color: '#1890ff', border: '1px solid #1890ff', display: 'inline-block', width: 16, height: 16, textAlign: 'center', borderRadius: '50%', fontSize: 12, lineHeight: '12px', marginRight: 10 }}>{labels[k]} </span>}
|
|
|
{anster?.is_true === '1' && <span style={{ color: '#ffffff', border: '1px solid #1890ff', display: 'inline-block', width: 16, height: 16, textAlign: 'center', borderRadius: '50%', fontSize: 12, lineHeight: '12px', marginRight: 10, backgroundColor: '#1890ff' }}>{labels[k]} </span>}
|
|
|
<span style={{ display: 'inline-block' }}>{anster?.answer}</span>
|
|
|
</div>
|
|
|
))}
|
|
|
</div>
|
|
|
}
|
|
|
{(item?.question_type === 1) && // 多选题
|
|
|
<div style={{ padding: '0 15px 15px 15px' }}>
|
|
|
{item?.answers && item?.answers.map((anster, k) => (
|
|
|
<div value={k} checked style={{ width: '100%', padding: 5, fontSize: 14 }}>
|
|
|
{anster?.is_true === '0' && <span style={{ color: '#1890ff', border: '1px solid #1890ff', display: 'inline-block', width: 16, height: 16, textAlign: 'center', borderRadius: '50%', fontSize: 12, lineHeight: '12px', marginRight: 10 }}>{labels[k]} </span>}
|
|
|
{anster?.is_true === '1' && <span style={{ color: '#ffffff', border: '1px solid #1890ff', display: 'inline-block', width: 16, height: 16, textAlign: 'center', borderRadius: '50%', fontSize: 12, lineHeight: '12px', marginRight: 10, backgroundColor: '#1890ff' }}>{labels[k]} </span>}
|
|
|
<span style={{ display: 'inline-block' }}>{anster?.answer}</span>
|
|
|
</div>
|
|
|
))}
|
|
|
</div>
|
|
|
}
|
|
|
{(item?.question_type === 2) && // 判断选题
|
|
|
<div style={{ padding: '0 15px 15px 15px' }}>
|
|
|
{item?.answers && item?.answers.map((anster, k) => (
|
|
|
<div value={k} checked style={{ width: '100%', padding: 5, fontSize: 14 }}>
|
|
|
{anster?.is_true === '0' && <span style={{ color: '#1890ff', border: '1px solid #1890ff', display: 'inline-block', width: 16, height: 16, textAlign: 'center', borderRadius: '50%', fontSize: 12, lineHeight: '12px', marginRight: 10 }}>{labels[k]} </span>}
|
|
|
{anster?.is_true === '1' && <span style={{ color: '#ffffff', border: '1px solid #1890ff', display: 'inline-block', width: 16, height: 16, textAlign: 'center', borderRadius: '50%', fontSize: 12, lineHeight: '12px', marginRight: 10, backgroundColor: '#1890ff' }}>{labels[k]} </span>}
|
|
|
<span style={{ display: 'inline-block' }}>{anster?.answer}</span>
|
|
|
</div>
|
|
|
))}
|
|
|
</div>
|
|
|
}
|
|
|
<div style={{ height: 'auto', backgroundColor: '#f0f0f0', textAlign: 'right', padding: 5, opacity: 1 }}>
|
|
|
<Button disabled={idx === 0} onClick={async ()=>{
|
|
|
const success = await handleExchangeSortNum(uuidPaper,[questions[idx-1]?.id, item?.id].toString(), rulesId)
|
|
|
if (success) {
|
|
|
run({
|
|
|
paper_uuid: uuidPaper,
|
|
|
page_size: 1000,
|
|
|
page_number: 1
|
|
|
}); // 获取当前选题列表
|
|
|
}
|
|
|
}}><ArrowUpOutlined /></Button>
|
|
|
<Button disabled={idx+1 === questions?.length} onClick={async ()=>{
|
|
|
const success = await handleExchangeSortNum(uuidPaper, [ item?.id, questions[idx+1]?.id].toString(), rulesId)
|
|
|
if (success) {
|
|
|
run({
|
|
|
paper_uuid: uuidPaper,
|
|
|
page_size: 1000,
|
|
|
page_number: 1
|
|
|
}); // 获取当前选题列表
|
|
|
}
|
|
|
}}><ArrowDownOutlined /></Button>
|
|
|
<Popconfirm key="popconfirm" title={`确认删除当前项吗?`} okText="是" cancelText="否"
|
|
|
onConfirm={async () => {
|
|
|
const success = await handleRemoveTempQuestion(uuidPaper, [{ question_id: item?.id }]); // 调用批量删除函数(如果接口不支持批量需要在service中处理)
|
|
|
if (success) {
|
|
|
run({
|
|
|
paper_uuid: uuidPaper,
|
|
|
page_size: 1000,
|
|
|
page_number: 1
|
|
|
}); // 获取当前选题列表
|
|
|
}
|
|
|
}}
|
|
|
>
|
|
|
<Button><DeleteOutlined /></Button>
|
|
|
</Popconfirm>
|
|
|
</div>
|
|
|
</div>
|
|
|
))}
|
|
|
|
|
|
</Space>
|
|
|
</ProCard>
|
|
|
}
|
|
|
{!questions &&
|
|
|
<Empty style={{minHeight:360, padding:60, verticalAlign:'middle',color:'#cccccc'}} description='暂无试卷' />
|
|
|
}
|
|
|
</Col>
|
|
|
<Col span={6} style={{ paddingLeft: 24 }}>
|
|
|
<div style={{ background: '#ffffff', padding: 24 }}>
|
|
|
<Space direction="vertical" style={{ width: '100%' }}>
|
|
|
<strong>试卷信息与设置</strong>
|
|
|
<Typography>共 {questions?.length} 题 {'-'} 分</Typography>
|
|
|
<Divider style={{ margin: '6px 0', opacity: 0.5 }} />
|
|
|
<Space direction="vertical">
|
|
|
{questionType.map((item) => {
|
|
|
return <Typography>{item?.name} 共 {typeQuestionCount[Number(item.code)]} 题 {'-'} 分</Typography>
|
|
|
}
|
|
|
)}
|
|
|
</Space>
|
|
|
<Divider style={{ margin: '6px 0', opacity: 0.5 }} />
|
|
|
<Button size="large" block onClick={() => {
|
|
|
/**
|
|
|
* 设置分值前需要题型数据
|
|
|
* [{count: 0, score: 0, score_harf: 0},{count: 0, score: 0, score_harf: 0},{count: 0, score: 0, score_harf: 0}]
|
|
|
*/
|
|
|
//
|
|
|
const _data = []
|
|
|
typeQuestionCount?.forEach((item) => {
|
|
|
_data.push({ count: item, score: 0, score_harf: 0 })
|
|
|
})
|
|
|
setQuestionTypeValues(_data)
|
|
|
console.log('typeQuestionCount', typeQuestionCount);
|
|
|
handleScoreModalVisible(true)
|
|
|
}}>批量设置分值</Button>
|
|
|
<Tooltip defaultVisible={false} zIndex={1} title={<span style={{display:'block', width:152}}>请选择试题组卷并设置分值后保存</span>} placement="bottom" color='#108ee9'>
|
|
|
<Button size="large" disabled={questions ? false : true} type="primary" block onClick={async () => {
|
|
|
console.log('uuidPaper::', uuidPaper)
|
|
|
console.log('rules_id::', params?.id)
|
|
|
const paper_id = paper_id ? paper_id : 0;
|
|
|
await handleUpdatePaper(params?.id || rulesId, uuidPaper, paper_id)
|
|
|
}}>保存试卷</Button>
|
|
|
</Tooltip>
|
|
|
</Space>
|
|
|
</div>
|
|
|
</Col>
|
|
|
</Row>
|
|
|
</div>
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
|
<StepsForm.StepForm
|
|
|
name="time"
|
|
|
title="完成"
|
|
|
stepProps={{
|
|
|
description: false,
|
|
|
}}
|
|
|
onFinish={async () => {
|
|
|
console.log(formRef.current?.getFieldsValue());
|
|
|
// 跳转到指定路由
|
|
|
history.push('/examinationrules/normal');
|
|
|
return true;
|
|
|
}}
|
|
|
>
|
|
|
<Row gutter={24}>
|
|
|
<Col lg={12} md={12} sm={12} offset={8}>
|
|
|
{currentStep === 2 && <ProDescriptions
|
|
|
layout='horizontal'
|
|
|
column={1}
|
|
|
//actionRef={actionRef}
|
|
|
title={false}
|
|
|
request={async () => {
|
|
|
console.log('rulesId...', rulesId)
|
|
|
//{rules_id: rulesId}
|
|
|
console.log('params...', params)
|
|
|
const result = await queryRulesView({id: rulesId})
|
|
|
console.log('queryRulesView', result)
|
|
|
const subjectInfo = await getSubjectInfo({ subject_id: result.bean.subject_id })
|
|
|
console.log('subjectInfo', subjectInfo)
|
|
|
return { data: { ...result.bean, subject_name: subjectInfo.data.subject_name } };
|
|
|
|
|
|
}}
|
|
|
extra={false}
|
|
|
>
|
|
|
<ProDescriptions.Item dataIndex="id" hideInDescriptions />
|
|
|
<ProDescriptions.Item dataIndex="rules_name" label="考试名称" valueType="text" />
|
|
|
<ProDescriptions.Item dataIndex="subject_name" label="关联主题" valueType="text" />
|
|
|
<ProDescriptions.Item dataIndex="examination_time" label="考试时长" valueType="text" renderText={(text) => (`${text} 分钟`)} />
|
|
|
<ProDescriptions.Item dataIndex="grade" label="试卷信息" valueType="text" render={() => {
|
|
|
{/** 从试卷中读取 临时卷必须保存后才进入此页 */ }
|
|
|
return <Space direction="vertical">
|
|
|
<span>共 {paperInfo?.question_type_count?.map(item=>item.count)?.reduce((prev, curr)=>prev + curr)} 道题, {paperInfo?.sum_score || '-'} 分</span>
|
|
|
<span>{paperInfo?.question_type_count?.map(item=>(<span style={{paddingRight:10}}>{`${item?.type_name} ${item?.count} 道题 `}</span>))}</span>
|
|
|
<span>通过线 {paperInfo?.pass_score || '-'} 分</span>
|
|
|
</Space>
|
|
|
}} />
|
|
|
</ProDescriptions>
|
|
|
}
|
|
|
</Col>
|
|
|
</Row>
|
|
|
</StepsForm.StepForm>
|
|
|
</StepsForm>
|
|
|
</ProCard>
|
|
|
|
|
|
<ModalForm
|
|
|
title={`手动组卷`}
|
|
|
width="80%"
|
|
|
layout='horizontal'
|
|
|
visible={selectorModalVisible}
|
|
|
onVisibleChange={handleSelectorModalVisible}
|
|
|
onFinish={async (values) => {
|
|
|
console.log('v::::', values.name);
|
|
|
const rows = selectorRef?.current?.getSelectedRows()
|
|
|
console.log('rows::::', rows);
|
|
|
const { code, data: paper, msg } = await handleAppend(Number(params?.id || rulesId), rows)
|
|
|
console.log('paper', paper)
|
|
|
setUuidPaper(paper?.paper_uuid)
|
|
|
console.log('paper_uuid', paper?.paper_uuid)
|
|
|
run({
|
|
|
paper_uuid: paper?.paper_uuid,
|
|
|
page_size: 1000,
|
|
|
page_number: 1
|
|
|
}); // 获取当前选题列表
|
|
|
// message.success('提交成功');
|
|
|
handleSelectorModalVisible(false)
|
|
|
return true;
|
|
|
}}
|
|
|
>
|
|
|
{selectorModalVisible && <QuestionSelector ref={selectorRef} />}
|
|
|
</ModalForm>
|
|
|
<ModalForm
|
|
|
title={`系统组卷`}
|
|
|
width="80%"
|
|
|
visible={autoModalVisible}
|
|
|
onVisibleChange={handleAutoModalVisible}
|
|
|
onFinish={async () => {
|
|
|
const values = autoRef?.current.getData()
|
|
|
console.log('data-v', values)
|
|
|
//const values = [{"question_type":0,"chapter_list": [{ "chapter_id":76, "count":1 },{ "chapter_id":77, "count":1 }]}]
|
|
|
const {code, data: paper, msg} = await autoPaper({rules_id: Number(params?.id), auto_param: JSON.stringify(values)})
|
|
|
//console.log('paper', paper)
|
|
|
setUuidPaper(paper?.paper_uuid)
|
|
|
run({
|
|
|
paper_uuid: paper?.paper_uuid,
|
|
|
page_size: 1000,
|
|
|
page_number: 1
|
|
|
}); // 获取当前选题列表
|
|
|
message.success('提交成功');
|
|
|
handleAutoModalVisible(false)
|
|
|
return true;
|
|
|
}}
|
|
|
>
|
|
|
{autoModalVisible && <AutoSelector ref={autoRef} subjectId={subjectId} questionType={questionType} />}
|
|
|
</ModalForm>
|
|
|
<ModalForm
|
|
|
title={`批量设置分值`}
|
|
|
//
|
|
|
width="60%"
|
|
|
visible={scoreModalVisible}
|
|
|
onVisibleChange={handleScoreModalVisible}
|
|
|
onFinish={async () => {
|
|
|
console.log('typeQuestionCount', typeQuestionCount)
|
|
|
const values = setterRef.current?.getData() // 获取题型分值数据
|
|
|
const passSocre = setterRef.current?.getValue() // 获取通过分数线
|
|
|
const sumCore = setterRef.current?.getSum() // 获取总分
|
|
|
console.log('批量设置分值v::::2', values);
|
|
|
// 题型分数
|
|
|
const { code, data: paper, msg } = await saveQuestionTypeScore({ rules_id: Number(params?.id || rulesId), type_score: JSON.stringify(values) })
|
|
|
const { success } = await updateScore({ rules_id: Number(params?.id || rulesId), pass_socre: passSocre, sum_score: sumCore })
|
|
|
//setSumScore(_sumScore)
|
|
|
//console.log('paper', paper)
|
|
|
// setUuidPaper(paper?.paper_uuid)
|
|
|
// message.success('提交成功');
|
|
|
handleScoreModalVisible(false)
|
|
|
return true;
|
|
|
}}
|
|
|
>
|
|
|
<ScoreSetter ref={setterRef} questionTypeValues={questionTypeValues || false} />
|
|
|
</ModalForm>
|
|
|
</PageContainer>
|
|
|
|
|
|
);
|
|
|
}; |