You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

897 lines
32 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/** 资质考试 */
//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 type { ReactText } from 'react';
import { 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 type { DataItem } from '../dashboard/analysis/data';
import type { ActionType, ProColumns } from '@ant-design/pro-table';
import ProFormRichEdit from '../course/subject/components/ProFormRichEdit';
import type { TableListItem } from '../course/option/data';
import AnswersSelector from './components/AnswersEditor';
//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');
/**
* 添加试题
*
* @param fields
*/
const handleAdd = async (fields: TableListItem) => {
const hide = message.loading('正在添加');
try {
await saveQuestion({ ...fields });
hide();
message.success('添加成功');
return true;
} catch (error) {
hide();
message.error('添加失败请重试!');
return false;
}
};
/**
* 编辑试题
*
* @param fields
*/
const handleUpdate = async (fields: TableListItem) => {
const hide = message.loading('正在保存');
try {
await saveQuestion({ ...fields });
hide();
message.success('保存成功');
return true;
} catch (error) {
hide();
message.error('保存失败请重试!');
return false;
}
};
/**
* 删除试题
*
* @param selectedRows
*/
const handleRemove = async (selectedRows: TableListItem[]) => {
console.log('selectedRows--', selectedRows)
const hide = message.loading('正在删除');
if (!selectedRows) return true;
try {
const { code, msg } = await removeQuestion({
key: selectedRows.map((row) => row.key),
});
hide();
if (code === 2000) {
message.success('删除成功,即将刷新');
} else {
message.warning(msg);
}
return true;
} catch (error) {
hide();
message.error('删除失败,请重试');
return false;
}
};
const QuestionBank = () => {
const match = useRouteMatch();
console.log('match', match);
const type = history.location.pathname === '/questionbank/attestation' ? 1 : 0; // 题库类型
const actionRef = useRef<ActionType>();
const formRef = useRef();
const [questionType, setQuestionType] = useState([]);
const [parsing, setParsing] = useState();
const [createModalVisible, handleCreateModalVisible] = useState<boolean>(false);
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: '' });
const [pageNumber, setPageNumber] = useState(1)
//const [answertrueValues, setAnswertrueValues] = useState(); // 编辑试题答案项值
//const [options, setOptions] = useState([]); // 设置当前选项, 用于删除选项时判断
/** 表单项定义 */
const columns: ProColumns<TableListItem>[] = [
{
title: '标签',
valueType: 'select',
dataIndex: 'tag_ids',
sorter: false,
hideInTable: true,
hideInForm: false,
hideInSearch: true,
fieldProps: {
mode: "multiple"
},
formItemProps: {
rules: [
{
required: true,
message: '请填标签',
},
]
},
/*
renderFormItem:(item,{ type, defaultRender, formItemProps, fieldProps, ...rest },form)=>{
return defaultRender
},*/
//renderText: (val: string) => `${val}`,
request: async () => {
const { data: Items } = await queryTagList({});
console.log('queryTagList...')
const tags = []
for (let i = 0; i < Items.length; i++) {
tags.push({ label: Items[i]?.tag_name, value: Items[i]?.tag_id })
}
console.log(tags, 'tags:::');
return tags;
},
},
{
title: '课程',
valueType: 'select',
dataIndex: 'course_id',
sorter: false,
hideInTable: false,
hideInForm: false,
hideInSearch: true,
fieldProps: {
//mode: "multiple"
},
formItemProps: {
rules: [
{
required: true,
message: '请选择课程',
},
]
},
renderText: (val: string) => `${val}`,
dependencies: ['tag_ids'],
request: async (params) => {
const { tag_ids } = params;
const { data: Items } = await queryCourseListByTag({ tag_ids: tag_ids?.toString() });
console.log('queryCourseListByTag...')
const courses = []
for (let i = 0; i < Items?.length; i++) {
courses.push({ label: Items[i]?.course_name, value: Items[i]?.course_id })
}
console.log(courses, 'courses:::');
return courses;
},
},
{
title: '题干',
dataIndex: 'question_stem',
valueType: 'text',
hideInTable: false,
hideInDescriptions: false,
hideInForm: false,
hideInSearch: true,
fieldProps: {
maxLength: 50
},
formItemProps: {
rules: [
{
required: true,
message: '请填写题干内容',
},
]
},
},
{
title: '选项',
dataIndex: 'answers',
valueType: 'text',
sorter: false,
hideInTable: false,
hideInForm: false,
hideInSearch: true,
renderFormItem: (item, { defaultRender, ...rest }, form) => (
<AnswersSelector type={addType?.value || Number(form.getFieldValue('question_type'))} />
),
formItemProps: {
rules: [
{
required: true,
message: '请填写选项',
},
]
},
},
{
title: '正确答案',
dataIndex: 'answertrue',
valueType: 'text',
sorter: false,
hideInTable: false,
hideInForm: false,
hideInSearch: true,
dependencies: ['answers'],
renderFormItem: (item, { defaultRender, ...rest }, form) => {
console.log('正确答案...', form.getFieldValue('answers'))
// 关联长度变化及编辑回显
console.log('edit answertrue11', item)
console.log('form::::::', form.getFieldValue('answertrue'))
console.log('rest', rest)
console.log('question_type:::', form.getFieldValue('question_type'))
// 获取选项长度
const len = form.getFieldValue('answers')?.length || 2;
const opts = []
for (let i = 0; i < len; i++) {
opts.push(labels[i])
}
if (Number(form.getFieldValue('question_type')) === 0) {
console.log('my type', Number(form.getFieldValue('question_type')))
} else {
console.log('====0')
}
console.log('answers??', form.getFieldValue('answers')?.length)
console.log('addType?.value', addType?.value)
// 0 单选 1 多选 2 判断
return ((addType?.value === 0 || addType?.value === 2) || (Number(form.getFieldValue('question_type')) === 0) || Number(form.getFieldValue('question_type')) === 2) ?
<Radio.Group
name="answertrue"
options={addType?.value === 0 || (Number(form.getFieldValue('question_type')) === 0) ? opts : ['A', 'B']}
/>
:
<Checkbox.Group
name="answertrue"
options={opts}
/>
},
formItemProps: {
rules: [
{
required: true,
message: '请填写答案',
},
]
},
},
{
title: '解析',
dataIndex: 'parsing',
valueType: 'textarea',
sorter: false,
hideInTable: false,
hideInForm: false,
hideInSearch: true,
formItemProps: {
rules: [
{
required: true,
message: '请填写试题解析',
}, {
validator: (rule, value) => {
console.log("表单:", value, value.replace(/(^\s*)|(\s*$)/g, ""), "|")
if (value.replace(/(^\s*)|(\s*$)/g, "") === "") {
return Promise.reject('请填写试题解析')
} else {
return Promise.resolve()
}
}
}
]
},
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>
style={{ minWidth: 1180 }}
rowKey='id'
itemLayout="vertical"
actionRef={actionRef}
rowClassName='questionbank-list-item'
pagination={{
defaultPageSize: 10,
showSizeChanger: false,
showQuickJumper: true
}}
search={{
labelWidth: 120,
}}
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',);
setAddType({ name: questionType[Number(value?.key)]?.name, value: Number(value?.key) });
handleCreateModalVisible(true);
}}>
{menuItems}
</Menu>
);
return [
<Dropdown overlay={menu}>
<Button type="primary">
<PlusOutlined /> <DownOutlined />
</Button>
</Dropdown>,
<Button key="remove" type="primary" danger onClick={async (value) => {
console.log('del selectedRowsState', selectedRowsState)
const selectedRows = selectedRowsState?.map((item) => ({ key: item?.id }))
console.log('selectedRows', selectedRows)
if (selectedRows?.length > 0) {
const success = await handleRemove(selectedRows);
if (success) {
// handleModalVisible(false);
if (actionRef.current) {
setSelectedRows([]);
actionRef.current?.reloadAndRest();
}
}
} else {
message.warn('请选择删除项')
}
}}>
<DeleteOutlined />
</Button>,
<Button type="primary" 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,
}
}
onChange={({ file, fileList, event }) => {
console.log('file status', file?.status)
console.log('file event', event)
if (file?.status === 'done' && file?.response?.success === true) {
message.success(file?.response?.info);
actionRef.current?.reload(); // 上传完成刷新
}
if (file?.status === 'done' && file?.response?.success === false) {
message.error(file?.response?.error_list?.toString());
//actionRef.current?.reload(); // 上传完成刷新
}
if (file?.status === 'error') {
message.error('批量上传失败');
}
}}
>
<Button key="upload" type="primary">
<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, };
}
console.log('questions?.pageNumber', actionRef.current)
console.log('questions?.totalRow', questions?.totalRow)
setPageNumber(questions?.pageNumber)
return {
current: Number(questions?.pageNumber),
data: data,
pageSize: Number(questions?.pageSize),
success: true,
total: Number(questions?.totalRow) || 10,
};
}}
//dataSource={dataSource}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
// grid={{ gutter: 16, column: 1 }}
showActions="always"
showExtra="always"
metas={{
title: {
title: '题干',
search: false,
dataIndex: 'question_stem',
render: (text: React.ReactNode, record: T, index: number) => (<span style={{ fontFamily: 'auto' }}><Text code style={{ width: 80, fontSize: 10, color: 'bfbfbf', display: 'none' }}>{record?.id}</Text> {text}</span>),
},
avatar: {
title: '题型',
search: false,
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 `${(pageNumber - 1) * actionRef.current?.pageInfo?.pageSize + index + 1}. [${type[0]?.name}]`
},
},
description: {
search: false,
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) ? ['A', 'B'][key] : labels[key]}. ${item?.answer}`}</Typography.Text>
</List.Item>)
}}
/>
);
},
},
subTitle: {
search: false
},
content: {
search: false,
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]}` === `1`).toString()
break;
case 2: // 判断
answer = ['A', 'B']?.filter((x, idx, self) => `${answertrue[idx]}` === `1`).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: {
search: false,
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={() => {
console.log('record', record)
setCurrentRow(record);
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?.reloadAndRest();
}
}
}}
>
<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>
)
}
},
/** 搜索定义 */
question_type: {
title: '题型',
valueType: 'select',
search: true,
dataIndex: 'question_type',
request: async () => {
const { list: Items } = await queryQuestionType();
console.log('queryQuestionType...', Items)
const types = []
for (let i = 0; i < Items.length; i++) {
types.push({ label: Items[i]?.name, value: Items[i]?.code })
}
console.log(types, 'types:::');
return types;
},
},
tags: {
title: '标签',
search: true,
valueType: 'select',
dataIndex: 'tag_ids',
fieldProps: {
//mode: "multiple"
},
request: async () => {
const { data: Items } = await queryTagList({});
console.log('queryTagList...')
const tags = []
for (let i = 0; i < Items.length; i++) {
tags.push({ label: Items[i]?.tag_name, value: Items[i]?.tag_id })
}
console.log(tags, 'tags:::');
return tags;
},
},
course_id: {
title: '课程',
search: true,
valueType: 'select',
dataIndex: 'course_id',
fieldProps: {
//mode: "multiple"
},
dependencies: ['tag_ids'],
request: async (params) => {
const { tag_ids } = params;
const { data: Items } = await queryCourseListByTag({ tag_ids: tag_ids?.toString() });
console.log('queryCourseListByTag...')
const courses = []
for (let i = 0; i < Items?.length; i++) {
courses.push({ label: Items[i]?.course_name, value: Items[i]?.course_id })
}
console.log(courses, 'courses:::');
return courses;
}
},
question_stem: {
title: '搜索', // 题干
search: true,
dataIndex: 'question_stem',
valueType: 'text',
fieldProps: {
placeholder: '请输入关键字'
},
},
create_time: {
title: '创建时间',
search: true,
dataIndex: 'create_time',
valueType: 'dateRange',
fieldProps: {
placeholder: ['开始时间', '结束时间']
},
},
}}
/>
<Modal
title={`新建${addType?.name}`}
//
width="60%"
visible={createModalVisible}
destroyOnClose
onCancel={() => {
setAddType({ name: '', value: '' }); // 还原题型选择
handleCreateModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm<DataItem>
formRef={formRef}
layout="horizontal"
layoutType="Form"
labelCol={{ span: 8 }}
wrapperCol={{ span: 12 }}
onValuesChange={() => {
//console.log('formRef', formRef.current.getFieldInstance('answertrue'))
//console.log('formRef.current', formRef.current.getFieldsValue(['answertrue']))
//console.log('v', value)
//console.log('answers', formRef?.current?.getFieldValue('answers'))
const answerTrue = formRef?.current?.getFieldValue('answertrue');
let fixed_answertrue;
// 如果正确答案为字符串(单选 / 判断)
if (typeof answerTrue === 'string') {
console.log('string.....')
fixed_answertrue = labels.indexOf(answerTrue) < (formRef?.current?.getFieldValue('answers')?.length || 0) ? answerTrue : undefined;
} else if (answerTrue?.length > 0) {
fixed_answertrue = answerTrue?.filter((item, key) => {
return labels.indexOf(item) < (formRef?.current?.getFieldValue('answers')?.length || 0)
})
}
console.log('answerTrue', answerTrue)
/*
const */
//console.log('fixed', fixed_answertrue)
formRef?.current?.setFieldsValue({ answertrue: fixed_answertrue })
}}
onFinish={async (values: any) => {
//console.log('formRef.current', formRef.current.getFieldsValue(['answertrue']))
console.log(values);
return
// 表单处理
console.log('columns:', columns);
console.log('values:', values);
const opts = [];
values?.answers?.forEach((item, key) => {
//
const isTrue = (values?.answertrue.toString().indexOf(labels[key]) !== -1) ? 1 : 0; // 判断是否为正确答案
opts.push({ answer: item, is_true: isTrue })
})
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={() => {
setAddType({ name: '', value: '' }); // 还原题型选择
handleUpdateModalVisible(false);
}}
footer={null}
>
<BetaSchemaForm<DataItem>
layout="horizontal"
layoutType="Form"
labelCol={{ span: 8 }}
wrapperCol={{ span: 12 }}
request={() => {
// 编辑数据初始化
console.log('currentRow##', currentRow)
//answers:currentRow?.answers.map((item)=>(item.answer))
const answertrue = currentRow?.answertrue?.split(',');
console.log('answertrue,,,', answertrue)
const answerTrueData = labels?.filter((x, idx, self) => (`${answertrue[idx]}` === '1'))
console.log('$$$', answerTrueData)
const trueData = Number(currentRow?.question_type) === 1 ? answerTrueData : answerTrueData[0] // 处理单选和判断
const tag_ids = currentRow?.tag_ids.split(',')
return { ...currentRow, answers: currentRow?.answers.map((item) => (item.answer)), answertrue: trueData, tag_ids: tag_ids.map(item => Number(item)) }
}}
onFinish={async (values: any) => {
// 表单处理
console.log('columns:', columns);
console.log('values:', values);
const opts = [];
values?.answers?.forEach((item, key) => {
const is_true = values?.answertrue.indexOf(labels[key]) > -1 ? 1 : 0;
opts.push({ answer: item, is_true: is_true || 0 }) // 循环选项
})
const success = await handleUpdate({
...currentRow,
...values,
type: type, // 必填0-常规题,1-资质考试题
answers: JSON.stringify(opts),
tag_ids: values?.tag_ids?.toString(), // 标签ids
//question_type: currentRow?.question_type, // 题型
// subject_id: params?.id || 0,
});
if (success) {
handleUpdateModalVisible(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 QuestionBank;