Files
fe-manage/src/components/drawers/AddTest.vue
2022-12-30 15:37:06 +08:00

987 lines
27 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>
<a-drawer
:visible="addtestVisible"
class="drawerStyle addtestDrawer"
width="80%"
placement="right"
@after-visible-change="afterVisibleChange"
>
<div class="drawerMain">
<div class="header">
<div class="headerTitle">{{ edit ? "编辑" : "添加" }}考试</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../assets/images/basicinfo/close.png"
@click="closeDrawer2"
/>
</div>
<!-- 2022-11-30注释 后面放开 修改div的padding-topL:32 -->
<div style="display: flex; flex-direction: row; padding-top: 0px">
<!-- <button
style="width: 100px"
@click="changeOuter(1)"
:class="[isOuter == 1 ? 'outer' : 'notOuter']"
>
系统考试
</button> -->
<!-- <button
style="width: 100px"
@click="changeOuter(2)"
:class="[isOuter == 2 ? 'outer' : 'notOuter']"
>
外部考试
</button> -->
</div>
<div 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="test.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">
<button class="xkbtn" @click="selectTest">
{{ chooseCourse ? "重选" : "选择" }}试卷
</button>
<div v-if="paperName != ''">
<a-tag closable color="processing" @close="delTag">
<span style="font-size: 14px; line-height: 33px">{{
paperName
}}</span>
</a-tag>
</div>
</div>
<!-- 选择面授侧弹窗 -->
<div>
<sel-facet
v-model:selfacetVisible="selfacetvisible"
v-model:chooseCourse="chooseCourse"
v-model:chooseCourseName="chooseCourseName"
/>
</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="test.chooseTime"
: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
:min="0"
:max="300"
:precision="0"
style="width: 400px; height: 40px; border-radius: 8px"
v-model:value="test.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
v-model:value="test.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
v-model:value="test.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
:min="-1"
:max="300"
:precision="0"
style="
width: 100px;
height: 32px;
border-radius: 8px;
overflow: hidden;
"
v-model:value="test.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
style="margin-right: 12px"
v-model:value="test.showAnswers"
>
<a-radio v-model:checked="checked" :value="1" @click="cloradio1"
>允许查看
</a-radio>
<a-radio v-model:checked="checked" :value="2" @click="cloradio1"
>不允许查看
</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
style="margin-right: 12px"
v-model:value="test.showAnalysis"
>
<a-radio v-model:checked="checked" :value="1" @click="cloradio2"
>允许查看
</a-radio>
<a-radio v-model:checked="checked" :value="2" @click="cloradio2"
>不允许查看
</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
style="margin-right: 12px"
v-model:value="test.scoringModel"
>
<a-radio v-model:checked="checked" :value="1" @click="cloradio3"
>最高一次
</a-radio>
<a-radio v-model:checked="checked" :value="2" @click="cloradio3"
>最后一次
</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
style="margin-right: 12px"
v-model:value="test.questionArrangement"
>
<a-radio
v-model:checked="checked"
:value="1"
@click="cloradio4"
>试题乱序
</a-radio>
<a-radio
v-model:checked="checked"
:value="2"
@click="cloradio4"
>选项乱序
</a-radio>
<a-radio
v-model:checked="checked"
:value="3"
@click="cloradio4"
>全部乱序
</a-radio>
<a-radio
v-model:checked="checked"
:value="4"
@click="cloradio4"
>不乱序
</a-radio>
</a-radio-group>
</div>
</div>
<div class="main_item" style="height: 20px;"></div>
</div>
</div>
<div class="main_btns">
<a-button class="btn1" @click="closeDrawer2">取消</a-button>
<a-button class="btn2" @click="updateTest">确定</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>
import {reactive, toRefs} from "vue";
import {message} from "ant-design-vue";
import {
createExamination,
queryExaminationDetailById,
updateExamination,
} from "@/api/indexExam";
import STest from "./SelectTest.vue";
import {ProjectEditTask, RouterEditTask} from "@/api/indexTask";
import {addTempTask} from "../../api/indexTaskadd";
import dayjs from "dayjs";
//import { toDate } from "@/api/method";
export default {
name: "AddTest",
components: {
STest,
},
props: {
addtestVisible: {
type: Boolean,
default: false,
},
EditTestId: {
// 要编辑的考试id
type: Number,
default: null,
},
isactive: {
type: Number,
default: null,
},
routerId: {
type: Number,
default: null,
},
projectId: {
type: Number,
default: null,
},
routerTaskId: {
type: Number,
default: null,
},
chooseStageId: {
type: Number,
default: null,
},
isLevel: {
// 是否是关卡页面触发
type: Number,
default: null,
},
projectTaskId: {
// 要编辑的projectId
type: Number,
default: null,
},
edit: {
//
type: Boolean,
default: null,
},
faceLevel: {
type: Boolean,
default: false,
},
projectTemplateId: {
type: Number,
default: null,
},
testName: {
type: String,
default: null,
},
},
setup(props, ctx) {
const state = reactive({
test: {
examinationName: '',
chooseTime: '',
examinationDuration: '',
passLine: '',
examinationExplain: null,
examinationLimit: null,
showAnswers: 1,
showAnalysis: 1,
scoringModel: 2,
questionArrangement: 4,
},
addLoading: false,
isOuter: 1, // 是否为外部考试
STvisible: false, //选择试卷抽屉
paperId: null, //试卷id 子组件传过来给考试抽屉创建考试信息需要
paperName: "", //试卷名称 子组件传过来给考试抽屉选择试卷后框框用
id: "",
testName: "",
TestName: "",
testObj: {
name: "",
paperId: "",
choosedTime: "",
duration: "",
},
choosedTestList: [
{
value: "提高核心竞争力",
key: 1,
},
],
});
const clearAll = () => {
state.test = {
examinationName: '',
chooseTime: '',
examinationDuration: '',
passLine: '',
examinationExplain: null,
examinationLimit: null,
showAnswers: 1,
showAnalysis: 1,
scoringModel: 2,
questionArrangement: 4,
};
};
const closeDrawer = () => {
state.statechoosedTime = "";
ctx.emit("update:addtestVisible", false);
ctx.emit("update:edit", false);
ctx.emit("update:EditTestId", state.EditTestId);
ctx.emit("update:testName", state.test.examinationName);
console.log("statetestName", state.test.examinationName);
localStorage.setItem("stageId", props.chooseStageId);
localStorage.setItem("chapterId", props.isactive);
state.addLoading = false;
clearAll();
};
const closeDrawer2 = () => {
state.paperName = "";
state.statechoosedTime = "";
ctx.emit("update:edit", false);
ctx.emit("update:addtestVisible", false);
clearAll();
state.addLoading = false;
};
const afterVisibleChange = (bool) => {
console.log("props", props);
if (props.addtestVisible && props.EditTestId && props.EditTestId >0) {
// 该页面显示同时 edit为true 时,发送查询请求,
queryTest();
}
if (bool) {
state.test.showAnswers = 1;
state.test.showAnalysis = 1;
state.test.scoringModel = 2;
state.test.questionArrangement = 4;
}
};
const selectTest = () => {
state.STvisible = true;
};
const delTag = () => {
state.paperId = 0;
state.paperName = "";
};
const queryTest = () => {
queryExaminationDetailById({examinationId: props.EditTestId})
.then((res) => {
state.test = res.data.data;
state.test.showAnswers = Number(state.test.showAnswers);
state.test.showAnalysis = Number(state.test.showAnalysis);
state.test.scoringModel = Number(state.test.scoringModel);
state.test.questionArrangement = Number(
state.test.questionArrangement
);
state.test.chooseTime = [
dayjs(res.data.data.examinationStartTime, "YYYY-MM-DD HH:mm"),
dayjs(res.data.data.examinationEndTime, "YYYY-MM-DD HH:mm"),
];
state.paperName = state.test.examinationTestName;
// state.paperId=dayjs
state.paperId = state.test.examinationTestId;
console.log("querytest", state.test);
})
.catch(() => {
//message.error(`查询失败`);
});
};
const updateTest = () => {
if (!state.test.examinationName) {
message.destroy();
return message.warning("请输入考试名称");
}
if (!state.paperId) {
message.destroy();
return message.warning("请输入选择试卷");
}
if (!state.test.chooseTime) {
message.destroy();
return message.warning("请输入开始结束时间");
}
if (!state.test.examinationDuration) {
message.destroy();
return message.warning("请输入考试时长");
}
if (!state.test.passLine) {
message.destroy();
return message.warning("请输入及格线");
}
state.addLoading = true;
console.log("test", state.test);
// state.test.examinationStartTime = toDate(
// new Date(state.test.chooseTime[0].$d).getTime() / 1000,
// "Y-M-D h:m"
// );
// state.test.examinationEndTime =toDate(
// new Date(state.test.$slotschooseTime[1].$d).getTime() / 1000,
// "Y-M-D h:m"
// );
(state.test.examinationStartTime = dayjs(state.test.chooseTime[0]).format(
"YYYY-MM-DD HH:mm"
)),
(state.test.examinationEndTime = dayjs(state.test.chooseTime[1]).format(
"YYYY-MM-DD HH:mm"
)),
(state.test.examinationPaperId = state.paperId);
//TODO缺少paperName字段
state.test.examinationTestName = state.paperName;
//考试推送
state.test.targetId = 0;
state.test.type = 0;
state.test.chapterId=0;
if(props.isLevel == 1){
state.test.targetId = props.routerId;
state.test.chapterId = props.isactive;
state.test.type = 2;
} else if (props.isLevel == 2) {
state.test.targetId = props.projectId;
state.test.type = 1;
}
if (props.EditTestId > 0) {
// 编辑任务
updateExamination(state.test)
.then(async (res) => {
await updateTask(res);
// closeDrawer();
})
.catch(() => {
message.destroy();
message.error(`编辑失败`);
});
} else {
// 创建任务
createExamination(state.test)
.then(async (res) => {
await updateTask(res);
// closeDrawer();
})
.catch(() => {
message.destroy();
message.error(`创建失败`);
});
}
};
const updateTask = (res) => {
state.EditTestId = res.data.data.examinationId;
if (props.faceLevel) {
state.EditTestId = res.data.data.examinationId;
state.paperName = "";
closeDrawer();
} else {
if (props.isLevel == 1) {
if (!props.isactive) {
message.destroy();
return message.warning("请先选中关卡");
}
let editObj1 = {
chapterId: props.isactive,
duration: res.data.data.examinationDuration,
courseId: res.data.data.examinationId,
name: res.data.data.examinationName,
routerId: props.routerId,
routerTaskId: props.routerTaskId || 0,
type: 5,
};
RouterEditTask(editObj1)
.then(() => {
console.log("props.edit", props.edit);
message.success(`${props.edit ? "编辑" : "新增"}任务成功`);
ctx.emit("changeData", false);
state.paperName = "";
closeDrawer();
})
.catch(() => {
//message.error(`${props.edit ? "编辑" : "新增"}关卡任务失败`);
});
} else if (props.isLevel == 2) {
let editObj = {
courseId: res.data.data.examinationId,
duration: res.data.data.examinationDuration,
name: res.data.data.examinationName,
projectId: props.projectId,
projectTaskId: props.projectTaskId || 0,
stageId: props.chooseStageId || 0,
type: 5,
};
// 新增编辑或新增项目
ProjectEditTask(editObj)
.then(() => {
message.success(`${props.edit ? "编辑" : "新增"}任务成功`);
ctx.emit("changeData", false);
state.paperName = "";
closeDrawer();
})
.catch(() => {
//message.error(`${props.EditTestId ? "编辑" : "新增"}阶段任务失败`);
});
} else if (props.isLevel == 3) {
addTempTask({
courseId: res.data.data.examinationId,
duration: res.data.data.examinationDuration,
name: res.data.data.examinationName,
projectTemplateId: props.projectTemplateId,
projectTaskId: props.projectTaskId || 0,
stageId: props.chooseStageId || 0,
type: 5,
})
.then(() => {
message.success(`${props.edit ? "编辑" : "新增"}任务成功`);
ctx.emit("changeData", false);
state.paperName = "";
closeDrawer();
})
.catch(() => {
//message.error(`${props.EditTestId ? "编辑" : "新增"}阶段任务失败`);
});
}
}
};
const cloradio1 = (value) => {
if (value != "") {
state.showAnswers = "";
}
};
const cloradio2 = (value) => {
if (value != "") {
state.showAnalysis = "";
}
};
const cloradio3 = (value) => {
if (value != "") {
state.scoringModel = "";
}
};
const cloradio4 = (value) => {
if (value != "") {
state.questionArrangement = "";
}
};
const changeOuter = (value) => {
state.isOuter = value;
};
const chooseTest = () => {
};
const closeTag = (removedTag) => {
const tags = state.choosedTestList.filter(
(item) => item.key != removedTag
);
state.choosedTestList = tags;
};
const getData = (value) => {
state.paperId = value.paperId;
state.paperName = value.testName;
state.id = value.id;
//state.testName = value.testName;
console.log("value",value);
};
const range = (start, end) => {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
};
const disabledDate = (current) => {
// Can not select days before today and today
// console.log('1111', dayjs().endOf('day'))
return current && current < dayjs().startOf('day');
};
const disabledDateTime = () => {
return {
disabledHours: () => range(0, 24).splice(4, 20),
disabledMinutes: () => range(30, 60),
disabledSeconds: () => [55, 56],
};
};
return {
afterVisibleChange,
closeDrawer,
closeDrawer2,
selectTest,
cloradio1,
cloradio2,
cloradio3,
cloradio4,
disabledDateTime,
clearAll,
delTag,
// layout,
updateTest,
queryTest,
changeOuter,
chooseTest,
closeTag,
getData,
disabledDate,
...toRefs(state),
};
},
};
</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>