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

main
hujunpeng 3 months ago
parent da9be7517a
commit 913365cd70
  1. 52
      packages/examination/src/api/examPaper/index.tsx
  2. 3
      packages/examination/src/components/contentMain/index.js
  3. 382
      packages/examination/src/views/examPaper/examPaperAdd.tsx
  4. 23
      packages/examination/src/views/examPaper/examPaperList.tsx
  5. 229
      packages/examination/src/views/examPaper/examPaperView.tsx

@ -65,58 +65,48 @@ export function batchUpdatePaperStatus(data: any) {
} }
/* /*
* *
*/ */
export function add(questionData: object) { export function getDetail(id: string|null) {
return axios({ return axios({
url: "/ex/question/add", url: '/ex/examPaper/getDetail?id=' + id,
method: 'post', method: 'get'
data: questionData
}); });
} }
/* /*
* *
*/ */
export function update(questionData: object) { export function getRandomQuestions(industryId: string, questionCount: number){
const data = {
industryId:industryId,
questionCount:questionCount
};
return axios({ return axios({
url: "/ex/question/update", url: "/ex/examPaper/getRandomQuestions",
method: 'post', method: 'post',
data: questionData data: data
});
}
/*
*
*/
export function findIndustry() {
return axios({
url: '/ex/question/findIndustry',
method: 'get'
}) })
} }
/* /*
* *
*/ */
export function getDetail(id: string) { export function save(data: object) {
return axios({ return axios({
url: '/ex/question/getDetail?id=' + id, url: "/ex/examPaper/add",
method: 'get' method: 'post',
data: data
}); });
} }
/* /*
* *
*/ */
export function getRandomQuestions(industryId: string, questionCount: number){ export function update(data: object) {
const data = {
industryId:industryId,
questionCount:questionCount
};
return axios({ return axios({
url: "/ex/examPaper/getRandomQuestions", url: "/ex/examPaper/update",
method: 'post', method: 'post',
data: data data: data
}) });
} }

