You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

570 lines
29 KiB

import React, { useEffect, useRef, useState } from 'react';
import { history, useParams, useRequest } from 'umi';
import { ModalForm, ProFormInstance } from '@ant-design/pro-form';
import { ProFormRadio } from '@ant-design/pro-form';
import ProForm, {StepsForm, ProFormText, ProFormSelect, ProFormDateRangePicker } from '@ant-design/pro-form';
import ProCard from '@ant-design/pro-card';
import { Button, Checkbox, Col, Divider, Input, List, Menu, message, Radio, Row, Space, Typography } 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, queryRulesList, queryRulesPaper, saveQuestionTypeScore, autoPaperOfficial, queryPaperQuestionList } from '../../service';
import { queryQuestionList, queryQuestionType } from '@/pages/questionbank/service';
import ProTable, { ActionType, EditableProTable, ProColumns } from '@ant-design/pro-table';
//import { TableListPagination } from '@/pages/ListTableList2/data';
import { DiffOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons';
//import { TableListItem } from '../../components/QuestionSelector';
import ScoreSetter from '../../components/ScoreSetter';
import AutoSelector from '../components/AutoSelector';
import QuestionSelector from '../../components/QuestionSelector';
import { getSubjectInfo } from '@/pages/course/subject/service';
/** 选项序号 */
const labels = ['A','B','C','D','E','F','G','H','I','J','K'];
/** 题型序号 */
const numberType = ['一','二','三','四','五','六','七','八','九','十'];
export default () => {
const questionNumber = [1,1,1];
const params = useParams();
const formRef = useRef<ProFormInstance>();
const actionRef = useRef<ActionType>();
const setterRef = useRef();
const autoRef = useRef();
const [currentStep, setCurrentStep] = useState(0);
const [questionTypeValues, setQuestionTypeValues] = useState([]); // 题型数据[{count:0, score:0, score_harf:0}]
const [questionType, setQuestionType] = useState([]); // 题型
/** 自动组卷窗口 */
const [autoModalVisible, handleAutoModalVisible] = useState<boolean>(false);
/** 分值窗口 */
const [scoreModalVisible, handleScoreModalVisible] = useState<boolean>(false);
/** 试卷详情窗口 */
const [paperModalVisible, handlePaperModalVisible] = useState<boolean>(false);
/** 查看试卷 */
const { data: questions, run } = useRequest(async (params) => {
console.log('questions', questions)
return queryPaperQuestionList(params);
},{
manual: true,
formatResult: (result) => {
return result?.question_list;
}});
/** 列表项定义 */
const columns: ProColumns[] = [
{
title: '序号',
key: 'index',
valueType: 'indexBorder',
width: 48,
},
{
title: '考试名称',
dataIndex: 'rules_name',
valueType: 'text',
hideInTable: false,
hideInForm: false,
hideInSearch: true,
},
{
title: '试卷',
dataIndex: 'examination_time',
valueType: 'text',
sorter: false,
hideInTable: true,
hideInForm: true,
hideInSearch: true,
renderText: (val: string) => `${val}`,
},
{
title: '关联主题',
dataIndex: 'subject_name',
valueType: 'text',
hideInTable: true,
hideInForm: true,
hideInSearch: true,
},
{
title: '题型设置',
dataIndex: 'question_type_count',
valueType: 'text',
hideInTable: true,
hideInForm: false,
hideInSearch: false,
request: async () => {
/*
const { data: Items } = await querySubjectList({});
// console.log(Items, ')))');
const sinfo = []
for (let i = 0; i < Items.list.length; i++) {
// console.log(Items.list[i], ">>>")
sinfo.push({ label: Items.list[i].subject_name, value: Items.list[i].subject_id })
}
console.log(sinfo, 'sinfo');
*/
return [];
},
},
{
title: '总分',
dataIndex: 'sum_score',
sorter: false,
valueType: 'text',
hideInSearch: true,
hideInForm: false,
renderText: (val: string) => `${val || 0}`,
},
{
title: '通过线',
dataIndex: 'pass_score',
sorter: false,
valueType: 'text',
hideInSearch: true,
hideInForm: false,
renderText: (val: string) => `${val || '-'}`,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
width: 200,
render: (_dom: any, record: React.SetStateAction) => {
console.log(record, 'record')
return [
<a
key="detail"
onClick={() => {
//console.log('entity', entity);
//setCurrentRow(record);
//
run({
paper_id: record?.paper_id,
}); // 获取试卷试题列表
handlePaperModalVisible(true); // 试卷详情
}}
>
</a>,
<a
key="create"
onClick={async () => {
//history.push(`/examination/option/registration/${record.examination_id}`);
//setCurrentRow(record);
const _type_count: any[] = [];
record?.question_type_count.forEach((item: { count: any; })=>{
_type_count.push(item?.count || 0)
})
const { success } = await autoPaperOfficial(
{
paper_id: record?.paper_id,
rules_id: Number(params?.id),
question_count: '50,50', // 当前数据库没保存,只能采用默认
question_type_count: _type_count?.toString()
}
)
}}
>
</a>,
]
},
},
];
console.log(params, 'params');
let ruleData = {}
if (params?.id) {
console.log(JSON.stringify(params), "878");
const { data } = useRequest(async () => {
const { bean } = await queryRulesView(params);
return { data: bean }
});
ruleData = data
}
console.log(ruleData, 'ruleData');
/** 获取题型 */
const { data: questionTypeData } = useRequest(() => {
return queryQuestionType();
},{
formatResult: (result) => {
return result.list;
}
});
useEffect(() => {
setQuestionType(questionTypeData || []);
return ()=>{
/** 退出当前页面清空Map */
//parsingMap.clear();
}
}, [questionTypeData]);
return (
<PageContainer content={''} extraContent={''}>
<ProCard className={styles.examinationrules}>
<StepsForm<{
name: string;
}>
formRef={formRef}
onFinish={async () => {
message.success('提交成功');
}}
formProps={{
layout: "horizontal",
labelCol: { span: 8 },
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 }
}
console.log(fileds, 'fileds', params);
// return false
await saveRules({
...fileds,
b_use: 0,
rules_type: 1,
start_time: fileds.dateRange[0],
end_time: fileds.dateRange[1]
});
setCurrentStep(1)
return true;
}}
>
<Row gutter={24}>
<Col lg={24} md={24} sm={24}>
{ruleData && (
<>
<ProFormText
name="rules_name"
label="考试名称"
width="md"
initialValue={ruleData.rules_name}
// tooltip="最长为 6 位汉字,需要与考生身份证一致"
placeholder="请输入名称"
rules={[{ required: true, message: '请输入考试名称' }]}
// value="锦书"
// disabled
/>
<ProFormSelect
width="md"
initialValue={ruleData.subject_id}
request={async () => {
return querySubjectList().then(({ data }) => {
console.log(data, 'querySubjectList')
return data.list.map((item) => {
return {
label: item.subject_name,
value: item.subject_id,
};
});
});
}}
rules={[{ required: true, message: '请选择主题' }]}
name="subject_id"
label="关联主题"
/>
<ProFormText name="examination_time" label="考试时长"
initialValue={ruleData.examination_time}
rules={[{ required: true, message: '请输入考试时长' }]}
// tooltip="限制考试时长的情况下,用户考试中离开,倒计时不会停止。"
/>
<ProFormText name="paper_count" label="试卷数量"
initialValue={ruleData.paper_count}
rules={[{ required: true, message: '请输入数量' }]}
// tooltip="限制考试时长的情况下,用户考试中离开,倒计时不会停止。"
/>
<ProFormDateRangePicker name="dateRange" label="试卷有效期" initialValue={[ruleData.start_time, ruleData.end_time]} />
</>
)}
</Col>
</Row>
</StepsForm.StepForm>
<StepsForm.StepForm<{
checkbox: string;
}>
name="object"
title="组卷"
stepProps={{
description: false,
}}
onFinish={async () => {
console.log(formRef.current?.getFieldsValue());
setCurrentStep(2)
return true;
}}
>
<div style={{ margin: '0' }}>
{`试卷`}
<ProTable
page
headerTitle={false}
actionRef={actionRef}
rowKey="examination_id"
options={false}
search={false}
toolBarRender={() => (
<Space style={{margin:-24}} >
<Button
type="primary"
key="primary"
onClick={() => {
handleAutoModalVisible(true)
}}
>
<PlusOutlined />
</Button>
<Button
type="primary"
key="primary"
onClick={() => {
handleScoreModalVisible(true)
}}
>
<DiffOutlined />
</Button>
</Space>
)}
request={async (value) => {
console.log('queryRulesPaper::')
/** 获取试卷 */
const _data = await queryRulesPaper(
{
rules_id: params?.id,
page_number: value.current,
page_size: value.pageSize
}
);
const _questionTypeCountData = [];
_data.question_list[0]?.question_type_count.forEach((item)=>{
_questionTypeCountData.push(item.count)
})
console.log('_questionTypeCountData', _questionTypeCountData)
const _questionType = [];
console.log('_data.question_type_score', _data.question_type_score)
if(_data?.question_type_score.length > 0){
_data.question_type_score?.forEach((item, index)=>{
_questionType.push({count: _questionTypeCountData[index], score: item.score, score_harf: item.score_harf})
})
}else{
_questionTypeCountData?.forEach((item, index)=>{
_questionType.push({count: _questionTypeCountData[index], score:0, score_harf: 0})
})
}
console.log('_questionType', _questionType)
setQuestionTypeValues(_questionType)
return {
current: _data?.pageNumber,
data: _data?.question_list,
pageSize: _data?.pageSize,
total: _data?.totalRow || 0,
};
}}
// dataSource={list}
columns={columns}
rowSelection={false}
/>
</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={16} md={16} sm={16} offset={6}>
{currentStep === 2 && <ProDescriptions
layout='horizontal'
column={1}
//actionRef={actionRef}
title={false}
request={async () => {
const result = await queryRulesView(params)
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> 0 , 100 </span>
<span>: 0 : 0 : 0 </span>
<span>线 60 </span>
</Space>
}} />
<ProDescriptions.Item dataIndex="paper_count" label="试卷数量" valueType="text" render={()=>{
return <div stype={{padding:0}}><span style={{display:'inline-block', width:200}}>0</span> <span><ExclamationCircleOutlined /> </span></div>
}} />
<ProDescriptions.Item dataIndex="live_time" label="试卷有效期" valueType="text" render={()=>{
return <div stype={{padding:0}}><span style={{display:'inline-block', width:200}}>2020/03/01</span> <span><ExclamationCircleOutlined /> </span></div>
}} />
</ProDescriptions>
}
</Col>
</Row>
</StepsForm.StepForm>
</StepsForm>
</ProCard>
<ModalForm
title="系统组卷"
visible={autoModalVisible}
onVisibleChange={handleAutoModalVisible}
onFinish={async () => {
const values = autoRef.current?.getData();
console.log('系统组卷::::', values);
const {code, data: paper, msg} = await autoPaperOfficial({rules_id:Number(params?.id), question_count: values?.questionCount.toString(), question_type_count: values?.questionTypeCount.toString()})
console.log('paper', paper)
// setUuidPaper(paper?.paper_uuid)
// message.success('提交成功');
actionRef.current?.reload()
handleAutoModalVisible(false)
return true;
}}
>
<AutoSelector ref={autoRef} questionType={questionType} />
</ModalForm>
<ModalForm
title={`批量设置分值`}
//
width="60%"
visible={scoreModalVisible}
onVisibleChange={handleScoreModalVisible}
footer={null}
onFinish={async () => {
const values = setterRef.current?.getData()
console.log('批量设置分值v::::', values);
const {code, data: paper, msg} = await saveQuestionTypeScore({rules_id:Number(params?.id), type_score: JSON.stringify(values)})
console.log('paper', paper)
// setUuidPaper(paper?.paper_uuid)
// message.success('提交成功');
handleScoreModalVisible(false)
return true;
}}
>
<ScoreSetter ref={setterRef} questionTypeValues={questionTypeValues} />
</ModalForm>
<ModalForm
title={`试卷详情`}
//
width="80%"
visible={paperModalVisible}
onVisibleChange={handlePaperModalVisible}
footer={null}
onFinish={async () => {
const values = setterRef.current?.getData()
console.log('试卷详情::::', values);
//const {code, data: paper, msg} = await saveQuestionTypeScore({rules_id:Number(params?.id), type_score: JSON.stringify(values)})
console.log('paper', paper)
// setUuidPaper(paper?.paper_uuid)
// message.success('提交成功');
handleScoreModalVisible(false)
return true;
}}
>
{questionType && questionType?.map((typeItem, index)=>{
//console.log('questionType:::', questionType)
return <>
{questions?.length === 0 && <div></div>}
<div key={typeItem?.code} style={{padding:10, fontSize:16}}>{numberType[index]}. {typeItem?.name}</div>
<div style={{padding:'0 10px 0 50px'}}>
{ questions && questions.map((item, idx)=>(
(typeItem?.code === item?.question_type) &&
<div style={{border:'none'}}>
<Typography style={{ marginBottom: 16, fontSize: 14, padding: '15px 15px 0 15px' }}>
{questionNumber[item?.question_type]++}. {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>
))}
</div>
</>
})}
</ModalForm>
</PageContainer>
);
};