Files
fe-manage/src/components/drawers/AddTest.vue

1078 lines
31 KiB
Vue

<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>
<a-form
v-if="isOuter == 1"
ref="formRef"
name="custom-validation"
:model="formState"
:rules="rules"
v-bind="layout"
@finish="handleFinish"
@validate="handleValidate"
@finishFailed="handleFinishFailed"
>
<div class="contentMain">
<div class="main_left">
<div class="main_item">
<div class="btnbox">
<a-form-item
has-feedback
label="考试名称"
name="examinationName"
>
<a-input
v-model:value="formState.examinationName"
style="width: 424px; height: 32px; margin-left: 35px"
autocomplete="off"
placeholder="请输入考试名称"
show-count :maxlength="50"
/>
</a-form-item>
</div>
</div>
<div class="main_item2">
<a-form-item
has-feedback
label="考试说明"
name="examinationExplain"
><div class="textarea">
<a-textarea
v-model:value="formState.examinationExplain"
placeholder="请输入考试说明"
allow-clear
:rows="6"
style="margin-left: 35px"
show-count :maxlength="200"
/></div>
</a-form-item>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item has-feedback label="选择考试" name="choosedTest">
<a-button
type="primary"
style="width: 100px; margin-left: 35px"
class="outer"
@click.prevent
@click="selectTest()"
>
选择考试
</a-button>
<!-- <a-dropdown>
<a-button
type="primary"
style="width: 100px; margin-left: 35px"
class="outer"
@click.prevent
@click="selectTest()"
>
选择试卷
<DownOutlined />
</a-button>
<template #overlay>
<a-menu>
<a-menu-item
v-for="item in formState.choosedTest"
:key="item.key"
>
<a @click="chooseTest(item.key - 1)">{{
item.value
}}</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown> -->
<a-tag v-if="paperName != ''" closable color="processing" @close="delTag">
<span style="font-size:14px;line-height: 33px;">删除考试</span>
</a-tag>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item has-feedback label="考试时间" name="choosedTime">
<a-range-picker
v-model:value="formState.choosedTime"
format="YYYY-MM-DD"
style="width: 424px; margin-left: 35px"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item
has-feedback
label="考试时长"
name="examinationDuration"
>
<a-input
v-model:value="formState.examinationDuration"
type="number"
style="width: 388px; height: 32px; margin-left: 35px"
/>
</a-form-item>
<span style="transform: translateY(-50%)">分钟</span>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<span style="margin-right: 43px">考试限制</span>
<a-form-item
has-feedback
label="允许重复考试"
name="examinationLimit"
>
<a-input-number
:min="-1"
:precision="0"
type="number"
v-model:value="formState.examinationLimit"
style="
width: 88px;
height: 32px;
border-radius: 8px;
overflow: hidden;
"
/>
<span style="margin-left: 8px"></span>
<span style="margin-left: 24px; color: #999999"
>-1表示无限制</span
>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item has-feedback label="显示答案" name="showAnswers">
<a-radio-group
style="margin-left: 35px; margin-right: 12px"
v-model:value="formState.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>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item has-feedback label="显示解析" name="showAnalysis">
<a-radio-group
style="margin-left: 35px; margin-right: 12px"
v-model:value="formState.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>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item has-feedback label="评分模式" name="scoringModel">
<a-radio-group
style="margin-left: 35px; margin-right: 12px"
v-model:value="formState.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>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item has-feedback label="及格线" name="passLine">
<a-input
v-model:value="formState.passLine"
type="number"
style="width: 88px; height: 32px; margin-left: 35px"
/>
</a-form-item>
<span style="margin-left: 8px"></span>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item
has-feedback
label="作业要求"
name="questionArrangement"
>
<a-radio-group
style="margin-right: 12px"
v-model:value="formState.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-group>
</a-form-item>
</div>
</div>
</div>
</div>
<div class="main_btns">
<a-button class="btn1" @click="closeDrawer2">取消</a-button>
<a-button class="btn2" html-type="submit">确定</a-button>
</div>
</a-form>
<a-form
v-else
ref="formRef"
name="custom-validation"
:model="formState"
:rules="rules"
v-bind="layout"
@finish="handleFinish"
@validate="handleValidate"
@finishFailed="handleFinishFailed"
>
<div class="contentMain">
<div class="main_left">
<div class="main_item">
<div class="btnbox">
<a-form-item
has-feedback
label="考试名称"
name="examinationName"
>
<a-input
v-model:value="formState.examinationName"
style="width: 424px; height: 32px; margin-left: 35px"
autocomplete="off"
placeholder="请输入考试名称"
show-count :maxlength="50"
/>
</a-form-item>
</div>
</div>
<div class="main_item">
<div class="btnbox">
<a-form-item
has-feedback
label="数据来源"
name="examinationName"
>
<a-input
v-model:value="请输入数据来源"
style="width: 424px; height: 32px; margin-left: 35px"
autocomplete="off"
placeholder="数据来源"
show-count :maxlength="50"
/>
</a-form-item>
</div>
</div>
<div class="main_item2">
<a-form-item
has-feedback
label="考试说明"
name="examinationExplain"
>
<div class="textarea">
<a-textarea
v-model:value="formState.examinationExplain"
placeholder="请输入考试说明"
allow-clear
:rows="6"
style="margin-left: 35px"
show-count :maxlength="200"
/></div>
</a-form-item>
</div>
</div>
</div>
<div class="main_btns">
<a-button class="btn1" @click="closeDrawer2">取消</a-button>
<a-button class="btn2" html-type="submit">确定</a-button>
</div>
</a-form>
</div>
<!-- 加载动画 -->
<div class="aeLoading" :style="{ display: addLoading ? 'flex' : 'none' }">
<a-spin :spinning="addLoading" tip="添加中..." />
</div>
<!-- 选择考试抽屉 -->
<s-test v-model:STvisible="STvisible" @getSTData="getData" />
</a-drawer>
</template>
<script>
import { reactive, ref, 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";
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,
},
},
setup(props, ctx) {
const formState = reactive({
examinationName: "",
examinationDuration: 0,
examinationLimit: "",
passLine: null,
examinationEndTime: "",
examinationExplain: "",
questionArrangement: 1,
scoringModel: 2,
showAnalysis: 2,
showAnswers: 2,
choosedTime: "",
paperName: "",
choosedTest: [
{
key: 1,
value: "提高核心竞争力",
},
{
key: 2,
value: "增强创新意识感",
},
{
key: 3,
value: "巩固基础求发展",
},
],
});
const state = reactive({
addLoading: false,
isOuter: 1, // 是否为外部考试
STvisible: false, //选择试卷抽屉
paperId: null, //试卷id 子组件传过来给考试抽屉创建考试信息需要
paperName: "", //试卷名称 子组件传过来给考试抽屉选择试卷后框框用
id: "",
testName: "",
choosedTestList: [
{
value: "提高核心竞争力",
key: 1,
},
],
});
const formRef = ref();
let checkExaminationName = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入考试名称");
}
};
/*
let checkChoosedTest = async (_rule, value) => {
if (!value) {
return Promise.reject("请选择考试");
}
};*/
let checkChoosedTime = async (_rule, value) => {
if (!value.length) {
return Promise.reject("请选择时间");
}
};
let checkExaminationDuration = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入考试时长");
}
};
let checkLimit = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入考试限制");
}
};
let checkShowAnswers = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入作业名称");
}
};
let checkShowAnalysis = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入作业名称");
}
};
let checkScoringModel = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入作业名称");
}
};
let checkQuestionArrangement = async (_rule, value) => {
if (!value) {
return Promise.reject("请输入作业名称");
}
};
const rules = {
examinationName: [
{
required: true,
validator: checkExaminationName,
trigger: "change",
},
],
/*
choosedTest: [
{
required: true,
validator: checkChoosedTest,
trigger: "change",
},
],*/
choosedTime: [
{
required: true,
validator: checkChoosedTime,
trigger: "change",
},
],
examinationDuration: [
{
required: true,
validator: checkExaminationDuration,
trigger: "change",
},
],
limit: [
{
required: true,
validator: checkLimit,
trigger: "change",
},
],
showAnswers: [
{
validator: checkShowAnswers,
trigger: "change",
},
],
showAnalysis: [
{
validator: checkShowAnalysis,
trigger: "change",
},
],
scoringModel: [
{
validator: checkScoringModel,
trigger: "change",
},
],
questionArrangement: [
{
validator: checkQuestionArrangement,
trigger: "change",
},
],
};
const options1 = ref([
{
label: "math",
value: "math",
},
{
label: "eng",
value: "eng",
},
]);
const handleFinish = () => {
updateTest();
};
const handleFinishFailed = () => {
message.error("handleFinishFailed");
};
const resetForm = () => {
formRef.value.resetFields();
state.paperName = "";
state.paperId = null;
state.id = "";
state.testName = "";
};
const handleValidate = (...args) => {
console.log(args);
};
const closeDrawer = () => {
formState.choosedTime = "";
ctx.emit("update:addtestVisible", false);
ctx.emit("update:edit", false);
ctx.emit("update:EditTestId", state.EditTestId);
localStorage.setItem("stageId", props.chooseStageId);
localStorage.setItem("chapterId", props.isactive);
resetForm();
};
const closeDrawer2 = () => {
formState.choosedTime = "";
ctx.emit("update:addtestVisible", false);
resetForm();
};
const afterVisibleChange = () => {
if (props.addtestVisible && props.edit) {
// 该页面显示同时 edit为true 时,发送查询请求,
queryTest();
}
};
const selectTest = () => {
state.STvisible = true;
};
const delTag = () => {
state.paperId = 0;
state.paperName = "";
};
const queryTest = () => {
// state.addLoading = true;
queryExaminationDetailById({ examinationId: props.EditTestId })
.then((res) => {
formState.examinationName = res.data.data.examinationName;
formState.workRequirement = res.data.data.workRequirement;
formState.examinationDuration = res.data.data.examinationDuration;
formState.examinationLimit =
Number(res.data.data.examinationLimit) || -1;
formState.passLine = res.data.data.passLine;
formState.examinationExplain = res.data.data.examinationExplain;
formState.questionArrangement =
Number(res.data.data.questionArrangement) || 1;
formState.scoringModel = Number(res.data.data.scoringModel) || 1;
formState.showAnalysis = Number(res.data.data.showAnalysis) || 1;
formState.showAnswers = Number(res.data.data.showAnswers) || 1;
formState.papaerName = res.data.data.examinationTestName;
state.paperName = res.data.data.examinationTestName;
if (
res.data.data.examinationEndTime &&
res.data.data.examinationStartTime
) {
formState.choosedTime = [
dayjs(res.data.data.examinationStartTime, "YYYY-MM-DD"),
dayjs(res.data.data.examinationEndTime, "YYYY-MM-DD"),
];
state.addLoading = false;
} else {
formState.choosedTime = [];
}
})
.catch(() => {
//message.error(`查询失败`);
});
};
const updateTest = () => {
//state.addLoading = true;updateTask
let obj = {
examinationDuration: formState.examinationDuration,
examinationEndTime: dayjs(formState.choosedTime[1]).format(
"YYYY-MM-DD"
),
examinationExplain: formState.examinationExplain,
examinationId: props.edit ? props.EditTestId : 0,
examinationLimit: formState.examinationLimit,
examinationName: formState.examinationName,
examinationPaperId: 0,
// examinationPaperName: formState.choosedTest,
examinationStartTime: dayjs(formState.choosedTime[0]).format(
"YYYY-MM-DD"
),
passLine: formState.passLine,
questionArrangement: formState.questionArrangement,
scoringModel: formState.scoringModel,
showAnalysis: formState.showAnalysis,
showAnswers: formState.showAnswers,
examinationTestId: state.paperId,
examinationTestName: state.paperName,
};
if(!(state.paperId >0)){
message.destroy();
return message.error("请选择考试");
}
if (props.edit) {
// 编辑任务
updateExamination(obj)
.then(async (res) => {
await updateTask(res);
closeDrawer();
})
.catch(() => {
message.destroy();
message.error(`编辑失败`);
});
} else {
// 创建任务
createExamination(obj)
.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;
} else {
if (props.isLevel == 1) {
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(() => {
//message.success(`${props.edit ? "编辑" : "新增"}关卡任务成功`);
ctx.emit("changeData", false);
state.addLoading = false;
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.EditTestId ? "编辑" : "新增"}阶段任务成功`);
ctx.emit("changeData", false);
})
.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.EditTestId ? "编辑" : "新增"}阶段任务成功`);
ctx.emit("changeData", false);
})
.catch(() => {
//message.error(`${props.EditTestId ? "编辑" : "新增"}阶段任务失败`);
});
}
}
};
const cloradio1 = (value) => {
if (value != "") {
formState.showAnswers = "";
}
};
const cloradio2 = (value) => {
if (value != "") {
formState.showAnalysis = "";
}
};
const cloradio3 = (value) => {
if (value != "") {
formState.scoringModel = "";
}
};
const cloradio4 = (value) => {
if (value != "") {
formState.questionArrangement = "";
}
};
const changeOuter = (value) => {
state.isOuter = value;
};
const chooseTest = (index) => {
for (let i in state.choosedTestList) {
if (state.choosedTestList[i].key == formState.choosedTest[index].key)
return;
}
state.choosedTestList.push(formState.choosedTest[index]);
};
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;
};
return {
formState,
afterVisibleChange,
closeDrawer,
closeDrawer2,
selectTest,
cloradio1,
cloradio2,
cloradio3,
cloradio4,
options1,
handleFinish,
handleFinishFailed,
resetForm,
handleValidate,
formRef,
delTag,
// layout,
rules,
updateTest,
queryTest,
changeOuter,
chooseTest,
closeTag,
getData,
...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: 423px;
.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;
margin-top: 10px;
margin-bottom: 24px;
.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_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>