Commit 6bea225f by chenshu

fix:merge

parents 1a27722f b9910af1
...@@ -20,7 +20,8 @@ interface FetchParams { ...@@ -20,7 +20,8 @@ interface FetchParams {
} }
interface FetchOptions { interface FetchOptions {
requestType: string // 请求类型 form为表单类型 json为json类型,默认json类型 requestType: string, // 请求类型 form为表单类型 json为json类型,默认json类型
reject: boolean,
} }
interface HeadersType{ interface HeadersType{
storeId?:any, storeId?:any,
...@@ -33,7 +34,7 @@ class Axios { ...@@ -33,7 +34,7 @@ class Axios {
method: string, method: string,
url: string, url: string,
params: any, params: any,
options: FetchOptions = { requestType: 'json' } options: FetchOptions = { requestType: 'json', reject: false }
): Promise<any> { ): Promise<any> {
const _url = `${url}?storeId=${User.getStoreId()}&token=${User.getToken()}&storeUserId=${User.getStoreUserId()}&userId=${User.getUserId()}`; const _url = `${url}?storeId=${User.getStoreId()}&token=${User.getToken()}&storeUserId=${User.getStoreUserId()}&userId=${User.getUserId()}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
...@@ -86,8 +87,9 @@ class Axios { ...@@ -86,8 +87,9 @@ class Axios {
const { message: ResMessage, success, resultMsg, resultCode } = response.data; const { message: ResMessage, success, resultMsg, resultCode } = response.data;
if (success || resultCode === 0) { if (success || resultCode === 0) {
return response; return response;
} } else if (!options.reject) {
message.error(ResMessage || resultMsg); message.error(ResMessage || resultMsg);
}
return Promise.reject(response.data); return Promise.reject(response.data);
}, (error): AxiosPromise => { }, (error): AxiosPromise => {
const requestStatus = error.request.status const requestStatus = error.request.status
......
...@@ -12,6 +12,7 @@ import { Input, Button, Tree } from "antd"; ...@@ -12,6 +12,7 @@ import { Input, Button, Tree } from "antd";
import "./Classification.less"; import "./Classification.less";
import User from "@/common/js/user"; import User from "@/common/js/user";
import KnowledgeAPI from "@/data-source/knowledge/request-api"; import KnowledgeAPI from "@/data-source/knowledge/request-api";
import Bus from "@/core/bus";
const { Search } = Input; const { Search } = Input;
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
...@@ -31,6 +32,11 @@ class Classification extends Component { ...@@ -31,6 +32,11 @@ class Classification extends Component {
componentDidMount() { componentDidMount() {
this.queryCategoryTree(); this.queryCategoryTree();
Bus.bind('knowledgeCategoryTree', this.queryCategoryTree)
}
componentWillUnmount() {
Bus.unbind('knowledgeCategoryTree', this.queryCategoryTree)
} }
shouldComponentUpdate = (nextProps, nextState) => { shouldComponentUpdate = (nextProps, nextState) => {
......
...@@ -127,8 +127,7 @@ class KnowledgeBaseList extends React.Component { ...@@ -127,8 +127,7 @@ class KnowledgeBaseList extends React.Component {
// 预览文件 // 预览文件
handleScanFile = (folder) => { handleScanFile = (folder) => {
console.log(folder) const { folderFormat, folderSize, ossUrl } = folder;
const { folderFormat, folderSize, ossUrl } = folder
switch (folderFormat) { switch (folderFormat) {
case "PDF": case "PDF":
window.open(ossUrl, "_blank") window.open(ossUrl, "_blank")
...@@ -403,7 +402,6 @@ class KnowledgeBaseList extends React.Component { ...@@ -403,7 +402,6 @@ class KnowledgeBaseList extends React.Component {
width: 160, width: 160,
fixed: "right", fixed: "right",
render: (val, record, index) => { render: (val, record, index) => {
console.log(this.props.categoryId)
return this.props.categoryId === "0" ? ( return this.props.categoryId === "0" ? (
<div className='operate'> <div className='operate'>
<div className='operate__item' onClick={() => this.handleDelete(record)}> <div className='operate__item' onClick={() => this.handleDelete(record)}>
...@@ -451,9 +449,8 @@ class KnowledgeBaseList extends React.Component { ...@@ -451,9 +449,8 @@ class KnowledgeBaseList extends React.Component {
// 前往上课数据页面 // 前往上课数据页面
handleLinkToClassData = (item) => { handleLinkToClassData = (item) => {
const { match } = this.props const { match } = this.props;
console.log(item) localStorage.setItem("WatchData_CourseName", item.name);
localStorage.setItem("WatchData_CourseName", item.name)
window.RCHistory.push({ window.RCHistory.push({
// pathname: `${match.url}/course-data?type=${item.courseType}&id=${item.liveCourseId}`, // pathname: `${match.url}/course-data?type=${item.courseType}&id=${item.liveCourseId}`,
pathname: `${match.url}/course-data?type=${item.type}&id=${item.id}` pathname: `${match.url}/course-data?type=${item.type}&id=${item.id}`
...@@ -484,13 +481,19 @@ class KnowledgeBaseList extends React.Component { ...@@ -484,13 +481,19 @@ class KnowledgeBaseList extends React.Component {
} }
render() { render() {
const { dataSource = [], totalCount, query, match } = this.props const { dataSource = [], totalCount, query, match, selectedRowKeys, onSelectChange } = this.props;
const { current, size } = query const { current, size } = query;
const rowSelection = {
selectedRowKeys,
preserveSelectedRowKeys: true,
onChange: onSelectChange,
}
return ( return (
<div className='knowledge-base-list'> <div className='knowledge-base-list'>
<Table <Table
rowKey={(record) => record.id} rowKey={(record) => record.id}
size='middle' rowSelection={rowSelection}
size="middle"
dataSource={dataSource} dataSource={dataSource}
columns={this.parseColumns()} columns={this.parseColumns()}
pagination={false} pagination={false}
......
...@@ -9,19 +9,27 @@ ...@@ -9,19 +9,27 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { Button, Menu, Dropdown,message } from "antd"; import { Button, Menu, Dropdown,message, Modal } from "antd";
import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal"; import SelectPrepareFileModal from "@/modules/prepare-lesson/modal/SelectPrepareFileModal";
import { DownOutlined } from "@ant-design/icons"; import { DownOutlined } from "@ant-design/icons";
import AddCourse from "../modal/AddCourse"; import AddCourse from "../modal/AddCourse";
import User from "@/common/js/user"; import User from "@/common/js/user";
import Service from "@/common/js/service";
import KnowledgeAPI from "@/data-source/knowledge/request-api"; import KnowledgeAPI from "@/data-source/knowledge/request-api";
import MoveModal from '../../teach-tool/modal/MoveModal';
import Bus from "@/core/bus";
import './KnowledgeBaseOpt.less';
export default function KnowledgeBaseOpt({ export default function KnowledgeBaseOpt({
categoryId, categoryId,
selectedRowKeys,
updateCategoryTree, updateCategoryTree,
onChange, onChange,
onChangeKeys,
}) { }) {
const [modal, setModal] = useState(null); const [modal, setModal] = useState(null);
const [openMoveModal, setOpenMoveModal] = useState(false);
const [data, setData] = useState([]);
const menu = ( const menu = (
<Menu> <Menu>
...@@ -34,6 +42,40 @@ export default function KnowledgeBaseOpt({ ...@@ -34,6 +42,40 @@ export default function KnowledgeBaseOpt({
</Menu> </Menu>
); );
useEffect(() => {
queryCategoryTree();
}, []);
useEffect(() => {
clearSelect();
}, [categoryId])
// 查询分类树
function queryCategoryTree() {
let query = {
storeId: User.getStoreId(),
withCount: true,
};
KnowledgeAPI.getCategoryTree(query).then((res) => {
const { categoryList = [] } = res.result;
let list = renderTreeNodes(categoryList);
setData(list);
});
}
function renderTreeNodes(data) {
let newTreeData = data.map((item) => {
item.title = item.categoryName;
item.value = item.id;
item.key = item.id;
if (item.sonCategoryList) {
item.children = renderTreeNodes(item.sonCategoryList);
}
return item;
});
return newTreeData;
};
function handAddCourse() { function handAddCourse() {
let modal = ( let modal = (
<AddCourse <AddCourse
...@@ -86,16 +128,127 @@ export default function KnowledgeBaseOpt({ ...@@ -86,16 +128,127 @@ export default function KnowledgeBaseOpt({
setModal(modal); setModal(modal);
} }
function batchMove() {
if (_.isEmpty(selectedRowKeys)) {
message.warning('请先选择要移动的知识');
return null;
}
setOpenMoveModal(true);
}
function batchMoveRemote(categoryId) {
const data = {
categoryId,
ids: selectedRowKeys,
storeId: User.getStoreId(),
};
Service.Hades('public/hades/batchMoveKnowledgeCategory', data, { reject: true }).then((res) => {
if (res.success) {
message.success('移动成功');
onChange();
Bus.trigger('knowledgeCategoryTree');
clearSelect();
} else {
message.error('移动失败');
}
}).catch(() => {
message.error('移动失败');
})
}
function batchDelete() {
if (_.isEmpty(selectedRowKeys)) {
message.warning('请先选择要删除的知识');
return null;
}
Modal.confirm({
title: "确定要删除知识吗?",
content: "删除后,不可恢复。",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "删除",
cancelText: "取消",
onOk: () => {
const data = {
ids: selectedRowKeys,
storeId: User.getStoreId(),
};
Service.Hades('public/hades/batchDelKnowledge', data, { reject: true }).then((res) => {
if (res.success) {
message.success('删除成功');
onChange();
Bus.trigger('knowledgeCategoryTree');
clearSelect();
} else {
message.error('删除失败');
}
}).catch(() => {
message.error('删除失败');
})
},
})
}
function onSelectPaper(keys) {
if (keys.length > 50) {
message.warning('最多只能选择50个知识');
return null;
}
onChangeKeys(keys);
};
function clearSelect() {
onChangeKeys([]);
}
return ( return (
<div className="video-course-opt"> <div className="knowledge-course-opt">
<Dropdown overlay={menu}> {_.isEmpty(selectedRowKeys) ?
<Button type="primary" className="mr12"> (categoryId !== '0' && <Dropdown overlay={menu}>
<Button type="primary" className="mr8">
添加知识 添加知识
<DownOutlined /> <DownOutlined />
</Button> </Button>
</Dropdown> </Dropdown>)
: <div className="select-container">
<span className="con">
<div>
<span className="icon iconfont tip">&#xe6f2;</span>
<span className="text">已选择{selectedRowKeys.length}</span>
</div>
<div>
<span className="clear" onClick={clearSelect}>清空</span>
</div>
</span>
</div>
}
<Button
className="mr8"
onClick={() => {
batchMove();
}}
>批量移动</Button>
<Button
onClick={() => {
batchDelete();
}}
>批量删除</Button>
{modal} {modal}
{openMoveModal &&
<MoveModal
visible={openMoveModal}
title="知识"
data={data}
categoryId={categoryId}
length={selectedRowKeys.length}
onCancel={() => setOpenMoveModal(false)}
onOk={(categoryId) => {
batchMoveRemote(categoryId);
setOpenMoveModal(false);
}}
/>
}
</div> </div>
); );
} }
.knowledge-course-opt {
display: flex;
.select-container{
margin-right: 24px;
.con{
background: #FFF4DD;
border-radius: 4px;
padding: 3px 16px;
display: inline-flex;
align-items: center;
justify-content: space-between;
.tip{
font-size:14px;
color:#FF9D14;
margin-right:8px;
}
.text{
font-size:14px;
color:#666;
margin-right:30px;
}
.clear{
color:#5289FA;
font-size:14px;
}
}
}
}
\ No newline at end of file
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
* @LastEditTime: 2021-05-30 20:36:42 * @LastEditTime: 2021-05-30 20:36:42
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
import React from "react" import React from "react";
import { message } from 'antd'
import KnowledgeBaseFilter from "./components/KnowledgeBaseFilter" import KnowledgeBaseFilter from "./components/KnowledgeBaseFilter";
import KnowledgeBaseOpt from "./components/KnowledgeBaseOpt" import KnowledgeBaseOpt from "./components/KnowledgeBaseOpt";
import KnowledgeBaseList from "./components/KnowledgeBaseList" import KnowledgeBaseList from "./components/KnowledgeBaseList";
import Classification from "./components/Classification" import Classification from "./components/Classification";
import KnowledgeAPI from "@/data-source/knowledge/request-api" import KnowledgeAPI from "@/data-source/knowledge/request-api"
import User from "@/common/js/user" import User from "@/common/js/user"
...@@ -28,9 +28,10 @@ export default class KnowledgeBase extends React.Component { ...@@ -28,9 +28,10 @@ export default class KnowledgeBase extends React.Component {
}, },
dataSource: [], // 知识库列表 dataSource: [], // 知识库列表
totalCount: 0, // 知识库数据总条数 totalCount: 0, // 知识库数据总条数
categoryId: "0", categoryId: '0',
updateCategoryFlag: false updateCategoryFlag: false,
} selectedRowKeys: [],
};
} }
componentWillMount() { componentWillMount() {
...@@ -73,8 +74,23 @@ export default class KnowledgeBase extends React.Component { ...@@ -73,8 +74,23 @@ export default class KnowledgeBase extends React.Component {
}) })
} }
onSelectChange = (selectedRowKeys) => {
if (selectedRowKeys.length > 50) {
message.warning('最多只能选择50个题目');
return null;
}
this.setState({ selectedRowKeys });
};
render() { render() {
const { dataSource, totalCount, query, categoryId, updateCategoryFlag } = this.state const {
dataSource,
totalCount,
query,
categoryId,
updateCategoryFlag,
selectedRowKeys,
} = this.state;
return ( return (
<div className='page'> <div className='page'>
<div className='content-header'>知识库</div> <div className='content-header'>知识库</div>
...@@ -92,13 +108,19 @@ export default class KnowledgeBase extends React.Component { ...@@ -92,13 +108,19 @@ export default class KnowledgeBase extends React.Component {
<KnowledgeBaseFilter onChange={this.handleFetchScheduleList} /> <KnowledgeBaseFilter onChange={this.handleFetchScheduleList} />
{/* 操作模块 */} {/* 操作模块 */}
{categoryId !== "0" && ( <KnowledgeBaseOpt
<KnowledgeBaseOpt onChange={this.handleFetchScheduleList} updateCategoryTree={this.updateCategoryTree} categoryId={categoryId} /> onChange={this.handleFetchScheduleList}
)} updateCategoryTree={this.updateCategoryTree}
categoryId={categoryId}
selectedRowKeys={selectedRowKeys}
onChangeKeys={(keys) => this.setState({ selectedRowKeys: keys })}
/>
{/* 知识库列表模块 */} {/* 知识库列表模块 */}
<KnowledgeBaseList <KnowledgeBaseList
query={query} query={query}
selectedRowKeys={selectedRowKeys}
onSelectChange={this.onSelectChange}
categoryId={categoryId} categoryId={categoryId}
dataSource={dataSource} dataSource={dataSource}
totalCount={totalCount} totalCount={totalCount}
......
import React, { useState, useRef, useEffect, useContext } from 'react' import React, { useState, useRef, useEffect, useContext } from 'react'
import Breadcrumbs from "@/components/Breadcrumbs"; import Breadcrumbs from "@/components/Breadcrumbs";
import { Form, Alert, Input, Button, InputNumber, DatePicker, Switch, Radio, message, Modal } from 'antd'; import { Form, Alert, Input, Button, InputNumber, DatePicker, Switch, Radio, message, Modal, Tooltip } from 'antd';
import { Route, withRouter } from 'react-router-dom'; import { Route, withRouter } from 'react-router-dom';
import User from "@/common/js/user"; import User from "@/common/js/user";
import moment from 'moment' import moment from 'moment'
...@@ -36,20 +36,27 @@ function AddExam(props: any) { ...@@ -36,20 +36,27 @@ function AddExam(props: any) {
const [getData, setGetData] = useState(false); const [getData, setGetData] = useState(false);
const [preview, setPreview] = useState(false); const [preview, setPreview] = useState(false);
const [examTotal, setExamTotal] = useState(0); const [examTotal, setExamTotal] = useState(0);
const timer = useRef({});
const request = useRef(false); const request = useRef(false);
const { match } = props; const { match } = props;
const [examDuration, setExamDuration] = useState(undefined); const [examDuration, setExamDuration] = useState(undefined);
useEffect(() => { useEffect(() => {
if (props.type === 'edit') { switch (props.type) {
queryExamDetail() case "copy": // 考试列表-复制考试进入
case "edit": // 考试列表-编辑考试进入
queryExamDetail();
break;
case "organizeExam": // 试卷列表-组织考试进入
case "newPaperToAddExam": // 组卷页面-新建保存试卷并组织考试
case "editPaperToAddExam": // 组卷页面-编辑保存试卷并组织考试
setGetData(true);
setPaperInfo(props.paperInfo);
break;
} }
}, []) }, [])
useEffect(() => { useEffect(() => {
console.log(paperInfo)
setPaperId(paperInfo.paperId) setPaperId(paperInfo.paperId)
setPassRate(paperInfo.passRate) setPassRate(paperInfo.passRate)
...@@ -75,9 +82,9 @@ function AddExam(props: any) { ...@@ -75,9 +82,9 @@ function AddExam(props: any) {
const { result } = res const { result } = res
setPaperInfo(result.examPaper) setPaperInfo(result.examPaper)
setPaperId(result.examPaper.paperId) setPaperId(result.examPaper.paperId)
setStartTime(result.examStartTime) setStartTime(props.type === 'edit' ? result.examStartTime : '')
setExamEndTime(result.examEndTime) setExamEndTime(props.type === 'edit' ? result.examEndTime : '')
setExamName(result.examName) setExamName(props.type === 'edit' ? result.examName : `${result.examName}(复制)`)
setPassRate(result.passRate * 100) setPassRate(result.passRate * 100)
setNeedPhone(result.needPhone) setNeedPhone(result.needPhone)
setExamDesc(result.examDesc) setExamDesc(result.examDesc)
...@@ -174,8 +181,19 @@ function AddExam(props: any) { ...@@ -174,8 +181,19 @@ function AddExam(props: any) {
Service.Hades(props.type === 'edit' ? 'public/hades/editExam' : "public/hades/createExam", param).then((res) => { Service.Hades(props.type === 'edit' ? 'public/hades/editExam' : "public/hades/createExam", param).then((res) => {
message.success(props.type === 'edit' ? '编辑成功' : '创建成功'); message.success(props.type === 'edit' ? '编辑成功' : '创建成功');
switch (props.type) {
case "organizeExam": // 试卷列表-组织考试进入
case "newPaperToAddExam": // 组卷保存组织考试
case "editPaperToAddExam":
window.RCHistory.push("/examination-manage-index")
break;
case "add":
case "edit": // 考试列表-新建或编辑
case "copy": // 考试列表-新建或编辑
props.freshList() props.freshList()
props.history.goBack(); props.history.goBack();
break;
}
}) })
} }
...@@ -227,9 +245,25 @@ function AddExam(props: any) { ...@@ -227,9 +245,25 @@ function AddExam(props: any) {
}) })
} }
let title = '';
switch (props.type) {
case 'add':
case "organizeExam":
case "newPaperToAddExam":
case "editPaperToAddExam":
title = '新建考试';
break;
case 'edit':
title = '编辑考试';
break;
case 'copy':
title = '复制考试';
break;
default:
break;
}
return <div className="page examPage"> return <div className="page examPage">
<Breadcrumbs navList={props.type === 'edit' ? "编辑考试" : "新建考试"} goBack={handleGoBack} /> <Breadcrumbs navList={title} goBack={handleGoBack} />
<div className="box"> <div className="box">
<div className="show-tips"> <div className="show-tips">
...@@ -296,11 +330,18 @@ function AddExam(props: any) { ...@@ -296,11 +330,18 @@ function AddExam(props: any) {
<Form.Item label="及格线" <Form.Item
label={<div>
<span>及格线</span>
<Tooltip title="默认为选中试卷所设置的及格线,可修改">
<span className="icon iconfont" style={{ color: '#BFBFBF', marginLeft: 4 }}>&#xe61d;</span>
</Tooltip>
</div>}
style={{ marginTop: 24 }} style={{ marginTop: 24 }}
validateStatus={(check && !passRate) ? 'error' : ''} validateStatus={(check && !passRate) ? 'error' : ''}
help={check && !passRate && '请输入及格线'} help={check && !passRate && '请输入及格线'}
required> required
>
<InputNumber value={passRate} min={0} max={100} onChange={(value: any) => { setPassRate(parseInt(value)) }} style={{ width: 100 }} /> <InputNumber value={passRate} min={0} max={100} onChange={(value: any) => { setPassRate(parseInt(value)) }} style={{ width: 100 }} />
<span style={{ marginLeft: 4 }}>% <span style={{ marginLeft: 4 }}>%
</span> </span>
...@@ -314,6 +355,7 @@ function AddExam(props: any) { ...@@ -314,6 +355,7 @@ function AddExam(props: any) {
required> required>
<RangePicker <RangePicker
style={{ width: 320 }} style={{ width: 320 }}
showTime={{ defaultValue: [moment().add(5, 'minutes'), moment().add(5, 'minutes')] }}
ranges={{ ranges={{
'近七天': [moment(), moment().add(6, 'day').endOf('day')], '近七天': [moment(), moment().add(6, 'day').endOf('day')],
'近1个月': [moment(), moment().add(1, 'month').endOf('day')], '近1个月': [moment(), moment().add(1, 'month').endOf('day')],
...@@ -325,7 +367,6 @@ function AddExam(props: any) { ...@@ -325,7 +367,6 @@ function AddExam(props: any) {
examEndTime ? moment(Number(examEndTime)) : null examEndTime ? moment(Number(examEndTime)) : null
]} ]}
disabledTime={disabledRangeTime} disabledTime={disabledRangeTime}
showTime
format="YYYY/MM/DD HH:mm" format="YYYY/MM/DD HH:mm"
onChange={(date: any) => { onChange={(date: any) => {
setStartTime(date && date[0]?.valueOf()); setStartTime(date && date[0]?.valueOf());
...@@ -350,7 +391,7 @@ function AddExam(props: any) { ...@@ -350,7 +391,7 @@ function AddExam(props: any) {
help={check && (desclen > 1000) && '最多只能输入1000个字'} help={check && (desclen > 1000) && '最多只能输入1000个字'}
> >
{ {
(getData || (props.type !== 'edit')) && <GraphicsEditor (getData || (props.type === 'add')) && <GraphicsEditor
maxLimit={1000} maxLimit={1000}
isIntro={true} isIntro={true}
detail={{ detail={{
......
...@@ -207,7 +207,6 @@ function ExamData(props: any) { ...@@ -207,7 +207,6 @@ function ExamData(props: any) {
return <div className="rr"> return <div className="rr">
<a <a
target="_blank"
download download
id="load-play-back-excel" id="load-play-back-excel"
style={{ position: "absolute", left: "-10000px" }} style={{ position: "absolute", left: "-10000px" }}
......
...@@ -10,6 +10,7 @@ import User from "@/common/js/user"; ...@@ -10,6 +10,7 @@ import User from "@/common/js/user";
import { XMContext } from "@/store/context"; import { XMContext } from "@/store/context";
import ExamShareModal from './ExamShareModal' import ExamShareModal from './ExamShareModal'
import DataAnalysic from './DataAnalysic' import DataAnalysic from './DataAnalysic'
import PreviewModal from './PreviewModal'
import './index.less' import './index.less'
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const { Search } = Input; const { Search } = Input;
...@@ -53,6 +54,8 @@ function ExaminationManager(props: any) { ...@@ -53,6 +54,8 @@ function ExaminationManager(props: any) {
const [order, setOrder] = useState(sortStatus.type); const [order, setOrder] = useState(sortStatus.type);
const [modal, setModal] = useState(null); const [modal, setModal] = useState(null);
const [questionCntSort, setQuestionCntSort] = useState(sortState) const [questionCntSort, setQuestionCntSort] = useState(sortState)
const [openPreviewModal, setOpenPreviewModal] = useState(false);
const [info, setInfo] = useState({ examDuration: 0 });
const queryRef = useRef({}); const queryRef = useRef({});
const orderEnum = { const orderEnum = {
...@@ -163,12 +166,10 @@ function ExaminationManager(props: any) { ...@@ -163,12 +166,10 @@ function ExaminationManager(props: any) {
> >
分享 分享
</div> </div>
<span className="operate__item split" > | </span>
{ <Dropdown overlay={getOpe(record)}>
((ctx.xmState?.userPermission?.AddExam() && (moment().valueOf() < record.examStartTime)) || (ctx.xmState?.userPermission?.DelExam() && (moment().valueOf() + 30 * 60 * 1000 < record.examStartTime))) && [<span className="operate__item split" > | </span>, <Dropdown overlay={getOpe(record)}>
<span className='more'>更多</span> <span className='more'>更多</span>
</Dropdown>] </Dropdown>
}
...@@ -178,6 +179,18 @@ function ExaminationManager(props: any) { ...@@ -178,6 +179,18 @@ function ExaminationManager(props: any) {
]; ];
function queryExamDetail(examId: string) {
Service.Hades("public/hades/queryExamDetail", {
examId,
tenantId: User.getStoreId(),
userId: User.getStoreUserId(),
source: 0
}).then((res) => {
setInfo(res.result);
setOpenPreviewModal(true);
});
}
function shareModal(record: any) { function shareModal(record: any) {
const modal = <ExamShareModal const modal = <ExamShareModal
data={record} data={record}
...@@ -190,8 +203,14 @@ function ExaminationManager(props: any) { ...@@ -190,8 +203,14 @@ function ExaminationManager(props: any) {
function getOpe(item: any) { function getOpe(item: any) {
return <Menu> return <Menu>
<Menu.Item
key="1"
onClick={() => {
queryExamDetail(item.examId);
}}
>预览</Menu.Item>
{ {
ctx.xmState?.userPermission?.AddExam() && (moment().valueOf() < item.examStartTime) && <Menu.Item key="0"> ctx.xmState?.userPermission?.AddExam() && (moment().valueOf() < item.examStartTime) && <Menu.Item key="2">
<span <span
onClick={() => { onClick={() => {
if (moment().valueOf() + 5 * 60 * 1000 > item.examStartTime) { if (moment().valueOf() + 5 * 60 * 1000 > item.examStartTime) {
...@@ -213,8 +232,11 @@ function ExaminationManager(props: any) { ...@@ -213,8 +232,11 @@ function ExaminationManager(props: any) {
</Menu.Item> </Menu.Item>
} }
{ctx.xmState?.userPermission?.AddExam() &&
<Menu.Item key="3" onClick={() => props.history.push(`${match.url}/copy/${item.examId}`)}>复制</Menu.Item>
}
{ {
ctx.xmState?.userPermission?.DelExam() && (moment().valueOf() + 30 * 60 * 1000 < item.examStartTime) && <Menu.Item key="1"> ctx.xmState?.userPermission?.DelExam() && ((moment().valueOf() + 30 * 60 * 1000 < item.examStartTime) || (moment().valueOf() > item.examEndTime)) && <Menu.Item key="4">
<span <span
onClick={() => { onClick={() => {
deleteExam(item) deleteExam(item)
...@@ -281,7 +303,6 @@ function ExaminationManager(props: any) { ...@@ -281,7 +303,6 @@ function ExaminationManager(props: any) {
function onChange(pagination: any, filters: any, sorter: any, extra: any) { function onChange(pagination: any, filters: any, sorter: any, extra: any) {
setfield(sorter.field); setfield(sorter.field);
setOrder(sorter.order) setOrder(sorter.order)
console.log(sorter.field, sorter.order, (orderEnum as any)[sorter.field])
let _query: any = { ...queryRef.current }; let _query: any = { ...queryRef.current };
_query.order = (orderEnum as any)[sorter.field][sorter.order] || 'EXAM_START_TIME_DESC' _query.order = (orderEnum as any)[sorter.field][sorter.order] || 'EXAM_START_TIME_DESC'
setQuery(_query) setQuery(_query)
...@@ -400,7 +421,6 @@ function ExaminationManager(props: any) { ...@@ -400,7 +421,6 @@ function ExaminationManager(props: any) {
total={total} total={total}
onShowSizeChange={onShowSizeChange} onShowSizeChange={onShowSizeChange}
toPage={(page: any) => { toPage={(page: any) => {
console.log(page)
let _query: any = { ...queryRef.current }; let _query: any = { ...queryRef.current };
_query.current = page + 1; _query.current = page + 1;
setQuery(_query) setQuery(_query)
...@@ -409,8 +429,14 @@ function ExaminationManager(props: any) { ...@@ -409,8 +429,14 @@ function ExaminationManager(props: any) {
} }
</div> </div>
</div> </div>
{openPreviewModal &&
<PreviewModal
info={{ ...info, examDuration: (info.examDuration || 0) / 60000 }}
onClose={() => { setOpenPreviewModal(false) }}
/>
}
<Route path={`${match.url}/add`} render={() => { <Route path={`${match.url}/add`} render={() => {
return <AddExam freshList={() => { return <AddExam type="add" freshList={() => {
let _query: any = { ...queryRef.current }; let _query: any = { ...queryRef.current };
if (_query.current != 1) { if (_query.current != 1) {
_query.current = 1; _query.current = 1;
...@@ -418,8 +444,6 @@ function ExaminationManager(props: any) { ...@@ -418,8 +444,6 @@ function ExaminationManager(props: any) {
} else { } else {
getList() getList()
} }
}} />; }} />;
}} /> }} />
<Route path={`${match.url}/edit/:id`} render={() => { <Route path={`${match.url}/edit/:id`} render={() => {
...@@ -427,6 +451,11 @@ function ExaminationManager(props: any) { ...@@ -427,6 +451,11 @@ function ExaminationManager(props: any) {
getList() getList()
}} />; }} />;
}} /> }} />
<Route path={`${match.url}/copy/:id`} render={() => {
return <AddExam type='copy' freshList={() => {
getList()
}} />;
}} />
<Route path={`${match.url}/analysic/:id`} render={() => { <Route path={`${match.url}/analysic/:id`} render={() => {
return <DataAnalysic />; return <DataAnalysic />;
......
...@@ -182,7 +182,6 @@ function DataAnalysic(props: any) { ...@@ -182,7 +182,6 @@ function DataAnalysic(props: any) {
return <div className="rr"> return <div className="rr">
<a <a
target="_blank"
download download
id="load-play-back-excel" id="load-play-back-excel"
style={{ position: "absolute", left: "-10000px" }} style={{ position: "absolute", left: "-10000px" }}
......
import React from 'react';
import { Modal, TreeSelect } from 'antd';
import './MoveModal.less';
class MoveModal extends React.Component {
constructor(props) {
super(props);
this.state = {
categoryId: undefined,
};
}
handleChangeCatalogList = (value, label) => {
this.setState({ categoryId: value, categoryName: label[0] });
};
filterData = (data, id) => {
let newTreeData = data.map((item) => {
item.disabled = id === item.id;
if (item.children) {
item.children = this.filterData(item.children, id);
}
return item;
});
return newTreeData;
}
render() {
const { visible, title, onCancel, onOk, data, length, categoryId: id } = this.props;
const { categoryId } = this.state;
const moveData = this.filterData(data, id);
return (
<Modal
title={`移动${title}`}
visible={visible}
onCancel={onCancel}
maskClosable={false}
className="common-move-modal"
onOk={() => onOk(categoryId)}
>
<div className="tip">
<span className="icon iconfont">&#xe6f2;</span>
<span className="text">已选择<span style={{ color: '#2966FF' }}>{length}</span>{title},移动后,原有分类将移除此{title}</span>
</div>
<div className="move-item">
<span className="label">选择分类:</span>
<TreeSelect
showSearch
treeNodeFilterProp="title"
style={{ width: 240 }}
dropdownStyle={{ maxHeight: 220 }}
treeData={moveData}
placeholder="请选择分类"
allowClear
value={categoryId}
onChange={(value, label) => {
this.handleChangeCatalogList(value, label);
}}
/>
</div>
</Modal>
)
}
}
export default MoveModal;
\ No newline at end of file
.common-move-modal {
.tip {
display: flex;
align-items: center;
margin-bottom: 16px;
.iconfont {
font-size: 14px;
color: #BFBFBF;
margin-right: 8px;
}
.text {
color: #999;
font-size: 14px;
}
}
.move-item {
.label {
color: #333;
}
}
}
\ No newline at end of file
/* /*
* @Author: yuananting * @Author: yuananting
* @Date: 2021-03-27 16:15:13 * @Date: 2021-03-27 16:15:13
* @LastEditors: wufan * @LastEditors: yuananting
* @LastEditTime: 2021-05-30 16:56:15 * @LastEditTime: 2021-05-30 21:22:25
* @Description: 助学工具-新建/复制/编辑试卷 * @Description: 助学工具-新建/复制/编辑试卷
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -29,6 +29,8 @@ import PaperPreviewModal from "./modal/PreviewPaperModal"; ...@@ -29,6 +29,8 @@ import PaperPreviewModal from "./modal/PreviewPaperModal";
import User from "@/common/js/user"; import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService"; import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import Bus from "@/core/bus"; import Bus from "@/core/bus";
import { Route, withRouter } from "react-router-dom";
import AddExam from "@/modules/teach-tool/examination-manager/AddExam";
const questionTypeEnum = { const questionTypeEnum = {
SINGLE_CHOICE: "单选题", SINGLE_CHOICE: "单选题",
...@@ -127,11 +129,10 @@ class OperatePaper extends Component { ...@@ -127,11 +129,10 @@ class OperatePaper extends Component {
const { paperName, passRate } = result; const { paperName, passRate } = result;
this.setState( this.setState(
{ {
selectQuestionList: result.questionList.sort( selectQuestionList: result.questionList,
(a, b) => b.updateTime - a.updateTime
),
formData: { formData: {
...result, ...result,
paperId: getParameterByName("paperId"),
paperName: paperName:
currentOperate === "copy" ? paperName + "(复制)" : paperName, currentOperate === "copy" ? paperName + "(复制)" : paperName,
}, },
...@@ -222,11 +223,6 @@ class OperatePaper extends Component { ...@@ -222,11 +223,6 @@ class OperatePaper extends Component {
case "descend": case "descend":
currentQuestionList = sortedTableData.reverse(); currentQuestionList = sortedTableData.reverse();
break; break;
case "default":
currentQuestionList = _selectQuestionList.sort(
(a, b) => b.updateTime - a.updateTime
);
break;
default: default:
currentQuestionList = _selectQuestionList; currentQuestionList = _selectQuestionList;
break; break;
...@@ -261,7 +257,7 @@ class OperatePaper extends Component { ...@@ -261,7 +257,7 @@ class OperatePaper extends Component {
getSelectedQuestion={this.state.selectQuestionList} getSelectedQuestion={this.state.selectQuestionList}
setSelectedQuestion={(list) => { setSelectedQuestion={(list) => {
this.setState({ selectQuestionModal: null }, () => { this.setState({ selectQuestionModal: null }, () => {
this.setFormData(list.sort((a, b) => b.updateTime - a.updateTime)); this.setFormData(list);
}); });
}} }}
close={() => { close={() => {
...@@ -332,10 +328,11 @@ class OperatePaper extends Component { ...@@ -332,10 +328,11 @@ class OperatePaper extends Component {
}; };
// 保存试卷 // 保存试卷
savePaper = async () => { savePaper = (saveType) => {
this.setState({ check: true }); this.setState({ check: true });
const { selectQuestionList, formData, currentOperate } = this.state; const { selectQuestionList, formData, currentOperate } = this.state;
const categoryId = getParameterByName("categoryId"); const categoryId = getParameterByName("categoryId");
const { match } = this.props;
let questionList = []; let questionList = [];
if ( if (
!formData.passRate || !formData.passRate ||
...@@ -370,6 +367,13 @@ class OperatePaper extends Component { ...@@ -370,6 +367,13 @@ class OperatePaper extends Component {
AidToolService.createPaper(this.state.formData) AidToolService.createPaper(this.state.formData)
.then((res) => { .then((res) => {
if (res.success) { if (res.success) {
if (saveType === "saveToAddExam") {
this.setState({formData:{ ...formData, paperId: res.result}},() => {
window.RCHistory.push({
pathname: `${match.url}/exam-operate-page`,
});
})
} else {
message.success( message.success(
currentOperate === "new" ? "新建成功" : "复制成功" currentOperate === "new" ? "新建成功" : "复制成功"
); );
...@@ -383,6 +387,7 @@ class OperatePaper extends Component { ...@@ -383,6 +387,7 @@ class OperatePaper extends Component {
); );
Bus.trigger("queryCategoryTree", "remain"); Bus.trigger("queryCategoryTree", "remain");
} }
}
}) })
.catch((e) => { .catch((e) => {
window.RCHistory.push({ window.RCHistory.push({
...@@ -402,6 +407,11 @@ class OperatePaper extends Component { ...@@ -402,6 +407,11 @@ class OperatePaper extends Component {
}) })
.then((res) => { .then((res) => {
if (res.success) { if (res.success) {
if (saveType === "saveToAddExam") {
window.RCHistory.push({
pathname: `${match.url}/exam-operate-page`,
});
} else {
message.success("编辑成功"); message.success("编辑成功");
window.RCHistory.push({ window.RCHistory.push({
pathname: `/paper-manage-index?categoryId=${categoryId}`, pathname: `/paper-manage-index?categoryId=${categoryId}`,
...@@ -412,6 +422,7 @@ class OperatePaper extends Component { ...@@ -412,6 +422,7 @@ class OperatePaper extends Component {
selectQuestionList.length selectQuestionList.length
); );
} }
}
}) })
.catch((e) => { .catch((e) => {
window.RCHistory.push({ window.RCHistory.push({
...@@ -469,7 +480,7 @@ class OperatePaper extends Component { ...@@ -469,7 +480,7 @@ class OperatePaper extends Component {
sortByQuestionType = (pagination, filters, sorter) => { sortByQuestionType = (pagination, filters, sorter) => {
const { columnKey, order } = sorter; const { columnKey, order } = sorter;
if (columnKey === "questionType") { if (columnKey === "questionType") {
this.setFormData(this.state.selectQuestionList, order || "default"); this.setFormData(this.state.selectQuestionList, order);
} }
}; };
...@@ -681,6 +692,7 @@ class OperatePaper extends Component { ...@@ -681,6 +692,7 @@ class OperatePaper extends Component {
formData, formData,
loading, loading,
check, check,
currentOperate,
} = this.state; } = this.state;
const { const {
singleChoiceCnt, singleChoiceCnt,
...@@ -699,8 +711,9 @@ class OperatePaper extends Component { ...@@ -699,8 +711,9 @@ class OperatePaper extends Component {
questionCnt, questionCnt,
totalScore, totalScore,
} = formData; } = formData;
const { match } = this.props;
return ( return (
<div>
<div className="page operate-paper-page"> <div className="page operate-paper-page">
<Breadcrumbs navList={currentNav} goBack={() => this.handleGoBack()} /> <Breadcrumbs navList={currentNav} goBack={() => this.handleGoBack()} />
<Spin spinning={loading}> <Spin spinning={loading}>
...@@ -733,6 +746,8 @@ class OperatePaper extends Component { ...@@ -733,6 +746,8 @@ class OperatePaper extends Component {
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="passRate" name="passRate"
label="及格线:" label="及格线:"
...@@ -776,8 +791,12 @@ class OperatePaper extends Component { ...@@ -776,8 +791,12 @@ class OperatePaper extends Component {
自选题目 自选题目
</Button> </Button>
{questionCnt > 0 && ( {questionCnt > 0 && (
<div className="paper-info-tip" style={{ margin: "0 auto 12px" }}> <div
总计<span>{totalScore}</span>分,共<span>{questionCnt}</span> className="paper-info-tip"
style={{ margin: "0 auto 12px" }}
>
总计<span>{totalScore}</span>分,共
<span>{questionCnt}</span>
题。{" "} 题。{" "}
{singleChoiceCnt > 0 && {singleChoiceCnt > 0 &&
`单选题${singleChoiceCnt}题,共${singleChoiceScore}分;`} `单选题${singleChoiceCnt}题,共${singleChoiceScore}分;`}
...@@ -799,15 +818,17 @@ class OperatePaper extends Component { ...@@ -799,15 +818,17 @@ class OperatePaper extends Component {
dataSource={selectQuestionList} dataSource={selectQuestionList}
pagination={false} pagination={false}
onChange={this.sortByQuestionType} onChange={this.sortByQuestionType}
selections={false}
/> />
</ConfigProvider> </ConfigProvider>
</Form> </Form>
</div> </div>
<div className="footer shrink-footer"> <div className="footer">
<Button onClick={this.handleGoBack}>取消</Button> <Button onClick={this.handleGoBack}>取消</Button>
<Button onClick={this.previewPaper}>预览</Button> <Button onClick={this.previewPaper}>预览</Button>
<Button type="primary" onClick={this.savePaper}> <Button onClick={() => this.savePaper("saveToAddExam")}>
保存并组织考试
</Button>
<Button type="primary" onClick={() => this.savePaper()}>
保存 保存
</Button> </Button>
</div> </div>
...@@ -815,8 +836,26 @@ class OperatePaper extends Component { ...@@ -815,8 +836,26 @@ class OperatePaper extends Component {
{selectQuestionModal} {selectQuestionModal}
{paperPreviewModal} {paperPreviewModal}
</div> </div>
<Route
path={`${match.url}/exam-operate-page`}
render={() => {
return (
<AddExam
paperInfo={formData}
type={
currentOperate === "edit"
? "editPaperToAddExam"
: "newPaperToAddExam"
}
/>
);
}}
/>
</div>
); );
} }
} }
export default OperatePaper; export default withRouter(OperatePaper);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 11:23:47 * @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-05-20 11:37:40 * @LastEditTime: 2021-05-31 13:42:54
* @Description: 助学工具-题库-试卷列表数据 * @Description: 助学工具-题库-试卷列表数据
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -24,10 +24,13 @@ import { PageControl } from "@/components"; ...@@ -24,10 +24,13 @@ import { PageControl } from "@/components";
import "./PaperList.less"; import "./PaperList.less";
import { Route, withRouter } from "react-router-dom"; import { Route, withRouter } from "react-router-dom";
import OperatePaper from "@/modules/teach-tool/paper-manage/OperatePaper"; import OperatePaper from "@/modules/teach-tool/paper-manage/OperatePaper";
import AddExam from "@/modules/teach-tool/examination-manager/AddExam";
import User from "@/common/js/user"; import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService"; import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import Service from "@/common/js/service";
import _ from "underscore"; import _ from "underscore";
import PaperPreviewModal from "../modal/PreviewPaperModal"; import PaperPreviewModal from "../modal/PreviewPaperModal";
import MoveModal from '../../modal/MoveModal';
import Bus from "@/core/bus"; import Bus from "@/core/bus";
const { Search } = Input; const { Search } = Input;
...@@ -49,14 +52,18 @@ class PaperList extends Component { ...@@ -49,14 +52,18 @@ class PaperList extends Component {
dataSource: [], dataSource: [],
paperPreviewModal: null, // 试卷预览模态框 paperPreviewModal: null, // 试卷预览模态框
loading: false, loading: false,
selectedPaperKeys: [],
paperInfo: {}, // 选择的某份试卷用于组织考试
}; };
} }
componentDidMount() { componentDidMount() {
this.queryPaperPageList(); this.queryPaperPageList();
this.queryCategoryTree();
Bus.bind("queryPaperPageList", (selectedCategoryId, count) => { Bus.bind("queryPaperPageList", (selectedCategoryId, count) => {
selectedCategoryId = selectedCategoryId =
selectedCategoryId === "null" ? null : selectedCategoryId; selectedCategoryId === "null" ? null : selectedCategoryId;
this.clearSelect();
this.setState({ loading: true }); this.setState({ loading: true });
if (count >= 100) { if (count >= 100) {
setTimeout(() => { setTimeout(() => {
...@@ -72,6 +79,35 @@ class PaperList extends Component { ...@@ -72,6 +79,35 @@ class PaperList extends Component {
Bus.unbind("queryPaperPageList", this.queryPaperPageList); Bus.unbind("queryPaperPageList", this.queryPaperPageList);
} }
// 查询分类树
queryCategoryTree = () => {
let query = {
bizType: 'PAPER',
count: true,
source: 0,
userId: User.getStoreUserId(),
tenantId: User.getStoreId(),
};
AidToolService.queryCategoryTree(query).then((res) => {
const { categoryList = [] } = res.result;
let list = this.renderTreeNodes(categoryList);
this.setState({ paperData: list });
});
}
renderTreeNodes = (data) => {
let newTreeData = data.map((item) => {
item.title = item.categoryName;
item.value = item.id;
item.key = item.id;
if (item.sonCategoryList) {
item.children = this.renderTreeNodes(item.sonCategoryList);
}
return item;
});
return newTreeData;
};
// 初始化列表查询 // 初始化列表查询
InitSearch = (categoryId) => { InitSearch = (categoryId) => {
const _query = { const _query = {
...@@ -88,7 +124,6 @@ class PaperList extends Component { ...@@ -88,7 +124,6 @@ class PaperList extends Component {
// 查询试卷列表 // 查询试卷列表
queryPaperPageList = async () => { queryPaperPageList = async () => {
const res = await AidToolService.queryPaperPageList(this.state.query); const res = await AidToolService.queryPaperPageList(this.state.query);
Bus.trigger("queryCategoryTree", "remain");
const { records = [], total = 0 } = res.result; const { records = [], total = 0 } = res.result;
this.setState({ dataSource: records, total, loading: false }); this.setState({ dataSource: records, total, loading: false });
}; };
...@@ -140,6 +175,20 @@ class PaperList extends Component { ...@@ -140,6 +175,20 @@ class PaperList extends Component {
} }
}; };
organizeExam = (record) => {
const { match } = this.props;
this.setState(
{
paperInfo: record,
},
() => {
window.RCHistory.push({
pathname: `${match.url}/exam-operate-page`,
});
}
);
};
// 删除试卷 // 删除试卷
deletePaper = (record) => { deletePaper = (record) => {
let params = { let params = {
...@@ -161,6 +210,7 @@ class PaperList extends Component { ...@@ -161,6 +210,7 @@ class PaperList extends Component {
} }
this.setState({ query: _query }, () => { this.setState({ query: _query }, () => {
this.queryPaperPageList(); this.queryPaperPageList();
Bus.trigger("queryCategoryTree", "remain");
}); });
} }
}); });
...@@ -249,7 +299,7 @@ class PaperList extends Component { ...@@ -249,7 +299,7 @@ class PaperList extends Component {
}, },
}, },
{ {
title: "题目数量", title: "试卷数量",
key: "questionCnt", key: "questionCnt",
dataIndex: "questionCnt", dataIndex: "questionCnt",
width: this.props.type !== "modal-select" ? "12%" : "20%", width: this.props.type !== "modal-select" ? "12%" : "20%",
...@@ -346,6 +396,9 @@ class PaperList extends Component { ...@@ -346,6 +396,9 @@ class PaperList extends Component {
<Menu.Item key="edit"> <Menu.Item key="edit">
<span onClick={() => this.editPaper(item)}>编辑</span> <span onClick={() => this.editPaper(item)}>编辑</span>
</Menu.Item> </Menu.Item>
<Menu.Item key="organizeExam">
<span onClick={() => this.organizeExam(item)}>组织考试</span>
</Menu.Item>
<Menu.Item key="del"> <Menu.Item key="del">
<span onClick={() => this.confirmDeletePaper(item)}>删除</span> <span onClick={() => this.confirmDeletePaper(item)}>删除</span>
</Menu.Item> </Menu.Item>
...@@ -370,6 +423,87 @@ class PaperList extends Component { ...@@ -370,6 +423,87 @@ class PaperList extends Component {
this.props.onSelect(selectedRows[0] || {}); this.props.onSelect(selectedRows[0] || {});
}; };
batchMove = () => {
const { selectedPaperKeys } = this.state;
if (_.isEmpty(selectedPaperKeys)) {
message.warning('请先选择要移动的试卷');
return null;
}
this.setState({ openMoveModal: true });
}
batchMoveRemote = (categoryId) => {
const { selectedPaperKeys } = this.state;
const data = {
categoryId,
paperId: selectedPaperKeys,
source: 0,
tenantId: User.getStoreId(),
userId: User.getUserId(),
};
Service.Hades('public/hades/batchMovePaperCategory', data, { reject: true }).then((res) => {
if (res.success) {
message.success('移动成功');
this.queryPaperPageList();
Bus.trigger("queryCategoryTree", "remain");
this.clearSelect();
} else {
message.error('移动失败');
}
}).catch(() => {
message.error('移动失败');
})
}
batchDelete = () => {
const { selectedPaperKeys } = this.state;
if (_.isEmpty(selectedPaperKeys)) {
message.warning('请先选择要删除的试卷');
return null;
}
Modal.confirm({
title: "确定要删除试卷吗?",
content: "删除后,不可恢复。",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "删除",
cancelText: "取消",
onOk: () => {
const data = {
paperId: selectedPaperKeys,
source: 0,
tenantId: User.getStoreId(),
userId: User.getUserId(),
};
Service.Hades('public/hades/batchDeletePaper', data, { reject: true }).then((res) => {
if (res.success) {
message.success('删除成功');
this.queryPaperPageList();
Bus.trigger("queryCategoryTree", "remain");
this.clearSelect();
} else {
message.error('删除失败');
}
}).catch(() => {
message.error('删除失败');
})
},
})
}
onSelectPaper = (selectedPaperKeys) => {
if (selectedPaperKeys.length > 50) {
message.warning('最多只能选择50个试卷');
return null;
}
this.setState({ selectedPaperKeys });
};
clearSelect = () => {
this.setState({ selectedPaperKeys: [] });
}
render() { render() {
const { const {
dataSource = [], dataSource = [],
...@@ -378,8 +512,17 @@ class PaperList extends Component { ...@@ -378,8 +512,17 @@ class PaperList extends Component {
paperPreviewModal, paperPreviewModal,
selectedRowKeys, selectedRowKeys,
loading, loading,
selectedPaperKeys,
openMoveModal,
paperData,
paperInfo,
} = this.state; } = this.state;
const { current, size, categoryId, paperName } = query; const { current, size, categoryId, paperName } = query;
const paperRowSelection = {
selectedRowKeys: selectedPaperKeys,
preserveSelectedRowKeys: true,
onChange: this.onSelectPaper,
}
const rowSelection = { const rowSelection = {
type: "radio", type: "radio",
selectedRowKeys, selectedRowKeys,
...@@ -418,9 +561,12 @@ class PaperList extends Component { ...@@ -418,9 +561,12 @@ class PaperList extends Component {
</div> </div>
</Row> </Row>
</div> </div>
{this.props.type !== "modal-select" && isPermiss && categoryId && ( {this.props.type !== "modal-select" && isPermiss && (
<Button <div className="select-box">
{_.isEmpty(selectedPaperKeys) ?
(!!categoryId && <Button
type="primary" type="primary"
className="mr8"
onClick={() => { onClick={() => {
window.RCHistory.push({ window.RCHistory.push({
pathname: `${match.url}/paper-operate-page?type=new&categoryId=${categoryId}`, pathname: `${match.url}/paper-operate-page?type=new&categoryId=${categoryId}`,
...@@ -428,14 +574,39 @@ class PaperList extends Component { ...@@ -428,14 +574,39 @@ class PaperList extends Component {
}} }}
> >
新建试卷 新建试卷
</Button> </Button>)
: <div className="select-container">
<span className="con">
<div>
<span className="icon iconfont tip">&#xe6f2;</span>
<span className="text">已选择{selectedPaperKeys.length}</span>
</div>
<div>
<span className="clear" onClick={this.clearSelect}>清空</span>
</div>
</span>
</div>
}
<Button
className="mr8"
onClick={() => {
this.batchMove();
}}
>批量移动</Button>
<Button
onClick={() => {
this.batchDelete();
}}
>批量删除</Button>
</div>
)} )}
<div className="paper-list-content"> <div className="paper-list-content">
<ConfigProvider renderEmpty={this.customizeRenderEmpty}> <ConfigProvider renderEmpty={this.customizeRenderEmpty}>
{this.props.type !== "modal-select" ? ( {this.props.type !== "modal-select" ? (
<Table <Table
rowKey={(record) => record.id} rowKey={(record) => record.paperId}
rowSelection={paperRowSelection}
dataSource={dataSource} dataSource={dataSource}
columns={this.parseColumns()} columns={this.parseColumns()}
pagination={false} pagination={false}
...@@ -444,9 +615,9 @@ class PaperList extends Component { ...@@ -444,9 +615,9 @@ class PaperList extends Component {
/> />
) : ( ) : (
<Table <Table
rowKey={(record) => record.id} rowKey={(record) => record.paperId}
dataSource={dataSource} dataSource={dataSource}
size={this.props.type == "modal-select"?'small':'middle'} size={this.props.type == "modal-select" ? "small" : "middle"}
rowKey={(item) => { rowKey={(item) => {
return item.paperId; return item.paperId;
}} }}
...@@ -464,7 +635,7 @@ class PaperList extends Component { ...@@ -464,7 +635,7 @@ class PaperList extends Component {
current={current - 1} current={current - 1}
pageSize={size} pageSize={size}
total={total} total={total}
size={this.props.type == "modal-select"?'small':'middle'} size={this.props.type == "modal-select" ? "small" : "middle"}
toPage={(page) => { toPage={(page) => {
const _query = { ...query, current: page + 1 }; const _query = { ...query, current: page + 1 };
this.setState({ query: _query }, () => this.setState({ query: _query }, () =>
...@@ -477,11 +648,36 @@ class PaperList extends Component { ...@@ -477,11 +648,36 @@ class PaperList extends Component {
</div> </div>
)} )}
{paperPreviewModal} {paperPreviewModal}
{openMoveModal &&
<MoveModal
visible={openMoveModal}
title="试卷"
data={paperData}
categoryId={query.categoryId}
length={selectedRowKeys.length}
onCancel={() => this.setState({ openMoveModal: false })}
onOk={(categoryId) => {
this.batchMoveRemote(categoryId);
this.setState({ openMoveModal: false });
}}
/>
}
</div> </div>
<Route <Route
path={`${match.url}/paper-operate-page`} path={`${match.url}/paper-operate-page`}
component={OperatePaper} component={OperatePaper}
/> />
<Route
path={`${match.url}/exam-operate-page`}
render={() => {
return (
<AddExam
paperInfo={paperInfo}
type="organizeExam"
/>
);
}}
/>
</div> </div>
); );
} }
......
.paper-list { .paper-list {
.select-box {
display: flex;
align-items: center;
.select-container{
margin-right: 24px;
.con{
background: #FFF4DD;
border-radius: 4px;
padding: 3px 16px;
display: inline-flex;
align-items: center;
justify-content: space-between;
.tip{
font-size:14px;
color:#FF9D14;
margin-right:8px;
}
.text{
font-size:14px;
color:#666;
margin-right:30px;
}
.clear{
color:#5289FA;
font-size:14px;
}
}
}
}
.ant-radio-wrapper{ .ant-radio-wrapper{
left: -10px; left: -10px;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: yuananting * @Author: yuananting
* @Date: 2021-02-25 11:23:47 * @Date: 2021-02-25 11:23:47
* @LastEditors: yuananting * @LastEditors: yuananting
* @LastEditTime: 2021-05-20 11:43:21 * @LastEditTime: 2021-05-30 18:17:05
* @Description: 助学工具-新建试卷-选择题目列表 * @Description: 助学工具-新建试卷-选择题目列表
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有 * @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/ */
...@@ -16,6 +16,7 @@ import { ...@@ -16,6 +16,7 @@ import {
Select, Select,
Tooltip, Tooltip,
message, message,
DatePicker,
} from "antd"; } from "antd";
import { PageControl } from "@/components"; import { PageControl } from "@/components";
import "./SelectQuestionList.less"; import "./SelectQuestionList.less";
...@@ -23,8 +24,10 @@ import User from "@/common/js/user"; ...@@ -23,8 +24,10 @@ import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService"; import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import _ from "underscore"; import _ from "underscore";
import Bus from "@/core/bus"; import Bus from "@/core/bus";
import moment from 'moment';
const { Search } = Input; const { Search } = Input;
const { RangePicker } = DatePicker;
const questionTypeEnum = { const questionTypeEnum = {
SINGLE_CHOICE: "单选题", SINGLE_CHOICE: "单选题",
...@@ -68,12 +71,15 @@ class SelectQuestionList extends Component { ...@@ -68,12 +71,15 @@ class SelectQuestionList extends Component {
categoryId: null, // 当前题库分类Id categoryId: null, // 当前题库分类Id
questionName: null, // 题目名称 questionName: null, // 题目名称
questionType: null, // 题目类型 questionType: null, // 题目类型
updateDateStart: null,
updateDateEnd: null,
source: 0, source: 0,
tenantId: User.getStoreId(), tenantId: User.getStoreId(),
userId: User.getStoreUserId(), userId: User.getStoreUserId(),
}, },
dataSource: [], dataSource: [],
selectQuestionKeys: [], selectQuestionKeys: [],
expandFilter: false,
}; };
} }
...@@ -98,6 +104,8 @@ class SelectQuestionList extends Component { ...@@ -98,6 +104,8 @@ class SelectQuestionList extends Component {
order: "UPDATED_DESC", // 排序规则 order: "UPDATED_DESC", // 排序规则
questionName: null, // 题目名称 questionName: null, // 题目名称
questionType: null, // 题目类型 questionType: null, // 题目类型
updateDateStart: null,
updateDateEnd: null,
}; };
this.setState({ query: _query }, () => { this.setState({ query: _query }, () => {
this.queryQuestionPageListWithContent(); this.queryQuestionPageListWithContent();
...@@ -134,6 +142,8 @@ class SelectQuestionList extends Component { ...@@ -134,6 +142,8 @@ class SelectQuestionList extends Component {
order: "UPDATED_DESC", // 排序规则 order: "UPDATED_DESC", // 排序规则
questionName: null, // 题目名称 questionName: null, // 题目名称
questionType: null, // 题目类型 questionType: null, // 题目类型
updateDateStart: null,
updateDateEnd: null,
}; };
this.setState({ query: _query }, () => { this.setState({ query: _query }, () => {
this.queryQuestionPageListWithContent(); this.queryQuestionPageListWithContent();
...@@ -215,11 +225,23 @@ class SelectQuestionList extends Component { ...@@ -215,11 +225,23 @@ class SelectQuestionList extends Component {
// 改变搜索条件 // 改变搜索条件
handleChangeQuery = (searchType, value) => { handleChangeQuery = (searchType, value) => {
const _query = this.state.query;
switch (searchType) {
case "questionName":
_query.questionName = value;
break;
case "updatedTime":
_query.updateDateStart = value && value[0]?.startOf('day').valueOf();
_query.updateDateEnd = value && value[1]?.endOf('day').valueOf();
break;
case "questionType":
_query.questionType = value;
break
}
this.setState( this.setState(
{ {
query: { query: {
...this.state.query, ..._query,
[searchType]: value || null,
current: 1, current: 1,
}, },
}, },
...@@ -281,6 +303,7 @@ class SelectQuestionList extends Component { ...@@ -281,6 +303,7 @@ class SelectQuestionList extends Component {
total, total,
query, query,
selectQuestionKeys = [], selectQuestionKeys = [],
expandFilter,
} = this.state; } = this.state;
const { current, size, questionName, questionType } = query; const { current, size, questionName, questionType } = query;
const rowSelection = { const rowSelection = {
...@@ -375,8 +398,24 @@ class SelectQuestionList extends Component { ...@@ -375,8 +398,24 @@ class SelectQuestionList extends Component {
&#xe61b;{" "} &#xe61b;{" "}
</span> </span>
</Tooltip> </Tooltip>
<span style={{ cursor: 'pointer' }} className="fold-btn" onClick={() => {
this.setState({expandFilter:!expandFilter})
}}>{expandFilter ? <span><span>收起</span><span className="iconfont icon fold-icon" >&#xe82d; </span> </span> : <span>展开<span className="iconfont icon fold-icon" >&#xe835; </span></span>}</span>
</div> </div>
</Row> </Row>
{expandFilter && <Row>
<div className="search-condition__item">
<span className="search-label">更新时间:</span>
<RangePicker
value={[
query.updateDateStart ? moment(Number(query.updateDateStart)) : null,
query.updateDateEnd ? moment(Number(query.updateDateEnd)) : null
]}
onChange={(value) => {
this.handleChangeQuery("updatedTime", value)
}} />
</div>
</Row>}
</div> </div>
<div className="select-tip-box"> <div className="select-tip-box">
<div> <div>
......
...@@ -19,18 +19,26 @@ import { ...@@ -19,18 +19,26 @@ import {
Button, Button,
Modal, Modal,
message, message,
Menu,
Dropdown,
DatePicker,
} from "antd"; } from "antd";
import _ from "underscore";
import { Route, withRouter } from "react-router-dom";
import { DownOutlined } from '@ant-design/icons';
import { PageControl } from "@/components"; import { PageControl } from "@/components";
import "./QuestionList.less";
import User from "@/common/js/user"; import User from "@/common/js/user";
import AidToolService from "@/domains/aid-tool-domain/AidToolService"; import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import _ from "underscore";
import PreviewQuestionModal from "../modal/PreviewQuestionModal"; import PreviewQuestionModal from "../modal/PreviewQuestionModal";
import BatchImportQuestionModal from "../modal/BatchImportQuestionModal"; import BatchImportQuestionModal from "../modal/BatchImportQuestionModal";
import { Route, withRouter } from "react-router-dom";
import OperateQuestion from "../OperateQuestion"; import OperateQuestion from "../OperateQuestion";
import Bus from "@/core/bus"; import Bus from "@/core/bus";
import moment from 'moment';
import Service from "@/common/js/service";
import MoveModal from '../../modal/MoveModal';
import "./QuestionList.less";
const { RangePicker } = DatePicker;
const { Search } = Input; const { Search } = Input;
const questionTypeEnum = { const questionTypeEnum = {
...@@ -82,13 +90,16 @@ class QuestionList extends Component { ...@@ -82,13 +90,16 @@ class QuestionList extends Component {
dataSource: [], // 题库列表 dataSource: [], // 题库列表
previewQuestionModal: null, // 题目预览模态框 previewQuestionModal: null, // 题目预览模态框
batchImportQuestionModal: null, // 批量导入模态框 batchImportQuestionModal: null, // 批量导入模态框
selectedRowKeys: [],
}; };
} }
componentDidMount() { componentDidMount() {
this.queryQuestionPageList(); this.queryQuestionPageList();
this.queryCategoryTree();
Bus.bind("queryQuestionPageList", (selectedCategoryId) => { Bus.bind("queryQuestionPageList", (selectedCategoryId) => {
selectedCategoryId = selectedCategoryId =
selectedCategoryId === "null" ? null : selectedCategoryId; selectedCategoryId === "null" ? null : selectedCategoryId;
this.clearSelect();
this.InitSearch(selectedCategoryId); this.InitSearch(selectedCategoryId);
}); });
} }
...@@ -97,6 +108,35 @@ class QuestionList extends Component { ...@@ -97,6 +108,35 @@ class QuestionList extends Component {
Bus.unbind("queryQuestionPageList", this.queryQuestionPageList); Bus.unbind("queryQuestionPageList", this.queryQuestionPageList);
} }
// 查询分类树
queryCategoryTree = () => {
let query = {
bizType: 'QUESTION',
count: true,
source: 0,
userId: User.getStoreUserId(),
tenantId: User.getStoreId(),
};
AidToolService.queryCategoryTree(query).then((res) => {
const { categoryList = [] } = res.result;
let list = this.renderTreeNodes(categoryList);
this.setState({ questionData: list });
});
};
renderTreeNodes = (data) => {
let newTreeData = data.map((item) => {
item.title = item.categoryName;
item.value = item.id;
item.key = item.id;
if (item.sonCategoryList) {
item.children = this.renderTreeNodes(item.sonCategoryList);
}
return item;
});
return newTreeData;
};
// 初始化列表查询 // 初始化列表查询
InitSearch = (categoryId) => { InitSearch = (categoryId) => {
const _query = { const _query = {
...@@ -213,6 +253,15 @@ class QuestionList extends Component { ...@@ -213,6 +253,15 @@ class QuestionList extends Component {
); );
const columns = [ const columns = [
{ {
title: "题型",
key: "questionTypeEnum",
dataIndex: "questionTypeEnum",
width: "16%",
render: (val) => {
return questionTypeEnum[val];
},
},
{
title: "题目", title: "题目",
key: "questionStem", key: "questionStem",
dataIndex: "questionStem", dataIndex: "questionStem",
...@@ -250,15 +299,6 @@ class QuestionList extends Component { ...@@ -250,15 +299,6 @@ class QuestionList extends Component {
}, },
}, },
{ {
title: "题型",
key: "questionTypeEnum",
dataIndex: "questionTypeEnum",
width: "16%",
render: (val) => {
return questionTypeEnum[val];
},
},
{
title: "正确率", title: "正确率",
key: "accuracy", key: "accuracy",
dataIndex: "accuracy", dataIndex: "accuracy",
...@@ -387,15 +427,20 @@ class QuestionList extends Component { ...@@ -387,15 +427,20 @@ class QuestionList extends Component {
AidToolService.deleteQuestion(params).then((res) => { AidToolService.deleteQuestion(params).then((res) => {
if (res.success) { if (res.success) {
message.success("删除成功"); message.success("删除成功");
const { query, total } = this.state; const { query, total, selectedRowKeys } = this.state;
const { size, current } = query; const { size, current } = query;
const _query = query; const _query = query;
let data = {};
if (total / size < current) { if (total / size < current) {
if (total % size === 1) { if (total % size === 1) {
_query.current = 1; _query.current = 1;
} }
} }
this.setState({ query: _query }, () => { data.query = _query;
if (selectedRowKeys.includes(record.id)) {
data.selectedRowKeys = _.reject(selectedRowKeys, item => item === record.id);
}
this.setState(data, () => {
this.queryQuestionPageList(); this.queryQuestionPageList();
Bus.trigger("queryCategoryTree", "remain"); Bus.trigger("queryCategoryTree", "remain");
}); });
...@@ -428,6 +473,117 @@ class QuestionList extends Component { ...@@ -428,6 +473,117 @@ class QuestionList extends Component {
this.setState({ batchImportQuestionModal: m }); this.setState({ batchImportQuestionModal: m });
}; };
onSelectChange = (selectedRowKeys) => {
if (selectedRowKeys.length > 50) {
message.warning('最多只能选择50个题目');
return null;
}
this.setState({ selectedRowKeys });
};
/**
* 设置【更多操作】选项
*/
setMoreOperationOption() {
return (
<Menu>
<Menu.Item key="2">
<div
key="import"
onClick={() => {
this.batchMove();
}}
>
批量移动
</div>
</Menu.Item>
<Menu.Item key="1">
<div
key="import"
onClick={() => {
this.batchDelete();
}}
>
批量删除
</div>
</Menu.Item>
</Menu>
);
}
batchMove = () => {
const { selectedRowKeys } = this.state;
if (_.isEmpty(selectedRowKeys)) {
message.warning('请先选择要移动的题目');
return null;
}
this.setState({ openMoveModal: true });
}
batchMoveRemote = (categoryId) => {
const { selectedRowKeys } = this.state;
const data = {
categoryId,
id: selectedRowKeys,
source: 0,
tenantId: User.getStoreId(),
userId: User.getUserId(),
};
Service.Hades('public/hades/batchMoveQuestion', data, { reject: true }).then((res) => {
if (res.success) {
message.success('移动成功');
Bus.trigger('queryCategoryTree', 'init');
this.queryQuestionPageList();
this.clearSelect();
} else {
message.error('移动失败');
}
}).catch(() => {
message.error('移动失败');
})
}
batchDelete = () => {
const { selectedRowKeys } = this.state;
if (_.isEmpty(selectedRowKeys)) {
message.warning('请先选择要删除的题目');
return null;
}
Modal.confirm({
title: "确定要删除题目吗?",
content: "删除后,不可恢复。",
icon: (
<span className="icon iconfont default-confirm-icon">&#xe839; </span>
),
okText: "删除",
cancelText: "取消",
onOk: () => {
const data = {
id: selectedRowKeys,
source: 0,
tenantId: User.getStoreId(),
userId: User.getUserId(),
};
Service.Hades('public/hades/batchDeleteQuestion', data, { reject: true }).then((res) => {
if (res.success) {
message.success('删除成功');
Bus.trigger('queryCategoryTree', 'init');
this.queryQuestionPageList();
this.clearSelect();
} else {
message.error('删除失败');
}
}).catch(() => {
message.error('删除失败');
})
},
})
}
clearSelect = () => {
this.setState({ selectedRowKeys: [] });
}
render() { render() {
const { const {
dataSource = [], dataSource = [],
...@@ -435,9 +591,17 @@ class QuestionList extends Component { ...@@ -435,9 +591,17 @@ class QuestionList extends Component {
query, query,
previewQuestionModal, previewQuestionModal,
batchImportQuestionModal, batchImportQuestionModal,
selectedRowKeys,
openMoveModal,
questionData,
} = this.state; } = this.state;
const { current, size, categoryId, questionName, questionType } = query; const { current, size, categoryId, questionName, questionType } = query;
const { match } = this.props; const { match } = this.props;
const rowSelection = {
selectedRowKeys,
preserveSelectedRowKeys: true,
onChange: this.onSelectChange,
};
return ( return (
<div className="question-list"> <div className="question-list">
<div className="question-list-filter"> <div className="question-list-filter">
...@@ -448,7 +612,7 @@ class QuestionList extends Component { ...@@ -448,7 +612,7 @@ class QuestionList extends Component {
<Search <Search
placeholder="搜索题目名称" placeholder="搜索题目名称"
value={questionName} value={questionName}
style={{ width: 178 }} style={{ width: '100%' }}
onChange={(e) => { onChange={(e) => {
this.handleChangeQuery("questionName", e.target.value); this.handleChangeQuery("questionName", e.target.value);
}} }}
...@@ -464,7 +628,7 @@ class QuestionList extends Component { ...@@ -464,7 +628,7 @@ class QuestionList extends Component {
<Select <Select
placeholder="请选择题目类型" placeholder="请选择题目类型"
value={questionType} value={questionType}
style={{ width: 178 }} style={{ width: '100%' }}
showSearch showSearch
allowClear allowClear
enterButton={<span className="icon iconfont">&#xe832;</span>} enterButton={<span className="icon iconfont">&#xe832;</span>}
...@@ -482,13 +646,32 @@ class QuestionList extends Component { ...@@ -482,13 +646,32 @@ class QuestionList extends Component {
> >
{_.map(questionTypeList, (item, index) => { {_.map(questionTypeList, (item, index) => {
return ( return (
<Select.Option value={item.value} key={item.key}> <Select.Option value={item.value} key={item.value}>
{item.label} {item.label}
</Select.Option> </Select.Option>
); );
})} })}
</Select> </Select>
</div> </div>
<div className="search-condition__item">
<span className="search-label">更新时间:</span>
<RangePicker
value={
query.updateDateStart
? [moment(query.updateDateStart), moment(query.updateDateEnd)]
: null
}
style={{ width: '100%' }}
format={"YYYY-MM-DD"}
onChange={(dates) => {
const _query = _.clone(query);
_query.updateDateStart = dates ? dates[0].startOf("day").valueOf() : null;
_query.updateDateEnd = dates ? dates[1].endOf("day").valueOf() : null;
_query.current = 0;
this.setState({ query: _query }, () => this.queryQuestionPageList());
}}
/>
</div>
</div> </div>
<div className="reset-fold-area"> <div className="reset-fold-area">
...@@ -504,12 +687,33 @@ class QuestionList extends Component { ...@@ -504,12 +687,33 @@ class QuestionList extends Component {
</Row> </Row>
</div> </div>
{["CloudManager", "StoreManager"].includes(User.getUserRole()) && {["CloudManager", "StoreManager"].includes(User.getUserRole()) &&
categoryId && ( (
<Space size={16}> <Space size={16}>
<Button type="primary" onClick={this.handleCreateQuestion}> {_.isEmpty(selectedRowKeys) ?
(!!categoryId && [
<Button key="1" type="primary" onClick={this.handleCreateQuestion}>
新建题目 新建题目
</Button>,
<Button key="2" onClick={this.batchImportQuestion}>批量导入</Button>
])
: <div className="select-container">
<span className="con">
<div>
<span className="icon iconfont tip">&#xe6f2;</span>
<span className="text">已选择{selectedRowKeys.length}</span>
</div>
<div>
<span className="clear" onClick={this.clearSelect}>清空</span>
</div>
</span>
</div>
}
<Dropdown className="ml8" overlay={this.setMoreOperationOption()}>
<Button id="more_operate">
更多操作
<DownOutlined />
</Button> </Button>
<Button onClick={this.batchImportQuestion}>批量导入</Button> </Dropdown>
</Space> </Space>
)} )}
<div className="question-list-content"> <div className="question-list-content">
...@@ -521,6 +725,7 @@ class QuestionList extends Component { ...@@ -521,6 +725,7 @@ class QuestionList extends Component {
pagination={false} pagination={false}
bordered bordered
onChange={this.handleChangeTable} onChange={this.handleChangeTable}
rowSelection={rowSelection}
/> />
</ConfigProvider> </ConfigProvider>
{total > 0 && ( {total > 0 && (
...@@ -542,6 +747,20 @@ class QuestionList extends Component { ...@@ -542,6 +747,20 @@ class QuestionList extends Component {
)} )}
{previewQuestionModal} {previewQuestionModal}
{batchImportQuestionModal} {batchImportQuestionModal}
{openMoveModal &&
<MoveModal
visible={openMoveModal}
title="题目"
data={questionData}
categoryId={query.categoryId}
length={selectedRowKeys.length}
onCancel={() => this.setState({ openMoveModal: false })}
onOk={(categoryId) => {
this.batchMoveRemote(categoryId);
this.setState({ openMoveModal: false });
}}
/>
}
</div> </div>
<Route <Route
path={`${match.url}/question-operate-page`} path={`${match.url}/question-operate-page`}
......
...@@ -8,13 +8,16 @@ ...@@ -8,13 +8,16 @@
flex-wrap: wrap; flex-wrap: wrap;
&__item { &__item {
display: flex;
margin-right: 3%; margin-right: 3%;
margin-bottom: 16px; margin-bottom: 16px;
width: 30%;
.search-label { .search-label {
vertical-align: middle; vertical-align: middle;
display: inline-block; display: inline-block;
height: 32px; height: 32px;
line-height: 32px; line-height: 32px;
flex-shrink: 0;
} }
} }
} }
...@@ -37,6 +40,31 @@ ...@@ -37,6 +40,31 @@
} }
} }
} }
.select-container{
.con {
background: #FFF4DD;
border-radius: 4px;
padding: 3px 16px;
display: inline-flex;
align-items: center;
justify-content: space-between;
.tip {
font-size: 14px;
color: #FF9D14;
margin-right: 8px;
}
.text {
font-size: 14px;
color: #666;
margin-right: 30px;
}
.clear {
color: #5289FA;
font-size: 14px;
}
}
}
.data-icon { .data-icon {
cursor: pointer; cursor: pointer;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment