|
|
|
@ -9,21 +9,22 @@ 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 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 { DataItem } from '../dashboard/analysis/data';
|
|
|
|
|
import { ActionType, ProColumns } from '@ant-design/pro-table';
|
|
|
|
|
import type { DataItem } from '../dashboard/analysis/data';
|
|
|
|
|
import type { ActionType, ProColumns } from '@ant-design/pro-table';
|
|
|
|
|
import ProFormRichEdit from '../course/subject/components/ProFormRichEdit';
|
|
|
|
|
import { TableListItem } from '../course/option/data';
|
|
|
|
|
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 labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
|
|
|
|
|
const parsingMap = new Map()
|
|
|
|
|
console.log('first');
|
|
|
|
|
|
|
|
|
@ -32,10 +33,10 @@ console.log('first');
|
|
|
|
|
*
|
|
|
|
|
* @param fields
|
|
|
|
|
*/
|
|
|
|
|
const handleAdd = async (fields: TableListItem) => {
|
|
|
|
|
const handleAdd = async (fields: TableListItem) => {
|
|
|
|
|
const hide = message.loading('正在添加');
|
|
|
|
|
try {
|
|
|
|
|
await saveQuestion({ ...fields});
|
|
|
|
|
await saveQuestion({ ...fields });
|
|
|
|
|
hide();
|
|
|
|
|
message.success('添加成功');
|
|
|
|
|
return true;
|
|
|
|
@ -51,10 +52,10 @@ console.log('first');
|
|
|
|
|
*
|
|
|
|
|
* @param fields
|
|
|
|
|
*/
|
|
|
|
|
const handleUpdate = async (fields: TableListItem) => {
|
|
|
|
|
const handleUpdate = async (fields: TableListItem) => {
|
|
|
|
|
const hide = message.loading('正在保存');
|
|
|
|
|
try {
|
|
|
|
|
await saveQuestion({ ...fields});
|
|
|
|
|
await saveQuestion({ ...fields });
|
|
|
|
|
hide();
|
|
|
|
|
message.success('保存成功');
|
|
|
|
|
return true;
|
|
|
|
@ -76,13 +77,13 @@ const handleRemove = async (selectedRows: TableListItem[]) => {
|
|
|
|
|
if (!selectedRows) return true;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const {code, msg} = await removeQuestion({
|
|
|
|
|
const { code, msg } = await removeQuestion({
|
|
|
|
|
key: selectedRows.map((row) => row.key),
|
|
|
|
|
});
|
|
|
|
|
hide();
|
|
|
|
|
if(code === 2000 ){
|
|
|
|
|
if (code === 2000) {
|
|
|
|
|
message.success('删除成功,即将刷新');
|
|
|
|
|
}else{
|
|
|
|
|
} else {
|
|
|
|
|
message.warning(msg);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
@ -97,26 +98,26 @@ const QuestionBank = () => {
|
|
|
|
|
const match = useRouteMatch();
|
|
|
|
|
console.log('match', match);
|
|
|
|
|
|
|
|
|
|
const type = history.location.pathname === '/questionbank/attestation' ? 1 : 0 ; // 题库类型
|
|
|
|
|
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 [addType, setAddType] = useState({ name: '', value: '' });
|
|
|
|
|
|
|
|
|
|
const [pageNumber, setPageNumber] = useState(1)
|
|
|
|
|
//const [answertrueValues, setAnswertrueValues] = useState(); // 编辑试题答案项值
|
|
|
|
|
//const [options, setOptions] = useState([]); // 设置当前选项, 用于删除选项时判断
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 表单项定义 */
|
|
|
|
|
const columns: ProColumns<TableListItem>[] = [
|
|
|
|
|
{
|
|
|
|
@ -176,8 +177,8 @@ const QuestionBank = () => {
|
|
|
|
|
renderText: (val: string) => `${val}`,
|
|
|
|
|
dependencies: ['tag_ids'],
|
|
|
|
|
request: async (params) => {
|
|
|
|
|
const {tag_ids} = params;
|
|
|
|
|
const { data: Items } = await queryCourseListByTag({tag_ids: tag_ids?.toString()});
|
|
|
|
|
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++) {
|
|
|
|
@ -198,7 +199,7 @@ const QuestionBank = () => {
|
|
|
|
|
fieldProps: {
|
|
|
|
|
maxLength: 50
|
|
|
|
|
},
|
|
|
|
|
formItemProps: {
|
|
|
|
|
formItemProps: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
@ -235,42 +236,42 @@ const QuestionBank = () => {
|
|
|
|
|
hideInTable: false,
|
|
|
|
|
hideInForm: false,
|
|
|
|
|
hideInSearch: true,
|
|
|
|
|
dependencies:['answers'],
|
|
|
|
|
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('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++){
|
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
|
|
|
opts.push(labels[i])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(Number(form.getFieldValue('question_type')) === 0){
|
|
|
|
|
|
|
|
|
|
if (Number(form.getFieldValue('question_type')) === 0) {
|
|
|
|
|
console.log('my type', Number(form.getFieldValue('question_type')))
|
|
|
|
|
}else{
|
|
|
|
|
} else {
|
|
|
|
|
console.log('====0')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log('answers??',form.getFieldValue('answers')?.length)
|
|
|
|
|
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}
|
|
|
|
|
/>
|
|
|
|
|
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: {
|
|
|
|
@ -295,43 +296,52 @@ const QuestionBank = () => {
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
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();
|
|
|
|
|
});
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
const { data: template } = useRequest(() => {
|
|
|
|
|
return exportQuestionTemplate();
|
|
|
|
|
});
|
|
|
|
|
*/
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setQuestionType(data || []);
|
|
|
|
|
return ()=>{
|
|
|
|
|
return () => {
|
|
|
|
|
/** 退出当前页面清空Map */
|
|
|
|
|
parsingMap.clear();
|
|
|
|
|
}
|
|
|
|
@ -340,7 +350,7 @@ const QuestionBank = () => {
|
|
|
|
|
return (
|
|
|
|
|
<PageContainer content={false} extraContent={false} className={styles.questionbank}>
|
|
|
|
|
<ProList<any>
|
|
|
|
|
style={{minWidth:1180}}
|
|
|
|
|
style={{ minWidth: 1180 }}
|
|
|
|
|
rowKey='id'
|
|
|
|
|
itemLayout="vertical"
|
|
|
|
|
actionRef={actionRef}
|
|
|
|
@ -356,34 +366,34 @@ const QuestionBank = () => {
|
|
|
|
|
toolBarRender={() => {
|
|
|
|
|
const menuItems = [];
|
|
|
|
|
console.log('toolBarRender', questionType);
|
|
|
|
|
if(questionType?.length > 0){
|
|
|
|
|
if (questionType?.length > 0) {
|
|
|
|
|
console.log('push');
|
|
|
|
|
questionType.forEach((item: {code: number, name: string})=>{
|
|
|
|
|
questionType.forEach((item: { code: number, name: string }) => {
|
|
|
|
|
menuItems.push(<Menu.Item key={item?.code}>{item?.name}</Menu.Item>)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
const menu = (
|
|
|
|
|
<Menu onClick={(value)=>{
|
|
|
|
|
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)});
|
|
|
|
|
console.log('menuquestionType',);
|
|
|
|
|
setAddType({ name: questionType[Number(value?.key)]?.name, value: Number(value?.key) });
|
|
|
|
|
handleCreateModalVisible(true);
|
|
|
|
|
}}>
|
|
|
|
|
}}>
|
|
|
|
|
{menuItems}
|
|
|
|
|
</Menu>
|
|
|
|
|
</Menu>
|
|
|
|
|
);
|
|
|
|
|
return [
|
|
|
|
|
<Dropdown overlay={menu}>
|
|
|
|
|
<Button type="primary">
|
|
|
|
|
<PlusOutlined /> 新建试题 <DownOutlined />
|
|
|
|
|
<PlusOutlined /> 新建试题 <DownOutlined />
|
|
|
|
|
</Button>
|
|
|
|
|
</Dropdown>,
|
|
|
|
|
<Button key="remove" type="primary" danger onClick={async (value)=>{
|
|
|
|
|
<Button key="remove" type="primary" danger onClick={async (value) => {
|
|
|
|
|
console.log('del selectedRowsState', selectedRowsState)
|
|
|
|
|
const selectedRows = selectedRowsState?.map((item)=>({key:item?.id}))
|
|
|
|
|
const selectedRows = selectedRowsState?.map((item) => ({ key: item?.id }))
|
|
|
|
|
console.log('selectedRows', selectedRows)
|
|
|
|
|
if(selectedRows?.length > 0){
|
|
|
|
|
if (selectedRows?.length > 0) {
|
|
|
|
|
const success = await handleRemove(selectedRows);
|
|
|
|
|
if (success) {
|
|
|
|
|
// handleModalVisible(false);
|
|
|
|
@ -393,13 +403,13 @@ const QuestionBank = () => {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
} else {
|
|
|
|
|
message.warn('请选择删除项')
|
|
|
|
|
}
|
|
|
|
|
}}>
|
|
|
|
|
<DeleteOutlined /> 批量删除
|
|
|
|
|
</Button>,
|
|
|
|
|
<Button type="primary" key="download" onClick={()=>{window.location.href='/dsideal_yy/zygh/training/exportQuestionTemplate'}} >
|
|
|
|
|
<Button type="primary" key="download" onClick={() => { window.location.href = '/dsideal_yy/zygh/training/exportQuestionTemplate' }} >
|
|
|
|
|
<DownloadOutlined /> 下载模板
|
|
|
|
|
</Button>,
|
|
|
|
|
<Upload
|
|
|
|
@ -411,18 +421,18 @@ const QuestionBank = () => {
|
|
|
|
|
type: type,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onChange={({file, fileList, event })=>{
|
|
|
|
|
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);
|
|
|
|
|
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() );
|
|
|
|
|
if (file?.status === 'done' && file?.response?.success === false) {
|
|
|
|
|
message.error(file?.response?.error_list?.toString());
|
|
|
|
|
//actionRef.current?.reload(); // 上传完成刷新
|
|
|
|
|
}
|
|
|
|
|
if(file?.status === 'error'){
|
|
|
|
|
if (file?.status === 'error') {
|
|
|
|
|
message.error('批量上传失败');
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
@ -463,13 +473,13 @@ const QuestionBank = () => {
|
|
|
|
|
page_size: value?.pageSize,
|
|
|
|
|
});
|
|
|
|
|
// 课程名称及课程标签
|
|
|
|
|
console.log('data',questions);
|
|
|
|
|
console.log('data', questions);
|
|
|
|
|
const data = []
|
|
|
|
|
for(let i=0; i<questions?.table_List.length; i++){
|
|
|
|
|
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, };
|
|
|
|
|
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)
|
|
|
|
@ -496,7 +506,7 @@ const QuestionBank = () => {
|
|
|
|
|
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>),
|
|
|
|
|
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: '题型',
|
|
|
|
@ -504,15 +514,15 @@ const QuestionBank = () => {
|
|
|
|
|
dataIndex: 'question_type',
|
|
|
|
|
valueType: 'text',
|
|
|
|
|
render: (text: React.ReactNode, record: T, index: number) => {
|
|
|
|
|
const type = questionType?.filter((item, idx, self)=>{
|
|
|
|
|
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}]`
|
|
|
|
|
console.log('questionType::::', questionType);
|
|
|
|
|
return `${(pageNumber - 1) * actionRef.current?.pageInfo?.pageSize + index + 1}. [${type[0]?.name}]`
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
description: {
|
|
|
|
@ -528,51 +538,51 @@ const QuestionBank = () => {
|
|
|
|
|
bordered={false}
|
|
|
|
|
dataSource={record.answers || []}
|
|
|
|
|
rowKey='id'
|
|
|
|
|
renderItem={ (item, key) => {
|
|
|
|
|
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>
|
|
|
|
|
<Typography.Text mark={false}>{`${(record?.question_type === 2) ? ['A', 'B'][key] : labels[key]}. ${item?.answer}`}</Typography.Text>
|
|
|
|
|
</List.Item>)
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
subTitle: {
|
|
|
|
|
subTitle: {
|
|
|
|
|
search: false
|
|
|
|
|
},
|
|
|
|
|
content: {
|
|
|
|
|
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){
|
|
|
|
|
switch (record?.question_type) {
|
|
|
|
|
case 0: // 单选
|
|
|
|
|
case 1: // 多选
|
|
|
|
|
answer = labels?.filter((x, idx, self)=>`${answertrue[idx]}` === `1`).toString()
|
|
|
|
|
answer = labels?.filter((x, idx, self) => `${answertrue[idx]}` === `1`).toString()
|
|
|
|
|
break;
|
|
|
|
|
case 2: // 判断
|
|
|
|
|
answer = ['A', 'B']?.filter((x, idx, self)=>`${answertrue[idx]}` === `1`).toString()
|
|
|
|
|
answer = ['A', 'B']?.filter((x, idx, self) => `${answertrue[idx]}` === `1`).toString()
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
console.log('expandedDescRowKeys', expandedDescRowKeys)
|
|
|
|
|
if(expandedDescRowKeys?.indexOf(record.id) > -1){
|
|
|
|
|
if (expandedDescRowKeys?.indexOf(record.id) > -1) {
|
|
|
|
|
return (
|
|
|
|
|
<Space direction="vertical" style={{borderTop:'solid 1px #f0f0f0', padding:10, margin: '5px -18px 0 -24px', background: '#fdfdfd'}}>
|
|
|
|
|
<Space direction="vertical" style={{ borderTop: 'solid 1px #f0f0f0', padding: 10, margin: '5px -18px 0 -24px', background: '#fdfdfd' }}>
|
|
|
|
|
<Typography>正确答案:
|
|
|
|
|
{answer}
|
|
|
|
|
{answer}
|
|
|
|
|
</Typography>
|
|
|
|
|
<Typography>【解析】:<div dangerouslySetInnerHTML={{__html: parsing.get(record.id)}} /></Typography>
|
|
|
|
|
<Typography>【解析】:<div dangerouslySetInnerHTML={{ __html: parsing.get(record.id) }} /></Typography>
|
|
|
|
|
</Space>
|
|
|
|
|
);
|
|
|
|
|
}else{
|
|
|
|
|
} else {
|
|
|
|
|
return (
|
|
|
|
|
<Space direction="vertical" style={{borderTop:'solid 1px #f0f0f0', padding:10, margin: '5px -18px 0 -24px', background: '#fdfdfd'}}>
|
|
|
|
|
<Space direction="vertical" style={{ borderTop: 'solid 1px #f0f0f0', padding: 10, margin: '5px -18px 0 -24px', background: '#fdfdfd' }}>
|
|
|
|
|
<Typography>正确答案:
|
|
|
|
|
{answer}
|
|
|
|
|
{answer}
|
|
|
|
|
</Typography>
|
|
|
|
|
</Space>
|
|
|
|
|
)
|
|
|
|
@ -585,24 +595,24 @@ const QuestionBank = () => {
|
|
|
|
|
cardActionProps: 'extra',
|
|
|
|
|
render: (text: React.ReactNode, record: T, _index: number) => {
|
|
|
|
|
let eye
|
|
|
|
|
if(expandedDescRowKeys?.indexOf(record.id) > -1){
|
|
|
|
|
if (expandedDescRowKeys?.indexOf(record.id) > -1) {
|
|
|
|
|
eye = <><EyeInvisibleOutlined /> 隐藏解析</>
|
|
|
|
|
}else{
|
|
|
|
|
} else {
|
|
|
|
|
eye = <><EyeOutlined /> 查看解析</>
|
|
|
|
|
}
|
|
|
|
|
return(
|
|
|
|
|
<Row style={{padding:'10px 24px'}}>
|
|
|
|
|
<Col flex={1} style={{textAlign:'left'}}>
|
|
|
|
|
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'}}>
|
|
|
|
|
<Col flex={1} style={{ textAlign: 'right' }}>
|
|
|
|
|
<Space direction="horizontal" size="middle">
|
|
|
|
|
<a onClick={()=>{
|
|
|
|
|
console.log('record',record)
|
|
|
|
|
<a onClick={() => {
|
|
|
|
|
console.log('record', record)
|
|
|
|
|
setCurrentRow(record);
|
|
|
|
|
handleUpdateModalVisible(true)
|
|
|
|
|
return false;
|
|
|
|
@ -626,35 +636,35 @@ const QuestionBank = () => {
|
|
|
|
|
|
|
|
|
|
<a
|
|
|
|
|
key="view"
|
|
|
|
|
onClick={async ()=>{
|
|
|
|
|
if(expandedDescRowKeys?.indexOf(record.id) > -1){
|
|
|
|
|
const descRowKeys = expandedDescRowKeys?.filter((item, idx, self)=>{
|
|
|
|
|
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})
|
|
|
|
|
} 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>
|
|
|
|
|
</Row>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/** 搜索定义 */
|
|
|
|
|
question_type:{
|
|
|
|
|
question_type: {
|
|
|
|
|
title: '题型',
|
|
|
|
|
valueType: 'select',
|
|
|
|
|
search: true,
|
|
|
|
@ -670,7 +680,7 @@ const QuestionBank = () => {
|
|
|
|
|
return types;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
tags: {
|
|
|
|
|
tags: {
|
|
|
|
|
title: '标签',
|
|
|
|
|
search: true,
|
|
|
|
|
valueType: 'select',
|
|
|
|
@ -699,8 +709,8 @@ const QuestionBank = () => {
|
|
|
|
|
},
|
|
|
|
|
dependencies: ['tag_ids'],
|
|
|
|
|
request: async (params) => {
|
|
|
|
|
const {tag_ids} = params;
|
|
|
|
|
const { data: Items } = await queryCourseListByTag({tag_ids: tag_ids?.toString()});
|
|
|
|
|
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++) {
|
|
|
|
@ -716,7 +726,7 @@ const QuestionBank = () => {
|
|
|
|
|
dataIndex: 'question_stem',
|
|
|
|
|
valueType: 'text',
|
|
|
|
|
fieldProps: {
|
|
|
|
|
placeholder:'请输入关键字'
|
|
|
|
|
placeholder: '请输入关键字'
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
create_time: {
|
|
|
|
@ -725,19 +735,19 @@ const QuestionBank = () => {
|
|
|
|
|
dataIndex: 'create_time',
|
|
|
|
|
valueType: 'dateRange',
|
|
|
|
|
fieldProps: {
|
|
|
|
|
placeholder:['开始时间','结束时间']
|
|
|
|
|
},
|
|
|
|
|
placeholder: ['开始时间', '结束时间']
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Modal
|
|
|
|
|
title={`新建${addType?.name }`}
|
|
|
|
|
title={`新建${addType?.name}`}
|
|
|
|
|
//
|
|
|
|
|
width="60%"
|
|
|
|
|
visible={createModalVisible}
|
|
|
|
|
destroyOnClose
|
|
|
|
|
onCancel={() => {
|
|
|
|
|
setAddType({name: '', value: ''}); // 还原题型选择
|
|
|
|
|
setAddType({ name: '', value: '' }); // 还原题型选择
|
|
|
|
|
handleCreateModalVisible(false);
|
|
|
|
|
}}
|
|
|
|
|
footer={null}
|
|
|
|
@ -748,7 +758,7 @@ const QuestionBank = () => {
|
|
|
|
|
layoutType="Form"
|
|
|
|
|
labelCol={{ span: 8 }}
|
|
|
|
|
wrapperCol={{ span: 12 }}
|
|
|
|
|
onValuesChange={()=>{
|
|
|
|
|
onValuesChange={() => {
|
|
|
|
|
//console.log('formRef', formRef.current.getFieldInstance('answertrue'))
|
|
|
|
|
//console.log('formRef.current', formRef.current.getFieldsValue(['answertrue']))
|
|
|
|
|
//console.log('v', value)
|
|
|
|
@ -756,11 +766,11 @@ const QuestionBank = () => {
|
|
|
|
|
const answerTrue = formRef?.current?.getFieldValue('answertrue');
|
|
|
|
|
let fixed_answertrue;
|
|
|
|
|
// 如果正确答案为字符串(单选 / 判断)
|
|
|
|
|
if(typeof answerTrue === 'string'){
|
|
|
|
|
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)=>{
|
|
|
|
|
} else if (answerTrue?.length > 0) {
|
|
|
|
|
fixed_answertrue = answerTrue?.filter((item, key) => {
|
|
|
|
|
return labels.indexOf(item) < (formRef?.current?.getFieldValue('answers')?.length || 0)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
@ -768,19 +778,21 @@ const QuestionBank = () => {
|
|
|
|
|
/*
|
|
|
|
|
const */
|
|
|
|
|
//console.log('fixed', fixed_answertrue)
|
|
|
|
|
formRef?.current?.setFieldsValue({answertrue: 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);
|
|
|
|
|
console.log('values:', values);
|
|
|
|
|
const opts = [];
|
|
|
|
|
values?.answers?.forEach((item, key)=>{
|
|
|
|
|
values?.answers?.forEach((item, key) => {
|
|
|
|
|
//
|
|
|
|
|
const isTrue = (values?.answertrue.toString().indexOf(labels[key]) !== -1) ? 1 : 0; // 判断是否为正确答案
|
|
|
|
|
opts.push({answer:item, is_true:isTrue})
|
|
|
|
|
opts.push({ answer: item, is_true: isTrue })
|
|
|
|
|
})
|
|
|
|
|
const success = await handleAdd({
|
|
|
|
|
...values,
|
|
|
|
@ -790,7 +802,7 @@ const QuestionBank = () => {
|
|
|
|
|
// subject_id: params?.id || 0,
|
|
|
|
|
});
|
|
|
|
|
console.log('123')
|
|
|
|
|
if(success){
|
|
|
|
|
if (success) {
|
|
|
|
|
handleCreateModalVisible(false);
|
|
|
|
|
actionRef.current?.reload();
|
|
|
|
|
}
|
|
|
|
@ -810,13 +822,13 @@ const QuestionBank = () => {
|
|
|
|
|
/>
|
|
|
|
|
</Modal>
|
|
|
|
|
<Modal
|
|
|
|
|
title={`编辑${addType?.name }`}
|
|
|
|
|
title={`编辑${addType?.name}`}
|
|
|
|
|
//
|
|
|
|
|
width="60%"
|
|
|
|
|
visible={updateModalVisible}
|
|
|
|
|
destroyOnClose
|
|
|
|
|
onCancel={() => {
|
|
|
|
|
setAddType({name: '', value: ''}); // 还原题型选择
|
|
|
|
|
setAddType({ name: '', value: '' }); // 还原题型选择
|
|
|
|
|
handleUpdateModalVisible(false);
|
|
|
|
|
}}
|
|
|
|
|
footer={null}
|
|
|
|
@ -826,29 +838,29 @@ const QuestionBank = () => {
|
|
|
|
|
layoutType="Form"
|
|
|
|
|
labelCol={{ span: 8 }}
|
|
|
|
|
wrapperCol={{ span: 12 }}
|
|
|
|
|
request={()=>{
|
|
|
|
|
request={() => {
|
|
|
|
|
// 编辑数据初始化
|
|
|
|
|
console.log('currentRow##',currentRow)
|
|
|
|
|
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('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)) }
|
|
|
|
|
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('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}) // 循环选项
|
|
|
|
|
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,
|
|
|
|
@ -858,7 +870,7 @@ const QuestionBank = () => {
|
|
|
|
|
//question_type: currentRow?.question_type, // 题型
|
|
|
|
|
// subject_id: params?.id || 0,
|
|
|
|
|
});
|
|
|
|
|
if(success){
|
|
|
|
|
if (success) {
|
|
|
|
|
handleUpdateModalVisible(false);
|
|
|
|
|
actionRef.current?.reloadAndRest?.();
|
|
|
|
|
}
|
|
|
|
|