@ -35,9 +35,9 @@ import ExamPaperList from 'views/examPaper/examPaperList';
import ExamDetailAnalysis from "../../views/exam-online/exam-detail-analysis"; import ExamDetailAnalysis from "../../views/exam-online/exam-detail-analysis";
import ExamPaperAnalysis from "../../views/exam-online/exam-paper-analysis"; import ExamPaperAnalysis from "../../views/exam-online/exam-paper-analysis";
import ExamPaperAdd from 'views/examPaper/examPaperAdd'; import ExamPaperAdd from 'views/examPaper/examPaperAdd';
import ExamPaperView from 'views/examPaper/examPaperView';
import ExamPaperAnalysisDetail from "../../views/exam-online/exam_paper_analysis_detail"; import ExamPaperAnalysisDetail from "../../views/exam-online/exam_paper_analysis_detail";
class ContentMain extends Component { class ContentMain extends Component {
render() { render() {
return ( return (
@ -61,7 +61,6 @@ class ContentMain extends Component {
<Route exact path='/exam-statistics' component={ ExamStatistics }/> <Route exact path='/exam-statistics' component={ ExamStatistics }/>
<Route exact path='/exam-detail-analysis' component={ ExamDetailAnalysis }/> <Route exact path='/exam-detail-analysis' component={ ExamDetailAnalysis }/>
<Route exact path='/exam-paper-analysis' component={ ExamPaperAnalysis }/> <Route exact path='/exam-paper-analysis' component={ ExamPaperAnalysis }/>
<Route exact path='/exam_paper_analysis_detail' component={ ExamPaperAnalysisDetail }/>
<Route exact path='/questionList' component={ QuestionList }/> <Route exact path='/questionList' component={ QuestionList }/>
<Route exact path='/questionAdd' component={ QuestionAdd }/> <Route exact path='/questionAdd' component={ QuestionAdd }/>
<Route exact path='/questionUp' component={ QuestionUp }/> <Route exact path='/questionUp' component={ QuestionUp }/>

@ -1,8 +1,8 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import {Form, Input, Button, Radio, Checkbox, Select, message, Modal, Table} from 'antd'; import { Form, Input, Button, Radio, Checkbox, Select, message, Modal, Table } from 'antd';
import { findIndustry, getRandomQuestions } from 'api/examPaper'; import { getRandomQuestions, save, update, getDetail} from 'api/examPaper';
import { getList} from 'api/question'; import { getList ,findIndustry} from 'api/question';
import {dictionary} from "../../api/dict"; import { dictionary } from "../../api/dict";
const { Option } = Select; const { Option } = Select;
@ -23,6 +23,8 @@ interface QuestionState {
// 定义组件的状态接口 // 定义组件的状态接口
interface States { interface States {
id: string| null;
isEdit: string| null;
num: number; num: number;
page: number; page: number;
total: number; total: number;
@ -39,7 +41,7 @@ interface States {
selectedParams: any; selectedParams: any;
selectedQuestionList: QuestionState[]; selectedQuestionList: QuestionState[];
questionSelectList: QuestionState[]; questionSelectList: QuestionState[];
queryCondition: string; selectedRowKeys: string[]; // 修改为存储 id 的数组
} }
class ExamPaperAdd extends Component<any, States> { class ExamPaperAdd extends Component<any, States> {
@ -50,6 +52,8 @@ class ExamPaperAdd extends Component<any, States> {
this.formRef = React.createRef(); this.formRef = React.createRef();
this.formRefSub = React.createRef(); this.formRefSub = React.createRef();
this.state = { this.state = {
id: null,
isEdit: null,
num: 10, num: 10,
page: 1, page: 1,
total: 0, total: 0,
@ -66,14 +70,22 @@ class ExamPaperAdd extends Component<any, States> {
selectedParams: {}, selectedParams: {},
selectedQuestionList: [], selectedQuestionList: [],
questionSelectList: [], questionSelectList: [],
queryCondition: '' selectedRowKeys: []
}; };
} }
// 初期 // 初期
componentDidMount() { componentDidMount() {
const id = sessionStorage.getItem('id');
const isEdit= sessionStorage.getItem('isEdit');
this.setState({ id: id ,isEdit: isEdit});
sessionStorage.removeItem('id');
sessionStorage.removeItem('isEdit');
this.findIndustry(); this.findIndustry();
this.findDict(); this.findDict();
if(isEdit === 'true'){
this.getDetail(id);
}
} }
// 监管行业 // 监管行业
@ -94,6 +106,41 @@ class ExamPaperAdd extends Component<any, States> {
}); });
} }
// 试卷详情
getDetail = (id: string|null) => {
getDetail(id).then((res: any) => {
if (res.data) {
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({ questions: newQuestions });
const formValues = {};
formValues['paperName'] = res.data.head.paperName;
formValues['industryId'] = res.data.head.industryId;
formValues['questionCount'] = res.data.head.questionCount;
formValues['totalScore'] = res.data.head.totalScore;
formValues['examDuration'] = res.data.head.examDuration;
formValues['durationType'] = res.data.head.durationType;
formValues['paperContent'] = res.data.head.paperContent;
this.formRef.current.setFieldsValue(formValues);
}
}).catch(() => {
message.error('获取题目详情失败,请重试');
});
};
// 随机生成题目 // 随机生成题目
handleRandomGenerate = () => { handleRandomGenerate = () => {
this.formRef.current.validateFields(['industryId', 'questionCount']) this.formRef.current.validateFields(['industryId', 'questionCount'])
@ -105,7 +152,7 @@ class ExamPaperAdd extends Component<any, States> {
.then((res: any) => { .then((res: any) => {
if (res.data) { if (res.data) {
if (res.data.length == 0) { if (res.data.length == 0) {
message.warning('题库没题了'); message.warning('题库题目不足');
this.setState({ questions: [] }); this.setState({ questions: [] });
return; return;
} }
@ -134,41 +181,55 @@ class ExamPaperAdd extends Component<any, States> {
message.error('获取随机题目失败'); message.error('获取随机题目失败');
}); });
}) })
.catch(() => {}); .catch(() => { });
}; };
// 打开手动选题模态框 // 打开手动选题模态框
handleOpenManualSelectionModal = () => { handleOpenManualSelectionModal = () => {
const { questions } = this.state; const { questions, selectedQuestionList } = this.state;
this.formRef.current.validateFields(['industryId', 'questionCount']) this.formRef.current.validateFields(['industryId', 'questionCount'])
.then((values: any) => { .then((values: any) => {
const industryId = values.industryId; const industryId = values.industryId;
const questionCount = values.questionCount; const questionCount = values.questionCount;
this.setState({ this.setState({
isModalVisible: true, isModalVisible: true,
selectedParams: { questions, industryId, questionCount } selectedQuestionList: questions,
selectedParams: { selectedQuestionList, industryId, questionCount }
}, () => {
this.handleQuery(); // 打开模态框时执行查询
}); });
}) })
.catch(() => {}); .catch(() => { });
}; };
// 关闭手动选题模态框 // 关闭手动选题模态框
handleCloseManualSelectionModal = () => { handleCloseManualSelectionModal = () => {
this.setState({ isModalVisible: false }); this.setState({
}; isModalVisible: false,
selectedParams: {},
// 处理选择试题添加到已选列表 selectedQuestionList: [],
handleSelectQuestion = (selectedRows:any) => { questionSelectList: [],
const { selectedQuestionList } = this.state; selectedRowKeys: [],
const newSelectedList = [...selectedQuestionList,...selectedRows]; listQuery: {
this.setState({ selectedQuestionList: newSelectedList }); industryId: undefined,
serviceTypeId: undefined,
questionContent: undefined
},
num: 10,
page: 1,
total: 0,
});
if (this.formRefSub.current) {
this.formRefSub.current.resetFields();
}
}; };
// 处理删除已选试题 // 处理删除已选试题
handleDeleteQuestion = (record:any) => { handleDeleteQuestion = (record: QuestionState) => {
const { questions } = this.state; const { selectedQuestionList} = this.state;
const newQuestion = questions.filter(question => question.id!== record.id); const newQuestion = selectedQuestionList.filter(item => item.id!== record.id);
this.setState({ questions: newQuestion }); const newSelectedRowKeys = newQuestion.map(item => item.id);
this.setState({ selectedQuestionList: newQuestion, selectedRowKeys: newSelectedRowKeys });
}; };
// 处理查询 // 处理查询
@ -185,7 +246,7 @@ class ExamPaperAdd extends Component<any, States> {
getList(num, page, listQuery) getList(num, page, listQuery)
.then((res: any) => { .then((res: any) => {
if (res.data) { if (res.data) {
this.setState({total: res.data.total}); this.setState({ total: res.data.total });
const newQuestions: QuestionState[] = res.data.data.map((questionData: any) => { const newQuestions: QuestionState[] = res.data.data.map((questionData: any) => {
const options = questionData.options.split(','); const options = questionData.options.split(',');
const answerOptions = options.map((option: any) => { const answerOptions = options.map((option: any) => {
@ -201,7 +262,9 @@ class ExamPaperAdd extends Component<any, States> {
answer: String(questionData.answer) answer: String(questionData.answer)
}; };
}); });
this.setState({ questionSelectList: newQuestions }); const { selectedQuestionList } = this.state;
const newSelectedRowKeys = selectedQuestionList.map(item => item.id);
this.setState({ questionSelectList: newQuestions, selectedRowKeys: newSelectedRowKeys });
} else { } else {
message.warning('未找到符合条件的试题'); message.warning('未找到符合条件的试题');
} }
@ -211,51 +274,132 @@ class ExamPaperAdd extends Component<any, States> {
}); });
}; };
// 确认
handleConfirmSelection = () => {
const { selectedQuestionList } = this.state;
this.setState({
questions: selectedQuestionList,
isModalVisible: false,
selectedParams: {},
selectedQuestionList: [],
questionSelectList: [],
selectedRowKeys: [],
listQuery: {
industryId: undefined,
serviceTypeId: undefined,
questionContent: undefined
},
num: 10,
page: 1,
total: 0,
});
if (this.formRefSub.current) {
this.formRefSub.current.resetFields();
}
};
// 保存试卷
handleSaveExamPaper = () => {
const { isEdit, id } = this.state;
this.formRef.current.validateFields()
.then((values: any) => {
const { questions } = this.state;
if (questions === null || questions.length === 0) {
message.error('请至少选择一道题目');
return;
}
const questionIds = questions.map(question => question.id);
const data = {
...values,
id,
questionIds
};
this.setState({ isLoading: true });
if (isEdit === 'true') {
update(data)
.then((res) => {
if (res.data) {
message.success('试卷更新成功');
this.props.history.push('/examPaperList');
} else {
message.error('试卷更新失败');
}
})
.catch(() => {
message.error('试卷更新时出错,请稍后重试');
})
.finally(() => {
this.setState({ isLoading: false });
});
} else {
save(data)
.then((res) => {
if (res.data) {
message.success('试卷保存成功');
this.props.history.push('/examPaperList');
} else {
message.error('试卷保存失败');
}
})
.catch(() => {
message.error('试卷保存时出错,请稍后重试');
})
.finally(() => {
this.setState({ isLoading: false });
});
}
});
};
render() { render() {
const { industryDict, serviceTypeDict, questions, isLoading, isModalVisible, questionSelectList } = this.state; const { industryDict, serviceTypeDict, questions, isLoading, isModalVisible, selectedQuestionList, questionSelectList, selectedRowKeys } = this.state;
// 分页切换 // 分页切换
const changePage = (current: number, pageSize?: number) => { const changePage = (current: number, pageSize?: number) => {
setTimeout(() => { setTimeout(() => {
this.setState({page: current, num: pageSize || 20}); this.setState({ page: current, num: pageSize || 20 });
this.handleQuery(); this.handleQuery();
}, 0); }, 0);
}; };
// 多少每页 // 多少每页
const selectChange = (page: number, num: number) => { const selectChange = (page: number, num: number) => {
this.setState({ page, num }); this.setState({ page, num });
this.handleQuery(); this.handleQuery();
}; };
// 页面跳转
const handleListQuestion = () => { const handleListQuestion = () => {
this.props.history.push('/examPaperList'); this.props.history.push('/examPaperList');
}; };
const columns: any = [ const columns: any = [
{ title: '序号', dataIndex: 'index', align: 'center', width: 60, { title: '序号', dataIndex: 'index', align: 'center', width: 60,
render: (_:number, __:number, index:number) => index + 1 render: (_: number, __: number, index: number) => index + 1
}, },
{ title: 'AQ服务类型', dataIndex: 'serviceTypeId', key: 'serviceTypeId', align: 'center', width: 150, { title: 'AQ服务类型', dataIndex: 'serviceTypeId', key: 'serviceTypeId', align: 'center', width: 150,
render: (serviceTypeId:any) => { render: (serviceTypeId: any) => {
const serviceType = serviceTypeDict?.find((item: { dictKey: string | number; dictValue: string }) => String(item.dictKey) === serviceTypeId); const serviceType = serviceTypeDict?.find((item: { dictKey: string | number; dictValue: string }) => String(item.dictKey) === serviceTypeId);
return serviceType? serviceType.dictValue : serviceTypeId; return serviceType? serviceType.dictValue : serviceTypeId;
} }
}, },
{ title: '题型', dataIndex: 'questionTypes', key: 'questionTypes', align: 'center', width: 80, { title: '题型', dataIndex: 'questionTypes', key: 'questionTypes', align: 'center', width: 80,
render: (questionTypes:any) => { render: (questionTypes: any) => {
if (questionTypes === '1') { if (questionTypes === '1') {
return '单选题'; return '单选题';
} else if (questionTypes === '2') { } else if (questionTypes === '2') {
return '多选题'; return '多选题';
} }
return questionTypes;} return questionTypes;
}
}, },
{ title: '题干', dataIndex: 'questionContent', key: 'questionContent', align: 'center', width: 450 }, { title: '题干', dataIndex: 'questionContent', key: 'questionContent', align: 'center', width: 450 },
{ title: '答案', dataIndex: 'answer', key: 'answer', align: 'center', width: 120 }, { title: '答案', dataIndex: 'answer', key: 'answer', align: 'center', width: 120 },
{ title: '操作', dataIndex: 'operation', align: 'center', width: 120, { title: '操作', dataIndex: 'operation', align: 'center', width: 120,
render: (_:number, record:number) => ( render: (_: number, record: QuestionState) => (
<Button type="link" danger onClick={() => this.handleDeleteQuestion(record)}></Button> <Button type="link" danger onClick={() => this.handleDeleteQuestion(record)}></Button>
) )
} }
]; ];
// 移除操作列
const columnsWithoutOperation = columns.filter((column: any) => column.dataIndex!== 'operation');
return ( return (
<div className="container"> <div className="container">
<Form ref={this.formRef}> <Form ref={this.formRef}>
@ -275,7 +419,7 @@ class ExamPaperAdd extends Component<any, States> {
rules={[{ required: true, message: '请选择监管行业' }]} rules={[{ required: true, message: '请选择监管行业' }]}
> >
<Select placeholder="请选择监管行业" style={{ width: 240 }} allowClear> <Select placeholder="请选择监管行业" style={{ width: 240 }} allowClear>
{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++) {
@ -294,6 +438,7 @@ class ExamPaperAdd extends Component<any, States> {
<Form.Item <Form.Item
label="题目数量:" label="题目数量:"
name="questionCount" name="questionCount"
style={{ width: 240 }}
rules={[{ required: true, message: '请输入题目数量' }]} rules={[{ required: true, message: '请输入题目数量' }]}
> >
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入题目数量" min={1} /> <Input type="number" style={{ textAlign: 'right' }} placeholder="请输入题目数量" min={1} />
@ -301,6 +446,7 @@ class ExamPaperAdd extends Component<any, States> {
<Form.Item <Form.Item
label="总分值:" label="总分值:"
name="totalScore" name="totalScore"
style={{ width: 240 }}
rules={[{ required: true, message: '请输入总分值' }]} rules={[{ required: true, message: '请输入总分值' }]}
> >
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入总分值" min={1} /> <Input type="number" style={{ textAlign: 'right' }} placeholder="请输入总分值" min={1} />
@ -308,14 +454,25 @@ class ExamPaperAdd extends Component<any, States> {
<Form.Item <Form.Item
label="考试时长:" label="考试时长:"
name="examDuration" name="examDuration"
style={{ width: 240 }}
rules={[{ required: true, message: '请输入考试时长' }]}
>
<Input type="number" style={{ textAlign: 'right' }} placeholder="请输入考试时长" min={1} />
</Form.Item>
<Form.Item
name="durationType"
style={{ width: 90 }}
rules={[{ required: true, message: '请输入考试时长' }]} rules={[{ required: true, message: '请输入考试时长' }]}
> >
<Input type="number" style={{ textAlign: 'right' }} addonAfter="分钟" placeholder="请输入考试时长" min={1} /> <Select>
<Option value="1">(min)</Option>
<Option value="2">(h)</Option>
</Select>
</Form.Item> </Form.Item>
</div> </div>
<Form.Item <Form.Item
label="内容描述:" label="内容描述:"
name="description" name="paperContent"
style={{ width: 1190 }} style={{ width: 1190 }}
rules={[{ required: true, message: '请输入内容描述' }]} rules={[{ required: true, message: '请输入内容描述' }]}
> >
@ -342,7 +499,7 @@ class ExamPaperAdd extends Component<any, States> {
> >
<span style={{ fontWeight: 'bold' }}>{index + 1}. {question.questionContent}</span> <span style={{ fontWeight: 'bold' }}>{index + 1}. {question.questionContent}</span>
<Form.Item> <Form.Item>
{ question.questionTypes === '1' ? ( {question.questionTypes === '1'? (
<Radio.Group value={question.answer}> <Radio.Group value={question.answer}>
{question.answerOptions.map((option) => ( {question.answerOptions.map((option) => (
<Radio value={option.value}> <Radio value={option.value}>
@ -351,7 +508,7 @@ class ExamPaperAdd extends Component<any, States> {
))} ))}
</Radio.Group> </Radio.Group>
) : ( ) : (
<Checkbox.Group value={question.answer ? question.answer.split(',') : []}> <Checkbox.Group value={question.answer? question.answer.split(',') : []}>
{question.answerOptions.map((option) => ( {question.answerOptions.map((option) => (
<Checkbox value={option.value}> <Checkbox value={option.value}>
{option.value}. {option.label} {option.value}. {option.label}
@ -376,7 +533,7 @@ class ExamPaperAdd extends Component<any, States> {
<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}> <Button type="primary" htmlType="submit" loading={isLoading} onClick={this.handleSaveExamPaper}>
</Button> </Button>
</div> </div>
@ -390,7 +547,7 @@ class ExamPaperAdd extends Component<any, States> {
<Button key="cancel" onClick={this.handleCloseManualSelectionModal}> <Button key="cancel" onClick={this.handleCloseManualSelectionModal}>
</Button>, </Button>,
<Button key="ok" type="primary" onClick={this.handleCloseManualSelectionModal}> <Button key="ok" type="primary" onClick={this.handleConfirmSelection}>
</Button> </Button>
]} ]}
@ -399,75 +556,100 @@ class ExamPaperAdd extends Component<any, States> {
> >
<div> <div>
<h3 style={{ fontWeight: 'bold' }}></h3> <h3 style={{ fontWeight: 'bold' }}></h3>
<div style={{ height: '500', overflowY: 'auto' }}>
<Table <Table
dataSource={questions} dataSource={selectedQuestionList}
columns={columns} columns={columns}
pagination={{ pagination={{
showQuickJumper: true,
pageSize: 5 pageSize: 5
}} }}
/> />
</div>
</div> </div>
<div> <div>
<h3 style={{ fontWeight: 'bold' }}></h3> <h3 style={{ fontWeight: 'bold' }}></h3>
<Form <Form
className="filter" className="filter"
layout="inline" layout="inline"
ref={this.formRefSub} ref={this.formRefSub}
>
<Form.Item
label="AQ服务类型:"
name="serviceTypeId"
> >
<Form.Item <Select placeholder="请选择AQ服务类型"
label="AQ服务类型:" style={{ width: 240 }}
name="serviceTypeId" allowClear>
> {
<Select placeholder="请选择AQ服务类型" serviceTypeDict && serviceTypeDict.length > 0?
style={{ width: 240 }} (() => {
allowClear> let rows = [];
{ for (let i = 0; i < serviceTypeDict.length; i++) {
serviceTypeDict && serviceTypeDict.length > 0? const item = serviceTypeDict[i];
(() => { rows.push(
let rows = []; <Option value={item.dictKey}>{item.dictValue}</Option>
for (let i = 0; i < serviceTypeDict.length; i++) { );
const item = serviceTypeDict[i]; }
rows.push( return rows;
<Option value={item.dictKey}>{item.dictValue}</Option> })()
); :
} <Option disabled></Option>
return rows; }
})() </Select>
: </Form.Item>
<Option disabled></Option> <Form.Item
} label="题干条件:"
</Select> name="questionContent"
</Form.Item> >
<Form.Item <Input placeholder="请输入题干条件" style={{ width: 500 }}/>
label="题干条件:" </Form.Item>
name="questionContent" <Form.Item>
> <Button type="primary" onClick={this.handleQuery}></Button>
<Input placeholder="请输入题干条件" style={{ width: 500 }}/> </Form.Item>
</Form.Item> </Form>
<Form.Item> </div>
<Button type="primary" onClick={this.handleQuery}></Button> <Table
</Form.Item> dataSource={questionSelectList}
</Form> columns={columnsWithoutOperation}
</div> rowKey="id"
<Table rowSelection={{
dataSource={questionSelectList} selectedRowKeys: selectedRowKeys,
columns={columns} onChange: (newSelectedRowKeys, selectedRows) => {
rowSelection={{ const { selectedQuestionList,questionSelectList } = this.state;
onChange: this.handleSelectQuestion const newSelectedQuestionList = selectedRows.reduce((acc, row) => {
}} if (!acc.some(item => item.id === row.id)) {
pagination={{ acc.push(row);
total: this.state.total, }
current: this.state.page, return acc;
showQuickJumper: true, }, [...selectedQuestionList]);
showSizeChanger: true,
showTotal: (total) => `${total}`, const deselectedIds = questionSelectList
onShowSizeChange: selectChange, .filter(item =>!newSelectedRowKeys.includes(item.id))
onChange: changePage .map(item => item.id);
const finalSelectedQuestionList = newSelectedQuestionList.filter(
item =>!deselectedIds.includes(item.id)
);
const selectedRowKeys = finalSelectedQuestionList.map(item => String(item.id));
this.setState({
selectedQuestionList: finalSelectedQuestionList,
selectedRowKeys: selectedRowKeys
});
},
getCheckboxProps: () => ({
disabled: false
})
}} }}
/> pagination={{
total: this.state.total,
current: this.state.page,
showQuickJumper: true,
showSizeChanger: true,
showTotal: (total) => `${total}`,
onShowSizeChange: selectChange,
onChange: changePage,
pageSize: 5
}}
/>
</Modal> </Modal>
</div> </div>
); );

@ -1,7 +1,8 @@
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 { TableRowSelection } from 'antd/lib/table/interface';
import {deleteSingle, deleteMultiple, findIndustry, getList, updatePaperStatus, batchUpdatePaperStatus} from 'api/examPaper'; import { deleteSingle, deleteMultiple, getList, updatePaperStatus, batchUpdatePaperStatus } from 'api/examPaper';
import { findIndustry } from 'api/question';
const { Option } = Select; const { Option } = Select;
@ -267,11 +268,6 @@ class ExamPaperList extends Component<any, States> {
}) })
}; };
// 页面跳转
const handleAddQuestion = () => {
this.props.history.push('/examPaperAdd');
};
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) => {
@ -302,11 +298,14 @@ class ExamPaperList extends Component<any, States> {
render: (record: any) => [ render: (record: any) => [
<span className='mr10 link' onClick={() => { <span className='mr10 link' onClick={() => {
this.setState({title: '编辑', modalWidth: '85%'}) this.setState({title: '编辑', modalWidth: '85%'})
this.props.history.push(`/questionUp/${record.id}`); sessionStorage.setItem('id', String(record.id));
sessionStorage.setItem('isEdit', "true");
this.props.history.push(`/examPaperAdd`);
}}></span>, }}></span>,
<span className='mr10 link' onClick={() => { <span className='mr10 link' onClick={() => {
this.setState({title: '预览', modalWidth: '85%'}) this.setState({title: '编辑', modalWidth: '85%'})
this.deleteSingle(record.id); sessionStorage.setItem('id', String(record.id));
this.props.history.push(`/examPaperView`);
}}></span>, }}></span>,
<span className='mr10 link' onClick={() => { <span className='mr10 link' onClick={() => {
this.updatePaperStatus(record.id, record.paperStatus); // 调用更新状态的方法 this.updatePaperStatus(record.id, record.paperStatus); // 调用更新状态的方法
@ -400,7 +399,9 @@ class ExamPaperList extends Component<any, States> {
<Button type="default" onClick={() => this.batchUpdatePaperStatus(0)}></Button> <Button type="default" onClick={() => this.batchUpdatePaperStatus(0)}></Button>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Button type="primary" onClick={handleAddQuestion}></Button> <Button type="primary" onClick={() => {
this.props.history.push(`/examPaperAdd`);
}}></Button>
</Form.Item> </Form.Item>
</Form> </Form>
<Table <Table

@ -0,0 +1,229 @@
import React, { Component } from 'react';
import { Form, Input, Button, Radio, Checkbox, Select, message} from 'antd';
import { getDetail} from 'api/examPaper';
import { findIndustry} from 'api/question';
const { Option } = Select;
interface optionsState {
value: string;
label: string;
}
// 定义单个试题的状态接口
interface QuestionState {
id: string;
serviceTypeId: string;
questionTypes: string;
questionContent: string;
answerOptions: optionsState[];
answer: string | null;
}
// 定义组件的状态接口
interface States {
id: string | undefined;
industryDict: any;
paperName : string | undefined;
industryId : number | undefined;
questionCount : number | undefined;
totalScore : number | undefined;
examDuration : string | undefined;
durationType : number | undefined;
paperContent : string | undefined;
questions: QuestionState[];
}
class ExamPaperView extends Component<any, States> {
formRef: any;
constructor(props: any) {
super(props);
this.formRef = React.createRef();
this.state = {
id: undefined,
industryDict: undefined,
paperName: undefined,
industryId: undefined,
questionCount: undefined,
totalScore: undefined,
examDuration: undefined,
durationType: undefined,
paperContent: undefined,
questions: [],
};
}
// 初期
componentDidMount() {
const id = sessionStorage.getItem('id');
sessionStorage.removeItem('id');
this.findIndustry();
this.getDetail(id);
}
// 监管行业
findIndustry() {
findIndustry().then((res: any) => {
if (res.data) {
this.setState({ industryDict: res.data });
}
});
}
// 试卷详情
getDetail = (id: string | null) => {
getDetail(id).then((res: any) => {
if (res.data) {
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)
};
});
const paperName = res.data.head.paperName;
const industryId = res.data.head.industryId;
const questionCount = res.data.head.questionCount;
const totalScore = res.data.head.totalScore;
const examDuration = res.data.head.examDuration;
const durationType = res.data.head.durationType;
const paperContent = res.data.head.paperContent;
this.setState({
questions: newQuestions,
paperName,
industryId,
questionCount,
totalScore,
examDuration,
durationType,
paperContent,
});
}
}).catch(() => {
message.error('获取题目详情失败,请重试');
});
};
findDurationTypeName = (durationType:number | undefined) => {
switch (durationType) {
case 1:
return '分(min)';
case 2:
return '时(h)';
default:
return '未知';
}
};
findIndustryName = (industryId:number | undefined) => {
const { industryDict } = this.state;
if (industryDict) {
const industry = industryDict.find((item:any) => item.industryId === String(industryId));
return industry ? industry.industryName : '未知行业';
}
return '未知行业';
};
render() {
const {
questions,
paperName,
industryId,
questionCount,
totalScore,
examDuration,
durationType,
paperContent,
} = this.state;
// 页面跳转
const handleListQuestion = () => {
this.props.history.push('/examPaperList');
};
return (
<div className="container">
<Form ref={this.formRef}>
<h3 style={{ fontWeight: 'bold' }}></h3>
<Form.Item label="试卷名称:">
<span>{paperName}</span>
</Form.Item>
<div style={{ display: 'flex', gap: 20 }}>
<Form.Item label="监管行业:">
<span>{this.findIndustryName(industryId)}</span>
</Form.Item>
<Form.Item label="题目数量:">
<span>{questionCount}</span>
</Form.Item>
<Form.Item label="总分值:">
<span>{totalScore}</span>
</Form.Item>
<Form.Item label="考试时长:">
<span>{examDuration}</span>
</Form.Item>
<Form.Item label="">
<span>{this.findDurationTypeName(durationType)}</span>
</Form.Item>
</div>
<Form.Item label="内容描述:">
<span>{paperContent}</span>
</Form.Item>
<div style={{ display: 'flex' }}>
<h3 style={{ fontWeight: 'bold' }}></h3>
</div>
{questions.map((question, index) => (
<div
style={{
border: '1px solid #e8e8e8',
padding: 10,
marginBottom: 10
}}
>
<span style={{ fontWeight: 'bold' }}>{index + 1}. {question.questionContent}</span>
<Form.Item>
{question.questionTypes === '1'? (
<Radio.Group value={question.answer}>
{question.answerOptions.map((option) => (
<Radio value={option.value}>
{option.value}. {option.label}
</Radio>
))}
</Radio.Group>
) : (
<Checkbox.Group value={question.answer? question.answer.split(',') : []}>
{question.answerOptions.map((option) => (
<Checkbox value={option.value}>
{option.value}. {option.label}
</Checkbox>
))}
</Checkbox.Group>
)}
</Form.Item>
</div>
))}
<div
style={{
textAlign: 'right',
position: 'fixed',
bottom: 10,
right: 10,
width: '100%',
backgroundColor: 'white',
zIndex: 1000
}}
>
<Button type="default" htmlType="button" onClick={
handleListQuestion
}>
</Button>
</div>
</Form>
</div>
);
}
}
export default ExamPaperView;
Loading…
Cancel
Save