|
|
|
@ -1,6 +1,8 @@ |
|
|
|
|
import React, { Component } from 'react'; |
|
|
|
|
import { Form, Input, Button, Radio, Checkbox, Select, message } from 'antd'; |
|
|
|
|
import {Form, Input, Button, Radio, Checkbox, Select, message, Modal, Table} from 'antd'; |
|
|
|
|
import { findIndustry, getRandomQuestions } from 'api/examPaper'; |
|
|
|
|
import { getList} from 'api/question'; |
|
|
|
|
import {dictionary} from "../../api/dict"; |
|
|
|
|
|
|
|
|
|
const { Option } = Select; |
|
|
|
|
|
|
|
|
@ -12,6 +14,7 @@ interface optionsState { |
|
|
|
|
// 定义单个试题的状态接口
|
|
|
|
|
interface QuestionState { |
|
|
|
|
id: string; |
|
|
|
|
serviceTypeId: string; |
|
|
|
|
questionTypes: string; |
|
|
|
|
questionContent: string; |
|
|
|
|
answerOptions: optionsState[]; |
|
|
|
@ -20,27 +23,57 @@ interface QuestionState { |
|
|
|
|
|
|
|
|
|
// 定义组件的状态接口
|
|
|
|
|
interface States { |
|
|
|
|
num: number; |
|
|
|
|
page: number; |
|
|
|
|
total: number; |
|
|
|
|
listQuery: { |
|
|
|
|
industryId: string | undefined; |
|
|
|
|
serviceTypeId: string | undefined; |
|
|
|
|
questionContent: string | undefined; |
|
|
|
|
}; |
|
|
|
|
industryDict: any; |
|
|
|
|
serviceTypeDict: any; |
|
|
|
|
isLoading: boolean; |
|
|
|
|
questions: QuestionState[]; |
|
|
|
|
isModalVisible: boolean; |
|
|
|
|
selectedParams: any; |
|
|
|
|
selectedQuestionList: QuestionState[]; |
|
|
|
|
questionSelectList: QuestionState[]; |
|
|
|
|
queryCondition: string; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
formRef: any; |
|
|
|
|
|
|
|
|
|
formRefSub: any; |
|
|
|
|
constructor(props: any) { |
|
|
|
|
super(props); |
|
|
|
|
this.formRef = React.createRef(); |
|
|
|
|
this.formRefSub = React.createRef(); |
|
|
|
|
this.state = { |
|
|
|
|
num: 10, |
|
|
|
|
page: 1, |
|
|
|
|
total: 0, |
|
|
|
|
listQuery: { |
|
|
|
|
industryId: undefined, |
|
|
|
|
serviceTypeId: undefined, |
|
|
|
|
questionContent: undefined |
|
|
|
|
}, |
|
|
|
|
industryDict: undefined, |
|
|
|
|
serviceTypeDict: undefined, |
|
|
|
|
isLoading: false, |
|
|
|
|
questions: [] |
|
|
|
|
questions: [], |
|
|
|
|
isModalVisible: false, |
|
|
|
|
selectedParams: {}, |
|
|
|
|
selectedQuestionList: [], |
|
|
|
|
questionSelectList: [], |
|
|
|
|
queryCondition: '' |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 初期
|
|
|
|
|
componentDidMount() { |
|
|
|
|
this.findIndustry(); |
|
|
|
|
this.findDict(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 监管行业
|
|
|
|
@ -52,6 +85,15 @@ class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// AQ服务类型
|
|
|
|
|
findDict() { |
|
|
|
|
dictionary('serviceTypeDict').then((res) => { |
|
|
|
|
if (res.data) { |
|
|
|
|
this.setState({ serviceTypeDict: res.data }); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 随机生成题目
|
|
|
|
|
handleRandomGenerate = () => { |
|
|
|
|
this.formRef.current.validateFields(['industryId', 'questionCount']) |
|
|
|
@ -71,9 +113,11 @@ class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
const options = questionData.options.split(','); |
|
|
|
|
const answerOptions = options.map((option: any) => { |
|
|
|
|
const [value, label] = option.split(':'); |
|
|
|
|
return { value, label };}); |
|
|
|
|
return { value, label }; |
|
|
|
|
}); |
|
|
|
|
return { |
|
|
|
|
id: String(questionData.id), |
|
|
|
|
serviceTypeId: String(questionData.serviceTypeId), |
|
|
|
|
questionTypes: String(questionData.questionTypes), |
|
|
|
|
questionContent: String(questionData.questionContent), |
|
|
|
|
answerOptions: answerOptions, |
|
|
|
@ -85,17 +129,133 @@ class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
} else { |
|
|
|
|
message.error('未获取到随机题目'); |
|
|
|
|
} |
|
|
|
|
}).catch(() => { |
|
|
|
|
}) |
|
|
|
|
.catch(() => { |
|
|
|
|
message.error('获取随机题目失败'); |
|
|
|
|
}); |
|
|
|
|
}).catch(() => {}); |
|
|
|
|
}) |
|
|
|
|
.catch(() => {}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 打开手动选题模态框
|
|
|
|
|
handleOpenManualSelectionModal = () => { |
|
|
|
|
const { questions } = this.state; |
|
|
|
|
this.formRef.current.validateFields(['industryId', 'questionCount']) |
|
|
|
|
.then((values: any) => { |
|
|
|
|
const industryId = values.industryId; |
|
|
|
|
const questionCount = values.questionCount; |
|
|
|
|
this.setState({ |
|
|
|
|
isModalVisible: true, |
|
|
|
|
selectedParams: { questions, industryId, questionCount } |
|
|
|
|
}); |
|
|
|
|
}) |
|
|
|
|
.catch(() => {}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 关闭手动选题模态框
|
|
|
|
|
handleCloseManualSelectionModal = () => { |
|
|
|
|
this.setState({ isModalVisible: false }); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 处理选择试题添加到已选列表
|
|
|
|
|
handleSelectQuestion = (selectedRows:any) => { |
|
|
|
|
const { selectedQuestionList } = this.state; |
|
|
|
|
const newSelectedList = [...selectedQuestionList,...selectedRows]; |
|
|
|
|
this.setState({ selectedQuestionList: newSelectedList }); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 处理删除已选试题
|
|
|
|
|
handleDeleteQuestion = (record:any) => { |
|
|
|
|
const { questions } = this.state; |
|
|
|
|
const newQuestion = questions.filter(question => question.id!== record.id); |
|
|
|
|
this.setState({ questions: newQuestion }); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 处理查询
|
|
|
|
|
handleQuery = () => { |
|
|
|
|
const { num, page, selectedParams } = this.state; |
|
|
|
|
const industryId = selectedParams.industryId; |
|
|
|
|
const { serviceTypeId } = this.formRefSub.current.getFieldsValue(['serviceTypeId']); |
|
|
|
|
const { questionContent } = this.formRefSub.current.getFieldsValue(['questionContent']); |
|
|
|
|
const listQuery = { |
|
|
|
|
industryId, |
|
|
|
|
serviceTypeId, |
|
|
|
|
questionContent |
|
|
|
|
}; |
|
|
|
|
getList(num, page, listQuery) |
|
|
|
|
.then((res: any) => { |
|
|
|
|
if (res.data) { |
|
|
|
|
this.setState({total: res.data.total}); |
|
|
|
|
const newQuestions: QuestionState[] = res.data.data.map((questionData: any) => { |
|
|
|
|
const options = questionData.options.split(','); |
|
|
|
|
const answerOptions = options.map((option: any) => { |
|
|
|
|
const [value, label] = option.split(':'); |
|
|
|
|
return { value, label }; |
|
|
|
|
}); |
|
|
|
|
return { |
|
|
|
|
id: String(questionData.id), |
|
|
|
|
serviceTypeId: String(questionData.serviceTypeId), |
|
|
|
|
questionTypes: String(questionData.questionTypes), |
|
|
|
|
questionContent: String(questionData.questionContent), |
|
|
|
|
answerOptions: answerOptions, |
|
|
|
|
answer: String(questionData.answer) |
|
|
|
|
}; |
|
|
|
|
}); |
|
|
|
|
this.setState({ questionSelectList: newQuestions }); |
|
|
|
|
} else { |
|
|
|
|
message.warning('未找到符合条件的试题'); |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
.catch(() => { |
|
|
|
|
message.error('检索试题失败'); |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
render() { |
|
|
|
|
const { industryDict, questions, isLoading } = this.state; |
|
|
|
|
const { industryDict, serviceTypeDict, questions, isLoading, isModalVisible, questionSelectList } = this.state; |
|
|
|
|
// 分页切换
|
|
|
|
|
const changePage = (current: number, pageSize?: number) => { |
|
|
|
|
setTimeout(() => { |
|
|
|
|
this.setState({page: current, num: pageSize || 20}); |
|
|
|
|
this.handleQuery(); |
|
|
|
|
}, 0); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 多少每页
|
|
|
|
|
const selectChange = (page: number, num: number) => { |
|
|
|
|
this.setState({ page, num }); |
|
|
|
|
this.handleQuery(); |
|
|
|
|
}; |
|
|
|
|
const handleListQuestion = () => { |
|
|
|
|
this.props.history.push('/examPaperList'); |
|
|
|
|
}; |
|
|
|
|
const columns: any = [ |
|
|
|
|
{ title: '序号', dataIndex: 'index', align: 'center', width: 60, |
|
|
|
|
render: (_:number, __:number, index:number) => index + 1 |
|
|
|
|
}, |
|
|
|
|
{ title: 'AQ服务类型', dataIndex: 'serviceTypeId', key: 'serviceTypeId', align: 'center', width: 150, |
|
|
|
|
render: (serviceTypeId:any) => { |
|
|
|
|
const serviceType = serviceTypeDict?.find((item: { dictKey: string | number; dictValue: string }) => String(item.dictKey) === serviceTypeId); |
|
|
|
|
return serviceType? serviceType.dictValue : serviceTypeId; |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
{ title: '题型', dataIndex: 'questionTypes', key: 'questionTypes', align: 'center', width: 80, |
|
|
|
|
render: (questionTypes:any) => { |
|
|
|
|
if (questionTypes === '1') { |
|
|
|
|
return '单选题'; |
|
|
|
|
} else if (questionTypes === '2') { |
|
|
|
|
return '多选题'; |
|
|
|
|
} |
|
|
|
|
return questionTypes;} |
|
|
|
|
}, |
|
|
|
|
{ title: '题干', dataIndex: 'questionContent', key: 'questionContent', align: 'center', width: 450 }, |
|
|
|
|
{ title: '答案', dataIndex: 'answer', key: 'answer', align: 'center', width: 120 }, |
|
|
|
|
{ title: '操作', dataIndex: 'operation', align: 'center', width: 120, |
|
|
|
|
render: (_:number, record:number) => ( |
|
|
|
|
<Button type="link" danger onClick={() => this.handleDeleteQuestion(record)}>删除</Button> |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
]; |
|
|
|
|
return ( |
|
|
|
|
<div className="container"> |
|
|
|
|
<Form ref={this.formRef}> |
|
|
|
@ -148,7 +308,6 @@ class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
<Form.Item |
|
|
|
|
label="考试时长:" |
|
|
|
|
name="examDuration" |
|
|
|
|
|
|
|
|
|
rules={[{ required: true, message: '请输入考试时长' }]} |
|
|
|
|
> |
|
|
|
|
<Input type="number" style={{ textAlign: 'right' }} addonAfter="分钟" placeholder="请输入考试时长" min={1} /> |
|
|
|
@ -168,11 +327,18 @@ class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
<Button type="link" onClick={this.handleRandomGenerate}> |
|
|
|
|
随机生成 |
|
|
|
|
</Button> |
|
|
|
|
<Button type="link">手动选题</Button> |
|
|
|
|
<Button type="link" onClick={this.handleOpenManualSelectionModal}> |
|
|
|
|
手动选题 |
|
|
|
|
</Button> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
{questions.map((question, index) => ( |
|
|
|
|
<div style={{border: '1px solid #e8e8e8', padding: 10, marginBottom: 10,backgroundColor: 'lightblue'}} |
|
|
|
|
<div |
|
|
|
|
style={{ |
|
|
|
|
border: '1px solid #e8e8e8', |
|
|
|
|
padding: 10, |
|
|
|
|
marginBottom: 10 |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
<span style={{ fontWeight: 'bold' }}>{index + 1}. {question.questionContent}</span> |
|
|
|
|
<Form.Item> |
|
|
|
@ -215,6 +381,94 @@ class ExamPaperAdd extends Component<any, States> { |
|
|
|
|
</Button> |
|
|
|
|
</div> |
|
|
|
|
</Form> |
|
|
|
|
<Modal |
|
|
|
|
title="选择试题" |
|
|
|
|
open={isModalVisible} |
|
|
|
|
maskClosable={false} |
|
|
|
|
onCancel={this.handleCloseManualSelectionModal} |
|
|
|
|
footer={[ |
|
|
|
|
<Button key="cancel" onClick={this.handleCloseManualSelectionModal}> |
|
|
|
|
取消 |
|
|
|
|
</Button>, |
|
|
|
|
<Button key="ok" type="primary" onClick={this.handleCloseManualSelectionModal}> |
|
|
|
|
确定 |
|
|
|
|
</Button> |
|
|
|
|
]} |
|
|
|
|
width={1100} |
|
|
|
|
style={{ top: 20 }} |
|
|
|
|
> |
|
|
|
|
<div> |
|
|
|
|
<h3 style={{ fontWeight: 'bold' }}>已选列表</h3> |
|
|
|
|
<div style={{ height: '500', overflowY: 'auto' }}> |
|
|
|
|
<Table |
|
|
|
|
dataSource={questions} |
|
|
|
|
columns={columns} |
|
|
|
|
pagination={{ |
|
|
|
|
showQuickJumper: true, |
|
|
|
|
pageSize: 5 |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div> |
|
|
|
|
<h3 style={{ fontWeight: 'bold' }}>试题选择</h3> |
|
|
|
|
<Form |
|
|
|
|
className="filter" |
|
|
|
|
layout="inline" |
|
|
|
|
ref={this.formRefSub} |
|
|
|
|
> |
|
|
|
|
<Form.Item |
|
|
|
|
label="AQ服务类型:" |
|
|
|
|
name="serviceTypeId" |
|
|
|
|
> |
|
|
|
|
<Select placeholder="请选择AQ服务类型" |
|
|
|
|
style={{ width: 240 }} |
|
|
|
|
allowClear> |
|
|
|
|
{ |
|
|
|
|
serviceTypeDict && serviceTypeDict.length > 0? |
|
|
|
|
(() => { |
|
|
|
|
let rows = []; |
|
|
|
|
for (let i = 0; i < serviceTypeDict.length; i++) { |
|
|
|
|
const item = serviceTypeDict[i]; |
|
|
|
|
rows.push( |
|
|
|
|
<Option value={item.dictKey}>{item.dictValue}</Option> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
return rows; |
|
|
|
|
})() |
|
|
|
|
: |
|
|
|
|
<Option disabled>暂无数据</Option> |
|
|
|
|
} |
|
|
|
|
</Select> |
|
|
|
|
</Form.Item> |
|
|
|
|
<Form.Item |
|
|
|
|
label="题干条件:" |
|
|
|
|
name="questionContent" |
|
|
|
|
> |
|
|
|
|
<Input placeholder="请输入题干条件" style={{ width: 500 }}/> |
|
|
|
|
</Form.Item> |
|
|
|
|
<Form.Item> |
|
|
|
|
<Button type="primary" onClick={this.handleQuery}>查询</Button> |
|
|
|
|
</Form.Item> |
|
|
|
|
</Form> |
|
|
|
|
</div> |
|
|
|
|
<Table |
|
|
|
|
dataSource={questionSelectList} |
|
|
|
|
columns={columns} |
|
|
|
|
rowSelection={{ |
|
|
|
|
onChange: this.handleSelectQuestion |
|
|
|
|
}} |
|
|
|
|
pagination={{ |
|
|
|
|
total: this.state.total, |
|
|
|
|
current: this.state.page, |
|
|
|
|
showQuickJumper: true, |
|
|
|
|
showSizeChanger: true, |
|
|
|
|
showTotal: (total) => `共 ${total} 条`, |
|
|
|
|
onShowSizeChange: selectChange, |
|
|
|
|
onChange: changePage |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
</Modal> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|