xialiang 3 years ago
commit a72f239e0c

@ -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<TableListItem>[] = [
{
@ -288,15 +288,27 @@ const TableList: React.FC = () => {
<a
key="remove"
onClick={ () => {
handleRemove([{ key: record?.subject_id }]); // 调用批量删除函数如果接口不支持批量需要在service中处理
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
showConfirm(record)
}}>
</a>,
],
},
];
const showConfirm=async (record)=>{
confirm({
title: '确认删除主题吗?',
centered:true,
onOk() {
handleRemove([{ key: record?.subject_id }]); // 调用批量删除函数如果接口不支持批量需要在service中处理
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
},
onCancel() {
},
});
};
return (
<PageContainer>

@ -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;
}
}}
>
<Row gutter={24}>
@ -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={() => [
<Button
type="primary"
@ -531,8 +537,9 @@ export default () => {
</Button>,
]}
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,
});

@ -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<ProFormInstance>();
@ -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<boolean>(false);
@ -41,6 +47,16 @@ export default () => {
/** 试卷详情窗口 */
const [paperModalVisible, handlePaperModalVisible] = useState<boolean>(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 && <div></div>}
<div key={typeItem?.code} style={{padding:10, fontSize:16}}>{numberType[index]}. {typeItem?.name}</div>
<div style={{padding:'0 10px 0 50px'}}>
{ questions && questions.map((item, idx)=>(
(typeItem?.code === item?.question_type) &&
<div style={{border:'none'}}>
<Typography style={{ marginBottom: 16, fontSize: 14, padding: '15px 15px 0 15px' }}>
{questionNumber[item?.question_type]++}. {item?.question_stem}
</Typography>
{(item?.question_type === 0) && // 单选题
<div style={{padding:'0 15px 15px 15px'}}>
{item?.answers && item?.answers.map((anster, k)=>(
<div value={k} checked style={{width: '100%', padding: 5, fontSize: 14 }}>
{anster?.is_true === '0' && <span style={{color:'#1890ff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10}}>{labels[k]} </span> }
{anster?.is_true === '1' && <span style={{color:'#ffffff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10, backgroundColor:'#1890ff'}}>{labels[k]} </span> }
<span style={{display:'inline-block'}}>{anster?.answer}</span>
</div>
))}
</div>
}
{(item?.question_type === 1) && // 多选题
<div style={{padding:'0 15px 15px 15px'}}>
{item?.answers && item?.answers.map((anster, k)=>(
<div value={k} checked style={{width: '100%', padding: 5, fontSize: 14 }}>
{anster?.is_true === '0' && <span style={{color:'#1890ff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10}}>{labels[k]} </span> }
{anster?.is_true === '1' && <span style={{color:'#ffffff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10, backgroundColor:'#1890ff'}}>{labels[k]} </span> }
<span style={{display:'inline-block'}}>{anster?.answer}</span>
</div>
))}
</div>
}
{(item?.question_type === 2) && // 判断选题
<div style={{padding:'0 15px 15px 15px'}}>
{item?.answers && item?.answers.map((anster, k)=>(
<div value={k} checked style={{width: '100%', padding: 5, fontSize: 14 }}>
{anster?.is_true === '0' && <span style={{color:'#1890ff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10}}>{labels[k]} </span> }
{anster?.is_true === '1' && <span style={{color:'#ffffff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10, backgroundColor:'#1890ff'}}>{labels[k]} </span> }
<span style={{display:'inline-block'}}>{anster?.answer}</span>
</div>
))}
</div>
}
</div>
))}
</div>
</>
})}
</ModalForm>
</PageContainer>

@ -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<ActionType>();
const [questionType, setQuestionType] = useState([]); // #1. 题型
const [parsing, setParsing] = useState();
const [expandedDescRowKeys, setExpandedDescRowKeys] = useState<readonly ReactText[]>([]); // 展开解析设置
/** 表单项定义 */
const columns: ProColumns<TableListItem>[] = [
{
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) => (
<AnswersSelector />
)
},
{
title: '答案',
dataIndex: 'answertrue',
valueType: 'text',
sorter: false,
hideInTable: false,
hideInForm: false,
hideInSearch: true,
renderFormItem: (item, { defaultRender, ...rest }, form) => (
// 0 单选 1 多选 2 判断
(addType?.value !== 1 ) ?
<ProFormRadio.Group
label=""
initialValue={'A'}
options={['A', 'B', 'C', 'D']}
/>
:
<ProFormCheckbox.Group
label=""
initialValue={[]}
options={['A', 'B', 'C', 'D']}
/>
)
/*
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) => (<div dangerouslySetInnerHTML={{__html: val}} />),
renderFormItem: (item, { defaultRender, ...rest }, form) => (
<ProFormRichEdit
name="parsing"
label=""
width="xl"
// tooltip="最长为 6 位汉字,需要与考生身份证一致"
placeholder="请填写试题解析"
// rules={[{ required: true }]}
value=""
// disabled
/>
),
},
]
/** 获取题型 */
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 (
<PageContainer content={false} extraContent={false} className={styles.questionbank}>
<ProList<any>
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(<Menu.Item key={item?.code}>{item?.name}</Menu.Item>)
})
}
const menu = (
<Menu onClick={(value)=>{
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}
</Menu>
);
return [
<Dropdown overlay={menu}>
<Button >
<PlusOutlined /> <DownOutlined />
</Button>
</Dropdown>,
/*
<Button key="remove" type="default" danger>
<DeleteOutlined />
</Button>*/,
<Button key="download" onClick={()=>{window.location.href='/dsideal_yy/zygh/training/exportQuestionTemplate'}} >
<DownloadOutlined />
</Button>,
<Upload
accept='.xlsx'
showUploadList={false}
action="/dsideal_yy/zygh/training/importQuestionData"
data={
{
type: type,
}
}
>
<Button key="upload" >
<UploadOutlined />
</Button>
</Upload>,
];
}}
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<questions?.table_List.length; i++){
const { data: course } = await queryCourseView({
course_id: questions?.table_List[i]?.course_id
});
data[i] = {...questions?.table_List[i], course_name:course?.course_name, tag_name:course?.tag_name, };
}
return {
current: questions?.pageNumber,
data: data,
pageSize: questions?.pageSize,
success: true,
total: questions?.totalRow || 0,
};
}}
//dataSource={dataSource}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
// grid={{ gutter: 16, column: 1 }}
showActions="always"
showExtra="always"
metas={{
title: {
dataIndex: 'question_stem',
render: (text: React.ReactNode, record: T, index: number) => (<><Text code style={{width:80, fontSize:10, color:'bfbfbf'}}>{record?.id}</Text> {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 (
<List
header={false}
footer={false}
bordered={false}
dataSource={record.answers || []}
rowKey='id'
renderItem={ (item, key) => {
console.log('item', item);
return (
<List.Item>
<Typography.Text mark={false}>{`${(record?.question_type === 2) ? ['T','F'][key] : labels[key]}. ${item?.answer}`}</Typography.Text>
</List.Item>)
}}
/>
);
},
},
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 (
<Space direction="vertical" style={{borderTop:'solid 1px #f0f0f0', padding:10, margin: '5px -18px 0 -24px', background: '#fdfdfd'}}>
<Typography>
{answer}
</Typography>
<Typography><div dangerouslySetInnerHTML={{__html: parsing.get(record.id)}} /></Typography>
</Space>
);
}else{
return (
<Space direction="vertical" style={{borderTop:'solid 1px #f0f0f0', padding:10, margin: '5px -18px 0 -24px', background: '#fdfdfd'}}>
<Typography>
{answer}
</Typography>
</Space>
)
}
},
},
actions: {
cardActionProps: 'extra',
render: (text: React.ReactNode, record: T, _index: number) => {
let eye
if(expandedDescRowKeys?.indexOf(record.id) > -1){
eye = <><EyeInvisibleOutlined /> </>
}else{
eye = <><EyeOutlined /> </>
}
return(
<Row style={{padding:'10px 24px'}}>
<Col flex={1} style={{textAlign:'left'}}>
<Space direction="horizontal" size="large">
<Typography>{record?.create_time}</Typography>
<Typography>{record?.tag_name}</Typography>
<Typography>{record?.course_name}</Typography>
</Space>
</Col>
<Col flex={1} style={{textAlign:'right'}}>
<Space direction="horizontal" size="middle">
<a onClick={()=>{
handleUpdateModalVisible(true)
return false;
}} target="_blank" rel="noopener noreferrer" key="link">
<EditOutlined />
</a>
<Popconfirm key="popconfirm" title={`确认删除当前项吗?`} okText="是" cancelText="否"
onConfirm={async () => {
const success = await handleRemove([{ key: record?.id }]); // 调用批量删除函数如果接口不支持批量需要在service中处理
if (success) {
// handleModalVisible(false);
if (actionRef.current) {
setSelectedRows([]);
actionRef.current?.reload();
}
}
}}
>
<a key="remove" ><DeleteOutlined /> </a>
</Popconfirm>
<a
key="view"
onClick={async ()=>{
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}
</a>
</Space>
</Col>
</Row>
)
}
},
}}
/>
<Modal
title={`新建${addType?.name }`}
//
width="60%"
visible={createModalVisible}
destroyOnClose
onCancel={() => {
handleCreateModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm<DataItem>
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) => (
<Row>
<Col span={12} offset={8}>
<Space>{doms}</Space>
</Col>
</Row>
),
}}
// action = ''
title="新建"
columns={columns}
/>
</Modal>
<Modal
title={`编辑${addType?.name }`}
//
width="60%"
visible={updateModalVisible}
destroyOnClose
onCancel={() => {
handleUpdateModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm<DataItem>
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) => (
<Row>
<Col span={12} offset={8}>
<Space>{doms}</Space>
</Col>
</Row>
),
}}
// action = ''
title="编辑"
columns={columns}
/>
</Modal>
</PageContainer>
);
};
export default QuestionPaper;

@ -0,0 +1,59 @@
<ProCard
title="一. 单选题 共50分每题1分111"
extra={false}
split='vertical'
bordered
headerBordered
>
<Space direction="vertical" style={{ width: '100%', padding: '24px 48px' }}>
{ questions && questions.map(
<>
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
0.
</Typography>
<Radio.Group onChange={() => { return true }} value={0} size="large">
<Space direction="vertical" style={{ fontSize: 16 }}>
<Radio value={1} style={{ padding: 5, fontSize: 16 }}>A. 退</Radio>
<Radio value={2} style={{ padding: 5, fontSize: 16 }}>B. </Radio>
<Radio value={3} style={{ padding: 5, fontSize: 16 }}>C. </Radio>
<Radio value={4} style={{ padding: 5, fontSize: 16 }}>D. </Radio>
</Space>
</Radio.Group>
</>
)}
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
4.
</Typography>
<Radio.Group onChange={() => { return true }} value={0} size="large">
<Space direction="vertical" style={{ fontSize: 16 }}>
<Radio value={1} style={{ padding: 5, fontSize: 16 }}>A. 退</Radio>
<Radio value={2} style={{ padding: 5, fontSize: 16 }}>B. </Radio>
<Radio value={3} style={{ padding: 5, fontSize: 16 }}>C. </Radio>
<Radio value={4} style={{ padding: 5, fontSize: 16 }}>D. </Radio>
</Space>
</Radio.Group>
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
5. ()
</Typography>
<Checkbox.Group onChange={() => { return true }}>
<Space direction="vertical" style={{}}>
<Checkbox value={1} style={{ padding: 5, fontSize: 16 }}>A. 退</Checkbox>
<Checkbox value={2} style={{ padding: 5, fontSize: 16 }}>B. </Checkbox>
<Checkbox value={3} style={{ padding: 5, fontSize: 16 }}>C. </Checkbox>
<Checkbox value={4} style={{ padding: 5, fontSize: 16 }}>D. </Checkbox>
</Space>
</Checkbox.Group>
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
6. 退
</Typography>
<Radio.Group onChange={() => { return true }} value={0} size="large">
<Space direction="vertical" style={{ fontSize: 16 }}>
<Radio value={1} style={{ padding: 5, fontSize: 16 }}></Radio>
<Radio value={2} style={{ padding: 5, fontSize: 16 }}></Radio>
</Space>
</Radio.Group>
</Space>
</ProCard>

@ -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<ActionType>();
const [questionType, setQuestionType] = useState([]); // #1. 题型
const [parsing, setParsing] = useState();
const [expandedDescRowKeys, setExpandedDescRowKeys] = useState<readonly ReactText[]>([]); // 展开解析设置
/** 表单项定义 */
const columns: ProColumns<TableListItem>[] = [
{
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) => (
<AnswersSelector />
)
},
{
title: '答案',
dataIndex: 'answertrue',
valueType: 'text',
sorter: false,
hideInTable: false,
hideInForm: false,
hideInSearch: true,
renderFormItem: (item, { defaultRender, ...rest }, form) => (
// 0 单选 1 多选 2 判断
(addType?.value !== 1 ) ?
<ProFormRadio.Group
label=""
initialValue={'A'}
options={['A', 'B', 'C', 'D']}
/>
:
<ProFormCheckbox.Group
label=""
initialValue={[]}
options={['A', 'B', 'C', 'D']}
/>
)
/*
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) => (<div dangerouslySetInnerHTML={{__html: val}} />),
renderFormItem: (item, { defaultRender, ...rest }, form) => (
<ProFormRichEdit
name="parsing"
label=""
width="xl"
// tooltip="最长为 6 位汉字,需要与考生身份证一致"
placeholder="请填写试题解析"
// rules={[{ required: true }]}
value=""
// disabled
/>
),
},
]
/** 获取题型 */
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 (
<PageContainer content={false} extraContent={false} className={styles.questionbank}>
<ProList<any>
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(<Menu.Item key={item?.code}>{item?.name}</Menu.Item>)
})
}
const menu = (
<Menu onClick={(value)=>{
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}
</Menu>
);
return [
<Dropdown overlay={menu}>
<Button >
<PlusOutlined /> <DownOutlined />
</Button>
</Dropdown>,
/*
<Button key="remove" type="default" danger>
<DeleteOutlined />
</Button>*/,
<Button key="download" onClick={()=>{window.location.href='/dsideal_yy/zygh/training/exportQuestionTemplate'}} >
<DownloadOutlined />
</Button>,
<Upload
accept='.xlsx'
showUploadList={false}
action="/dsideal_yy/zygh/training/importQuestionData"
data={
{
type: type,
}
}
>
<Button key="upload" >
<UploadOutlined />
</Button>
</Upload>,
];
}}
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<questions?.table_List.length; i++){
const { data: course } = await queryCourseView({
course_id: questions?.table_List[i]?.course_id
});
data[i] = {...questions?.table_List[i], course_name:course?.course_name, tag_name:course?.tag_name, };
}
return {
current: questions?.pageNumber,
data: data,
pageSize: questions?.pageSize,
success: true,
total: questions?.totalRow || 0,
};
}}
//dataSource={dataSource}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
// grid={{ gutter: 16, column: 1 }}
showActions="always"
showExtra="always"
metas={{
title: {
dataIndex: 'question_stem',
render: (text: React.ReactNode, record: T, index: number) => (<><Text code style={{width:80, fontSize:10, color:'bfbfbf'}}>{record?.id}</Text> {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 (
<List
header={false}
footer={false}
bordered={false}
dataSource={record.answers || []}
rowKey='id'
renderItem={ (item, key) => {
console.log('item', item);
return (
<List.Item>
<Typography.Text mark={false}>{`${(record?.question_type === 2) ? ['T','F'][key] : labels[key]}. ${item?.answer}`}</Typography.Text>
</List.Item>)
}}
/>
);
},
},
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 (
<Space direction="vertical" style={{borderTop:'solid 1px #f0f0f0', padding:10, margin: '5px -18px 0 -24px', background: '#fdfdfd'}}>
<Typography>
{answer}
</Typography>
<Typography><div dangerouslySetInnerHTML={{__html: parsing.get(record.id)}} /></Typography>
</Space>
);
}else{
return (
<Space direction="vertical" style={{borderTop:'solid 1px #f0f0f0', padding:10, margin: '5px -18px 0 -24px', background: '#fdfdfd'}}>
<Typography>
{answer}
</Typography>
</Space>
)
}
},
},
actions: {
cardActionProps: 'extra',
render: (text: React.ReactNode, record: T, _index: number) => {
let eye
if(expandedDescRowKeys?.indexOf(record.id) > -1){
eye = <><EyeInvisibleOutlined /> </>
}else{
eye = <><EyeOutlined /> </>
}
return(
<Row style={{padding:'10px 24px'}}>
<Col flex={1} style={{textAlign:'left'}}>
<Space direction="horizontal" size="large">
<Typography>{record?.create_time}</Typography>
<Typography>{record?.tag_name}</Typography>
<Typography>{record?.course_name}</Typography>
</Space>
</Col>
<Col flex={1} style={{textAlign:'right'}}>
<Space direction="horizontal" size="middle">
<a onClick={()=>{
handleUpdateModalVisible(true)
return false;
}} target="_blank" rel="noopener noreferrer" key="link">
<EditOutlined />
</a>
<Popconfirm key="popconfirm" title={`确认删除当前项吗?`} okText="是" cancelText="否"
onConfirm={async () => {
const success = await handleRemove([{ key: record?.id }]); // 调用批量删除函数如果接口不支持批量需要在service中处理
if (success) {
// handleModalVisible(false);
if (actionRef.current) {
setSelectedRows([]);
actionRef.current?.reload();
}
}
}}
>
<a key="remove" ><DeleteOutlined /> </a>
</Popconfirm>
<a
key="view"
onClick={async ()=>{
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}
</a>
</Space>
</Col>
</Row>
)
}
},
}}
/>
<Modal
title={`新建${addType?.name }`}
//
width="60%"
visible={createModalVisible}
destroyOnClose
onCancel={() => {
handleCreateModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm<DataItem>
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) => (
<Row>
<Col span={12} offset={8}>
<Space>{doms}</Space>
</Col>
</Row>
),
}}
// action = ''
title="新建"
columns={columns}
/>
</Modal>
<Modal
title={`编辑${addType?.name }`}
//
width="60%"
visible={updateModalVisible}
destroyOnClose
onCancel={() => {
handleUpdateModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm<DataItem>
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) => (
<Row>
<Col span={12} offset={8}>
<Space>{doms}</Space>
</Col>
</Row>
),
}}
// action = ''
title="编辑"
columns={columns}
/>
</Modal>
</PageContainer>
);
};
export default QuestionPaper;

