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"; // @ts-ignore import { saveAs } from "file-saver"; import TextArea from "antd/es/input/TextArea"; const { Option } = Select; interface States { industryDict: any; serviceTypeDict: any; formIds: string[]; questionTypesMap: { [formId: string]: string }; } class QuestionAdd extends Component { formRef: any; fileInputRef: any; constructor(props: any) { super(props); this.formRef = React.createRef(); this.fileInputRef = React.createRef(); this.state = { industryDict: [], serviceTypeDict: [], formIds: ["form_0"], questionTypesMap: { "form_0": "1" } }; const formValues = {}; formValues[`questionTypes_form_0`] = '1'; this.componentDidMount = () => { this.formRef.current?.setFieldsValue(formValues); this.handleFindDict(); }; } componentDidMount() { } // 字典 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 = (formId: string, value: string) => { const { questionTypesMap } = this.state; const formValues = {}; formValues[`questionTypes_${formId}`] = value; this.formRef.current.setFieldsValue(formValues); this.setState((prevState) => ({ questionTypesMap: { ...prevState.questionTypesMap, [formId]: value } })); }; // 新增试题 handleAddNewQuestion = () => { const { formIds } = this.state; const lastId = formIds[formIds.length - 1]; const lastNumber = parseInt(lastId.split('_')[1], 10); const newId = `form_${lastNumber + 1}`; const formValues = { [`questionTypes_${newId}`]: "1" }; this.formRef.current.setFieldsValue(formValues); this.setState((prevState) => ({ formIds: [...prevState.formIds, newId], questionTypesMap: { ...prevState.questionTypesMap, [newId]: "1" } })); }; // 删除试题 handleDeleteQuestion = (formId: string) => { const formValues = {}; const fields = [ "questionTypes", "industryId", "serviceTypeId", "questionContent", "optionA", "optionB", "optionC", "optionD", "answer" ]; fields.forEach((field) => { formValues[`${field}_${formId}`] = undefined; }); this.formRef.current.setFieldsValue(formValues); const { questionTypesMap } = this.state; const newQuestionTypesMap = { ...questionTypesMap }; delete newQuestionTypesMap[formId]; this.setState((prevState) => ({ formIds: prevState.formIds.filter((id) => id!== formId), questionTypesMap: newQuestionTypesMap })); }; // 表单提交 handleSubmit = () => { this.formRef.current.validateFields().then((values: any) => { const questions: any = []; const { formIds } = this.state; formIds.forEach((formId) => { let answer = values[`answer_${formId}`]; if (Array.isArray(answer)) { answer.sort(); answer = answer.join(","); } questions.push({ questionTypes: values[`questionTypes_${formId}`], industryId: values[`industryId_${formId}`], serviceTypeId: values[`serviceTypeId_${formId}`], questionContent: values[`questionContent_${formId}`], optionA: values[`optionA_${formId}`], optionB: values[`optionB_${formId}`], optionC: values[`optionC_${formId}`], optionD: values[`optionD_${formId}`], answer: answer }); }); 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) => { 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 = {}; const formIds: string[] = []; const questionTypesMap = {}; if (rows.length === 0) { message.warn('导入的文件中没有有效数据行'); return; } rows.forEach((row: any, index) => { const formId = `form_${index}`; formIds.push(formId); formValues[`questionTypes_${formId}`] = String(row[0]); formValues[`industryId_${formId}`] = String(row[1]); formValues[`serviceTypeId_${formId}`] = String(row[2]); formValues[`questionContent_${formId}`] = String(row[3]); formValues[`optionA_${formId}`] = String(row[4]); formValues[`optionB_${formId}`] = String(row[5]); formValues[`optionC_${formId}`] = String(row[6]); formValues[`optionD_${formId}`] = String(row[7]); formValues[`answer_${formId}`] = String(row[8]); questionTypesMap[formId] = String(row[0]); }); this.setState({ formIds, questionTypesMap }, () => { 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, formIds, questionTypesMap } = this.state; const handleListQuestion = () => { this.props.history.push("/questionList"); }; return (
{formIds.map((formId, index) => (
this.handleQuestionTypeChange(formId, e.target.value)} > 单选题 多选题 {index > 0 && ( )}
{questionTypesMap[formId] === "1"? (
A B
C D
) : (
A B
C D
)}
))}
); } } export default QuestionAdd;