pull/1/head
z 2024-01-22 15:55:37 +08:00
parent ec267cc310
commit 6db2c2cb03
13 changed files with 1729 additions and 0 deletions

View File

@ -122,6 +122,10 @@
width: 100% !important;
}
.el-textarea.is-disabled .el-textarea__inner {
--el-disabled-border-color: var(--el-border-color);
}
.el-table {
--el-table-bg-color: #071a43 !important;
--el-bg-color: #071a43 !important;

View File

@ -1001,6 +1001,85 @@ export default [
},
],
},
{
path: "/online_learn_exam/task",
meta: { title: "任务管理", isSubMenu: false },
component: "children",
children: [
{
path: "/online_learn_exam/task",
component: "online_learn_exam/task/index",
},
{
path: "/online_learn_exam/task/view",
meta: {
title: "查看",
activeMenu: "/online_learn_exam/task",
},
component: "online_learn_exam/task/view",
},
{
path: "/online_learn_exam/task/update",
meta: {
title: "修改",
activeMenu: "/online_learn_exam/task",
},
component: "online_learn_exam/task/view",
},
{
path: "/online_learn_exam/task/add",
meta: {
title: "新增",
activeMenu: "/online_learn_exam/task",
},
component: "online_learn_exam/task/add",
},
{
path: "/online_learn_exam/task/student_details",
meta: {
title: "学员详情",
activeMenu: "/online_learn_exam/task",
},
component: "children",
children: [
{
path: "",
component: "online_learn_exam/task/student_details",
},
{
path: "/online_learn_exam/task/student_details/learning_details",
meta: {
title: "学习详情",
activeMenu: "/online_learn_exam/task",
},
component: "online_learn_exam/task/learning_details",
},
],
},
{
path: "/online_learn_exam/task/exam_details",
meta: {
title: "考试详情",
activeMenu: "/online_learn_exam/task",
},
component: "children",
children: [
{
path: "",
component: "online_learn_exam/task/exam_details",
},
{
path: "/online_learn_exam/task/exam_details/exam_paper_details",
meta: {
title: "考卷详情",
activeMenu: "/online_learn_exam/task",
},
component: "online_learn_exam/task/exam_paper_details",
},
],
},
],
},
],
},
{

View File

@ -53,3 +53,18 @@ export const getPaperQuestionsNumber = (params) =>
export const setPaperAdd = (params) => post("/stageexampaperinput/add", params); // 试卷管理添加
export const getPaperQuestionsList = (params) =>
post("/question/getQuestionList", params); // 试卷管理可选题列表
export const getTaskList = (params) => post("/studytask/list", params); // 任务管理列表
export const getTaskViewInfo = (params) => post("/studytask/goEdit", params); // 任务管理查看
export const getTaskViewUserList = (params) =>
post("/stagestudentrelation/listAllByStudyTaskId", params); // 任务管理查看人员
export const getTaskViewExaminationList = (params) =>
post("/stageexampaper/getPageDataByStudyTaskId", params); // 任务管理查看考试
export const setTaskAdd = (params) => post("/studytask/add", params); // 任务管理添加
export const setTaskUpdate = (params) =>
post("/studytask/updateEndTimeAndUser", params); // 任务管理修改
export const getTaskLearningDetailsList = (params) =>
post("/studytask/getAllByuserInfo", params); // 任务管理学习详情
export const getTaskExamDetailsList = (params) =>
post("/stagestudentrelation/list", params); // 任务管理考试详情列表
export const getTaskExamPaperDetails = (params) =>
post("/stageexam/findResult", params); // 任务管理考卷详情查看

View File

@ -0,0 +1,371 @@
<template>
<div>
<layout-card>
<el-form
ref="formRef"
:rules="rules"
:model="data.form"
label-width="170px"
>
<el-row>
<el-col :span="12">
<el-form-item label="学习任务名称" prop="STUDY_NAME">
<el-input v-model="data.form.STUDY_NAME" />
</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"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="培训时间" prop="PEIXUE_TIME">
<el-date-picker
v-model="data.form.PEIXUE_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="24">
<el-form-item label="是否签到" prop="KJ_STATE">
<div style="display: flex">
<div>
<el-radio-group v-model="data.form.KJ_STATE">
<el-radio label="1"></el-radio>
<el-radio disabled label="2"></el-radio>
</el-radio-group>
</div>
<div class="text-red ml-10">
*开启签到后学员培训前需要进行电子手签并会记录到学员名册及考勤档案中
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="是否开启防挂机验证" prop="GJ_STATE">
<div style="display: flex">
<div>
<el-radio-group v-model="data.form.GJ_STATE">
<el-radio label="1"></el-radio>
<el-radio disabled label="2"></el-radio>
</el-radio-group>
</div>
<div class="text-red ml-10">
*开启防挂机验证员工学习过程会进行人脸识别确保是员工本人在培训
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="添加课程" prop="curriculumList">
<div class="flex">
<el-button
type="primary"
@click="data.curriculumDialogVisible = true"
>
添加课程
</el-button>
<layout-table
:data="data.form.curriculumList"
:show-pagination="false"
:max-height="200"
>
<el-table-column prop="CURRICULUMNAME" label="课程名称" />
<el-table-column
prop="COURSEWARECOUNT"
label="课件数"
width="150"
/>
<el-table-column
prop="CLASSHOUR"
label="学时(分钟)"
width="150"
/>
</layout-table>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="添加人员" prop="userList">
<div class="flex">
<el-button
type="primary"
@click="data.examinationUserDialogVisible = true"
>
添加人员
</el-button>
<layout-table
:data="data.form.userList"
:show-pagination="false"
:max-height="200"
>
<el-table-column prop="USERNAME" label="用户名" />
<el-table-column prop="NAME" label="姓名" />
<el-table-column prop="DEPARTMENT_NAME" label="部门" />
</layout-table>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="设置考试" prop="examinationList">
<div class="flex">
<el-button type="primary" @click="fnExamination">
设置考试
</el-button>
<layout-table
:data="data.form.examinationList"
:show-pagination="false"
:max-height="200"
>
<el-table-column prop="kaoshoName" label="考试名称" />
<el-table-column prop="ANSWERSHEETTIME" label="考试时长" />
<el-table-column prop="examType" label="考试类型">
<template #default="{ row }">
<span v-if="row.examType === '1'">线</span>
</template>
</el-table-column>
<el-table-column prop="EXAMNAME" label="阶段试卷" />
</layout-table>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="设置记录人员" prop="RECORDER">
<div class="flex">
<el-button
type="primary"
@click="data.recordUserDialogVisible = true"
>
设置记录人员
</el-button>
<el-input
v-model="data.form.RECORDER"
disabled
type="textarea"
autosize
/>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="设置安全生产机构负责人" prop="CHARGE">
<div class="flex">
<el-button
type="primary"
@click="data.responsibilityUserDialogVisible = true"
>
设置安全生产机构负责人
</el-button>
<el-input
v-model="data.form.CHARGE"
disabled
type="textarea"
autosize
/>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="tc mt-10">
<el-button type="primary" @click="fnSubmit"></el-button>
</div>
</layout-card>
<curriculum
v-model:visible="data.curriculumDialogVisible"
v-model:curriculum-list="data.form.curriculumList"
/>
<examination
v-model:visible="data.examinationDialog.visible"
v-model:form="data.examinationDialog.form"
v-model:examination-list="data.form.examinationList"
:peixue-time="data.form.PEIXUE_TIME"
/>
<user
v-model:visible="data.examinationUserDialogVisible"
v-model:user-list="data.form.userList"
type="1"
/>
<user
v-model:visible="data.recordUserDialogVisible"
v-model:user-list="data.form.recordUserList"
type="2"
@submit="fnRecordUserDialogSubmit"
/>
<user
v-model:visible="data.responsibilityUserDialogVisible"
v-model:user-list="data.form.responsibilityUserList"
type="3"
@submit="fnResponsibilityUserDialogSubmit"
/>
</div>
</template>
<script setup>
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
import { nextTick, reactive, ref } from "vue";
import { setTaskAdd } from "@/request/online_learn_exam.js";
import { ElMessage } from "element-plus";
import { debounce } from "throttle-debounce";
import { useRouter } from "vue-router";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { useUserStore } from "@/pinia/user.js";
import Curriculum from "./components/curriculum.vue";
import Examination from "./components/examination.vue";
import { cloneDeep } from "lodash-es";
import User from "./components/user.vue";
const router = useRouter();
const userStore = useUserStore();
const formRef = ref(null);
const rules = {
STUDY_NAME: [
{ required: true, message: "学习任务名称不能为空", trigger: "blur" },
],
TRAINTYPE: [
{ required: true, message: "培训行业类型不能为空", trigger: "change" },
],
POSTTYPE: [
{ required: true, message: "岗位培训类型不能为空", trigger: "change" },
],
PEIXUE_TIME: [
{ required: true, message: "培训时间不能为空", trigger: "change" },
],
KJ_STATE: [{ required: true, message: "是否签到不能为空", trigger: "blur" }],
GJ_STATE: [
{
required: true,
message: "是否开启防挂机验证不能为空",
trigger: "blur",
},
],
curriculumList: [
{ required: true, message: "课程不能为空", trigger: "change" },
],
userList: [{ required: true, message: "人员不能为空", trigger: "change" }],
examinationList: [
{ required: true, message: "考试不能为空", trigger: "change" },
],
};
const data = reactive({
form: {
STUDY_NAME: "",
TRAINTYPE: userStore.getUserInfo.CORP_TRAINTYPE,
POSTTYPE: "",
PEIXUE_TIME: [],
KJ_STATE: "1",
GJ_STATE: "1",
curriculumList: [],
userList: [],
recordUserList: [],
responsibilityUserList: [],
examinationList: [],
RECORDERUSERIDS: "",
RECORDER: "",
CHARGEUSERIDS: "",
CHARGE: "",
},
curriculumDialogVisible: false,
examinationUserDialogVisible: false,
recordUserDialogVisible: false,
responsibilityUserDialogVisible: false,
examinationDialog: {
visible: false,
form: {
kaoshoName: "",
ANSWERSHEETTIME: 1,
NUMBER_OF_EXAMINATIONS: "",
examType: "",
},
},
});
const fnRecordUserDialogSubmit = (selectionData) => {
const USER_IDS = selectionData.map((item) => item.USER_ID).join(",");
const NAMES = selectionData.map((item) => item.NAME).join(",");
data.form.RECORDERUSERIDS = USER_IDS;
data.form.RECORDER = NAMES;
};
const fnResponsibilityUserDialogSubmit = (selectionData) => {
const USER_IDS = selectionData.map((item) => item.USER_ID).join(",");
const NAMES = selectionData.map((item) => item.NAME).join(",");
data.form.CHARGEUSERIDS = USER_IDS;
data.form.CHARGE = NAMES;
};
const fnExamination = async () => {
if (data.form.PEIXUE_TIME?.length === 2) {
data.examinationDialog.visible = true;
await nextTick();
if (data.form.examinationList.length === 1)
data.examinationDialog.form = cloneDeep(data.form.examinationList[0]);
} else ElMessage.warning("请选择培训时间");
};
const fnSubmit = debounce(
1000,
async () => {
await useFormValidate(formRef);
const form = data.form;
const examination = form.examinationList[0];
const curIds = form.curriculumList
.map((item) => item.CURRICULUM_ID)
.join(",");
const userIds = form.userList.map((item) => item.USER_ID).join(",");
await setTaskAdd({
...form,
curIds,
userIds,
PEIXUE_START_TIME: form.PEIXUE_TIME[0],
PEIXUE_END_TIME: form.PEIXUE_TIME[1],
INPUT_ID: examination.STAGEEXAMPAPERINPUT_ID,
kaoshoName: examination.kaoshoName,
examType: examination.examType,
ANSWERSHEETTIME: examination.ANSWERSHEETTIME,
EXAMSCORE: examination.EXAMSCORE,
QUESTIONNUM:
parseInt(examination.DANYUANTICOUNT) +
parseInt(examination.DUOXUANTICOUNT) +
parseInt(examination.PANDUITICOUNT),
NUMBER_OF_EXAMINATIONS: examination.NUMBER_OF_EXAMINATIONS,
});
ElMessage.success("保存成功");
router.back();
},
{ atBegin: true }
);
</script>
<style lang="scss" scoped>
.flex {
flex: 1;
display: flex;
.el-button {
width: 186px;
margin-right: 20px;
}
.el-textarea {
width: 50%;
}
:deep(.el-table) {
width: 50%;
}
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<el-dialog v-model="visible" title="选择课程" :on-close="fnClose">
<el-form :model="searchForm" @submit.prevent="fnResetPagination">
<el-row>
<el-col :span="9">
<el-form-item label="课程名称" prop="KEYWORDS" label-width="80px">
<el-input v-model="searchForm.KEYWORDS" />
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item
label="岗位培训类型"
prop="POSTTYPE"
label-width="110px"
>
<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>
<layout-table
ref="tableRef"
row-key="CURRICULUM_ID"
:data="list"
v-model:pagination="pagination"
@get-data="fnGetData"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="CURRICULUMNAME" label="课程名称" />
<el-table-column
:show-overflow-tooltip="true"
prop="train_type_name"
label="培训行业类型"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="post_type_name"
label="岗位培训类型"
/>
<el-table-column prop="CLASSHOUR" label="学时(分钟)" width="150" />
<el-table-column prop="COURSEWARECOUNT" label="课件数" width="70" />
</layout-table>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { serialNumber } from "@/assets/js/utils.js";
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
import { useVModels } from "@vueuse/core";
import useListData from "@/assets/js/useListData.js";
import { getCurriculumList } from "@/request/online_learn_exam.js";
import { nextTick, watch } from "vue";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
curriculumList: {
type: Array,
required: true,
default: () => [],
},
});
const emits = defineEmits(["update:visible", "update:curriculumList"]);
const { visible, curriculumList } = useVModels(props, emits);
const { list, searchForm, pagination, fnGetData, fnResetPagination, tableRef } =
useListData(getCurriculumList, {
immediate: false,
clearSelection: false,
});
const fnInit = async () => {
await nextTick();
props.curriculumList.forEach((item) => {
tableRef.value.toggleRowSelection(item);
});
list.value.length === 0 && fnGetData();
};
const fnClose = () => {
tableRef.value.clearSelection();
visible.value = false;
};
const fnSubmit = () => {
curriculumList.value = tableRef.value.getSelectionRows();
fnClose();
};
watch(
() => props.visible,
(val) => {
if (val) {
fnInit();
}
}
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,190 @@
<template>
<el-dialog v-model="visible" title="考试设置" :on-close="fnClose">
<el-form ref="formRef" :rules="rules" :model="form" label-width="140px">
<el-form-item label="考试名称" prop="kaoshoName">
<el-input v-model="form.kaoshoName" />
</el-form-item>
<el-form-item label="考试时间">
<el-date-picker
:model-value="peixueTime"
disabled
type="daterange"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form-item>
<el-form-item label="考试时长(分钟)" prop="ANSWERSHEETTIME">
<el-input-number :min="1" v-model="form.ANSWERSHEETTIME" />
</el-form-item>
<el-form-item label="考试次数" prop="NUMBER_OF_EXAMINATIONS">
<el-select v-model="form.NUMBER_OF_EXAMINATIONS">
<el-option label="2次" value="2" />
<el-option label="重复考试" value="-1" />
</el-select>
</el-form-item>
<el-form-item label="考试类型" prop="examType">
<el-select v-model="form.examType">
<el-option label="线上考试" value="1" />
</el-select>
</el-form-item>
<el-form-item label="总分数">
<el-input disabled :model-value="currentCheck.EXAMSCORE" />
</el-form-item>
<el-form-item label="合格分数">
<el-input disabled :model-value="currentCheck.PASSSCORE" />
</el-form-item>
</el-form>
<div style="padding-left: 140px">
<layout-table
:data="list"
v-model:pagination="pagination"
@get-data="fnGetData"
>
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="EXAMNAME" label="阶段试卷" />
<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 prop="ANSWERSHEETTIME" label="试题数" width="80">
<template v-slot="{ row }">
{{
Number(row.DUOXUANTICOUNT) +
Number(row.DANYUANTICOUNT) +
Number(row.PANDUITICOUNT)
}}
</template>
</el-table-column>
<el-table-column prop="EXAMSCORE" label="总分数" width="80" />
<el-table-column prop="PASSSCORE" label="及格分数" width="80" />
<el-table-column label="操作" width="80">
<template v-slot="{ row }">
<el-button type="primary" text link @click="fnApply(row)">
{{
currentCheck.STAGEEXAMPAPERINPUT_ID ===
row.STAGEEXAMPAPERINPUT_ID
? "取消使用"
: "使用"
}}
</el-button>
</template>
</el-table-column>
</layout-table>
</div>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"> </el-button>
</template>
</el-dialog>
</template>
<script setup>
import { serialNumber } from "@/assets/js/utils.js";
import useListData from "@/assets/js/useListData.js";
import { getPaperList } from "@/request/online_learn_exam.js";
import { useVModels } from "@vueuse/core";
import { ref, watch } from "vue";
import useFormValidate from "@/assets/js/useFormValidate.js";
import { ElMessage } from "element-plus";
import { cloneDeep } from "lodash-es";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
form: {
type: Object,
required: true,
default: () => ({}),
},
peixueTime: {
type: Array,
required: true,
default: () => [],
},
examinationList: {
type: Array,
required: true,
default: () => [],
},
});
const emits = defineEmits([
"update:visible",
"update:form",
"update:examinationList",
]);
const { visible, form, examinationList } = useVModels(props, emits);
const { list, pagination, fnGetData } = useListData(getPaperList, {
otherParams: { STATE: "0" },
immediate: false,
});
const rules = {
kaoshoName: [
{ required: true, message: "考试名称不能为空", trigger: "blur" },
],
ANSWERSHEETTIME: [
{ required: true, message: "考试时长不能为空", trigger: "blur" },
],
NUMBER_OF_EXAMINATIONS: [
{ required: true, message: "考试次数不能为空", trigger: "change" },
],
examType: [
{ required: true, message: "考试类型不能为空", trigger: "change" },
],
};
const formRef = ref(null);
const currentCheck = ref({});
const fnInit = () => {
if (props.examinationList[0])
currentCheck.value = cloneDeep(props.examinationList[0]);
else currentCheck.value = {};
list.value.length === 0 && fnGetData();
};
const fnClose = () => {
formRef.value.resetFields();
visible.value = false;
};
const fnApply = (row) => {
if (
currentCheck.value.STAGEEXAMPAPERINPUT_ID === row.STAGEEXAMPAPERINPUT_ID
) {
currentCheck.value = {};
return;
}
currentCheck.value = row;
};
const fnSubmit = async () => {
await useFormValidate(formRef);
if (!currentCheck.value.STAGEEXAMPAPERINPUT_ID) {
ElMessage.error("请选择试卷");
return;
}
examinationList.value = [{ ...form.value, ...currentCheck.value }];
visible.value = false;
};
watch(
() => props.visible,
(val) => {
if (val) {
fnInit();
}
}
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,139 @@
<template>
<el-dialog v-model="visible" title="选择人员" :on-close="fnClose">
<el-form
:model="searchForm"
label-width="80px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="9">
<el-form-item label="人员名称" prop="KEYWORDS">
<el-input v-model="searchForm.KEYWORDS" />
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="部门" prop="DEPARTMENT_ID">
<layout-department v-model="searchForm.DEPARTMENT_ID" />
</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>
<layout-table
ref="tableRef"
row-key="USER_ID"
:data="list"
v-model:pagination="pagination"
@get-data="fnGetData"
>
<el-table-column reserve-selection type="selection" width="55" />
<el-table-column label="序号" width="60">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column prop="USERNAME" label="用户名" />
<el-table-column prop="NAME" label="姓名" />
<el-table-column prop="DEPARTMENT_NAME" label="部门" />
<el-table-column
prop="POST_NAME"
label="岗位"
width="150"
show-overflow-tooltip
/>
<el-table-column prop="ROLE_NAME" label="角色" />
</layout-table>
<template #footer>
<el-button @click="fnClose"></el-button>
<el-button type="primary" @click="fnSubmit"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import { serialNumber } from "@/assets/js/utils.js";
import LayoutDepartment from "@/components/department/index.vue";
import useListData from "@/assets/js/useListData.js";
import { getUserList } from "@/request/enterprise_management.js";
import { useVModels } from "@vueuse/core";
import { nextTick, watch } from "vue";
const props = defineProps({
visible: {
type: Boolean,
required: true,
default: false,
},
userList: {
type: Array,
required: true,
default: () => [],
},
type: {
type: String,
required: true,
default: "",
},
});
const emits = defineEmits(["update:visible", "update:userList", "submit"]);
const { visible, userList } = useVModels(props, emits);
const otherParams = {
1: {
IS_STUDENT: "true",
IS_RECORDER: "0",
IS_CHARGE: "0",
},
2: {
IS_STUDENT: "",
IS_RECORDER: "1",
IS_CHARGE: "0",
},
3: {
IS_STUDENT: "",
IS_RECORDER: "0",
IS_CHARGE: "1",
},
};
const { list, pagination, fnGetData, fnResetPagination, tableRef, searchForm } =
useListData(getUserList, {
otherParams: otherParams[props.type],
immediate: false,
clearSelection: false,
key: "userList",
});
const fnInit = async () => {
await nextTick();
props.userList.forEach((item) => {
console.log(item.NAME);
tableRef.value.toggleRowSelection(item);
});
list.value.length === 0 && fnGetData();
};
const fnClose = () => {
tableRef.value.clearSelection();
visible.value = false;
};
const fnSubmit = () => {
const selectionData = tableRef.value.getSelectionRows();
userList.value = selectionData;
emits("submit", selectionData);
fnClose();
};
watch(
() => props.visible,
(val) => {
if (val) {
fnInit();
}
}
);
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,85 @@
<template>
<layout-card>
<layout-table
:data="list"
v-model:pagination="pagination"
@get-data="fnGetData"
>
<el-table-column label="序号" width="60" type="index" />
<el-table-column label="考试名称">
{{ EXAMNAME }}
</el-table-column>
<el-table-column prop="USERNAME" label="参考人" />
<el-table-column prop="OPERATTIME" label="考试时间" />
<el-table-column prop="PLAYCOUNT" label="考试类型">
线上考试
</el-table-column>
<el-table-column prop="STAGEEXAMSCORE" label="得分">
<template v-slot="{ row }">
<span v-if="row.STAGEEXAMSCORE === '-1'"></span>
<span v-else>{{ row.STAGEEXAMSCORE }}</span>
</template>
</el-table-column>
<el-table-column prop="STAGEEXAMSCORE" label="考试结果">
<template v-slot="{ row }">
<span v-if="row.STAGEEXAMSCORE === '-1'"></span>
<span v-else-if="Number(row.STAGEEXAMSCORE) >= Number(PASSSCORE)">
通过
</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/task/exam_details/exam_paper_details',
query: {
USER_ID: row.USER_ID,
STUDYTASK_ID,
STAGEEXAMPAPER_ID,
},
})
"
>
考卷详情
</el-button>
</template>
</el-table-column>
</layout-table>
</layout-card>
</template>
<script setup>
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
getTaskExamDetailsList,
getTaskViewExaminationList,
} from "@/request/online_learn_exam.js";
import useListData from "@/assets/js/useListData.js";
const router = useRouter();
const route = useRoute();
const { STUDYTASK_ID, STAGEEXAMPAPER_ID } = route.query;
const PASSSCORE = ref("");
const EXAMNAME = ref("");
const { list, pagination, fnGetData } = useListData(getTaskExamDetailsList, {
otherParams: { STUDYTASK_ID, STAGEEXAMPAPER_ID },
});
const fnGetDataOther = async () => {
const resData = await getTaskViewExaminationList({
STUDYTASK_ID,
STAGEEXAMPAPER_ID,
});
PASSSCORE.value = resData.varList[0].PASSSCORE;
EXAMNAME.value = resData.varList[0].EXAMNAME;
};
fnGetDataOther();
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,122 @@
<template>
<layout-card>
<el-descriptions :column="2" border>
<el-descriptions-item label="试卷名称" :span="2">
{{ data.info.EXAMNAME }}
</el-descriptions-item>
<el-descriptions-item label="培训行业类型">
{{ data.info.studyTaskData?.post_type_name }}
</el-descriptions-item>
<el-descriptions-item label="岗位培训类型">
{{ data.info.studyTaskData?.train_type_name }}
</el-descriptions-item>
<el-descriptions-item label="总分数">
{{ data.info.stageexampaperData?.EXAMSCORE }}
</el-descriptions-item>
<el-descriptions-item label="合格分数">
{{ data.info.stageexampaperData?.PASSSCORE }}
</el-descriptions-item>
<el-descriptions-item label="考试结果">
{{ data.info.EXAMSCORE }}
</el-descriptions-item>
<el-descriptions-item label="考试时间">
{{ data.info.OPERATTIME }}
</el-descriptions-item>
</el-descriptions>
<div class="items mt-20 p-20">
<div
v-for="(item, index) in data.info.QUESTIONLIST"
:key="item.QUESTION_ID"
class="item ptb-20"
>
<div class="mb-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.RESULT === 'RIGHT' ? 'text-green' : 'text-red',
]"
>
答案{{ item.ANSWERRIGHT }}
</div>
</div>
</div>
</layout-card>
</template>
<script setup>
import { reactive } from "vue";
import { useRoute } from "vue-router";
import { getTaskExamPaperDetails } from "@/request/online_learn_exam.js";
const route = useRoute();
const { USER_ID, STUDYTASK_ID, STAGEEXAMPAPER_ID } = route.query;
const data = reactive({
info: {},
});
const fnGetData = async () => {
const resData = await getTaskExamPaperDetails({
USER_ID,
STUDYTASK_ID,
STAGEEXAMPAPER_ID,
});
data.info = resData.pd;
data.info.QUESTIONLIST.forEach((item) => {
if (item.ANSWER === item.ANSWERRIGHT) item.RESULT = "RIGHT";
else item.RESULT = "ERROR";
if (item.QUESTIONTYPE === "2") item.ANSWER = item.ANSWER.split("");
});
};
fnGetData();
</script>
<style lang="scss" scoped>
.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,216 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="120px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="5">
<el-form-item label="学习任务名称" prop="KEYWORDS">
<el-input v-model="searchForm.KEYWORDS" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="培训行业类型" prop="TRAINTYPE">
<layout-learning-train-type
v-model="searchForm.TRAINTYPE"
type="industry"
/>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="岗位培训类型" prop="POSTTYPE">
<layout-learning-train-type
v-model="searchForm.POSTTYPE"
type="post"
/>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="任务状态">
<el-select v-model="searchForm.STATUS">
<el-option
v-for="item in stateList"
:key="item.ID"
:label="item.NAME"
:value="item.ID"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<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="STUDY_NAME"
label="学习任务名称"
show-overflow-tooltip
/>
<el-table-column
prop="train_type_name"
label="培训行业类型"
show-overflow-tooltip
/>
<el-table-column
prop="post_type_name"
label="岗位培训类型"
show-overflow-tooltip
/>
<el-table-column
prop="PEIXUE_START_TIME"
label="培训开始时间"
width="100"
/>
<el-table-column
prop="PEIXUE_END_TIME"
label="培训结束时间"
width="100"
/>
<el-table-column prop="SUM_CLASSHOUR" label="任务课时" width="100" />
<el-table-column prop="userCount" label="应参考人数" width="100" />
<el-table-column label="参考人数/合格人数">
<template v-slot="{ row }">
<span>{{ row.cj }}/{{ row.hg }}</span>
</template>
</el-table-column>
<el-table-column label="任务状态" width="100">
<template v-slot="{ row }">
<span
class="text-red"
v-if="
dayjs(row.PEIXUE_START_TIME).diff(dayjs(), 'day') <= 0 &&
dayjs(row.PEIXUE_END_TIME).diff(dayjs(), 'day') >= 0
"
>
进行中
</span>
<span
class="text-green"
v-if="dayjs(row.PEIXUE_END_TIME).diff(dayjs(), 'day') <= 0"
>
已结束
</span>
<span v-if="dayjs(row.PEIXUE_START_TIME).diff(dayjs(), 'day') > 0">
未开始
</span>
</template>
</el-table-column>
<el-table-column label="操作" width="250">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/task/view',
query: { STUDYTASK_ID: row.STUDYTASK_ID, type: 'view' },
})
"
>
查看
</el-button>
<el-button
v-if="
dayjs(row.PEIXUE_START_TIME).diff(dayjs(), 'day') > 0 &&
buttonJurisdiction.edit
"
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/task/update',
query: { STUDYTASK_ID: row.STUDYTASK_ID, type: 'update' },
})
"
>
编辑
</el-button>
<el-button
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/task/student_details',
query: { STUDYTASK_ID: row.STUDYTASK_ID },
})
"
>
学员详情
</el-button>
<el-button
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/task/exam_details',
query: {
STUDYTASK_ID: row.STUDYTASK_ID,
STAGEEXAMPAPER_ID: row.STAGEEXAMPAPER_ID,
},
})
"
>
考试详情
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
v-if="buttonJurisdiction.add"
type="primary"
@click="router.push({ path: '/online_learn_exam/task/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 { getTaskList } from "@/request/online_learn_exam.js";
import { useRouter } from "vue-router";
import dayjs from "dayjs";
const stateList = [
{ ID: "1", NAME: "未开始" },
{ ID: "2", NAME: "进行中" },
{ ID: "3", NAME: "已结束" },
];
const router = useRouter();
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
useListData(getTaskList);
const buttonJurisdiction = await useButtonJurisdiction("curriculum");
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,52 @@
<template>
<layout-card>
<layout-table :data="list" :show-pagination="false">
<el-table-column label="序号" width="60" type="index" />
<el-table-column prop="COURSEWARENAME" label="资料名称" />
<el-table-column prop="CLASSHOUR" label="总学习时长(分钟)" />
<el-table-column label="已学习时长(分钟)">
<template v-slot="{ row }">
<template v-if="row.COURSEWARETYPE === '2'">
<span v-if="!row.PLAYCOUNT">
{{
row.RESOURCETIME
? Number(row.RESOURCETIME / 60).toFixed(2)
: "0"
}}
</span>
<span v-if="row.PLAYCOUNT > 0">
{{ row.CLASSHOUR }}
</span>
</template>
<template v-if="row.COURSEWARETYPE === '1'">
<span v-if="!row.PLAYCOUNT">
{{
row.RESOURCETIME
? Number(row.RESOURCETIME / 60).toFixed(2)
: "0"
}}
</span>
<span v-if="row.PLAYCOUNT > 0">
{{ row.CLASSHOUR }}
</span>
</template>
</template>
</el-table-column>
</layout-table>
</layout-card>
</template>
<script setup>
import { useRoute } from "vue-router";
import { getTaskLearningDetailsList } from "@/request/online_learn_exam.js";
import useListData from "@/assets/js/useListData.js";
const route = useRoute();
const { STUDYTASK_ID, STUDYTASK_USERID } = route.query;
const { list } = useListData(getTaskLearningDetailsList, {
otherParams: { STUDYTASK_ID, STUDYTASK_USERID },
usePagination: false,
});
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,108 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="80px"
@submit.prevent="fnGetData"
>
<el-row>
<el-col :span="5">
<el-form-item label="员工姓名" prop="userkey">
<el-input v-model="searchForm.userkey" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="部门" prop="DEPARTMENT_ID">
<layout-department v-model="searchForm.DEPARTMENT_ID" />
</el-form-item>
</el-col>
<el-col :span="4">
<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-row>
</el-form>
</el-card>
<layout-card>
<layout-table :data="list" :show-pagination="false">
<el-table-column label="序号" width="60" type="index" />
<el-table-column prop="USER_NAME" label="姓名" />
<el-table-column prop="PHONE" label="电话" />
<el-table-column prop="DEPARTMENT_NAME" label="部门" />
<el-table-column prop="POSTNAME" label="岗位" />
<el-table-column label="任务学时">
{{ SUM_CLASSHOUR }}
</el-table-column>
<el-table-column prop="COMPLETE_CLASSHOUR" label="已学习学时" />
<el-table-column label="学习状态">
<template v-slot="{ row }">
<span v-if="row.COMPLETE_CLASSHOUR >= SUM_CLASSHOUR"> </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="考试结果">
<template v-slot="{ row }">
<span v-if="row.STAGEEXAMSCORE === '-1'"></span>
<span v-else-if="Number(row.STAGEEXAMSCORE) >= Number(PASSSCORE)">
已通过
</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template v-slot="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: '/online_learn_exam/task/student_details/learning_details',
query: { STUDYTASK_USERID: row.USER_ID, STUDYTASK_ID },
})
"
>
学习详情
</el-button>
</template>
</el-table-column>
</layout-table>
</layout-card>
</div>
</template>
<script setup>
import { ref } from "vue";
import LayoutDepartment from "@/components/department/index.vue";
import { useRoute, useRouter } from "vue-router";
import useListData from "@/assets/js/useListData.js";
import {
getTaskViewExaminationList,
getTaskViewInfo,
getTaskViewUserList,
} from "@/request/online_learn_exam.js";
const router = useRouter();
const route = useRoute();
const { STUDYTASK_ID } = route.query;
const SUM_CLASSHOUR = ref("");
const PASSSCORE = ref("");
const { list, searchForm, fnGetData } = useListData(getTaskViewUserList, {
otherParams: { STUDYTASK_ID },
usePagination: false,
});
const fnGetDataOther = async () => {
const { pd } = await getTaskViewInfo({ STUDYTASK_ID });
const { varList } = await getTaskViewExaminationList({ STUDYTASK_ID });
SUM_CLASSHOUR.value = pd.SUM_CLASSHOUR;
PASSSCORE.value = varList[0].PASSSCORE;
};
fnGetDataOther();
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,230 @@
<template>
<div>
<layout-card>
<el-descriptions :column="1" border>
<el-descriptions-item label="学习任务名称">
{{ data.info.STUDY_NAME }}
</el-descriptions-item>
<el-descriptions-item label="培训行业类型">
{{ data.info.post_type_name }}
</el-descriptions-item>
<el-descriptions-item label="岗位培训类型">
{{ data.info.train_type_name }}
</el-descriptions-item>
<el-descriptions-item label="培训时间">
<div style="display: flex; align-items: center">
<span>
{{ data.info.PEIXUE_START_TIME }} -
{{ data.info.PEIXUE_END_TIME }}
</span>
<el-button
type="primary"
size="small"
class="ml-10"
v-if="type === 'update' && data.info.PEIXUE_END_TIME"
@click="data.info.PEIXUE_END_TIME = ''"
>
编辑
</el-button>
<el-date-picker
style="width: 200px !important; margin-left: 10px"
v-if="!data.info.PEIXUE_END_TIME"
v-model="data.info.PEIXUE_END_TIME"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
type="date"
:disabled-date="fnDisabledDate"
/>
</div>
</el-descriptions-item>
<el-descriptions-item label="是否签到">
{{ data.info.KJ_STATE === 1 ? "是" : "否" }}
<br />
<span class="text-red">
开启签到后学员培训前需要进行电子手签并会记录到学员名册及考勤档案中
</span>
</el-descriptions-item>
<el-descriptions-item label="是否开启防挂机验证">
{{ data.info.KJ_STATE === 1 ? "是" : "否" }}
<br />
<span class="text-red">
开启放挂机验证员工学习过程会进行人脸识别确保是员工本人在培训
</span>
</el-descriptions-item>
<el-descriptions-item label="已选择课程">
<layout-table :data="data.curriculumList" :show-pagination="false">
<el-table-column label="课程名称" prop="CURRICULUMNAME" />
<el-table-column label="课件数" prop="COURSEWARECOUNT" />
</layout-table>
</el-descriptions-item>
<el-descriptions-item label="已选择人员">
<layout-table :data="data.oldUserList" :show-pagination="false">
<el-table-column label="用户名" prop="USERNAME" />
<el-table-column label="姓名" prop="NAME" />
<el-table-column label="部门" prop="DEPARTMENT_NAME" />
<el-table-column label="操作" v-if="type === 'update'">
<template v-slot="{ row, $index }">
<el-button
type="primary"
text
link
@click="fnDeleteOldUser(row.STAGESTUDENTRELATION_ID, $index)"
>
删除
</el-button>
</template>
</el-table-column>
<template #button>
<el-button
type="primary"
size="small"
v-if="type === 'update'"
@click="data.examinationUserDialogVisible = true"
>
添加人员
</el-button>
</template>
</layout-table>
</el-descriptions-item>
<el-descriptions-item
label="新添加人员"
v-if="data.newUserList.length > 0"
>
<layout-table :data="data.newUserList" :show-pagination="false">
<el-table-column label="用户名" prop="USERNAME" />
<el-table-column label="姓名" prop="NAME" />
<el-table-column label="部门" prop="DEPARTMENT_NAME" />
<el-table-column label="操作" v-if="type === 'update'">
<template v-slot="{ row, $index }">
<el-button
type="primary"
text
link
@click="fnDeleteNewUser(row.USER_ID, $index)"
>
删除
</el-button>
</template>
</el-table-column>
</layout-table>
</el-descriptions-item>
<el-descriptions-item label="已设置考试">
<layout-table :data="data.examinationList" :show-pagination="false">
<el-table-column label="考试名称" prop="EXAMNAME" />
<el-table-column label="考试时长" prop="ANSWERSHEETTIME" />
<el-table-column label="试卷名称" prop="shijuanName" />
</layout-table>
</el-descriptions-item>
</el-descriptions>
<div class="mt-10 tc" v-if="type === 'update'">
<el-button type="primary" @click="fnSubmit"></el-button>
</div>
</layout-card>
<user
v-model:visible="data.examinationUserDialogVisible"
v-model:user-list="data.userListAll"
type="1"
@submit="fnUserDialogSubmit"
/>
</div>
</template>
<script setup>
import LayoutCard from "@/components/card/index.vue";
import LayoutTable from "@/components/table/index.vue";
import { useRoute, useRouter } from "vue-router";
import { reactive } from "vue";
import {
getTaskViewExaminationList,
getTaskViewInfo,
getTaskViewUserList,
setTaskUpdate,
} from "@/request/online_learn_exam.js";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
import User from "@/views/online_learn_exam/task/components/user.vue";
import { differenceWith } from "lodash-es";
const route = useRoute();
const router = useRouter();
const { STUDYTASK_ID, type } = route.query;
const data = reactive({
info: {},
curriculumList: [],
userList: [],
oldUserList: [],
newUserList: [],
examinationList: [],
deleteUserList: [],
examinationUserDialogVisible: false,
});
const fnGetData = async () => {
const { pd, scurAllList } = await getTaskViewInfo({ STUDYTASK_ID });
const { varList: userList } = await getTaskViewUserList({
STUDYTASK_ID,
});
const { varList: examinationList } = await getTaskViewExaminationList({
STUDYTASK_ID,
});
data.info = pd;
data.curriculumList = scurAllList;
data.userListAll = [...userList];
data.oldUserList = userList;
data.examinationList = examinationList;
};
fnGetData();
const fnDisabledDate = (time) => {
return (
time.getTime() < new Date().getTime() ||
time.getTime() < new Date(data.info.PEIXUE_START_TIME).getTime()
);
};
const fnDeleteOldUser = (STAGESTUDENTRELATION_ID, index) => {
data.deleteUserList.push(STAGESTUDENTRELATION_ID);
data.oldUserList.splice(index, 1);
data.userListAll.splice(
data.userListAll.findIndex(
(item) => item.STAGESTUDENTRELATION_ID === STAGESTUDENTRELATION_ID
),
1
);
};
const fnDeleteNewUser = (USER_ID, index) => {
data.newUserList.splice(index, 1);
data.userListAll.splice(
data.userListAll.findIndex((item) => item.USER_ID === USER_ID),
1
);
};
const fnUserDialogSubmit = (selectionData) => {
data.newUserList = differenceWith(selectionData, data.oldUserList, (a, b) => {
return a.USER_ID === b.USER_ID;
});
};
const fnSubmit = debounce(
1000,
async () => {
if (!data.info.PEIXUE_END_TIME) {
ElMessage.warning("请培训时间结束时间");
return;
}
if (data.userList.length === 0 && data.newUserList.length === 0) {
ElMessage.warning("请选择人员");
return;
}
const userIds = data.newUserList.map((item) => item.USER_ID).join(",");
await setTaskUpdate({
deleteUserIds: data.deleteUserList.join(","),
STUDYTASK_ID,
STAGEEXAMPAPER_ID: data.info.STAGEEXAMPAPER_ID,
PEIXUE_END_TIME: data.info.PEIXUE_END_TIME,
userIds,
});
ElMessage.success("保存成功");
router.back();
},
{ atBegin: true }
);
</script>
<style lang="scss" scoped></style>