@ -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', {

@ -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 () => {
<Radio.Button value={2} style={{width:200, textAlign:'center'}}></Radio.Button>
</Radio.Group>
<Divider style={{ margin: '6px 0', opacity: 0.5 }} />
<Row>
<Col span={18} style={{ background: '#ffffff', padding: 0 }}>
<ProCard
title="一. 单选题 共50分每题1分111"
title=""
extra={false}
split='vertical'
bordered
headerBordered
>
<Space direction="vertical" style={{ width: '100%', padding: '24px 48px' }}>
{ questions && questions.map(
<>
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
0.
{ questions && questions.map((item, idx)=>(
item &&
<div style={{border:'none'}}>
<Typography style={{ marginBottom: 16, fontSize: 14, padding: '15px 15px 0 15px' }}>
{idx+1}. {item?.question_stem}
</Typography>
<Radio.Group onChange={() => { return true }} value={0} size="large">
<Space direction="vertical" style={{ fontSize: 16 }}>
<Radio value={1} style={{ padding: 5, fontSize: 16 }}>A. 退</Radio>
<Radio value={2} style={{ padding: 5, fontSize: 16 }}>B. </Radio>
<Radio value={3} style={{ padding: 5, fontSize: 16 }}>C. </Radio>
<Radio value={4} style={{ padding: 5, fontSize: 16 }}>D. </Radio>
</Space>
</Radio.Group>
</>
)}
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
4.
</Typography>
<Radio.Group onChange={() => { return true }} value={0} size="large">
<Space direction="vertical" style={{ fontSize: 16 }}>
<Radio value={1} style={{ padding: 5, fontSize: 16 }}>A. 退</Radio>
<Radio value={2} style={{ padding: 5, fontSize: 16 }}>B. </Radio>
<Radio value={3} style={{ padding: 5, fontSize: 16 }}>C. </Radio>
<Radio value={4} style={{ padding: 5, fontSize: 16 }}>D. </Radio>
</Space>
</Radio.Group>
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
5. ()
</Typography>
<Checkbox.Group onChange={() => { return true }}>
<Space direction="vertical" style={{}}>
<Checkbox value={1} style={{ padding: 5, fontSize: 16 }}>A. 退</Checkbox>
<Checkbox value={2} style={{ padding: 5, fontSize: 16 }}>B. </Checkbox>
<Checkbox value={3} style={{ padding: 5, fontSize: 16 }}>C. </Checkbox>
<Checkbox value={4} style={{ padding: 5, fontSize: 16 }}>D. </Checkbox>
</Space>
</Checkbox.Group>
<Typography style={{ marginBottom: 16, fontSize: 18 }}>
6. 退
</Typography>
<Radio.Group onChange={() => { return true }} value={0} size="large">
<Space direction="vertical" style={{ fontSize: 16 }}>
<Radio value={1} style={{ padding: 5, fontSize: 16 }}></Radio>
<Radio value={2} style={{ padding: 5, fontSize: 16 }}></Radio>
</Space>
</Radio.Group>
{(item?.question_type === 0) && // 单选题
<div style={{padding:'0 15px 15px 15px'}}>
{item?.answers && item?.answers.map((anster, k)=>(
<div value={k} checked style={{width: '100%', padding: 5, fontSize: 14 }}>
{anster?.is_true === '0' && <span style={{color:'#1890ff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10}}>{labels[k]} </span> }
{anster?.is_true === '1' && <span style={{color:'#ffffff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10, backgroundColor:'#1890ff'}}>{labels[k]} </span> }
<span style={{display:'inline-block'}}>{anster?.answer}</span>
</div>
))}
</div>
}
{(item?.question_type === 1) && // 多选题
<div style={{padding:'0 15px 15px 15px'}}>
{item?.answers && item?.answers.map((anster, k)=>(
<div value={k} checked style={{width: '100%', padding: 5, fontSize: 14 }}>
{anster?.is_true === '0' && <span style={{color:'#1890ff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10}}>{labels[k]} </span> }
{anster?.is_true === '1' && <span style={{color:'#ffffff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10, backgroundColor:'#1890ff'}}>{labels[k]} </span> }
<span style={{display:'inline-block'}}>{anster?.answer}</span>
</div>
))}
</div>
}
{(item?.question_type === 2) && // 判断选题
<div style={{padding:'0 15px 15px 15px'}}>
{item?.answers && item?.answers.map((anster, k)=>(
<div value={k} checked style={{width: '100%', padding: 5, fontSize: 14 }}>
{anster?.is_true === '0' && <span style={{color:'#1890ff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10}}>{labels[k]} </span> }
{anster?.is_true === '1' && <span style={{color:'#ffffff', border:'1px solid #1890ff', display:'inline-block', width:16, height:16, textAlign:'center', borderRadius:'50%', fontSize:12, lineHeight:'12px', marginRight:10, backgroundColor:'#1890ff'}}>{labels[k]} </span> }
<span style={{display:'inline-block'}}>{anster?.answer}</span>
</div>
))}
</div>
}
<div style={{height:'auto', backgroundColor:'#f0f0f0', textAlign:'right', padding:5, opacity:0.5}}>
<Button><ArrowUpOutlined /></Button> <Button><ArrowDownOutlined /></Button> <Button><DeleteOutlined /></Button>
</div>
</div>
))}
</Space>
</ProCard>
</Col>
<Col span={6} style={{ paddingLeft: 24 }}>
<div style={{ background: '#ffffff', padding: 24 }}>
<Space direction="vertical" style={{ width: '100%' }}>
<strong></strong>
<Typography> { 0 } { 0 } </Typography>
<Typography> { '-' } { '-' } </Typography>
<Divider style={{ margin: '6px 0', opacity: 0.5 }} />
<Space direction="vertical">
{ questionType.map((item)=>{
return <Typography>{item?.name} { 0 } { 0 } </Typography>
return <Typography>{item?.name} { '-' } { '-' } </Typography>
}
)}
</Space>
@ -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;
}}
>

@ -140,10 +140,9 @@ export async function removeRules(data: { key: number[] }, options?: Record<stri
/** 组卷,查询试题临时表(当前选题列表) */
export async function queryTempQuestionList(
params: {
/** 当前的页码 */
current?: number;
/** 页面的容量 */
pageSize?: number;
paper_uuid: string; // paper_uuid参数不能为空
page_size: number;
page_number: number;
},
options?: Record<string, any>,
) {
@ -185,6 +184,30 @@ export async function queryRulesPaper(
});
}
/**
* 06
*
*/
export async function queryPaperQuestionList(
params: {
paper_id: string; // 试卷id
},
options?: Record<string, any>,
) {
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<string, any>, options?: Record<string, any>) {
return request<TableListItem>('/dsideal_yy/zygh/training/rules/saveQuestionTypeScore', {
@ -204,3 +227,5 @@ export async function autoPaperOfficial(data: Record<string, any>, options?: Rec
...(options || {}),
});
}

@ -88,6 +88,7 @@ const QuestionBank = () => {
const [updateModalVisible, handleUpdateModalVisible] = useState<boolean>(false);
const [selectedRowsState, setSelectedRows] = useState<API.RuleListItem[]>([]);
const [currentRow, setCurrentRow] = useState<TableListItem>();
const [expandedDescRowKeys, setExpandedDescRowKeys] = useState<readonly ReactText[]>([]); // 展开解析设置
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 ) ?
<ProFormRadio.Group
label=""
initialValue={'A'}
options={['A', 'B', 'C', 'D']}
/>
label=""
initialValue={'A'}
options={['A', 'B', 'C', 'D']}
/>
:
<ProFormCheckbox.Group
label=""
initialValue={[]}
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 = () => {
<Col flex={1} style={{textAlign:'right'}}>
<Space direction="horizontal" size="middle">
<a onClick={()=>{
console.log('record',record)
setCurrentRow(record);
handleUpdateModalVisible(true)
return false;
}} target="_blank" rel="noopener noreferrer" key="link">
@ -563,8 +568,9 @@ const QuestionBank = () => {
console.log('columns:', columns);
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);

@ -156,7 +156,7 @@ const CardList = () => {
<div style={{ paddingRight: '1rem', width: '20%', display: 'inline-block', textAlign: 'right' }}>
<Button type="primary" onClick={() => {
const info = item.chapter_id + ',' + item.course_id + ',' + item.subject_id;
window.open(location.pathname+'s#/course/detail/' + info)
window.open(location.pathname+'#/course/detail/' + info)
// history.push( '/course/detail/'+info);
}}></Button>
</div>

Loading…
Cancel
Save