forked from integrated_whb/integrated_whb_vue
dev
parent
3213c25bc1
commit
7b110927c4
2
.env
2
.env
|
@ -1,4 +1,4 @@
|
|||
VITE_BASE_URL=http://192.168.0.49:8093/
|
||||
VITE_BASE_URL=http://192.168.0.55:8093/
|
||||
VITE_PROXY=/api/
|
||||
VITE_FILE_URL=https://file.zcloudchina.com/YTHFile
|
||||
VITE_TEMPLATE_URL=https://qaaq.qhdsafety.com/file/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"axios": "^1.6.3",
|
||||
"dayjs": "^1.11.10",
|
||||
"echarts": "^5.4.3",
|
||||
"element-plus": "^2.4.4",
|
||||
"element-plus": "^2.6.1",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jspdf": "^2.5.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
|
|
@ -46,6 +46,33 @@ export const getClassManagementStudentExamRecordsList = (params) =>
|
|||
post("/stageexam/list", params); // 班级管理学员考试记录列表
|
||||
export const getClassManagementStudentExamRecordsView = (params) =>
|
||||
post("/stageexam/findExam", params); // 班级管理学员考试记录查看
|
||||
|
||||
export const getTrainingProgressList = (params) =>
|
||||
post("/student/studentList", params); // 查询进度列表
|
||||
|
||||
export const getTrainingProgressListExportStudentRecords = (params) =>
|
||||
post("/student/derivedRecord", params); // 导出学员信息
|
||||
|
||||
export const getExamdraftList = (params) =>
|
||||
post("/stageexampaperCache/list", params); // 试卷草稿管理列表
|
||||
|
||||
export const setpaperQuestionCacheQuestionsAdd = (params) =>
|
||||
post("/paperQuestionCache/add", params); // 草稿试卷管理试题新增
|
||||
|
||||
export const setpaperQuestionCacheQuestionsEdit = (params) =>
|
||||
post("/paperQuestionCache/edit", params); // 草稿试卷管理试题修改
|
||||
|
||||
export const setpaperQuestionCacheDelete = (params) =>
|
||||
post("/paperQuestionCache/delete", params); // 草稿试卷管理试题删除
|
||||
|
||||
export const setstageexampaperCacheEdit = (params) =>
|
||||
post("/stageexampaperCache/edit", params); // 草稿试卷管理保存修改
|
||||
|
||||
export const setstageexampaperCacheDelete = (params) =>
|
||||
post("/stageexampaperCache/delete", params); // 草稿试卷管理保存修改
|
||||
|
||||
export const setstageexampaperCacheformal = (params) =>
|
||||
post("/stageexampaperCache/convertStageexam", params); // 草稿试卷管理保存修改
|
||||
export const getClassManagementCurriculumList = (params) =>
|
||||
post("/classCurriculum/list", params); // 班级管理课程列表
|
||||
export const setClassManagementCurriculumDelete = (params) =>
|
||||
|
|
|
@ -24,3 +24,9 @@ export const getExamPaperManagementView = (params) =>
|
|||
post("/stageexampaperinput/goEdit", params); // 试卷管理查看
|
||||
export const getExamPaperManagementTestQuestions = (params) =>
|
||||
post("/paperQuestion/listForInherit", params); // 试卷管理试题
|
||||
|
||||
export const getpaperQuestionCacheQuestions = (params) =>
|
||||
post("/paperQuestionCache/list", params); // 试卷草稿管理试题
|
||||
|
||||
export const getStagexampaperCacheView = (params) =>
|
||||
post("/stageexampaperCache/goEdit", params); // 试卷管理查看
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'add' ? '新增' : '修改'"
|
||||
@close="fnClose"
|
||||
@open="fnQuestionTypeChange"
|
||||
>
|
||||
<el-form ref="formRef" :rules="rules" :model="form" label-width="110px">
|
||||
<el-form-item label="试题类型" prop="QUESTIONTYPE">
|
||||
<el-select v-model="form.QUESTIONTYPE" @change="fnQuestionTypeChange">
|
||||
<el-option
|
||||
v-for="item in questionTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="题干" prop="QUESTIONDRY">
|
||||
<el-input
|
||||
v-model="form.QUESTIONDRY"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
<template v-if="form.QUESTIONTYPE !== '3' && form.QUESTIONTYPE !== '4'">
|
||||
<el-form-item label="选项A" prop="OPTIONA">
|
||||
<el-input v-model="form.OPTIONA" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选项B" prop="OPTIONB">
|
||||
<el-input v-model="form.OPTIONB" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选项C" prop="OPTIONC">
|
||||
<el-input v-model="form.OPTIONC" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选项D" prop="OPTIOND">
|
||||
<el-input v-model="form.OPTIOND" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item label="答案" prop="ANSWER">
|
||||
<el-select v-model="form.ANSWER">
|
||||
<el-option
|
||||
v-for="item in answerOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="分值" prop="SCORE">
|
||||
<el-input-number v-model="form.SCORE" />
|
||||
</el-form-item>
|
||||
<el-form-item label="试题标签" prop="LABEL_TYPE">
|
||||
<el-select v-model="form.LABEL_TYPE">
|
||||
<el-option
|
||||
v-for="item in testQuestionLabels"
|
||||
:key="item.DICTIONARIES_ID"
|
||||
:label="item.NAME"
|
||||
:value="item.DICTIONARIES_ID"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联课件名称" prop="VIDEOCOURSEWARE_ID">
|
||||
<el-select-v2
|
||||
v-model="form.VIDEOCOURSEWARE_ID"
|
||||
:options="associatedCoursewareName"
|
||||
filterable
|
||||
:props="{ label: 'COURSEWARENAME', value: 'VIDEOCOURSEWARE_ID' }"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="答案解析" prop="DESCR">
|
||||
<el-input
|
||||
v-model="form.DESCR"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import { nextTick, ref } from "vue";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { layoutFnGetTestQuestionLabels } from "@/assets/js/data_dictionary.js";
|
||||
import {
|
||||
getAssociatedCoursewareNameList,
|
||||
setpaperQuestionCacheQuestionsAdd,
|
||||
setpaperQuestionCacheQuestionsEdit,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
|
||||
const questionTypeOptions = [
|
||||
{ value: "1", label: "单选题" },
|
||||
{ value: "2", label: "多选题" },
|
||||
{ value: "3", label: "判断题" },
|
||||
];
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
isInherit: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits([
|
||||
"update:visible",
|
||||
"update:form",
|
||||
"get-data",
|
||||
"confirm",
|
||||
]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const formRef = ref(null);
|
||||
const answerOptions = ref([]);
|
||||
const associatedCoursewareName = ref([]);
|
||||
const rules = {
|
||||
QUESTIONTYPE: [
|
||||
{ required: true, message: "请选择试题类型", trigger: "change" },
|
||||
],
|
||||
QUESTIONDRY: [{ required: true, message: "请输入题干", trigger: "blur" }],
|
||||
OPTIONA: [{ required: true, message: "请输入选项A", trigger: "blur" }],
|
||||
OPTIONB: [{ required: true, message: "请输入选项B", trigger: "blur" }],
|
||||
OPTIONC: [{ required: true, message: "请输入选项C", trigger: "blur" }],
|
||||
OPTIOND: [{ required: true, message: "请输入选项D", trigger: "blur" }],
|
||||
ANSWER: [{ required: true, message: "请选择答案", trigger: "change" }],
|
||||
SCORE: [{ required: true, message: "请输入分值", trigger: "blur" }],
|
||||
LABEL_TYPE: [
|
||||
{ required: true, message: "请选择试题标签", trigger: "change" },
|
||||
],
|
||||
VIDEOCOURSEWARE_ID: [
|
||||
{ required: true, message: "请选择关联课件名称", trigger: "change" },
|
||||
],
|
||||
};
|
||||
const testQuestionLabels = await layoutFnGetTestQuestionLabels();
|
||||
const fnGetAssociatedCoursewareNameList = async () => {
|
||||
const resData = await getAssociatedCoursewareNameList();
|
||||
associatedCoursewareName.value = resData.CourseWareNameList;
|
||||
};
|
||||
fnGetAssociatedCoursewareNameList();
|
||||
const fnQuestionTypeChange = async () => {
|
||||
await nextTick();
|
||||
if (form.value.QUESTIONTYPE === "1") {
|
||||
answerOptions.value = [
|
||||
{ value: "A", label: "A" },
|
||||
{ value: "B", label: "B" },
|
||||
{ value: "C", label: "C" },
|
||||
{ value: "D", label: "D" },
|
||||
];
|
||||
} else if (form.value.QUESTIONTYPE === "2") {
|
||||
answerOptions.value = [
|
||||
{ value: "AB", label: "AB" },
|
||||
{ value: "AC", label: "AC" },
|
||||
{ value: "AD", label: "AD" },
|
||||
{ value: "BC", label: "BC" },
|
||||
{ value: "BD", label: "BD" },
|
||||
{ value: "CD", label: "CD" },
|
||||
{ value: "ABC", label: "ABC" },
|
||||
{ value: "ABD", label: "ABD" },
|
||||
{ value: "ACD", label: "ACD" },
|
||||
{ value: "BCD", label: "BCD" },
|
||||
{ value: "ABCD", label: "ABCD" },
|
||||
];
|
||||
} else if (form.value.QUESTIONTYPE === "3") {
|
||||
answerOptions.value = [
|
||||
{ value: "A", label: "对" },
|
||||
{ value: "B", label: "错" },
|
||||
];
|
||||
} else {
|
||||
answerOptions.value = [];
|
||||
}
|
||||
};
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
if (form.value.QUESTIONTYPE === "3") {
|
||||
form.value.OPTIONA = "对";
|
||||
form.value.OPTIONB = "错";
|
||||
form.value.OPTIONC = "";
|
||||
form.value.OPTIOND = "";
|
||||
}
|
||||
let arr = [];
|
||||
if (form.value.QUESTIONTYPE === "3") {
|
||||
arr = ["#" + form.value.OPTIONA + "#", "#" + form.value.OPTIONB + "#"];
|
||||
} else if (form.value.QUESTIONTYPE !== "4") {
|
||||
arr = [
|
||||
"#" + form.value.OPTIONA + "#",
|
||||
"#" + form.value.OPTIONB + "#",
|
||||
"#" + form.value.OPTIONC + "#",
|
||||
"#" + form.value.OPTIOND + "#",
|
||||
];
|
||||
}
|
||||
const s = arr.join(",") + ",";
|
||||
for (let i = 0; i < arr.length - 1; i++) {
|
||||
if (s.replace(arr[i] + ",", "").indexOf(arr[i]) > -1) {
|
||||
ElMessage.warning("试题答案重复:" + arr[i].split("#").join(""));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!props.isInherit) {
|
||||
props.type === "add"
|
||||
? await setpaperQuestionCacheQuestionsAdd({
|
||||
...form.value,
|
||||
STAGEEXAMPAPERINPUT_ID: props.id,
|
||||
})
|
||||
: await setpaperQuestionCacheQuestionsEdit({ ...form.value });
|
||||
emits("get-data");
|
||||
} else {
|
||||
emits("confirm", cloneDeep(form.value));
|
||||
}
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,297 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<el-divider content-position="left">试卷基本信息</el-divider>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="data.form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<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="EXAMSCORE">
|
||||
<el-input-number v-model="data.form.EXAMSCORE" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合格分数" prop="PASSSCORE">
|
||||
<el-input-number v-model="data.form.PASSSCORE" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div v-if="type !== 'add'">
|
||||
<el-divider content-position="left">试卷题目信息</el-divider>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnGetData"
|
||||
>
|
||||
<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="QUESTIONTYPE">
|
||||
<el-select v-model="searchForm.QUESTIONTYPE">
|
||||
<el-option
|
||||
v-for="item in questionTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</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="fnGetData">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label-width="10px" class="end">
|
||||
<el-button type="primary" @click="fnAddOrEdit({}, '')">
|
||||
新增试题
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="items mt-20 p-20">
|
||||
<div
|
||||
v-for="(item, index) in list"
|
||||
:key="item.PAPER_QUESTION_ID"
|
||||
class="item ptb-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 }}
|
||||
<span class="ml-10">(题目分值:{{ item.SCORE }})</span>
|
||||
</div>
|
||||
<div class="mt-10 ml-30">
|
||||
<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>
|
||||
<div class="flex">
|
||||
<div>
|
||||
<div class="mt-10">答案:{{ item.ANSWER }}</div>
|
||||
<div class="mt-10">答案解析:{{ item.DESCR }}</div>
|
||||
<div class="mt-10">关联课件名称:{{ item.COURSEWARENAME }}</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<el-button @click="fnAddOrEdit(item, index)">编辑</el-button>
|
||||
<el-button @click="fnDelete(item.PAPER_QUESTION_ID, index)">
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-10 tc">
|
||||
<el-button type="primary" @click="fnSubmit"> 保存修改 </el-button>
|
||||
</div>
|
||||
<add-test-questions
|
||||
:id="STAGEEXAMPAPERINPUT_ID"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
:type="data.addOrEditDialog.type"
|
||||
:is-inherit="type === 'inherit'"
|
||||
@get-data="fnGetDataInfo"
|
||||
@confirm="fnAddTestQuestionsConfirm"
|
||||
/>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, reactive, ref } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import {
|
||||
setpaperQuestionCacheDelete,
|
||||
setstageexampaperCacheEdit,
|
||||
} from "@/request/training_process_management.js";
|
||||
import {
|
||||
getpaperQuestionCacheQuestions,
|
||||
getStagexampaperCacheView,
|
||||
} from "@/request/training_resource_management.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { cloneDeep, sumBy } from "lodash-es";
|
||||
import AddTestQuestions from "./components/add_test_questions.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { type, STAGEEXAMPAPERINPUT_ID } = route.query;
|
||||
|
||||
const questionTypeOptions = [
|
||||
{ value: "1", label: "单选题" },
|
||||
{ value: "2", label: "多选题" },
|
||||
{ value: "3", label: "判断题" },
|
||||
];
|
||||
const rules = {
|
||||
EXAMNAME: [{ required: true, message: "请输入试卷名称", trigger: "blur" }],
|
||||
EXAMSCORE: [{ required: true, message: "请输入总分数", trigger: "blur" }],
|
||||
PASSSCORE: [{ required: true, message: "请输入合格分数", trigger: "blur" }],
|
||||
fileList: [{ required: true, message: "请上传试题", trigger: "change" }],
|
||||
};
|
||||
const formRef = ref(null);
|
||||
const data = reactive({
|
||||
form: {
|
||||
EXAMNAME: "",
|
||||
EXAMSCORE: 0,
|
||||
PASSSCORE: 0,
|
||||
fileList: [],
|
||||
},
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
form: {
|
||||
QUESTIONTYPE: "",
|
||||
QUESTIONDRY: "",
|
||||
OPTIONA: "",
|
||||
OPTIONB: "",
|
||||
OPTIONC: "",
|
||||
OPTIOND: "",
|
||||
ANSWER: "",
|
||||
SCORE: 0,
|
||||
LABEL_TYPE: "",
|
||||
VIDEOCOURSEWARE_ID: "",
|
||||
},
|
||||
type: "",
|
||||
index: "",
|
||||
},
|
||||
});
|
||||
const { list, searchForm, fnGetData } = useListData(
|
||||
getpaperQuestionCacheQuestions,
|
||||
{
|
||||
otherParams: { STAGEEXAMPAPERINPUT_ID },
|
||||
immediate: false,
|
||||
usePagination: false,
|
||||
}
|
||||
);
|
||||
const fnGetDataInfo = async () => {
|
||||
if (!STAGEEXAMPAPERINPUT_ID) return;
|
||||
const resData = await getStagexampaperCacheView({ STAGEEXAMPAPERINPUT_ID });
|
||||
resData.pd.EXAMSCORE = +resData.pd.EXAMSCORE;
|
||||
resData.pd.PASSSCORE = +resData.pd.PASSSCORE;
|
||||
data.form = resData.pd;
|
||||
fnGetData();
|
||||
};
|
||||
fnGetDataInfo();
|
||||
|
||||
const fnAddOrEdit = async (row, index) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.type = row.PAPER_QUESTION_ID ? "edit" : "add";
|
||||
data.addOrEditDialog.index = index;
|
||||
if (row.PAPER_QUESTION_ID) {
|
||||
data.addOrEditDialog.form = cloneDeep(row);
|
||||
data.addOrEditDialog.form.SCORE = +row.SCORE;
|
||||
}
|
||||
};
|
||||
const fnAddTestQuestionsConfirm = (value) => {
|
||||
if (data.addOrEditDialog.type === "add") list.value.push(value);
|
||||
else list.value.splice(data.addOrEditDialog.index, 1, value);
|
||||
data.form.EXAMSCORE = sumBy(list.value, (item) => +item.SCORE);
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (PAPER_QUESTION_ID) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
await setpaperQuestionCacheDelete({
|
||||
PAPER_QUESTION_ID,
|
||||
STAGEEXAMPAPERINPUT_ID,
|
||||
});
|
||||
ElMessage.success("删除成功");
|
||||
await fnGetDataInfo();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
if (data.form.PASSSCORE > data.form.EXAMSCORE) {
|
||||
ElMessage.warning("合格分数不能大于总分数");
|
||||
return;
|
||||
}
|
||||
await setstageexampaperCacheEdit({
|
||||
...data.form,
|
||||
});
|
||||
ElMessage.success("保存成功");
|
||||
router.back();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPaginationTransfer"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="试卷名称:">
|
||||
<el-input v-model="searchForm.KEYWORDS" placeholder="搜索" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="创建时间" prop="dates">
|
||||
<el-date-picker
|
||||
v-model="searchForm.dates"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="满分:">
|
||||
<el-input v-model="searchForm.EXAMSCORE" placeholder="满分" />
|
||||
</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="fnResetPaginationTransfer">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<layout-card>
|
||||
<layout-table
|
||||
ref="tableRef"
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetDataTransfer"
|
||||
>
|
||||
<el-table-column label="序号" width="60" fixed="left">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="EXAMNAME" label="试卷名称" />
|
||||
<el-table-column prop="CREATTIME" label="上传时间" align="center" />
|
||||
<el-table-column prop="EXAMSCORE" label="满分" align="center" />
|
||||
<el-table-column label="试卷类型" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.SOURCETYPE, TypeOfTestPaperList) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="text"
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/examdraft_management/edit',
|
||||
query: {
|
||||
STAGEEXAMPAPERINPUT_ID: row.STAGEEXAMPAPERINPUT_ID,
|
||||
},
|
||||
})
|
||||
"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button type="text" @click="fnDelete(row.STAGEEXAMPAPERINPUT_ID)"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button
|
||||
type="text"
|
||||
@click="convertStageexam(row.STAGEEXAMPAPERINPUT_ID, '0')"
|
||||
>转成正式试卷</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
getExamdraftList,
|
||||
setstageexampaperCacheDelete,
|
||||
setstageexampaperCacheformal,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { serialNumber, translationStatus } from "@/assets/js/utils.js";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
const router = useRouter();
|
||||
|
||||
const TypeOfTestPaperList = [
|
||||
{ ID: "1", NAME: "平台试卷" },
|
||||
{ ID: "2", NAME: "自建试卷" },
|
||||
];
|
||||
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
|
||||
useListData(getExamdraftList);
|
||||
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
const fnResetPaginationTransfer = () => {
|
||||
fnResetPagination({
|
||||
STARTTIME: searchForm.value.dates?.[0],
|
||||
ENDTIME: searchForm.value.dates?.[1],
|
||||
});
|
||||
};
|
||||
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (STAGEEXAMPAPERINPUT_ID) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setstageexampaperCacheDelete({ STAGEEXAMPAPERINPUT_ID });
|
||||
ElMessage.success("删除成功");
|
||||
fnResetPaginationTransfer();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
|
||||
const convertStageexam = debounce(
|
||||
1000,
|
||||
async (STAGEEXAMPAPERINPUT_ID) => {
|
||||
await ElMessageBox.confirm("确定要转成正式试卷吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setstageexampaperCacheformal({ STAGEEXAMPAPERINPUT_ID });
|
||||
ElMessage.success("转成正式试卷成功");
|
||||
fnResetPaginationTransfer();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,362 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPaginationTransfer"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学员姓名" prop="STUDENT_NAME">
|
||||
<el-input v-model="searchForm.STUDENT_NAME" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="班级编码" prop="CODE">
|
||||
<el-input v-model="searchForm.CODE" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<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="TIME">
|
||||
<el-date-picker
|
||||
v-model="searchForm.TIME"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="结束时间" prop="TIME1">
|
||||
<el-date-picker
|
||||
v-model="searchForm.TIME1"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="入班时间" prop="TIME2">
|
||||
<el-date-picker
|
||||
v-model="searchForm.TIME2"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学习状态" prop="STUDYSTATE">
|
||||
<el-select v-model="searchForm.STUDYSTATE">
|
||||
<el-option
|
||||
v-for="item in studyStateList"
|
||||
:key="item.ID"
|
||||
:value="item.ID"
|
||||
:label="item.NAME"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="考试状态" prop="STAGEEXAMSTATE">
|
||||
<el-select v-model="searchForm.STAGEEXAMSTATE">
|
||||
<el-option
|
||||
v-for="item in stageExamStateList"
|
||||
:key="item.ID"
|
||||
:value="item.ID"
|
||||
:label="item.NAME"
|
||||
/>
|
||||
</el-select>
|
||||
</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="fnResetPaginationTransfer">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<layout-card>
|
||||
<div class="table_btn">
|
||||
<el-button type="primary" @click="fnStudentRecords"
|
||||
>导出学员信息</el-button
|
||||
>
|
||||
</div>
|
||||
<layout-table
|
||||
ref="tableRef"
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetDataTransfer"
|
||||
>
|
||||
<el-table-column label="序号" width="60" fixed="left">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="学员姓名"
|
||||
prop="STUDENT_NAME"
|
||||
show-overflow-tooltip
|
||||
fixed="left"
|
||||
/>
|
||||
<el-table-column
|
||||
label="身份证号"
|
||||
prop="USER_ID_CARD"
|
||||
show-overflow-tooltip
|
||||
fixed="left"
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
label="班级名称"
|
||||
prop="CLASS_NAME"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
label="班级编码"
|
||||
prop="CODE"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
label="部门"
|
||||
prop="DEPARTMENT_NAME"
|
||||
show-overflow-tooltip
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
label="工种"
|
||||
prop="POST_NAME"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
prop="START_TIME"
|
||||
label="培训开始时间"
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
prop="END_TIME"
|
||||
label="培训结束时间"
|
||||
align="center"
|
||||
width="100"
|
||||
/>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
prop="CREATTIME"
|
||||
label="入班时间"
|
||||
align="center"
|
||||
width="100"
|
||||
/>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
prop="CURRICULUMNAME"
|
||||
label="培训课程"
|
||||
align="center"
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
prop="ALL_CLASSHOUR"
|
||||
label="要求学时"
|
||||
align="center"
|
||||
width="100"
|
||||
/>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
prop="COMPLETE_CLASSHOUR"
|
||||
label="已完成学时"
|
||||
align="center"
|
||||
width="100"
|
||||
/>
|
||||
<el-table-column label="学习状态" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.STUDYSTATE, studyStateList) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="考试状态" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.STAGEEXAMSTATE, stageExamStateList) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="EXAMSCORE" label="考试分数" width="100" />
|
||||
<el-table-column label="任务状态" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.STATE, taskStatusList) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { serialNumber, translationStatus } from "@/assets/js/utils.js";
|
||||
import {
|
||||
getTrainingProgressListExportStudentRecords,
|
||||
getTrainingProgressList,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import * as XLSX from "xlsx";
|
||||
const studyStateList = [
|
||||
{ ID: "0", NAME: "未学习" },
|
||||
{ ID: "1", NAME: "学习中" },
|
||||
{ ID: "2", NAME: "已学完" },
|
||||
{ ID: "3", NAME: "已完成" },
|
||||
{ ID: "4", NAME: "未完成" },
|
||||
{ ID: "5", NAME: "待评估" },
|
||||
{ ID: "6", NAME: "评估未合格" },
|
||||
];
|
||||
const stageExamStateList = [
|
||||
{ ID: "0", NAME: "不考试" },
|
||||
{ ID: "1", NAME: "待考试" },
|
||||
{ ID: "2", NAME: "考试未通过" },
|
||||
{ ID: "3", NAME: "考试通过" },
|
||||
{ ID: "4", NAME: "未参加" },
|
||||
];
|
||||
const taskStatusList = [
|
||||
{ ID: "1", NAME: "未申请" },
|
||||
{ ID: "4", NAME: "待开班" },
|
||||
{ ID: "5", NAME: "培训中" },
|
||||
{ ID: "6", NAME: "培训结束" },
|
||||
];
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
|
||||
useListData(getTrainingProgressList);
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
STARTTIME: searchForm.value.TIME?.[0],
|
||||
ENDTIME: searchForm.value.TIME?.[1],
|
||||
OVERSTARTTIME: searchForm.value.TIME1?.[0],
|
||||
OVERENDTIME: searchForm.value.TIME1?.[1],
|
||||
CREATESTARTTIME: searchForm.value.TIME2?.[0],
|
||||
CREATENDTIME: searchForm.value.TIME2?.[1],
|
||||
});
|
||||
};
|
||||
const fnResetPaginationTransfer = () => {
|
||||
fnResetPagination({
|
||||
STARTTIME: searchForm.value.TIME?.[0],
|
||||
ENDTIME: searchForm.value.TIME?.[1],
|
||||
OVERSTARTTIME: searchForm.value.TIME1?.[0],
|
||||
OVERENDTIME: searchForm.value.TIME1?.[1],
|
||||
CREATESTARTTIME: searchForm.value.TIME2?.[0],
|
||||
CREATENDTIME: searchForm.value.TIME2?.[1],
|
||||
});
|
||||
};
|
||||
const fnStudentRecords = async () => {
|
||||
await ElMessageBox.confirm("确定要导出查询出来所有的学员信息?", {
|
||||
type: "warning",
|
||||
});
|
||||
const resData = await getTrainingProgressListExportStudentRecords({
|
||||
...searchForm.value,
|
||||
STARTTIME: searchForm.value.TIME?.[0],
|
||||
ENDTIME: searchForm.value.TIME?.[1],
|
||||
OVERSTARTTIME: searchForm.value.TIME1?.[0],
|
||||
OVERENDTIME: searchForm.value.TIME1?.[1],
|
||||
CREATESTARTTIME: searchForm.value.TIME2?.[0],
|
||||
CREATENDTIME: searchForm.value.TIME2?.[1],
|
||||
});
|
||||
if (resData.varList.length > 0) fnExportStudentRecords(resData.varList);
|
||||
else ElMessage.warning("没有学员信息");
|
||||
};
|
||||
|
||||
const fnExportStudentRecords = (list) => {
|
||||
const tableData = [
|
||||
[
|
||||
"序号",
|
||||
"学员姓名",
|
||||
"身份证号",
|
||||
"班级名称",
|
||||
"班级编码",
|
||||
"部门",
|
||||
"工种",
|
||||
"培训开始时间",
|
||||
"培训结束时间",
|
||||
"入班时间",
|
||||
"培训课程",
|
||||
"要求学时",
|
||||
"已完成学时",
|
||||
"学习状态",
|
||||
"考试状态",
|
||||
"考试分数",
|
||||
"任务状态",
|
||||
],
|
||||
];
|
||||
list.forEach((item, index) => {
|
||||
for (let i = 0; i < studyStateList.length; i++) {
|
||||
if (studyStateList[i].ID === item.STUDYSTATE) {
|
||||
item.STUDYSTATE = studyStateList[i].NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < stageExamStateList.length; i++) {
|
||||
if (stageExamStateList[i].ID === item.STAGEEXAMSTATE) {
|
||||
item.STAGEEXAMSTATE = stageExamStateList[i].NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < taskStatusList.length; i++) {
|
||||
if (taskStatusList[i].ID === item.STATE) {
|
||||
item.STATE = taskStatusList[i].NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item.COMPLETE_CLASSHOUR === "0.0") item.COMPLETE_CLASSHOUR = "0";
|
||||
if (item.ALL_CLASSHOUR === "0.0") item.ALL_CLASSHOUR = "0";
|
||||
tableData.push([
|
||||
index + 1,
|
||||
item.STUDENT_NAME,
|
||||
item.USER_ID_CARD,
|
||||
item.CLASS_NAME,
|
||||
item.CODE,
|
||||
item.DEPARTMENT_NAME,
|
||||
item.POST_NAME,
|
||||
item.START_TIME,
|
||||
item.END_TIME,
|
||||
item.CREATTIME,
|
||||
item.CURRICULUMNAME,
|
||||
item.ALL_CLASSHOUR,
|
||||
item.COMPLETE_CLASSHOUR,
|
||||
item.STUDYSTATE,
|
||||
item.STAGEEXAMSTATE,
|
||||
item.EXAMSCORE,
|
||||
item.STATE,
|
||||
]);
|
||||
});
|
||||
const ws = XLSX.utils.aoa_to_sheet(tableData);
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "学员信息统计");
|
||||
XLSX.writeFile(wb, "学员信息统计表.xlsx");
|
||||
ElMessage.success("导出成功");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table_btn {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue