diff --git a/packages/examination/src/api/examPaper/index.tsx b/packages/examination/src/api/examPaper/index.tsx index da486ab..65d2f10 100644 --- a/packages/examination/src/api/examPaper/index.tsx +++ b/packages/examination/src/api/examPaper/index.tsx @@ -65,58 +65,48 @@ export function batchUpdatePaperStatus(data: any) { } /* -* 新增试卷 +* 题目详情 */ -export function add(questionData: object) { +export function getDetail(id: string|null) { return axios({ - url: "/ex/question/add", - method: 'post', - data: questionData + url: '/ex/examPaper/getDetail?id=' + id, + method: 'get' }); } /* -* 修改题目 +* 随机查询 */ -export function update(questionData: object) { +export function getRandomQuestions(industryId: string, questionCount: number){ + const data = { + industryId:industryId, + questionCount:questionCount + }; return axios({ - url: "/ex/question/update", + url: "/ex/examPaper/getRandomQuestions", method: 'post', - data: questionData - }); -} - -/* -* 行业 -*/ -export function findIndustry() { - return axios({ - url: '/ex/question/findIndustry', - method: 'get' + data: data }) } /* -* 题目详情 +* 新增试卷 */ -export function getDetail(id: string) { +export function save(data: object) { return axios({ - url: '/ex/question/getDetail?id=' + id, - method: 'get' + url: "/ex/examPaper/add", + method: 'post', + data: data }); } /* -* 查询 +* 更新试卷 */ -export function getRandomQuestions(industryId: string, questionCount: number){ - const data = { - industryId:industryId, - questionCount:questionCount - }; +export function update(data: object) { return axios({ - url: "/ex/examPaper/getRandomQuestions", + url: "/ex/examPaper/update", method: 'post', data: data - }) + }); } diff --git a/packages/examination/src/components/contentMain/index.js b/packages/examination/src/components/contentMain/index.js index 98f6d0f..53f14f4 100644 --- a/packages/examination/src/components/contentMain/index.js +++ b/packages/examination/src/components/contentMain/index.js @@ -35,9 +35,9 @@ import ExamPaperList from 'views/examPaper/examPaperList'; import ExamDetailAnalysis from "../../views/exam-online/exam-detail-analysis"; import ExamPaperAnalysis from "../../views/exam-online/exam-paper-analysis"; import ExamPaperAdd from 'views/examPaper/examPaperAdd'; +import ExamPaperView from 'views/examPaper/examPaperView'; import ExamPaperAnalysisDetail from "../../views/exam-online/exam_paper_analysis_detail"; - class ContentMain extends Component { render() { return ( @@ -61,7 +61,6 @@ class ContentMain extends Component { - diff --git a/packages/examination/src/views/examPaper/examPaperAdd.tsx b/packages/examination/src/views/examPaper/examPaperAdd.tsx index 676fc46..43f033d 100644 --- a/packages/examination/src/views/examPaper/examPaperAdd.tsx +++ b/packages/examination/src/views/examPaper/examPaperAdd.tsx @@ -1,8 +1,8 @@ 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"; +import { Form, Input, Button, Radio, Checkbox, Select, message, Modal, Table } from 'antd'; +import { getRandomQuestions, save, update, getDetail} from 'api/examPaper'; +import { getList ,findIndustry} from 'api/question'; +import { dictionary } from "../../api/dict"; const { Option } = Select; @@ -23,6 +23,8 @@ interface QuestionState { // 定义组件的状态接口 interface States { + id: string| null; + isEdit: string| null; num: number; page: number; total: number; @@ -39,7 +41,7 @@ interface States { selectedParams: any; selectedQuestionList: QuestionState[]; questionSelectList: QuestionState[]; - queryCondition: string; + selectedRowKeys: string[]; // 修改为存储 id 的数组 } class ExamPaperAdd extends Component { @@ -50,6 +52,8 @@ class ExamPaperAdd extends Component { this.formRef = React.createRef(); this.formRefSub = React.createRef(); this.state = { + id: null, + isEdit: null, num: 10, page: 1, total: 0, @@ -66,14 +70,22 @@ class ExamPaperAdd extends Component { selectedParams: {}, selectedQuestionList: [], questionSelectList: [], - queryCondition: '' + selectedRowKeys: [] }; } // 初期 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.findDict(); + if(isEdit === 'true'){ + this.getDetail(id); + } } // 监管行业 @@ -94,6 +106,41 @@ class ExamPaperAdd extends Component { }); } + // 试卷详情 + 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 = () => { this.formRef.current.validateFields(['industryId', 'questionCount']) @@ -105,7 +152,7 @@ class ExamPaperAdd extends Component { .then((res: any) => { if (res.data) { if (res.data.length == 0) { - message.warning('题库没题了'); + message.warning('题库题目不足'); this.setState({ questions: [] }); return; } @@ -134,41 +181,55 @@ class ExamPaperAdd extends Component { message.error('获取随机题目失败'); }); }) - .catch(() => {}); + .catch(() => { }); }; // 打开手动选题模态框 handleOpenManualSelectionModal = () => { - const { questions } = this.state; + const { questions, selectedQuestionList } = 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 } + selectedQuestionList: questions, + selectedParams: { selectedQuestionList, industryId, questionCount } + }, () => { + this.handleQuery(); // 打开模态框时执行查询 }); }) - .catch(() => {}); + .catch(() => { }); }; // 关闭手动选题模态框 handleCloseManualSelectionModal = () => { - this.setState({ isModalVisible: false }); - }; - - // 处理选择试题添加到已选列表 - handleSelectQuestion = (selectedRows:any) => { - const { selectedQuestionList } = this.state; - const newSelectedList = [...selectedQuestionList,...selectedRows]; - this.setState({ selectedQuestionList: newSelectedList }); + this.setState({ + 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(); + } }; // 处理删除已选试题 - handleDeleteQuestion = (record:any) => { - const { questions } = this.state; - const newQuestion = questions.filter(question => question.id!== record.id); - this.setState({ questions: newQuestion }); + handleDeleteQuestion = (record: QuestionState) => { + const { selectedQuestionList} = this.state; + const newQuestion = selectedQuestionList.filter(item => item.id!== record.id); + const newSelectedRowKeys = newQuestion.map(item => item.id); + this.setState({ selectedQuestionList: newQuestion, selectedRowKeys: newSelectedRowKeys }); }; // 处理查询 @@ -185,7 +246,7 @@ class ExamPaperAdd extends Component { getList(num, page, listQuery) .then((res: any) => { 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 options = questionData.options.split(','); const answerOptions = options.map((option: any) => { @@ -201,7 +262,9 @@ class ExamPaperAdd extends Component { 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 { message.warning('未找到符合条件的试题'); } @@ -211,51 +274,132 @@ class ExamPaperAdd extends Component { }); }; + // 确认 + 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() { - 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) => { setTimeout(() => { - this.setState({page: current, num: pageSize || 20}); + 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 + render: (_: number, __: number, index: number) => index + 1 }, { 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); return serviceType? serviceType.dictValue : serviceTypeId; } }, { title: '题型', dataIndex: 'questionTypes', key: 'questionTypes', align: 'center', width: 80, - render: (questionTypes:any) => { + render: (questionTypes: any) => { if (questionTypes === '1') { return '单选题'; } else if (questionTypes === '2') { 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: 'operation', align: 'center', width: 120, - render: (_:number, record:number) => ( + render: (_: number, record: QuestionState) => ( ) } ]; + + // 移除操作列 + const columnsWithoutOperation = columns.filter((column: any) => column.dataIndex!== 'operation'); return (
@@ -275,7 +419,7 @@ class ExamPaperAdd extends Component { rules={[{ required: true, message: '请选择监管行业' }]} > @@ -301,6 +446,7 @@ class ExamPaperAdd extends Component { @@ -308,14 +454,25 @@ class ExamPaperAdd extends Component { + + + - +
@@ -342,7 +499,7 @@ class ExamPaperAdd extends Component { > {index + 1}. {question.questionContent} - { question.questionTypes === '1' ? ( + {question.questionTypes === '1'? ( {question.answerOptions.map((option) => ( @@ -351,7 +508,7 @@ class ExamPaperAdd extends Component { ))} ) : ( - + {question.answerOptions.map((option) => ( {option.value}. {option.label} @@ -376,7 +533,7 @@ class ExamPaperAdd extends Component { - @@ -390,7 +547,7 @@ class ExamPaperAdd extends Component { , - ]} @@ -399,75 +556,100 @@ class ExamPaperAdd extends Component { >

已选列表

-
-

试题选择

- + - - - - - - - - - - -
-
`共 ${total} 条`, - onShowSizeChange: selectChange, - onChange: changePage + + + + + + + + + + +
{ + const { selectedQuestionList,questionSelectList } = this.state; + const newSelectedQuestionList = selectedRows.reduce((acc, row) => { + if (!acc.some(item => item.id === row.id)) { + acc.push(row); + } + return acc; + }, [...selectedQuestionList]); + + const deselectedIds = questionSelectList + .filter(item =>!newSelectedRowKeys.includes(item.id)) + .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 + }} + /> ); diff --git a/packages/examination/src/views/examPaper/examPaperList.tsx b/packages/examination/src/views/examPaper/examPaperList.tsx index 8034004..e4d2b96 100644 --- a/packages/examination/src/views/examPaper/examPaperList.tsx +++ b/packages/examination/src/views/examPaper/examPaperList.tsx @@ -1,7 +1,8 @@ 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, findIndustry, getList, updatePaperStatus, batchUpdatePaperStatus} from 'api/examPaper'; +import { deleteSingle, deleteMultiple, getList, updatePaperStatus, batchUpdatePaperStatus } from 'api/examPaper'; +import { findIndustry } from 'api/question'; const { Option } = Select; @@ -267,11 +268,6 @@ class ExamPaperList extends Component { }) }; - // 页面跳转 - const handleAddQuestion = () => { - this.props.history.push('/examPaperAdd'); - }; - const columns: any = [ { title: '序号', dataIndex: 'index', key: 'index', align: 'center', width: 60, render: (_: number, __: number, index: number) => { @@ -302,11 +298,14 @@ class ExamPaperList extends Component { render: (record: any) => [ { 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`); }}>编辑, { - this.setState({title: '预览', modalWidth: '85%'}) - this.deleteSingle(record.id); + this.setState({title: '编辑', modalWidth: '85%'}) + sessionStorage.setItem('id', String(record.id)); + this.props.history.push(`/examPaperView`); }}>预览, { this.updatePaperStatus(record.id, record.paperStatus); // 调用更新状态的方法 @@ -400,7 +399,9 @@ class ExamPaperList extends Component { - +
{ + 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 ( +
+
+

基本信息

+ + {paperName} + +
+ + {this.findIndustryName(industryId)} + + + {questionCount} + + + {totalScore} + + + {examDuration} + + + {this.findDurationTypeName(durationType)} + +
+ + {paperContent} + +
+

试题详情

+
+ {questions.map((question, index) => ( +
+ {index + 1}. {question.questionContent} + + {question.questionTypes === '1'? ( + + {question.answerOptions.map((option) => ( + + {option.value}. {option.label} + + ))} + + ) : ( + + {question.answerOptions.map((option) => ( + + {option.value}. {option.label} + + ))} + + )} + +
+ ))} +
+ +
+ +
+ ); + } +} +export default ExamPaperView; \ No newline at end of file