Files
fe-manage/src/components/drawers/AddTest.vue
2023-02-20 10:37:33 +08:00

753 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div @click="openDrawer">
<slot></slot>
</div>
<a-drawer
:visible="visible"
class="drawerStyle addtestDrawer"
width="800"
placement="right"
>
<div class="drawerMain">
<div class="header">
<div class="headerTitle">{{ taskIndex >= 0 ? "编辑" : "添加" }}考试</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../assets/images/basicinfo/close.png"
@click="closeDrawer"
/>
</div>
<div style="display: flex; flex-direction: row; padding-top: 0px; margin-top: 20px; margin-left: 32px;">
<div v-if="taskIndex >= 0">
<button
v-if="isOuter==1"
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="isOuter == 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
v-else
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="isOuter == 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
</div>
<div v-else>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="isOuter == 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="isOuter == 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
</div>
</div>
<div v-if="isOuter===1" class="contentMain">
<div class="main_left">
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">考试名称</span>
</div>
<div class="btnbox">
<a-input
:disabled="taskIndex >= 0"
v-model:value="formData.examinationName"
style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入考试名称"
:maxlength="20"
/>
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">选择试卷</span>
</div>
<s-test v-model:id="formData.examinationTestId" v-model:name="formData.examinationTestName">
<div class="btnbox">
<button class="xkbtn" @click="selectTest" :disabled="taskIndex >= 0">
{{ formData.examinationTestId ? "重选" : "选择" }}试卷
</button>
</div>
</s-test>
<div v-if="formData.examinationTestId">
<a-tag closable color="processing" @close="delTag" :closeIcon="taskIndex >= 0">
<span style="font-size: 14px; line-height: 33px">{{ formData.examinationTestName }}</span>
</a-tag>
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">考试时间</span>
</div>
<div class="btnbox">
<a-range-picker
style="width: 400px; height: 40px; border-radius: 8px"
:show-time="{format:'hh:mm'}"
:disabled-date="disabledDate"
:disabled-time="disabledRangeTime"
format="YYYY/MM/DD HH:mm"
v-model:value="dateTime"
@change="timeChange"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">考试时长</span>
</div>
<div class="select">
<a-input-number
:disabled="taskIndex >= 0"
:min="0"
:max="300"
:precision="0"
style="width: 400px; height: 40px; border-radius: 8px"
v-model:value="formData.examinationDuration"
></a-input-number>
<span style="color: #999999; margin-left: 8px">分钟</span>
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">及格线</span>
</div>
<div class="btnbox">
<a-input
:disabled="taskIndex >= 0"
v-model:value="formData.passLine"
type="number"
style="width: 400px; height: 40px; border-radius: 8px"
/>
<span style="color: #999999; margin-left: 8px"></span>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px">考试说明</span>
</div>
<div class="textarea">
<a-textarea
:disabled="taskIndex >= 0"
v-model:value="formData.examinationExplain"
placeholder="请输入考试说明"
allow-clear
show-count
:maxlength="200"
:rows="6"
/>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px;margin-top: 10px;">考试限制</span>
</div>
<div class="kqszbox">
<div class="setbox">
<div class="timerbox">
<span>允许重复考试</span>
<a-input-number
:disabled="taskIndex >= 0"
:min="-1"
:max="300"
:precision="0"
style="
width: 100px;
height: 32px;
border-radius: 8px;
overflow: hidden;"
v-model:value="formData.examinationLimit"
></a-input-number>
<span style="color: #999999; margin-left: 8px"
>,-1表示无限制</span
>
</div>
</div>
</div>
</div>
<div class="main_item">
<div class="signbox">
<span style="margin-right: 3px">显示答案</span>
</div>
<div class="btnbox">
<a-radio-group
:disabled="taskIndex >= 0"
style="margin-right: 12px"
v-model:value="formData.showAnswers"
>
<a-radio :value="1">允许查看</a-radio>
<a-radio :value="2">不允许查看</a-radio>
</a-radio-group>
</div>
</div>
<div class="main_item">
<div class="signbox">
<span style="margin-right: 3px">显示解析</span>
</div>
<div class="btnbox">
<a-radio-group
:disabled="taskIndex >= 0"
style="margin-right: 12px"
v-model:value="formData.showAnalysis"
>
<a-radio :value="1">允许查看</a-radio>
<a-radio :value="2">不允许查看</a-radio>
</a-radio-group>
</div>
</div>
<div class="main_item">
<div class="signbox">
<span style="margin-right: 3px">评分模式</span>
</div>
<div class="btnbox">
<a-radio-group
:disabled="taskIndex >= 0"
style="margin-right: 12px"
v-model:value="formData.scoringModel"
>
<a-radio :value="1">最高一次</a-radio>
<a-radio :value="2">最后一次</a-radio>
</a-radio-group>
</div>
</div>
<div class="main_item">
<div class="signbox">
<span style="margin-right: 3px">试题排列</span>
</div>
<div class="btnbox">
<a-radio-group
:disabled="taskIndex >= 0"
style="margin-right: 12px"
v-model:value="formData.questionArrangement"
>
<a-radio :value="1">试题乱序</a-radio>
<a-radio :value="2">选项乱序</a-radio>
<a-radio :value="3">全部乱序</a-radio>
<a-radio :value="4">不乱序</a-radio>
</a-radio-group>
</div>
</div>
<div class="main_item" style="height: 20px;"></div>
</div>
</div>
<div v-else class="contentMain">
<div class="main_left">
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">考试名称</span>
</div>
<div class="btnbox">
<a-input
v-model:value="formDataOuter.examinationName"
style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入考试名称"
:maxlength="20"
/>
</div>
</div>
<div class="main_item">
<div class="signbox">
<div class="sign">
<img
src="@/assets/images/coursewareManage/asterisk.png"
alt=""
/>
</div>
<span style="margin-right: 3px">数据来源</span>
</div>
<div class="btnbox">
<a-input
v-model:value="formDataOuter.source"
style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入数据来源"
:maxlength="20"
/>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px">考试说明</span>
</div>
<div class="textarea">
<a-textarea
v-model:value="formDataOuter.externalExplain"
placeholder="请输入考试说明"
allow-clear
show-count
:maxlength="200"
:rows="6"
/>
</div>
</div>
</div>
</div>
<div class="main_btns">
<a-button class="btn1" @click="closeDrawer">取消</a-button>
<a-button v-if="isOuter==1" class="btn2" @click="confirm">确定</a-button>
<a-button v-else class="btn2" @click="confirmouter">确定</a-button>
</div>
<!-- 加载动画 -->
<div class="aeLoading" :style="{ display: addLoading ? 'flex' : 'none' }">
<a-spin :spinning="addLoading" tip=""/>
</div>
<!-- 选择考试抽屉 -->
<s-test v-model:STvisible="STvisible" @getSTData="getData"/>
</div>
</a-drawer>
</template>
<script setup>
import {defineEmits, defineProps, ref} from "vue";
import STest from "./SelectTest.vue";
import dayjs from "dayjs";
import {message} from "ant-design-vue";
const props = defineProps({
type: Number,
taskList: []
})
const visible = ref(false)
const formData = ref({
examType: 1,
showAnswers: 2,
showAnalysis: 2,
scoringModel: 2,
questionArrangement: 4
})
const formDataOuter = ref({
examType: 2,
examinationName:"",
source:"",
externalExplain:""
})
const emit = defineEmits({})
const taskIndex = ref(-1);
const dateTime = ref([]);
const isOuter = ref(1);
const closeDrawer = () => {
visible.value = false
taskIndex.value = -1
formData.value = {
examType: 1,
showAnswers: 2,
showAnalysis: 2,
scoringModel: 2,
questionArrangement: 4
}
formDataOuter.value = ref({
examType: 2,
examinationName:"",
source:"",
externalExplain:""
})
dateTime.value = []
};
// const range = (start, end) => {
// const result = [];
// for (let i = start; i < end; i++) {
// result.push(i);
// }
// return result;
// };
function timeChange(time, timeStr) {
formData.value.examinationStartTime = timeStr[0]
formData.value.examinationEndTime = timeStr[1]
}
const disabledDate = (current) => {
return current && current < dayjs().startOf('day');
};
const disabledRangeTime = () => ({
// disabledHours: () => range(0, 24).splice(4, 20),
// disabledMinutes: () => range(30, 60),
// disabledSeconds: () => [55, 56],
});
// 系统考试
function confirm() {
if (!formData.value.examinationName) {
message.warning("请输入考试名称");
return
}
if (!formData.value.examinationTestId) {
message.warning("请输入选择试卷");
return
}
if (!formData.value.examinationStartTime) {
message.warning("请输入开始结束时间");
return
}
if (!formData.value.examinationEndTime) {
message.warning("请输入开始结束时间");
return
}
if (!formData.value.examinationDuration) {
message.warning("请输入考试时长");
return
}
if (!formData.value.passLine) {
message.warning("请输入及格线");
return
}
// debugger
if (taskIndex.value === -1) {
const list = props.taskList
list.push({name: formData.value.examinationName, type: props.type, info: {...formData.value}})
} else {
const data = props.taskList[taskIndex.value]
data.name = formData.value.examinationName
data.info = formData.value
data.examType = formData.value == 1 ? 1 : 2
}
emit('update:taskList', [...props.taskList])
closeDrawer()
}
// 外部考试
function confirmouter() {
if (!formDataOuter.value.examinationName) {
message.warning("请输入考试名称");
return
}
if (!formDataOuter.value.source) {
message.warning("请输入数据来源");
return
}
if (taskIndex.value === -1) {
const list = props.taskList
list.push({name: formDataOuter.value.examinationName,duration:dayjs(formData.value.examinationEndTime).diff(formData.value.examinationStartTime,'minutes'), type: props.type, info: {...formDataOuter.value}})
} else {
const data = props.taskList[taskIndex.value]
data.name = formDataOuter.value.examinationName
data.info = formDataOuter.value
data.examType = 2
data.duration = dayjs(formData.value.examinationEndTime).diff(formData.value.examinationStartTime,'minutes')
}
emit('update:taskList', [...props.taskList])
closeDrawer()
}
function openDrawer(i, row) {
row && row.info.examType == 1 ? row && (formData.value = row.info) : row && (formDataOuter.value = row.info);
row ? isOuter.value = row.info.examType : isOuter.value = 1;
row && row.info.examType == 1 && (dateTime.value = [dayjs(row.info.examinationStartTime, "YYYY-MM-DD HH:mm"), dayjs(row.info.examinationEndTime, "YYYY-MM-DD HH:mm")]);
(i >= 0) && (taskIndex.value = i);
visible.value = true
}
const delTag = () => {
formData.value.examinationTestId = '';
formData.value.examinationTestName = '';
}
function changeOuter(v) {
isOuter.value = v;
}
defineExpose({openDrawer})
</script>
<style lang="scss">
.ant-table-striped :deep(.table-striped) td {
background-color: #fafafa !important;
}
.outer {
background-color: #4ea6ff;
color: #fff;
border-radius: 5px;
border: 1px solid #a09292;
height: 36px;
margin-right: 10px;
}
.notOuter {
color: #000;
border-radius: 5px;
border: 1px solid #a09292;
background: #fff;
margin-right: 10px;
padding: 3px;
}
.tag-style {
color: rgb(113, 113, 237);
background-color: #d7d1f7;
}
.addtestDrawer {
.drawerMain {
.header {
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
margin-left: 24px;
}
}
.contentMain {
display: flex;
justify-content: space-between;
.main_left {
padding-right: 30px;
flex: 1;
border-right: 1px solid #e8e8e8;
.main_item {
display: flex;
align-items: center;
margin-top: 32px;
margin-bottom: 32px;
.signbox {
width: 120px;
display: flex;
justify-content: end;
align-items: center;
.sign {
margin-right: 5px;
}
}
.btnbox {
display: flex;
flex: 1;
align-items: center;
.xkbtn {
cursor: pointer;
width: 130px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-right: 8px;
color: #fff;
}
}
}
.main_item2 {
display: flex;
align-items: flex-start;
margin-bottom: 32px;
.textarea {
width: 400px;
.ant-input {
width: 100%;
}
.ant-input-textarea-show-count {
position: relative;
}
.ant-input-textarea-show-count::after {
position: absolute;
right: 10px;
bottom: 0px;
}
.ant-input {
border-radius: 8px;
}
}
.signbox {
width: 120px;
display: flex;
justify-content: end;
align-items: center;
.sign {
margin-right: 5px;
}
}
.kqszbox {
.qdqtbox {
margin-left: 56px;
}
.setbox {
display: flex;
flex-wrap: wrap;
.timerbox {
margin-top: 6px;
margin-right: 32px;
display: flex;
align-items: center;
flex-wrap: nowrap;
}
}
}
.btnbox2 {
display: flex;
flex-direction: column;
justify-content: flex-start;
.xkbtn {
cursor: pointer;
width: 130px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-right: 16px 8px 32px 0;
color: #fff;
margin-top: 16px;
margin-bottom: 60px;
}
}
}
}
}
.main_table {
position: relative;
padding-bottom: 80px;
.ant-checkbox-wrapper {
align-items: center;
margin-top: -2px;
}
.ant-table-selection-column {
padding: 0px !important;
padding-left: 5px !important;
}
.ant-table-thead > tr > th {
background-color: rgba(239, 244, 252, 1);
}
th.h {
background-color: #eff4fc !important;
}
.ant-table-tbody
> tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)
> td {
background: #f6f9fd;
}
.pa {
left: 0;
width: 100%;
display: flex;
justify-content: center;
position: absolute;
bottom: 20px;
}
}
.main_btns {
height: 72px;
width: 100%;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.16);
.btn1 {
width: 100px;
height: 40px;
border: 1px solid #4ea6ff;
border-radius: 8px;
color: #4ea6ff;
background-color: #fff;
cursor: pointer;
}
.btn2 {
cursor: pointer;
width: 100px;
height: 40px;
background: #4ea6ff;
border-radius: 8px;
border: 0;
margin-left: 15px;
color: #fff;
}
}
}
}
</style>