pull/1/head
z 2024-01-20 17:18:25 +08:00
parent 9b837c85c9
commit ec267cc310
8 changed files with 1115 additions and 48 deletions

View File

@ -974,6 +974,33 @@ export default [
},
],
},
{
path: "/online_learn_exam/paper",
meta: { title: "试卷管理", isSubMenu: false },
component: "children",
children: [
{
path: "/online_learn_exam/paper",
component: "online_learn_exam/paper/index",
},
{
path: "/online_learn_exam/paper/view",
meta: {
title: "查看",
activeMenu: "/online_learn_exam/paper",
},
component: "online_learn_exam/paper/view",
},
{
path: "/online_learn_exam/paper/add",
meta: {
title: "新增",
activeMenu: "/online_learn_exam/paper",
},
component: "online_learn_exam/paper/add",
},
],
},
],
},
{

View File

@ -40,3 +40,16 @@ export const setCurriculumAdd = (params) => upload("/curriculum/add", params); /
export const setCurriculumEdit = (params) => upload("/curriculum/edit", params); // 课程管理修改
export const setCurriculumInherit = (params) =>
upload("/curriculum/inherit", params); // 课程管理继承
export const getPaperList = (params) =>
post("/stageexampaperinput/list", params); // 试卷管理列表
export const getPaperView = (params) =>
post("/stageexampaperinput/goEdit", params); // 试卷管理查看
export const setPaperDelete = (params) =>
post("/stageexampaperinput/delete", params); // 试卷管理删除
export const setPaperState = (params) =>
post("/stageexampaperinput/editState", params); // 试卷管理启用禁用
export const getPaperQuestionsNumber = (params) =>
post("/question/getCountByQuestionType", params); // 试卷管理可选题数
export const setPaperAdd = (params) => post("/stageexampaperinput/add", params); // 试卷管理添加
export const getPaperQuestionsList = (params) =>
post("/question/getQuestionList", params); // 试卷管理可选题列表

View File

@ -0,0 +1,382 @@
<template>
<layout-card>
<el-form
ref="formRef"
:rules="rules"
:model="data.form"
label-width="200px"
>
<el-row>
<el-col :span="24">
<el-form-item label="试卷名称" prop="EXAMNAME">
<el-input v-model="data.form.EXAMNAME" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="培训行业类型" prop="TRAINTYPE">
<layout-learning-train-type
v-model="data.form.TRAINTYPE"
type="industry"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="岗位培训类型" prop="POSTTYPE">
<layout-learning-train-type
v-model="data.form.POSTTYPE"
type="post"
@update:model-value="fnGetPaperQuestionsNumber"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="总分数" prop="EXAMSCORE">
<el-input-number v-model="data.form.EXAMSCORE" :min="0" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合格分数" prop="PASSSCORE">
<el-input-number :min="0" v-model="data.form.PASSSCORE" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="状态">
<el-switch
v-model="data.form.automationFlag"
active-value="0"
inactive-value="1"
active-text="自动生成试卷"
inactive-text="手动生成试卷"
@change="
data.testPaper = { danxuan: [], duoxuan: [], panduan: [] }
"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="`单选题数(可选题数:${data.danxuanCount})`"
prop="DANYUANTICOUNT"
>
<div style="flex: 1; display: flex">
<el-input-number
:min="0"
:max="data.danxuanCount"
v-model="data.form.DANYUANTICOUNT"
/>
<el-button
class="ml-10"
v-if="data.form.automationFlag === '1'"
type="primary"
@click="fnSelectTopic('1')"
>
选择题目
</el-button>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单选分数" prop="DANXUANTINUMBER">
<el-input-number :min="0" v-model="data.form.DANXUANTINUMBER" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="`多选题数(可选题数:${data.duoxuanCount})`"
prop="DUOXUANTICOUNT"
>
<div style="flex: 1; display: flex">
<el-input-number
:min="0"
:max="data.duoxuanCount"
v-model="data.form.DUOXUANTICOUNT"
/>
<el-button
class="ml-10"
v-if="data.form.automationFlag === '1'"
type="primary"
@click="fnSelectTopic('2')"
>
选择题目
</el-button>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="多选分数" prop="DUOXUANTINUMBER">
<el-input-number :min="0" v-model="data.form.DUOXUANTINUMBER" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="`判断题数(可选题数:${data.panduanCount})`"
prop="PANDUITICOUNT"
>
<div style="flex: 1; display: flex">
<el-input-number
:min="0"
:max="data.panduanCount"
v-model="data.form.PANDUITICOUNT"
/>
<el-button
class="ml-10"
v-if="data.form.automationFlag === '1'"
type="primary"
@click="fnSelectTopic('3')"
>
选择题目
</el-button>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="判断分数" prop="PANDUITINUMBER">
<el-input-number :min="0" v-model="data.form.PANDUITINUMBER" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="tc mt-10">
<el-button
v-if="data.form.automationFlag === '1'"
:disabled="
data.testPaper.danxuan.length === 0 &&
data.testPaper.duoxuan.length === 0 &&
data.testPaper.panduan.length === 0
"
type="primary"
@click="data.viewPaperDialogVisible = true"
>
查看试卷
</el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</div>
<select-topic
v-model:visible="data.selectTopicDialog.visible"
:select-list="data.selectTopicDialog.selectList"
:post-type="data.form.POSTTYPE"
:question-type="data.selectTopicDialog.QUESTIONTYPE"
:max-count="data.selectTopicDialog.maxCount"
@submit="fnSelectTopicDialogSubmit"
/>
<view-paper
:test-paper="data.testPaper"
v-model:visible="data.viewPaperDialogVisible"
/>
</layout-card>
</template>
<script setup>
import { reactive, ref } from "vue";
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
import { useUserStore } from "@/pinia/user.js";
import { debounce } from "throttle-debounce";
import {
getPaperQuestionsNumber,
setPaperAdd,
} from "@/request/online_learn_exam.js";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import SelectTopic from "./components/select_topic.vue";
import ViewPaper from "./components/view_paper.vue";
const userStore = useUserStore();
const router = useRouter();
const rules = {
EXAMNAME: [{ required: true, message: "试卷名称不能为空", trigger: "blur" }],
POSTTYPE: [
{ required: true, message: "岗位培训类型不能为空", trigger: "change" },
],
EXAMSCORE: [{ required: true, message: "总分数不能为空", trigger: "blur" }],
PASSSCORE: [{ required: true, message: "合格分数不能为空", trigger: "blur" }],
DUOXUANTICOUNT: [
{ required: true, message: "多选题数不能为空", trigger: "blur" },
],
DUOXUANTINUMBER: [
{ required: true, message: "多选分数不能为空", trigger: "blur" },
],
DANYUANTICOUNT: [
{ required: true, message: "单选题数不能为空", trigger: "blur" },
],
DANXUANTINUMBER: [
{ required: true, message: "单选分数不能为空", trigger: "blur" },
],
PANDUITICOUNT: [
{ required: true, message: "判断题数不能为空", trigger: "blur" },
],
PANDUITINUMBER: [
{ required: true, message: "判断分数不能为空", trigger: "blur" },
],
};
const formRef = ref(null);
const data = reactive({
form: {
EXAMNAME: "",
TRAINTYPE: userStore.getUserInfo.CORP_TRAINTYPE,
POSTTYPE: "",
EXAMSCORE: 100,
PASSSCORE: 0,
automationFlag: "0",
DANYUANTICOUNT: 0,
DANXUANTINUMBER: 0,
DUOXUANTICOUNT: 0,
DUOXUANTINUMBER: 0,
PANDUITICOUNT: 0,
PANDUITINUMBER: 0,
},
danxuanCount: 0,
duoxuanCount: 0,
panduanCount: 0,
testPaper: { danxuan: [], duoxuan: [], panduan: [] },
selectTopicDialog: {
visible: false,
QUESTIONTYPE: "",
selectList: [],
maxCount: 0,
},
viewPaperDialogVisible: false,
});
const fnGetPaperQuestionsNumber = async () => {
data.testPaper = { danxuan: [], duoxuan: [], panduan: [] };
data.danxuanCount = 0;
data.duoxuanCount = 0;
data.panduanCount = 0;
const resData = await getPaperQuestionsNumber({
POSTTYPE: data.form.POSTTYPE,
});
resData.varList.forEach((item) => {
if (item.QUESTIONTYPE === "1") {
data.danxuanCount = item.count;
} else if (item.QUESTIONTYPE === "2") {
data.duoxuanCount = item.count;
} else if (item.QUESTIONTYPE === "3") {
data.panduanCount = item.count;
}
});
};
const fnSelectTopic = (QUESTIONTYPE) => {
const { form, danxuanCount, duoxuanCount, panduanCount } = data;
if (QUESTIONTYPE === "1") {
if (!form.DANYUANTICOUNT) {
ElMessage.warning("请填写题目数量");
return;
}
if (form.DANYUANTICOUNT > danxuanCount) {
ElMessage.warning("题目数量不能大于可选题数");
return;
}
}
if (QUESTIONTYPE === "2") {
if (!form.DUOXUANTICOUNT) {
ElMessage.warning("请填写题目数量");
return;
}
if (form.DUOXUANTICOUNT > duoxuanCount) {
ElMessage.warning("题目数量不能大于可选题数");
return;
}
}
if (QUESTIONTYPE === "3") {
if (!form.PANDUITICOUNT) {
ElMessage.warning("请填写题目数量");
return;
}
if (form.PANDUITICOUNT > panduanCount) {
ElMessage.warning("题目数量不能大于可选题数");
return;
}
}
data.selectTopicDialog.QUESTIONTYPE = QUESTIONTYPE;
let selectList = [];
let maxCount = 0;
if (QUESTIONTYPE === "1") {
selectList = data.testPaper.danxuan;
maxCount = form.DANYUANTICOUNT;
}
if (QUESTIONTYPE === "2") {
selectList = data.testPaper.duoxuan;
maxCount = form.DUOXUANTICOUNT;
}
if (QUESTIONTYPE === "3") {
selectList = data.testPaper.panduan;
maxCount = form.PANDUITICOUNT;
}
data.selectTopicDialog.selectList = selectList;
data.selectTopicDialog.maxCount = maxCount;
data.selectTopicDialog.visible = true;
};
const fnSelectTopicDialogSubmit = (selectList) => {
const { QUESTIONTYPE } = data.selectTopicDialog;
if (QUESTIONTYPE === "1") data.testPaper.danxuan = selectList;
if (QUESTIONTYPE === "2") data.testPaper.duoxuan = selectList;
if (QUESTIONTYPE === "3") data.testPaper.panduan = selectList;
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
const { form, danxuanCount, duoxuanCount, panduanCount, testPaper } = data;
const sumFraction =
form.DANYUANTICOUNT * form.DANXUANTINUMBER +
form.DUOXUANTICOUNT * form.DUOXUANTINUMBER +
form.PANDUITICOUNT * form.PANDUITINUMBER;
if (sumFraction !== form.EXAMSCORE) {
ElMessage.warning("习题分数总计不等于总分数");
return;
}
if (form.PASSSCORE > form.EXAMSCORE) {
ElMessage.warning("总分数不能小于合格分数");
return;
}
if (form.DANYUANTICOUNT > danxuanCount) {
ElMessage.warning("单选习题数量大于可选题数");
return;
}
if (form.DUOXUANTICOUNT > duoxuanCount) {
ElMessage.warning("多选习题数量大于可选题数");
return;
}
if (form.PANDUITICOUNT > panduanCount) {
ElMessage.warning("判断习题数量大于可选题数");
return;
}
if (form.DANYUANTICOUNT && !form.DANXUANTINUMBER) {
ElMessage.warning("单选分数不能为0");
return;
}
if (form.DUOXUANTICOUNT && !form.DUOXUANTINUMBER) {
ElMessage.warning("多选分数不能为0");
return;
}
if (form.PANDUITICOUNT && !form.PANDUITINUMBER) {
ElMessage.warning("判断分数不能为0");
return;
}
if (form.automationFlag === "1") {
if (form.DANYUANTICOUNT !== testPaper.danxuan.length) {
ElMessage.warning("单选题数与已经选择的题数不符");
return;
}
if (form.DUOXUANTICOUNT !== testPaper.duoxuan.length) {
ElMessage.warning("多选题数与已经选择的题数不符");
return;
}
if (form.PANDUITICOUNT !== testPaper.panduan.length) {
ElMessage.warning("判断题数与已经选择的题数不符");
return;
}
}
await setPaperAdd({
...form,
testPaper: JSON.stringify(testPaper),
});
ElMessage.success("保存成功");
router.back();
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,216 @@
<template>
<el-dialog
v-model="visible"
title="选择题目"
append-to-body
:on-close="fnClose"
>
<el-form :model="searchForm" label-width="110px">
<el-row>
<el-col :span="12">
<el-form-item label="题干关键字" prop="KEYWORDS">
<el-input v-model="searchForm.KEYWORDS" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-scrollbar style="height: 500px">
<div class="items mt-20 p-20">
<div
v-for="(item, index) in list"
:key="item.QUESTION_ID"
class="item ptb-20"
>
<el-row :gutter="10">
<el-col :span="20">
<div class="mt-10">
{{ index + 1 }}.
<span v-if="item.QUESTIONTYPE === '1'">()</span>
<span v-if="item.QUESTIONTYPE === '2'">()</span>
<span v-if="item.QUESTIONTYPE === '3'">()</span>
{{ item.QUESTIONDRY }}
</div>
<el-radio-group
v-if="item.QUESTIONTYPE === '1'"
disabled
:model-value="item.ANSWER"
>
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
<el-radio label="C">C.{{ item.OPTIONC }}</el-radio>
<el-radio label="D">D.{{ item.OPTIOND }}</el-radio>
</el-radio-group>
<el-checkbox-group
v-if="item.QUESTIONTYPE === '2'"
disabled
:model-value="item.ANSWER.split('')"
>
<el-checkbox label="A">A.{{ item.OPTIONA }}</el-checkbox>
<el-checkbox label="B">B.{{ item.OPTIONB }}</el-checkbox>
<el-checkbox label="C">C.{{ item.OPTIONC }}</el-checkbox>
<el-checkbox label="D">D.{{ item.OPTIOND }}</el-checkbox>
</el-checkbox-group>
<el-radio-group
v-if="item.QUESTIONTYPE === '3'"
disabled
:model-value="item.ANSWER"
>
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
</el-radio-group>
<div class="mt-10">答案{{ item.ANSWER }}</div>
</el-col>
<el-col :span="2">
<el-button
v-if="!(item.isChoose && item.isChoose === '1')"
type="primary"
@click="fnChoice(item)"
>
选择
</el-button>
<el-button
v-if="item.isChoose && item.isChoose === '1'"
type="success"
@click="fnDeselect(item)"
>
取消选择
</el-button>
</el-col>
</el-row>
</div>
</div>
</el-scrollbar>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { useVModel } from "@vueuse/core";
import { getPaperQuestionsList } from "@/request/online_learn_exam.js";
import useListData from "@/assets/js/useListData.js";
import { ref, watch } from "vue";
import { cloneDeep } from "lodash-es";
import { throttle } from "throttle-debounce";
import { ElMessage } from "element-plus";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
questionType: {
type: String,
required: true,
default: "",
},
postType: {
type: String,
required: true,
default: "",
},
selectList: {
type: Array,
required: true,
default: () => [],
},
maxCount: {
type: Number,
required: true,
default: 0,
},
});
const emits = defineEmits(["update:visible", "submit"]);
const visible = useVModel(props, "visible", emits);
const listAll = ref([]);
const currentSelectList = ref([]);
const { list, fnGetData, searchForm } = useListData(getPaperQuestionsList, {
usePagination: false,
key: "list",
callbackFn: (list) => {
list.forEach((item) => {
for (let j = 0; j < currentSelectList.value.length; j++) {
if (item.QUESTION_ID === currentSelectList.value[j].QUESTION_ID) {
item.isChoose = "1";
break;
}
}
});
listAll.value = cloneDeep(list);
},
});
const fnFilterList = throttle(500, (val) => {
list.value = listAll.value.filter((item) => {
return item.QUESTIONDRY.includes(val);
});
});
const fnGetCurrentIndex = (list, QUESTION_ID) => {
return list.findIndex((item) => item.QUESTION_ID === QUESTION_ID);
};
const fnChoice = (row) => {
if (Number(props.maxCount <= currentSelectList.value.length)) {
ElMessage.warning("最多可以选择" + props.maxCount + "个");
return;
}
list.value[fnGetCurrentIndex(list.value, row.QUESTION_ID)].isChoose = "1";
listAll.value[fnGetCurrentIndex(listAll.value, row.QUESTION_ID)].isChoose =
"1";
currentSelectList.value.push(row);
};
const fnDeselect = (row) => {
list.value[fnGetCurrentIndex(list.value, row.QUESTION_ID)].isChoose = "0";
listAll.value[fnGetCurrentIndex(listAll.value, row.QUESTION_ID)].isChoose =
"0";
currentSelectList.value.splice(
fnGetCurrentIndex(currentSelectList.value, row.QUESTION_ID),
1
);
};
const fnClose = () => {
searchForm.value.KEYWORDS = "";
visible.value = false;
};
const fnSubmit = () => {
emits("submit", currentSelectList.value);
fnClose();
};
watch(
() => searchForm.value.KEYWORDS,
(val) => {
fnFilterList(val);
}
);
watch(
() => props.visible,
(val) => {
if (val) {
currentSelectList.value = cloneDeep(props.selectList);
fnGetData({
POSTTYPE: props.postType,
QUESTIONTYPE: props.questionType,
});
}
}
);
</script>
<style scoped lang="scss">
.items {
border: 1px solid var(--el-border-color);
.item {
border-bottom: 1px dashed #ebeef5;
&:first-child {
padding-top: 0;
}
&:last-child {
border-bottom: none;
}
}
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<el-dialog v-model="visible" title="查看试卷" append-to-body>
<template v-if="testPaper.danxuan.length > 0">
<el-divider content-position="left">单选题</el-divider>
<div class="items mt-20 p-20">
<div
v-for="(item, index) in testPaper.danxuan"
:key="item.QUESTION_ID"
class="item ptb-20"
>
<div class="mb-10">
{{ index + 1 }}. (单选题) {{ item.QUESTIONDRY }}
</div>
<el-radio-group disabled :model-value="item.ANSWER">
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
<el-radio label="C">C.{{ item.OPTIONC }}</el-radio>
<el-radio label="D">D.{{ item.OPTIOND }}</el-radio>
</el-radio-group>
<div class="mt-10">答案{{ item.ANSWER }}</div>
</div>
</div>
</template>
<template v-if="testPaper.duoxuan.length > 0">
<el-divider content-position="left">多选题</el-divider>
<div class="items mt-20 p-20">
<div
v-for="(item, index) in testPaper.duoxuan"
:key="item.QUESTION_ID"
class="item ptb-20"
>
<div class="mb-10">
{{ index + 1 }}.(多选题) {{ item.QUESTIONDRY }}
</div>
<el-checkbox-group disabled :model-value="item.ANSWER.split('')">
<el-checkbox label="A">A.{{ item.OPTIONA }}</el-checkbox>
<el-checkbox label="B">B.{{ item.OPTIONB }}</el-checkbox>
<el-checkbox label="C">C.{{ item.OPTIONC }}</el-checkbox>
<el-checkbox label="D">D.{{ item.OPTIOND }}</el-checkbox>
</el-checkbox-group>
<div class="mt-10">答案{{ item.ANSWER }}</div>
</div>
</div>
</template>
<template v-if="testPaper.panduan.length > 0">
<el-divider content-position="left">判断题</el-divider>
<div class="items mt-20 p-20">
<div
v-for="(item, index) in testPaper.panduan"
:key="item.QUESTION_ID"
class="item ptb-20"
>
<div class="mb-10">
{{ index + 1 }}.(判断题) {{ item.QUESTIONDRY }}
</div>
<el-radio-group disabled :model-value="item.ANSWER">
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
</el-radio-group>
<div class="mt-10">答案{{ item.ANSWER }}</div>
</div>
</div>
</template>
<template #footer>
<el-button @click="visible = false">取消</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { useVModel } from "@vueuse/core";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
testPaper: {
type: Object,
required: true,
default: () => {},
},
});
const emits = defineEmits(["update:visible"]);
const visible = useVModel(props, "visible", emits);
</script>
<style scoped lang="scss">
.items {
border: 1px solid var(--el-border-color);
.item {
border-bottom: 1px dashed #ebeef5;
&:first-child {
padding-top: 0;
}
&:last-child {
border-bottom: none;
}
}
}
</style>

View File

@ -0,0 +1,183 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="80px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="6">
<el-form-item label="试卷名称" prop="KEYWORDS">
<el-input v-model="searchForm.KEYWORDS" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
label="岗位培训类型"
prop="POSTTYPE"
label-width="120px"
>
<layout-learning-train-type
v-model="searchForm.POSTTYPE"
type="post"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="10px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
:data="list"
@get-data="fnGetData"
v-model:pagination="pagination"
>
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column
prop="EXAMNAME"
label="试卷名称"
show-overflow-tooltip
/>
<el-table-column
prop="post_type_name"
label="岗位培训类型"
show-overflow-tooltip
/>
<el-table-column
prop="train_type_name"
label="培训行业类型"
show-overflow-tooltip
/>
<el-table-column label="试题数" width="100">
<template v-slot="{ row }">
{{
Number(row.DUOXUANTICOUNT) +
Number(row.DANYUANTICOUNT) +
Number(row.PANDUITICOUNT)
}}
</template>
</el-table-column>
<el-table-column prop="EXAMSCORE" label="总分数" width="100" />
<el-table-column prop="PASSSCORE" label="及格分数" width="100" />
<el-table-column label="试卷状态" width="100">
<template v-slot="{ row }">
<span v-if="row.STATE === 0"></span>
<span v-if="row.STATE === 1"></span>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/paper/view',
query: { STAGEEXAMPAPERINPUT_ID: row.STAGEEXAMPAPERINPUT_ID },
})
"
>
查看
</el-button>
<el-button
v-if="buttonJurisdiction.edit && row.STATE === 0"
type="primary"
text
link
@click="fnEditState(row.STAGEEXAMPAPERINPUT_ID, 1)"
>
禁用
</el-button>
<el-button
v-if="buttonJurisdiction.edit && row.STATE === 1"
type="primary"
text
link
@click="fnEditState(row.STAGEEXAMPAPERINPUT_ID, 0)"
>
启用
</el-button>
<el-button
v-if="buttonJurisdiction.del && row.EXAMSTATE === '0'"
type="primary"
text
link
@click="fnDelete(row.STAGEEXAMPAPERINPUT_ID)"
>
删除
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="router.push({ path: '/online_learn_exam/paper/add' })"
>
新建试卷
</el-button>
</template>
</layout-table>
</layout-card>
</div>
</template>
<script setup>
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
import useListData from "@/assets/js/useListData.js";
import { serialNumber } from "@/assets/js/utils.js";
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
import {
getPaperList,
setPaperDelete,
setPaperState,
} from "@/request/online_learn_exam.js";
import { debounce } from "throttle-debounce";
import { ElMessage, ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
useListData(getPaperList);
const buttonJurisdiction = await useButtonJurisdiction("stageexampaper");
const fnDelete = debounce(
1000,
async (STAGEEXAMPAPERINPUT_ID) => {
await ElMessageBox.confirm("确定要删除该试卷吗?", { type: "warning" });
await setPaperDelete({ STAGEEXAMPAPERINPUT_ID });
ElMessage.success("删除成功");
fnResetPagination();
},
{ atBegin: true }
);
const fnEditState = debounce(
1000,
async (STAGEEXAMPAPERINPUT_ID, STATE) => {
const message = STATE === 1 ? "禁用" : "启用";
await ElMessageBox.confirm(`确定要${message}吗?`, { type: "warning" });
await setPaperState({
STAGEEXAMPAPERINPUT_ID,
STATE,
});
ElMessage.success(`${message}成功`);
fnResetPagination();
},
{ atBegin: true }
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,131 @@
<template>
<layout-card>
<el-descriptions :column="3" border>
<el-descriptions-item label="试卷名称" :span="3">
{{ data.info.EXAMNAME }}
</el-descriptions-item>
<el-descriptions-item label="试卷总分">
{{ data.info.EXAMSCORE }}
</el-descriptions-item>
<el-descriptions-item label="合格分数" :span="2">
{{ data.info.PASSSCORE }}
</el-descriptions-item>
<el-descriptions-item label="岗位培训类型">
{{ data.info.post_type_name }}
</el-descriptions-item>
<el-descriptions-item label="行业培训类型" :span="2">
{{ data.info.train_type_name }}
</el-descriptions-item>
<el-descriptions-item label="多选题数">
{{ data.info.DUOXUANTICOUNT }}
</el-descriptions-item>
<el-descriptions-item label="多选分数">
{{ data.info.DUOXUANTINUMBER }}
</el-descriptions-item>
<el-descriptions-item label="多选总分数">
{{ data.info.DUOXUANTINUMBER * data.info.DUOXUANTICOUNT }}
</el-descriptions-item>
<el-descriptions-item label="单选题数">
{{ data.info.DANYUANTICOUNT }}
</el-descriptions-item>
<el-descriptions-item label="单选分数">
{{ data.info.DANXUANTINUMBER }}
</el-descriptions-item>
<el-descriptions-item label="单选总分数">
{{ data.info.DANXUANTINUMBER * data.info.DANYUANTICOUNT }}
</el-descriptions-item>
<el-descriptions-item label="判断题数">
{{ data.info.PANDUITICOUNT }}
</el-descriptions-item>
<el-descriptions-item label="判断分数">
{{ data.info.PANDUITINUMBER }}
</el-descriptions-item>
<el-descriptions-item label="判断总分数">
{{ data.info.PANDUITINUMBER * data.info.PANDUITICOUNT }}
</el-descriptions-item>
</el-descriptions>
<div class="items mt-20 p-20">
<div
v-for="(row, index) in data.questionList"
:key="row.QUESTION_ID"
class="item ptb-20"
>
<div class="mt-10">
{{ index + 1 }}.
<span v-if="row.QUESTIONTYPE === '1'"> () </span>
<span v-if="row.QUESTIONTYPE === '2'"> () </span>
<span v-if="row.QUESTIONTYPE === '3'"> () </span>
{{ row.QUESTIONDRY }}
</div>
<div class="mt-10 ml-30">
<el-radio-group
v-if="row.QUESTIONTYPE === '1'"
disabled
:model-value="row.ANSWER"
>
<el-radio label="A">A.{{ row.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ row.OPTIONB }}</el-radio>
<el-radio label="C">C.{{ row.OPTIONC }}</el-radio>
<el-radio label="D">D.{{ row.OPTIOND }}</el-radio>
</el-radio-group>
<el-checkbox-group
v-if="row.QUESTIONTYPE === '2'"
disabled
:model-value="row.ANSWER.split('')"
>
<el-checkbox label="A">A.{{ row.OPTIONA }}</el-checkbox>
<el-checkbox label="B">B.{{ row.OPTIONB }}</el-checkbox>
<el-checkbox label="C">C.{{ row.OPTIONC }}</el-checkbox>
<el-checkbox label="D">D.{{ row.OPTIOND }}</el-checkbox>
</el-checkbox-group>
<el-radio-group
v-if="row.QUESTIONTYPE === '3'"
disabled
:model-value="row.ANSWER"
>
<el-radio label="A">A.{{ row.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ row.OPTIONB }}</el-radio>
</el-radio-group>
</div>
<div class="mt-10">答案{{ row.ANSWER }}</div>
</div>
</div>
</layout-card>
</template>
<script setup>
import { reactive } from "vue";
import { getPaperView } from "@/request/online_learn_exam.js";
import { useRoute } from "vue-router";
const route = useRoute();
const { STAGEEXAMPAPERINPUT_ID } = route.query;
const data = reactive({
info: {},
questionList: [],
});
const fnGetData = async () => {
const resData = await getPaperView({ STAGEEXAMPAPERINPUT_ID });
data.info = resData.pd;
data.questionList = resData.inputQue;
};
fnGetData();
</script>
<style scoped lang="scss">
.items {
border: 1px solid var(--el-border-color);
.item {
border-bottom: 1px dashed #ebeef5;
&:first-child {
padding-top: 0;
}
&:last-child {
border-bottom: none;
}
}
}
</style>

View File

@ -35,53 +35,51 @@
{{ data.info.PANDUITINUMBER }}
</el-descriptions-item>
</el-descriptions>
<div
v-for="(row, index) in [
...data.questionList,
...data.questionList,
...data.questionList,
]"
:key="row.QUESTION_ID"
class="item ptb-20"
>
<div class="mt-20">
{{ index + 1 }}.
<span v-if="row.QUESTIONTYPE === '1'"> () </span>
<span v-if="row.QUESTIONTYPE === '2'"> () </span>
<span v-if="row.QUESTIONTYPE === '3'"> () </span>
{{ row.QUESTIONDRY }}
<div class="items mt-20 p-20">
<div
v-for="(row, index) in data.questionList"
:key="row.QUESTION_ID"
class="item ptb-20"
>
<div class="mt-10">
{{ index + 1 }}.
<span v-if="row.QUESTIONTYPE === '1'"> () </span>
<span v-if="row.QUESTIONTYPE === '2'"> () </span>
<span v-if="row.QUESTIONTYPE === '3'"> () </span>
{{ row.QUESTIONDRY }}
</div>
<div class="mt-10 ml-30">
<el-radio-group
v-if="row.QUESTIONTYPE === '1'"
disabled
:model-value="row.ANSWER"
>
<el-radio label="A">A.{{ row.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ row.OPTIONB }}</el-radio>
<el-radio label="C">C.{{ row.OPTIONC }}</el-radio>
<el-radio label="D">D.{{ row.OPTIOND }}</el-radio>
</el-radio-group>
<el-checkbox-group
v-if="row.QUESTIONTYPE === '2'"
disabled
:model-value="row.ANSWER.split('')"
>
<el-checkbox label="A">A.{{ row.OPTIONA }}</el-checkbox>
<el-checkbox label="B">B.{{ row.OPTIONB }}</el-checkbox>
<el-checkbox label="C">C.{{ row.OPTIONC }}</el-checkbox>
<el-checkbox label="D">D.{{ row.OPTIOND }}</el-checkbox>
</el-checkbox-group>
<el-radio-group
v-if="row.QUESTIONTYPE === '3'"
disabled
:model-value="row.ANSWER"
>
<el-radio label="A">A.{{ row.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ row.OPTIONB }}</el-radio>
</el-radio-group>
</div>
<div class="mt-10">答案{{ row.ANSWER }}</div>
</div>
<div class="mt-10 ml-30">
<el-radio-group
v-if="row.QUESTIONTYPE === '1'"
:disabled="true"
v-model="row.ANSWER"
>
<el-radio label="A">A.{{ row.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ row.OPTIONB }}</el-radio>
<el-radio label="C">C.{{ row.OPTIONC }}</el-radio>
<el-radio label="D">D.{{ row.OPTIOND }}</el-radio>
</el-radio-group>
<el-checkbox-group
v-if="row.QUESTIONTYPE === '2'"
:disabled="true"
:model-value="row.ANSWER.split('')"
>
<el-checkbox label="A">A.{{ row.OPTIONA }}</el-checkbox>
<el-checkbox label="B">B.{{ row.OPTIONB }}</el-checkbox>
<el-checkbox label="C">C.{{ row.OPTIONC }}</el-checkbox>
<el-checkbox label="D">D.{{ row.OPTIOND }}</el-checkbox>
</el-checkbox-group>
<el-radio-group
v-if="row.QUESTIONTYPE === '3'"
:disabled="true"
v-model="row.ANSWER"
>
<el-radio label="A">A.{{ row.OPTIONA }}</el-radio>
<el-radio label="B">B.{{ row.OPTIONB }}</el-radio>
</el-radio-group>
</div>
<div class="mt-10">答案{{ row.ANSWER }}</div>
</div>
</layout-card>
</template>
@ -108,7 +106,19 @@ fnGetData();
</script>
<style scoped lang="scss">
.item {
border-bottom: 1px dashed #ebeef5;
.items {
border: 1px solid var(--el-border-color);
.item {
border-bottom: 1px dashed #ebeef5;
&:first-child {
padding-top: 0;
}
&:last-child {
border-bottom: none;
}
}
}
</style>