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

main
hujunpeng 4 months ago
parent bc052dfa73
commit 17e162eed9
  1. 308
      packages/examination/src/views/examPaper/examPaperAdd.tsx
  2. 7
      packages/examination/src/views/question/questionList.tsx

@ -1,6 +1,8 @@
import React, { Component } from'react';
import { Form, Input, Button, Radio, Checkbox, Select, message } from 'antd';
import React, { Component } from 'react';
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,17 +85,26 @@ 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'])
.then((values:any) => {
.then((values: any) => {
const industryId = values.industryId;
const questionCount = values.questionCount;
// 随机获取试题
getRandomQuestions(industryId, questionCount)
.then((res: any) => {
if (res.data) {
if(res.data.length == 0){
if (res.data.length == 0) {
message.warning('题库没题了');
this.setState({ questions: [] });
return;
@ -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}>
@ -103,18 +263,18 @@ class ExamPaperAdd extends Component<any, States> {
<Form.Item
label="试卷名称:"
name="paperName"
style={{width: 1190}}
rules={[{required: true, message: '请输入试卷名称'}]}
style={{ width: 1190 }}
rules={[{ required: true, message: '请输入试卷名称' }]}
>
<Input placeholder="请输入试卷名称"/>
<Input placeholder="请输入试卷名称" />
</Form.Item>
<div style={{display: 'flex', gap: 20}}>
<div style={{ display: 'flex', gap: 20 }}>
<Form.Item
label="监管行业:"
name={`industryId`}
rules={[{ required: true, message: '请选择监管行业' }]}
>
<Select placeholder="请选择监管行业" style={{width: 240}} allowClear>
<Select placeholder="请选择监管行业" style={{ width: 240 }} allowClear>
{industryDict && industryDict.length > 0 ? (
(() => {
let rows = [];
@ -136,47 +296,53 @@ class ExamPaperAdd extends Component<any, States> {
name="questionCount"
rules={[{ required: true, message: '请输入题目数量' }]}
>
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入题目数量" min={1}/>
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入题目数量" min={1} />
</Form.Item>
<Form.Item
label="总分值:"
name="totalScore"
rules={[{ required: true, message: '请输入总分值' }]}
>
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入总分值" min={1}/>
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入总分值" min={1} />
</Form.Item>
<Form.Item
label="考试时长:"
name="examDuration"
rules={[{ required: true, message: '请输入考试时长' }]}
>
<Input type="number" style={{ textAlign: 'right' }} addonAfter="分钟" placeholder="请输入考试时长" min={1}/>
<Input type="number" style={{ textAlign: 'right' }} addonAfter="分钟" placeholder="请输入考试时长" min={1} />
</Form.Item>
</div>
<Form.Item
label="内容描述:"
name="description"
style={{width: 1190}}
style={{ width: 1190 }}
rules={[{ required: true, message: '请输入内容描述' }]}
>
<Input.TextArea placeholder="请输入内容描述"/>
<Input.TextArea placeholder="请输入内容描述" />
</Form.Item>
<div style={{display: 'flex'}}>
<div style={{ display: 'flex' }}>
<h3 style={{ fontWeight: 'bold' }}></h3>
<div>
<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>
<span style={{ fontWeight: 'bold' }}>{index + 1}. {question.questionContent}</span>
<Form.Item>
{question.questionTypes === '1' ? (
{ question.questionTypes === '1' ? (
<Radio.Group value={question.answer}>
{question.answerOptions.map((option) => (
<Radio value={option.value}>
@ -207,7 +373,7 @@ class ExamPaperAdd extends Component<any, States> {
zIndex: 1000
}}
>
<Button type="default" htmlType="button" onClick={handleListQuestion} style={{marginRight: 10}}>
<Button type="default" htmlType="button" onClick={handleListQuestion} style={{ marginRight: 10 }}>
</Button>
<Button type="primary" htmlType="submit" loading={isLoading}>
@ -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>
);
}

@ -36,9 +36,9 @@ class QuestionList extends Component<any, States> {
num: 10,
page: 1,
listQuery: {
industryId: undefined,
serviceTypeId: undefined,
questionContent: undefined
industryId: '',
serviceTypeId: '',
questionContent: ''
},
list: [],
total: 0,
@ -250,7 +250,6 @@ class QuestionList extends Component<any, States> {
},
{ 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={() => {

Loading…
Cancel
Save