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.
346 lines
17 KiB
346 lines
17 KiB
import React, { Component } from'react'; |
|
import { Form, Input, Button, Radio, Checkbox, Select, message } from 'antd'; |
|
import { dictionary } from "api/dict/index"; |
|
import { addQuestion, findIndustry } from 'api/question'; |
|
import * as XLSX from 'xlsx'; |
|
import { saveAs } from 'file-saver'; |
|
|
|
const { Option} = Select; |
|
|
|
interface States { |
|
industryDict: any; |
|
serviceTypeDict: any; |
|
formCount: number; |
|
} |
|
|
|
class QuestionAdd extends Component<any, States> { |
|
formRef: any; |
|
fileInputRef: any; |
|
constructor(props: any) { |
|
super(props); |
|
this.formRef = React.createRef(); |
|
this.fileInputRef = React.createRef(); |
|
this.state = { |
|
industryDict: [], |
|
serviceTypeDict: [], |
|
formCount: 1 |
|
}; |
|
} |
|
|
|
componentDidMount() { |
|
this.handleFindDict(); |
|
} |
|
|
|
// 字典 |
|
handleFindDict() { |
|
// 监管行业 |
|
findIndustry() |
|
.then((res: any) => { |
|
if (res.data) { |
|
this.setState({ industryDict: res.data }); |
|
} |
|
}) |
|
.catch(() => { |
|
message.error('获取监管行业字典数据失败,请稍后重试'); |
|
}); |
|
// AQ服务类型 |
|
dictionary('serviceTypeDict') |
|
.then((res) => { |
|
if (res.data) { |
|
this.setState({ serviceTypeDict: res.data }); |
|
} |
|
}) |
|
.catch(() => { |
|
message.error('获取AQ服务类型字典数据失败,请稍后重试'); |
|
}); |
|
} |
|
|
|
// 题型切换 |
|
handleQuestionTypeChange = (index: number, value: string) => { |
|
const formValues = {}; |
|
formValues[`questionTypes_${index}`] = value; |
|
formValues[`answer_${index}`] = ''; |
|
this.formRef.current.setFieldsValue(formValues); |
|
}; |
|
|
|
// 新增试题 |
|
handleAddNewQuestion = () => { |
|
this.setState((prevState) => ({ |
|
formCount: prevState.formCount + 1, |
|
})); |
|
}; |
|
|
|
// 删除试题 |
|
handleDeleteQuestion = (index: number) => { |
|
this.setState((prevState) => ({ |
|
formCount: prevState.formCount - 1, |
|
})); |
|
}; |
|
|
|
// 处理表单提交 |
|
handleSubmit = () => { |
|
this.formRef.current.validateFields().then((values: any) => { |
|
const questions = []; |
|
for (let i = 0; i < this.state.formCount; i++) { |
|
const question = { |
|
questionTypes: values[`questionTypes_${i}`], |
|
industryId: values[`industryId_${i}`], |
|
serviceTypeId: values[`serviceTypeId_${i}`], |
|
questionContent: values[`questionContent_${i}`], |
|
optionA: values[`optionA_${i}`], |
|
optionB: values[`optionB_${i}`], |
|
optionC: values[`optionC_${i}`], |
|
optionD: values[`optionD_${i}`], |
|
answer: values[`answer_${i}`], |
|
}; |
|
questions.push(question); |
|
} |
|
|
|
addQuestion(questions).then((res) => { |
|
const success = res['success']; |
|
if (success) { |
|
message.success(`新增成功`); |
|
this.props.history.push('/questionList'); |
|
} else { |
|
message.error('新增试题失败,请稍后重试'); |
|
} |
|
}).catch(() => { |
|
message.error('新增试题时发生错误,请检查'); |
|
}); |
|
}); |
|
}; |
|
|
|
// 下载模板 |
|
handleDownloadTemplate = () => { |
|
const headers = ['题型', '监管行业', 'AQ服务类型', '题干', '选项A', '选项B', '选项C', '选项D', '答案']; |
|
const ws = XLSX.utils.aoa_to_sheet([headers]); |
|
const wb = XLSX.utils.book_new(); |
|
XLSX.utils.book_append_sheet(wb, ws, '试题模板'); |
|
const wbOut = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }); |
|
saveAs(new Blob([wbOut], { type: 'application/octet-stream' }), '试题模板.xlsx'); |
|
}; |
|
|
|
// 一键导入 |
|
handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { |
|
const file = e.target.files?.[0]; |
|
if (file) { |
|
const reader = new FileReader(); |
|
reader.onload = (event) => { |
|
const data = new Uint8Array(event.target?.result as ArrayBuffer); |
|
const workbook = XLSX.read(data, { type: 'array' }); |
|
const firstSheetName = workbook.SheetNames[0]; |
|
const worksheet = workbook.Sheets[firstSheetName]; |
|
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); |
|
const rows = jsonData.slice(1); |
|
const formValues = {}; |
|
rows.forEach((row: any, index) => { |
|
formValues[`questionTypes_${index}`] = String(row[0]); |
|
formValues[`industryId_${index}`] = String(row[1]); |
|
formValues[`serviceTypeId_${index}`] = String(row[2]); |
|
formValues[`questionContent_${index}`] = String(row[3]); |
|
formValues[`optionA_${index}`] = String(row[4]); |
|
formValues[`optionB_${index}`] = String(row[5]); |
|
formValues[`optionC_${index}`] = String(row[6]); |
|
formValues[`optionD_${index}`] = String(row[7]); |
|
formValues[`answer_${index}`] = String(row[8]); |
|
}); |
|
this.setState({ formCount: rows.length }, () => { |
|
this.formRef.current.setFieldsValue(formValues); |
|
}); |
|
}; |
|
reader.readAsArrayBuffer(file); |
|
|
|
const input = this.fileInputRef.current; |
|
if (input) { |
|
input.value = null; |
|
} |
|
} |
|
}; |
|
|
|
// 文件 |
|
handleImportClick = () => { |
|
this.fileInputRef.current?.click(); |
|
}; |
|
|
|
render() { |
|
const { industryDict, serviceTypeDict, formCount } = this.state; |
|
const handleListQuestion = () => { |
|
this.props.history.push('/questionList'); |
|
}; |
|
return ( |
|
<div className="container"> |
|
<div style={{textAlign: 'right'}}> |
|
<Button type="default" style={{marginRight: 10}} onClick={this.handleDownloadTemplate}>下载模版</Button> |
|
<Button type="default" onClick={this.handleImportClick}>一键导入</Button> |
|
<input |
|
type="file" |
|
ref={this.fileInputRef} |
|
style={{display: 'none'}} |
|
accept=".xlsx,.xls" |
|
onChange={this.handleFileChange} |
|
/> |
|
</div> |
|
<Form ref={this.formRef} layout="inline"> |
|
{Array.from({ length: formCount }, (_, index) => ( |
|
<div key={index} style={{marginBottom: 30}}> |
|
<div style={{display: 'flex'}}> |
|
<Form.Item name={`questionTypes_${index}`}> |
|
<Radio.Group |
|
onChange={(e) => this.handleQuestionTypeChange(index, e.target.value)}> |
|
<Radio.Button value="1">单选题</Radio.Button> |
|
<Radio.Button value="2">多选题</Radio.Button> |
|
</Radio.Group> |
|
</Form.Item> |
|
<Form.Item |
|
label="监管行业:" |
|
name={`industryId_${index}`} |
|
rules={[{required: true, message: '请选择监管行业'}]} |
|
> |
|
<Select placeholder="请选择监管行业" |
|
style={{width: 240}} |
|
allowClear> |
|
{ |
|
industryDict && industryDict.length > 0 ? |
|
(() => { |
|
let rows = []; |
|
for (let i = 0; i < industryDict.length; i++) { |
|
const item = industryDict[i]; |
|
rows.push( |
|
<Option value={item.industryId}>{item.industryName}</Option> |
|
); |
|
} |
|
return rows; |
|
})() |
|
: |
|
<Option disabled>暂无数据</Option> |
|
} |
|
</Select> |
|
</Form.Item> |
|
<Form.Item |
|
label="AQ服务类型:" |
|
name={`serviceTypeId_${index}`} |
|
rules={[{required: true, message: '请选择AQ服务类型'}]} |
|
> |
|
<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={String(item.dictKey)}>{item.dictValue}</Option> |
|
); |
|
} |
|
return rows; |
|
})() |
|
: |
|
<Option disabled>暂无数据</Option> |
|
} |
|
</Select> |
|
</Form.Item> |
|
<Form.Item> |
|
{index > 0 && ( |
|
<Button type="link" onClick={() => this.handleDeleteQuestion(index)}>X</Button>)} |
|
</Form.Item> |
|
</div> |
|
<div style={{display: 'flex'}}> |
|
<Form.Item |
|
label="题干:" |
|
name={`questionContent_${index}`} |
|
style={{marginTop: 10}} |
|
rules={[{required: true, message: '请输入题干内容'}]} |
|
> |
|
<Input.TextArea |
|
placeholder="请输入题干内容" |
|
style={{width: 1100, height: 60}} |
|
/> |
|
</Form.Item> |
|
</div> |
|
<div style={{marginTop: 10, marginLeft: 40}}> |
|
<div style={{display: 'flex'}}> |
|
<Form.Item |
|
name={`answer_${index}`} |
|
rules={[{ required: true, message: '请选择答案' }]}> |
|
{this.formRef.current && this.formRef.current.getFieldValue(`questionTypes_${index}`) === '1' ? ( |
|
<Radio.Group> |
|
<div style={{display: 'flex'}}> |
|
<Radio value="A">A</Radio> |
|
<Form.Item name={`optionA_${index}`} rules={[{required: true, message: '请输入答案A'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
<Radio value="B">B</Radio> |
|
<Form.Item name={`optionB_${index}`} rules={[{required: true, message: '请输入答案B'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
</div> |
|
<div style={{display: 'flex', marginTop: 10}}> |
|
<Radio value="C">C</Radio> |
|
<Form.Item name={`optionC_${index}`} rules={[{required: true, message: '请输入答案C'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
<Radio value="D">D</Radio> |
|
<Form.Item name={`optionD_${index}`} rules={[{required: true, message: '请输入答案D'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
</div> |
|
</Radio.Group> |
|
) : ( |
|
<Checkbox.Group> |
|
<div style={{display: 'flex'}}> |
|
<Checkbox value="A">A</Checkbox> |
|
<Form.Item name={`optionA_${index}`} rules={[{required: true, message: '请输入答案A'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
<Checkbox value="B">B</Checkbox> |
|
<Form.Item name={`optionB_${index}`} rules={[{required: true, message: '请输入答案B'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
</div> |
|
<div style={{display: 'flex', marginTop: 10}}> |
|
<Checkbox value="C">C</Checkbox> |
|
<Form.Item name={`optionC_${index}`} rules={[{required: true, message: '请输入答案C'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
<Checkbox value="D">D</Checkbox> |
|
<Form.Item name={`optionD_${index}`} rules={[{required: true, message: '请输入答案D'}]}> |
|
<Input placeholder="请输入答案" style={{width: 500}}/> |
|
</Form.Item> |
|
</div> |
|
</Checkbox.Group> |
|
)} |
|
</Form.Item> |
|
</div> |
|
</div> |
|
</div> |
|
))} |
|
</Form> |
|
<div style={{textAlign: 'right'}}> |
|
<Button type="default" onClick={this.handleAddNewQuestion}> |
|
新增试题 |
|
</Button> |
|
</div> |
|
<div style={{ |
|
textAlign: 'right', |
|
position: 'fixed', |
|
bottom: 10, |
|
right: 10, |
|
width: '100%', |
|
zIndex: 1000 |
|
}}> |
|
<Button type="default" htmlType="button" onClick={handleListQuestion} style={{marginRight: 10}}> |
|
取消 |
|
</Button> |
|
<Button type="primary" htmlType="submit" onClick={this.handleSubmit}> |
|
确定添加 |
|
</Button> |
|
</div> |
|
</div> |
|
); |
|
} |
|
} |
|
|
|
export default QuestionAdd; |