Files
fe-manage/src/components/drawers/CommonTest.vue
2023-04-12 15:31:43 +08:00

727 lines
20 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">{{ info?.examinationName >= 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>
<div v-if="info?.examinationName >= 0">
<button
v-if="info?.examType == 1"
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="formData.examType === 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
v-else
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="formData.examType === 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
</div>
<div v-else>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(1)"
:class="formData.examType === 1 ? 'outer' : 'notOuter'"
>
系统考试
</button>
<button
style="width: 100px; cursor: pointer;"
@click="changeOuter(2)"
:class="formData.examType === 2 ? 'outer' : 'notOuter'"
>
外部考试
</button>
</div>
</div>
</div>
<div v-if="formData.examType===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="info?.examinationName >= 0?true:false"
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.examinationPaperId" v-model:name="formData.examinationTestName">
<div class="btnbox">
<button class="xkbtn" style="margin:0" :disabled="info?.examinationName >= 0?true:false">
{{ formData.examinationPaperId ? "重选" : "选择" }}试卷
</button>
</div>
</s-test>
<div v-if="formData.examinationPaperId">
<a-tag closable color="processing" @close="delTag" :closeIcon="true">
<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"
format="YYYY-MM-DD HH:mm"
valueFormat="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="info?.examinationName >= 0?true:false"
:min="0"
:max="999999"
: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
min="0"
:disabled="info?.examinationName >= 0?true:false"
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="info?.examinationName >= 0?true:false"
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="info?.examinationName >= 0?true:false"
:min="-1"
:max="999999"
: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="info?.examinationName >= 0?true:false"
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="info?.examinationName >= 0?true:false"
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="info?.examinationName >= 0?true:false"
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="info?.examinationName >= 0?true:false"
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="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>
<div class="btnbox">
<a-input
v-model:value="formData.source"
style="width: 400px; height: 40px; border-radius: 8px"
placeholder="请输入数据来源"
show-count :maxlength="420"
/>
</div>
</div>
<div class="main_item2">
<div class="signbox">
<span style="margin-right: 3px">考试说明</span>
</div>
<div class="textarea">
<a-textarea
v-model:value="formData.externalExplain"
placeholder="请输入考试说明"
allow-clear
show-count
:maxlength="200"
:rows="6"
/>
</div>
</div>
</div>
</div>
<div class="main_btns">
<a-button class="btn2" @click="closeDrawer">取消</a-button>
<a-button class="btn2" @click="confirm">确定</a-button>
</div>
</div>
</a-drawer>
</template>
<script setup>
import {defineEmits, defineProps, ref, watch} from "vue";
import STest from "./SelectTest.vue";
import dayjs from "dayjs";
import {Form, message} from "ant-design-vue";
const props = defineProps({
info: {}
})
const visible = ref(false)
const initValue = {
examinationName: '',
examinationPaperId: '',
examinationStartTime: '',
examinationEndTime: '',
examinationDuration: '',
passLine: '',
examType: 1,
source: "",
showAnswers: 2,
showAnalysis: 2,
scoringModel: 2,
questionArrangement: 4,
externalExplain: ""
}
const formData = ref(initValue)
const innerRule = {
examinationName: [
{
required: true,
message: '请输入考试名称',
},
],
examinationPaperId: [
{
required: true,
message: '请输入选择试卷',
},
],
examinationStartTime: [
{
required: true,
message: '请输入开始开始时间',
},
],
examinationEndTime: [
{
required: true,
message: '请输入开始结束时间',
},
],
examinationDuration: [
{
required: true,
message: '请输入考试时长',
},
],
passLine: [
{
required: true,
message: '请输入及格线',
},
],
}
const outerRule = {
examinationName: [
{
required: true,
message: '请输入考试名称',
},
],
source: [
{
required: true,
message: '请输入数据来源',
},
],
}
const rulesRef = ref(innerRule);
const emit = defineEmits({})
const dateTime = ref([]);
const {resetFields, validate} = Form.useForm(formData, rulesRef);
watch(() => formData.value.examType, () => {
formData.value.examType === 1 ? rulesRef.value = innerRule : rulesRef.value = outerRule
})
watch([props, visible], () => {
console.log(props.info)
resetFields(props.info)
dateTime.value = [props.info?.examinationStartTime || '', props.info?.examinationEndTime || '']
})
const closeDrawer = () => {
visible.value = false
resetFields()
dateTime.value = []
};
function timeChange(time, timeStr) {
formData.value.examinationStartTime = timeStr[0]
formData.value.examinationEndTime = timeStr[1]
}
const disabledDate = (current) => {
return current && current < dayjs().startOf('day');
};
async function confirm() {
await validate().catch(({errorFields}) => {
message.warning(errorFields[0].errors.join());
throw Error("数据校验不通过")
});
emit('update:info', {...formData.value})
closeDrawer()
}
function openDrawer() {
visible.value = true
}
const delTag = () => {
formData.value.examinationPaperId = '';
formData.value.examinationTestName = '';
}
function changeOuter(v) {
formData.value.examType = 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;
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>