forked from integrated_whb/integrated_whb_vue
Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # src/views/enterprise_management/department/components/add.vuedev
commit
02a0c7fcae
File diff suppressed because it is too large
Load Diff
|
@ -21,7 +21,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,7 +46,8 @@
|
|||
"vue3-pdfjs": "^0.1.6",
|
||||
"vue3-print-nb": "^0.1.4",
|
||||
"vue3-puzzle-vcode": "^1.1.5",
|
||||
"vue3-seamless-scroll": "^2.0.1"
|
||||
"vue3-seamless-scroll": "^2.0.1",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@our-patches/postcss-px-to-viewport": "^1.2.0",
|
||||
|
|
|
@ -298,6 +298,7 @@
|
|||
.el-dialog {
|
||||
background: transparent !important;
|
||||
--el-dialog-margin-top: 50px !important;
|
||||
padding: 0 !important;
|
||||
|
||||
.el-dialog__header {
|
||||
background-image: url("/src/assets/images/public/tctitlebg.png");
|
||||
|
@ -321,8 +322,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.el-dialog__body, .el-dialog__footer {
|
||||
.el-dialog__body {
|
||||
background-color: var(--el-bullet-frame-bg-color);
|
||||
padding: calc(var(--el-dialog-padding-primary) + 10px) var(--el-dialog-padding-primary);
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
background-color: var(--el-bullet-frame-bg-color);
|
||||
padding: var(--el-dialog-padding-primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,3 +425,7 @@
|
|||
.el-color-predefine__color-selector.selected {
|
||||
--el-color-primary: #fff !important;
|
||||
}
|
||||
|
||||
.el-input-number.is-disabled .el-input-number__decrease, .el-input-number.is-disabled .el-input-number__increase{
|
||||
border-color: var(--el-border-color) !important;
|
||||
}
|
||||
|
|
|
@ -224,12 +224,12 @@ export const layoutFnGetInsuranceCompany = async () => {
|
|||
// 培训类型
|
||||
export const layoutFnGetTrainingType = async (params) => {
|
||||
const resData = await getTrainingType(params);
|
||||
return ref(resData.trainingtypelist);
|
||||
return ref(resData.varList);
|
||||
};
|
||||
// 行业类型
|
||||
export const layoutFnGetIndustryType = async (params) => {
|
||||
const resData = await getIndustryType(params);
|
||||
return ref(JSON.parse(resData.zTreeNodes));
|
||||
return ref(resData.zTreeNodes);
|
||||
};
|
||||
// 岗位类型
|
||||
export const layoutFnGetPostType = async (params) => {
|
||||
|
@ -241,3 +241,10 @@ export const layoutFnGetTrainingLevel = async (params) => {
|
|||
const resData = await getTrainingLevel(params);
|
||||
return ref(resData.varList);
|
||||
};
|
||||
// 试题标签
|
||||
export const layoutFnGetTestQuestionLabels = async () => {
|
||||
const resData = await getLevels({
|
||||
DICTIONARIES_ID: "a60ebc858e2c46108bf82bbd8acc8f50",
|
||||
});
|
||||
return ref(resData.list);
|
||||
};
|
||||
|
|
|
@ -103,11 +103,11 @@
|
|||
<el-radio-group v-model="form.RECTIFICATIONTYPE">
|
||||
<el-radio
|
||||
:disabled="form.HIDDENLEVEL === 'hiddenLevel0002'"
|
||||
label="1"
|
||||
value="1"
|
||||
>
|
||||
立即整改
|
||||
</el-radio>
|
||||
<el-radio label="2">限期整改</el-radio>
|
||||
<el-radio value="2">限期整改</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -133,7 +133,7 @@ export const getStandardLevels = () =>
|
|||
});
|
||||
// 培训类型
|
||||
export const getTrainingType = (params) =>
|
||||
post("/trainingtype/privateList", {
|
||||
post("/trainingtype/listAll", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { post } from "@/request/axios.js";
|
||||
import { post, upload } from "@/request/axios.js";
|
||||
|
||||
export const getStudentsList = (params) =>
|
||||
post("/archives/getStudentsList", params); // 一人一档用户列表
|
||||
|
@ -24,6 +24,8 @@ export const getLearningRecord = (params) =>
|
|||
export const getDict = (params) => post("/dictionaries/getLevels", params); // 获取人员类型
|
||||
export const downloadFilesdetailword = (params) =>
|
||||
post("/archives/filesdetailword", params); // 一人一档:档案详情导出
|
||||
export const downloadAward = (params) =>
|
||||
post("/archives/batchDownloadWord", params); // 一人一档:补充档案导出
|
||||
|
||||
export const getClassPapers = (params) =>
|
||||
post("/archives/getClassPapers", params); // 一期一档:班级试卷列表
|
||||
|
@ -70,12 +72,19 @@ export const downloadSign = (params) => post("/archives/sign", params); // 一
|
|||
|
||||
export const downloadAllwordzip = (params) =>
|
||||
post("/archivesallcorpword/allwordzip", params); // 一企一档:档案目录
|
||||
export const getArchivesfilesList = (params) =>
|
||||
post("/archivesfiles/list", params); // 一企一档列表
|
||||
export const getArchivesPostmanList = (params) =>
|
||||
post("/archivespostman/list", params); // 一企一档:年度三岗人员管理台账列表
|
||||
export const downloadPersonmanage = (params) =>
|
||||
post("/archivespostman/personmanage", params); // 一企一档:三岗人员管理台账导出
|
||||
export const getPostmanView = (params) =>
|
||||
post("/archivespostman/goEdit", params); // 一企一档:三岗人员管理台账查看
|
||||
export const setPostmanDelete = (params) =>
|
||||
post("/archivespostman/delete", params); // 一企一档:三岗人员管理台账删除
|
||||
export const setPostmanAdd = (params) => upload("/archivespostman/add", params); // 一企一档:三岗人员管理台账添加
|
||||
export const setPostmanEdit = (params) =>
|
||||
upload("/archivespostman/edit", params); // 一企一档:三岗人员管理台账修改
|
||||
export const setPostmanImport = (params) =>
|
||||
upload("/archivespostman/readExcel", params); // 一企一档:三岗人员管理台账导入
|
||||
export const getArchivesTeacherList = (params) =>
|
||||
post("/archivesteacher/list", params); // 一企一档:年度本单位师资管理台账
|
||||
export const getArchivesPlanList = (params) =>
|
||||
|
@ -84,6 +93,18 @@ export const getArchivesManagerList = (params) =>
|
|||
post("/archivesedumanager/list", params); // 一企一档:年度安全培训教育管理台账
|
||||
export const getArchivesCapitalList = (params) =>
|
||||
post("/archivescapital/list", params); // 一企一档:年度培训资金提取和使用情况管理台账
|
||||
export const setCapitalDelete = (params) =>
|
||||
post("/archivescapital/delete", params); // 一企一档:年度培训资金提取和使用情况管理台账删除
|
||||
export const getCapitalView = (params) =>
|
||||
post("/archivescapital/goEdit", params); // 一企一档:年度培训资金提取和使用情况管理台账查看
|
||||
export const setCapitalAdd = (params) => post("/archivescapital/add", params); // 一企一档:年度培训资金提取和使用情况管理台账添加
|
||||
export const setCapitalEdit = (params) => post("/archivescapital/edit", params); // 一企一档:年度培训资金提取和使用情况管理台账修改
|
||||
export const setArchivesFilesUpload = (params) =>
|
||||
upload("/archivesfiles/add", params); // 一企一档:上传pdf文件
|
||||
export const getArchivesFilesList = (params) =>
|
||||
post("/archivesfiles/listAll", params); // 一企一档:获取附件
|
||||
export const setArchivesFilesDelete = (params) =>
|
||||
post("/archivesfiles/delete", params); // 一企一档:删除附件
|
||||
export const downloadFundmanageword = (params) =>
|
||||
post("/archivescapital/fundmanageword", params); // 一企一档:年度培训资金提取和使用情况管理台账导出
|
||||
export const downloadTrainingplanword = (params) =>
|
||||
|
@ -96,3 +117,12 @@ export const downloadTeacherword = (params) =>
|
|||
export const getPdffileList = (params) => post("/archivespdffile/list", params); // 档案下载重新下载
|
||||
export const redownLoad = (params) =>
|
||||
post("/archivespdffile/redownload", params); // 档案下载重新下载
|
||||
export const getClassStrengthenDetailsList = (params) =>
|
||||
post("/class/strengthenlist", params); // 效果评估:班级列表
|
||||
export const getStudentStrengthenDetailsList = (params) =>
|
||||
post("/class/strengthenstudentlist", params); // 效果评估:学员列表
|
||||
export const getClassEvaluation = (params) =>
|
||||
post("/class/getEvaluation", params); // 获取班级效果评估表信息
|
||||
export const getStudentEvaluation = (params) =>
|
||||
post("/student/getEvaluation", params); // 获取个人效果评估表信息
|
||||
export const downloadClassEvaluation = (params) => post("class/hs", params); // 导出班级效果评估表信息
|
||||
|
|
|
@ -1,4 +1,48 @@
|
|||
import { post } from "@/request/axios.js";
|
||||
import { post, upload } from "@/request/axios.js";
|
||||
|
||||
export const setExamPaperManagementDelete = (params) =>
|
||||
post("/stageexampaperinput/delete", params); // 试卷管理删除
|
||||
export const setExamPaperManagementAdd = (params) =>
|
||||
upload("/stageexampaperinput/add", params); // 试卷管理添加
|
||||
export const setExamPaperManagementEdit = (params) =>
|
||||
upload("/stageexampaperinput/edit", params); // 试卷管理修改
|
||||
export const setExamPaperManagementInherit = (params) =>
|
||||
post("/stageexampaperinput/inherit", params); // 试卷管理继承
|
||||
export const setExamPaperManagementAddToDraft = (params) =>
|
||||
upload("/stageexampaperCache/add", params); // 试卷管理保存到草稿
|
||||
export const setExamPaperManagementTestQuestionsDelete = (params) =>
|
||||
post("/paperQuestion/delete", params); // 试卷管理试题删除
|
||||
export const setExamPaperManagementTestQuestionsAdd = (params) =>
|
||||
post("/paperQuestion/add", params); // 试卷管理试题新增
|
||||
export const setExamPaperManagementTestQuestionsEdit = (params) =>
|
||||
post("/paperQuestion/edit", params); // 试卷管理试题修改
|
||||
export const getAssociatedCoursewareNameList = (params) =>
|
||||
post("/videocourseware/getCourseWareName", params); // 关联课件名称
|
||||
export const getClassManagementList = (params) => post("/class/list", params); // 班级管理列表
|
||||
export const setClassManagementDelete = (params) =>
|
||||
post("/class/delete", params); // 班级管理删除
|
||||
export const setClassManagementDelay = (params) =>
|
||||
post("/class/postpone", params); // 班级管理延期
|
||||
export const getPersonnelList = (params) =>
|
||||
post("/trainedusersign/listByEnt", { loading: false, params }); // 班级管理添加人员
|
||||
export const getClassManagementView = (params) => post("/class/goEdit", params); // 班级管理查看
|
||||
export const setClassManagementAdd = (params) => post("/class/add", params); // 班级管理添加
|
||||
export const setClassManagementEdit = (params) => post("/class/edit", params); // 班级管理修改
|
||||
export const setClassManagementModifyExamTimes = (params) =>
|
||||
post("/class/editNumberofexams", params); // 班级管理修改考试次数
|
||||
export const getClassManagementStudentList = (params) =>
|
||||
post("/student/classStudentList", params); // 班级管理学员列表
|
||||
export const getClassManagementExportLearningRecords = (params) =>
|
||||
post("/student/exportStudentList", params); // 班级管理导出学员学习记录
|
||||
export const setClassManagementStudentDelete = (params) =>
|
||||
post("/student/deleteStudent", params); // 班级管理学员删除
|
||||
export const getClassManagementSelectStudentList = (params) =>
|
||||
post("/user/studentList", params); // 班级管理新增学员列表
|
||||
export const getClassManagementSelectStudentAdd = (params) =>
|
||||
post("/student/add", params); // 班级管理新增学员保存
|
||||
export const getClassManagementStudentLearningRecordsList = (params) =>
|
||||
post("/coursestudyvideorecord/getAllByuserInfo", params); // 班级管理学员学习记录列表
|
||||
export const getClassManagementStudentExamRecordsList = (params) =>
|
||||
post("/stageexam/list", params); // 班级管理学员考试记录列表
|
||||
export const getClassManagementStudentExamRecordsView = (params) =>
|
||||
post("/stageexam/findExam", params); // 班级管理学员考试记录查看
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
v-if="data.component"
|
||||
v-model:type="data.type"
|
||||
:title="data.title"
|
||||
:corp-name="data.corp_name"
|
||||
:year="data.YEAR"
|
||||
/>
|
||||
</el-card>
|
||||
|
@ -53,6 +54,7 @@ import Eduplan from "./components/eduplan";
|
|||
import Edumanager from "./components/edumanager";
|
||||
import Capital from "./components/capital";
|
||||
import { downloadAllwordzip } from "@/request/training_archive_management.js";
|
||||
import { getEnterpriseInfo } from "@/request/enterprise_management.js";
|
||||
|
||||
const data = reactive({
|
||||
list: [
|
||||
|
@ -81,8 +83,14 @@ const data = reactive({
|
|||
YEAR: dayjs().format("YYYY"),
|
||||
component: "",
|
||||
type: "",
|
||||
corp_name: "",
|
||||
title: "",
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
const resData = await getEnterpriseInfo();
|
||||
data.corp_name = resData.pd.CORP_NAME;
|
||||
};
|
||||
fnGetData();
|
||||
const fnExport = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
|
|
|
@ -6,13 +6,22 @@
|
|||
@close="fnClose"
|
||||
>
|
||||
<div class="tr">
|
||||
<el-button type="primary" @click="list.push({})">新增</el-button>
|
||||
<el-button type="danger" @click="fnDelete">删除</el-button>
|
||||
<el-button type="primary" @click="fnExport">导出</el-button>
|
||||
</div>
|
||||
<div class="tc">
|
||||
<h3>{{ year }}年度培训资金提取和使用情况管理台账</h3>
|
||||
</div>
|
||||
<p class="mb">单位名称:{{ name }}</p>
|
||||
<layout-table :data="data.list" :show-pagination="false">
|
||||
<p class="mb">单位名称:{{ corpName }}</p>
|
||||
<layout-table
|
||||
:data="list"
|
||||
:show-pagination="false"
|
||||
:stripe="false"
|
||||
:highlight-current-row="true"
|
||||
@row-click="fnRowClick"
|
||||
@row-dblclick="fnRowDblclick"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="DATE" label="日期" />
|
||||
<el-table-column label="费用项目">
|
||||
|
@ -32,6 +41,43 @@
|
|||
</el-table-column>
|
||||
<el-table-column prop="BALANCE" label="余额" />
|
||||
</layout-table>
|
||||
<table class="print_use dn">
|
||||
<thead>
|
||||
<tr>
|
||||
<td rowspan="2">序号</td>
|
||||
<td rowspan="2">日期</td>
|
||||
<td colspan="9">费用项目</td>
|
||||
<td rowspan="2">余额</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>提取金额</td>
|
||||
<td>培训教材教具费</td>
|
||||
<td>师资费</td>
|
||||
<td>试卷印制费</td>
|
||||
<td>外出培训费</td>
|
||||
<td>教学设备、课桌椅等购置维护费</td>
|
||||
<td>培训活动费</td>
|
||||
<td>委托培训费</td>
|
||||
<td>其他与培训有关的直接支出</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in list" :key="index">
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>{{ item.DATE }}</td>
|
||||
<td>{{ item.AMOUNT }}</td>
|
||||
<td>{{ item.MATERIAL_COST }}</td>
|
||||
<td>{{ item.TEACHER_COST }}</td>
|
||||
<td>{{ item.PAPER_COST }}</td>
|
||||
<td>{{ item.OUTSIDE_COST }}</td>
|
||||
<td>{{ item.EQUIPMENT_COST }}</td>
|
||||
<td>{{ item.TRAIN_COST }}</td>
|
||||
<td>{{ item.ENTRUST_COST }}</td>
|
||||
<td>{{ item.OTHER_COST }}</td>
|
||||
<td>{{ item.BALANCE }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex mt">
|
||||
<div>制表人:</div>
|
||||
<div>编制日期:</div>
|
||||
|
@ -45,17 +91,28 @@
|
|||
<el-button @click="fnClose">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<capital-add
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
:type="data.addOrEditDialog.type"
|
||||
:year="year"
|
||||
@get-data="fnGetData"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import LayoutTable from "@/components/table/index";
|
||||
import { reactive, watchEffect } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { nextTick, reactive, watchEffect } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import {
|
||||
getArchivesCapitalList,
|
||||
downloadFundmanageword,
|
||||
setCapitalDelete,
|
||||
getCapitalView,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import capitalAdd from "./capital_add.vue";
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
|
@ -66,31 +123,44 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
CORPINFO_ID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
year: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const data = reactive({
|
||||
list: [],
|
||||
ARCHIVESCAPITAL_ID: "",
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
DATE: "",
|
||||
AMOUNT: "",
|
||||
MATERIAL_COST: "",
|
||||
TEACHER_COST: "",
|
||||
PAPER_COST: "",
|
||||
OUTSIDE_COST: "",
|
||||
EQUIPMENT_COST: "",
|
||||
TRAIN_COST: "",
|
||||
ENTRUST_COST: "",
|
||||
OTHER_COST: "",
|
||||
BALANCE: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:type"]);
|
||||
const fnGetData = async () => {
|
||||
const resData = await getArchivesCapitalList({
|
||||
const { list, fnGetData } = useListData(getArchivesCapitalList, {
|
||||
otherParams: {
|
||||
TYPE: props.type,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
YEAR: props.year,
|
||||
});
|
||||
data.list = resData.varList;
|
||||
};
|
||||
},
|
||||
usePagination: false,
|
||||
immediate: false,
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (props.type === 105) fnGetData();
|
||||
});
|
||||
|
@ -100,8 +170,7 @@ const fnExport = debounce(
|
|||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
await downloadFundmanageword({
|
||||
YEAR: props.year,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
NAME: props.name,
|
||||
NAME: props.corpName,
|
||||
});
|
||||
await ElMessageBox.confirm(
|
||||
"导出后请前往档案下载中下载该档案!",
|
||||
|
@ -111,6 +180,35 @@ const fnExport = debounce(
|
|||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnRowClick = (row) => {
|
||||
data.ARCHIVESCAPITAL_ID = row.ARCHIVESCAPITAL_ID;
|
||||
};
|
||||
const fnRowDblclick = async (row) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
if (row.ARCHIVESCAPITAL_ID) {
|
||||
const resData = await getCapitalView({
|
||||
ARCHIVESCAPITAL_ID: row.ARCHIVESCAPITAL_ID,
|
||||
});
|
||||
data.addOrEditDialog.form = resData.pd;
|
||||
data.addOrEditDialog.type = "edit";
|
||||
} else data.addOrEditDialog.type = "add";
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
if (data.ARCHIVESCAPITAL_ID) {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setCapitalDelete({
|
||||
ARCHIVESCAPITAL_ID: data.ARCHIVESCAPITAL_ID,
|
||||
});
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
data.ARCHIVESCAPITAL_ID = "";
|
||||
fnGetData();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnClose = () => {
|
||||
emits("update:type", 0);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:append-to-body="true"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:on-close="fnClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="220px">
|
||||
<el-form-item label="日期" prop="DATE">
|
||||
<el-date-picker
|
||||
v-model="form.DATE"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="提取金额 " prop="AMOUNT">
|
||||
<el-input v-model="form.AMOUNT" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目类型 " prop="ITEM_TYPE">
|
||||
<el-input v-model="form.ITEM_TYPE" />
|
||||
</el-form-item>
|
||||
<el-form-item label="培训教材教具费" prop="MATERIAL_COST">
|
||||
<el-input v-model="form.MATERIAL_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="师资费 " prop="TEACHER_COST">
|
||||
<el-input v-model="form.TEACHER_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="试卷印制费 " prop="PAPER_COST">
|
||||
<el-input v-model="form.PAPER_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="外出培训费 " prop="OUTSIDE_COST">
|
||||
<el-input v-model="form.OUTSIDE_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="教学设备、课桌椅等购置维护费 " prop="EQUIPMENT_COST">
|
||||
<el-input v-model="form.EQUIPMENT_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="培训活动费 " prop="TRAIN_COST">
|
||||
<el-input v-model="form.TRAIN_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="委托培训费 " prop="ENTRUST_COST">
|
||||
<el-input v-model="form.ENTRUST_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="其他与培训有关的直接支出" prop="OTHER_COST">
|
||||
<el-input v-model="form.OTHER_COST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="余额" prop="BALANCE">
|
||||
<el-input v-model="form.BALANCE" />
|
||||
</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 { ref } from "vue";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import {
|
||||
setCapitalAdd,
|
||||
setCapitalEdit,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
year: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const rules = {
|
||||
DATE: [{ required: true, message: "请选择日期", trigger: "blur" }],
|
||||
AMOUNT: [{ required: true, message: "提取金额不能为空", trigger: "blur" }],
|
||||
ITEM_TYPE: [{ required: true, message: "项目类型不能为空", trigger: "blur" }],
|
||||
MATERIAL_COST: [
|
||||
{ required: true, message: "培训教材教具费不能为空", trigger: "blur" },
|
||||
],
|
||||
TEACHER_COST: [
|
||||
{ required: true, message: "师资费不能为空", trigger: "blur" },
|
||||
],
|
||||
PAPER_COST: [
|
||||
{ required: true, message: "试卷印制费不能为空", trigger: "blur" },
|
||||
],
|
||||
OUTSIDE_COST: [
|
||||
{ required: true, message: "外出培训费不能为空", trigger: "blur" },
|
||||
],
|
||||
EQUIPMENT_COST: [
|
||||
{
|
||||
required: true,
|
||||
message: "教学设备、课桌椅等购置维护费不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
TRAIN_COST: [
|
||||
{ required: true, message: "培训活动费不能为空", trigger: "blur" },
|
||||
],
|
||||
ENTRUST_COST: [
|
||||
{ required: true, message: "委托培训费不能为空", trigger: "blur" },
|
||||
],
|
||||
OTHER_COST: [
|
||||
{
|
||||
required: true,
|
||||
message: "其他与培训有关的直接支出不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
BALANCE: [{ required: true, message: "余额不能为空", trigger: "blur" }],
|
||||
};
|
||||
const formRef = ref(null);
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
props.type === "add"
|
||||
? await setCapitalAdd({ ...props.form, YEAR: props.year })
|
||||
: await setCapitalEdit({ ...props.form });
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("get-data");
|
||||
},
|
||||
{
|
||||
atBegin: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -11,8 +11,8 @@
|
|||
<div class="tc">
|
||||
<h3>{{ year }}年度安全培训教育管理台账</h3>
|
||||
</div>
|
||||
<p class="mb">单位名称:{{ name }}</p>
|
||||
<layout-table :data="data.list" :show-pagination="false">
|
||||
<p class="mb">单位名称:{{ corpName }}</p>
|
||||
<layout-table :data="list" :show-pagination="false">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="TRAINING_DATE" label="培训时间" />
|
||||
<el-table-column prop="TRAINING_OBJECT" label="培训对象" />
|
||||
|
@ -27,9 +27,7 @@
|
|||
<el-table-column prop="TRAINING_CONTENT" label="培训内容" />
|
||||
<el-table-column prop="PERSON_NUMBER" label="参加人数" />
|
||||
<el-table-column prop="CLASS_HOURS" label="培训学时" />
|
||||
<el-table-column prop="TRAINING_PLACE" label="培训地点">
|
||||
<span>{{ name }}</span>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CORP_NAME" label="培训地点" />
|
||||
<el-table-column prop="TRAINING_TEACHERS" label="培训教师" />
|
||||
<el-table-column prop="ASSESSMENT_METHOD" label="考核方式">
|
||||
<span>线上考核</span>
|
||||
|
@ -60,13 +58,14 @@
|
|||
|
||||
<script setup>
|
||||
import LayoutTable from "@/components/table/index";
|
||||
import { reactive, watchEffect } from "vue";
|
||||
import { watchEffect } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import {
|
||||
getArchivesManagerList,
|
||||
downloadEdumanageword,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
|
@ -77,11 +76,7 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
CORPINFO_ID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
@ -90,19 +85,15 @@ const props = defineProps({
|
|||
required: true,
|
||||
},
|
||||
});
|
||||
const data = reactive({
|
||||
list: [],
|
||||
});
|
||||
const emits = defineEmits(["update:type"]);
|
||||
const fnGetData = async () => {
|
||||
const resData = await getArchivesManagerList({
|
||||
const { list, fnGetData } = useListData(getArchivesManagerList, {
|
||||
otherParams: {
|
||||
TYPE: props.type,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
YEAR: props.year,
|
||||
});
|
||||
|
||||
data.list = resData.varList;
|
||||
};
|
||||
},
|
||||
usePagination: false,
|
||||
immediate: false,
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (props.type === 104) fnGetData();
|
||||
});
|
||||
|
@ -112,8 +103,7 @@ const fnExport = debounce(
|
|||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
await downloadEdumanageword({
|
||||
YEAR: props.year,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
NAME: props.name,
|
||||
NAME: props.corpName,
|
||||
});
|
||||
await ElMessageBox.confirm(
|
||||
"导出后请前往档案下载中下载该档案!",
|
||||
|
|
|
@ -7,15 +7,13 @@
|
|||
>
|
||||
<div class="tr">
|
||||
<el-button type="primary" @click="fnExport">导出</el-button>
|
||||
<el-button type="primary" @click="data.dialogForFile = true"
|
||||
>上传文件</el-button
|
||||
>
|
||||
<el-button type="primary" @click="fnImport">上传文件</el-button>
|
||||
</div>
|
||||
<div class="tc">
|
||||
<h3>{{ year }}年度安全培训教育计划</h3>
|
||||
</div>
|
||||
<p class="mb">单位名称:{{ name }}</p>
|
||||
<layout-table :data="data.list" :show-pagination="false">
|
||||
<p class="mb">单位名称:{{ corpName }}</p>
|
||||
<layout-table :data="list" :show-pagination="false">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="START_TIME" label="开始时间" />
|
||||
<el-table-column prop="END_TIME" label="结束时间" />
|
||||
|
@ -28,9 +26,7 @@
|
|||
<span>线上考核</span>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CLASSHOUR" label="学时" />
|
||||
<el-table-column prop="PLACE" label="地点">
|
||||
<span>{{ name }}</span>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CORP_NAME" label="地点" />
|
||||
<el-table-column prop="TRAINING_TEACHERS" label="培训教师" />
|
||||
<el-table-column prop="FUND_GUARANTEE" label="经费保障">
|
||||
<span>安全生产投入</span>
|
||||
|
@ -43,28 +39,9 @@
|
|||
<div>档案管理人员:</div>
|
||||
<div>更新日期:</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">关闭</el-button>
|
||||
</template>
|
||||
<el-dialog
|
||||
v-model:visible="data.dialogForFile"
|
||||
:title="'安全培训教育计划'"
|
||||
top="50px"
|
||||
width="1200px"
|
||||
append-to-body
|
||||
>
|
||||
<file
|
||||
v-if="data.dialogForFile"
|
||||
:id="CORPINFO_ID"
|
||||
:year="year"
|
||||
:type="103"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="data.dialogForFile = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<template #footer> <el-button @click="fnClose">关闭</el-button> </template>
|
||||
<pdf
|
||||
v-if="data.dialogForFile"
|
||||
v-model:visible="data.dialogForFile.visible"
|
||||
:title="'安全培训教育计划'"
|
||||
:type="103"
|
||||
:year="year"
|
||||
|
@ -82,6 +59,7 @@ import {
|
|||
downloadTrainingplanword,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import Pdf from "./pdf.vue";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
|
@ -92,11 +70,7 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
@ -106,19 +80,16 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
const data = reactive({
|
||||
list: [],
|
||||
dialogForFile: false,
|
||||
dialogForFile: {
|
||||
visible: false,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:type"]);
|
||||
const fnGetData = async () => {
|
||||
const resData = await getArchivesPlanList({
|
||||
TYPE: props.type,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
ENTERPRISE_ID: props.ENTERPRISE_ID,
|
||||
YEAR: props.year,
|
||||
});
|
||||
data.list = resData.varList;
|
||||
};
|
||||
const { list, fnGetData } = useListData(getArchivesPlanList, {
|
||||
otherParams: { TYPE: props.type, YEAR: props.year },
|
||||
usePagination: false,
|
||||
immediate: false,
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (props.type === 103) fnGetData();
|
||||
});
|
||||
|
@ -128,8 +99,6 @@ const fnExport = debounce(
|
|||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
await downloadTrainingplanword({
|
||||
YEAR: props.year,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
ENTERPRISE_ID: props.ENTERPRISE_ID,
|
||||
NAME: props.name,
|
||||
});
|
||||
await ElMessageBox.confirm(
|
||||
|
@ -140,6 +109,9 @@ const fnExport = debounce(
|
|||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnImport = () => {
|
||||
data.dialogForFile.visible = !data.dialogForFile.visible;
|
||||
};
|
||||
const fnClose = () => {
|
||||
emits("update:type", 0);
|
||||
};
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="title"
|
||||
:model-value="
|
||||
type === 1 || type === 2 || type === 3 || type === 4 || type === 103
|
||||
type === 1 || type === 2 || type === 3 || type === 4 || visible
|
||||
"
|
||||
width="1100px"
|
||||
@close="fnClose"
|
||||
>
|
||||
<div>
|
||||
<layout-upload
|
||||
:file-list="[]"
|
||||
auto-upload
|
||||
:http-request="fnUpload"
|
||||
accept=".pdf"
|
||||
:show-file-list="false"
|
||||
:limit="999"
|
||||
>
|
||||
<template #tip>只能上传pdf文件</template>
|
||||
</layout-upload>
|
||||
</div>
|
||||
<div class="content-flex">
|
||||
<div class="content-left">
|
||||
<el-scrollbar style="height: 600px">
|
||||
<layout-table
|
||||
:data="data.list"
|
||||
:data="list"
|
||||
:show-header="false"
|
||||
:show-pagination="false"
|
||||
:border="false"
|
||||
|
@ -20,16 +33,26 @@
|
|||
@row-click="fnRowClick"
|
||||
>
|
||||
<el-table-column prop="FILE_NAME" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click.stop="fnDelete(row)">
|
||||
<el-icon color="red" class="mr-10">
|
||||
<delete />
|
||||
</el-icon>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<div v-if="!data.pdfSrc" class="content-tip">
|
||||
<div v-if="!pdfSrc" class="content-tip">
|
||||
<div class="box">
|
||||
<div class="icon">
|
||||
<icon-file-pdf-one
|
||||
theme="filled"
|
||||
size="60"
|
||||
size="50"
|
||||
fill="#fff"
|
||||
:stroke-width="3"
|
||||
/>
|
||||
|
@ -40,16 +63,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-scrollbar style="height: 600px">
|
||||
<div v-if="data.pdfSrc">
|
||||
<vue-pdf
|
||||
v-for="page in data.numOfPages"
|
||||
:key="page"
|
||||
:src="data.pdfSrc"
|
||||
:page="page"
|
||||
/>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<layout-pdf v-if="pdfSrc" :src="pdfSrc" model="normal" />
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
|
@ -59,13 +73,26 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import LayoutTable from "@/components/table/index";
|
||||
import { nextTick, reactive, watchEffect } from "vue";
|
||||
import { VuePdf, createLoadingTask } from "vue3-pdfjs/esm";
|
||||
import { getArchivesfilesList } from "@/request/training_archive_management.js";
|
||||
import {
|
||||
getArchivesFilesList,
|
||||
setArchivesFilesDelete,
|
||||
setArchivesFilesUpload,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import LayoutUpload from "@/components/upload/index.vue";
|
||||
import LayoutPdf from "@/components/pdf/index.vue";
|
||||
import { ref, watchEffect } from "vue";
|
||||
import { Delete } from "@element-plus/icons-vue";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
|
||||
const FILE_URL = import.meta.env.VITE_FILE_URL;
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
required: true,
|
||||
|
@ -74,7 +101,7 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
CORPINFO_ID: {
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
@ -83,21 +110,14 @@ const props = defineProps({
|
|||
required: true,
|
||||
},
|
||||
});
|
||||
const data = reactive({
|
||||
list: [],
|
||||
pdfSrc: "",
|
||||
numOfPages: 0,
|
||||
const emits = defineEmits(["update:visible", "update:type"]);
|
||||
const { visible } = useVModels(props, emits);
|
||||
const pdfSrc = ref("");
|
||||
const { list, fnGetData } = useListData(getArchivesFilesList, {
|
||||
otherParams: { TYPE: props.type, YEAR: props.year },
|
||||
usePagination: false,
|
||||
immediate: false,
|
||||
});
|
||||
const emits = defineEmits(["update:type"]);
|
||||
const fnGetData = async () => {
|
||||
const resData = await getArchivesfilesList({
|
||||
TYPE: props.type,
|
||||
YEAR: props.year,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
MODULE: "corp",
|
||||
});
|
||||
data.list = resData.varList;
|
||||
};
|
||||
watchEffect(() => {
|
||||
if (
|
||||
props.type === 1 ||
|
||||
|
@ -106,21 +126,38 @@ watchEffect(() => {
|
|||
props.type === 4 ||
|
||||
props.type === 103
|
||||
)
|
||||
fnGetData();
|
||||
fnGetData({ TYPE: props.type, YEAR: props.year });
|
||||
});
|
||||
const fnUpload = async (item) => {
|
||||
const formData = new FormData();
|
||||
formData.append("FFILE", item.file);
|
||||
formData.append("TYPE", props.type);
|
||||
formData.append("YEAR", props.year);
|
||||
await setArchivesFilesUpload(formData);
|
||||
fnGetData({ TYPE: props.type, YEAR: props.year });
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async ({ ARCHIVESFILES_ID, FILE_PATH }) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setArchivesFilesDelete({
|
||||
ARCHIVESFILES_ID,
|
||||
FILE_PATH,
|
||||
});
|
||||
ElMessage.success("删除成功");
|
||||
fnGetData({ TYPE: props.type, YEAR: props.year });
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnRowClick = async (row) => {
|
||||
data.pdfSrc = "";
|
||||
await nextTick();
|
||||
data.pdfSrc = FILE_URL + row.FILE_PATH;
|
||||
const loadingTask = createLoadingTask(FILE_URL + row.FILE_PATH);
|
||||
loadingTask.promise.then((pdf) => {
|
||||
data.numOfPages = pdf.numPages;
|
||||
});
|
||||
pdfSrc.value = row.FILE_PATH;
|
||||
};
|
||||
const fnClose = () => {
|
||||
data.pdfSrc = "";
|
||||
data.numOfPages = 0;
|
||||
pdfSrc.value = "";
|
||||
emits("update:type", 0);
|
||||
visible.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,13 +6,23 @@
|
|||
@close="fnClose"
|
||||
>
|
||||
<div class="tr">
|
||||
<el-button type="primary" @click="list.push({})">新增</el-button>
|
||||
<el-button type="danger" @click="fnDelete">删除</el-button>
|
||||
<el-button type="primary" @click="fnImport">导入</el-button>
|
||||
<el-button type="primary" @click="fnExport">导出</el-button>
|
||||
</div>
|
||||
<div class="tc">
|
||||
<h3>{{ year }}年度三岗人员管理台账</h3>
|
||||
</div>
|
||||
<p class="mb">单位名称:{{ name }}</p>
|
||||
<layout-table :data="data.list" :show-pagination="false">
|
||||
<p class="mb">单位名称:{{ corpName }}</p>
|
||||
<layout-table
|
||||
:data="list"
|
||||
:show-pagination="false"
|
||||
:stripe="false"
|
||||
:highlight-current-row="true"
|
||||
@row-click="fnRowClick"
|
||||
@row-dblclick="fnRowDblclick"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="NAME" label="姓名" />
|
||||
<el-table-column prop="POST" label="岗位/操作项目" />
|
||||
|
@ -30,12 +40,31 @@
|
|||
<el-table-column prop="CARD_ID" label="证书号" />
|
||||
<el-table-column prop="EFFECTIVE_DATE" label="证书有效期限" />
|
||||
<el-table-column prop="RETRAINING" label="复训日期" />
|
||||
<el-table-column prop="RETRAINING" label="操作" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" @click="handleEdit(row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
<table class="print_use dn">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>序号</td>
|
||||
<td>姓名</td>
|
||||
<td>岗位/操作项目</td>
|
||||
<td>电话</td>
|
||||
<td>证书号</td>
|
||||
<td>证书有效期限</td>
|
||||
<td>复训日期</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in list" :key="index">
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>{{ item.NAME }}</td>
|
||||
<td>{{ item.POST }}</td>
|
||||
<td>{{ item.PHONE }}</td>
|
||||
<td>{{ item.CARD_ID }}</td>
|
||||
<td>{{ item.EFFECTIVE_DATE }}</td>
|
||||
<td>{{ item.RETRAINING }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex mt">
|
||||
<div>档案管理人员:</div>
|
||||
<div>更新日期:</div>
|
||||
|
@ -43,18 +72,36 @@
|
|||
<template #footer>
|
||||
<el-button @click="fnClose">关闭</el-button>
|
||||
</template>
|
||||
<postman-add
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
:type="data.addOrEditDialog.type"
|
||||
:year="year"
|
||||
@get-data="fnGetData"
|
||||
/>
|
||||
<layout-import-file
|
||||
v-model:visible="data.importDialogVisible"
|
||||
template-url="/TrafficFile/template/post.xls"
|
||||
@submit="fnSubmitImport"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import LayoutTable from "@/components/table/index";
|
||||
import { reactive, watchEffect } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { nextTick, reactive, watchEffect } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import {
|
||||
getArchivesPostmanList,
|
||||
downloadPersonmanage,
|
||||
getPostmanView,
|
||||
setPostmanDelete,
|
||||
setPostmanImport,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import PostmanAdd from "./postman_add.vue";
|
||||
import LayoutImportFile from "@/components/import_file/index.vue";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
|
||||
const FILE_URL = import.meta.env.VITE_FILE_URL;
|
||||
const props = defineProps({
|
||||
|
@ -66,31 +113,37 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
CORPINFO_ID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
year: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const data = reactive({
|
||||
list: [],
|
||||
importDialogVisible: false,
|
||||
ARCHIVES_POSTMAN_ID: "",
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
NAME: "",
|
||||
POST: "",
|
||||
PHONE: "",
|
||||
CARD_ID: "",
|
||||
EFFECTIVE_DATE: "",
|
||||
RETRAINING: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:type"]);
|
||||
const fnGetData = async () => {
|
||||
const resData = await getArchivesPostmanList({
|
||||
TYPE: props.type,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
YEAR: props.year,
|
||||
});
|
||||
data.list = resData.varList;
|
||||
};
|
||||
const { list, fnGetData } = useListData(getArchivesPostmanList, {
|
||||
otherParams: { TYPE: props.type, YEAR: props.year },
|
||||
usePagination: false,
|
||||
immediate: false,
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (props.type === 101) fnGetData();
|
||||
});
|
||||
|
@ -100,8 +153,7 @@ const fnExport = debounce(
|
|||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
await downloadPersonmanage({
|
||||
YEAR: props.year,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
NAME: props.name,
|
||||
NAME: props.corpName,
|
||||
});
|
||||
await ElMessageBox.confirm(
|
||||
"导出后请前往档案下载中下载该档案!",
|
||||
|
@ -111,6 +163,42 @@ const fnExport = debounce(
|
|||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnRowClick = (row) => {
|
||||
data.ARCHIVES_POSTMAN_ID = row.ARCHIVES_POSTMAN_ID;
|
||||
};
|
||||
const fnRowDblclick = async (row) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
if (row.ARCHIVES_POSTMAN_ID) {
|
||||
const resData = await getPostmanView({
|
||||
ARCHIVES_POSTMAN_ID: row.ARCHIVES_POSTMAN_ID,
|
||||
});
|
||||
data.addOrEditDialog.form = resData.pd;
|
||||
data.addOrEditDialog.type = "edit";
|
||||
} else data.addOrEditDialog.type = "add";
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
if (data.ARCHIVES_POSTMAN_ID) {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setPostmanDelete({
|
||||
ARCHIVES_POSTMAN_ID: data.ARCHIVES_POSTMAN_ID,
|
||||
});
|
||||
ElMessage.success("删除成功");
|
||||
}
|
||||
data.ARCHIVES_POSTMAN_ID = "";
|
||||
fnGetData();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnImport = () => {
|
||||
data.importDialogVisible = !data.importDialogVisible;
|
||||
};
|
||||
const fnSubmitImport = async (formData) => {
|
||||
const resData = await setPostmanImport(formData);
|
||||
ElMessage.success(resData.msg);
|
||||
};
|
||||
const fnClose = () => {
|
||||
emits("update:type", 0);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:append-to-body="true"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:on-close="fnClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="姓名" prop="NAME">
|
||||
<el-input v-model="form.NAME" />
|
||||
</el-form-item>
|
||||
<el-form-item label="岗位/操作项目" prop="POST">
|
||||
<el-input v-model="form.POST" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="PHONE">
|
||||
<el-input v-model="form.PHONE" />
|
||||
</el-form-item>
|
||||
<el-form-item label="照片" prop="hideUpload">
|
||||
<layout-upload
|
||||
v-model:file-list="form.hideUpload"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
list-type="picture-card"
|
||||
:limit="1"
|
||||
delete-to-server
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="证书号" prop="CARD_ID">
|
||||
<el-input v-model="form.CARD_ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="证书有效期限" prop="EFFECTIVE_DATE">
|
||||
<el-date-picker
|
||||
v-model="form.EFFECTIVE_DATE"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="date"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="复训日期" prop="RETRAINING">
|
||||
<el-date-picker
|
||||
v-model="form.RETRAINING"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="date"
|
||||
/>
|
||||
</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 { ref } from "vue";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import {
|
||||
setPostmanAdd,
|
||||
setPostmanEdit,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import LayoutUpload from "@/components/upload/index.vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
year: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const rules = {
|
||||
NAME: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
|
||||
POST: [{ required: true, message: "岗位/操作项目不能为空", trigger: "blur" }],
|
||||
PHONE: [
|
||||
{ required: true, message: "手机号不能为空", trigger: "blur" },
|
||||
{
|
||||
pattern:
|
||||
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
|
||||
message: "请输入正确的手机号",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
hideUpload: [{ required: true, message: "照片不能为空", trigger: "blur" }],
|
||||
CARD_ID: [{ required: true, message: "证书号不能为空", trigger: "blur" }],
|
||||
EFFECTIVE_DATE: [
|
||||
{ required: true, message: "请选择证书有效期限", trigger: "change" },
|
||||
],
|
||||
RETRAINING: [
|
||||
{ required: true, message: "请选择复训日期", trigger: "change" },
|
||||
],
|
||||
};
|
||||
const formRef = ref(null);
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
const formData = new FormData();
|
||||
Object.keys(props.form).forEach((key) => {
|
||||
formData.append(key, props.form[key]);
|
||||
});
|
||||
if (props.form.hideUpload[0].raw) {
|
||||
formData.append("FFILE", props.form.hideUpload[0].raw);
|
||||
}
|
||||
formData.append("YEAR", props.year);
|
||||
props.type === "add"
|
||||
? await setPostmanAdd(formData)
|
||||
: await setPostmanEdit(formData);
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("get-data");
|
||||
},
|
||||
{
|
||||
atBegin: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -11,8 +11,8 @@
|
|||
<div class="tc">
|
||||
<h3>{{ year }}年度本单位师资管理台账</h3>
|
||||
</div>
|
||||
<p class="mb">单位名称:{{ name }}</p>
|
||||
<layout-table :data="data.list" :show-pagination="false">
|
||||
<p class="mb">单位名称:{{ corpName }}</p>
|
||||
<layout-table :data="list" :show-pagination="false">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="NAME" label="姓名" />
|
||||
<el-table-column prop="WORKYEAR" label="从事本专业工作年限" />
|
||||
|
@ -37,13 +37,14 @@
|
|||
|
||||
<script setup>
|
||||
import LayoutTable from "@/components/table/index";
|
||||
import { reactive, watchEffect } from "vue";
|
||||
import { watchEffect } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import {
|
||||
getArchivesTeacherList,
|
||||
downloadTeacherword,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
|
@ -54,11 +55,7 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
CORPINFO_ID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
@ -67,18 +64,12 @@ const props = defineProps({
|
|||
required: true,
|
||||
},
|
||||
});
|
||||
const data = reactive({
|
||||
list: [],
|
||||
});
|
||||
const emits = defineEmits(["update:type"]);
|
||||
const fnGetData = async () => {
|
||||
const resData = await getArchivesTeacherList({
|
||||
TYPE: props.type,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
YEAR: props.year,
|
||||
});
|
||||
data.list = resData.varList;
|
||||
};
|
||||
const { list, fnGetData } = useListData(getArchivesTeacherList, {
|
||||
otherParams: { TYPE: props.type, YEAR: props.year },
|
||||
usePagination: false,
|
||||
immediate: false,
|
||||
});
|
||||
watchEffect(() => {
|
||||
if (props.type === 102) fnGetData();
|
||||
});
|
||||
|
@ -88,8 +79,7 @@ const fnExport = debounce(
|
|||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
await downloadTeacherword({
|
||||
YEAR: props.year,
|
||||
CORPINFO_ID: props.CORPINFO_ID,
|
||||
NAME: props.name,
|
||||
NAME: props.corpName,
|
||||
});
|
||||
await ElMessageBox.confirm(
|
||||
"导出后请前往档案下载中下载该档案!",
|
||||
|
|
|
@ -37,20 +37,20 @@
|
|||
v-model="item.ANSWER"
|
||||
:disabled="true"
|
||||
>
|
||||
<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 value="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<el-radio value="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
<el-radio value="C">C.{{ item.OPTIONC }}</el-radio>
|
||||
<el-radio value="D">D.{{ item.OPTIOND }}</el-radio>
|
||||
</el-radio-group>
|
||||
<el-checkbox-group
|
||||
v-if="item.QUESTIONTYPE === '2'"
|
||||
v-model="item.checkList"
|
||||
:disabled="true"
|
||||
>
|
||||
<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 value="A">A.{{ item.OPTIONA }}</el-checkbox>
|
||||
<el-checkbox value="B">B.{{ item.OPTIONB }}</el-checkbox>
|
||||
<el-checkbox value="C">C.{{ item.OPTIONC }}</el-checkbox>
|
||||
<el-checkbox value="D">D.{{ item.OPTIOND }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
<el-radio-group
|
||||
v-if="item.QUESTIONTYPE === '3'"
|
||||
|
@ -58,9 +58,9 @@
|
|||
:disabled="true"
|
||||
class="panduan"
|
||||
>
|
||||
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<el-radio value="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<div class="el-radio"></div>
|
||||
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
<el-radio value="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
<div class="el-radio"></div>
|
||||
</el-radio-group>
|
||||
</dl>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<div id="printContent">
|
||||
<h2 class="tc">学员考核成绩统计表</h2>
|
||||
<div class="flex mt mb">
|
||||
<span>平台名称:{{ data.info.CORPINFO_NAME }}</span>
|
||||
<span>平台名称:{{ corpName }}</span>
|
||||
<span
|
||||
>报表日期:{{ dayjs(data.clazz.END_TIME).format("YYYY-MM-DD") }}</span
|
||||
>
|
||||
|
@ -21,7 +21,7 @@
|
|||
<td colspan="2">公司名称</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{{ data.clazz.CORP_INFO }}</td>
|
||||
<td colspan="2">{{ corpName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>培训时间</td>
|
||||
|
@ -173,6 +173,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
corpName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const data = reactive({
|
||||
info: {},
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
<el-button type="primary" @click="fnExport">导出</el-button>
|
||||
</div>
|
||||
<div class="tc">
|
||||
<h3>{{ CORP_NAME }}培训计划</h3>
|
||||
<h3>{{ corpName }}培训计划</h3>
|
||||
</div>
|
||||
<p class="mb">单位名称:{{ CORP_INFO }}</p>
|
||||
<p class="mb">单位名称:{{ corpName }}</p>
|
||||
<layout-table :data="data.list" :show-pagination="false">
|
||||
<el-table-column type="index" label="序号" width="50" />
|
||||
<el-table-column label="培训人员类型"> 从业人员 </el-table-column>
|
||||
|
@ -33,7 +33,7 @@
|
|||
<el-table-column prop="TRAINING_TEACHERS" label="授课教师" />
|
||||
</layout-table>
|
||||
<div class="flex mt">
|
||||
<div>编制单位:{{ CORP_NAME }}</div>
|
||||
<div>编制单位:{{ corpName }}</div>
|
||||
<div>编制日期:</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
</div>
|
||||
<layout-table
|
||||
ref="tableRef"
|
||||
v-model:pagination="data.pagination"
|
||||
v-model:pagination="pagination"
|
||||
row-key="CURRICULUM_ID"
|
||||
:data="data.varlist"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column reserve-selection type="selection" width="55" />
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(data.pagination, $index) }}
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="CURRICULUMNAME" label="教材名称" />
|
||||
|
@ -50,17 +50,12 @@ import {
|
|||
getClassCurriculumList,
|
||||
downloadTeachingMaterialAll,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
|
||||
const route = useRoute();
|
||||
const { CLASS_ID } = route.query;
|
||||
const tableRef = ref(null);
|
||||
const data = reactive({
|
||||
varlist: [],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
},
|
||||
type: 0,
|
||||
CURRICULUM_ID: "",
|
||||
});
|
||||
|
@ -68,16 +63,9 @@ const fnView = (row) => {
|
|||
data.type = 106;
|
||||
data.CURRICULUM_ID = row.CURRICULUM_ID;
|
||||
};
|
||||
const fnGetData = async () => {
|
||||
const resData = await getClassCurriculumList({
|
||||
currentPage: data.pagination.currentPage,
|
||||
pageSize: data.pagination.pageSize,
|
||||
CLASS_ID,
|
||||
});
|
||||
data.varlist = resData.varList;
|
||||
data.pagination.total = resData.page.totalResult;
|
||||
};
|
||||
fnGetData();
|
||||
const { list, pagination, fnGetData } = useListData(getClassCurriculumList, {
|
||||
otherParams: { CLASS_ID },
|
||||
});
|
||||
const fnExport = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="data.searchForm"
|
||||
:model="searchForm"
|
||||
label-width="80px"
|
||||
@submit.prevent="fnResetPagination"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="试卷名称" prop="KEYWORDS">
|
||||
<el-input v-model="data.searchForm.KEYWORDS" />
|
||||
<el-input v-model="searchForm.KEYWORDS" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
|
@ -18,10 +18,7 @@
|
|||
<el-button native-type="reset" @click="fnResetPagination">
|
||||
重置
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="data.varlist.length > 0"
|
||||
type="primary"
|
||||
@click="fnExport"
|
||||
<el-button v-if="list.length > 0" type="primary" @click="fnExport"
|
||||
>导出</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
|
@ -30,15 +27,15 @@
|
|||
</el-form>
|
||||
<layout-table
|
||||
ref="tableRef"
|
||||
v-model:pagination="data.pagination"
|
||||
v-model:pagination="pagination"
|
||||
row-key="STAGEEXAMPAPERINPUT_ID"
|
||||
:data="data.varlist"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column reserve-selection type="selection" width="55" />
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(data.pagination, $index) }}
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="EXAMNAME" label="试卷名称" />
|
||||
|
@ -78,18 +75,12 @@ import {
|
|||
getClassPaperList,
|
||||
downloadArchivePapers,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
|
||||
const route = useRoute();
|
||||
const { CLASS_ID, CLASS_NAME } = route.query;
|
||||
const tableRef = ref(null);
|
||||
const data = reactive({
|
||||
varlist: [],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
},
|
||||
searchForm: {},
|
||||
type: 0,
|
||||
STAGEEXAMPAPERINPUT_ID: "",
|
||||
});
|
||||
|
@ -97,26 +88,8 @@ const fnView = (STAGEEXAMPAPERINPUT_ID) => {
|
|||
data.type = 103;
|
||||
data.STAGEEXAMPAPERINPUT_ID = STAGEEXAMPAPERINPUT_ID;
|
||||
};
|
||||
const fnGetData = async () => {
|
||||
const resData = await getClassPaperList({
|
||||
currentPage: data.pagination.currentPage,
|
||||
pageSize: data.pagination.pageSize,
|
||||
CLASS_ID,
|
||||
...data.searchForm,
|
||||
});
|
||||
data.varlist = resData.varList;
|
||||
data.pagination.total = resData.page.totalResult;
|
||||
};
|
||||
fnGetData();
|
||||
const fnResetPagination = () => {
|
||||
data.pagination = {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
};
|
||||
tableRef.value.clearSelection();
|
||||
fnGetData();
|
||||
};
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getClassPaperList, { otherParams: { CLASS_ID } });
|
||||
const fnExport = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
|
|
|
@ -727,16 +727,16 @@
|
|||
:disabled="true"
|
||||
>
|
||||
<dd>
|
||||
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<el-radio value="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
<el-radio value="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio label="C">C.{{ item.OPTIONC }}</el-radio>
|
||||
<el-radio value="C">C.{{ item.OPTIONC }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio label="D">D.{{ item.OPTIOND }}</el-radio>
|
||||
<el-radio value="D">D.{{ item.OPTIOND }}</el-radio>
|
||||
</dd>
|
||||
</el-radio-group>
|
||||
<el-checkbox-group
|
||||
|
@ -745,16 +745,16 @@
|
|||
:disabled="true"
|
||||
>
|
||||
<dd>
|
||||
<el-checkbox label="A">A.{{ item.OPTIONA }}</el-checkbox>
|
||||
<el-checkbox value="A">A.{{ item.OPTIONA }}</el-checkbox>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-checkbox label="B">B.{{ item.OPTIONB }}</el-checkbox>
|
||||
<el-checkbox value="B">B.{{ item.OPTIONB }}</el-checkbox>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-checkbox label="C">C.{{ item.OPTIONC }}</el-checkbox>
|
||||
<el-checkbox value="C">C.{{ item.OPTIONC }}</el-checkbox>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-checkbox label="D">D.{{ item.OPTIOND }}</el-checkbox>
|
||||
<el-checkbox value="D">D.{{ item.OPTIOND }}</el-checkbox>
|
||||
</dd>
|
||||
</el-checkbox-group>
|
||||
<el-radio-group
|
||||
|
@ -763,10 +763,10 @@
|
|||
:disabled="true"
|
||||
>
|
||||
<dd>
|
||||
<el-radio label="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
<el-radio value="A">A.{{ item.OPTIONA }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio label="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
<el-radio value="B">B.{{ item.OPTIONB }}</el-radio>
|
||||
</dd>
|
||||
</el-radio-group>
|
||||
<div class="flex">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<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">
|
||||
|
@ -23,6 +23,14 @@
|
|||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" @click="fnBatchDownload">
|
||||
下载补充档案
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary"> 班级档案 </el-button>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
@ -83,12 +91,42 @@ import { serialNumber } from "@/assets/js/utils.js";
|
|||
import useListData from "@/assets/js/useListData.js";
|
||||
import { ref } from "vue";
|
||||
|
||||
import { getStudentsList } from "@/request/training_archive_management.js";
|
||||
import {
|
||||
downloadAward,
|
||||
getStudentsList,
|
||||
} from "@/request/training_archive_management.js";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
|
||||
const tableRef = ref(null);
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getStudentsList);
|
||||
</script>
|
||||
|
||||
const fnBatchDownload = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
const selectionData = tableRef.value.getSelectionRows();
|
||||
if (selectionData.length === 0) {
|
||||
ElMessage.warning("请选中要下载的学员补充档案...");
|
||||
return;
|
||||
}
|
||||
const ids = selectionData
|
||||
.map((item) => {
|
||||
return item.USER_ID;
|
||||
})
|
||||
.join(",");
|
||||
await downloadAward({
|
||||
ids,
|
||||
});
|
||||
await ElMessageBox.confirm(
|
||||
"导出后请前往档案下载中下载该档案!",
|
||||
"温馨提示",
|
||||
{ type: "info" }
|
||||
);
|
||||
tableRef.value.clearSelection();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" width="1100px" title="效果评估表">
|
||||
<div class="tr mb">
|
||||
<el-button type="primary" @click="fnExport">导出</el-button>
|
||||
</div>
|
||||
<div id="printContent">
|
||||
<h1 style="text-align: center; margin-left: 60px">
|
||||
安全生产教育培训动态评估报告
|
||||
</h1>
|
||||
<p class="p1" style="width: 100%; text-align: center">
|
||||
企业名称:
|
||||
{{ data.evaluationDialogForm.CORP_NAME }}
|
||||
评估日期:
|
||||
{{ data.evaluationDialogForm.END_TIME }}
|
||||
</p>
|
||||
<h3>一、评估概述</h3>
|
||||
<p class="p1">
|
||||
本报告旨在对{{ data.evaluationDialogForm.CORP_NAME }}公司
|
||||
的安全生产培训进行动态评估,安全生产培训的目标是提高员工的安全意识和技能,促进工作场所的安全管理和事故预防。本报告将对培训的实施情况、培训效果、参与度、员工考试通过率、知识盲点以及可能的改进措施进行评估和分析。
|
||||
</p>
|
||||
<h3>二、评估内容</h3>
|
||||
<p class="p1">
|
||||
贵公司于{{ data.evaluationDialogForm.START_TIME }}时间 -
|
||||
{{ data.evaluationDialogForm.END_TIME }}时间进行了{{
|
||||
data.evaluationDialogForm.CLASS_NAME
|
||||
}}培训,培训内容如下:{{ data.evaluationDialogForm.coursewareName }}
|
||||
</p>
|
||||
<h3>三、考试结果</h3>
|
||||
<p class="p1">
|
||||
<b
|
||||
>(一)本次考试共{{
|
||||
data.evaluationDialogForm.EXMA_COUNT
|
||||
}}人参加,合格人数{{
|
||||
data.evaluationDialogForm.PASS_COUNT
|
||||
}}人,未合格人数{{
|
||||
data.evaluationDialogForm.NO_PASS_COUNT
|
||||
}}人,通过率{{
|
||||
data.evaluationDialogForm.passRate
|
||||
}}%。具体情况如下:</b
|
||||
>
|
||||
</p>
|
||||
<div id="chart" ref="chart" style="width: 900px; height: 320px" />
|
||||
<p class="p1"><b>(二)评估结果和分析</b></p>
|
||||
<p class="p1">
|
||||
基于评估结果和培训过程中的观察,我们对员工的知识盲点进行分析,指出可能存在的理解不足或需要加强的知识领域,主要知识盲点体现为:
|
||||
</p>
|
||||
<p class="p1">{{ data.evaluationDialogForm.error }}</p>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>标签名称</td>
|
||||
<td>错误率</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-for="(value, key) in data.evaluationDialogForm.ratioMap"
|
||||
:key="key"
|
||||
>
|
||||
<td>{{ key }}</td>
|
||||
<td>{{ value }}%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="p1">知识盲点对应课件为:</p>
|
||||
<p class="p1">{{ data.evaluationDialogForm.errorVideoName }}</p>
|
||||
<p class="p1"><b>(三)评估建议</b></p>
|
||||
<p class="p1">
|
||||
存在的知识盲点需要进一步加强和补充。我们建议您将重点放在弥补这些盲点上,通过进一步学习、参与讨论或与安全专家交流弥补知识盲区。
|
||||
</p>
|
||||
<h3>四、强化培训记录</h3>
|
||||
<p class="p1"><b>(一)强化培训考试记录</b></p>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td colspan="3">班级名称</td>
|
||||
<td colspan="3">培训时间</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">{{ data.evaluationDialogForm.CLASS_NAME }}</td>
|
||||
<td colspan="3">
|
||||
{{
|
||||
dayjs(data.evaluationDialogForm.START_TIME).format(
|
||||
"YYYY年MM月DD日"
|
||||
)
|
||||
}}
|
||||
-
|
||||
{{
|
||||
dayjs(data.evaluationDialogForm.END_TIME).format("YYYY年MM月DD日")
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">培训人数</td>
|
||||
<td colspan="3">合格人数</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">{{ data.evaluationDialogForm.STR_EXMA_COUNT }}</td>
|
||||
<td colspan="3">{{ data.evaluationDialogForm.STR_PASS_COUNT }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">合格学员名单</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 10%">序号</td>
|
||||
<td style="width: 15%">姓名</td>
|
||||
<td style="width: 25%">身份证号</td>
|
||||
<td style="width: 20%">手机号</td>
|
||||
<td style="width: 10%">性别</td>
|
||||
<td style="width: 25%">效果评估成绩</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-for="(value, key) in data.evaluationDialogForm.PASS_List"
|
||||
:key="key"
|
||||
>
|
||||
<td style="width: 10%">{{ key + 1 }}</td>
|
||||
<td style="width: 15%">{{ value.NAME }}</td>
|
||||
<td style="width: 25%">{{ value.USER_ID_CARD }}</td>
|
||||
<td style="width: 20%">{{ value.PHONE }}</td>
|
||||
<td style="width: 10%">{{ value.SEX }}</td>
|
||||
<td style="width: 25%">{{ value.STRENGTHENEXAMSCORE }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">未合格学员名单</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 10%">序号</td>
|
||||
<td style="width: 15%">姓名</td>
|
||||
<td style="width: 25%">身份证号</td>
|
||||
<td style="width: 20%">手机号</td>
|
||||
<td style="width: 10%">性别</td>
|
||||
<td style="width: 25%">效果评估成绩</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-for="(value, key) in data.evaluationDialogForm.NO_PASS_List"
|
||||
:key="key"
|
||||
>
|
||||
<td style="width: 10%">{{ key + 1 }}</td>
|
||||
<td style="width: 15%">{{ value.NAME }}</td>
|
||||
<td style="width: 25%">{{ value.USER_ID_CARD }}</td>
|
||||
<td style="width: 20%">{{ value.PHONE }}</td>
|
||||
<td style="width: 10%">{{ value.SEX }}</td>
|
||||
<td style="width: 25%">{{ value.STRENGTHENEXAMSCORE }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watchEffect } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
|
||||
import { getClassEvaluation } from "@/request/training_archive_management.js";
|
||||
import { useVModel } from "@vueuse/core";
|
||||
import dayjs from "dayjs";
|
||||
const props = defineProps({
|
||||
classId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const visible = useVModel(props, "visible");
|
||||
const data = reactive({
|
||||
evaluationDialogForm: {},
|
||||
count1: "",
|
||||
count2: "",
|
||||
count3: "",
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
const resData = await getClassEvaluation({
|
||||
CLASS_ID: props.classId,
|
||||
});
|
||||
data.evaluationDialogForm = resData.pageData;
|
||||
data.count1 = data.pageData.count1;
|
||||
data.count2 = data.pageData.count2;
|
||||
data.count3 = data.pageData.count3;
|
||||
};
|
||||
const fnExport = async () => {
|
||||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
window.location.href =
|
||||
import.meta.env[import.meta.env.DEV ? "VITE_PROXY" : "VITE_BASE_URL"] +
|
||||
"class/hs?CLASS_ID=" +
|
||||
props.classId;
|
||||
};
|
||||
watchEffect(() => {
|
||||
if (visible.value) fnGetData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
td {
|
||||
border: 1px solid var(--el-border-color);
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,283 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" width="1100px" title="效果评估表">
|
||||
<div class="tr mb">
|
||||
<el-button type="primary" @click="fnExport">导出</el-button>
|
||||
</div>
|
||||
<div id="printContent">
|
||||
<h1 style="text-align: center; margin-left: 60px">
|
||||
安全生产教育培训动态评估报告
|
||||
</h1>
|
||||
<p class="p1" style="width: 100%; text-align: center">
|
||||
姓名: {{ data.evaluationDialogForm.NAME }}
|
||||
身份证号:
|
||||
{{
|
||||
data.evaluationDialogForm.USER_ID_CARD
|
||||
}} 评估日期:
|
||||
{{ data.evaluationDialogForm.OPERATTIME }}
|
||||
</p>
|
||||
<h3>一、评估概述</h3>
|
||||
<p class="p1">
|
||||
本报告旨在评估您在最近接受的安全培训中的个人效果,并提供课程考试结果以及指出可能存在的知识盲点。安全培训的目标是提高您在工作环境中的安全意识和行为,以减少事故和伤害的发生。本报告将对您的培训参与度、知识掌握程度、课程考试成绩以及可能存在的知识盲点进行评估。
|
||||
</p>
|
||||
<h3>二、学员基本情况</h3>
|
||||
<table
|
||||
align="center"
|
||||
border="1"
|
||||
cellspacing="0"
|
||||
width="100%"
|
||||
class="table"
|
||||
>
|
||||
<tr>
|
||||
<td style="width: 70px">姓名</td>
|
||||
<td style="width: 60px">{{ data.evaluationDialogForm.NAME }}</td>
|
||||
<td style="width: 55px">性别</td>
|
||||
<td style="width: 80px">{{ data.evaluationDialogForm.SEX }}</td>
|
||||
<td style="width: 60px">身份证号</td>
|
||||
<td style="width: 150px">
|
||||
{{ data.evaluationDialogForm.USER_ID_CARD }}
|
||||
</td>
|
||||
<td style="width: 60px">学历</td>
|
||||
<td style="width: 200px">
|
||||
{{ data.evaluationDialogForm.DEGREE_OF_EDUCATION }}
|
||||
</td>
|
||||
<td style="width: 60px">专业</td>
|
||||
<td>{{ data.evaluationDialogForm.MAJOR }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>职务/职称</td>
|
||||
<td>{{ data.evaluationDialogForm.DUTIES }}</td>
|
||||
<td>部门</td>
|
||||
<td>{{ data.evaluationDialogForm.DEPARTMENT_NAME }}</td>
|
||||
<td>工种</td>
|
||||
<td>{{ data.evaluationDialogForm.POST_NAME }}</td>
|
||||
<td>行业类别</td>
|
||||
<td>{{ data.evaluationDialogForm.INDUSTRY_ALL_NAME }}</td>
|
||||
<td>联系电话</td>
|
||||
<td>{{ data.evaluationDialogForm.PHONE }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>人员类型</td>
|
||||
<td colspan="9">{{ data.evaluationDialogForm.PERSONNEL_TYPE }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3>三、评估内容</h3>
|
||||
<p class="p1">
|
||||
您在 {{ data.evaluationDialogForm.START_TIME }} -
|
||||
{{ data.evaluationDialogForm.END_TIME }} 进行了
|
||||
{{ data.evaluationDialogForm.CLASS_NAME }}, 培训内容如下:
|
||||
{{ data.evaluationDialogForm.coursewareName }}
|
||||
</p>
|
||||
<p class="p1">
|
||||
您参加了培训后的课程考试,并取得了以下成绩:{{
|
||||
data.evaluationDialogForm.STAGEEXAMSCORE
|
||||
}}分
|
||||
</p>
|
||||
<h3>四、评估结果</h3>
|
||||
<p class="p1">根据我们的评估,您的个人培训效果如下:</p>
|
||||
<p class="p1">
|
||||
<b
|
||||
>(一)您在培训期间表现出积极的参与度,完成了所有的培训课程和活动;</b
|
||||
>
|
||||
</p>
|
||||
<p class="p1">
|
||||
<b
|
||||
>(二)<span v-if="data.evaluationDialogForm.correct !== ''"
|
||||
>您对 {{ data.evaluationDialogForm.correct }} 知识掌握得很好。</span
|
||||
>在评估过程中,我们发现您可能存在以下知识盲点:{{
|
||||
data.evaluationDialogForm.error
|
||||
}}</b
|
||||
>
|
||||
</p>
|
||||
<p class="p1">知识盲点对应课件为:</p>
|
||||
<p class="p1">{{ data.evaluationDialogForm.errorVideoName }}</p>
|
||||
<p class="p1"><b>(三)评估建议</b></p>
|
||||
<p class="p1">
|
||||
存在的知识盲点需要进一步加强和补充。我们建议您将重点放在弥补这些盲点上,通过进一步学习、参与讨论或与安全专家交流弥补知识盲区。
|
||||
</p>
|
||||
<h3>五、强化培训记录</h3>
|
||||
<p class="p1"><b>(一)强化培训考试记录</b></p>
|
||||
|
||||
<div
|
||||
v-if="data.evaluationDialogForm.STRENGTHEN_EXAMNAME !== '0'"
|
||||
class="page-break"
|
||||
>
|
||||
<div class="levelup no-print">
|
||||
<h1>考卷详情</h1>
|
||||
</div>
|
||||
<div class="paper-details chapter_box">
|
||||
<div class="chapter_right_img" />
|
||||
<h1 style="text-align: center">
|
||||
{{ data.evaluationDialogForm.STRENGTHEN_EXAMNAME }}
|
||||
</h1>
|
||||
<div style="text-align: center">
|
||||
(满分:{{ data.evaluationDialogForm.STRENGTHEN_EXAMSCORE }}分)
|
||||
</div>
|
||||
<div class="subflex">
|
||||
<span>班级名称:{{ data.evaluationDialogForm.CLASS_NAME }}</span>
|
||||
<span>姓名:{{ data.evaluationDialogForm.NAME }}</span>
|
||||
</div>
|
||||
<div class="subflex">
|
||||
<span
|
||||
>考试时间:{{
|
||||
data.evaluationDialogForm.STRENGTHEN_OPERATTIME
|
||||
}}</span
|
||||
>
|
||||
<span
|
||||
>分数:{{ data.evaluationDialogForm.STRENGTHENEXAMSCORE }}</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="study-papg">
|
||||
<dl
|
||||
v-for="(row, key) in data.evaluationDialogForm
|
||||
.strengthenexamrecord"
|
||||
:key="key"
|
||||
>
|
||||
<dt>
|
||||
<span v-if="row.QUESTIONTYPE === '1'" class="mark mark-green"
|
||||
>(单选题)
|
||||
</span>
|
||||
<span v-if="row.QUESTIONTYPE === '2'" class="mark mark-blue"
|
||||
>(多选题)</span
|
||||
>
|
||||
<span v-if="row.QUESTIONTYPE === '3'" class="mark mark-orange"
|
||||
>(判断题)</span
|
||||
>
|
||||
<span v-if="row.QUESTIONTYPE === '4'" class="mark mark-purple"
|
||||
>(填空题)</span
|
||||
>
|
||||
{{ key + 1 }}.{{ row.QUESTIONDRY }}
|
||||
<span class="ml-10">(题目分值:{{ row.SCORE }})</span>
|
||||
</dt>
|
||||
<el-radio-group
|
||||
v-if="row.QUESTIONTYPE === '1'"
|
||||
v-model="row.ANSWER"
|
||||
:disabled="true"
|
||||
>
|
||||
<dd>
|
||||
<el-radio value="A">A.{{ row.OPTIONA }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio value="B">B.{{ row.OPTIONB }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio value="C">C.{{ row.OPTIONC }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio value="D">D.{{ row.OPTIOND }}</el-radio>
|
||||
</dd>
|
||||
</el-radio-group>
|
||||
<el-checkbox-group
|
||||
v-if="row.QUESTIONTYPE === '2'"
|
||||
v-model="row.checkList"
|
||||
:disabled="true"
|
||||
>
|
||||
<dd>
|
||||
<el-checkbox value="A">A.{{ row.OPTIONA }}</el-checkbox>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-checkbox value="B">B.{{ row.OPTIONB }}</el-checkbox>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-checkbox value="C">C.{{ row.OPTIONC }}</el-checkbox>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-checkbox value="D">D.{{ row.OPTIOND }}</el-checkbox>
|
||||
</dd>
|
||||
</el-checkbox-group>
|
||||
<el-radio-group
|
||||
v-if="row.QUESTIONTYPE === '3'"
|
||||
v-model="row.ANSWER"
|
||||
:disabled="true"
|
||||
>
|
||||
<dd>
|
||||
<el-radio value="A">A.{{ row.OPTIONA }}</el-radio>
|
||||
</dd>
|
||||
<dd>
|
||||
<el-radio value="B">B.{{ row.OPTIONB }}</el-radio>
|
||||
</dd>
|
||||
</el-radio-group>
|
||||
<div class="flex-layout space-between">
|
||||
<div>
|
||||
<div v-if="row.QUESTIONTYPE === '4'" class="mb-10">
|
||||
学员答案:{{ row.ANSWER }}
|
||||
</div>
|
||||
<div class="mb-10">参考答案:{{ row.ANSWERRIGHT }}</div>
|
||||
<div>答案解析:{{ row.DESCR }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, watchEffect } from "vue";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
|
||||
import { getStudentEvaluation } from "@/request/training_archive_management.js";
|
||||
import { useVModel } from "@vueuse/core";
|
||||
const props = defineProps({
|
||||
studentId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const visible = useVModel(props, "visible");
|
||||
const data = reactive({
|
||||
evaluationDialogForm: {},
|
||||
count1: "",
|
||||
count2: "",
|
||||
count3: "",
|
||||
});
|
||||
const fnGetData = async () => {
|
||||
const resData = await getStudentEvaluation({
|
||||
STUDENT_ID: props.studentId,
|
||||
});
|
||||
data.evaluationDialogForm = resData.pageData;
|
||||
data.count1 = data.pageData.count1;
|
||||
data.count2 = data.pageData.count2;
|
||||
data.count3 = data.pageData.count3;
|
||||
};
|
||||
|
||||
const fnExport = async () => {
|
||||
await ElMessageBox.confirm("确定要导出吗?", { type: "warning" });
|
||||
window.location.href =
|
||||
import.meta.env[import.meta.env.DEV ? "VITE_PROXY" : "VITE_BASE_URL"] +
|
||||
"student/hs?STUDENT_ID=" +
|
||||
props.studentId;
|
||||
};
|
||||
watchEffect(() => {
|
||||
if (visible.value) fnGetData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
td {
|
||||
border: 1px solid var(--el-border-color);
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,126 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPagination"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="班级名称" prop="NAME">
|
||||
<el-input
|
||||
v-model="searchForm.NAME"
|
||||
placeholder="请输入班级名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="年份" prop="YEAR">
|
||||
<el-date-picker
|
||||
v-model="searchForm.YEAR"
|
||||
value-format="YYYY"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</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
|
||||
ref="tableRef"
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column type="selection" width="55"> </el-table-column>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="NAME" label="班级名称" width="200" />
|
||||
<el-table-column prop="CODE" label="班级编码" width="200" />
|
||||
<el-table-column prop="TRAINTYPENAME" label="培训类型" width="200" />
|
||||
<el-table-column prop="POSTTYPENAME" label="岗位类型" width="200" />
|
||||
<el-table-column
|
||||
prop="PASSSTUDENTCOUNT"
|
||||
label="效果评估通过人数"
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="ALLSTUDENTCOUNT"
|
||||
label="效果评估总人数"
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/effect_appraisal/enterprise_effect/index/studentStrengthenDetailsList',
|
||||
query: {
|
||||
CLASS_ID: row.CLASS_ID,
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
学员详情
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="goClassStrengthenInfo(row.CLASS_ID)"
|
||||
>
|
||||
班级效果评估表
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
<class-strengthen
|
||||
v-model:visible="data.evaluationDialog.visible"
|
||||
:class-id="data.evaluationDialog.CLASS_ID"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { serialNumber } from "@/assets/js/utils.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { reactive, ref } from "vue";
|
||||
|
||||
import { getClassStrengthenDetailsList } from "@/request/training_archive_management.js";
|
||||
import router from "@/router/index.js";
|
||||
import ClassStrengthen from "./components/classStrengthen.vue";
|
||||
|
||||
const data = reactive({
|
||||
evaluationDialog: {
|
||||
visible: false,
|
||||
CLASS_ID: "",
|
||||
},
|
||||
});
|
||||
const tableRef = ref(null);
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getClassStrengthenDetailsList);
|
||||
|
||||
const goClassStrengthenInfo = (class_id) => {
|
||||
data.evaluationDialog.visible = true;
|
||||
data.evaluationDialog.CLASS_ID = class_id;
|
||||
};
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnResetPagination"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="姓名" prop="STUDENTNAME">
|
||||
<el-input v-model="searchForm.NAME" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="年份" prop="YEAR">
|
||||
<el-date-picker
|
||||
v-model="searchForm.YEAR"
|
||||
value-format="YYYY"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</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
|
||||
ref="tableRef"
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column type="selection" width="55"> </el-table-column>
|
||||
<el-table-column label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="STUDENTNAME" label="姓名" width="200" />
|
||||
<el-table-column prop="USERIDCARD" label="身份证号" width="200" />
|
||||
<el-table-column prop="PHONE" label="手机号" width="200" />
|
||||
<el-table-column
|
||||
prop="STRENGTHENEXAMSTATE"
|
||||
label="效果评估状态"
|
||||
width="200"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.STRENGTHENEXAMSTATE === "3" ? "通过" : "未通过" }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="STRENGTHENEXAMSCORE"
|
||||
label="效果评估最高分"
|
||||
width="200"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{
|
||||
row.STRENGTHENEXAMSCORE
|
||||
? row.STRENGTHENEXAMSCORE
|
||||
: "未进行评估考试"
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="goStudentStrengthenInfo(row.STUDENT_ID)"
|
||||
>
|
||||
查看个人效果评估
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
<student-strengthen
|
||||
v-model:visible="data.evaluationDialog.visible"
|
||||
:student-id="data.evaluationDialog.STUDENT_ID"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { serialNumber } from "@/assets/js/utils.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { reactive, ref } from "vue";
|
||||
|
||||
import { getStudentStrengthenDetailsList } from "@/request/training_archive_management.js";
|
||||
import { useRoute } from "vue-router";
|
||||
import StudentStrengthen from "./components/studentStrengthen.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const { CLASS_ID } = route.query;
|
||||
const tableRef = ref(null);
|
||||
const data = reactive({
|
||||
evaluationDialog: {
|
||||
visible: false,
|
||||
STUDENT_ID: "",
|
||||
},
|
||||
});
|
||||
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getStudentStrengthenDetailsList, {
|
||||
otherParams: { CLASS_ID },
|
||||
});
|
||||
|
||||
const goStudentStrengthenInfo = (student_id) => {
|
||||
data.evaluationDialog.visible = true;
|
||||
data.evaluationDialog.STUDENT_ID = student_id;
|
||||
};
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -45,14 +45,14 @@
|
|||
v-model="form.ISSUPERVISE"
|
||||
@change="fnChangeRegulatoryAuthorities"
|
||||
>
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
<el-radio value="1">是</el-radio>
|
||||
<el-radio value="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否外来人员部门" prop="FOREIGNPERSONNEL">
|
||||
<el-radio-group v-model="form.FOREIGNPERSONNEL">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
<el-radio value="1">是</el-radio>
|
||||
<el-radio value="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="状态" prop="STATUS">
|
||||
<el-radio-group v-model="form.STATUS">
|
||||
<el-radio label="0">启用</el-radio>
|
||||
<el-radio label="1">禁用</el-radio>
|
||||
<el-radio value="0">启用</el-radio>
|
||||
<el-radio value="1">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="告知卡" prop="files">
|
||||
|
|
|
@ -178,16 +178,16 @@
|
|||
<el-col :span="24">
|
||||
<el-form-item label="是否主要负责人" prop="ISHEAD">
|
||||
<el-radio-group v-model="data.form.ISHEAD">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
<el-radio value="1">是</el-radio>
|
||||
<el-radio value="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="是否部门领导" prop="ISLEADER">
|
||||
<el-radio-group v-model="data.form.ISLEADER">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
<el-radio value="1">是</el-radio>
|
||||
<el-radio value="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
<el-tooltip
|
||||
content="温馨提示:部门领导可以审核离岗申请,查看同部门清单数据"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<el-col :span="24">
|
||||
<el-form-item label="是否合格" prop="ISQUALIFIED">
|
||||
<el-radio-group v-model="data.form.ISQUALIFIED">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="2">否</el-radio>
|
||||
<el-radio value="1">是</el-radio>
|
||||
<el-radio value="2">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
:model-value="data.form.IS_NORMAL"
|
||||
@change="fnIsNormalChange"
|
||||
>
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="2">否</el-radio>
|
||||
<el-radio value="1">是</el-radio>
|
||||
<el-radio value="2">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -168,7 +168,7 @@
|
|||
<el-col :span="24">
|
||||
<el-form-item label="整改方案" prop="HAVESCHEME">
|
||||
<el-radio-group v-model="data.form.HAVESCHEME">
|
||||
<el-radio label="1" value="1">有</el-radio>
|
||||
<el-radio value="1">有</el-radio>
|
||||
<el-radio :disabled="data.info.ISCONFIRM === '1'" label="0">
|
||||
无
|
||||
</el-radio>
|
||||
|
@ -245,7 +245,7 @@
|
|||
<el-col :span="24">
|
||||
<el-form-item label="整改计划" prop="HAVEPLAN">
|
||||
<el-radio-group v-model="data.form.HAVEPLAN">
|
||||
<el-radio label="1" value="1">有</el-radio>
|
||||
<el-radio value="1">有</el-radio>
|
||||
<el-radio :disabled="data.info.ISCONFIRM === '1'" label="0">
|
||||
无
|
||||
</el-radio>
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<layout-card>
|
||||
<el-tabs v-model="active" @tab-change="fnTabChange">
|
||||
<el-tab-pane
|
||||
label="基本信息"
|
||||
:name="
|
||||
type === 'add'
|
||||
? '/training_process_management/class_management/add'
|
||||
: type === 'edit'
|
||||
? '/training_process_management/class_management/edit'
|
||||
: '/training_process_management/class_management/view'
|
||||
"
|
||||
lazy
|
||||
:disabled="!CLASS_ID"
|
||||
>
|
||||
<basic-info />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
label="学员"
|
||||
name="/training_process_management/class_management/student"
|
||||
lazy
|
||||
:disabled="!CLASS_ID"
|
||||
>
|
||||
<student />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
label="课程"
|
||||
name="/training_process_management/class_management/curriculum"
|
||||
lazy
|
||||
:disabled="!CLASS_ID"
|
||||
>
|
||||
<curriculum />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</layout-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import BasicInfo from "./components/basic_info.vue";
|
||||
import Student from "./components/student.vue";
|
||||
import Curriculum from "./components/curriculum.vue";
|
||||
import { ref } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const { CLASS_ID, type } = route.query;
|
||||
const active = ref(route.path);
|
||||
const fnTabChange = (path) => {
|
||||
router.replace({
|
||||
path,
|
||||
query: { ...route.query },
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,170 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" title="添加学员">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="发布类型" prop="releaseType">
|
||||
<el-radio-group v-model="form.releaseType">
|
||||
<el-radio value="1">按身份发布</el-radio>
|
||||
<el-radio value="2">按人员发布</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="从业身份" prop="personnelTypes">
|
||||
<el-checkbox-group
|
||||
v-model="form.personnelTypes"
|
||||
@change="fnGetDataTransfer"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="item in personnelTypeList"
|
||||
:key="item.DICTIONARIES_ID"
|
||||
:label="item.NAME"
|
||||
:value="item.DICTIONARIES_ID"
|
||||
/>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<layout-table
|
||||
ref="tableRef"
|
||||
:data="list"
|
||||
:show-pagination="false"
|
||||
max-height="500"
|
||||
row-key="USER_ID"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="form.releaseType === '2'"
|
||||
reserve-selection
|
||||
type="selection"
|
||||
width="55"
|
||||
/>
|
||||
<el-table-column label="序号" width="60" type="index" />
|
||||
<el-table-column prop="NAME" label="姓名" />
|
||||
<el-table-column prop="DEPARTMENT_NAME" label="部门" />
|
||||
<el-table-column prop="POST_NAME" label="岗位" />
|
||||
<el-table-column prop="USER_ID_CARD" label="身份证号" />
|
||||
<el-table-column prop="PERSONNEL_TYPE_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 { useVModels } from "@vueuse/core";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getClassManagementSelectStudentAdd,
|
||||
getClassManagementSelectStudentList,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { layoutFnGetPersonnelType } from "@/assets/js/data_dictionary.js";
|
||||
import { ref, watch } from "vue";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const { CLASS_ID, EXAMINATION } = route.query;
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
selectList: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const { list, fnGetData, tableRef } = useListData(
|
||||
getClassManagementSelectStudentList,
|
||||
{
|
||||
usePagination: false,
|
||||
key: "userList",
|
||||
immediate: false,
|
||||
callbackFn: (list) => {
|
||||
for (let i = 0; i < props.selectList.length; i++) {
|
||||
for (let j = 0; j < list.length; j++) {
|
||||
if (list[j].USER_ID === props.selectList[i].USER_ID) {
|
||||
list.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
const rules = {
|
||||
releaseType: [{ required: true, message: "请选择发布类型", trigger: "blur" }],
|
||||
personnelTypes: [
|
||||
{ required: true, message: "请选择从业身份", trigger: "blur" },
|
||||
],
|
||||
};
|
||||
const formRef = ref(null);
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
PERSONNEL_TYPES: form.value.personnelTypes.join(","),
|
||||
});
|
||||
};
|
||||
watch(
|
||||
() => visible.value,
|
||||
() => {
|
||||
if (visible.value) {
|
||||
if (form.value.personnelTypes.length > 0) fnGetDataTransfer();
|
||||
}
|
||||
}
|
||||
);
|
||||
const personnelTypeList = await layoutFnGetPersonnelType();
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
tableRef.value.clearSelection();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
if (list.value.length === 0) {
|
||||
ElMessage.warning("当前从业身份没有学习人员,请重新选择");
|
||||
return;
|
||||
}
|
||||
let currentIds = "";
|
||||
if (form.value.releaseType === "1") {
|
||||
currentIds = list.value.map((item) => item.USER_ID).join(",");
|
||||
} else {
|
||||
const selectionData = tableRef.value.getSelectionRows();
|
||||
if (selectionData.length === 0) {
|
||||
ElMessage.warning("请选择学员");
|
||||
return;
|
||||
}
|
||||
currentIds = selectionData.map((item) => item.USER_ID).join(",");
|
||||
}
|
||||
await getClassManagementSelectStudentAdd({
|
||||
RELEASE_TYPE: form.value.releaseType,
|
||||
PERSONNEL_TYPES: form.value.personnelTypes.join(","),
|
||||
CLASS_ID,
|
||||
EXAMINATION,
|
||||
userIds: currentIds,
|
||||
});
|
||||
ElMessage.success("添加成功");
|
||||
fnClose();
|
||||
emits("get-data");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,370 @@
|
|||
<template>
|
||||
<el-form ref="formRef" :model="data.form" :rules="rules" label-width="160px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-divider content-position="left">基本信息</el-divider>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班级名称" prop="NAME">
|
||||
<el-input
|
||||
v-model="data.form.NAME"
|
||||
placeholder="请输入班级名称"
|
||||
:disabled="isEdit"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训日期" prop="TIME">
|
||||
<el-date-picker
|
||||
v-model="data.form.TIME"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
:disabled="isEdit"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="培训类型" prop="TRAINTYPE">
|
||||
<layout-learning-train-type
|
||||
ref="trainingTypeRef"
|
||||
v-model="data.form.TRAINTYPE"
|
||||
type="trainingType"
|
||||
:disabled="isEdit"
|
||||
@update:model-value="
|
||||
data.form.POSTTYPE = '';
|
||||
data.form.TRAINLEVEL = '';
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位类型" prop="POSTTYPE">
|
||||
<layout-learning-train-type
|
||||
ref="postTypeRef"
|
||||
v-model="data.form.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="data.form.TRAINTYPE"
|
||||
:disabled="isEdit"
|
||||
@update:model-value="data.form.TRAINLEVEL = ''"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
label="培训级别"
|
||||
prop="TRAINLEVEL"
|
||||
:rules="[
|
||||
{
|
||||
required: data.trainingLevelList.length !== 0,
|
||||
message: '请选择培训级别',
|
||||
trigger: 'change',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<layout-learning-train-type
|
||||
ref="trainingLevelRef"
|
||||
v-model="data.form.TRAINLEVEL"
|
||||
type="trainingLevel"
|
||||
:search-value="data.form.POSTTYPE"
|
||||
:disabled="isEdit"
|
||||
@throw-data="data.trainingLevelList = $event"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template
|
||||
v-if="
|
||||
data.form.TRAINTYPE &&
|
||||
data.form.TRAINTYPE !== 'c70bf859512241579a8a30fc5d1ae153'
|
||||
"
|
||||
>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="记录人员" prop="RECORDOR">
|
||||
<el-select
|
||||
v-model="data.form.RECORDOR"
|
||||
filterable
|
||||
:disabled="isEdit"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.recordingPersonnelList"
|
||||
:key="item.USERSIGNID"
|
||||
:value="item.USERSIGNID"
|
||||
:label="item.USERNAME"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="考核人员" prop="ASSESSOR">
|
||||
<el-select
|
||||
v-model="data.form.ASSESSOR"
|
||||
filterable
|
||||
:disabled="isEdit"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.assessorsList"
|
||||
:key="item.USERSIGNID"
|
||||
:value="item.USERSIGNID"
|
||||
:label="item.USERNAME"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="安全管理部门负责人" prop="SAFETYDEPTOR">
|
||||
<el-select
|
||||
v-model="data.form.SAFETYDEPTOR"
|
||||
filterable
|
||||
:disabled="isEdit"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.headOfSafetyManagementDepartmentList"
|
||||
:key="item.USERSIGNID"
|
||||
:value="item.USERSIGNID"
|
||||
:label="item.USERNAME"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="负责人" prop="PRINCIPAL">
|
||||
<el-input
|
||||
v-model="data.form.PRINCIPAL"
|
||||
placeholder="请输入负责人"
|
||||
:disabled="isEdit"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="负责人电话" prop="PRINCIPAL_PHONE">
|
||||
<el-input
|
||||
v-model="data.form.PRINCIPAL_PHONE"
|
||||
placeholder="请输入负责人电话"
|
||||
:disabled="isEdit"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<el-col :span="24">
|
||||
<el-divider content-position="left">基本设置</el-divider>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否开启考试" prop="EXAMINATION">
|
||||
<el-radio-group v-model="data.form.EXAMINATION" :disabled="isEdit">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
<span class="ml-10">
|
||||
不考试的班级,学员学习完所有课程,即为完成学业。
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="data.form.EXAMINATION === 1" :span="12">
|
||||
<el-form-item label="考试次数" prop="NUMBEROFEXAMS">
|
||||
<div style="flex: 1; display: flex">
|
||||
<el-input-number
|
||||
v-model="data.form.NUMBEROFEXAMS"
|
||||
:min="1"
|
||||
:max="2147483600"
|
||||
:disabled="isEdit"
|
||||
/>
|
||||
<el-button
|
||||
v-if="STATE && STATE !== '1' && STATE !== '6'"
|
||||
type="primary"
|
||||
class="ml-10"
|
||||
@click="fnModifyExamTimes"
|
||||
>
|
||||
修改考试次数
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否人脸识别" prop="ISFACE">
|
||||
<el-radio-group v-model="data.form.ISFACE" :disabled="isEdit">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="data.form.EXAMINATION === 1" :span="12">
|
||||
<el-form-item label="是否效果评估" prop="ISSTRENGTHEN">
|
||||
<el-radio-group v-model="data.form.ISSTRENGTHEN" :disabled="isEdit">
|
||||
<el-radio label="2">强制</el-radio>
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div v-if="!isEdit" class="mt-10 tc">
|
||||
<el-button type="primary" @click="fnSubmit">
|
||||
{{ !CLASS_ID ? "保存并下一步" : "保存" }}
|
||||
</el-button>
|
||||
</div>
|
||||
<modify-exam-times
|
||||
:id="CLASS_ID"
|
||||
v-model:visible="data.modifyExamTimesDialog.visible"
|
||||
v-model:form="data.modifyExamTimesDialog.form"
|
||||
@get-data="fnGetData"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, reactive, ref } from "vue";
|
||||
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
|
||||
import {
|
||||
getClassManagementView,
|
||||
getPersonnelList,
|
||||
setClassManagementAdd,
|
||||
setClassManagementEdit,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import ModifyExamTimes from "./modify_exam_times.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { STATE, CLASS_ID, type } = route.query;
|
||||
const isEdit = STATE && STATE !== "1";
|
||||
const formRef = ref(null);
|
||||
const trainingTypeRef = ref(null);
|
||||
const postTypeRef = ref(null);
|
||||
const trainingLevelRef = ref(null);
|
||||
const data = reactive({
|
||||
recordingPersonnelList: [],
|
||||
assessorsList: [],
|
||||
headOfSafetyManagementDepartmentList: [],
|
||||
trainingLevelList: [],
|
||||
form: {
|
||||
NAME: "",
|
||||
TIME: "",
|
||||
TRAINTYPE: "",
|
||||
POSTTYPE: "",
|
||||
TRAINLEVEL: "",
|
||||
RECORDOR: "",
|
||||
ASSESSOR: "",
|
||||
SAFETYDEPTOR: "",
|
||||
PRINCIPAL: "",
|
||||
PRINCIPAL_PHONE: "",
|
||||
EXAMINATION: 1,
|
||||
NUMBEROFEXAMS: 1,
|
||||
ISFACE: "1",
|
||||
ISSTRENGTHEN: "1",
|
||||
},
|
||||
modifyExamTimesDialog: {
|
||||
visible: false,
|
||||
form: { NUMBEROFEXAMS: 1, source: 1 },
|
||||
},
|
||||
});
|
||||
const rules = {
|
||||
NAME: [{ required: true, message: "请输入班级名称", trigger: "blur" }],
|
||||
TIME: [{ required: true, message: "请选择培训日期", trigger: "change" }],
|
||||
TRAINTYPE: [{ required: true, message: "请选择培训类型", trigger: "change" }],
|
||||
POSTTYPE: [{ required: true, message: "请选择岗位类型", trigger: "change" }],
|
||||
RECORDOR: [{ required: true, message: "请选择记录人员", trigger: "change" }],
|
||||
ASSESSOR: [{ required: true, message: "请选择考核人员", trigger: "change" }],
|
||||
SAFETYDEPTOR: [
|
||||
{ required: true, message: "请选择安全管理部门负责人", trigger: "change" },
|
||||
],
|
||||
PRINCIPAL: [{ required: true, message: "请输入负责人", trigger: "blur" }],
|
||||
PRINCIPAL_PHONE: [
|
||||
{ required: true, message: "请输入负责人电话", trigger: "blur" },
|
||||
{
|
||||
pattern:
|
||||
/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/,
|
||||
message: "请输入正确的手机号码",
|
||||
},
|
||||
],
|
||||
EXAMINATION: [
|
||||
{ required: true, message: "请选择是否开启考试", trigger: "change" },
|
||||
],
|
||||
ISFACE: [
|
||||
{ required: true, message: "请选择是否人脸识别", trigger: "change" },
|
||||
],
|
||||
ISSTRENGTHEN: [
|
||||
{ required: true, message: "请选择是否效果评估", trigger: "change" },
|
||||
],
|
||||
NUMBEROFEXAMS: [
|
||||
{ required: true, message: "请输入考试次数", trigger: "blur" },
|
||||
],
|
||||
};
|
||||
const fnGetData = async () => {
|
||||
if (!CLASS_ID) return;
|
||||
const resData = await getClassManagementView({ CLASS_ID });
|
||||
resData.pd.TIME = [resData.pd.START_TIME, resData.pd.END_TIME];
|
||||
data.form = resData.pd;
|
||||
};
|
||||
fnGetData();
|
||||
const fnGetPersonnelList = async () => {
|
||||
const { varList: recordingPersonnelList } = await getPersonnelList({
|
||||
USERSIGNTYPE: "854c77daf3734384807a638dfafe04d5",
|
||||
});
|
||||
const { varList: assessorsList } = await getPersonnelList({
|
||||
USERSIGNTYPE: "f2726f92987d4f77be1c3f0460669418",
|
||||
});
|
||||
const { varList: headOfSafetyManagementDepartmentList } =
|
||||
await getPersonnelList({
|
||||
USERSIGNTYPE: "5f4794189cf24fc2a7e12fa47b70139e",
|
||||
});
|
||||
data.recordingPersonnelList = recordingPersonnelList;
|
||||
data.assessorsList = assessorsList;
|
||||
data.headOfSafetyManagementDepartmentList =
|
||||
headOfSafetyManagementDepartmentList;
|
||||
};
|
||||
fnGetPersonnelList();
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await useFormValidate(formRef);
|
||||
const params = {
|
||||
...data.form,
|
||||
ISSTRENGTHEN: data.form.EXAMINATION === 1 ? data.form.ISSTRENGTHEN : "0",
|
||||
START_TIME: data.form.TIME[0],
|
||||
END_TIME: data.form.TIME[1],
|
||||
SAMPLINGNUMBER: "0",
|
||||
TRAINTYPE_NAME: trainingTypeRef.value.getCurrentNode().NAME,
|
||||
POSTTYPE_NAME: postTypeRef.value.getCurrentNode().NAME,
|
||||
TRAINLEVEL_NAME: trainingLevelRef.value.getCurrentNode().NAME || "",
|
||||
trainAllName:
|
||||
trainingTypeRef.value.getCurrentNode().NAME +
|
||||
"-" +
|
||||
postTypeRef.value.getCurrentNode().NAME,
|
||||
};
|
||||
let resData;
|
||||
!CLASS_ID
|
||||
? (resData = await setClassManagementAdd(params))
|
||||
: await setClassManagementEdit(params);
|
||||
ElMessage.success("提交成功");
|
||||
await router.replace({
|
||||
path: !CLASS_ID
|
||||
? "/training_process_management/class_management/student"
|
||||
: type === "add"
|
||||
? "/training_process_management/class_management/add"
|
||||
: "/training_process_management/class_management/edit",
|
||||
query: {
|
||||
...route.query,
|
||||
CLASS_ID: !CLASS_ID ? resData.CLASS_ID : CLASS_ID,
|
||||
TRAINTYPE: data.form.TRAINTYPE,
|
||||
EXAMINATION: data.form.EXAMINATION,
|
||||
ISSTRENGTHEN: data.form.ISSTRENGTHEN,
|
||||
},
|
||||
});
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnModifyExamTimes = async () => {
|
||||
data.modifyExamTimesDialog.visible = true;
|
||||
await nextTick();
|
||||
data.modifyExamTimesDialog.form.NUMBEROFEXAMS = data.form.NUMBEROFEXAMS;
|
||||
data.modifyExamTimesDialog.form.source = data.form.NUMBEROFEXAMS;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-if="!isEdit" class="mt-10 tc">
|
||||
<el-button
|
||||
@click="
|
||||
router.replace({
|
||||
path: '/training_process_management/class_management/student',
|
||||
query: { ...route.query },
|
||||
})
|
||||
"
|
||||
>
|
||||
上一步
|
||||
</el-button>
|
||||
<el-button type="primary"> 完成 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { STATE } = route.query;
|
||||
const isEdit = STATE && STATE !== "1";
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" title="延期" :on-close="fnClose">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="60px">
|
||||
<el-form-item label="日期" prop="TIME">
|
||||
<el-date-picker
|
||||
v-model="form.TIME"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
:disabled-date="fnDisabledDate"
|
||||
/>
|
||||
</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 { ref } from "vue";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import { setClassManagementDelay } from "@/request/training_process_management.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const formRef = ref(null);
|
||||
const rules = {
|
||||
TIME: [{ required: true, message: "请选择日期", trigger: "change" }],
|
||||
};
|
||||
const fnDisabledDate = (time) => {
|
||||
return time.getTime() <= new Date(form.value.TIME).getTime();
|
||||
};
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = async () => {
|
||||
await useFormValidate(formRef);
|
||||
await setClassManagementDelay({ ...form.value });
|
||||
ElMessage.success("延期成功");
|
||||
fnClose();
|
||||
emits("get-data");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,107 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" title="考试详情" width="70%">
|
||||
<el-divider content-position="left">考试学员信息</el-divider>
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<div>学员名字:{{ info.USERNAME }}</div>
|
||||
<div>考试时间:{{ info.EXAMTIMEBEGIN + "至" + info.EXAMTIMEEND }}</div>
|
||||
<div>得分:{{ info.EXAMSCORE }}</div>
|
||||
</div>
|
||||
<el-divider content-position="left">试卷基本信息</el-divider>
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<div>试卷名称:{{ info.EXAMNAME }}</div>
|
||||
<div>试卷总分:{{ info.PAPEREXAMSCORE }}</div>
|
||||
<div>考试时长:{{ info.ANSWERSHEETTIME }}分钟</div>
|
||||
<div>通过分数:{{ info.PASSSCORE }}</div>
|
||||
</div>
|
||||
<el-divider content-position="left">试卷内容信息</el-divider>
|
||||
<div class="items mt-20 p-20">
|
||||
<div
|
||||
v-for="(item, index) in info.QUESTIONLIST"
|
||||
: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="mt-10">答案:{{ item.ANSWER }}</div>
|
||||
<div class="mt-10">答案解析:{{ item.DESCR }}</div>
|
||||
<div class="mt-10">关联课件名称:{{ item.COURSEWARENAME }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<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,
|
||||
},
|
||||
info: {
|
||||
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>
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<div>
|
||||
<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-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
|
||||
v-model:pagination="pagination"
|
||||
:data="list"
|
||||
@get-data="fnGetData"
|
||||
>
|
||||
<el-table-column label="序号" width="60" fixed="left">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="试卷名称" prop="EXAMNAME" />
|
||||
<el-table-column label="成绩" prop="EXAMSCORE" width="100" />
|
||||
<el-table-column label="是否通过" width="100">
|
||||
<template #default="{ row }">
|
||||
{{ row.RESULT === "0" ? "未通过" : "" }}
|
||||
{{ row.RESULT === "1" ? "通过" : "" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="正确题数" prop="EXAMQUESTIONRIGHT" width="100" />
|
||||
<el-table-column label="错误题数" prop="EXAMQUESTIONWRONG" width="100" />
|
||||
<el-table-column label="正确率(%)" prop="ACCURACY" width="100" />
|
||||
<el-table-column label="考试时间" width="300">
|
||||
<template #default="{ row }">
|
||||
{{ row.EXAMTIMEBEGIN + "至" + row.EXAMTIMEEND }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80px">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnExamDetails(row.STAGEEXAM_ID)"
|
||||
>
|
||||
考试详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
<exam-details
|
||||
v-model:visible="data.examDetailsDialog.visible"
|
||||
:info="data.examDetailsDialog.info"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getClassManagementStudentExamRecordsList,
|
||||
getClassManagementStudentExamRecordsView,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { useRoute } from "vue-router";
|
||||
import { serialNumber } from "@/assets/js/utils.js";
|
||||
import { reactive } from "vue";
|
||||
import ExamDetails from "./exam_details.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const { STUDENT_ID, CLASS_ID } = route.query;
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getClassManagementStudentExamRecordsList, {
|
||||
otherParams: { STUDENT_ID, CLASS_ID },
|
||||
});
|
||||
const data = reactive({
|
||||
examDetailsDialog: {
|
||||
visible: false,
|
||||
info: {},
|
||||
},
|
||||
});
|
||||
const fnExamDetails = async (STAGEEXAM_ID) => {
|
||||
const resData = await getClassManagementStudentExamRecordsView({
|
||||
STAGEEXAM_ID,
|
||||
});
|
||||
data.examDetailsDialog.info = resData.pd;
|
||||
data.examDetailsDialog.visible = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form :model="searchForm" label-width="80px" @submit.prevent="fnGetData">
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="课程名称" prop="CURRICULUMNAME">
|
||||
<el-input v-model="searchForm.CURRICULUMNAME" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="小节名称" prop="CHAPTERNAME">
|
||||
<el-input v-model="searchForm.CHAPTERNAME" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学习状态" prop="STATE">
|
||||
<el-select v-model="searchForm.STATE">
|
||||
<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="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-row>
|
||||
</el-form>
|
||||
<layout-table :data="list" :show-pagination="false">
|
||||
<el-table-column label="序号" width="60" type="index" />
|
||||
<el-table-column label="课程名称" prop="CURRICULUMNAME" />
|
||||
<el-table-column label="小节名称" prop="CHAPTERNAME" />
|
||||
<el-table-column label="学习情况" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.FINISHTIME">已完成</span>
|
||||
<span v-else-if="row.CREATTIME">学习中</span>
|
||||
<span v-else>未学习</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始学习时间" prop="CREATTIME" width="150" />
|
||||
<el-table-column label="完成时间" prop="FINISHTIME" width="150" />
|
||||
<el-table-column label="最近观看时间" prop="OPERATTIME" width="150" />
|
||||
</layout-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { getClassManagementStudentLearningRecordsList } from "@/request/training_process_management.js";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const { STUDENT_ID, CLASS_ID } = route.query;
|
||||
const stateList = [
|
||||
{ ID: "-1", NAME: "未学习" },
|
||||
{ ID: "0", NAME: "学习中" },
|
||||
{ ID: "1", NAME: "已完成" },
|
||||
];
|
||||
const { list, searchForm, fnGetData } = useListData(
|
||||
getClassManagementStudentLearningRecordsList,
|
||||
{
|
||||
otherParams: { STUDENT_ID, CLASS_ID },
|
||||
usePagination: false,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,70 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" title="修改考试次数" :on-close="fnClose">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="原考试次数" prop="source">
|
||||
<el-input-number v-model="form.source" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="新考试次数" prop="NUMBEROFEXAMS">
|
||||
<el-input-number v-model="form.NUMBEROFEXAMS" :min="+form.source + 1" />
|
||||
</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 { ref } from "vue";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import { setClassManagementModifyExamTimes } from "@/request/training_process_management.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => {},
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "update:form", "get-data"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const formRef = ref(null);
|
||||
const rules = {
|
||||
NUMBEROFEXAMS: [
|
||||
{ required: true, message: "请填写考试次数", trigger: "blur" },
|
||||
],
|
||||
};
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = async () => {
|
||||
await useFormValidate(formRef);
|
||||
await ElMessageBox.confirm(
|
||||
"确定要修改该班级的考试次数吗?考试已通过的学员不受影响",
|
||||
{ type: "warning" }
|
||||
);
|
||||
await setClassManagementModifyExamTimes({
|
||||
...form.value,
|
||||
CLASS_ID: props.id,
|
||||
});
|
||||
ElMessage.success("修改成功");
|
||||
fnClose();
|
||||
emits("get-data");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,358 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-form
|
||||
:model="searchForm"
|
||||
label-width="100px"
|
||||
@submit.prevent="fnGetDataTransfer"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="姓名" prop="NAME">
|
||||
<el-input v-model="searchForm.NAME" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="部门" prop="DEPARTMENT_ID">
|
||||
<layout-department
|
||||
v-model="searchForm.DEPARTMENT_ID"
|
||||
@update:model-value="fnGetPost"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="岗位" prop="POST_ID">
|
||||
<el-select v-model="searchForm.POST_ID">
|
||||
<el-option
|
||||
v-for="item in data.postList"
|
||||
:key="item.POST_ID"
|
||||
:label="item.NAME"
|
||||
:value="item.POST_ID"
|
||||
/>
|
||||
</el-select>
|
||||
</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 learningStatus"
|
||||
:key="item.ID"
|
||||
:label="item.NAME"
|
||||
:value="item.ID"
|
||||
/>
|
||||
</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 examStatus"
|
||||
:key="item.ID"
|
||||
:label="item.NAME"
|
||||
:value="item.ID"
|
||||
/>
|
||||
</el-select>
|
||||
</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-width="10px">
|
||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||
<el-button native-type="reset" @click="fnGetDataTransfer">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label-width="10px" class="end">
|
||||
<el-button
|
||||
v-if="!isEdit"
|
||||
type="primary"
|
||||
@click="data.addStudentDialog.visible = true"
|
||||
>
|
||||
新增学员
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="isEdit"
|
||||
type="primary"
|
||||
@click="fnGetLearningRecords"
|
||||
>
|
||||
导出学员学习记录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<layout-table :data="list" :show-pagination="false" max-height="500">
|
||||
<el-table-column label="序号" width="60" type="index" fixed="left" />
|
||||
<el-table-column fixed width="100" prop="NAME" label="姓名" />
|
||||
<el-table-column width="200" prop="DEPARTMENT_NAME" label="部门" />
|
||||
<el-table-column width="200" prop="POST_NAME" label="岗位" />
|
||||
<el-table-column width="200" prop="USER_ID_CARD" label="身份证号" />
|
||||
<el-table-column width="200" prop="FILE_NUMBER" label="档案编号" />
|
||||
<el-table-column width="100" label="人脸认证">
|
||||
<template #default="{ row }">
|
||||
{{ row.AUTHENTICATION === "0" ? "未认证" : "已认证" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" prop="ALL_CLASSHOUR" label="要求学时" />
|
||||
<el-table-column width="100" label="已完成学时">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.COMPLETE_CLASSHOUR">
|
||||
{{
|
||||
row.COMPLETE_CLASSHOUR === "0.0"
|
||||
? 0
|
||||
: parseFloat(row.COMPLETE_CLASSHOUR).toFixed(1)
|
||||
}}
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" label="考试状态">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.STAGEEXAMSTATE, examStatus) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" label="学习状态">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.STUDYSTATE, learningStatus) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="OPERATORNAME" label="操作人" />
|
||||
<el-table-column width="150" prop="CREATTIME" label="入班时间" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="!isEdit"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.STUDENT_ID)"
|
||||
>
|
||||
从本班移除
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="isEdit"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/class_management/student/learning_records',
|
||||
query: { STUDENT_ID: row.STUDENT_ID, CLASS_ID },
|
||||
})
|
||||
"
|
||||
>
|
||||
学习记录
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</layout-table>
|
||||
<div v-if="!isEdit" class="mt-10 tc">
|
||||
<el-button
|
||||
@click="
|
||||
router.replace({
|
||||
path:
|
||||
type === 'add'
|
||||
? '/training_process_management/class_management/add'
|
||||
: '/training_process_management/class_management/edit',
|
||||
query: { ...route.query },
|
||||
})
|
||||
"
|
||||
>
|
||||
上一步
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
router.replace({
|
||||
path: '/training_process_management/class_management/curriculum',
|
||||
query: { ...route.query },
|
||||
})
|
||||
"
|
||||
>
|
||||
下一步
|
||||
</el-button>
|
||||
</div>
|
||||
<add-student
|
||||
v-model:visible="data.addStudentDialog.visible"
|
||||
v-model:form="data.addStudentDialog.form"
|
||||
:select-list="list"
|
||||
@get-data="fnGetDataTransfer"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import LayoutDepartment from "@/components/department/index.vue";
|
||||
import { getPostListAll } from "@/request/data_dictionary.js";
|
||||
import { reactive } from "vue";
|
||||
import { translationStatus } from "@/assets/js/utils.js";
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import {
|
||||
getClassManagementExportLearningRecords,
|
||||
getClassManagementStudentList,
|
||||
setClassManagementStudentDelete,
|
||||
} from "@/request/training_process_management.js";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import * as XLSX from "xlsx";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import AddStudent from "./add_student.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { CLASS_ID, STATE, type } = route.query;
|
||||
const isEdit = STATE && STATE !== "1";
|
||||
const learningStatus = [
|
||||
{ ID: "0", NAME: "未学习" },
|
||||
{ ID: "1", NAME: "学习中" },
|
||||
{ ID: "2", NAME: "已学完" },
|
||||
{ ID: "3", NAME: "已完成" },
|
||||
{ ID: "4", NAME: "未完成" },
|
||||
{ ID: "5", NAME: "待评估" },
|
||||
{ ID: "6", NAME: "评估未合格" },
|
||||
];
|
||||
const examStatus = [
|
||||
{ ID: "0", NAME: "不考试" },
|
||||
{ ID: "1", NAME: "待考试" },
|
||||
{ ID: "2", NAME: "考试未通过" },
|
||||
{ ID: "3", NAME: "考试通过" },
|
||||
{ ID: "4", NAME: "未参加" },
|
||||
];
|
||||
const data = reactive({
|
||||
postList: [],
|
||||
addStudentDialog: {
|
||||
visible: false,
|
||||
form: {
|
||||
releaseType: "",
|
||||
personnelTypes: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
const { list, searchForm, fnGetData } = useListData(
|
||||
getClassManagementStudentList,
|
||||
{
|
||||
otherParams: { CLASS_ID },
|
||||
usePagination: false,
|
||||
callbackFn: (list, resData) => {
|
||||
data.addStudentDialog.form.releaseType =
|
||||
resData.classInfo.RELEASE_TYPE || "";
|
||||
data.addStudentDialog.form.personnelTypes = resData.classInfo
|
||||
.PERSONNEL_TYPES
|
||||
? resData.classInfo.PERSONNEL_TYPES.split(",")
|
||||
: [];
|
||||
},
|
||||
}
|
||||
);
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
START_TIME: searchForm.value.TIME?.[0],
|
||||
END_TIME: searchForm.value.TIME?.[1],
|
||||
});
|
||||
};
|
||||
const fnGetPost = async (DEPARTMENT_ID) => {
|
||||
data.postList = [];
|
||||
searchForm.value.POST_ID = "";
|
||||
if (!DEPARTMENT_ID) return;
|
||||
const resData = await getPostListAll({ DEPARTMENT_ID });
|
||||
data.postList = resData.postList;
|
||||
};
|
||||
const fnGetLearningRecords = async () => {
|
||||
await ElMessageBox.confirm("确定要导出查询出来所有的学习记录?", {
|
||||
type: "warning",
|
||||
});
|
||||
const resData = await getClassManagementExportLearningRecords({
|
||||
CLASS_ID,
|
||||
...searchForm.value,
|
||||
START_TIME: searchForm.value.TIME?.[0],
|
||||
END_TIME: searchForm.value.TIME?.[1],
|
||||
});
|
||||
if (resData.varList.length > 0) fnExportLearningRecords(resData.varList);
|
||||
else ElMessage.warning("没有学习记录");
|
||||
};
|
||||
const fnExportLearningRecords = (list) => {
|
||||
const tableData = [
|
||||
[
|
||||
"序号",
|
||||
"身份证",
|
||||
"姓名",
|
||||
"性别",
|
||||
"手机号",
|
||||
"部门",
|
||||
"岗位",
|
||||
"要求总学时",
|
||||
"已完成学时",
|
||||
"是否考试通过",
|
||||
"考试分数",
|
||||
"学习状态",
|
||||
"班级名称",
|
||||
],
|
||||
];
|
||||
list.forEach((item, index) => {
|
||||
for (let i = 0; i < learningStatus.length; i++) {
|
||||
if (learningStatus[i].ID === item.STUDYSTATE) {
|
||||
item.STUDYSTATE = learningStatus[i].NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < examStatus.length; i++) {
|
||||
if (learningStatus[i].ID === item.STAGEEXAMSTATE) {
|
||||
item.STAGEEXAMSTATE = learningStatus[i].NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item.ALL_CLASSHOUR === "0.0") item.ALL_CLASSHOUR = "0";
|
||||
const COMPLETE_CLASSHOUR =
|
||||
item.COMPLETE_CLASSHOUR === "0.0"
|
||||
? 0
|
||||
: parseFloat(item.COMPLETE_CLASSHOUR).toFixed(1);
|
||||
tableData.push([
|
||||
index + 1,
|
||||
item.USER_ID_CARD,
|
||||
item.NAME,
|
||||
item.SEX,
|
||||
item.PHONE,
|
||||
item.DEPARTMENT_NAME,
|
||||
item.POST_NAME,
|
||||
item.ALL_CLASSHOUR,
|
||||
COMPLETE_CLASSHOUR,
|
||||
item.STAGEEXAMSTATE,
|
||||
item.EXAMSCORE,
|
||||
item.STUDYSTATE,
|
||||
item.CLASS_NAME,
|
||||
]);
|
||||
});
|
||||
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("导出成功");
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (STUDENT_ID) => {
|
||||
await ElMessageBox.confirm("确定要从本班移除该学员吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setClassManagementStudentDelete({ STUDENT_ID });
|
||||
ElMessage.success("移除成功");
|
||||
fnGetDataTransfer();
|
||||
},
|
||||
{ atBegin: type }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,344 @@
|
|||
<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="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="TRAINTYPE">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINTYPE"
|
||||
type="trainingType"
|
||||
@update:model-value="
|
||||
searchForm.POSTTYPE = '';
|
||||
searchForm.TRAINLEVEL = '';
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="行业类型" prop="INDUSTRY_END_ID">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.INDUSTRY_END_ID"
|
||||
type="industryType"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="岗位类型" prop="POSTTYPE">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="searchForm.TRAINTYPE"
|
||||
@update:model-value="searchForm.TRAINLEVEL = ''"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="培训级别" prop="TRAINLEVEL">
|
||||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINLEVEL"
|
||||
type="trainingLevel"
|
||||
:search-value="searchForm.POSTTYPE"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="班级状态" prop="STATE">
|
||||
<el-select v-model="searchForm.STATE">
|
||||
<el-option
|
||||
v-for="item in classStatusList"
|
||||
: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="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-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="mb-10">
|
||||
<span class="mr-10">
|
||||
班级总数:<i>{{ data.clsNum }}</i>
|
||||
</span>
|
||||
<span>
|
||||
班级总人次:<i>{{ data.stuNum }}</i>
|
||||
</span>
|
||||
</div>
|
||||
<layout-table
|
||||
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="NAME"
|
||||
show-overflow-tooltip
|
||||
fixed="left"
|
||||
/>
|
||||
<el-table-column
|
||||
label="班级编码"
|
||||
prop="CODE"
|
||||
width="150"
|
||||
fixed="left"
|
||||
/>
|
||||
<el-table-column
|
||||
label="培训类型"
|
||||
prop="TRAININGTYPE_NAME"
|
||||
width="150"
|
||||
/>
|
||||
<el-table-column label="行业类型" prop="POSTTYPE_NAME" width="150" />
|
||||
<el-table-column
|
||||
label="岗位类型"
|
||||
prop="INDUSTRY_ALL_NAME"
|
||||
width="200"
|
||||
/>
|
||||
<el-table-column label="培训等级" prop="TRAINLEVEL_NAME" width="150" />
|
||||
<el-table-column label="负责人" prop="PRINCIPAL" width="150" />
|
||||
<el-table-column label="培训开始时间" prop="START_TIME" width="150" />
|
||||
<el-table-column label="培训结束时间" prop="END_TIME" width="150" />
|
||||
<el-table-column label="涉及培训岗位数" prop="POSTNUM" width="150" />
|
||||
<el-table-column label="学员人员数" prop="STUDENT_NUM" width="150" />
|
||||
<el-table-column label="试卷类型" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ translationStatus(row.STATE, classStatusList) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path:
|
||||
row.STATE === '1'
|
||||
? '/training_process_management/class_management/edit'
|
||||
: '/training_process_management/class_management/view',
|
||||
query: {
|
||||
STATE: row.STATE,
|
||||
CLASS_ID: row.CLASS_ID,
|
||||
EXAMINATION: row.EXAMINATION,
|
||||
ISSTRENGTHEN: row.ISSTRENGTHEN,
|
||||
TRAINTYPE: row.TRAINTYPE,
|
||||
type: row.STATE === '1' ? 'edit' : 'view',
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
{{ row.STATE === "1" ? "编辑" : "查看" }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/class_management/student',
|
||||
query: {
|
||||
STATE: row.STATE,
|
||||
CLASS_ID: row.CLASS_ID,
|
||||
EXAMINATION: row.EXAMINATION,
|
||||
ISSTRENGTHEN: row.ISSTRENGTHEN,
|
||||
TRAINTYPE: row.TRAINTYPE,
|
||||
type: 'edit',
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
学员
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/class_management/curriculum',
|
||||
query: {
|
||||
STATE: row.STATE,
|
||||
CLASS_ID: row.CLASS_ID,
|
||||
EXAMINATION: row.EXAMINATION,
|
||||
ISSTRENGTHEN: row.ISSTRENGTHEN,
|
||||
TRAINTYPE: row.TRAINTYPE,
|
||||
type: 'edit',
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
课程
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.STATE === '1' && row.STUDYRECORDCNT === 0"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.CLASS_ID)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.STATE !== '1'"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelay(row.CLASS_ID, row.END_TIME)"
|
||||
>
|
||||
延期
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="
|
||||
router.push({
|
||||
path: '/training_process_management/class_management/add',
|
||||
query: { type: 'add' },
|
||||
})
|
||||
"
|
||||
>
|
||||
新建培训任务
|
||||
</el-button>
|
||||
</template>
|
||||
</layout-table>
|
||||
</layout-card>
|
||||
<delay
|
||||
v-model:visible="data.delayDialog.visible"
|
||||
v-model:form="data.delayDialog.form"
|
||||
@get-data="fnResetPaginationTransfer"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useListData from "@/assets/js/useListData.js";
|
||||
import { serialNumber, translationStatus } from "@/assets/js/utils.js";
|
||||
import { useRouter } from "vue-router";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import {
|
||||
getClassManagementList,
|
||||
setClassManagementDelete,
|
||||
} from "@/request/training_process_management.js";
|
||||
import LayoutLearningTrainType from "@/components/learning_train_type/index.vue";
|
||||
import { nextTick, reactive } from "vue";
|
||||
import Delay from "./components/delay.vue";
|
||||
|
||||
const classStatusList = [
|
||||
{ ID: "1", NAME: "未申请" },
|
||||
{ ID: "4", NAME: "待开班" },
|
||||
{ ID: "5", NAME: "培训中" },
|
||||
{ ID: "6", NAME: "培训结束" },
|
||||
];
|
||||
const router = useRouter();
|
||||
const data = reactive({
|
||||
stuNum: 0,
|
||||
clsNum: 0,
|
||||
delayDialog: {
|
||||
visible: false,
|
||||
form: {
|
||||
CLASS_ID: "",
|
||||
TIME: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
||||
useListData(getClassManagementList, {
|
||||
callbackFn: (list, resData) => {
|
||||
data.stuNum = resData.stuNum;
|
||||
data.clsNum = resData.clsNum;
|
||||
},
|
||||
});
|
||||
const fnGetDataTransfer = () => {
|
||||
fnGetData({
|
||||
STARTTIME: searchForm.value.TIME?.[0],
|
||||
ENDTIME: searchForm.value.TIME?.[1],
|
||||
OVERSTARTTIME: searchForm.value.TIME1?.[0],
|
||||
OVERENDTIME: searchForm.value.TIME1?.[1],
|
||||
});
|
||||
};
|
||||
const fnResetPaginationTransfer = () => {
|
||||
fnResetPagination({
|
||||
STARTTIME: searchForm.value.TIME?.[0],
|
||||
ENDTIME: searchForm.value.TIME?.[1],
|
||||
OVERSTARTTIME: searchForm.value.TIME1?.[0],
|
||||
OVERENDTIME: searchForm.value.TIME1?.[1],
|
||||
});
|
||||
};
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (CLASS_ID) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
await setClassManagementDelete({ CLASS_ID });
|
||||
ElMessage.success("删除成功");
|
||||
fnResetPaginationTransfer();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnDelay = async (CLASS_ID, END_TIME) => {
|
||||
data.delayDialog.visible = true;
|
||||
await nextTick();
|
||||
data.delayDialog.form.CLASS_ID = CLASS_ID;
|
||||
data.delayDialog.form.TIME = END_TIME;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div>
|
||||
<layout-card>
|
||||
<el-tabs v-model="active" @tab-change="fnTabChange">
|
||||
<el-tab-pane label="学习记录" name="learning_records" lazy>
|
||||
<learning-records />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="考试记录" name="exam_records" lazy>
|
||||
<exam-records />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</layout-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
||||
import { ref } from "vue";
|
||||
import LearningRecords from "./components/learning_records.vue";
|
||||
import ExamRecords from "./components/exam_records.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const defaultName = "learning_records";
|
||||
const active = ref(route.query.active || defaultName);
|
||||
onBeforeRouteUpdate((to, from, next) => {
|
||||
active.value = to.query.active || defaultName;
|
||||
next();
|
||||
});
|
||||
const fnTabChange = (active) => {
|
||||
router.replace({
|
||||
path: "/training_process_management/class_management/student/learning_records",
|
||||
query: { ...route.query, active },
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -1,7 +1,382 @@
|
|||
<template>
|
||||
<layout-card>11</layout-card>
|
||||
<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"
|
||||
:disabled="type !== 'add'"
|
||||
/>
|
||||
</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>
|
||||
<template v-if="type === 'add'">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="下载模板">
|
||||
<el-button type="primary" @click="fnDownloadTemplate">
|
||||
下载
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="上传试题" prop="fileList">
|
||||
<layout-upload
|
||||
v-model:file-list="data.form.fileList"
|
||||
accept=".XLS,.XLSX,.xls,.xlsx"
|
||||
:size="1"
|
||||
>
|
||||
<template #tip>
|
||||
只能上传.XLS 和 .XLSX格式的单个文件,且文件大小不超过1MB!
|
||||
</template>
|
||||
</layout-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
</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('normal')">
|
||||
{{ buttonTextMap[type] }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="fnSubmit('draft')">
|
||||
保存到草稿箱
|
||||
</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></script>
|
||||
<script setup>
|
||||
import { nextTick, reactive, ref } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import LayoutUpload from "@/components/upload/index.vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/assets/js/useFormValidate.js";
|
||||
import {
|
||||
setExamPaperManagementAdd,
|
||||
setExamPaperManagementAddToDraft,
|
||||
setExamPaperManagementEdit,
|
||||
setExamPaperManagementInherit,
|
||||
setExamPaperManagementTestQuestionsDelete,
|
||||
} from "@/request/training_process_management.js";
|
||||
import {
|
||||
getExamPaperManagementTestQuestions,
|
||||
getExamPaperManagementView,
|
||||
} 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";
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { type, STAGEEXAMPAPERINPUT_ID } = route.query;
|
||||
const buttonTextMap = {
|
||||
add: "立即创建",
|
||||
edit: "保存修改",
|
||||
inherit: "继承试卷",
|
||||
};
|
||||
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(
|
||||
getExamPaperManagementTestQuestions,
|
||||
{
|
||||
otherParams: { STAGEEXAMPAPERINPUT_ID },
|
||||
immediate: false,
|
||||
usePagination: false,
|
||||
}
|
||||
);
|
||||
const fnGetDataInfo = async () => {
|
||||
if (!STAGEEXAMPAPERINPUT_ID) return;
|
||||
const resData = await getExamPaperManagementView({ STAGEEXAMPAPERINPUT_ID });
|
||||
resData.pd.EXAMSCORE = +resData.pd.EXAMSCORE;
|
||||
resData.pd.PASSSCORE = +resData.pd.PASSSCORE;
|
||||
data.form = resData.pd;
|
||||
fnGetData();
|
||||
};
|
||||
fnGetDataInfo();
|
||||
const fnDownloadTemplate = async () => {
|
||||
await ElMessageBox.confirm("确定要下载excel模板吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
window.open(
|
||||
import.meta.env[import.meta.env.DEV ? "VITE_PROXY" : "VITE_BASE_URL"] +
|
||||
"question/downExcel"
|
||||
);
|
||||
};
|
||||
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, index) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", {
|
||||
type: "warning",
|
||||
});
|
||||
if (type === "inherit") {
|
||||
list.value.splice(index, 1);
|
||||
data.form.EXAMSCORE = sumBy(list.value, (item) => +item.SCORE);
|
||||
ElMessage.success("删除成功");
|
||||
} else {
|
||||
await setExamPaperManagementTestQuestionsDelete({
|
||||
PAPER_QUESTION_ID,
|
||||
STAGEEXAMPAPERINPUT_ID,
|
||||
});
|
||||
ElMessage.success("删除成功");
|
||||
await fnGetDataInfo();
|
||||
}
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async (submitType) => {
|
||||
await useFormValidate(formRef);
|
||||
if (data.form.PASSSCORE > data.form.EXAMSCORE) {
|
||||
ElMessage.warning("合格分数不能大于总分数");
|
||||
return;
|
||||
}
|
||||
const formData = new FormData();
|
||||
Object.keys(data.form).forEach((key) => {
|
||||
formData.append(key, data.form[key]);
|
||||
});
|
||||
formData.delete("fileList");
|
||||
if (data.form.fileList?.length > 0) {
|
||||
formData.append("FFILENAME", data.form.fileList[0].name);
|
||||
formData.append("FFILE", data.form.fileList[0].raw);
|
||||
}
|
||||
let resData;
|
||||
if (submitType === "draft") {
|
||||
resData = await setExamPaperManagementAddToDraft(formData);
|
||||
} else if (submitType === "normal") {
|
||||
if (type === "add") {
|
||||
resData = await setExamPaperManagementAdd(formData);
|
||||
}
|
||||
if (type === "edit") {
|
||||
resData = await setExamPaperManagementEdit(formData);
|
||||
}
|
||||
if (type === "inherit") {
|
||||
await setExamPaperManagementInherit({
|
||||
...data.form,
|
||||
queList: JSON.stringify(list.value),
|
||||
});
|
||||
router.back();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (resData.code === 1) {
|
||||
ElMessage.success("保存成功");
|
||||
router.back();
|
||||
} else {
|
||||
ElMessage({
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: resData.msg,
|
||||
type: "error",
|
||||
showClose: true,
|
||||
duration: 10 * 1000,
|
||||
});
|
||||
}
|
||||
},
|
||||
{ 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,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,
|
||||
setExamPaperManagementTestQuestionsAdd,
|
||||
setExamPaperManagementTestQuestionsEdit,
|
||||
} 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 setExamPaperManagementTestQuestionsAdd({
|
||||
...form.value,
|
||||
STAGEEXAMPAPERINPUT_ID: props.id,
|
||||
})
|
||||
: await setExamPaperManagementTestQuestionsEdit({ ...form.value });
|
||||
emits("get-data");
|
||||
} else {
|
||||
emits("confirm", cloneDeep(form.value));
|
||||
}
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -93,7 +93,7 @@
|
|||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.SOURCETYPE === '1' || row.PAPERUSERCOUNT > 0"
|
||||
v-if="row.SOURCETYPE === '2' || row.PAPERUSERCOUNT === 0"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
|
@ -126,7 +126,7 @@
|
|||
继承
|
||||
</el-button>
|
||||
<el-button
|
||||
v-show="row.SOURCETYPE === '1' || row.PAPERUSERCOUNT > 0"
|
||||
v-if="row.SOURCETYPE === '2' || row.PAPERUSERCOUNT === 0"
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
ref="trainingTypeRef"
|
||||
v-model="data.form.TRAINTYPE"
|
||||
type="trainingType"
|
||||
@update:model-value="
|
||||
data.form.POSTTYPE = '';
|
||||
data.form.TRAINLEVEL = '';
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -38,6 +42,7 @@
|
|||
v-model="data.form.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="data.form.TRAINTYPE"
|
||||
@update:model-value="data.form.TRAINLEVEL = ''"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINTYPE"
|
||||
type="trainingType"
|
||||
@update:model-value="
|
||||
searchForm.POSTTYPE = '';
|
||||
searchForm.TRAINLEVEL = '';
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -47,6 +51,7 @@
|
|||
v-model="searchForm.POSTTYPE"
|
||||
type="postType"
|
||||
:search-value="searchForm.TRAINTYPE"
|
||||
@update:model-value="searchForm.TRAINLEVEL = ''"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<layout-learning-train-type
|
||||
v-model="searchForm.TRAINTYPE"
|
||||
type="trainingType"
|
||||
@update:model-value="searchForm.POSTTYPE = ''"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
|
Loading…
Reference in New Issue