题库管理代码提交

main
hujunpeng 4 months ago
parent 7ecca9ec82
commit daf10d7133
  1. 82
      packages/examination/src/api/question/index.tsx
  2. 10
      packages/examination/src/components/contentMain/index.js
  3. 505
      packages/examination/src/views/question/questionAdd.tsx
  4. 393
      packages/examination/src/views/question/questionList.tsx
  5. 403
      packages/examination/src/views/question/questionUp.tsx
  6. 22
      packages/examination/src/views/slider/menu.tsx

@ -0,0 +1,82 @@
import axios from '../axios';
/*
*
*/
export function getList(num: number, page: number, obj:object){
const rData = {
num:num,
page:page,
industryId:obj['industryId'],
serviceTypeId:obj['serviceTypeId'],
questionContent:obj['questionContent']
};
return axios({
url: "/ex/question/list",
method: 'post',
data: rData
})
}
/*
* ()
*/
export function deleteQuestion(id: number) {
return axios({
url: '/ex/question/delete?id=' + id,
method: 'get'
});
}
/*
*
*/
export function deleteQuestionList(ids: any) {
return axios({
url: '/ex/question/deleteList',
method: 'post',
data: ids
});
}
/*
*
*/
export function add(questionData: object) {
return axios({
url: "/ex/question/add",
method: 'post',
data: questionData
});
}
/*
*
*/
export function update(questionData: object) {
return axios({
url: "/ex/question/update",
method: 'post',
data: questionData
});
}
/*
*
*/
export function findIndustry() {
return axios({
url: '/ex/question/findIndustry',
method: 'get'
})
}
/*
*
*/
export function getDetail(id: string|null) {
return axios({
url: '/ex/question/getDetail?id=' + id,
method: 'get'
});
}

