合并题库

master
zhengpengju 3 years ago
parent fa7c9b3c9d
commit d9872d4404

@ -128,13 +128,13 @@ export default defineConfig({
name: '常规题库维护',
icon: 'smile',
path: '/questionbank/normal',
component: './questionbank/normal',
component: './questionbank',
},
{
name: '资质考试题库维护',
icon: 'smile',
path: '/questionbank/attestation',
component: './questionbank/attestation',
component: './questionbank',
},
],
},

@ -14,7 +14,7 @@ const Settings: LayoutSettings & {
colorWeak: false,
title: '生涯在线学习-资质考试',
pwa: false,
logo: '../logo.svg',
logo: './logo.svg',
iconfontUrl: '',
menu:{ locale: false } // 关闭国际化语言
};

@ -1,207 +0,0 @@
/** 资质考试 */
//import { AlignLeftOutlined, PlusOutlined } from '@ant-design/icons';
import { Switch, Button, Card, Col, List, Menu, Progress, Row, Typography, Space, Divider, Radio, Checkbox, Tag, Dropdown } 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, useState } from 'react';
import { PlusOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EditOutlined, EyeOutlined, EyeInvisibleOutlined, DownOutlined } from '@ant-design/icons';
//const { Paragraph } = Typography;
const QuestionBank = () => {
const [selectedRowsState, setSelectedRows] = useState<API.RuleListItem[]>([]);
const [expandedDescRowKeys, setExpandedDescRowKeys] = useState<readonly ReactText[]>([]); // 展开解析设置
const [addType, setAddType] = useState(0);
const numbers = [];
for(let i=0;i<50;i++){
numbers.push({id: `${i}`})
}
const dataSource = [
{
id: 1,
name: '下面哪个词语能体现未来思维?',
type: '单选',
options: [
{label: '井底之蛙', value: 'A'},
{label: '鼠目寸光', value: 'B'},
{label: '未雨绸缪', value: 'C'},
{label: '即时行乐', value: 'D'},
],
time: '2022/12/12',
tag: '生涯理论',
course: '特质因素理论',
answer:'C',
desc: '该成语意思是天还没有下雨,先把门窗绑牢。比喻事先做好准备工作。该成语意思是天还没有下雨,先把门窗绑牢。比喻事先做好准备工作。该成语意思是天还没有下雨,先把门窗绑牢。比喻事先做好准备工作。该成语意思是天还没有下雨,先把门窗绑牢。比喻事先做好准备工作。',
},
{
id: 2,
name: 'Ant Design',
type: '多选',
image:
'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg',
desc: '我是一条测试的描述',
},
{
id: 3,
name: '蚂蚁金服体验科技',
type: '判断',
image:
'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg',
desc: '我是一条测试的描述',
},
{
id: 4,
name: 'TechUI',
type: '单选',
image:
'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg',
desc: '我是一条测试的描述',
},
];
return (
<PageContainer content={false} extraContent={false} className={styles.questionbank}>
<ProList<any>
itemLayout="vertical"
rowClassName='questionbank-list-item'
pagination={{
defaultPageSize: 10,
showSizeChanger: false,
}}
toolBarRender={() => {
const menu = (
<Menu onClick={(value)=>setAddType(value)}>
<Menu.Item key="1"></Menu.Item>
<Menu.Item key="2"></Menu.Item>
<Menu.Item key="3"></Menu.Item>
</Menu>
);
return [
<Dropdown overlay={menu}>
<Button>
<PlusOutlined /> <DownOutlined />
</Button>
</Dropdown>,
<Button key="remove" type="default" danger>
<DeleteOutlined />
</Button>,
<Button key="download" >
<DownloadOutlined />
</Button>,
<Button key="upload" >
<UploadOutlined />
</Button>,
];
}}
onRow={(record: any) => {
return {
onMouseEnter: () => {
console.log(record);
},
onClick: () => {
console.log(record);
},
};
}}
rowKey="id"
headerTitle={false}
tooltip={false}
dataSource={dataSource}
rowSelection={{
onChange: (_, selectedRows) => {
setSelectedRows(selectedRows);
},
}}
// grid={{ gutter: 16, column: 1 }}
showActions="always"
showExtra="always"
metas={{
title: {
dataIndex: 'name',
render: (text: React.ReactNode, record: T, index: number) => `1. ${text}`,
},
avatar: {
dataIndex: 'type',
valueType: 'text',
render: (text: React.ReactNode, record: T, index: number) => `[${record.type}]`,
},
description: {
dataIndex: 'options',
valueType: 'checkbox',
render: (text: React.ReactNode, record: T, index: number) => {
return (
<List
header={false}
footer={false}
bordered={false}
dataSource={record.options || []}
renderItem={item => (
<List.Item>
<Typography.Text mark={false}>{`${item?.value}. ${item?.label}`}</Typography.Text>
</List.Item>
)}
/>
);
},
},
subTitle: { },
content: {
render: (text: React.ReactNode, record: T, index: number) => {
return (
<Space direction="vertical" style={{border:'solid 1px #f0f0f0;',padding:10}}>
<Typography>{record.answer}</Typography>
<Typography>{record.desc}</Typography>
</Space>
);
},
},
actions: {
cardActionProps: 'extra',
render: (text: React.ReactNode, record: T, _index: number) => {
return(
<Row style={{padding:'10px 24px'}}>
<Col flex={1} style={{textAlign:'left'}}>
<Space direction="horizontal" size="large">
<Typography>{record.time}</Typography>
<Typography>{record.tag}</Typography>
<Typography>{record.course}</Typography>
</Space>
</Col>
<Col flex={1} style={{textAlign:'right'}}>
<Space direction="horizontal" size="middle">
<a href={record.html_url} target="_blank" rel="noopener noreferrer" key="link">
<EditOutlined />
</a>
<a href={record.html_url} target="_blank" rel="noopener noreferrer" key="warning">
<DeleteOutlined />
</a>
<a
key="view"
onClick={()=>{
setExpandedDescRowKeys([...expandedDescRowKeys, record.id]);
console.log('record id:', record.id);
console.log('expandedDescRowKeys', expandedDescRowKeys)
}}
>
<EyeOutlined /> <EyeInvisibleOutlined />
</a>
</Space>
</Col>
</Row>
)
}
},
}}
/>
</PageContainer>
);
};
export default QuestionBank;

