Commit 5a878018 by zhujian

'feat:试卷页面'

parent e70744c5
import React, { useState, useRef, useEffect, useContext } from 'react'
import Breadcrumbs from "@/components/Breadcrumbs";
import { Form, Alert, Input, Button, InputNumber, DatePicker, Switch, Radio } from 'antd';
import { Form, Alert, Input, Button, InputNumber, DatePicker, Switch, Radio, message, Modal } from 'antd';
import { Route, withRouter } from 'react-router-dom';
import User from "@/common/js/user";
import moment from 'moment'
......@@ -30,6 +30,9 @@ function AddExam(props: any) {
const [resultShow, setResultShow] = useState('IMMEDIATELY');
const [examDesc, setExamDesc] = useState('');
const [passScore, setPassScore] = useState(100);
const [desclen, setDescLen] = useState(0);
const [check, setCheck] = useState(false);
const [examDuration, setExamDuration] = useState(0);
useEffect(() => {
......@@ -51,10 +54,11 @@ function AddExam(props: any) {
function handleSave() {
setCheck(true);
const param = {
paperId,
startTime:examStartTime,
endTime:examEndTime,
startTime: examStartTime,
endTime: examEndTime,
examName,
passRate,
examStartTime,
......@@ -70,8 +74,46 @@ function AddExam(props: any) {
tenantId: User.getStoreId(),
source: 0
}
Service.Hades("public/hades/createExam", param).then((res) => {
if (!param.examName) {
message.warning('请输入考试名称');
return
}
if (!paperId) {
message.warning('请选择试卷');
return
}
if (!passRate) {
message.warning('请输入及格线');
return
}
if (!examStartTime || !examEndTime) {
message.warning('请选择考试起止时间');
return
}
if (Number(examStartTime) < moment().valueOf()) {
message.warning('开始时间不能早于现在');
return
}
if (!examDuration) {
message.warning('请输入考试时长');
return
}
if (desclen > 1000) {
message.warning('内容过长,不能超过1000字');
return
}
Service.Hades("public/hades/createExam", param).then((res) => {
message.success('创建成功');
props.history.goBack();
})
}
......@@ -108,8 +150,21 @@ function AddExam(props: any) {
};
}
function handleGoBack() {
Modal.confirm({
title: '确定要返回吗?',
content: '返回后,本次编辑的内容将不被保存',
okText: '确认返回',
cancelText: '留在本页',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => {
props.history.goBack();
}
})
}
return <div className="page examPage">
<Breadcrumbs navList={"新建考试"} goBack={() => props.history.goBack()} />
<Breadcrumbs navList={"新建考试"} goBack={handleGoBack} />
<div className="box">
<Alert message="请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企培保有依据国家规定及平台规则进行处理的权利" type="info" showIcon />
......@@ -120,15 +175,21 @@ function AddExam(props: any) {
wrapperCol={{ span: 14 }}
layout="horizontal"
>
<Form.Item label="考试名称" required>
<Form.Item label="考试名称"
validateStatus={(check && !examName) ? 'error' : ''}
help={check && !examName && '请选择课程'}
required>
<Input placeholder='请输入试卷名称(40字以内)' value={examName} onChange={(e) => {
<Input placeholder='请输入试卷名称(40字以内)' maxLength={40} value={examName} onChange={(e) => {
console.log(e.target.value)
setExamName(e.target.value)
}} style={{ width: 300 }} />
</Form.Item>
<Form.Item label="选择试卷" required>
<Form.Item label="选择试卷"
validateStatus={(check && !paperId) ? 'error' : ''}
help={check && !paperId && '请选择试卷'}
required>
<span style={{ marginRight: 12, lineHeight: '32px' }}>{paperInfo.paperName}</span> <Button onClick={() => { setShowModal(true) }} >{paperInfo.paperId ? '重新选择' : '选择试卷'}</Button>
......@@ -164,7 +225,11 @@ function AddExam(props: any) {
}
<Form.Item label="及格线" style={{marginTop:24}} required>
<Form.Item label="及格线"
style={{ marginTop: 24 }}
validateStatus={(check && !passRate) ? 'error' : ''}
help={check && !passRate && '请输入及格线'}
required>
<InputNumber value={passRate} onChange={(value: any) => { setPassRate(value) }} style={{ width: 100 }} />
<span style={{ marginLeft: 4 }}>%
</span>
......@@ -172,7 +237,10 @@ function AddExam(props: any) {
{` 总分(${paperInfo.totalScore || 0})*及格线(${passRate || 0}%)=及格分数(${passScore})`}</span>
</Form.Item>
<Form.Item label="考试有效期" required>
<Form.Item label="考试有效期"
validateStatus={(check && !examStartTime) ? 'error' : ''}
help={check && !examStartTime && '请选择考试起止时间'}
required>
<RangePicker
ranges={{
'近七天': [moment(), moment().add(6, 'day').endOf('day')],
......@@ -188,13 +256,16 @@ function AddExam(props: any) {
showTime
format="YYYY/MM/DD HH:mm"
onChange={(date: any) => {
setStartTime(date && date[0]?.startOf('day').valueOf());
setExamEndTime(date && date[1]?.endOf('day').valueOf());
setStartTime(date && date[0]?.valueOf());
setExamEndTime(date && date[1]?.valueOf());
}}
/>
</Form.Item>
<Form.Item label="考试时长" required>
<Form.Item label="考试时长"
validateStatus={(check && !examDuration) ? 'error' : ''}
help={check && !examDuration && '请输入考试时长'}
required>
<InputNumber value={examDuration} max={1440} min={1} onChange={(value: any) => { setExamDuration(value) }} style={{ width: 100 }} />
<span style={{ marginLeft: 4 }}>分钟
</span>
......@@ -209,7 +280,7 @@ function AddExam(props: any) {
detail={{
content: examDesc
}}
onChange={(val: any) => { setExamDesc(val) }}
onChange={(val: any, len: any) => { setExamDesc(val); setDescLen(len) }}
/>
</Form.Item>
<div className="title" style={{ marginTop: 40 }}>考试设置</div>
......@@ -274,10 +345,12 @@ function AddExam(props: any) {
}} paperInfo={paperInfo} close={() => { setShowModal(false) }}></SelectPaperModal>
}
<div className="footer">
<Button onClick={() => { }}>取消</Button>
<Button onClick={handleGoBack}>取消</Button>
<Button onClick={() => { }}>预览</Button>
<Button type="primary" onClick={_.debounce(() => { handleSave() }, 3000, true)}>保存</Button>
</div>
</div>
}
......
import React, { useState, useRef, useEffect, useContext } from 'react'
import { Row, Input, Select, DatePicker, Tooltip, Button, Table, Dropdown, Menu } from 'antd';
import { Row, Input, Select, DatePicker, Tooltip, Button, Table, Dropdown, Menu, Modal } from 'antd';
import TeacherSelect from '@/modules/common/TeacherSelect';
import { Route, withRouter } from 'react-router-dom';
import Service from "@/common/js/service";
......@@ -32,7 +32,7 @@ function ExaminationManager(props: any) {
const [total, setTotal] = useState(0);
const [list, setList] = useState([]);
const [questionCntSort, setQuestionCntSort] = useState(sortState)
const queryRef = useRef(null);
const queryRef = useRef({});
const columns = [
......@@ -105,7 +105,7 @@ function ExaminationManager(props: any) {
</div>
{
(ctx.xmState?.userPermission?.AddExam() || ctx.xmState?.userPermission?.DelExam()) && [<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>
</Dropdown>]
}
......@@ -121,10 +121,18 @@ function ExaminationManager(props: any) {
function getOpe(item: any) {
return <Menu>
{
ctx.xmState?.userPermission?.AddExam() && <Menu.Item key="0">
ctx.xmState?.userPermission?.AddExam() && (moment().valueOf() < item.examStartTime) && <Menu.Item key="0">
<span
onClick={() => {
if (moment().valueOf() + 5 * 60 * 1000 < item.examStartTime) {
Modal.info({
title: '无法编辑',
content: '离考试开始时间小于5分钟,为保证答题数据的准确性,不能再进行编辑了',
})
} else {
}
}}
>
编辑
......@@ -133,10 +141,10 @@ function ExaminationManager(props: any) {
}
{
ctx.xmState?.userPermission?.DelExam() && <Menu.Item key="1">
ctx.xmState?.userPermission?.DelExam() && (moment().valueOf() + 30 * 60 * 1000 < item.examStartTime) && <Menu.Item key="1">
<span
onClick={() => {
deleteExam(item)
}}
>
删除
......@@ -149,6 +157,28 @@ function ExaminationManager(props: any) {
}
function deleteExam(item: any) {
Modal.confirm({
title: '删除考试',
content: '确定删除该考试吗?',
okText: '删除',
cancelText: '取消',
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => {
Service.Hades("public/hades/deleteExam", {
"examId": item.paperId,
userId: User.getStoreUserId(),
tenantId: User.getStoreId(),
source: 0
}).then(() => {
getList()
})
}
})
}
function getList() {
Service.Hades("public/hades/queryExamPageList", {
...query, userId: User.getStoreUserId(),
......@@ -156,6 +186,7 @@ function ExaminationManager(props: any) {
source: 0
}).then((res) => {
setList(res.result?.records || [])
setTotal(parseInt(res.result.total))
})
}
......@@ -213,22 +244,25 @@ function ExaminationManager(props: any) {
}} />
</div>
<div className="search-condition__item">
<span className="search-name">创建时间:</span>
<RangePicker
className='search-input'
value={[
query.createStartTime ? moment(Number(query.createStartTime)) : null,
query.createStartTime ? moment(Number(query.createEndTime)) : null
]}
onChange={(date: any) => {
const _query = { ...query }
_query.createStartTime = date && date[0]?.startOf('day').valueOf();
_query.createEndTime = date && date[1]?.endOf('day').valueOf();
setQuery(_query);
{
!!expandFilter && <div className="search-condition__item">
<span className="search-name">创建时间:</span>
<RangePicker
className='search-input'
value={[
query.createStartTime ? moment(Number(query.createStartTime)) : null,
query.createStartTime ? moment(Number(query.createEndTime)) : null
]}
onChange={(date: any) => {
const _query = { ...query }
_query.createStartTime = date && date[0]?.startOf('day').valueOf();
_query.createEndTime = date && date[1]?.endOf('day').valueOf();
setQuery(_query);
}} />
</div>
}
}} />
</div>
</div>
<div className="reset-fold-area">
<Tooltip title="清空筛选"><span className="resetBtn iconfont icon" onClick={() => {
......@@ -241,10 +275,10 @@ function ExaminationManager(props: any) {
</div>
</div>
{
ctx.xmState?.userPermission?.AddExam() && <Button type='primary' onClick={()=>{
ctx.xmState?.userPermission?.AddExam() && <Button type='primary' onClick={() => {
props.history.push({
pathname: `${match.url}/add`
})
})
}} style={{ margin: '12px 0' }}>新建考试</Button>
}
......@@ -269,8 +303,9 @@ function ExaminationManager(props: any) {
total={total}
onShowSizeChange={onShowSizeChange}
toPage={(page: any) => {
let _query: any = { ...query.current };
_query.current = page;
console.log(page)
let _query: any = { ...queryRef.current };
_query.current = page + 1;
setQuery(_query)
}}
/>
......
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