题库管理和试卷管理代码提交

main
hujunpeng 3 months ago
parent 537bded3b8
commit e0ec2a481e
  1. 24
      packages/examination/src/api/question/index.tsx
  2. 1
      packages/examination/src/components/contentMain/index.js
  3. 61
      packages/examination/src/views/examPaper/examPaperList.tsx
  4. 375
      packages/examination/src/views/question/questionAdd.tsx
  5. 291
      packages/examination/src/views/question/questionList.tsx

@ -1,10 +1,10 @@
import axios from '../axios'; import axios from '../axios';
/* /*
* *
*/ */
export function getList(num: number, page: number, obj:object){ export function getList(num: number, page: number, obj:object){
const rData = { const data = {
num:num, num:num,
page:page, page:page,
industryId:obj['industryId'], industryId:obj['industryId'],
@ -12,28 +12,18 @@ export function getList(num: number, page: number, obj:object){
questionContent:obj['questionContent'] questionContent:obj['questionContent']
}; };
return axios({ return axios({
url: "/ex/question/list", url: "/ex/question/getList",
method: 'post', method: 'post',
data: rData data: data
}) })
} }
/* /*
* () *
*/ */
export function deleteQuestion(id: number) { export function delQuestion(ids: any) {
return axios({ return axios({
url: '/ex/question/delete?id=' + id, url: '/ex/question/delQuestion',
method: 'get'
});
}
/*
*
*/
export function deleteQuestionList(ids: any) {
return axios({
url: '/ex/question/deleteList',
method: 'post', method: 'post',
data: ids data: ids
}); });

@ -66,6 +66,7 @@ class ContentMain extends Component {
<Route exact path='/questionEdit' component={ QuestionEdit }/> <Route exact path='/questionEdit' component={ QuestionEdit }/>
<Route exact path='/examPaperList' component={ ExamPaperList }/> <Route exact path='/examPaperList' component={ ExamPaperList }/>
<Route exact path='/examPaperAdd' component={ ExamPaperAdd }/> <Route exact path='/examPaperAdd' component={ ExamPaperAdd }/>
<Route exact path='/examPaperView' component={ ExamPaperView }/>
<Redirect exact from='/' to='/home'/> <Redirect exact from='/' to='/home'/>
</Switch> </Switch>
</div> </div>

@ -1,6 +1,5 @@
import React, { Component } from'react'; import React, { Component } from'react';
import { Form, Input, Button, Table, Select, message, Modal } from 'antd'; import { Form, Input, Button, Table, Select, message, Modal } from 'antd';
import { TableRowSelection } from 'antd/lib/table/interface';
import { deleteSingle, deleteMultiple, getList, updatePaperStatus, batchUpdatePaperStatus } from 'api/examPaper'; import { deleteSingle, deleteMultiple, getList, updatePaperStatus, batchUpdatePaperStatus } from 'api/examPaper';
import { findIndustry } from 'api/question'; import { findIndustry } from 'api/question';
@ -16,14 +15,9 @@ interface States {
list: any[]; list: any[];
total: number; total: number;
loading: boolean; loading: boolean;
currentRow: object;
title: string;
modalText: string;
modalWidth: number | string;
industryDict: any; industryDict: any;
serviceTypeDict: any; serviceTypeDict: any;
selectedRowKeys: number[]; selectedRowKeys: number[];
isAllSelected: boolean;
} }
class ExamPaperList extends Component<any, States> { class ExamPaperList extends Component<any, States> {
@ -41,17 +35,9 @@ class ExamPaperList extends Component<any, States> {
list: [], list: [],
total: 0, total: 0,
loading: false, loading: false,
currentRow: {
id: 0,
status: 0
},
title: '',
modalText: '',
modalWidth: 0,
industryDict: undefined, industryDict: undefined,
serviceTypeDict: undefined, serviceTypeDict: undefined,
selectedRowKeys: [], selectedRowKeys: []
isAllSelected: false,
}; };
} }
@ -79,7 +65,6 @@ class ExamPaperList extends Component<any, States> {
list: res.data.data, list: res.data.data,
total: res.data.total, total: res.data.total,
selectedRowKeys: [], selectedRowKeys: [],
isAllSelected: false,
}); });
this.setState({ loading: false }); this.setState({ loading: false });
}).catch(() => { }).catch(() => {
@ -99,7 +84,6 @@ class ExamPaperList extends Component<any, States> {
paperName: undefined paperName: undefined
}, },
selectedRowKeys: [], selectedRowKeys: [],
isAllSelected: false,
}); });
} }
}; };
@ -158,28 +142,10 @@ class ExamPaperList extends Component<any, States> {
}; };
// 多选 // 多选
onSelectChange = (selectedRowKeys: React.Key[]) => { onChange = (selectedRowKeys: React.Key[]) => {
this.setState({ this.setState({
selectedRowKeys: selectedRowKeys as number[], 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
}); });
}
}; };
// 更新试卷状态 // 更新试卷状态
@ -257,17 +223,6 @@ class ExamPaperList extends Component<any, States> {
const { industryDict, selectedRowKeys } = this.state; const { industryDict, 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 columns: any = [ const columns: any = [
{ title: '序号', dataIndex: 'index', key: 'index', align: 'center', width: 60, { title: '序号', dataIndex: 'index', key: 'index', align: 'center', width: 60,
render: (_: number, __: number, index: number) => { render: (_: number, __: number, index: number) => {
@ -297,13 +252,11 @@ class ExamPaperList extends Component<any, States> {
{ title: '操作', key: 'operation', align: 'center', fixed: 'right', width: 200, { title: '操作', key: 'operation', align: 'center', fixed: 'right', width: 200,
render: (record: any) => [ render: (record: any) => [
<span className='mr10 link' onClick={() => { <span className='mr10 link' onClick={() => {
this.setState({title: '编辑', modalWidth: '85%'})
sessionStorage.setItem('id', String(record.id)); sessionStorage.setItem('id', String(record.id));
sessionStorage.setItem('isEdit', "true"); sessionStorage.setItem('isEdit', "true");
this.props.history.push(`/examPaperAdd`); this.props.history.push(`/examPaperAdd`);
}}></span>, }}></span>,
<span className='mr10 link' onClick={() => { <span className='mr10 link' onClick={() => {
this.setState({title: '编辑', modalWidth: '85%'})
sessionStorage.setItem('id', String(record.id)); sessionStorage.setItem('id', String(record.id));
this.props.history.push(`/examPaperView`); this.props.history.push(`/examPaperView`);
}}></span>, }}></span>,
@ -311,7 +264,6 @@ class ExamPaperList extends Component<any, States> {
this.updatePaperStatus(record.id, record.paperStatus); // 调用更新状态的方法 this.updatePaperStatus(record.id, record.paperStatus); // 调用更新状态的方法
}}>{record.paperStatus === 0? '启用' : '停用'}</span>, // 根 }}>{record.paperStatus === 0? '启用' : '停用'}</span>, // 根
<span className="mr10 link" onClick={() => { <span className="mr10 link" onClick={() => {
this.setState({title: '删除', modalWidth: '85%'})
this.deleteSingle(record.id); this.deleteSingle(record.id);
}}></span> }}></span>
] ]
@ -409,7 +361,13 @@ class ExamPaperList extends Component<any, States> {
columns={columns} columns={columns}
rowKey="id" rowKey="id"
loading={loading} loading={loading}
scroll={{ y: '400px' }} rowSelection={{
selectedRowKeys: selectedRowKeys,
onChange: this.onChange,
getCheckboxProps: () => ({
disabled: false
})
}}
pagination={{ pagination={{
total: this.state.total, total: this.state.total,
current: this.state.page, current: this.state.page,
@ -419,7 +377,6 @@ class ExamPaperList extends Component<any, States> {
onShowSizeChange: selectChange, onShowSizeChange: selectChange,
onChange: changePage onChange: changePage
}} }}
rowSelection={rowSelection}
/> />
</div> </div>
); );

@ -4,91 +4,95 @@ import { dictionary } from "api/dict/index";
import { add, findIndustry } from 'api/question'; import { add, findIndustry } from 'api/question';
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import { CheckboxValueType } from 'antd/lib/checkbox/Group';
const { Option } = Select; const { Option} = Select;
// 定义单个试题的状态接口
interface QuestionState { interface QuestionState {
questionTypes: string; questionTypes: string;
industryId: string | null; industryId: string;
serviceTypeId: string | null; serviceTypeId: string;
questionContent: string; questionContent: string;
answerOptions: { [key: string]: string }; optionA: string;
answer: string | null; optionB: string;
optionC: string;
optionD: string;
answer: string;
} }
// 定义组件的状态接口
interface States { interface States {
industryDict: any; industryDict: any;
serviceTypeDict: any; serviceTypeDict: any;
isLoading: boolean;
questions: QuestionState[]; questions: QuestionState[];
} }
class QuestionAdd extends Component<any, States> { class QuestionAdd extends Component<any, States> {
formRef: any; formRef: any;
fileInputRef: any; fileInputRef: any;
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.formRef = React.createRef(); this.formRef = React.createRef();
this.fileInputRef = React.createRef(); this.fileInputRef = React.createRef();
this.state = { this.state = {
industryDict: undefined, industryDict: [],
serviceTypeDict: undefined, serviceTypeDict: [],
isLoading: false,
questions: [ questions: [
{ {
questionTypes: '1', questionTypes: '1',
industryId: '',
serviceTypeId: '',
questionContent: '', questionContent: '',
answerOptions: { A: '', B: '', C: '', D: ''}, optionA: '',
answer: null, optionB: '',
industryId: null, optionC: '',
serviceTypeId: null optionD: '',
answer: ''
} }
] ]
}; };
} }
// 初期
componentDidMount() { componentDidMount() {
this.getDict(); this.findDict();
this.findIndustry();
} }
// 字典 // 字典
getDict() { findDict() {
// 服务类型 // 监管行业
dictionary('serviceTypeDict').then((res) => { findIndustry()
.then((res: any) => {
if (res.data) { if (res.data) {
this.setState({ serviceTypeDict: res.data }); this.setState({ industryDict: res.data });
} }
})
.catch(() => {
message.error('获取监管行业字典数据失败,请稍后重试');
}); });
} // AQ服务类型
dictionary('serviceTypeDict')
// 行业 .then((res) => {
findIndustry() {
// 监管行业
findIndustry().then((res) => {
if (res.data) { if (res.data) {
this.setState({ industryDict: res.data }); this.setState({ serviceTypeDict: res.data });
} }
})
.catch(() => {
message.error('获取AQ服务类型字典数据失败,请稍后重试');
}); });
} }
// 题型 // 题型切换
handleQuestionTypeChange = (index: number, value: string) => { handleQuestionTypeChange = (index: number, value: string) => {
this.setState((prevState) => { this.setState((prevState) => {
const questions = [...prevState.questions]; const questions = [...prevState.questions];
questions[index].questionTypes = value; questions[index].questionTypes = value;
questions[index].answer = null; questions[index].answer = '';
return { return {
questions questions
}; };
}); });
}; };
// 单选框 // 单选框Change
handleRadioChange = (index: number, value: string) => { handleRadioChange = (index: number, value: string) => {
this.setState((prevState) => { this.setState((prevState) => {
const questions = [...prevState.questions]; const questions = [...prevState.questions];
@ -99,33 +103,13 @@ class QuestionAdd extends Component<any, States> {
}); });
}; };
// 多选框 // 多选框Change
handleCheckboxChange = (index: number, type: string, values: (string | number | boolean)[] | null) => { handleCheckboxChange = (index: number, values: CheckboxValueType[]) => {
this.setState((prevState) => { this.setState((prevState) => {
const questions = [...prevState.questions]; 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 stringValues = values.map((val) => String(val));
const newSelectedArray = Array.from(new Set([...currentSelectedArray, ...stringValues])); stringValues.sort();
newSelectedArray.sort(); questions[index].answer = stringValues.join(',');
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 { return {
questions questions
}; };
@ -139,12 +123,14 @@ class QuestionAdd extends Component<any, States> {
...prevState.questions, ...prevState.questions,
{ {
questionTypes: '1', questionTypes: '1',
industryId: '',
serviceTypeId: '',
questionContent: '', questionContent: '',
answerOptions: { A: '', B: '', C: '', D: ''}, optionA: '',
answerDisabled: false, optionB: '',
answer: null, optionC: '',
industryId: null, optionD: '',
serviceTypeId: null answer: ''
} }
] ]
})); }));
@ -163,36 +149,39 @@ class QuestionAdd extends Component<any, States> {
// 处理表单提交 // 处理表单提交
handleSubmit = () => { handleSubmit = () => {
this.setState({ isLoading: true }); this.formRef.current.validateFields().then((values: any) => {
this.formRef.current.validateFields().then((values: Record<string, any>) => {
const questions = this.state.questions.map((question, index) => { const questions = this.state.questions.map((question, index) => {
const industryId = values[`industryId_${index}`]; const industryId = values[`industryId_${index}`];
const serviceTypeId = values[`serviceTypeId_${index}`]; const serviceTypeId = values[`serviceTypeId_${index}`];
const questionContent = values[`questionContent_${index}`]; const questionContent = values[`questionContent_${index}`];
const optionA = values[`optionA_${index}`]
const optionB = values[`optionB_${index}`];
const optionC = values[`optionC_${index}`];
const optionD = values[`optionD_${index}`];
return { return {
...question, ...question,
industryId, industryId,
serviceTypeId, serviceTypeId,
questionContent questionContent,
optionA,
optionB,
optionC,
optionD,
}; };
}); });
add(questions).then((res) => { add(questions).then((res) => {
const count = res.data; const count = res.data;
if (count>0) { if (count > 0) {
message.success(`成功新增 ${count} 条试题`); message.success(`新增成功`);
this.setState({ isLoading: false });
this.props.history.push('/questionList'); this.props.history.push('/questionList');
} else { } else {
message.error('新增试题失败,请稍后重试'); message.error('新增试题失败,请稍后重试');
this.setState({ isLoading: false });
} }
}).catch(() => { }).catch(() => {
message.error('新增试题时发生错误,请检查'); message.error('新增试题时发生错误,请检查');
this.setState({ isLoading: false });
}); });
}).catch(() => { }).catch(() => {
this.setState({ isLoading: false });
}); });
}; };
@ -222,14 +211,12 @@ class QuestionAdd extends Component<any, States> {
const question: QuestionState = { const question: QuestionState = {
questionTypes: String(row[0]), questionTypes: String(row[0]),
industryId: String(row[1]), industryId: String(row[1]),
serviceTypeId: String(row[2]).trim().toLowerCase(), serviceTypeId: String(row[2]),
questionContent: String(row[3]), questionContent: String(row[3]),
answerOptions: { optionA: String(row[4]),
A: String(row[4]), optionB: String(row[5]),
B: String(row[5]), optionC: String(row[6]),
C: String(row[6]), optionD: String(row[7]),
D: String(row[7])
},
answer: String(row[8]) answer: String(row[8])
}; };
return question; return question;
@ -237,14 +224,15 @@ class QuestionAdd extends Component<any, States> {
this.setState({ questions: newQuestions }, () => { this.setState({ questions: newQuestions }, () => {
const formValues = {}; const formValues = {};
newQuestions.forEach((question, index) => { newQuestions.forEach((question, index) => {
formValues[`questionContent_${index}`] = question.questionContent; formValues[`questionTypes_${index}`] = question.questionTypes;
formValues[`industryId_${index}`] = question.industryId; formValues[`industryId_${index}`] = question.industryId;
formValues[`serviceTypeId_${index}`] = question.serviceTypeId; formValues[`serviceTypeId_${index}`] = question.serviceTypeId;
formValues[`questionContent_${index}`] = question.questionContent;
formValues[`answer_${index}`] = question.answer; formValues[`answer_${index}`] = question.answer;
formValues[`answerOption_A_${index}`] = question.answerOptions.A; formValues[`optionA_${index}`] = question.optionA;
formValues[`answerOption_B_${index}`] = question.answerOptions.B; formValues[`optionB_${index}`] = question.optionB;
formValues[`answerOption_C_${index}`] = question.answerOptions.C; formValues[`optionC_${index}`] = question.optionC;
formValues[`answerOption_D_${index}`] = question.answerOptions.D; formValues[`optionD_${index}`] = question.optionD;
}); });
this.formRef.current.setFieldsValue(formValues); this.formRef.current.setFieldsValue(formValues);
}); });
@ -259,20 +247,20 @@ class QuestionAdd extends Component<any, States> {
}; };
render() { render() {
const { industryDict, serviceTypeDict, questions, isLoading } = this.state; const { industryDict, serviceTypeDict, questions } = this.state;
// 使用 this.props.history 进行页面跳转 // 使用 this.props.history 进行页面跳转
const handleListQuestion = () => { const handleListQuestion = () => {
this.props.history.push('/questionList'); this.props.history.push('/questionList');
}; };
return ( return (
<div className="container" > <div className="container">
<div style={{ textAlign: 'right'}}> <div style={{textAlign: 'right'}}>
<Button type="default" style={{ marginRight: 10 }} onClick={this.downloadTemplate}></Button> <Button type="default" style={{marginRight: 10}} onClick={this.downloadTemplate}></Button>
<Button type="default" onClick={this.handleImportClick}></Button> <Button type="default" onClick={this.handleImportClick}></Button>
<input <input
type="file" type="file"
ref={this.fileInputRef} ref={this.fileInputRef}
style={{ display: 'none' }} style={{display: 'none'}}
accept=".xlsx,.xls" accept=".xlsx,.xls"
onChange={this.handleFileChange} onChange={this.handleFileChange}
/> />
@ -280,14 +268,12 @@ class QuestionAdd extends Component<any, States> {
<Form <Form
ref={this.formRef} ref={this.formRef}
layout="inline" layout="inline"
className="ant-bg-light"
> >
{questions.map((question, index) => ( {questions.map((question, index) => (
<div key={index} style={{ marginBottom: 30 }}> <div key={index} style={{marginBottom: 30}}>
<div style={{ display: 'flex' }}> <div style={{display: 'flex'}}>
<Form.Item> <Form.Item name={`questionTypes_${index}`}>
<Radio.Group <Radio.Group
value={question.questionTypes}
onChange={(e) => this.handleQuestionTypeChange(index, e.target.value)}> onChange={(e) => this.handleQuestionTypeChange(index, e.target.value)}>
<Radio.Button value="1"></Radio.Button> <Radio.Button value="1"></Radio.Button>
<Radio.Button value="2"></Radio.Button> <Radio.Button value="2"></Radio.Button>
@ -296,14 +282,13 @@ class QuestionAdd extends Component<any, States> {
<Form.Item <Form.Item
label="监管行业:" label="监管行业:"
name={`industryId_${index}`} name={`industryId_${index}`}
rules={[{ required: true, message: '请选择监管行业' }]} rules={[{required: true, message: '请选择监管行业'}]}
> >
<Select placeholder="请选择监管行业" <Select placeholder="请选择监管行业"
style={{ width: 240 }} style={{width: 240}}
allowClear allowClear>
value={question.industryId}>
{ {
industryDict && industryDict.length > 0? industryDict && industryDict.length > 0 ?
(() => { (() => {
let rows = []; let rows = [];
for (let i = 0; i < industryDict.length; i++) { for (let i = 0; i < industryDict.length; i++) {
@ -322,20 +307,20 @@ class QuestionAdd extends Component<any, States> {
<Form.Item <Form.Item
label="AQ服务类型:" label="AQ服务类型:"
name={`serviceTypeId_${index}`} name={`serviceTypeId_${index}`}
rules={[{ required: true, message: '请选择AQ服务类型' }]} rules={[{required: true, message: '请选择AQ服务类型'}]}
> >
<Select placeholder="请选择AQ服务类型" <Select placeholder="请选择AQ服务类型"
style={{ width: 240 }} style={{width: 240}}
allowClear allowClear>
value={question.serviceTypeId}>
{ {
serviceTypeDict && serviceTypeDict.length > 0? serviceTypeDict && serviceTypeDict.length > 0 ?
(() => { (() => {
let rows = []; let rows = [];
for (let i = 0; i < serviceTypeDict.length; i++) { for (let i = 0; i < serviceTypeDict.length; i++) {
const item = serviceTypeDict[i]; const item = serviceTypeDict[i];
rows.push( rows.push(
<Option value={String(item.dictKey).trim().toLowerCase()}>{item.dictValue}</Option> <Option
value={String(item.dictKey)}>{item.dictValue}</Option>
); );
} }
return rows; return rows;
@ -346,143 +331,105 @@ class QuestionAdd extends Component<any, States> {
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
{index > 0 && (<Button type="link" onClick={() => this.deleteQuestion(index)}>X</Button>)} {index > 0 && (
<Button type="link" onClick={() => this.deleteQuestion(index)}>X</Button>)}
</Form.Item> </Form.Item>
</div> </div>
<div style={{display: 'flex'}}>
<Form.Item <Form.Item
label="题干:" label="题干:"
name={`questionContent_${index}`} name={`questionContent_${index}`}
style={{marginTop: 10 }} style={{marginTop: 10}}
rules={[{ required: true, message: '请输入题干内容' }]} rules={[{required: true, message: '请输入题干内容'}]}
> >
<Input.TextArea <Input.TextArea
placeholder="请输入题干内容" placeholder="请输入题干内容"
value={question.questionContent} style={{width: 1100, height: 60}}
style={{ width: 1100, height: 60 }}
/> />
</Form.Item> </Form.Item>
<Form.Item </div>
style={{marginTop: 10, marginLeft: 40}} <div style={{marginTop: 10, marginLeft: 40}}>
> <div style={{display: 'flex'}}>
<div> {question.questionTypes === '1' ? (
<div style={{ display: 'flex' }}> <Form.Item>
{question.questionTypes === '1'? (
<Radio.Group <Radio.Group
name={`answer_${index}`}
value={question.answer} value={question.answer}
onChange={(e) => this.handleRadioChange(index, e.target.value)} onChange={(e) => this.handleRadioChange(index, e.target.value)}
> >
<div style={{display: 'flex'}}>
<Form.Item rules={[{required: true, message: '请选择选项'}]}>
<Radio value="A">A</Radio> <Radio value="A">A</Radio>
<Input </Form.Item>
placeholder="请输入答案" <Form.Item name={`optionA_${index}`} rules={[{required: true, message: '请输入答案A'}]}>
value={question.answerOptions.A} <Input placeholder="请输入答案" style={{width: 490}}/>
style={{ width: 490}} </Form.Item>
onChange={(e) => this.handleAnswerOptionChange(index, 'A', e.target.value)} <Form.Item>
/>
</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> <Radio value="B">B</Radio>
<Input </Form.Item>
placeholder="请输入答案" <Form.Item name={`optionB_${index}`} rules={[{required: true, message: '请输入答案B'}]}>
value={question.answerOptions.B} <Input placeholder="请输入答案" style={{width: 490}}/>
style={{ width: 490}} </Form.Item>
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>
<div style={{ display: 'flex', marginTop: 10 }}> <div style={{display: 'flex', marginTop: 10}}>
{question.questionTypes === '1'? ( <Form.Item>
<Radio.Group
value={question.answer}
onChange={(e) => this.handleRadioChange(index, e.target.value)}
>
<Radio value="C">C</Radio> <Radio value="C">C</Radio>
<Input </Form.Item>
placeholder="请输入答案" <Form.Item name={`optionC_${index}`} rules={[{required: true, message: '请输入答案C'}]}>
value={question.answerOptions.C} <Input placeholder="请输入答案" style={{width: 490}}/>
style={{ width: 490}} </Form.Item>
onChange={(e) => this.handleAnswerOptionChange(index, 'C', e.target.value)} <Form.Item>
/>
</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> <Radio value="D">D</Radio>
<Input </Form.Item>
placeholder="请输入答案" <Form.Item name={`optionD_${index}`} rules={[{required: true, message: '请输入答案D'}]}>
value={question.answerOptions.D} <Input placeholder="请输入答案" style={{width: 490}}/>
style={{ width: 490}} </Form.Item>
onChange={(e) => this.handleAnswerOptionChange(index, 'D', e.target.value)} </div>
/>
</Radio.Group> </Radio.Group>
</Form.Item>
) : ( ) : (
<Checkbox.Group <Checkbox.Group
style={{ marginLeft: 20 }} name={`answer_${index}`}
value={question.answer? String(question.answer || '').split(',') : []} value={question.answer ? String(question.answer || '').split(',') : []}
onChange={(values) => this.handleCheckboxChange(index,'D',values)}> onChange={(values) => this.handleCheckboxChange(index, values)}
>
<div style={{display: 'flex'}}>
<Form.Item>
<Checkbox value="A">A</Checkbox>
</Form.Item>
<Form.Item name={`optionA_${index}`} rules={[{required: true, message: '请输入答案A'}]}>
<Input placeholder="请输入答案" style={{width: 490}}/>
</Form.Item>
<Form.Item>
<Checkbox value="B">B</Checkbox>
</Form.Item>
<Form.Item name={`optionB_${index}`} rules={[{required: true, message: '请输入答案B'}]}>
<Input placeholder="请输入答案" style={{width: 490}}/>
</Form.Item>
</div>
<div style={{display: 'flex', marginTop: 10}}>
<Form.Item>
<Checkbox value="C">C</Checkbox>
</Form.Item>
<Form.Item name={`optionC_${index}`} rules={[{required: true, message: '请输入答案C'}]}>
<Input placeholder="请输入答案" style={{width: 490}}/>
</Form.Item>
<Form.Item>
<Checkbox value="D">D</Checkbox> <Checkbox value="D">D</Checkbox>
<Input </Form.Item>
placeholder="请输入答案" <Form.Item name={`optionD_${index}`} rules={[{required: true, message: '请输入答案D'}]}>
value={question.answerOptions.D} <Input placeholder="请输入答案" style={{width: 490}}/>
style={{ width: 500}} </Form.Item>
onChange={(e) => this.handleAnswerOptionChange(index, 'D', e.target.value)} </div>
/>
</Checkbox.Group> </Checkbox.Group>
)} )}
</div> </div>
</div> </div>
</Form.Item>
</div> </div>
))} ))}
</Form> </Form>
<div style={{ textAlign: 'right'}}> <div style={{textAlign: 'right'}}>
<Button type="default" onClick={this.addNewQuestion}> <Button type="default" onClick={this.addNewQuestion}>
</Button> </Button>
@ -493,13 +440,12 @@ class QuestionAdd extends Component<any, States> {
bottom: 10, bottom: 10,
right: 10, right: 10,
width: '100%', width: '100%',
backgroundColor: 'white',
zIndex: 1000 zIndex: 1000
}}> }}>
<Button type="default" htmlType="button" onClick={handleListQuestion} style={{ marginRight: 10 }}> <Button type="default" htmlType="button" onClick={handleListQuestion} style={{marginRight: 10}}>
</Button> </Button>
<Button type="primary" htmlType="submit" loading={isLoading} onClick={this.handleSubmit}> <Button type="primary" htmlType="submit" onClick={this.handleSubmit}>
</Button> </Button>
</div> </div>
@ -507,4 +453,5 @@ class QuestionAdd extends Component<any, States> {
); );
} }
} }
export default QuestionAdd; export default QuestionAdd;

@ -1,7 +1,6 @@
import React, { Component } from'react'; import React, { Component } from'react';
import {Form, Input, Button, Table, Select, message, Modal} from 'antd'; import { Form, Input, Button, Table, Select, message, Modal } from 'antd';
import { TableRowSelection } from 'antd/lib/table/interface'; import { delQuestion, findIndustry, getList } from 'api/question';
import {deleteQuestion, deleteQuestionList, findIndustry, getList} from 'api/question';
import { dictionary } from "api/dict/index"; import { dictionary } from "api/dict/index";
const { Option } = Select; const { Option } = Select;
@ -9,75 +8,68 @@ const { Option } = Select;
interface States { interface States {
num: number; num: number;
page: number; page: number;
total: number;
listQuery: { listQuery: {
industryId: string | undefined; industryId: string;
serviceTypeId: string | undefined; serviceTypeId: string;
questionContent: string | undefined; questionContent: string;
}; };
list: any[]; list: any[];
total: number;
loading: boolean; loading: boolean;
currentRow: object;
title: string;
modalText: string;
modalWidth: number | string;
industryDict: any; industryDict: any;
serviceTypeDict: any; serviceTypeDict: any;
selectedRowKeys: number[]; selectedRowKeys: number[];
isAllSelected: boolean;
} }
class QuestionList extends Component<any, States> { class QuestionList extends Component<any, States> {
formRef: any; formRef: any;
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.formRef = React.createRef(); this.formRef = React.createRef();
this.state = { this.state = {
num: 10, num: 10,
page: 1, page: 1,
total: 0,
listQuery: { listQuery: {
industryId: '', industryId: '',
serviceTypeId: '', serviceTypeId: '',
questionContent: '' questionContent: ''
}, },
list: [], list: [],
total: 0,
loading: false, loading: false,
currentRow: { industryDict: [],
id: 0, serviceTypeDict: [],
status: 0
},
title: '',
modalText: '',
modalWidth: 0,
industryDict: undefined,
serviceTypeDict: undefined,
selectedRowKeys: [], selectedRowKeys: [],
isAllSelected: false,
}; };
} }
componentDidMount() { componentDidMount() {
this.findDict(); this.findDict();
this.findIndustry();
this.getList(); this.getList();
} }
// 字典
findDict() {
// 监管行业 // 监管行业
findIndustry() { findIndustry()
findIndustry().then((res: any) => { .then((res: any) => {
if (res.data) { if (res.data) {
this.setState({ industryDict: res.data }); this.setState({ industryDict: res.data });
} }
})
.catch(() => {
message.error('获取监管行业字典数据失败,请稍后重试');
}); });
}
// AQ服务类型 // AQ服务类型
findDict() { dictionary('serviceTypeDict')
dictionary('serviceTypeDict').then((res) => { .then((res) => {
if (res.data) { if (res.data) {
this.setState({ serviceTypeDict: res.data }); this.setState({ serviceTypeDict: res.data });
} }
})
.catch(() => {
message.error('获取AQ服务类型字典数据失败,请稍后重试');
}); });
} }
@ -85,53 +77,52 @@ class QuestionList extends Component<any, States> {
getList() { getList() {
this.setState({ loading: true }); this.setState({ loading: true });
const { num, page, listQuery } = this.state; const { num, page, listQuery } = this.state;
getList(num, page, listQuery).then((res) => { getList(num, page, listQuery)
.then((res) => {
this.setState({ this.setState({
loading: false,
list: res.data.data, list: res.data.data,
total: res.data.total, total: res.data.total,
selectedRowKeys: [], selectedRowKeys: [],
isAllSelected: false,
}); });
this.setState({ loading: false }); })
}).catch(() => { .catch(() => {
message.error('获取数据失败');
})
.finally(() => {
this.setState({ loading: false }); this.setState({ loading: false });
}); });
} }
// 重置 // 重置
handleReset = () => { handleReset = () => {
if (this.formRef.current) {
// 重置表单字段
this.formRef.current.resetFields(); this.formRef.current.resetFields();
// 重置 listQuery 状态
this.setState({ this.setState({
listQuery: { listQuery: {
industryId: undefined, industryId: '',
serviceTypeId: undefined, serviceTypeId: '',
questionContent: undefined questionContent: '',
}, },
selectedRowKeys: [],
isAllSelected: false,
}); });
}
}; };
// 删除(明细) // 删除问题
deleteSingle = (id: number) => { handleDeleteQuestion = (id: number) => {
Modal.confirm({ Modal.confirm({
title: '确认删除', title: '确认删除',
content: '你确定要删除这个问题吗?', content: '你确定要删除这个问题吗?',
onOk: () => { onOk: () => {
deleteQuestion(id).then((res) => { const idList = [id];
const isSuccess = res.data; delQuestion(idList)
if (isSuccess) { .then((res) => {
const success = res['success'];
if (success) {
message.success('删除成功'); message.success('删除成功');
this.getList(); this.getList();
} else { } else {
message.error('删除失败,请稍后重试'); message.error('删除失败,请稍后重试');
} }
}).catch(() => { })
.catch(() => {
message.error('删除时发生错误,请检查'); message.error('删除时发生错误,请检查');
}); });
}, },
@ -140,21 +131,22 @@ class QuestionList extends Component<any, States> {
}); });
}; };
// 删除 // 批量删除问题
deleteMultiple = () => { handleBatchDeleteQuestions = () => {
const { selectedRowKeys } = this.state; const { selectedRowKeys } = this.state;
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的问题'); if (selectedRowKeys === null || selectedRowKeys.length === 0) {
message.warning('请选择要删除的问题').then();
return; return;
} }
Modal.confirm({ Modal.confirm({
title: '确认删除', title: '确认删除',
content: '你确定要删除这些选中的问题吗?', content: '你确定要删除这些选中的问题吗?',
onOk: () => { onOk: () => {
deleteQuestionList(selectedRowKeys) delQuestion(selectedRowKeys)
.then((res) => { .then((res) => {
const isSuccess = res.data; const success = res['success'];
if (isSuccess) { if (success) {
message.success('删除成功'); message.success('删除成功');
this.getList(); this.getList();
} else { } else {
@ -170,94 +162,104 @@ class QuestionList extends Component<any, States> {
}); });
}; };
// 多选 // 行选择
onSelectChange = (selectedRowKeys: React.Key[]) => { onChange = (selectedRowKeys: React.Key[]) => {
this.setState({ this.setState({
selectedRowKeys: selectedRowKeys as number[], 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() { render() {
const onFinish = (values: object) => { const onFinish = (values: object) => {
const _listQuery = { ...this.state.listQuery, ...values }; const listQuery = { ...this.state.listQuery, ...values };
this.setState({ listQuery: _listQuery }); this.setState({ listQuery });
this.getList(); this.getList();
}; };
const { industryDict, serviceTypeDict, selectedRowKeys } = this.state; const changePage = (current: number, pageSize?: number) => {
setTimeout(() => {
// 行选择 this.setState({ page: current, num: pageSize || 20 });
const rowSelection: TableRowSelection<any> = { this.getList();
selectedRowKeys, }, 0);
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 {
industryDict,
serviceTypeDict,
selectedRowKeys,
list,
loading,
page,
num
} = this.state;
const columns: any = [ const columns: any = [
{ title: '序号', dataIndex: 'index', key: 'index', align: 'center', width: 60, {
title: '序号',
dataIndex: 'index',
key: 'index',
align: 'center',
width: 60,
render: (_: number, __: number, index: number) => { render: (_: number, __: number, index: number) => {
const { page, num } = this.state;
return (page - 1) * num + index + 1; return (page - 1) * num + index + 1;
} }
}, },
{ title: '监管行业', dataIndex: 'industryId', key: 'industryId', align: 'center', width: 150, {
render: (industryId:any) => { title: '监管行业',
const industry = industryDict?.find((item: { industryId: string | number; industryName: string }) => String(item.industryId) === String(industryId)); dataIndex: 'industryId',
key: 'industryId',
align: 'center',
width: 150,
render: (industryId: any) => {
const industry = industryDict?.find((item: any) => item.industryId === String(industryId));
return industry? industry.industryName : industryId; return industry? industry.industryName : industryId;
} }
}, },
{ title: 'AQ服务类型', dataIndex: 'serviceTypeId', key: 'serviceTypeId', align: 'center', width: 150, {
render: (serviceTypeId:any) => { title: 'AQ服务类型',
const serviceType = serviceTypeDict?.find((item: { dictKey: string | number; dictValue: string }) => String(item.dictKey) === String(serviceTypeId)); dataIndex: 'serviceTypeId',
key: 'serviceTypeId',
align: 'center',
width: 150,
render: (serviceTypeId: any) => {
const serviceType = serviceTypeDict?.find((item: any) => item.dictKey === serviceTypeId);
return serviceType? serviceType.dictValue : serviceTypeId; return serviceType? serviceType.dictValue : serviceTypeId;
} }
}, },
{ title: '题型', dataIndex: 'questionTypes', key: 'questionTypes', align: 'center', width: 80, {
render: (questionTypes:any) => { title: '题型',
if (questionTypes === 1) { dataIndex: 'questionTypes',
return '单选题'; key: 'questionTypes',
} else if (questionTypes === 2) { align: 'center',
return '多选题'; width: 80,
render: (questionTypes: any) => {
return questionTypes === 1? '单选题' : '多选题';
} }
return questionTypes;}
}, },
{ title: '题干', dataIndex: 'questionContent', key: 'questionContent', align: 'center', width: 450 }, {
{ title: '答案', dataIndex: 'answer', key: 'answer', align: 'center', width: 120 }, title: '题干',
{ title: '操作', key: 'operation', align: 'center', fixed: 'right', width: 120, dataIndex: 'questionContent',
key: 'questionContent',
align: 'center',
width: 450
},
{
title: '答案',
dataIndex: 'answer',
key: 'answer',
align: 'center',
width: 120
},
{
title: '操作',
key: 'operation',
align: 'center',
fixed: 'right',
width: 120,
render: (record: any) => [ render: (record: any) => [
<span className='mr10 link' onClick={() => { <span className='mr10 link' onClick={() => {
this.setState({title: '删除', modalWidth: '85%'}) this.handleDeleteQuestion(record.id);
this.deleteSingle(record.id);
}}></span>, }}></span>,
<span className="mr10 link" onClick={() => { <span className="mr10 link" onClick={() => {
this.setState({title: '修正', modalWidth: '85%'})
sessionStorage.setItem('id', String(record.id)); sessionStorage.setItem('id', String(record.id));
this.props.history.push(`/questionEdit`); this.props.history.push(`/questionEdit`);
}}></span> }}></span>
@ -265,39 +267,23 @@ class QuestionList extends Component<any, States> {
}, },
]; ];
// 分页切换
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 ( return (
<div className="container">
<div className="list-filter"> <div className="list-filter">
<Form <Form
ref={this.formRef} ref={this.formRef}
className="filter" className="filter"
layout="inline" layout="inline"
name="basic"
onFinish={onFinish} onFinish={onFinish}
> >
<Form.Item <Form.Item
label="监管行业:" label="监管行业:"
name="industryId" name="industryId"
> >
<Select placeholder="请选择监管行业" <Select
placeholder="请选择监管行业"
style={{ width: 240 }} style={{ width: 240 }}
allowClear> allowClear
>
{ {
industryDict && industryDict.length > 0? industryDict && industryDict.length > 0?
(() => { (() => {
@ -319,9 +305,11 @@ class QuestionList extends Component<any, States> {
label="AQ服务类型:" label="AQ服务类型:"
name="serviceTypeId" name="serviceTypeId"
> >
<Select placeholder="请选择AQ服务类型" <Select
placeholder="请选择AQ服务类型"
style={{ width: 240 }} style={{ width: 240 }}
allowClear> allowClear
>
{ {
serviceTypeDict && serviceTypeDict.length > 0? serviceTypeDict && serviceTypeDict.length > 0?
(() => { (() => {
@ -343,7 +331,10 @@ class QuestionList extends Component<any, States> {
label="题干条件:" label="题干条件:"
name="questionContent" name="questionContent"
> >
<Input placeholder="请输入题干条件" style={{ width: 240 }}/> <Input
placeholder="请输入题干条件"
style={{ width: 240 }}
/>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Button type="default" onClick={this.handleReset}></Button> <Button type="default" onClick={this.handleReset}></Button>
@ -352,19 +343,18 @@ class QuestionList extends Component<any, States> {
<Button type="primary" htmlType="submit"></Button> <Button type="primary" htmlType="submit"></Button>
</Form.Item> </Form.Item>
</Form> </Form>
</div>
<Form <Form
className="filter" className="filter"
layout="inline" layout="inline"
name="basic" style={{ justifyContent: 'flex-end' }}
onFinish={onFinish}
style={{ display: 'flex', justifyContent: 'flex-end' }}
> >
<Form.Item> <Form.Item>
<Button type="default" onClick={this.deleteMultiple}></Button> <Button type="default" onClick={this.handleBatchDeleteQuestions}></Button>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Button type="primary" onClick={handleAddQuestion}></Button> <Button type="primary" onClick={() => {
this.props.history.push('/questionAdd');
}}></Button>
</Form.Item> </Form.Item>
</Form> </Form>
<Table <Table
@ -372,21 +362,24 @@ class QuestionList extends Component<any, States> {
columns={columns} columns={columns}
rowKey="id" rowKey="id"
loading={loading} loading={loading}
scroll={{ y: '400px' }} rowSelection={{
selectedRowKeys: selectedRowKeys,
onChange: this.onChange,
getCheckboxProps: () => ({
disabled: false
})
}}
pagination={{ pagination={{
total: this.state.total, total: this.state.total,
current: this.state.page, current: this.state.page,
showQuickJumper: true, showQuickJumper: true,
showSizeChanger: true, showSizeChanger: true,
showTotal: (total) => `${total}`, showTotal: (total) => `${total}`,
onShowSizeChange: selectChange,
onChange: changePage onChange: changePage
}} }}
rowSelection={rowSelection}
/> />
</div> </div>
); );
} }
} }
export default QuestionList; export default QuestionList;
Loading…
Cancel
Save