From 0714f49bc3975091bd02c98e55dee31ed8f02ab4 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期五, 30 一月 2026 15:00:13 +0800
Subject: [PATCH] 安全培训考核模块
---
src/views/safeProduction/safetyTrainingAssessment/index.vue | 403 ++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 356 insertions(+), 47 deletions(-)
diff --git a/src/views/safeProduction/safetyTrainingAssessment/index.vue b/src/views/safeProduction/safetyTrainingAssessment/index.vue
index 8fbfe9b..0027c7f 100644
--- a/src/views/safeProduction/safetyTrainingAssessment/index.vue
+++ b/src/views/safeProduction/safetyTrainingAssessment/index.vue
@@ -2,19 +2,19 @@
<div class="app-container">
<div class="search_form">
<div>
- <span class="search_title">鍩硅鍚嶇О锛�</span>
- <el-input v-model="searchForm.name"
+ <span class="search_title">璇剧▼缂栧彿锛�</span>
+ <el-input v-model="searchForm.courseCode"
style="width: 240px"
- placeholder="璇疯緭鍏ュ煿璁悕绉版悳绱�"
+ placeholder="璇疯緭鍏ュ煿璁紪鍙锋悳绱�"
@change="handleQuery"
clearable
:prefix-icon="Search" />
- <span class="search_title ml10">鍩硅绫诲瀷锛�</span>
- <el-select v-model="searchForm.type"
+ <span class="search_title ml10">鍩硅鏂瑰紡锛�</span>
+ <el-select v-model="searchForm.trainingMode"
clearable
@change="handleQuery"
style="width: 240px">
- <el-option v-for="item in knowledgeTypeOptions"
+ <el-option v-for="item in trainingModeOptions"
:key="item.value"
:label="item.label"
:value="item.value" />
@@ -28,12 +28,24 @@
<div>
<el-button type="primary"
@click="openForm('add')">鏂板鍩硅</el-button>
+ <el-button type="primary"
+ @click="opendetail">鍩硅璁板綍</el-button>
<el-button type="danger"
plain
@click="handleDelete">鍒犻櫎</el-button>
</div>
</div>
<div class="table_list">
+ <el-tabs v-model="searchForm.state"
+ @tab-click="tabhandleQuery">
+ <el-tab-pane label="鏈紑濮�"
+ :name="0"></el-tab-pane>
+ <el-tab-pane label="杩涜涓�"
+ :name="1"></el-tab-pane>
+ <el-tab-pane label="宸茬粨鏉�"
+ :name="2"></el-tab-pane>
+ </el-tabs>
+ <!-- state 鐘舵��(0锛氭湭寮�濮�1锛氳繘琛屼腑锛�2锛氬凡缁撴潫) -->
<PIMTable rowKey="id"
:column="tableColumn"
:tableData="tableData"
@@ -135,6 +147,8 @@
<el-form-item label="璇剧▼瀛﹀垎"
prop="projectCredits">
<el-input v-model="form.projectCredits"
+ type="number"
+ min="0"
placeholder="璇疯緭鍏ヨ绋嬪鍒�" />
</el-form-item>
</el-col>
@@ -181,51 +195,164 @@
</el-dialog>
<!-- 鏌ョ湅鐭ヨ瘑璇︽儏寮圭獥 -->
<el-dialog v-model="viewDialogVisible"
- title="鍩硅璇︽儏"
+ title="缁撴灉鏄庣粏"
width="900px"
:close-on-click-modal="false">
<div class="knowledge-detail">
- <el-descriptions :column="2"
- border>
- <el-descriptions-item label="鍩硅鍚嶇О"
- :span="2">
- <span class="detail-title">{{ currentKnowledge.name }}</span>
- </el-descriptions-item>
- <el-descriptions-item label="鍩硅缂栫爜">
- {{ currentKnowledge.code }}
- </el-descriptions-item>
- <el-descriptions-item label="鍩硅绫诲瀷">
- <el-tag type="info">
- <!-- {{ getTypeLabel(currentKnowledge.type) }} -->
+ <el-descriptions size="mini"
+ style="margin-left: 60px;"
+ :column="3">
+ <el-descriptions-item label="璇剧▼缂栧彿:">{{ currentKnowledge.courseCode }}</el-descriptions-item>
+ <el-descriptions-item label="鍩硅鍐呭:">{{ currentKnowledge.trainingContent }}</el-descriptions-item>
+ <el-descriptions-item label="鐘舵��:">
+ <el-tag :type="currentKnowledge.status === 0 ? 'success' : (currentKnowledge.status === 1 ? 'success' : 'info')">
+ {{ currentKnowledge.status === 0 ? '鏈紑濮�' : (currentKnowledge.status === 1 ? '杩涜涓�' : '宸茬粨鏉�') }}
</el-tag>
</el-descriptions-item>
- <el-descriptions-item label="鎵�鍦ㄤ綅缃�">
- {{ currentKnowledge.location }}
+ <el-descriptions-item label="鍩硅璁插笀:">
+ {{ currentKnowledge.trainingLecturer }}
</el-descriptions-item>
- <el-descriptions-item label="绠℃帶鎺柦">
- {{ currentKnowledge.controlMeasures }}
+ <el-descriptions-item label="鍩硅寮�濮嬫椂闂�:">
+ {{ currentKnowledge.trainingDate + ' ' + currentKnowledge.openingTime }}
</el-descriptions-item>
- <el-descriptions-item label="搴撳瓨鏁伴噺">
- {{ currentKnowledge.stockQty }}
+ <el-descriptions-item label="鍩硅缁撴潫鏃堕棿:">
+ {{ currentKnowledge.trainingDate + ' ' + currentKnowledge.endTime }}
</el-descriptions-item>
- <el-descriptions-item label="绠℃帶璐d换浜�">
- {{ currentKnowledge.principalUserId }}
+ <el-descriptions-item label="鍩硅鐩爣:">
+ {{ currentKnowledge.trainingObjectives }}
</el-descriptions-item>
- <el-descriptions-item label="璐d换浜鸿仈绯荤數璇�">
- {{ currentKnowledge.principalMobile }}
+ <el-descriptions-item label="鍙傚姞瀵硅薄:">
+ {{ currentKnowledge.participants }}
</el-descriptions-item>
- <el-descriptions-item label="椋庨櫓绛夌骇">
- <el-tag :type="getTypeTagType(currentKnowledge.riskLevel)">
- {{ currentKnowledge.riskLevel }}
+ <el-descriptions-item label="鍩硅鏂瑰紡:">
+ <el-tag type="primary">
+ {{ getTrainingModeLabel(currentKnowledge.trainingMode) }}
</el-tag>
</el-descriptions-item>
- <el-descriptions-item label="瑙勬牸 / 椋庨櫓鎻忚堪">
- {{ currentKnowledge.specInfo }}
+ <el-descriptions-item label="鍩硅鍦扮偣:">
+ {{ currentKnowledge.placeTraining }}
+ </el-descriptions-item>
+ <el-descriptions-item label="璇炬椂:">
+ {{ currentKnowledge.classHour }}
+ </el-descriptions-item>
+ <el-descriptions-item label="璇剧▼瀛﹀垎:">
+ {{ currentKnowledge.projectCredits }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鎶ュ悕浜烘暟:">
+ {{ currentKnowledge.nums }}
+ </el-descriptions-item>
+ <el-descriptions-item label="闄勪欢鍒楄〃:">
+ <el-button type="primary"
+ size="small"
+ @click="downLoadFile(endform)">闄勪欢鍒楄〃</el-button>
</el-descriptions-item>
</el-descriptions>
+ <el-divider style="margin: 20px 0;" />
+ <el-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="130px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璇勪环浜�:"
+ prop="courseCode">
+ <el-input v-model="endform.assessmentUserName"
+ disabled
+ placeholder="璇烽�夋嫨璇勪环浜�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璇勪环鏃堕棿:"
+ prop="trainingDate">
+ <el-date-picker style="width: 100%"
+ disabled
+ v-model="endform.assessmentDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鑰冩牳鏂瑰紡:"
+ prop="assessmentMethod">
+ <el-input v-model="endform.assessmentMethod"
+ placeholder="璇烽�夋嫨鑰冩牳鏂瑰紡" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈璇剧▼缁煎悎璇勪环:"
+ prop="comprehensiveAssessment">
+ <el-input v-model="endform.comprehensiveAssessment"
+ placeholder="璇疯緭鍏ユ湰娆¤绋嬬患鍚堣瘎浠�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="鍩硅鎽樿:"
+ prop="trainingAbstract">
+ <el-input v-model="endform.trainingAbstract"
+ type="textarea"
+ :rows="2"
+ placeholder="璇疯緭鍏ュ煿璁憳瑕�" />
+ </el-form-item>
+ <!-- <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="闄勪欢鏉愭枡锛�"
+ prop="remark">
+ <el-upload v-model:file-list="fileList"
+ :action="upload.url"
+ multiple
+ ref="fileUpload"
+ auto-upload
+ :headers="upload.headers"
+ :before-upload="handleBeforeUpload"
+ :on-error="handleUploadError"
+ :on-success="handleUploadSuccess"
+ :on-remove="handleRemove">
+ <el-button type="primary"
+ v-if="operationType !== 'view'">涓婁紶</el-button>
+ <template #tip
+ v-if="operationType !== 'view'">
+ <div class="el-upload__tip">
+ 鏂囦欢鏍煎紡鏀寔
+ doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
+ </div>
+ </template>
+ </el-upload>
+ </el-form-item>
+ </el-col>
+ </el-row> -->
+ </el-form>
+ <el-table style="margin-top: 20px;"
+ :data="endform.safeTrainingDetailsDtoList"
+ border
+ fit
+ highlight-current-row>
+ <el-table-column prop="nickName"
+ label="濮撳悕" />
+ <el-table-column prop="phonenumber"
+ label="鐢佃瘽鍙风爜" />
+ <el-table-column prop="examinationResults"
+ label="鑰冩牳缁撴灉">
+ <template #default="scope">
+ <el-select v-model="scope.row.examinationResults"
+ placeholder="璇烽�夋嫨鑰冩牳缁撴灉">
+ <el-option label="鍚堟牸"
+ value="鍚堟牸" />
+ <el-option label="涓嶅悎鏍�"
+ value="涓嶅悎鏍�" />
+ </el-select>
+ </template>
+ </el-table-column>
+ </el-table>
</div>
<template #footer>
<span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitForm2">鎻愪氦</el-button>
<el-button @click="viewDialogVisible = false">鍏抽棴</el-button>
</span>
</template>
@@ -265,7 +392,13 @@
safeTrainingFileListPage,
safeTrainingFileAdd,
safeTrainingFileDel,
+ safeTrainingSign,
+ safeTrainingGet,
+ safeTrainingSave,
} from "@/api/safeProduction/safetyTrainingAssessment.js";
+ import useUserStore from "@/store/modules/user";
+ import dayjs from "dayjs";
+ const userStore = useUserStore();
// 琛ㄥ崟楠岃瘉瑙勫垯
const rules = {
@@ -284,12 +417,18 @@
],
classHour: [{ required: true, message: "璇疯緭鍏ヨ鏃�", trigger: "blur" }],
};
-
+ const upload = reactive({
+ // 涓婁紶鐨勫湴鍧�
+ url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+ // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+ headers: { Authorization: "Bearer " + getToken() },
+ });
// 鍝嶅簲寮忔暟鎹�
const data = reactive({
searchForm: {
- name: "",
- type: "",
+ courseCode: "",
+ trainingMode: "",
+ state: 0,
},
tableLoading: false,
page: {
@@ -342,6 +481,13 @@
);
return item ? item.label : val;
};
+ // 鍒囨崲tab鏌ヨ
+ const tabhandleQuery = val => {
+ searchForm.value.state = val.paneName;
+ console.log(searchForm.value.state, "searchForm.value.state");
+
+ handleQuery();
+ };
// 琛ㄥ崟寮曠敤
const formRef = ref();
const riskLevelOptions = ref([
@@ -351,56 +497,69 @@
{ value: "閲嶅ぇ椋庨櫓", label: "閲嶅ぇ椋庨櫓" },
]);
+ const fileList = ref([]);
+
// 琛ㄦ牸鍒楅厤缃�
const tableColumn = ref([
{
label: "璇剧▼缂栧彿",
prop: "courseCode",
+ width: 150,
showOverflowTooltip: true,
},
{
label: "鍩硅鏃ユ湡",
prop: "trainingDate",
+ width: 120,
+
showOverflowTooltip: true,
},
{
label: "寮�濮嬫椂闂�",
prop: "openingTime",
+ width: 120,
showOverflowTooltip: true,
},
{
label: "缁撴潫鏃堕棿",
prop: "endTime",
+ width: 120,
showOverflowTooltip: true,
},
{
label: "鍩硅鐩爣",
prop: "trainingObjectives",
+ width: 200,
showOverflowTooltip: true,
},
{
label: "鍙傚姞瀵硅薄",
prop: "participants",
+ width: 200,
showOverflowTooltip: true,
},
{
label: "鍩硅鍐呭",
prop: "trainingContent",
+ width: 200,
showOverflowTooltip: true,
},
{
label: "鍩硅璁插笀",
prop: "trainingLecturer",
+ width: 200,
showOverflowTooltip: true,
},
{
label: "椤圭洰瀛﹀垎",
prop: "projectCredits",
+ width: 120,
showOverflowTooltip: true,
},
{
label: "鍩硅鏂瑰紡",
prop: "trainingMode",
+ width: 120,
showOverflowTooltip: true,
formatData: params => {
return getTrainingModeLabel(params);
@@ -409,11 +568,19 @@
{
label: "鍩硅鍦扮偣",
prop: "placeTraining",
+ width: 200,
showOverflowTooltip: true,
},
{
label: "璇炬椂",
prop: "classHour",
+ width: 120,
+ showOverflowTooltip: true,
+ },
+ {
+ label: "鎶ュ悕浜烘暟",
+ prop: "nums",
+ width: 120,
showOverflowTooltip: true,
},
{
@@ -421,27 +588,47 @@
label: "鎿嶄綔",
align: "center",
fixed: "right",
- width: 200,
+ width: 300,
operation: [
+ {
+ name: "绛惧埌",
+ type: "text",
+ disabled: row => row.state !== 1,
+ clickFun: row => {
+ signIn(row);
+ },
+ },
{
name: "缂栬緫",
type: "text",
+ disabled: row => row.state !== 0,
clickFun: row => {
openForm("edit", row);
},
},
{
name: "瀵煎嚭",
- type: "danger",
+ type: "text",
clickFun: row => {
exportKnowledge(row);
},
+ color: "#C49000",
},
{
name: "闄勪欢",
- type: "danger",
+ type: "text",
clickFun: row => {
downLoadFile(row);
+ },
+ color: "#007AFF",
+ },
+
+ {
+ name: "缁撴灉鏄庣粏",
+ type: "text",
+ // disabled: row => row.state !== 2,
+ clickFun: row => {
+ viewResultDetail(row);
},
},
// {
@@ -457,12 +644,133 @@
const userList = ref([]);
// 鐢熷懡鍛ㄦ湡
onMounted(() => {
+ getCurrentFactoryName();
getList();
startAutoRefresh();
userListNoPage().then(res => {
userList.value = res.data;
});
});
+ const endform = ref({
+ assessmentUserId: "", //璇勪环浜�
+ assessmentUserName: "", //璇勪环浜哄鍚�
+ assessmentMethod: "", //鑰冩牳鏂瑰紡
+ assessmentDate: "", //璇勪环鏃堕棿
+ comprehensiveAssessment: "", //缁煎悎璇勪环
+ trainingAbstract: "", //鍩硅鎽樿
+ safeTrainingFileList: [], //鍩硅闄勪欢
+ safeTrainingDetailsDtoList: [], //鑰冩牳缁撴灉璇︽儏
+ });
+ const operationType = ref("edit");
+ const viewResultDetail = row => {
+ // fileList.value = [];
+ operationType.value = "edit";
+ safeTrainingGet({ id: row.id }).then(res => {
+ if (res.code === 200) {
+ console.log(res.data, "res.data");
+ currentKnowledge.value = JSON.parse(JSON.stringify(res.data));
+ currentKnowledge.value.nums = row.nums;
+ viewDialogVisible.value = true;
+ endform.value = { ...res.data };
+ endform.value.assessmentUserName = endform.value.assessmentUserName
+ ? endform.value.assessmentUserName
+ : currentUserName.value;
+ endform.value.assessmentUserId = endform.value.assessmentUserId
+ ? endform.value.assessmentUserId
+ : currentUserId.value;
+ endform.value.assessmentDate = dayjs().format("YYYY-MM-DD");
+ } else {
+ proxy.$modal.msgError(res.msg || "鏌ヨ璇︽儏澶辫触");
+ }
+ });
+ };
+
+ // 涓婁紶鍓嶆牎妫�
+ function handleBeforeUpload(file) {
+ proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+ return true;
+ }
+ // 涓婁紶澶辫触
+ function handleUploadError(err) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+ proxy.$modal.closeLoading();
+ }
+ // 涓婁紶鎴愬姛鍥炶皟
+ function handleUploadSuccess(res, file, uploadFiles) {
+ proxy.$modal.closeLoading();
+ if (res.code === 200) {
+ // 纭繚 tempFileIds 瀛樺湪涓斾负鏁扮粍
+ if (!endform.value.safeTrainingFileList) {
+ endform.value.safeTrainingFileList = [];
+ }
+ endform.value.safeTrainingFileList.push({
+ id: res.data.tempId,
+ fileName: res.data.originalName,
+ url: res.data.tempPath,
+ safeTrainingId: currentKnowledge.value.id,
+ });
+ proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+ } else {
+ proxy.$modal.msgError(res.msg);
+ proxy.$refs.fileUpload.handleRemove(file);
+ }
+ }
+ // 绉婚櫎鏂囦欢
+ function handleRemove(file) {
+ if (operationType.value === "edit") {
+ let index = endform.value.safeTrainingFileList.findIndex(
+ item => item.fileName === file.name
+ );
+ if (index !== -1) {
+ endform.value.safeTrainingFileList.splice(index, 1);
+ }
+ }
+ }
+ const submitForm2 = () => {
+ endform.value.safeTrainingDetailsDtoList.forEach((item, index) => {
+ if (!item.examinationResults) {
+ proxy.$modal.msgError(`璇烽�夋嫨${item.nickName}鐨勮�冩牳缁撴灉`);
+ return;
+ }
+ });
+ console.log(endform.value, "endform.value");
+ proxy.$modal.loading("姝e湪鎻愪氦锛岃绋嶅��...");
+ safeTrainingSave(endform.value).then(res => {
+ proxy.$modal.closeLoading();
+ if (res.code === 200) {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ getList();
+ viewDialogVisible.value = false;
+ } else {
+ proxy.$modal.msgError(res.msg || "鎻愪氦澶辫触");
+ }
+ });
+ };
+ const opendetail = row => {
+ proxy.$router.push({
+ path: "/safeProduction/safetyTrainingAssessmentDetail",
+ });
+ };
+
+ const signIn = row => {
+ ElMessageBox.confirm("纭绛惧埌鍚楋紵", "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ }).then(() => {
+ safeTrainingSign({
+ safeTrainingId: row.id,
+ userId: currentUserId.value,
+ }).then(res => {
+ if (res.code === 200) {
+ proxy.$modal.msgSuccess("绛惧埌鎴愬姛");
+ getList();
+ } else {
+ proxy.$modal.msgError(res.msg || "绛惧埌澶辫触");
+ }
+ });
+ });
+ };
// 澶勭悊鐢ㄦ埛閫夋嫨鍙樺寲
const handleUserChange = userId => {
@@ -627,7 +935,7 @@
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
- link.download = `鍩硅璁板綍_${row.courseCode}.xlsx`;
+ link.download = `鍩硅璁板綍_${row.courseCode}.docx`;
// 妯℃嫙鐐瑰嚮涓嬭浇
document.body.appendChild(link);
@@ -670,6 +978,13 @@
const handleSelectionChange = selection => {
selectedIds.value = selection.map(item => item.id);
};
+ const currentUserId = ref("");
+ const currentUserName = ref("");
+ const getCurrentFactoryName = async () => {
+ let res = await userStore.getInfo();
+ currentUserId.value = res.user.userId;
+ currentUserName.value = res.user.nickName;
+ };
// 鎵撳紑琛ㄥ崟
const openForm = (type, row = null) => {
@@ -710,12 +1025,6 @@
});
}
dialogVisible.value = true;
- };
-
- // 鏌ョ湅鍩硅璇︽儏
- const viewKnowledge = row => {
- currentKnowledge.value = { ...row };
- viewDialogVisible.value = true;
};
// 鑾峰彇绫诲瀷鏍囩绫诲瀷
--
Gitblit v1.9.3