@ -28,6 +28,12 @@ import Customer from 'views/statistical/list';
import CustomerDetail from 'views/statistical/detail';
import ExamDetail from "../../views/exam-online/exam-detail";
import QuestionList from 'views/question/questionList';
import QuestionAdd from 'views/question/questionAdd';
import QuestionUp from 'views/question/questionUp';
import ExamPaperList from 'views/examPaper/examPaperList';
class ContentMain extends Component {
render() {
return (
@ -48,6 +54,10 @@ class ContentMain extends Component {
<Route exact path='/exam-add' component={ ExamAdd }/>
<Route exact path='/exam-edit' component={ ExamEdit }/>
<Route exact path='/exam-detail' component={ ExamDetail }/>
<Route exact path='/questionList' component={ QuestionList }/>
<Route exact path='/questionAdd' component={ QuestionAdd }/>
<Route exact path='/questionUp' component={ QuestionUp }/>
<Route exact path='/examPaperList' component={ ExamPaperList }/>
<Redirect exact from='/' to='/home'/>
</Switch>
</div>

@ -0,0 +1,505 @@
import React, { Component } from'react';
import { Form, Input, Button, Radio, Checkbox, Select, message } from 'antd';
import { dictionary } from "api/dict/index";
import { add, findIndustry } from 'api/question';
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
const { Option } = Select;
// 定义单个试题的状态接口
interface QuestionState {
questionTypes: string;
industryId: string | null;
serviceTypeId: string | null;
questionContent: string;
answerOptions: { [key: string]: string };
answer: string | null;
}
// 定义组件的状态接口
interface States {
industryDict: any;
serviceTypeDict: any;
isLoading: boolean;
questions: QuestionState[];
}
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: undefined,
serviceTypeDict: undefined,
isLoading: false,
questions: [
{
questionTypes: '1',
questionContent: '',
answerOptions: { A: '', B: '', C: '', D: ''},
answer: null,
industryId: null,
serviceTypeId: null
}
]
};
}
// 初期
componentDidMount() {
this.getDict();
this.findIndustry();
}
// 字典
getDict() {
// 服务类型
dictionary('serviceTypeDict').then((res) => {
if (res.data) {
this.setState({ serviceTypeDict: res.data });
}
});
}
// 行业
findIndustry() {
// 监管行业
findIndustry().then((res) => {
if (res.data) {
this.setState({ industryDict: res.data });
}
});
}
// 题型
handleQuestionTypeChange = (index: number, value: string) => {
this.setState((prevState) => {
const questions = [...prevState.questions];
questions[index].questionTypes = value;
questions[index].answer = null;
return {
questions
};
});
};
// 单选框
handleRadioChange = (index: number, value: string) => {
this.setState((prevState) => {
const questions = [...prevState.questions];
questions[index].answer = value;
return {
questions
};
});
};
// 多选框
handleCheckboxChange = (index: number, type: string, values: (string | number | boolean)[] | null) => {
this.setState((prevState) => {
const questions = [...prevState.questions];
const currentAnswer = questions[index].answer || '';
const currentSelectedArray = currentAnswer? currentAnswer.split(',') : [];
if (!values || values.length === 0) {
const newSelectedArray = currentSelectedArray.filter(val => val!== type);
newSelectedArray.sort();
questions[index].answer = newSelectedArray.join(',');
} else {
const stringValues = values.map((val) => String(val));
const newSelectedArray = Array.from(new Set([...currentSelectedArray, ...stringValues]));
newSelectedArray.sort();
questions[index].answer = newSelectedArray.join(',');
}
return {
questions
};
});
};
// 答案
handleAnswerOptionChange = (index: number, option: string, value: string) => {
this.setState((prevState) => {
const questions = [...prevState.questions];
questions[index].answerOptions[option] = value;
return {
questions
};
});
};
// 新增试题
addNewQuestion = () => {
this.setState((prevState) => ({
questions: [
...prevState.questions,
{
questionTypes: '1',
questionContent: '',
answerOptions: { A: '', B: '', C: '', D: ''},
answerDisabled: false,
answer: null,
industryId: null,
serviceTypeId: null
}
]
}));
};
// 删除试题
deleteQuestion = (index: number) => {
this.setState((prevState) => {
const questions = [...prevState.questions];
questions.splice(index, 1);
return {
questions
};
});
};
// 处理表单提交
handleSubmit = () => {
this.setState({ isLoading: true });
this.formRef.current.validateFields().then((values: Record<string, any>) => {
const questions = this.state.questions.map((question, index) => {
const industryId = values[`industryId_${index}`];
const serviceTypeId = values[`serviceTypeId_${index}`];
const questionContent = values[`questionContent_${index}`];
return {
...question,
industryId,
serviceTypeId,
questionContent
};
});
add(questions).then((res) => {
const count = res.data;
if (count>0) {
message.success(`成功新增 ${count} 条试题`);
this.setState({ isLoading: false });
this.props.history.push('/questionList');
} else {
message.error('新增试题失败,请稍后重试');
this.setState({ isLoading: false });
}
}).catch(() => {
message.error('新增试题时发生错误,请检查');
this.setState({ isLoading: false });
});
}).catch(() => {
this.setState({ isLoading: false });
});
};
// 下载模板
downloadTemplate = () => {
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 newQuestions = rows.map((row: any) => {
const question: QuestionState = {
questionTypes: String(row[0]),
industryId: String(row[1]),
serviceTypeId: String(row[2]).trim().toLowerCase(),
questionContent: String(row[3]),
answerOptions: {
A: String(row[4]),
B: String(row[5]),
C: String(row[6]),
D: String(row[7])
},
answer: String(row[8])
};
return question;
});
this.setState({ questions: newQuestions }, () => {
const formValues = {};
newQuestions.forEach((question, index) => {
formValues[`questionContent_${index}`] = question.questionContent;
formValues[`industryId_${index}`] = question.industryId;
formValues[`serviceTypeId_${index}`] = question.serviceTypeId;
formValues[`answer_${index}`] = question.answer;
formValues[`answerOption_A_${index}`] = question.answerOptions.A;
formValues[`answerOption_B_${index}`] = question.answerOptions.B;
formValues[`answerOption_C_${index}`] = question.answerOptions.C;
formValues[`answerOption_D_${index}`] = question.answerOptions.D;
});
this.formRef.current.setFieldsValue(formValues);
});
};
reader.readAsArrayBuffer(file);
}
};
// 文件
handleImportClick = () => {
this.fileInputRef.current?.click();
};
render() {
const { industryDict, serviceTypeDict, questions, isLoading } = this.state;
// 使用 this.props.history 进行页面跳转
const handleListQuestion = () => {
this.props.history.push('/questionList');
};
return (
<div className="container">
<div style={{ textAlign: 'right'}}>
<Button type="default" style={{ marginRight: 10 }} onClick={this.downloadTemplate}></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"
className="ant-bg-light"
>
{questions.map((question, index) => (
<div key={index} style={{ marginBottom: 30 }}>
<div style={{ display: 'flex' }}>
<Form.Item>
<Radio.Group
value={question.questionTypes}
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}`}
>
<Select placeholder="请选择监管行业"
style={{ width: 240 }}
allowClear
value={question.industryId}>
{
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}`}
>
<Select placeholder="请选择AQ服务类型"
style={{ width: 240 }}
allowClear
value={question.serviceTypeId}>
{
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).trim().toLowerCase()}>{item.dictValue}</Option>
);
}
return rows;
})()
:
<Option disabled></Option>
}
</Select>
</Form.Item>
<Form.Item>
{index > 0 && (<Button type="link" onClick={() => this.deleteQuestion(index)}>X</Button>)}
</Form.Item>
</div>
<Form.Item
label="题干:"
name={`questionContent_${index}`}
style={{marginTop: 10 }}
>
<Input.TextArea
placeholder="请输入题干内容"
value={question.questionContent}
style={{ width: 1100, height: 60 }}
/>
</Form.Item>
<Form.Item style={{marginTop: 10, marginLeft: 40}}>
<div>
<div style={{ display: 'flex' }}>
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange(index, e.target.value)}
>
<Radio value="A">A</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.A}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange(index, 'A', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange(index,'A', values,)}>
<Checkbox value="A">A</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.A}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange(index, 'A', e.target.value)}
/>
</Checkbox.Group>
)}
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange(index, e.target.value)}
style={{ marginLeft: 20 }}
>
<Radio value="B">B</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.B}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange(index, 'B', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
style={{ marginLeft: 20 }}
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange(index,'B',values)}>
<Checkbox value="B">B</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.B}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange(index, 'B', e.target.value)}
/>
</Checkbox.Group>
)}
</div>
<div style={{ display: 'flex', marginTop: 10 }}>
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange(index, e.target.value)}
>
<Radio value="C">C</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.C}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange(index, 'C', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange(index,'C', values)}>
<Checkbox value="C">C</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.C}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange(index, 'C', e.target.value)}
/>
</Checkbox.Group>
)}
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange(index, e.target.value)}
style={{ marginLeft: 20 }}
>
<Radio value="D">D</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.D}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange(index, 'D', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
style={{ marginLeft: 20 }}
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange(index,'D',values)}>
<Checkbox value="D">D</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.D}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange(index, 'D', e.target.value)}
/>
</Checkbox.Group>
)}
</div>
</div>
</Form.Item>
</div>
))}
</Form>
<div style={{ textAlign: 'right'}}>
<Button type="default" onClick={this.addNewQuestion}>
</Button>
</div>
<div style={{
textAlign: 'right',
position: 'fixed',
bottom: 10,
right: 10,
width: '100%',
backgroundColor: 'white',
zIndex: 1000
}}>
<Button type="default" htmlType="button" onClick={handleListQuestion} style={{ marginRight: 10 }}>
</Button>
<Button type="primary" htmlType="submit" loading={isLoading} onClick={this.handleSubmit}>
</Button>
</div>
</div>
);
}
}
export default QuestionAdd;

