diff --git a/admin/src/pages/course/subject/index.tsx b/admin/src/pages/course/subject/index.tsx index b241e89..5e1df6e 100644 --- a/admin/src/pages/course/subject/index.tsx +++ b/admin/src/pages/course/subject/index.tsx @@ -13,7 +13,7 @@ import UpdateForm from './components/UpdateForm'; import { copySubject, addSubject, updateSubject, removeSubject, querySubjectList, queryListChapterBySubject } from './service'; import type { TableListItem, TableListPagination } from './data'; import { queryCourseListByTag } from '../option/service'; - +const { confirm } = Modal; /** 章节列表项定义 */ const chapterColumns: ProColumns[] = [ { @@ -64,7 +64,7 @@ const chapterColumns: ProColumns[] = [ console.log(courses, 'courses:::'); return courses; }, - + }, { title: '学时', @@ -155,7 +155,7 @@ const TableList: React.FC = () => { const actionRef = useRef(); const actionChapterRef = useRef(); - + const [currentRow, setCurrentRow] = useState(); const [selectedRowsState, setSelectedRows] = useState([]); @@ -215,7 +215,7 @@ const TableList: React.FC = () => { }, { title: '信息', - dataIndex: 'total_course_minutes', + dataIndex: 'total_course_minutes', sorter: false, hideInSearch: true, width: 200, @@ -288,15 +288,27 @@ const TableList: React.FC = () => { { - handleRemove([{ key: record?.subject_id }]); // 调用批量删除函数(如果接口不支持批量需要在service中处理) - setSelectedRows([]); - actionRef.current?.reloadAndRest?.(); + showConfirm(record) + }}> 删除 , ], }, ]; + const showConfirm=async (record)=>{ + confirm({ + title: '确认删除主题吗?', + centered:true, + onOk() { + handleRemove([{ key: record?.subject_id }]); // 调用批量删除函数(如果接口不支持批量需要在service中处理) + setSelectedRows([]); + actionRef.current?.reloadAndRest?.(); + }, + onCancel() { + }, + }); + }; return ( diff --git a/admin/src/pages/course/subject/step/index.tsx b/admin/src/pages/course/subject/step/index.tsx index 8963745..c515282 100644 --- a/admin/src/pages/course/subject/step/index.tsx +++ b/admin/src/pages/course/subject/step/index.tsx @@ -387,7 +387,6 @@ export default () => { /* request={async () => { const data = await getSubjectInfo(5); - console.log('getSubjectInfo', data); // return { data: bean } @@ -396,14 +395,20 @@ export default () => { onFinish={async (value: any) => { const url = value?.upload[0]?.url?.replace('/dsideal_yy/html/','') || value?.upload[0]?.response?.url; - const { data } = await saveSubject({ + const info = await saveSubject({ ...value, subject_id: params?.id, attachment_json: `{ "url": "${url}"}` }); - setSubjectIntro({subject_id:data?.subject_id, subject_name: value?.subject_name, subject_describe:value?.subject_describe}); - return true; + if(info.code!==2000){ + message.warning(info.msg); + return false; + }else { + setSubjectIntro({subject_id:info?.data.subject_id, subject_name: value?.subject_name, subject_describe:value?.subject_describe}); + return true; + } + }} > @@ -498,7 +503,7 @@ export default () => { title="主题信息" /* request={async () => { - console.log('step2 主题信息') + // console.log('step2 主题信息') return Promise.resolve({ success: true, data: { id: '这是一段文本', object: '', date: '2020-07-30 08:00', duration: '', grade: 100, through: '>60', learn: '>20 min', times: 2 }, @@ -519,6 +524,7 @@ export default () => { rowKey="chapter_id" options={false} search={false} + params={subjectIntro} toolBarRender={() => [ , ]} request={async (value) => { + const { data } = await queryListChapterBySubject({ - subject_id: params?.id || 0, + subject_id: subjectIntro.subject_id, page_number: value?.current || 1, page_size: value?.pageSize, }); diff --git a/admin/src/pages/examinationrules/attestation/step/index.tsx b/admin/src/pages/examinationrules/attestation/step/index.tsx index 97e6f1f..336a353 100644 --- a/admin/src/pages/examinationrules/attestation/step/index.tsx +++ b/admin/src/pages/examinationrules/attestation/step/index.tsx @@ -4,12 +4,12 @@ import { ModalForm, ProFormInstance } from '@ant-design/pro-form'; import { ProFormRadio } from '@ant-design/pro-form'; import ProForm, {StepsForm, ProFormText, ProFormSelect, ProFormDateRangePicker } from '@ant-design/pro-form'; import ProCard from '@ant-design/pro-card'; -import { Button, Checkbox, Col, Divider, Input, List, Menu, message, Radio, Row, Space } from 'antd'; +import { Button, Checkbox, Col, Divider, Input, List, Menu, message, Radio, Row, Space, Typography } from 'antd'; import { PageContainer } from '@ant-design/pro-layout'; import ProDescriptions from '@ant-design/pro-descriptions'; import styles from './index.less' -import { saveRules, querySubjectList, queryRulesView, queryRulesList, queryRulesPaper, saveQuestionTypeScore, autoPaperOfficial } from '../../service'; -import { queryQuestionType } from '@/pages/questionbank/service'; +import { saveRules, querySubjectList, queryRulesView, queryRulesList, queryRulesPaper, saveQuestionTypeScore, autoPaperOfficial, queryPaperQuestionList } from '../../service'; +import { queryQuestionList, queryQuestionType } from '@/pages/questionbank/service'; import ProTable, { ActionType, EditableProTable, ProColumns } from '@ant-design/pro-table'; //import { TableListPagination } from '@/pages/ListTableList2/data'; import { DiffOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; @@ -19,10 +19,15 @@ import AutoSelector from '../components/AutoSelector'; import QuestionSelector from '../../components/QuestionSelector'; import { getSubjectInfo } from '@/pages/course/subject/service'; +/** 选项序号 */ +const labels = ['A','B','C','D','E','F','G','H','I','J','K']; + /** 题型序号 */ const numberType = ['一','二','三','四','五','六','七','八','九','十']; -const questions = [] + + export default () => { + const questionNumber = [1,1,1]; const params = useParams(); const formRef = useRef(); @@ -33,6 +38,7 @@ export default () => { const [currentStep, setCurrentStep] = useState(0); const [questionTypeValues, setQuestionTypeValues] = useState([]); // 题型数据[{count:0, score:0, score_harf:0}] + const [questionType, setQuestionType] = useState([]); // 题型 /** 自动组卷窗口 */ const [autoModalVisible, handleAutoModalVisible] = useState(false); @@ -41,6 +47,16 @@ export default () => { /** 试卷详情窗口 */ const [paperModalVisible, handlePaperModalVisible] = useState(false); + /** 查看试卷 */ + const { data: questions, run } = useRequest(async (params) => { + console.log('questions', questions) + return queryPaperQuestionList(params); + },{ + manual: true, + formatResult: (result) => { + return result?.question_list; + }}); + /** 列表项定义 */ const columns: ProColumns[] = [ { @@ -128,6 +144,10 @@ export default () => { onClick={() => { //console.log('entity', entity); //setCurrentRow(record); + // + run({ + paper_id: record?.paper_id, + }); // 获取试卷试题列表 handlePaperModalVisible(true); // 试卷详情 }} > @@ -171,7 +191,6 @@ export default () => { } console.log(ruleData, 'ruleData'); - const [questionType, setQuestionType] = useState([]); // 题型 /** 获取题型 */ const { data: questionTypeData } = useRequest(() => { return queryQuestionType(); @@ -493,12 +512,57 @@ export default () => { return true; }} > - {questions && questions?.map((item)=>{ + {questionType && questionType?.map((typeItem, index)=>{ + //console.log('questionType:::', questionType) return <> - + {questions?.length === 0 &&
暂无数据
} +
{numberType[index]}. {typeItem?.name}
+
+ { questions && questions.map((item, idx)=>( + (typeItem?.code === item?.question_type) && +
+ + {questionNumber[item?.question_type]++}. {item?.question_stem} + + {(item?.question_type === 0) && // 单选题 +
+ {item?.answers && item?.answers.map((anster, k)=>( +
+ {anster?.is_true === '0' && {labels[k]} } + {anster?.is_true === '1' && {labels[k]} } + {anster?.answer} +
+ ))} +
+ } + {(item?.question_type === 1) && // 多选题 +
+ {item?.answers && item?.answers.map((anster, k)=>( +
+ {anster?.is_true === '0' && {labels[k]} } + {anster?.is_true === '1' && {labels[k]} } + {anster?.answer} +
+ ))} +
+ } + {(item?.question_type === 2) && // 判断选题 +
+ {item?.answers && item?.answers.map((anster, k)=>( +
+ {anster?.is_true === '0' && {labels[k]} } + {anster?.is_true === '1' && {labels[k]} } + {anster?.answer} +
+ ))} +
+ } +
+ ))} +
})} - 试卷详情正在调整布局。。。。。。 +
diff --git a/admin/src/pages/examinationrules/components/QuestionPaper.tsx b/admin/src/pages/examinationrules/components/QuestionPaper.tsx new file mode 100644 index 0000000..18e6103 --- /dev/null +++ b/admin/src/pages/examinationrules/components/QuestionPaper.tsx @@ -0,0 +1,541 @@ +/** 试卷 */ +//import { AlignLeftOutlined, PlusOutlined } from '@ant-design/icons'; +import { Switch, Button, Card, Col, List, Menu, Progress, Row, Typography, Space, Divider, Radio, Checkbox, Tag, Dropdown, Upload, Modal, Form, Input, message, Popconfirm } from 'antd'; +import { PageContainer } from '@ant-design/pro-layout'; +//import { useRequest } from 'umi'; +//import { queryFakeList } from './service'; +//import type { CardListItemDataType } from './data'; +import styles from './style.less'; +//import SubMenu from 'antd/lib/menu/SubMenu'; +//import ProCard from '@ant-design/pro-card'; +import ProList from '@ant-design/pro-list'; +import { ReactText, useEffect, useRef, useState } from 'react'; +import { PlusOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EditOutlined, EyeOutlined, EyeInvisibleOutlined, DownOutlined, UserOutlined } from '@ant-design/icons'; +import { exportQuestionTemplate, queryQuestionById, queryQuestionList, queryQuestionType, removeQuestion, saveQuestion } from './service'; +import { useParams, useRequest, history, useRouteMatch } from 'umi'; +import { queryCourseListByTag, queryCourseView, queryTagList } from '@/pages/course/option/service'; +import ProForm, { BetaSchemaForm, ProFormCheckbox, ProFormList, ProFormRadio, ProFormSelect, ProFormText } from '@ant-design/pro-form'; +import { DataItem } from '../dashboard/analysis/data'; +import { ActionType, ProColumns } from '@ant-design/pro-table'; +import ProFormRichEdit from '../course/subject/components/ProFormRichEdit'; +import { TableListItem } from '../course/option/data'; + +//const { Paragraph } = Typography; +const { Text, Link } = Typography; + +const labels = ['A','B','C','D','E','F','G','H','I','J','K']; +const parsingMap = new Map() +console.log('first'); +const addType = 0; + +/** + * 试卷显示 + * @returns + * React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。 + */ +const QuestionPaper = (props: any, ref: any) => { + //const match = useRouteMatch(); + //console.log('match', match); + + //const type = history.location.pathname === '/questionbank/attestation' ? 1 : 0 ; // 题库类型 + const actionRef = useRef(); + + const [questionType, setQuestionType] = useState([]); // #1. 题型 + + const [parsing, setParsing] = useState(); + const [expandedDescRowKeys, setExpandedDescRowKeys] = useState([]); // 展开解析设置 + + /** 表单项定义 */ + const columns: ProColumns[] = [ + { + title: '题干', + dataIndex: 'question_stem', + valueType: 'text', + hideInTable: false, + hideInDescriptions: false, + hideInForm: false, + hideInSearch: true, + formItemProps: { + rules: [ + { + required: true, + message: '请填题干内容', + }, + ] + }, + }, + { + title: '选项', + dataIndex: 'answers', + valueType: 'text', + sorter: false, + hideInTable: false, + hideInForm: false, + hideInSearch: true, + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + + ) + }, + { + title: '答案', + dataIndex: 'answertrue', + valueType: 'text', + sorter: false, + hideInTable: false, + hideInForm: false, + hideInSearch: true, + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + // 0 单选 1 多选 2 判断 + (addType?.value !== 1 ) ? + + : + + + ) + /* + formItemProps: { + rules: [ + { + required: true, + message: '请填答案', + }, + ] + },*/ + }, + { + title: '解析', + dataIndex: 'parsing', + valueType: 'textarea', + sorter: false, + hideInTable: false, + hideInForm: false, + hideInSearch: true, + formItemProps: { + rules: [ + { + required: true, + message: '请填写试题解析', + }, + ] + }, + renderText: (val: string) => (
), + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + + ), + }, + ] + + /** 获取题型 */ + const { data } = useRequest(() => { + return queryQuestionType(); + },{ + formatResult: (result) => { + return result.list; + } + }); + +/* + const { data: template } = useRequest(() => { + return exportQuestionTemplate(); + }); + */ + useEffect(() => { + setQuestionType(data || []); + return ()=>{ + /** 退出当前页面清空Map */ + parsingMap.clear(); + } + }, [data]); + + //saveQuestion + return ( + + + itemLayout="vertical" + actionRef={actionRef} + rowClassName='questionbank-list-item' + pagination={{ + defaultPageSize: 10, + showSizeChanger: false, + }} + toolBarRender={() => { + const menuItems = []; + console.log('toolBarRender', questionType); + if(questionType?.length > 0){ + console.log('push'); + questionType.forEach((item: {code: number, name: string})=>{ + menuItems.push({item?.name}) + }) + } + const menu = ( + { + console.log('menu11', value); + console.log('menu11', value.key); + console.log('menuquestionType', ); + setQuestionType({ name: questionType[Number(value?.key)]?.name, value: Number(value?.key)}); + handleCreateModalVisible(true); + }}> + {menuItems} + + ); + return [ + + + , + /* + */, + , + + + , + ]; + }} + onRow={(record: any) => { + /* + return { + onMouseEnter: () => { + console.log(record); + }, + onClick: () => { + console.log(record); + }, + };*/ + }} + rowKey="id" + headerTitle={false} + tooltip={false} + request={async (value) => { + console.log('value', value) + /* + const { create_time } = value; + if (create_time) { + value.begin_time = create_time[0] + value.end_time = create_time[1] + }*/ + + const questions = await queryQuestionList({ + ...value, + type: type, + page_number: value?.current || 1, + page_size: value?.pageSize, + }); + // 课程名称及课程标签 + console.log('data',questions); + const data = [] + for(let i=0; i { + setSelectedRows(selectedRows); + }, + }} + // grid={{ gutter: 16, column: 1 }} + showActions="always" + showExtra="always" + metas={{ + title: { + dataIndex: 'question_stem', + render: (text: React.ReactNode, record: T, index: number) => (<>{record?.id} {text}), + }, + avatar: { + dataIndex: 'question_type', + valueType: 'text', + render: (text: React.ReactNode, record: T, index: number) => { + const type = questionType?.filter((item, idx, self)=>{ + console.log('FFFF', item, idx, self); + return item?.code === record.question_type + }); + console.log('type', type?.name); + console.log('type', type?.name); + console.log('questionType::::',questionType); + return `[${type[0]?.name}]` + }, + }, + description: { + dataIndex: 'answers', + valueType: 'checkbox', + render: (text: React.ReactNode, record: T, index: number) => { + console.log('description answers', record) + return ( + { + console.log('item', item); + return ( + + {`${(record?.question_type === 2) ? ['T','F'][key] : labels[key]}. ${item?.answer}`} + ) + }} + /> + ); + }, + }, + subTitle: { }, + content: { + render: (text: React.ReactNode, record: T, index: number) => { + let answer = ''; + const answertrue = record?.answertrue?.split(','); + console.log('answertrue', answertrue) + /** 题型 */ + switch(record?.question_type){ + case 0: // 单选 + case 1: // 多选 + answer = labels?.filter((x, idx, self)=>answertrue[idx] === `${idx}`).toString() + break; + case 2: // 判断 + answer = ['T', 'F']?.filter((x, idx, self)=>answertrue[idx] === `${idx}`).toString() + break; + } + console.log('expandedDescRowKeys', expandedDescRowKeys) + if(expandedDescRowKeys?.indexOf(record.id) > -1){ + return ( + + 正确答案: + {answer} + + 解析:
+ + ); + }else{ + return ( + + 正确答案: + {answer} + + + ) + } + + }, + }, + actions: { + cardActionProps: 'extra', + render: (text: React.ReactNode, record: T, _index: number) => { + let eye + if(expandedDescRowKeys?.indexOf(record.id) > -1){ + eye = <> 隐藏解析 + }else{ + eye = <> 查看解析 + } + return( + + + + 创建时间:{record?.create_time} + 标签:{record?.tag_name} + 所属课程:{record?.course_name} + + + + + { + handleUpdateModalVisible(true) + return false; + }} target="_blank" rel="noopener noreferrer" key="link"> + 编辑 + + { + const success = await handleRemove([{ key: record?.id }]); // 调用批量删除函数(如果接口不支持批量需要在service中处理) + if (success) { + // handleModalVisible(false); + if (actionRef.current) { + setSelectedRows([]); + actionRef.current?.reload(); + } + } + }} + > + 删除 + + + { + if(expandedDescRowKeys?.indexOf(record.id) > -1){ + const descRowKeys = expandedDescRowKeys?.filter((item, idx, self)=>{ + console.log('FFFF', item, idx, self); + return item !== record.id + }); + setExpandedDescRowKeys([...descRowKeys]); + }else{ + const { bean } = await queryQuestionById({id: record.id}) + parsingMap.set(bean.id, bean.parsing) + setParsing(parsingMap); + console.log('parsing', parsing); + setExpandedDescRowKeys([...expandedDescRowKeys, record.id]); + } + + console.log('record id:', record.id); + console.log('expandedDescRowKeys......', expandedDescRowKeys) + }} + > + {eye} + + + + + ) + } + }, + }} + /> + { + handleCreateModalVisible(false); + }} + footer={null} + > + + layout="horizontal" + layoutType="Form" + labelCol={{ span: 8 }} + wrapperCol={{ span: 12 }} + onFinish={async (values: any) => { + // 表单处理 + console.log('columns:', columns); + console.log('values:', values); + const opts = []; + values?.answers?.forEach((item)=>{ + opts.push({answer:item, is_true:0}) + }) + const success = await handleAdd({ + ...values, + type: type, // 必填,0-常规题,1-资质考试题 + answers: JSON.stringify(opts), + question_type: addType.value, + // subject_id: params?.id || 0, + }); + console.log('123') + if(success){ + handleCreateModalVisible(false); + actionRef.current?.reload(); + } + }} + submitter={{ + render: (props, doms) => ( + + + {doms} + + + ), + }} + // action = '' + title="新建" + columns={columns} + /> + + { + handleUpdateModalVisible(false); + }} + footer={null} + > + + layout="horizontal" + layoutType="Form" + labelCol={{ span: 8 }} + wrapperCol={{ span: 12 }} + onFinish={async (values: any) => { + // 表单处理 + console.log('columns:', columns); + console.log('values:', values); + const opts = []; + values?.answers?.forEach((item)=>{ + opts.push({answer:item, is_true:0}) + }) + const success = await handleAdd({ + ...values, + type: type, // 必填,0-常规题,1-资质考试题 + answers: JSON.stringify(opts), + question_type: addType.value, + // subject_id: params?.id || 0, + }); + console.log('123') + if(success){ + handleCreateModalVisible(false); + actionRef.current?.reloadAndRest?.(); + } + }} + submitter={{ + render: (props, doms) => ( + + + {doms} + + + ), + }} + // action = '' + title="编辑" + columns={columns} + /> + + + ); +}; + +export default QuestionPaper; diff --git a/admin/src/pages/examinationrules/components/temp.tsx b/admin/src/pages/examinationrules/components/temp.tsx new file mode 100644 index 0000000..822c355 --- /dev/null +++ b/admin/src/pages/examinationrules/components/temp.tsx @@ -0,0 +1,59 @@ + + + + { questions && questions.map( + <> + + 0. 以下哪些是符合法律规定的 ? + + { return true }} value={0} size="large"> + + A. 单位在试用期辞退员工 + B. 社会中介收取中介费 + C. 单位不缴纳五险一金 + D. 要求员工支付押金 + + + + )} + + 4. 以下哪些是符合法律规定的 ? + + { return true }} value={0} size="large"> + + A. 单位在试用期辞退员工 + B. 社会中介收取中介费 + C. 单位不缴纳五险一金 + D. 要求员工支付押金 + + + + + 5. 以下哪些是不符合法律规定的(多选) ? + + { return true }}> + + A. 单位在试用期辞退员工 + B. 社会中介收取中介费 + C. 单位不缴纳五险一金 + D. 要求员工支付押金 + + + + + 6. 单位在试用期辞退员工是符合法律规定的 ? + + { return true }} value={0} size="large"> + + 正确 + 错误 + + + + \ No newline at end of file diff --git a/admin/src/pages/examinationrules/normal/components/QuestionPaper.tsx b/admin/src/pages/examinationrules/normal/components/QuestionPaper.tsx new file mode 100644 index 0000000..18e6103 --- /dev/null +++ b/admin/src/pages/examinationrules/normal/components/QuestionPaper.tsx @@ -0,0 +1,541 @@ +/** 试卷 */ +//import { AlignLeftOutlined, PlusOutlined } from '@ant-design/icons'; +import { Switch, Button, Card, Col, List, Menu, Progress, Row, Typography, Space, Divider, Radio, Checkbox, Tag, Dropdown, Upload, Modal, Form, Input, message, Popconfirm } from 'antd'; +import { PageContainer } from '@ant-design/pro-layout'; +//import { useRequest } from 'umi'; +//import { queryFakeList } from './service'; +//import type { CardListItemDataType } from './data'; +import styles from './style.less'; +//import SubMenu from 'antd/lib/menu/SubMenu'; +//import ProCard from '@ant-design/pro-card'; +import ProList from '@ant-design/pro-list'; +import { ReactText, useEffect, useRef, useState } from 'react'; +import { PlusOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EditOutlined, EyeOutlined, EyeInvisibleOutlined, DownOutlined, UserOutlined } from '@ant-design/icons'; +import { exportQuestionTemplate, queryQuestionById, queryQuestionList, queryQuestionType, removeQuestion, saveQuestion } from './service'; +import { useParams, useRequest, history, useRouteMatch } from 'umi'; +import { queryCourseListByTag, queryCourseView, queryTagList } from '@/pages/course/option/service'; +import ProForm, { BetaSchemaForm, ProFormCheckbox, ProFormList, ProFormRadio, ProFormSelect, ProFormText } from '@ant-design/pro-form'; +import { DataItem } from '../dashboard/analysis/data'; +import { ActionType, ProColumns } from '@ant-design/pro-table'; +import ProFormRichEdit from '../course/subject/components/ProFormRichEdit'; +import { TableListItem } from '../course/option/data'; + +//const { Paragraph } = Typography; +const { Text, Link } = Typography; + +const labels = ['A','B','C','D','E','F','G','H','I','J','K']; +const parsingMap = new Map() +console.log('first'); +const addType = 0; + +/** + * 试卷显示 + * @returns + * React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。 + */ +const QuestionPaper = (props: any, ref: any) => { + //const match = useRouteMatch(); + //console.log('match', match); + + //const type = history.location.pathname === '/questionbank/attestation' ? 1 : 0 ; // 题库类型 + const actionRef = useRef(); + + const [questionType, setQuestionType] = useState([]); // #1. 题型 + + const [parsing, setParsing] = useState(); + const [expandedDescRowKeys, setExpandedDescRowKeys] = useState([]); // 展开解析设置 + + /** 表单项定义 */ + const columns: ProColumns[] = [ + { + title: '题干', + dataIndex: 'question_stem', + valueType: 'text', + hideInTable: false, + hideInDescriptions: false, + hideInForm: false, + hideInSearch: true, + formItemProps: { + rules: [ + { + required: true, + message: '请填题干内容', + }, + ] + }, + }, + { + title: '选项', + dataIndex: 'answers', + valueType: 'text', + sorter: false, + hideInTable: false, + hideInForm: false, + hideInSearch: true, + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + + ) + }, + { + title: '答案', + dataIndex: 'answertrue', + valueType: 'text', + sorter: false, + hideInTable: false, + hideInForm: false, + hideInSearch: true, + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + // 0 单选 1 多选 2 判断 + (addType?.value !== 1 ) ? + + : + + + ) + /* + formItemProps: { + rules: [ + { + required: true, + message: '请填答案', + }, + ] + },*/ + }, + { + title: '解析', + dataIndex: 'parsing', + valueType: 'textarea', + sorter: false, + hideInTable: false, + hideInForm: false, + hideInSearch: true, + formItemProps: { + rules: [ + { + required: true, + message: '请填写试题解析', + }, + ] + }, + renderText: (val: string) => (
), + renderFormItem: (item, { defaultRender, ...rest }, form) => ( + + ), + }, + ] + + /** 获取题型 */ + const { data } = useRequest(() => { + return queryQuestionType(); + },{ + formatResult: (result) => { + return result.list; + } + }); + +/* + const { data: template } = useRequest(() => { + return exportQuestionTemplate(); + }); + */ + useEffect(() => { + setQuestionType(data || []); + return ()=>{ + /** 退出当前页面清空Map */ + parsingMap.clear(); + } + }, [data]); + + //saveQuestion + return ( + + + itemLayout="vertical" + actionRef={actionRef} + rowClassName='questionbank-list-item' + pagination={{ + defaultPageSize: 10, + showSizeChanger: false, + }} + toolBarRender={() => { + const menuItems = []; + console.log('toolBarRender', questionType); + if(questionType?.length > 0){ + console.log('push'); + questionType.forEach((item: {code: number, name: string})=>{ + menuItems.push({item?.name}) + }) + } + const menu = ( + { + console.log('menu11', value); + console.log('menu11', value.key); + console.log('menuquestionType', ); + setQuestionType({ name: questionType[Number(value?.key)]?.name, value: Number(value?.key)}); + handleCreateModalVisible(true); + }}> + {menuItems} + + ); + return [ + + + , + /* + */, + , + + + , + ]; + }} + onRow={(record: any) => { + /* + return { + onMouseEnter: () => { + console.log(record); + }, + onClick: () => { + console.log(record); + }, + };*/ + }} + rowKey="id" + headerTitle={false} + tooltip={false} + request={async (value) => { + console.log('value', value) + /* + const { create_time } = value; + if (create_time) { + value.begin_time = create_time[0] + value.end_time = create_time[1] + }*/ + + const questions = await queryQuestionList({ + ...value, + type: type, + page_number: value?.current || 1, + page_size: value?.pageSize, + }); + // 课程名称及课程标签 + console.log('data',questions); + const data = [] + for(let i=0; i { + setSelectedRows(selectedRows); + }, + }} + // grid={{ gutter: 16, column: 1 }} + showActions="always" + showExtra="always" + metas={{ + title: { + dataIndex: 'question_stem', + render: (text: React.ReactNode, record: T, index: number) => (<>{record?.id} {text}), + }, + avatar: { + dataIndex: 'question_type', + valueType: 'text', + render: (text: React.ReactNode, record: T, index: number) => { + const type = questionType?.filter((item, idx, self)=>{ + console.log('FFFF', item, idx, self); + return item?.code === record.question_type + }); + console.log('type', type?.name); + console.log('type', type?.name); + console.log('questionType::::',questionType); + return `[${type[0]?.name}]` + }, + }, + description: { + dataIndex: 'answers', + valueType: 'checkbox', + render: (text: React.ReactNode, record: T, index: number) => { + console.log('description answers', record) + return ( + { + console.log('item', item); + return ( + + {`${(record?.question_type === 2) ? ['T','F'][key] : labels[key]}. ${item?.answer}`} + ) + }} + /> + ); + }, + }, + subTitle: { }, + content: { + render: (text: React.ReactNode, record: T, index: number) => { + let answer = ''; + const answertrue = record?.answertrue?.split(','); + console.log('answertrue', answertrue) + /** 题型 */ + switch(record?.question_type){ + case 0: // 单选 + case 1: // 多选 + answer = labels?.filter((x, idx, self)=>answertrue[idx] === `${idx}`).toString() + break; + case 2: // 判断 + answer = ['T', 'F']?.filter((x, idx, self)=>answertrue[idx] === `${idx}`).toString() + break; + } + console.log('expandedDescRowKeys', expandedDescRowKeys) + if(expandedDescRowKeys?.indexOf(record.id) > -1){ + return ( + + 正确答案: + {answer} + + 解析:
+ + ); + }else{ + return ( + + 正确答案: + {answer} + + + ) + } + + }, + }, + actions: { + cardActionProps: 'extra', + render: (text: React.ReactNode, record: T, _index: number) => { + let eye + if(expandedDescRowKeys?.indexOf(record.id) > -1){ + eye = <> 隐藏解析 + }else{ + eye = <> 查看解析 + } + return( + + + + 创建时间:{record?.create_time} + 标签:{record?.tag_name} + 所属课程:{record?.course_name} + + + + + { + handleUpdateModalVisible(true) + return false; + }} target="_blank" rel="noopener noreferrer" key="link"> + 编辑 + + { + const success = await handleRemove([{ key: record?.id }]); // 调用批量删除函数(如果接口不支持批量需要在service中处理) + if (success) { + // handleModalVisible(false); + if (actionRef.current) { + setSelectedRows([]); + actionRef.current?.reload(); + } + } + }} + > + 删除 + + + { + if(expandedDescRowKeys?.indexOf(record.id) > -1){ + const descRowKeys = expandedDescRowKeys?.filter((item, idx, self)=>{ + console.log('FFFF', item, idx, self); + return item !== record.id + }); + setExpandedDescRowKeys([...descRowKeys]); + }else{ + const { bean } = await queryQuestionById({id: record.id}) + parsingMap.set(bean.id, bean.parsing) + setParsing(parsingMap); + console.log('parsing', parsing); + setExpandedDescRowKeys([...expandedDescRowKeys, record.id]); + } + + console.log('record id:', record.id); + console.log('expandedDescRowKeys......', expandedDescRowKeys) + }} + > + {eye} + + + + + ) + } + }, + }} + /> + { + handleCreateModalVisible(false); + }} + footer={null} + > + + layout="horizontal" + layoutType="Form" + labelCol={{ span: 8 }} + wrapperCol={{ span: 12 }} + onFinish={async (values: any) => { + // 表单处理 + console.log('columns:', columns); + console.log('values:', values); + const opts = []; + values?.answers?.forEach((item)=>{ + opts.push({answer:item, is_true:0}) + }) + const success = await handleAdd({ + ...values, + type: type, // 必填,0-常规题,1-资质考试题 + answers: JSON.stringify(opts), + question_type: addType.value, + // subject_id: params?.id || 0, + }); + console.log('123') + if(success){ + handleCreateModalVisible(false); + actionRef.current?.reload(); + } + }} + submitter={{ + render: (props, doms) => ( + + + {doms} + + + ), + }} + // action = '' + title="新建" + columns={columns} + /> + + { + handleUpdateModalVisible(false); + }} + footer={null} + > + + layout="horizontal" + layoutType="Form" + labelCol={{ span: 8 }} + wrapperCol={{ span: 12 }} + onFinish={async (values: any) => { + // 表单处理 + console.log('columns:', columns); + console.log('values:', values); + const opts = []; + values?.answers?.forEach((item)=>{ + opts.push({answer:item, is_true:0}) + }) + const success = await handleAdd({ + ...values, + type: type, // 必填,0-常规题,1-资质考试题 + answers: JSON.stringify(opts), + question_type: addType.value, + // subject_id: params?.id || 0, + }); + console.log('123') + if(success){ + handleCreateModalVisible(false); + actionRef.current?.reloadAndRest?.(); + } + }} + submitter={{ + render: (props, doms) => ( + + + {doms} + + + ), + }} + // action = '' + title="编辑" + columns={columns} + /> + + + ); +}; + +export default QuestionPaper; diff --git a/admin/src/pages/examinationrules/normal/service.ts b/admin/src/pages/examinationrules/normal/service.ts index 6f61013..6b5abad 100644 --- a/admin/src/pages/examinationrules/normal/service.ts +++ b/admin/src/pages/examinationrules/normal/service.ts @@ -97,8 +97,10 @@ export async function updateRules( * @param params * @returns */ - export async function queryTempQuestionList(params: { +export async function queryTempQuestionList(params: { + paper_uuid: string; // paper_uuid参数不能为空 page_size: number; + page_number: number; //count: number; }): Promise<{ data: { list: CardListItemDataType[] } }> { return request('/dsideal_yy/zygh/training/rules/getTempQuestionList', { diff --git a/admin/src/pages/examinationrules/normal/step/index.tsx b/admin/src/pages/examinationrules/normal/step/index.tsx index 8d2e48c..07e9ae2 100644 --- a/admin/src/pages/examinationrules/normal/step/index.tsx +++ b/admin/src/pages/examinationrules/normal/step/index.tsx @@ -19,7 +19,7 @@ import styles from './index.less' import { saveRules, querySubjectList, queryRulesView, queryTempQuestionList, saveQuestionTypeScore } from '../../service'; import { queryCourseView } from '@/pages/course/option/service'; import { queryQuestionList, queryQuestionById, queryQuestionType } from '@/pages/questionbank/service'; -import { PlusOutlined, DownOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EyeInvisibleOutlined, EyeOutlined, EditOutlined } from '@ant-design/icons'; +import { PlusOutlined, DownOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EyeInvisibleOutlined, EyeOutlined, EditOutlined, ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons'; import ProList from '@ant-design/pro-list'; import { autoPaper, manualPaper, updatePaper } from '../service'; @@ -92,7 +92,7 @@ const waitTime = (time: number = 100) => { }, time); }); }; - +const labels = ['A','B','C','D','E','F','G','H','I','J','K'] // 模拟考试规则维护 export default () => { @@ -139,12 +139,13 @@ export default () => { }, [questionTypeData]); /** 组卷,查询试题临时表(当前选题列表) */ - const { data: questions, run } = useRequest(async () => { + const { data: questions, run } = useRequest(async (params) => { + console.log('questions', questions) return queryTempQuestionList(params); },{ manual: true, formatResult: (result) => { - return result?.bean; + return result?.table_List; }}); console.log(params, 'params'); @@ -289,77 +290,76 @@ export default () => { 系统组卷 + + - - { questions && questions.map( - <> - - 0. 以下哪些是符合法律规定的 ? + { questions && questions.map((item, idx)=>( + item && +
+ + {idx+1}. {item?.question_stem} - { return true }} value={0} size="large"> - - A. 单位在试用期辞退员工 - B. 社会中介收取中介费 - C. 单位不缴纳五险一金 - D. 要求员工支付押金 - - - - )} - - 4. 以下哪些是符合法律规定的 ? - - { return true }} value={0} size="large"> - - A. 单位在试用期辞退员工 - B. 社会中介收取中介费 - C. 单位不缴纳五险一金 - D. 要求员工支付押金 - - - - - 5. 以下哪些是不符合法律规定的(多选) ? - - { return true }}> - - A. 单位在试用期辞退员工 - B. 社会中介收取中介费 - C. 单位不缴纳五险一金 - D. 要求员工支付押金 - - - - - 6. 单位在试用期辞退员工是符合法律规定的 ? - - { return true }} value={0} size="large"> - - 正确 - 错误 - - - + {(item?.question_type === 0) && // 单选题 +
+ {item?.answers && item?.answers.map((anster, k)=>( +
+ {anster?.is_true === '0' && {labels[k]} } + {anster?.is_true === '1' && {labels[k]} } + {anster?.answer} +
+ ))} +
+ } + {(item?.question_type === 1) && // 多选题 +
+ {item?.answers && item?.answers.map((anster, k)=>( +
+ {anster?.is_true === '0' && {labels[k]} } + {anster?.is_true === '1' && {labels[k]} } + {anster?.answer} +
+ ))} +
+ } + {(item?.question_type === 2) && // 判断选题 +
+ {item?.answers && item?.answers.map((anster, k)=>( +
+ {anster?.is_true === '0' && {labels[k]} } + {anster?.is_true === '1' && {labels[k]} } + {anster?.answer} +
+ ))} +
+ } +
+ +
+
+ ))} + +
+
试卷信息与设置 - 共 { 0 } 题 { 0 } 分 + 共 { '-' } 题 { '-' } 分 { questionType.map((item)=>{ - return {item?.name} 共 { 0 } 题 { 0 } 分 + return {item?.name} 共 { '-' } 题 { '-' } 分 } )} @@ -459,9 +459,15 @@ export default () => { const {code, data: paper, msg} = await handleAppend(Number(params?.id), rows) console.log('paper', paper) setUuidPaper(paper?.paper_uuid) - run({paper_uuid: paper?.paper_uuid}); // 获取当前选题列表 + console.log('paper_uuid', paper?.paper_uuid) + run({ + paper_uuid: paper?.paper_uuid, + page_size: 1000, + page_number: 1 + }); // 获取当前选题列表 // message.success('提交成功'); handleSelectorModalVisible(false) + return true; }} > diff --git a/admin/src/pages/examinationrules/service.ts b/admin/src/pages/examinationrules/service.ts index 603e974..6a7d687 100644 --- a/admin/src/pages/examinationrules/service.ts +++ b/admin/src/pages/examinationrules/service.ts @@ -140,10 +140,9 @@ export async function removeRules(data: { key: number[] }, options?: Record, ) { @@ -185,6 +184,30 @@ export async function queryRulesPaper( }); } +/** + * 06 获取试卷内容 + * + */ + export async function queryPaperQuestionList( + params: { + paper_id: string; // 试卷id + }, + options?: Record, +) { + return request<{ + data: TableListItem[]; + /** 列表的内容总数 */ + total?: number; + success?: boolean; + }>('/dsideal_yy/zygh/training/rules/getPaperQuestionList', { + method: 'GET', + params: { + ...params, + }, + ...(options || {}), + }); +} + /** 组卷,修改题型分数 */ export async function saveQuestionTypeScore(data: Record, options?: Record) { return request('/dsideal_yy/zygh/training/rules/saveQuestionTypeScore', { @@ -204,3 +227,5 @@ export async function autoPaperOfficial(data: Record, options?: Rec ...(options || {}), }); } + + diff --git a/admin/src/pages/questionbank/index.tsx b/admin/src/pages/questionbank/index.tsx index d91fd3d..66f4380 100644 --- a/admin/src/pages/questionbank/index.tsx +++ b/admin/src/pages/questionbank/index.tsx @@ -88,6 +88,7 @@ const QuestionBank = () => { const [updateModalVisible, handleUpdateModalVisible] = useState(false); const [selectedRowsState, setSelectedRows] = useState([]); + const [currentRow, setCurrentRow] = useState(); const [expandedDescRowKeys, setExpandedDescRowKeys] = useState([]); // 展开解析设置 const [addType, setAddType] = useState({name: '', value: 0}); @@ -195,22 +196,24 @@ const QuestionBank = () => { hideInTable: false, hideInForm: false, hideInSearch: true, - renderFormItem: (item, { defaultRender, ...rest }, form) => ( + renderFormItem: (item, { defaultRender, ...rest }, form) => { + // 需要处理 + // 0 单选 1 多选 2 判断 - (addType?.value !== 1 ) ? + return (addType?.value !== 1 ) ? + label="" + initialValue={'A'} + options={['A', 'B', 'C', 'D']} + /> : + label="" + initialValue={[item]} + options={['A', 'B', 'C', 'D']} + /> - ) + }, /* formItemProps: { rules: [ @@ -442,10 +445,10 @@ const QuestionBank = () => { switch(record?.question_type){ case 0: // 单选 case 1: // 多选 - answer = labels?.filter((x, idx, self)=>answertrue[idx] === `${idx}`).toString() + answer = labels?.filter((x, idx, self)=>`${answertrue[idx]}` === `1`).toString() break; case 2: // 判断 - answer = ['T', 'F']?.filter((x, idx, self)=>answertrue[idx] === `${idx}`).toString() + answer = ['T', 'F']?.filter((x, idx, self)=>`${answertrue[idx]}` === `1`).toString() break; } console.log('expandedDescRowKeys', expandedDescRowKeys) @@ -491,6 +494,8 @@ const QuestionBank = () => { { + console.log('record',record) + setCurrentRow(record); handleUpdateModalVisible(true) return false; }} target="_blank" rel="noopener noreferrer" key="link"> @@ -561,10 +566,11 @@ const QuestionBank = () => { onFinish={async (values: any) => { // 表单处理 console.log('columns:', columns); - console.log('values:', values); + console.log('values:', values); const opts = []; - values?.answers?.forEach((item)=>{ - opts.push({answer:item, is_true:0}) + values?.answers?.forEach((item, key)=>{ + const isTrue = labels[key] === values?.answertrue ? 1 : 0; // 判断是否为正确答案 + opts.push({answer:item, is_true:isTrue}) }) const success = await handleAdd({ ...values, @@ -609,6 +615,12 @@ const QuestionBank = () => { layoutType="Form" labelCol={{ span: 8 }} wrapperCol={{ span: 12 }} + request={()=>{ + // + console.log('currentRow',currentRow) + //answers:currentRow?.answers.map((item)=>(item.answer)) + return {...currentRow, answers: currentRow?.answers.map((item)=>(item.answer)), answer_true: 1 } + }} onFinish={async (values: any) => { // 表单处理 console.log('columns:', columns); diff --git a/web/src/pages/course/list/index.tsx b/web/src/pages/course/list/index.tsx index 6f3b105..58b2f6d 100644 --- a/web/src/pages/course/list/index.tsx +++ b/web/src/pages/course/list/index.tsx @@ -156,7 +156,7 @@ const CardList = () => {