@ -1,10 +0,0 @@
import { request } from 'umi';
import type { CardListItemDataType } from './data.d';
export async function queryFakeList(params: {
count: number;
}): Promise<{ data: { list: CardListItemDataType[] } }> {
return request('/api/card_fake_list', {
params,
});
}

@ -12,14 +12,18 @@ import ProList from '@ant-design/pro-list';
import { ReactText, useEffect, useState } from 'react';
import { PlusOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined, EditOutlined, EyeOutlined, EyeInvisibleOutlined, DownOutlined } from '@ant-design/icons';
import { exportQuestionTemplate, queryQuestionById, queryQuestionList, queryQuestionType } from './service';
import { useRequest } from 'umi';
import { useParams, useRequest, history, useRouteMatch } from 'umi';
import { queryCourseView } from '@/pages/course/option/service';
//const { Paragraph } = Typography;
const parsingMap = new Map()
console.log('first');
const QuestionBank = () => {
console.log('second');
const match = useRouteMatch();
console.log('match', match);
const type = history.location.pathname === '/questionbank/attestation' ? 1 : 0 ; // 题库类型
const [questionType, setQuestionType] = useState([]);
const [parsing, setParsing] = useState();
@ -50,8 +54,6 @@ const QuestionBank = () => {
parsingMap.clear();
}
}, [data]);
return (
<PageContainer content={false} extraContent={false} className={styles.questionbank}>
@ -91,10 +93,10 @@ const QuestionBank = () => {
<Upload
accept='.xlsx'
showUploadList={false}
action="/dsideal_yy/res/plupload/"
action="dsideal_yy/zygh/training/importQuestionData"
data={
{
type: 0,
type: type,
}
}
>
@ -129,7 +131,7 @@ const QuestionBank = () => {
const questions = await queryQuestionList({
...value,
type: 0,
type: type,
page_number: value?.current || 1,
page_size: value?.pageSize,
});

@ -1,160 +0,0 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import type { Request, Response } from 'express';
import type { BasicListItemDataType } from './data.d';
const titles = [
'Alipay',
'Angular',
'Ant Design',
'Ant Design Pro',
'Bootstrap',
'React',
'Vue',
'Webpack',
];
const avatars = [
'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay
'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular
'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design
'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro
'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap
'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React
'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue
'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack
];
const covers = [
'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png',
'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png',
'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png',
'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png',
];
const desc = [
'那是一种内在的东西, 他们到达不了,也无法触及的',
'希望是一个好东西,也许是最好的,好东西是不会消亡的',
'生命就像一盒巧克力,结果往往出人意料',
'城镇中有那么多的酒馆,她却偏偏走进了我的酒馆',
'那时候我只会想自己想要什么,从不想自己拥有什么',
];
const user = [
'付小小',
'曲丽丽',
'林东东',
'周星星',
'吴加好',
'朱偏右',
'鱼酱',
'乐哥',
'谭小仪',
'仲尼',
];
function fakeList(count: number): BasicListItemDataType[] {
const list = [];
for (let i = 0; i < count; i += 1) {
list.push({
id: `fake-list-${i}`,
owner: user[i % 10],
title: titles[i % 8],
avatar: avatars[i % 8],
cover: parseInt(`${i / 4}`, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)],
status: ['active', 'exception', 'normal'][i % 3] as
| 'normal'
| 'exception'
| 'active'
| 'success',
percent: Math.ceil(Math.random() * 50) + 50,
logo: avatars[i % 8],
href: 'https://ant.design',
updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i).getTime(),
createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i).getTime(),
subDescription: desc[i % 5],
description:
'在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。',
activeUser: Math.ceil(Math.random() * 100000) + 100000,
newUser: Math.ceil(Math.random() * 1000) + 1000,
star: Math.ceil(Math.random() * 100) + 100,
like: Math.ceil(Math.random() * 100) + 100,
message: Math.ceil(Math.random() * 10) + 10,
content:
'段落示意:蚂蚁金服设计平台 ant.design用最小的工作量无缝接入蚂蚁金服生态提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design用最小的工作量无缝接入蚂蚁金服生态提供跨越设计与开发的体验解决方案。',
members: [
{
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png',
name: '曲丽丽',
id: 'member1',
},
{
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png',
name: '王昭君',
id: 'member2',
},
{
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png',
name: '董娜娜',
id: 'member3',
},
],
});
}
return list;
}
let sourceData: BasicListItemDataType[] = [];
function getFakeList(req: Request, res: Response) {
const params = req.query as any;
const count = Number(params.count) * 1 || 20;
const result = fakeList(count);
sourceData = result;
return res.json({
data: {
list: result,
},
});
}
function postFakeList(req: Request, res: Response) {
const { /* url = '', */ body } = req;
// const params = getUrlParams(url);
const { method, id } = body;
// const count = (params.count * 1) || 20;
let result = sourceData || [];
switch (method) {
case 'delete':
result = result.filter((item) => item.id !== id);
break;
case 'update':
result.forEach((item, i) => {
if (item.id === id) {
result[i] = { ...item, ...body };
}
});
break;
case 'post':
result.unshift({
...body,
id: `fake-list-${result.length}`,
createdAt: new Date().getTime(),
});
break;
default:
break;
}
return res.json({
data: {
list: result,
},
});
}
export default {
'GET /api/get_list': getFakeList,
'POST /api/post_fake_list': postFakeList,
};

@ -1,105 +0,0 @@
import type { FC } from 'react';
import {
ModalForm,
ProFormSelect,
ProFormDateTimePicker,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-form';
import type { BasicListItemDataType } from '../data.d';
import styles from '../style.less';
import { Button, Result } from 'antd';
type OperationModalProps = {
done: boolean;
visible: boolean;
current: Partial<BasicListItemDataType> | undefined;
onDone: () => void;
onSubmit: (values: BasicListItemDataType) => void;
};
const OperationModal: FC<OperationModalProps> = (props) => {
const { done, visible, current, onDone, onSubmit, children } = props;
if (!visible) {
return null;
}
return (
<ModalForm<BasicListItemDataType>
visible={visible}
title={done ? null : `任务${current ? '编辑' : '添加'}`}
className={styles.standardListForm}
width={640}
onFinish={async (values) => {
onSubmit(values);
}}
initialValues={current}
submitter={{
render: (_, dom) => (done ? null : dom),
}}
trigger={<>{children}</>}
modalProps={{
onCancel: () => onDone(),
destroyOnClose: true,
bodyStyle: done ? { padding: '72px 0' } : {},
}}
>
{!done ? (
<>
<ProFormText
name="title"
label="任务名称"
rules={[{ required: true, message: '请输入任务名称' }]}
placeholder="请输入"
/>
<ProFormDateTimePicker
name="createdAt"
label="开始时间"
rules={[{ required: true, message: '请选择开始时间' }]}
fieldProps={{
style: {
width: '100%',
},
}}
placeholder="请选择"
/>
<ProFormSelect
name="owner"
label="任务负责人"
rules={[{ required: true, message: '请选择任务负责人' }]}
options={[
{
label: '付晓晓',
value: 'xiao',
},
{
label: '周毛毛',
value: 'mao',
},
]}
placeholder="请选择管理员"
/>
<ProFormTextArea
name="subDescription"
label="产品描述"
rules={[{ message: '请输入至少五个字符的产品描述!', min: 5 }]}
placeholder="请输入至少五个字符"
/>
</>
) : (
<Result
status="success"
title="操作成功"
subTitle="一系列的信息描述,很短同样也可以带标点。"
extra={
<Button type="primary" onClick={onDone}>
</Button>
}
className={styles.formResult}
/>
)}
</ModalForm>
);
};
export default OperationModal;

@ -1,29 +0,0 @@
export type Member = {
avatar: string;
name: string;
id: string;
};
export type CardListItemDataType = {
id: string;
owner: string;
title: string;
avatar: string;
cover: string;
status: 'normal' | 'exception' | 'active' | 'success';
percent: number;
logo: string;
href: string;
body?: any;
updatedAt: number;
createdAt: number;
subDescription: string;
description: string;
activeUser: number;
newUser: number;
star: number;
like: number;
message: number;
content: string;
members: Member[];
};

@ -1,23 +0,0 @@
@import '~antd/es/style/themes/default.less';
.questionbank{
:global {
.ant-list-split.ant-list-something-after-last-item .ant-spin-container > .ant-list-items > .ant-list-item:last-child{
border: none;
}
.questionbank-list-item{
//background: #f0f0f0;
border: solid 1px #f0f0f0 !important;
margin: 15px 0;
}
.ant-list-vertical .ant-list-item-action{
padding: 0 !important;
margin: 0 -18px -12px -24px !important;
}
.ant-list-item-action li{
padding: 10px 18px;
background: #f0f0f0;
display: inline-block;
width: 100%;
}
}
}

@ -1,50 +0,0 @@
.textOverflow() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
}
.textOverflowMulti(@line: 3, @bg: #fff) {
position: relative;
max-height: @line * 1.5em;
margin-right: -1em;
padding-right: 1em;
overflow: hidden;
line-height: 1.5em;
text-align: justify;
&::before {
position: absolute;
right: 14px;
bottom: 0;
padding: 0 1px;
background: @bg;
content: '...';
}
&::after {
position: absolute;
right: 14px;
width: 1em;
height: 1em;
margin-top: 0.2em;
background: white;
content: '';
}
}
// mixins for clearfix
// ------------------------
.clearfix() {
zoom: 1;
&::before,
&::after {
display: table;
content: ' ';
}
&::after {
clear: both;
height: 0;
font-size: 0;
visibility: hidden;
}
}
Loading…
Cancel
Save