@ -0,0 +1,393 @@
import React, { Component } from'react';
import {Form, Input, Button, Table, Select, message, Modal} from 'antd';
import { TableRowSelection } from 'antd/lib/table/interface';
import {deleteQuestion, deleteQuestionList, findIndustry, getList} from 'api/question';
import { dictionary } from "api/dict/index";
const { Option } = Select;
interface States {
num: number;
page: number;
listQuery: {
industryId: string | undefined;
serviceTypeId: string | undefined;
questionContent: string | undefined;
};
list: any[];
total: number;
loading: boolean;
currentRow: object;
title: string;
modalText: string;
modalWidth: number | string;
industryDict: any;
serviceTypeDict: any;
selectedRowKeys: number[];
isAllSelected: boolean;
}
class QuestionList extends Component<any, States> {
formRef: any;
constructor(props: any) {
super(props);
this.formRef = React.createRef();
this.state = {
num: 10,
page: 1,
listQuery: {
industryId: undefined,
serviceTypeId: undefined,
questionContent: undefined
},
list: [],
total: 0,
loading: false,
currentRow: {
id: 0,
status: 0
},
title: '',
modalText: '',
modalWidth: 0,
industryDict: undefined,
serviceTypeDict: undefined,
selectedRowKeys: [],
isAllSelected: false,
};
}
componentDidMount() {
this.findDict();
this.findIndustry();
this.getList();
}
// 监管行业
findIndustry() {
findIndustry().then((res: any) => {
if (res.data) {
this.setState({ industryDict: res.data });
}
});
}
// AQ服务类型
findDict() {
dictionary('serviceTypeDict').then((res) => {
if (res.data) {
this.setState({ serviceTypeDict: res.data });
}
});
}
// 查询
getList() {
this.setState({ loading: true });
const { num, page, listQuery } = this.state;
getList(num, page, listQuery).then((res) => {
this.setState({
loading: false,
list: res.data.data,
total: res.data.total,
selectedRowKeys: [],
isAllSelected: false,
});
this.setState({ loading: false });
}).catch(() => {
this.setState({ loading: false });
});
}
// 重置
handleReset = () => {
if (this.formRef.current) {
// 重置表单字段
this.formRef.current.resetFields();
// 重置 listQuery 状态
this.setState({
listQuery: {
industryId: undefined,
serviceTypeId: undefined,
questionContent: undefined
},
selectedRowKeys: [],
isAllSelected: false,
});
}
};
// 删除(明细)
deleteSingle = (id: number) => {
Modal.confirm({
title: '确认删除',
content: '你确定要删除这个问题吗?',
onOk: () => {
deleteQuestion(id).then((res) => {
const isSuccess = res.data;
if (isSuccess) {
message.success('删除成功');
this.getList();
} else {
message.error('删除失败,请稍后重试');
}
}).catch(() => {
message.error('删除时发生错误,请检查');
});
},
onCancel: () => {
},
});
};
// 删除
deleteMultiple = () => {
const { selectedRowKeys } = this.state;
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的问题');
return;
}
Modal.confirm({
title: '确认删除',
content: '你确定要删除这些选中的问题吗?',
onOk: () => {
deleteQuestionList(selectedRowKeys)
.then((res) => {
const isSuccess = res.data;
if (isSuccess) {
message.success('删除成功');
this.getList();
} else {
message.error('删除失败,请稍后重试');
}
})
.catch(() => {
message.error('删除时发生错误,请检查');
});
},
onCancel: () => {
},
});
};
// 多选
onSelectChange = (selectedRowKeys: React.Key[]) => {
this.setState({
selectedRowKeys: selectedRowKeys as number[],
isAllSelected: selectedRowKeys.length === this.state.list.length
});
};
// 单选
onSelect = (record: any, selected: boolean) => {
if (selected) {
// 单选时只保留当前选中行
this.setState({
selectedRowKeys: [record.id],
isAllSelected: false
});
} else {
// 取消选中时清空选中行
this.setState({
selectedRowKeys: [],
isAllSelected: false
});
}
};
render() {
const onFinish = (values: object) => {
const _listQuery = { ...this.state.listQuery, ...values };
this.setState({ listQuery: _listQuery });
this.getList();
};
const { industryDict, serviceTypeDict, selectedRowKeys } = this.state;
// 行选择
const rowSelection: TableRowSelection<any> = {
selectedRowKeys,
onChange: this.onSelectChange,
onSelect: this.onSelect,
getCheckboxProps: (record) => ({
checked: selectedRowKeys.includes(record.id),
indeterminate: selectedRowKeys.includes(record.id),
})
};
// 页面跳转
const handleAddQuestion = () => {
this.props.history.push('/questionAdd');
};
const columns: any = [
{ title: '序号', dataIndex: 'index', key: 'index', align: 'center', width: 60,
render: (_: number, __: number, index: number) => {
const { page, num } = this.state;
return (page - 1) * num + index + 1;
}
},
{ title: '监管行业', dataIndex: 'industryId', key: 'industryId', align: 'center', width: 150,
render: (industryId:any) => {
const industry = industryDict?.find((item: { industryId: string | number; industryName: string }) => String(item.industryId) === String(industryId));
return industry? industry.industryName : industryId;
}
},
{ 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) === String(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: '题目ID', dataIndex: 'id', key: 'id', width: 120},
{ title: '操作', key: 'operation', align: 'center', fixed: 'right', width: 120,
render: (record: any) => [
<span className='mr10 link' onClick={() => {
this.setState({title: '删除', modalWidth: '85%'})
this.deleteSingle(record.id);
}}></span>,
<span className="mr10 link" onClick={() => {
this.setState({title: '修正', modalWidth: '85%'})
sessionStorage.setItem('id', String(record.id));
this.props.history.push(`/questionUp`);
}}></span>
]
},
];
// 分页切换
const changePage = (current: number, pageSize?: number) => {
setTimeout(() => {
this.setState({page: current, num: pageSize || 20});
this.getList();
}, 0);
};
// 多少每页
const selectChange = (page: number, num: number) => {
this.setState({ page, num });
this.getList();
};
const { list, loading } = this.state;
return (
<div className="container">
<div className="list-filter">
<Form
ref={this.formRef}
className="filter"
layout="inline"
name="basic"
onFinish={onFinish}
>
<Form.Item
label="监管行业:"
name="industryId"
>
<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"
>
<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: 240 }}/>
</Form.Item>
<Form.Item>
<Button type="default" onClick={this.handleReset}></Button>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit"></Button>
</Form.Item>
</Form>
</div>
<Form
className="filter"
layout="inline"
name="basic"
onFinish={onFinish}
style={{ display: 'flex', justifyContent: 'flex-end' }}
>
<Form.Item>
<Button type="default" onClick={this.deleteMultiple}></Button>
</Form.Item>
<Form.Item>
<Button type="primary" onClick={handleAddQuestion}></Button>
</Form.Item>
</Form>
<Table
dataSource={list}
columns={columns}
rowKey="id"
loading={loading}
scroll={{ y: '400px' }}
pagination={{
total: this.state.total,
current: this.state.page,
showQuickJumper: true,
showSizeChanger: true,
showTotal: (total) => `${total}`,
onShowSizeChange: selectChange,
onChange: changePage
}}
rowSelection={rowSelection}
/>
</div>
);
}
}
export default QuestionList;

@ -0,0 +1,403 @@
import React, { Component } from'react';
import { Form, Input, Button, Radio, Checkbox, Select, message } from 'antd';
import { dictionary } from "api/dict/index";
import {findIndustry, getDetail, update} from 'api/question';
const { Option } = Select;
interface QuestionState {
id: string|null;
questionTypes: string;
industryId: string;
serviceTypeId: string;
questionContent: string;
answerOptions: {[
key: string]: string
};
answer: string;
}
interface States {
industryDict: any;
serviceTypeDict: any;
isLoading: boolean;
question: QuestionState;
}
class QuestionUp extends Component<any, States> {
formRef: any;
constructor(props: any) {
super(props);
this.formRef = React.createRef();
this.state = {
industryDict: undefined,
serviceTypeDict: undefined,
isLoading: false,
question: {
id: '',
questionTypes: '1',
industryId: '',
serviceTypeId: '',
questionContent: '',
answerOptions: { A: '', B: '', C: '', D: '' },
answer: ''
},
};
}
componentDidMount() {
this.findIndustry()
this.findDict();
this.getDetail();
}
// 监管行业
findIndustry() {
findIndustry().then((res: any) => {
if (res.data) {
this.setState({ industryDict: res.data });
}
});
}
// AQ服务类型
findDict() {
dictionary('serviceTypeDict').then((res) => {
if (res.data) {
this.setState({ serviceTypeDict: res.data });
}
});
}
// 题目详情
getDetail = () => {
const id = sessionStorage.getItem('id');
sessionStorage.removeItem('id');
getDetail(id).then((res: any) => {
if (res.data) {
let answerOptions = {};
const options = res.data.options.split(';');
options.forEach((option: any) => {
const [key, value] = option.split(':');
answerOptions[key] = value;
});
const question: QuestionState = {
id:id,
questionTypes: String(res.data.questionTypes),
industryId: String(res.data.industryId),
serviceTypeId: String(res.data.serviceTypeId),
questionContent: String(res.data.questionContent),
answerOptions: answerOptions,
answer: res.data.answer
};
this.setState({ question: question }, () => {
const formValues = {};
formValues['questionTypes'] = question.questionTypes;
formValues['industryId'] = question.industryId;
formValues['serviceTypeId'] = question.serviceTypeId;
formValues['questionContent'] = question.questionContent;
formValues['answer'] = question.answer;
formValues['answerOption_A'] = question.answerOptions.A;
formValues['answerOption_B'] = question.answerOptions.B;
formValues['answerOption_C'] = question.answerOptions.C;
formValues['answerOption_D'] = question.answerOptions.D;
this.formRef.current.setFieldsValue(formValues);
});
}
}).catch(() => {
message.error('获取题目详情失败,请重试');
});
};
// 题型
handleQuestionTypeChange = (value: string) => {
this.setState((prevState) => {
prevState.question.questionTypes = value;
prevState.question.answer = '';
return {
question: prevState.question
};
});
};
// 单选框
handleRadioChange = (value: string) => {
this.setState((prevState) => {
prevState.question.answer = value;
return {
question: prevState.question
};
});
};
// 多选框
handleCheckboxChange = (type: string, values: (string | number | boolean)[] | null) => {
const currentAnswer = this.state.question.answer;
const currentSelectedArray = currentAnswer? currentAnswer.split(',') : [];
if (!values || values.length === 0) {
const newSelectedArray = currentSelectedArray.filter(val => val!== type);
newSelectedArray.sort();
this.setState((prevState) => {
prevState.question.answer = newSelectedArray.join(',');
return {
question: prevState.question
};
});
} else {
const stringValues = values.map((val) => String(val));
const newSelectedArray = Array.from(new Set([...currentSelectedArray, ...stringValues]));
newSelectedArray.sort();
this.setState((prevState) => {
prevState.question.answer = newSelectedArray.join(',');
return {
question: prevState.question
};
});
}
};
// 答案
handleAnswerOptionChange = (option: string, value: string) => {
this.setState((prevState) => {
prevState.question.answerOptions[option] = value;
return {
question: prevState.question
};
});
};
// 保存修改
update = () => {
this.setState({ isLoading: true });
this.formRef.current.validateFields().then((values: Record<string, any>) => {
const { question } = this.state;
const updatedQuestion = {
...question,
industryId: values['industryId'],
serviceTypeId: values['serviceTypeId'],
questionContent: values['questionContent']
};
this.setState({ question: updatedQuestion });
update(updatedQuestion).then((res) => {
const isSuccess = res.data;
if (isSuccess) {
message.success('修改成功');
this.setState({ isLoading: false });
this.props.history.push('/questionList');
} else {
message.error('修改失败,请稍后重试');
this.setState({ isLoading: false });
}
}).catch(() => {
message.error('修改时发生错误,请检查');
this.setState({ isLoading: false });
});
});
};
render() {
const { industryDict, serviceTypeDict, question, isLoading } = this.state;
const handleListQuestion = () => {
this.props.history.push('/questionList');
};
return (
<div className="container">
<Form ref={this.formRef} layout="inline">
<div style={{ display: 'flex'}}>
<Form.Item name="questionTypes">
<Radio.Group
onChange={(e) => this.handleQuestionTypeChange(e.target.value)}>
<Radio.Button value="1"></Radio.Button>
<Radio.Button value="2"></Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item
label="监管行业:"
name="industryId"
>
<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"
>
<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).trim().toLowerCase()}>{item.dictValue}</Option>
);
}
return rows;
})()
:
<Option disabled></Option>
}
</Select>
</Form.Item>
</div>
<Form.Item
label="题干:"
name="questionContent"
style={{ marginTop: 10 }}
>
<Input.TextArea
placeholder="请输入题干内容"
style={{ width: 1100, height: 60 }}
/>
</Form.Item>
<Form.Item style={{ marginTop: 10, marginLeft: 40 }}>
<div>
<div style={{ display: 'flex' }}>
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange(e.target.value)}
>
<Radio value="A">A</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.A}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange('A', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange('A', values,)}>
<Checkbox value="A">A</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.A}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange('A', e.target.value)}
/>
</Checkbox.Group>
)}
{question.questionTypes === '1' ? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange( e.target.value)}
style={{ marginLeft: 20 }}
>
<Radio value="B">B</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.B}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange('B', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
style={{ marginLeft: 20 }}
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange('B',values)}>
<Checkbox value="B">B</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.B}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange( 'B', e.target.value)}
/>
</Checkbox.Group>
)}
</div>
<div style={{ display: 'flex', marginTop: 10 }}>
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange( e.target.value)}
>
<Radio value="C">C</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.C}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange('C', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange('C', values)}>
<Checkbox value="C">C</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.C}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange( 'C', e.target.value)}
/>
</Checkbox.Group>
)}
{question.questionTypes === '1'? (
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange( e.target.value)}
style={{ marginLeft: 20 }}
>
<Radio value="D">D</Radio>
<Input
placeholder="请输入答案"
value={question.answerOptions.D}
style={{ width: 490}}
onChange={(e) => this.handleAnswerOptionChange('D', e.target.value)}
/>
</Radio.Group>
) : (
<Checkbox.Group
style={{ marginLeft: 20 }}
value={question.answer? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange('D',values)}>
<Checkbox value="D">D</Checkbox>
<Input
placeholder="请输入答案"
value={question.answerOptions.D}
style={{ width: 500}}
onChange={(e) => this.handleAnswerOptionChange('D', e.target.value)}
/>
</Checkbox.Group>
)}
</div>
</div>
</Form.Item>
</Form>
<div style={{ textAlign: 'right', marginTop: 30 }}>
<Button type="default" onClick={handleListQuestion} style={{ marginRight: 10 }}>
</Button>
<Button type="primary" htmlType="submit" loading={isLoading} onClick={this.update}>
</Button>
</div>
</div>
);
}
}
export default QuestionUp;

@ -34,6 +34,28 @@ const menuList = [
}
]
},
{
title: '题库管理',
key: 'question',
icon: 'icon-peizhi',
subs: [
{
title: '题库管理',
key: 'questionList',
}
]
},
{
title: '试卷管理',
key: 'question',
icon: 'icon-peizhi',
subs: [
{
title: '试卷管理',
key: 'examPaperList',
}
]
}
// {
// title: 'demo',
// key: 'demo',

Loading…
Cancel
Save