From cdf69116241fbcbb4725aa68ae06a6be578dcd73 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期一, 29 六月 2026 18:01:12 +0800
Subject: [PATCH] Merge branch 'dev_兴盛旺海' of http://114.132.189.42:9002/r/product-inventory-management into dev_兴盛旺海
---
src/api/safeProduction/safetyFacility.js | 140 +++
src/api/safeProduction/lineInspection.js | 125 ++
src/views/safeProduction/hazardReport/index.vue | 529 ++++++++++++
src/views/safeProduction/lineInspection/index.vue | 918 ++++++++++++++++++++
src/views/safeProduction/safetyFacility/index.vue | 810 ++++++++++++++++++
src/api/safeProduction/hazardReport.js | 60 +
6 files changed, 2,582 insertions(+), 0 deletions(-)
diff --git a/src/api/safeProduction/hazardReport.js b/src/api/safeProduction/hazardReport.js
new file mode 100644
index 0000000..178d9fc
--- /dev/null
+++ b/src/api/safeProduction/hazardReport.js
@@ -0,0 +1,60 @@
+import request from "@/utils/request";
+
+/**
+ * 闅愭偅涓婃姤API鎺ュ彛
+ */
+
+// 鑾峰彇闅愭偅涓婃姤鍒楄〃
+export function getHazardReportList(params) {
+ return request({
+ url: "/device/hazardReport/list",
+ method: "get",
+ params,
+ });
+}
+
+// 鏂板闅愭偅涓婃姤
+export function addHazardReport(data) {
+ return request({
+ url: "/device/hazardReport/add",
+ method: "post",
+ data,
+ });
+}
+
+// 璁板綍鏁存敼缁撴灉
+export function rectifyHazardReport(data) {
+ return request({
+ url: "/device/hazardReport/rectify",
+ method: "post",
+ data,
+ });
+}
+
+// 璁板綍楠屾敹缁撴灉
+export function acceptHazardReport(data) {
+ return request({
+ url: "/device/hazardReport/accept",
+ method: "post",
+ data,
+ });
+}
+
+// 鍒犻櫎闅愭偅涓婃姤璁板綍
+export function deleteHazardReport(ids) {
+ return request({
+ url: "/device/hazardReport/delete",
+ method: "delete",
+ data: ids,
+ });
+}
+
+// 瀵煎嚭闅愭偅涓婃姤璁板綍
+export function exportHazardReport(params) {
+ return request({
+ url: "/device/hazardReport/export",
+ method: "post",
+ params,
+ responseType: 'blob',
+ });
+}
diff --git a/src/api/safeProduction/lineInspection.js b/src/api/safeProduction/lineInspection.js
new file mode 100644
index 0000000..5e0c807
--- /dev/null
+++ b/src/api/safeProduction/lineInspection.js
@@ -0,0 +1,125 @@
+import request from "@/utils/request";
+
+/**
+ * 绾胯矾宸℃API鎺ュ彛
+ */
+
+// 鑾峰彇绾胯矾宸℃鍒楄〃
+export function getLineInspectionList(params) {
+ return request({
+ url: "/safeLineInspection/page",
+ method: "get",
+ params,
+ });
+}
+
+// 鏍规嵁ID鑾峰彇绾胯矾宸℃璇︽儏
+export function getLineInspectionById(id) {
+ return request({
+ url: `/safeLineInspection/${id}`,
+ method: "get",
+ });
+}
+
+// 鏂板绾胯矾宸℃
+export function addLineInspection(data) {
+ return request({
+ url: "/safeLineInspection",
+ method: "post",
+ data,
+ });
+}
+
+// 淇敼绾胯矾宸℃
+export function updateLineInspection(data) {
+ return request({
+ url: "/safeLineInspection",
+ method: "put",
+ data,
+ });
+}
+
+// 鍒犻櫎绾胯矾宸℃
+export function deleteLineInspection(ids) {
+ return request({
+ url: "/safeLineInspection/" + ids.join(","),
+ method: "delete",
+ });
+}
+
+// 瀹屾垚宸℃
+export function completeLineInspection(id) {
+ return request({
+ url: `/safeLineInspection/complete/${id}`,
+ method: "put",
+ });
+}
+
+// 鑾峰彇宸℃璁板綍鍒楄〃
+export function getInspectionRecords(inspectionId) {
+ return request({
+ url: `/safeLineInspectionRecord/list/${inspectionId}`,
+ method: "get",
+ });
+}
+
+// 鏂板宸℃璁板綍
+export function addInspectionRecord(data) {
+ return request({
+ url: "/safeLineInspectionRecord",
+ method: "post",
+ data,
+ });
+}
+
+// 鎵归噺鏂板宸℃璁板綍
+export function batchAddInspectionRecords(data) {
+ return request({
+ url: "/safeLineInspectionRecord/batch",
+ method: "post",
+ data,
+ });
+}
+
+// 鑾峰彇宸℃闅愭偅鍒楄〃
+export function getInspectionHazards(params) {
+ return request({
+ url: "/safeLineInspectionHazard/page",
+ method: "get",
+ params,
+ });
+}
+
+// 鏍规嵁宸℃浠诲姟ID鑾峰彇闅愭偅鍒楄〃
+export function getHazardsByInspectionId(inspectionId) {
+ return request({
+ url: `/safeLineInspectionHazard/list/${inspectionId}`,
+ method: "get",
+ });
+}
+
+// 鏂板闅愭偅
+export function addInspectionHazard(data) {
+ return request({
+ url: "/safeLineInspectionHazard",
+ method: "post",
+ data,
+ });
+}
+
+// 淇敼闅愭偅
+export function updateInspectionHazard(data) {
+ return request({
+ url: "/safeLineInspectionHazard",
+ method: "put",
+ data,
+ });
+}
+
+// 鍒犻櫎闅愭偅
+export function deleteInspectionHazard(ids) {
+ return request({
+ url: "/safeLineInspectionHazard/" + ids.join(","),
+ method: "delete",
+ });
+}
diff --git a/src/api/safeProduction/safetyFacility.js b/src/api/safeProduction/safetyFacility.js
new file mode 100644
index 0000000..20d8778
--- /dev/null
+++ b/src/api/safeProduction/safetyFacility.js
@@ -0,0 +1,140 @@
+import request from "@/utils/request";
+
+/**
+ * 瀹夊叏璁炬柦宸℃API鎺ュ彛
+ */
+
+// ============ 瀹夊叏璁炬柦鍙拌处 ============
+
+// 鑾峰彇瀹夊叏璁炬柦鍙拌处鍒楄〃
+export function getFacilityLedgerList(params) {
+ return request({
+ url: "/safeFacilityLedger/page",
+ method: "get",
+ params,
+ });
+}
+
+// 鏍规嵁ID鑾峰彇瀹夊叏璁炬柦鍙拌处璇︽儏
+export function getFacilityLedgerById(id) {
+ return request({
+ url: `/safeFacilityLedger/${id}`,
+ method: "get",
+ });
+}
+
+// 鏂板瀹夊叏璁炬柦鍙拌处
+export function addFacilityLedger(data) {
+ return request({
+ url: "/safeFacilityLedger",
+ method: "post",
+ data,
+ });
+}
+
+// 淇敼瀹夊叏璁炬柦鍙拌处
+export function updateFacilityLedger(data) {
+ return request({
+ url: "/safeFacilityLedger",
+ method: "put",
+ data,
+ });
+}
+
+// 鍒犻櫎瀹夊叏璁炬柦鍙拌处
+export function deleteFacilityLedger(ids) {
+ return request({
+ url: "/safeFacilityLedger/" + ids.join(","),
+ method: "delete",
+ });
+}
+
+// ============ 瀹夊叏璁炬柦宸℃ ============
+
+// 鑾峰彇瀹夊叏璁炬柦宸℃鍒楄〃
+export function getFacilityInspectionList(params) {
+ return request({
+ url: "/safeFacilityInspection/page",
+ method: "get",
+ params,
+ });
+}
+
+// 鏍规嵁ID鑾峰彇瀹夊叏璁炬柦宸℃璇︽儏
+export function getFacilityInspectionById(id) {
+ return request({
+ url: `/safeFacilityInspection/${id}`,
+ method: "get",
+ });
+}
+
+// 鏂板瀹夊叏璁炬柦宸℃
+export function addFacilityInspection(data) {
+ return request({
+ url: "/safeFacilityInspection",
+ method: "post",
+ data,
+ });
+}
+
+// 淇敼瀹夊叏璁炬柦宸℃
+export function updateFacilityInspection(data) {
+ return request({
+ url: "/safeFacilityInspection",
+ method: "put",
+ data,
+ });
+}
+
+// 鍒犻櫎瀹夊叏璁炬柦宸℃
+export function deleteFacilityInspection(ids) {
+ return request({
+ url: "/safeFacilityInspection/" + ids.join(","),
+ method: "delete",
+ });
+}
+
+// ============ 瀹夊叏璁炬柦鏁存敼 ============
+
+// 鑾峰彇瀹夊叏璁炬柦鏁存敼鍒楄〃
+export function getFacilityRectificationList(params) {
+ return request({
+ url: "/safeFacilityRectification/page",
+ method: "get",
+ params,
+ });
+}
+
+// 鏍规嵁ID鑾峰彇瀹夊叏璁炬柦鏁存敼璇︽儏
+export function getFacilityRectificationById(id) {
+ return request({
+ url: `/safeFacilityRectification/${id}`,
+ method: "get",
+ });
+}
+
+// 鏂板瀹夊叏璁炬柦鏁存敼
+export function addFacilityRectification(data) {
+ return request({
+ url: "/safeFacilityRectification",
+ method: "post",
+ data,
+ });
+}
+
+// 淇敼瀹夊叏璁炬柦鏁存敼
+export function updateFacilityRectification(data) {
+ return request({
+ url: "/safeFacilityRectification",
+ method: "put",
+ data,
+ });
+}
+
+// 鍒犻櫎瀹夊叏璁炬柦鏁存敼
+export function deleteFacilityRectification(ids) {
+ return request({
+ url: "/safeFacilityRectification/" + ids.join(","),
+ method: "delete",
+ });
+}
diff --git a/src/views/safeProduction/hazardReport/index.vue b/src/views/safeProduction/hazardReport/index.vue
new file mode 100644
index 0000000..26e652f
--- /dev/null
+++ b/src/views/safeProduction/hazardReport/index.vue
@@ -0,0 +1,529 @@
+<template>
+ <div class="hazard-report">
+ <!-- 鎼滅储鍖哄煙 -->
+ <div class="search-area">
+ <el-form :inline="true" :model="searchForm">
+ <el-form-item label="涓婃姤绫诲瀷">
+ <el-select v-model="searchForm.reportType" placeholder="璇烽�夋嫨绫诲瀷" clearable>
+ <el-option label="绾胯矾宸℃" value="绾胯矾宸℃" />
+ <el-option label="瀹夊叏璁炬柦宸℃" value="瀹夊叏璁炬柦宸℃" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="涓ラ噸绋嬪害">
+ <el-select v-model="searchForm.severity" placeholder="璇烽�夋嫨绋嬪害" clearable>
+ <el-option label="杞诲井" value="杞诲井" />
+ <el-option label="涓�鑸�" value="涓�鑸�" />
+ <el-option label="涓ラ噸" value="涓ラ噸" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鏁存敼鐘舵��">
+ <el-select v-model="searchForm.rectificationStatus" placeholder="璇烽�夋嫨鐘舵��" clearable>
+ <el-option label="寰呮暣鏀�" value="寰呮暣鏀�" />
+ <el-option label="鏁存敼涓�" value="鏁存敼涓�" />
+ <el-option label="宸插畬鎴�" value="宸插畬鎴�" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="涓婃姤浜�">
+ <el-input v-model="searchForm.reporter" placeholder="璇疯緭鍏ヤ笂鎶ヤ汉" clearable />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
+ <el-button @click="resetSearch">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <div class="actions">
+ <el-button type="primary" @click="handleAdd">涓婃姤闅愭偅</el-button>
+ <el-button type="success" @click="handleExport">瀵煎嚭</el-button>
+ </div>
+
+ <!-- 闅愭偅鍒楄〃 -->
+ <el-table :data="reportList" style="width: 100%; margin-top: 10px;" border>
+ <el-table-column prop="reportType" label="涓婃姤绫诲瀷" width="150" />
+ <el-table-column prop="facilityName" label="鍏宠仈璁炬柦" width="150" />
+ <el-table-column prop="hazardDescription" label="闅愭偅鎻忚堪" min-width="200" show-overflow-tooltip />
+ <el-table-column prop="severity" label="涓ラ噸绋嬪害" width="120">
+ <template #default="{ row }">
+ <el-tag :type="getSeverityType(row.severity)">
+ {{ row.severity }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="reporter" label="涓婃姤浜�" width="120" />
+ <el-table-column prop="reportTime" label="涓婃姤鏃堕棿" width="180" />
+ <el-table-column prop="rectificationStatus" label="鏁存敼鐘舵��" width="120">
+ <template #default="{ row }">
+ <el-tag :type="getRectificationStatusType(row.rectificationStatus)">
+ {{ row.rectificationStatus }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="rectificationPerson" label="鏁存敼璐d换浜�" width="120" />
+ <el-table-column label="鎿嶄綔" width="280" fixed="right">
+ <template #default="{ row }">
+ <el-button
+ v-if="row.rectificationStatus === '寰呮暣鏀�'"
+ type="warning"
+ link
+ @click="handleRectify(row)"
+ >
+ 鏁存敼
+ </el-button>
+ <el-button
+ v-if="row.rectificationStatus === '宸插畬鎴�' && !row.acceptancePerson"
+ type="success"
+ link
+ @click="handleAccept(row)"
+ >
+ 楠屾敹
+ </el-button>
+ <el-button type="primary" link @click="handleView(row)">鏌ョ湅</el-button>
+ <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 鍒嗛〉 -->
+ <div class="pagination">
+ <el-pagination
+ v-model:current-page="pagination.currentPage"
+ v-model:page-size="pagination.pageSize"
+ :page-sizes="[10, 20, 50, 100]"
+ :total="pagination.total"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handleCurrentChange"
+ />
+ </div>
+
+ <!-- 涓婃姤闅愭偅瀵硅瘽妗� -->
+ <el-dialog title="涓婃姤闅愭偅" v-model="showAddDialog" width="600px">
+ <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px">
+ <el-form-item label="涓婃姤绫诲瀷" prop="reportType">
+ <el-select v-model="addForm.reportType" placeholder="璇烽�夋嫨绫诲瀷">
+ <el-option label="绾胯矾宸℃" value="绾胯矾宸℃" />
+ <el-option label="瀹夊叏璁炬柦宸℃" value="瀹夊叏璁炬柦宸℃" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍏宠仈璁炬柦">
+ <el-select v-model="addForm.facilityId" placeholder="璇烽�夋嫨璁炬柦" clearable>
+ <el-option
+ v-for="item in facilityOptions"
+ :key="item.id"
+ :label="item.facilityName"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="闅愭偅鎻忚堪" prop="hazardDescription">
+ <el-input type="textarea" v-model="addForm.hazardDescription" placeholder="璇疯緭鍏ラ殣鎮f弿杩�" />
+ </el-form-item>
+ <el-form-item label="涓ラ噸绋嬪害" prop="severity">
+ <el-select v-model="addForm.severity" placeholder="璇烽�夋嫨绋嬪害">
+ <el-option label="杞诲井" value="杞诲井" />
+ <el-option label="涓�鑸�" value="涓�鑸�" />
+ <el-option label="涓ラ噸" value="涓ラ噸" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="涓婃姤浜�" prop="reporter">
+ <el-input v-model="addForm.reporter" placeholder="璇疯緭鍏ヤ笂鎶ヤ汉" />
+ </el-form-item>
+ <el-form-item label="澶囨敞">
+ <el-input type="textarea" v-model="addForm.remarks" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitAddForm">纭畾</el-button>
+ <el-button @click="showAddDialog = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏁存敼瀵硅瘽妗� -->
+ <el-dialog title="璁板綍鏁存敼缁撴灉" v-model="showRectifyDialog" width="500px">
+ <el-form :model="rectifyForm" label-width="100px">
+ <el-form-item label="闅愭偅鎻忚堪">
+ <el-input type="textarea" v-model="rectifyForm.hazardDescription" disabled />
+ </el-form-item>
+ <el-form-item label="鏁存敼璐d换浜�">
+ <el-input v-model="rectifyForm.rectificationPerson" placeholder="璇疯緭鍏ユ暣鏀硅矗浠讳汉" />
+ </el-form-item>
+ <el-form-item label="鏁存敼鎻忚堪">
+ <el-input type="textarea" v-model="rectifyForm.rectificationDescription" placeholder="璇疯緭鍏ユ暣鏀规帾鏂�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitRectify">纭畾</el-button>
+ <el-button @click="showRectifyDialog = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 楠屾敹瀵硅瘽妗� -->
+ <el-dialog title="璁板綍楠屾敹缁撴灉" v-model="showAcceptDialog" width="500px">
+ <el-form :model="acceptForm" label-width="100px">
+ <el-form-item label="鏁存敼鎻忚堪">
+ <el-input type="textarea" v-model="acceptForm.rectificationDescription" disabled />
+ </el-form-item>
+ <el-form-item label="楠屾敹浜�">
+ <el-input v-model="acceptForm.acceptancePerson" placeholder="璇疯緭鍏ラ獙鏀朵汉" />
+ </el-form-item>
+ <el-form-item label="楠屾敹缁撴灉">
+ <el-radio-group v-model="acceptForm.acceptanceResult">
+ <el-radio label="閫氳繃">閫氳繃</el-radio>
+ <el-radio label="涓嶉�氳繃">涓嶉�氳繃</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitAccept">纭畾</el-button>
+ <el-button @click="showAcceptDialog = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏌ョ湅璇︽儏瀵硅瘽妗� -->
+ <el-dialog title="闅愭偅璇︽儏" v-model="showViewDialog" width="600px">
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="涓婃姤绫诲瀷">{{ viewData.reportType }}</el-descriptions-item>
+ <el-descriptions-item label="鍏宠仈璁炬柦">{{ viewData.facilityName }}</el-descriptions-item>
+ <el-descriptions-item label="闅愭偅鎻忚堪" :span="2">{{ viewData.hazardDescription }}</el-descriptions-item>
+ <el-descriptions-item label="涓ラ噸绋嬪害">{{ viewData.severity }}</el-descriptions-item>
+ <el-descriptions-item label="涓婃姤浜�">{{ viewData.reporter }}</el-descriptions-item>
+ <el-descriptions-item label="涓婃姤鏃堕棿">{{ viewData.reportTime }}</el-descriptions-item>
+ <el-descriptions-item label="鏁存敼鐘舵��">{{ viewData.rectificationStatus }}</el-descriptions-item>
+ <el-descriptions-item label="鏁存敼璐d换浜�">{{ viewData.rectificationPerson }}</el-descriptions-item>
+ <el-descriptions-item label="鏁存敼鏃堕棿">{{ viewData.rectificationTime }}</el-descriptions-item>
+ <el-descriptions-item label="鏁存敼鎻忚堪" :span="2">{{ viewData.rectificationDescription }}</el-descriptions-item>
+ <el-descriptions-item label="楠屾敹浜�">{{ viewData.acceptancePerson }}</el-descriptions-item>
+ <el-descriptions-item label="楠屾敹鏃堕棿">{{ viewData.acceptanceTime }}</el-descriptions-item>
+ <el-descriptions-item label="楠屾敹缁撴灉">{{ viewData.acceptanceResult }}</el-descriptions-item>
+ </el-descriptions>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="showViewDialog = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import {
+ getHazardReportList,
+ addHazardReport,
+ rectifyHazardReport,
+ acceptHazardReport,
+ deleteHazardReport,
+ exportHazardReport
+} from '@/api/safeProduction/hazardReport'
+import { getSafetyFacilityList } from '@/api/equipmentManagement/safetyFacility'
+
+// 鎼滅储琛ㄥ崟
+const searchForm = reactive({
+ reportType: '',
+ severity: '',
+ rectificationStatus: '',
+ reporter: ''
+})
+
+// 鍒嗛〉鏁版嵁
+const pagination = reactive({
+ currentPage: 1,
+ pageSize: 10,
+ total: 0
+})
+
+// 鍒楄〃鏁版嵁
+const reportList = ref([])
+
+// 璁炬柦閫夐」
+const facilityOptions = ref([])
+
+// 瀵硅瘽妗嗙姸鎬�
+const showAddDialog = ref(false)
+const showRectifyDialog = ref(false)
+const showAcceptDialog = ref(false)
+const showViewDialog = ref(false)
+
+// 涓婃姤琛ㄥ崟
+const addForm = reactive({
+ reportType: '',
+ facilityId: null,
+ hazardDescription: '',
+ severity: '',
+ reporter: '',
+ remarks: ''
+})
+
+// 涓婃姤琛ㄥ崟楠岃瘉瑙勫垯
+const addFormRules = reactive({
+ reportType: [{ required: true, message: '璇烽�夋嫨涓婃姤绫诲瀷', trigger: 'change' }],
+ hazardDescription: [{ required: true, message: '璇疯緭鍏ラ殣鎮f弿杩�', trigger: 'blur' }],
+ severity: [{ required: true, message: '璇烽�夋嫨涓ラ噸绋嬪害', trigger: 'change' }],
+ reporter: [{ required: true, message: '璇疯緭鍏ヤ笂鎶ヤ汉', trigger: 'blur' }]
+})
+
+const addFormRef = ref(null)
+
+// 鏁存敼琛ㄥ崟
+const rectifyForm = reactive({
+ id: null,
+ hazardDescription: '',
+ rectificationPerson: '',
+ rectificationDescription: ''
+})
+
+// 楠屾敹琛ㄥ崟
+const acceptForm = reactive({
+ id: null,
+ rectificationDescription: '',
+ acceptancePerson: '',
+ acceptanceResult: '閫氳繃'
+})
+
+// 鏌ョ湅鏁版嵁
+const viewData = ref({})
+
+// 鑾峰彇涓ラ噸绋嬪害鏍囩绫诲瀷
+const getSeverityType = (severity) => {
+ const map = {
+ '杞诲井': 'info',
+ '涓�鑸�': 'warning',
+ '涓ラ噸': 'danger'
+ }
+ return map[severity] || 'info'
+}
+
+// 鑾峰彇鏁存敼鐘舵�佹爣绛剧被鍨�
+const getRectificationStatusType = (status) => {
+ const map = {
+ '寰呮暣鏀�': 'danger',
+ '鏁存敼涓�': 'warning',
+ '宸插畬鎴�': 'success'
+ }
+ return map[status] || 'info'
+}
+
+// 鑾峰彇闅愭偅鍒楄〃
+const fetchList = async () => {
+ try {
+ const params = {
+ ...searchForm,
+ current: pagination.currentPage,
+ size: pagination.pageSize
+ }
+ const res = await getHazardReportList(params)
+ if (res.code === 200) {
+ reportList.value = res.data.records || []
+ pagination.total = res.data.total || 0
+ } else {
+ ElMessage.error(res.message || '鑾峰彇鍒楄〃澶辫触')
+ }
+ } catch (error) {
+ ElMessage.error('鑾峰彇鍒楄〃澶辫触')
+ }
+}
+
+// 鑾峰彇璁炬柦鍒楄〃
+const fetchFacilityOptions = async () => {
+ try {
+ const res = await getSafetyFacilityList({ size: 1000 })
+ if (res.code === 200) {
+ facilityOptions.value = res.data.records || []
+ }
+ } catch (error) {
+ console.error('鑾峰彇璁炬柦鍒楄〃澶辫触')
+ }
+}
+
+// 鎼滅储
+const handleSearch = () => {
+ pagination.currentPage = 1
+ fetchList()
+}
+
+// 閲嶇疆鎼滅储
+const resetSearch = () => {
+ Object.assign(searchForm, {
+ reportType: '',
+ severity: '',
+ rectificationStatus: '',
+ reporter: ''
+ })
+ handleSearch()
+}
+
+// 涓婃姤闅愭偅
+const handleAdd = () => {
+ Object.assign(addForm, {
+ reportType: '',
+ facilityId: null,
+ hazardDescription: '',
+ severity: '',
+ reporter: '',
+ remarks: ''
+ })
+ showAddDialog.value = true
+}
+
+// 鏁存敼
+const handleRectify = (row) => {
+ Object.assign(rectifyForm, {
+ id: row.id,
+ hazardDescription: row.hazardDescription,
+ rectificationPerson: '',
+ rectificationDescription: ''
+ })
+ showRectifyDialog.value = true
+}
+
+// 楠屾敹
+const handleAccept = (row) => {
+ Object.assign(acceptForm, {
+ id: row.id,
+ rectificationDescription: row.rectificationDescription,
+ acceptancePerson: '',
+ acceptanceResult: '閫氳繃'
+ })
+ showAcceptDialog.value = true
+}
+
+// 鏌ョ湅璇︽儏
+const handleView = (row) => {
+ viewData.value = { ...row }
+ showViewDialog.value = true
+}
+
+// 鍒犻櫎
+const handleDelete = async (row) => {
+ try {
+ await ElMessageBox.confirm('纭鍒犻櫎璇ラ殣鎮h褰曞悧锛�', '鎻愮ず', {
+ type: 'warning'
+ })
+ const res = await deleteHazardReport([row.id])
+ if (res.code === 200) {
+ ElMessage.success('鍒犻櫎鎴愬姛')
+ fetchList()
+ } else {
+ ElMessage.error(res.message || '鍒犻櫎澶辫触')
+ }
+ } catch (error) {
+ // 鍙栨秷鍒犻櫎
+ }
+}
+
+// 鎻愪氦涓婃姤琛ㄥ崟
+const submitAddForm = async () => {
+ if (!addFormRef.value) return
+ try {
+ await addFormRef.value.validate()
+ const res = await addHazardReport(addForm)
+ if (res.code === 200) {
+ ElMessage.success('涓婃姤鎴愬姛')
+ showAddDialog.value = false
+ fetchList()
+ } else {
+ ElMessage.error(res.message || '涓婃姤澶辫触')
+ }
+ } catch (error) {
+ ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�')
+ }
+}
+
+// 鎻愪氦鏁存敼
+const submitRectify = async () => {
+ try {
+ const res = await rectifyHazardReport(rectifyForm)
+ if (res.code === 200) {
+ ElMessage.success('鏁存敼璁板綍鎴愬姛')
+ showRectifyDialog.value = false
+ fetchList()
+ } else {
+ ElMessage.error(res.message || '鎿嶄綔澶辫触')
+ }
+ } catch (error) {
+ ElMessage.error('鎿嶄綔澶辫触')
+ }
+}
+
+// 鎻愪氦楠屾敹
+const submitAccept = async () => {
+ try {
+ const res = await acceptHazardReport(acceptForm)
+ if (res.code === 200) {
+ ElMessage.success('楠屾敹璁板綍鎴愬姛')
+ showAcceptDialog.value = false
+ fetchList()
+ } else {
+ ElMessage.error(res.message || '鎿嶄綔澶辫触')
+ }
+ } catch (error) {
+ ElMessage.error('鎿嶄綔澶辫触')
+ }
+}
+
+// 瀵煎嚭
+const handleExport = async () => {
+ try {
+ const res = await exportHazardReport(searchForm)
+ const blob = new Blob([res])
+ const url = window.URL.createObjectURL(blob)
+ const link = document.createElement('a')
+ link.href = url
+ link.download = '闅愭偅涓婃姤璁板綍.xlsx'
+ link.click()
+ window.URL.revokeObjectURL(url)
+ ElMessage.success('瀵煎嚭鎴愬姛')
+ } catch (error) {
+ ElMessage.error('瀵煎嚭澶辫触')
+ }
+}
+
+// 鍒嗛〉澶у皬鏀瑰彉
+const handleSizeChange = (val) => {
+ pagination.pageSize = val
+ fetchList()
+}
+
+// 褰撳墠椤垫敼鍙�
+const handleCurrentChange = (val) => {
+ pagination.currentPage = val
+ fetchList()
+}
+
+onMounted(() => {
+ fetchList()
+ fetchFacilityOptions()
+})
+</script>
+
+<style scoped>
+.hazard-report {
+ padding: 20px;
+}
+
+.search-area {
+ background: #f5f7fa;
+ padding: 20px;
+ border-radius: 4px;
+ margin-bottom: 15px;
+}
+
+.actions {
+ margin-bottom: 15px;
+}
+
+.pagination {
+ margin-top: 20px;
+ display: flex;
+ justify-content: flex-end;
+}
+</style>
diff --git a/src/views/safeProduction/lineInspection/index.vue b/src/views/safeProduction/lineInspection/index.vue
new file mode 100644
index 0000000..ad3abed
--- /dev/null
+++ b/src/views/safeProduction/lineInspection/index.vue
@@ -0,0 +1,918 @@
+<template>
+ <div class="app-container">
+ <div class="search_form mb20">
+ <div>
+ <span class="search_title">宸℃缂栧彿锛�</span>
+ <el-input v-model="searchForm.inspectionCode"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
+ @change="handleQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">宸℃鍚嶇О锛�</span>
+ <el-input v-model="searchForm.inspectionName"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ュ贰妫�鍚嶇О"
+ @change="handleQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">绾胯矾鍚嶇О锛�</span>
+ <el-input v-model="searchForm.lineName"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ョ嚎璺悕绉�"
+ @change="handleQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">鐘舵�侊細</span>
+ <el-select v-model="searchForm.status"
+ clearable
+ @change="handleQuery"
+ style="width: 150px">
+ <el-option label="寰呭贰妫�" value="寰呭贰妫�" />
+ <el-option label="宸℃涓�" value="宸℃涓�" />
+ <el-option label="宸插畬鎴�" value="宸插畬鎴�" />
+ </el-select>
+ <el-button type="primary"
+ @click="handleQuery"
+ style="margin-left: 10px">
+ 鎼滅储
+ </el-button>
+ </div>
+ <div>
+ <el-button type="primary"
+ @click="openForm('add')">鏂板宸℃浠诲姟</el-button>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"
+ :total="page.total"></PIMTable>
+ </div>
+
+ <!-- 鏂板/缂栬緫宸℃浠诲姟寮圭獥 -->
+ <el-dialog v-model="dialogVisible"
+ :title="dialogTitle"
+ width="800px"
+ :close-on-click-modal="false">
+ <el-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃缂栧彿"
+ prop="inspectionCode">
+ <el-input v-model="form.inspectionCode"
+ placeholder="璇疯緭鍏ュ贰妫�缂栧彿" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃鍚嶇О"
+ prop="inspectionName">
+ <el-input v-model="form.inspectionName"
+ placeholder="璇疯緭鍏ュ贰妫�鍚嶇О" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="绾胯矾鍚嶇О"
+ prop="lineName">
+ <el-input v-model="form.lineName"
+ placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃绫诲瀷"
+ prop="inspectionType">
+ <el-select v-model="form.inspectionType"
+ placeholder="璇烽�夋嫨宸℃绫诲瀷"
+ style="width: 100%">
+ <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
+ <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璁″垝宸℃鏃堕棿"
+ prop="planTime">
+ <el-date-picker v-model="form.planTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃浜�"
+ prop="inspectorId">
+ <el-select v-model="form.inspectorIds"
+ placeholder="璇烽�夋嫨宸℃浜猴紙鍙閫夛級"
+ filterable
+ multiple
+ collapse-tags
+ collapse-tags-tooltip
+ clearable
+ style="width: 100%">
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="澶囨敞"
+ prop="remark">
+ <el-input v-model="form.remark"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitForm">纭畾</el-button>
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 宸℃璁板綍寮圭獥 -->
+ <el-dialog ref="recordDialogRef"
+ v-model="recordDialogVisible"
+ title="宸℃璁板綍"
+ width="70vw"
+ :close-on-click-modal="false"
+ @open="onRecordDialogOpen">
+ <div class="mb10">
+ <el-button type="primary"
+ size="small"
+ @click="openRecordForm">鏂板璁板綍</el-button>
+ </div>
+ <div class="dialog-table-wrapper">
+ <el-table :data="recordList"
+ border
+ style="width: 100%">
+ <el-table-column prop="checkPoint" label="妫�鏌ョ偣" width="150" show-overflow-tooltip />
+ <el-table-column prop="checkContent" label="妫�鏌ュ唴瀹�" min-width="200" show-overflow-tooltip />
+ <el-table-column prop="checkResult" label="妫�鏌ョ粨鏋�" width="100">
+ <template #default="{ row }">
+ <el-tag :type="row.checkResult === '姝e父' ? 'success' : 'danger'">
+ {{ row.checkResult }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="checkDesc" label="妫�鏌ヨ鏄�" width="200" show-overflow-tooltip />
+ <el-table-column prop="checkTime" label="妫�鏌ユ椂闂�" width="180" />
+ </el-table>
+ </div>
+
+ <!-- 鏂板璁板綍琛ㄥ崟 -->
+ <el-dialog v-model="recordFormVisible"
+ title="鏂板宸℃璁板綍"
+ width="600px"
+ append-to-body
+ :close-on-click-modal="false">
+ <el-form ref="recordFormRef"
+ :model="recordForm"
+ :rules="recordRules"
+ label-width="100px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="妫�鏌ョ偣"
+ prop="checkPoint">
+ <el-input v-model="recordForm.checkPoint"
+ placeholder="璇疯緭鍏ユ鏌ョ偣" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="妫�鏌ョ粨鏋�"
+ prop="checkResult">
+ <el-radio-group v-model="recordForm.checkResult">
+ <el-radio label="姝e父">姝e父</el-radio>
+ <el-radio label="寮傚父">寮傚父</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="妫�鏌ュ唴瀹�"
+ prop="checkContent">
+ <el-input v-model="recordForm.checkContent"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ユ鏌ュ唴瀹�" />
+ </el-form-item>
+ <el-form-item label="妫�鏌ヨ鏄�">
+ <el-input v-model="recordForm.checkDesc"
+ type="textarea"
+ :rows="2"
+ placeholder="璇疯緭鍏ユ鏌ヨ鏄�" />
+ </el-form-item>
+ <el-form-item label="妫�鏌ユ椂闂�">
+ <el-date-picker v-model="recordForm.checkTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨妫�鏌ユ椂闂�"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitRecordForm">纭畾</el-button>
+ <el-button @click="recordFormVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </el-dialog>
+
+ <!-- 闅愭偅绠$悊寮圭獥 -->
+ <el-dialog ref="hazardDialogRef"
+ v-model="hazardDialogVisible"
+ title="闅愭偅绠$悊"
+ width="75vw"
+ :close-on-click-modal="false"
+ @open="onHazardDialogOpen">
+ <div class="mb10">
+ <el-button type="primary"
+ size="small"
+ @click="openHazardForm('add')">涓婃姤闅愭偅</el-button>
+ </div>
+ <div class="dialog-table-wrapper">
+ <el-table :data="hazardList"
+ border
+ style="width: 100%">
+ <el-table-column prop="hazardCode" label="闅愭偅缂栧彿" width="120" show-overflow-tooltip />
+ <el-table-column prop="hazardDesc" label="闅愭偅鎻忚堪" min-width="200" show-overflow-tooltip />
+ <el-table-column prop="hazardLevel" label="闅愭偅绛夌骇" width="100">
+ <template #default="{ row }">
+ <el-tag :type="row.hazardLevel === '閲嶅ぇ' ? 'danger' : 'warning'">
+ {{ row.hazardLevel }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="hazardLocation" label="闅愭偅浣嶇疆" width="150" show-overflow-tooltip />
+ <el-table-column prop="status" label="鐘舵��" width="100">
+ <template #default="{ row }">
+ <el-tag :type="getHazardStatusType(row.status)">
+ {{ row.status }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="rectifyUserName" label="鏁存敼璐d换浜�" width="120" />
+ <el-table-column label="鎿嶄綔" width="150" fixed="right">
+ <template #default="{ row }">
+ <el-button type="primary" link @click="openHazardForm('edit', row)">缂栬緫</el-button>
+ <el-button type="success" link @click="handleRectify(row)" v-if="row.status !== '宸叉暣鏀�'">鏁存敼</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <!-- 闅愭偅琛ㄥ崟 -->
+ <el-dialog v-model="hazardFormVisible"
+ :title="hazardDialogTitle"
+ width="600px"
+ append-to-body
+ :close-on-click-modal="false">
+ <el-form ref="hazardFormRef"
+ :model="hazardForm"
+ :rules="hazardRules"
+ label-width="100px">
+ <el-form-item label="闅愭偅鎻忚堪"
+ prop="hazardDesc">
+ <el-input v-model="hazardForm.hazardDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ラ殣鎮f弿杩�" />
+ </el-form-item>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="闅愭偅绛夌骇"
+ prop="hazardLevel">
+ <el-select v-model="hazardForm.hazardLevel"
+ placeholder="璇烽�夋嫨闅愭偅绛夌骇"
+ style="width: 100%">
+ <el-option label="涓�鑸�" value="涓�鑸�" />
+ <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="闅愭偅浣嶇疆"
+ prop="hazardLocation">
+ <el-input v-model="hazardForm.hazardLocation"
+ placeholder="璇疯緭鍏ラ殣鎮d綅缃�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitHazardForm">纭畾</el-button>
+ <el-button @click="hazardFormVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏁存敼琛ㄥ崟 -->
+ <el-dialog v-model="rectifyFormVisible"
+ title="鏁存敼"
+ width="500px"
+ append-to-body
+ :close-on-click-modal="false">
+ <el-form ref="rectifyFormRef"
+ :model="rectifyForm"
+ label-width="100px">
+ <el-form-item label="鏁存敼璇存槑"
+ prop="rectifyDesc">
+ <el-input v-model="rectifyForm.rectifyDesc"
+ type="textarea"
+ :rows="4"
+ placeholder="璇疯緭鍏ユ暣鏀硅鏄�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitRectifyForm">纭畾</el-button>
+ <el-button @click="rectifyFormVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { nextTick, onMounted, ref, reactive, toRefs } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import { userListNoPage } from "@/api/system/user.js";
+import {
+ getLineInspectionList,
+ addLineInspection,
+ updateLineInspection,
+ deleteLineInspection,
+ completeLineInspection,
+ getInspectionRecords,
+ addInspectionRecord,
+ getHazardsByInspectionId,
+ addInspectionHazard,
+ updateInspectionHazard
+} from "@/api/safeProduction/lineInspection";
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+ inspectionCode: [{ required: true, message: "璇疯緭鍏ュ贰妫�缂栧彿", trigger: "blur" }],
+ inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�鍚嶇О", trigger: "blur" }],
+ lineName: [{ required: true, message: "璇疯緭鍏ョ嚎璺悕绉�", trigger: "blur" }]
+};
+
+const recordRules = {
+ checkPoint: [{ required: true, message: "璇疯緭鍏ユ鏌ョ偣", trigger: "blur" }],
+ checkContent: [{ required: true, message: "璇疯緭鍏ユ鏌ュ唴瀹�", trigger: "blur" }],
+ checkResult: [{ required: true, message: "璇烽�夋嫨妫�鏌ョ粨鏋�", trigger: "change" }]
+};
+
+const hazardRules = {
+ hazardDesc: [{ required: true, message: "璇疯緭鍏ラ殣鎮f弿杩�", trigger: "blur" }],
+ hazardLevel: [{ required: true, message: "璇烽�夋嫨闅愭偅绛夌骇", trigger: "change" }],
+ hazardLocation: [{ required: true, message: "璇疯緭鍏ラ殣鎮d綅缃�", trigger: "blur" }]
+};
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+ searchForm: {
+ inspectionCode: "",
+ inspectionName: "",
+ lineName: "",
+ status: ""
+ },
+ tableLoading: false,
+ page: {
+ current: 1,
+ size: 20,
+ total: 0
+ },
+ tableData: [],
+ selectedIds: [],
+ form: {
+ id: null,
+ inspectionCode: "",
+ inspectionName: "",
+ lineName: "",
+ inspectionType: "",
+ planTime: "",
+ inspectorId: "",
+ inspectorIds: [],
+ remark: ""
+ },
+ dialogVisible: false,
+ dialogTitle: "",
+ dialogType: "add",
+ // 宸℃璁板綍
+ currentInspectionId: null,
+ recordDialogVisible: false,
+ recordFormVisible: false,
+ recordList: [],
+ recordForm: {
+ inspectionId: null,
+ checkPoint: "",
+ checkContent: "",
+ checkResult: "姝e父",
+ checkDesc: "",
+ checkTime: ""
+ },
+ // 闅愭偅绠$悊
+ hazardDialogVisible: false,
+ hazardFormVisible: false,
+ hazardDialogTitle: "涓婃姤闅愭偅",
+ hazardList: [],
+ hazardForm: {
+ id: null,
+ inspectionId: null,
+ hazardDesc: "",
+ hazardLevel: "",
+ hazardLocation: ""
+ },
+ rectifyFormVisible: false,
+ rectifyForm: {
+ id: null,
+ rectifyDesc: ""
+ }
+});
+
+const {
+ searchForm,
+ tableLoading,
+ page,
+ tableData,
+ selectedIds,
+ form,
+ dialogVisible,
+ dialogTitle,
+ dialogType,
+ currentInspectionId,
+ recordDialogVisible,
+ recordFormVisible,
+ recordList,
+ recordForm,
+ hazardDialogVisible,
+ hazardFormVisible,
+ hazardDialogTitle,
+ hazardList,
+ hazardForm,
+ rectifyFormVisible,
+ rectifyForm
+} = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const formRef = ref();
+const recordFormRef = ref();
+const hazardFormRef = ref();
+const rectifyFormRef = ref();
+const userList = ref([]);
+
+// 琛ㄦ牸鍒楅厤缃�
+const tableColumn = ref([
+ {
+ label: "宸℃缂栧彿",
+ prop: "inspectionCode",
+ showOverflowTooltip: true,
+ minWidth: 150
+ },
+ {
+ label: "宸℃鍚嶇О",
+ prop: "inspectionName",
+ showOverflowTooltip: true,
+ minWidth: 180
+ },
+ {
+ label: "绾胯矾鍚嶇О",
+ prop: "lineName",
+ showOverflowTooltip: true,
+ minWidth: 150
+ },
+ {
+ label: "宸℃绫诲瀷",
+ prop: "inspectionType",
+ showOverflowTooltip: true,
+ minWidth: 100
+ },
+ {
+ label: "璁″垝宸℃鏃堕棿",
+ prop: "planTime",
+ showOverflowTooltip: true,
+ minWidth: 180
+ },
+ {
+ label: "宸℃浜�",
+ prop: "inspectorName",
+ showOverflowTooltip: true,
+ minWidth: 100
+ },
+ {
+ label: "鐘舵��",
+ prop: "status",
+ minWidth: 100,
+ dataType: "tag",
+ formatType: params => {
+ const typeMap = {
+ 寰呭贰妫�: "info",
+ 宸℃涓�: "warning",
+ 宸插畬鎴�: "success"
+ };
+ return typeMap[params] || "info";
+ }
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 350,
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: row => {
+ openForm("edit", row);
+ },
+ show: row => row.status === "寰呭贰妫�"
+ },
+ {
+ name: "宸℃璁板綍",
+ type: "text",
+ clickFun: row => {
+ openRecordDialog(row);
+ }
+ },
+ {
+ name: "闅愭偅绠$悊",
+ type: "text",
+ clickFun: row => {
+ openHazardDialog(row);
+ }
+ },
+ {
+ name: "瀹屾垚宸℃",
+ type: "text",
+ style: { color: "#67C23A" },
+ clickFun: row => {
+ handleComplete(row);
+ },
+ show: row => row.status === "宸℃涓�"
+ },
+ {
+ name: "鍒犻櫎",
+ type: "text",
+ style: { color: "#F56C6C" },
+ clickFun: row => {
+ handleDelete(row);
+ },
+ show: row => row.status === "寰呭贰妫�"
+ }
+ ]
+ }
+]);
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+ getList();
+ userListNoPage().then(res => {
+ userList.value = res.data;
+ });
+});
+
+// 寮圭獥鍥哄畾楂樺害澶勭悊
+const setDialogFixedHeight = () => {
+ setTimeout(() => {
+ // 鐩存帴鍦� body 涓婃壘鎵�鏈� el-dialog锛坱eleport 娓叉煋鍒� body锛�
+ const dialogs = document.body.querySelectorAll('.el-dialog');
+ const dialog = dialogs[dialogs.length - 1]; // 鏈�鍚庝竴涓氨鏄垰鎵撳紑鐨�
+ if (!dialog) return;
+ Object.assign(dialog.style, {
+ height: '70vh',
+ maxHeight: '70vh',
+ overflow: 'hidden',
+ display: 'flex',
+ flexDirection: 'column'
+ });
+ const body = dialog.querySelector('.el-dialog__body');
+ if (body) {
+ Object.assign(body.style, { flex: '1', overflow: 'hidden' });
+ }
+ const wrapper = dialog.querySelector('.dialog-table-wrapper');
+ if (wrapper) {
+ Object.assign(wrapper.style, { flex: '1', overflowY: 'auto' });
+ }
+ }, 100);
+};
+
+const recordDialogRef = ref(null);
+const hazardDialogRef = ref(null);
+
+const onRecordDialogOpen = () => setDialogFixedHeight();
+const onHazardDialogOpen = () => setDialogFixedHeight();
+const handleQuery = () => {
+ page.value.current = 1;
+ getList();
+};
+
+const getList = () => {
+ tableLoading.value = true;
+ getLineInspectionList({ ...page.value, ...searchForm.value })
+ .then(res => {
+ tableLoading.value = false;
+ tableData.value = res.data.records;
+ page.value.total = res.data.total;
+ })
+ .catch(() => {
+ tableLoading.value = false;
+ });
+};
+
+// 鍒嗛〉澶勭悊
+const pagination = obj => {
+ page.value.current = obj.page;
+ page.value.size = obj.limit;
+ getList();
+};
+
+// 閫夋嫨鍙樺寲澶勭悊
+const handleSelectionChange = selection => {
+ selectedIds.value = selection.map(item => item.id);
+};
+
+// 鑾峰彇闅愭偅鐘舵�佺被鍨�
+const getHazardStatusType = status => {
+ const map = {
+ 寰呮暣鏀�: "danger",
+ 鏁存敼涓�: "warning",
+ 宸叉暣鏀�: "success"
+ };
+ return map[status] || "info";
+};
+
+// 鎵撳紑琛ㄥ崟
+const openForm = (type, row = null) => {
+ dialogType.value = type;
+ if (type === "add") {
+ dialogTitle.value = "鏂板宸℃浠诲姟";
+ Object.assign(form.value, {
+ id: null,
+ inspectionCode: "",
+ inspectionName: "",
+ lineName: "",
+ inspectionType: "",
+ planTime: "",
+ inspectorId: "",
+ inspectorIds: [],
+ remark: ""
+ });
+ } else if (type === "edit" && row) {
+ dialogTitle.value = "缂栬緫宸℃浠诲姟";
+ // 灏嗛�楀彿鍒嗛殧鐨処D瀛楃涓茶浆鎹负鏁扮粍
+ const inspectorIds = row.inspectorId
+ ? row.inspectorId.split(",").map(id => parseInt(id.trim())).filter(id => !isNaN(id))
+ : [];
+ Object.assign(form.value, {
+ id: row.id,
+ inspectionCode: row.inspectionCode,
+ inspectionName: row.inspectionName,
+ lineName: row.lineName,
+ inspectionType: row.inspectionType,
+ planTime: row.planTime,
+ inspectorId: row.inspectorId,
+ inspectorIds: inspectorIds,
+ remark: row.remark
+ });
+ }
+ dialogVisible.value = true;
+};
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = async () => {
+ try {
+ await formRef.value.validate();
+ // 灏嗘暟缁勮浆鎹负閫楀彿鍒嗛殧鐨勫瓧绗︿覆
+ const submitData = {
+ ...form.value,
+ inspectorId: form.value.inspectorIds ? form.value.inspectorIds.join(",") : ""
+ };
+ delete submitData.inspectorIds;
+
+ const api = dialogType.value === "add" ? addLineInspection : updateLineInspection;
+ const res = await api(submitData);
+ if (res.code === 200) {
+ ElMessage.success(dialogType.value === "add" ? "娣诲姞鎴愬姛" : "鏇存柊鎴愬姛");
+ dialogVisible.value = false;
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+ }
+};
+
+// 鍒犻櫎
+const handleDelete = row => {
+ ElMessageBox.confirm("纭鍒犻櫎璇ュ贰妫�浠诲姟鍚楋紵", "鍒犻櫎", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(async () => {
+ const res = await deleteLineInspection([row.id]);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+ })
+ .catch(() => {});
+};
+
+// 瀹屾垚宸℃
+const handleComplete = row => {
+ ElMessageBox.confirm("纭瀹屾垚璇ュ贰妫�浠诲姟鍚楋紵", "瀹屾垚宸℃", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(async () => {
+ const res = await completeLineInspection(row.id);
+ if (res.code === 200) {
+ ElMessage.success("宸℃宸插畬鎴�");
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ })
+ .catch(() => {});
+};
+
+// 鎵撳紑宸℃璁板綍寮圭獥
+const openRecordDialog = row => {
+ currentInspectionId.value = row.id;
+ fetchRecords(row.id);
+ recordDialogVisible.value = true;
+};
+
+// 鑾峰彇宸℃璁板綍
+const fetchRecords = async inspectionId => {
+ const res = await getInspectionRecords(inspectionId);
+ if (res.code === 200) {
+ recordList.value = res.data || [];
+ }
+};
+
+// 鎵撳紑璁板綍琛ㄥ崟
+const openRecordForm = () => {
+ Object.assign(recordForm.value, {
+ inspectionId: currentInspectionId.value,
+ checkPoint: "",
+ checkContent: "",
+ checkResult: "姝e父",
+ checkDesc: "",
+ checkTime: ""
+ });
+ recordFormVisible.value = true;
+};
+
+// 鎻愪氦璁板綍琛ㄥ崟
+const submitRecordForm = async () => {
+ try {
+ await recordFormRef.value.validate();
+ const res = await addInspectionRecord({ ...recordForm.value });
+ if (res.code === 200) {
+ ElMessage.success("娣诲姞鎴愬姛");
+ recordFormVisible.value = false;
+ fetchRecords(currentInspectionId.value);
+ } else {
+ ElMessage.error(res.msg || "娣诲姞澶辫触");
+ }
+ } catch (error) {
+ console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+ }
+};
+
+// 鎵撳紑闅愭偅绠$悊寮圭獥
+const openHazardDialog = row => {
+ currentInspectionId.value = row.id;
+ fetchHazards(row.id);
+ hazardDialogVisible.value = true;
+};
+
+// 鑾峰彇闅愭偅鍒楄〃
+const fetchHazards = async inspectionId => {
+ const res = await getHazardsByInspectionId(inspectionId);
+ if (res.code === 200) {
+ hazardList.value = res.data || [];
+ }
+};
+
+// 鎵撳紑闅愭偅琛ㄥ崟
+const openHazardForm = (type, row = null) => {
+ if (type === "add") {
+ hazardDialogTitle.value = "涓婃姤闅愭偅";
+ Object.assign(hazardForm.value, {
+ id: null,
+ inspectionId: currentInspectionId.value,
+ hazardDesc: "",
+ hazardLevel: "",
+ hazardLocation: ""
+ });
+ } else {
+ hazardDialogTitle.value = "缂栬緫闅愭偅";
+ Object.assign(hazardForm.value, {
+ id: row.id,
+ inspectionId: row.inspectionId,
+ hazardDesc: row.hazardDesc,
+ hazardLevel: row.hazardLevel,
+ hazardLocation: row.hazardLocation
+ });
+ }
+ hazardFormVisible.value = true;
+};
+
+// 鎻愪氦闅愭偅琛ㄥ崟
+const submitHazardForm = async () => {
+ try {
+ await hazardFormRef.value.validate();
+ const api = hazardForm.value.id ? updateInspectionHazard : addInspectionHazard;
+ const res = await api({ ...hazardForm.value });
+ if (res.code === 200) {
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ hazardFormVisible.value = false;
+ fetchHazards(currentInspectionId.value);
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+ }
+};
+
+// 鏁存敼
+const handleRectify = row => {
+ Object.assign(rectifyForm.value, {
+ id: row.id,
+ rectifyDesc: ""
+ });
+ rectifyFormVisible.value = true;
+};
+
+// 鎻愪氦鏁存敼琛ㄥ崟
+const submitRectifyForm = async () => {
+ const res = await updateInspectionHazard({
+ id: rectifyForm.value.id,
+ status: "宸叉暣鏀�",
+ rectifyDesc: rectifyForm.value.rectifyDesc
+ });
+ if (res.code === 200) {
+ ElMessage.success("鏁存敼鎴愬姛");
+ rectifyFormVisible.value = false;
+ fetchHazards(currentInspectionId.value);
+ } else {
+ ElMessage.error(res.msg || "鏁存敼澶辫触");
+ }
+};
+</script>
+
+<style scoped>
+.search_title {
+ font-size: 14px;
+ color: #606266;
+}
+
+.mb10 {
+ margin-bottom: 10px;
+}
+
+.mb20 {
+ margin-bottom: 20px;
+}
+
+.ml10 {
+ margin-left: 10px;
+}
+</style>
diff --git a/src/views/safeProduction/safetyFacility/index.vue b/src/views/safeProduction/safetyFacility/index.vue
new file mode 100644
index 0000000..f707580
--- /dev/null
+++ b/src/views/safeProduction/safetyFacility/index.vue
@@ -0,0 +1,810 @@
+<template>
+ <div class="app-container">
+ <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+ <!-- 瀹夊叏璁炬柦鍙拌处 -->
+ <el-tab-pane label="瀹夊叏璁炬柦鍙拌处" name="ledger">
+ <div class="search_form mb20">
+ <div>
+ <span class="search_title">璁炬柦缂栧彿锛�</span>
+ <el-input v-model="ledgerSearchForm.facilityCode"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ヨ鏂界紪鍙�"
+ @change="handleLedgerQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">璁炬柦鍚嶇О锛�</span>
+ <el-input v-model="ledgerSearchForm.facilityName"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ヨ鏂藉悕绉�"
+ @change="handleLedgerQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">璁炬柦绫诲瀷锛�</span>
+ <el-select v-model="ledgerSearchForm.facilityType"
+ clearable
+ @change="handleLedgerQuery"
+ style="width: 150px">
+ <el-option label="娑堥槻鍣ㄦ潗" value="娑堥槻鍣ㄦ潗" />
+ <el-option label="瀹夊叏璁惧" value="瀹夊叏璁惧" />
+ <el-option label="闃叉姢鐢ㄥ搧" value="闃叉姢鐢ㄥ搧" />
+ <el-option label="鐩戞帶璁惧" value="鐩戞帶璁惧" />
+ </el-select>
+ <span class="search_title ml10">鐘舵�侊細</span>
+ <el-select v-model="ledgerSearchForm.status"
+ clearable
+ @change="handleLedgerQuery"
+ style="width: 120px">
+ <el-option label="姝e父" value="姝e父" />
+ <el-option label="寮傚父" value="寮傚父" />
+ <el-option label="鎶ュ簾" value="鎶ュ簾" />
+ </el-select>
+ <el-button type="primary"
+ @click="handleLedgerQuery"
+ style="margin-left: 10px">
+ 鎼滅储
+ </el-button>
+ </div>
+ <div>
+ <el-button type="primary"
+ @click="openLedgerForm('add')">鏂板璁炬柦</el-button>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable rowKey="id"
+ :column="ledgerTableColumn"
+ :tableData="ledgerTableData"
+ :page="ledgerPage"
+ :isSelection="true"
+ @selection-change="handleLedgerSelectionChange"
+ :tableLoading="ledgerTableLoading"
+ @pagination="ledgerPagination"
+ :total="ledgerPage.total"></PIMTable>
+ </div>
+ </el-tab-pane>
+
+ <!-- 瀹夊叏璁炬柦宸℃ -->
+ <el-tab-pane label="瀹夊叏璁炬柦宸℃" name="inspection">
+ <div class="search_form mb20">
+ <div>
+ <span class="search_title">宸℃缂栧彿锛�</span>
+ <el-input v-model="inspectionSearchForm.inspectionCode"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
+ @change="handleInspectionQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">鐘舵�侊細</span>
+ <el-select v-model="inspectionSearchForm.status"
+ clearable
+ @change="handleInspectionQuery"
+ style="width: 150px">
+ <el-option label="寰呭贰妫�" value="寰呭贰妫�" />
+ <el-option label="宸插贰妫�" value="宸插贰妫�" />
+ </el-select>
+ <el-button type="primary"
+ @click="handleInspectionQuery"
+ style="margin-left: 10px">
+ 鎼滅储
+ </el-button>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable rowKey="id"
+ :column="inspectionTableColumn"
+ :tableData="inspectionTableData"
+ :page="inspectionPage"
+ :isSelection="false"
+ :tableLoading="inspectionTableLoading"
+ @pagination="inspectionPagination"
+ :total="inspectionPage.total"></PIMTable>
+ </div>
+ </el-tab-pane>
+
+ <!-- 鏁存敼璺熻釜 -->
+ <el-tab-pane label="鏁存敼璺熻釜" name="rectification">
+ <div class="search_form mb20">
+ <div>
+ <span class="search_title">鐘舵�侊細</span>
+ <el-select v-model="rectificationSearchForm.status"
+ clearable
+ @change="handleRectificationQuery"
+ style="width: 150px">
+ <el-option label="寰呮暣鏀�" value="寰呮暣鏀�" />
+ <el-option label="鏁存敼涓�" value="鏁存敼涓�" />
+ <el-option label="宸叉暣鏀�" value="宸叉暣鏀�" />
+ <el-option label="宸查獙鏀�" value="宸查獙鏀�" />
+ </el-select>
+ <el-button type="primary"
+ @click="handleRectificationQuery"
+ style="margin-left: 10px">
+ 鎼滅储
+ </el-button>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable rowKey="id"
+ :column="rectificationTableColumn"
+ :tableData="rectificationTableData"
+ :page="rectificationPage"
+ :isSelection="false"
+ :tableLoading="rectificationTableLoading"
+ @pagination="rectificationPagination"
+ :total="rectificationPage.total"></PIMTable>
+ </div>
+ </el-tab-pane>
+ </el-tabs>
+
+ <!-- 璁炬柦鍙拌处琛ㄥ崟寮圭獥 -->
+ <el-dialog v-model="ledgerDialogVisible"
+ :title="ledgerDialogTitle"
+ width="800px"
+ :close-on-click-modal="false">
+ <el-form ref="ledgerFormRef"
+ :model="ledgerForm"
+ :rules="ledgerRules"
+ label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璁炬柦缂栧彿"
+ prop="facilityCode">
+ <el-input v-model="ledgerForm.facilityCode"
+ placeholder="璇疯緭鍏ヨ鏂界紪鍙�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="璁炬柦鍚嶇О"
+ prop="facilityName">
+ <el-input v-model="ledgerForm.facilityName"
+ placeholder="璇疯緭鍏ヨ鏂藉悕绉�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="璁炬柦绫诲瀷"
+ prop="facilityType">
+ <el-select v-model="ledgerForm.facilityType"
+ placeholder="璇烽�夋嫨璁炬柦绫诲瀷"
+ style="width: 100%">
+ <el-option label="娑堥槻鍣ㄦ潗" value="娑堥槻鍣ㄦ潗" />
+ <el-option label="瀹夊叏璁惧" value="瀹夊叏璁惧" />
+ <el-option label="闃叉姢鐢ㄥ搧" value="闃叉姢鐢ㄥ搧" />
+ <el-option label="鐩戞帶璁惧" value="鐩戞帶璁惧" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瑙勬牸鍨嬪彿"
+ prop="facilitySpec">
+ <el-input v-model="ledgerForm.facilitySpec"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="瀹夎浣嶇疆"
+ prop="installLocation">
+ <el-input v-model="ledgerForm.installLocation"
+ placeholder="璇疯緭鍏ュ畨瑁呬綅缃�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="瀹夎鏃堕棿"
+ prop="installTime">
+ <el-date-picker v-model="ledgerForm.installTime"
+ type="date"
+ placeholder="璇烽�夋嫨瀹夎鏃堕棿"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鐢熶骇鏃ユ湡"
+ prop="productionDate">
+ <el-date-picker v-model="ledgerForm.productionDate"
+ type="date"
+ placeholder="璇烽�夋嫨鐢熶骇鏃ユ湡"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈夋晥鏈�(澶�)"
+ prop="validPeriod">
+ <el-input-number v-model="ledgerForm.validPeriod"
+ :min="0"
+ placeholder="璇疯緭鍏ユ湁鏁堟湡"
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鐘舵��"
+ prop="status">
+ <el-select v-model="ledgerForm.status"
+ placeholder="璇烽�夋嫨鐘舵��"
+ style="width: 100%">
+ <el-option label="姝e父" value="姝e父" />
+ <el-option label="寮傚父" value="寮傚父" />
+ <el-option label="鎶ュ簾" value="鎶ュ簾" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="澶囨敞"
+ prop="remark">
+ <el-input v-model="ledgerForm.remark"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitLedgerForm">纭畾</el-button>
+ <el-button @click="ledgerDialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 宸℃琛ㄥ崟寮圭獥 -->
+ <el-dialog v-model="inspectionDialogVisible"
+ :title="inspectionDialogTitle"
+ width="600px"
+ :close-on-click-modal="false">
+ <el-form ref="inspectionFormRef"
+ :model="inspectionForm"
+ :rules="inspectionRules"
+ label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃缂栧彿"
+ prop="inspectionCode">
+ <el-input v-model="inspectionForm.inspectionCode"
+ placeholder="璇疯緭鍏ュ贰妫�缂栧彿" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃绫诲瀷"
+ prop="inspectionType">
+ <el-select v-model="inspectionForm.inspectionType"
+ placeholder="璇烽�夋嫨宸℃绫诲瀷"
+ style="width: 100%">
+ <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
+ <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="璁″垝宸℃鏃堕棿"
+ prop="planTime">
+ <el-date-picker v-model="inspectionForm.planTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%" />
+ </el-form-item>
+ <template v-if="inspectionDialogTitle === '宸℃'">
+ <el-form-item label="妫�鏌ョ粨鏋�"
+ prop="checkResult">
+ <el-radio-group v-model="inspectionForm.checkResult">
+ <el-radio label="姝e父">姝e父</el-radio>
+ <el-radio label="寮傚父">寮傚父</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ <el-form-item label="妫�鏌ヨ鏄�">
+ <el-input v-model="inspectionForm.checkDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ユ鏌ヨ鏄�" />
+ </el-form-item>
+ </template>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitInspectionForm">纭畾</el-button>
+ <el-button @click="inspectionDialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏁存敼琛ㄥ崟寮圭獥 -->
+ <el-dialog v-model="rectificationDialogVisible"
+ :title="rectificationDialogTitle"
+ width="600px"
+ :close-on-click-modal="false">
+ <el-form ref="rectificationFormRef"
+ :model="rectificationForm"
+ label-width="120px">
+ <template v-if="rectificationDialogTitle !== '楠屾敹'">
+ <el-form-item label="闂鎻忚堪">
+ <el-input v-model="rectificationForm.problemDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ラ棶棰樻弿杩�" />
+ </el-form-item>
+ <el-form-item label="闂绛夌骇">
+ <el-select v-model="rectificationForm.problemLevel"
+ placeholder="璇烽�夋嫨闂绛夌骇"
+ style="width: 100%">
+ <el-option label="涓�鑸�" value="涓�鑸�" />
+ <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
+ </el-select>
+ </el-form-item>
+ </template>
+ <el-form-item label="鏁存敼璇存槑" v-if="rectificationDialogTitle === '鏁存敼'">
+ <el-input v-model="rectificationForm.rectifyDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ユ暣鏀硅鏄�" />
+ </el-form-item>
+ <el-form-item label="楠屾敹璇存槑" v-if="rectificationDialogTitle === '楠屾敹'">
+ <el-input v-model="rectificationForm.verifyDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ラ獙鏀惰鏄�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitRectificationForm">纭畾</el-button>
+ <el-button @click="rectificationDialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import {
+ getFacilityLedgerList,
+ addFacilityLedger,
+ updateFacilityLedger,
+ deleteFacilityLedger,
+ getFacilityInspectionList,
+ addFacilityInspection,
+ updateFacilityInspection,
+ deleteFacilityInspection,
+ getFacilityRectificationList,
+ addFacilityRectification,
+ updateFacilityRectification
+} from "@/api/safeProduction/safetyFacility";
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const ledgerRules = {
+ facilityCode: [{ required: true, message: "璇疯緭鍏ヨ鏂界紪鍙�", trigger: "blur" }],
+ facilityName: [{ required: true, message: "璇疯緭鍏ヨ鏂藉悕绉�", trigger: "blur" }],
+ facilityType: [{ required: true, message: "璇烽�夋嫨璁炬柦绫诲瀷", trigger: "change" }],
+ installLocation: [{ required: true, message: "璇疯緭鍏ュ畨瑁呬綅缃�", trigger: "blur" }]
+};
+
+const inspectionRules = {
+ inspectionCode: [{ required: true, message: "璇疯緭鍏ュ贰妫�缂栧彿", trigger: "blur" }]
+};
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+ activeTab: "ledger",
+ // 璁炬柦鍙拌处
+ ledgerSearchForm: { facilityCode: "", facilityName: "", facilityType: "", status: "" },
+ ledgerTableLoading: false,
+ ledgerPage: { current: 1, size: 20, total: 0 },
+ ledgerTableData: [],
+ ledgerSelectedIds: [],
+ ledgerForm: {
+ id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
+ installLocation: "", installTime: "", productionDate: "", validPeriod: null,
+ status: "姝e父", remark: ""
+ },
+ ledgerDialogVisible: false,
+ ledgerDialogTitle: "",
+ ledgerDialogType: "add",
+ // 宸℃璁板綍
+ inspectionSearchForm: { inspectionCode: "", status: "" },
+ inspectionTableLoading: false,
+ inspectionPage: { current: 1, size: 20, total: 0 },
+ inspectionTableData: [],
+ inspectionForm: {
+ id: null, facilityId: null, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
+ planTime: "", checkResult: "", checkDesc: ""
+ },
+ inspectionDialogVisible: false,
+ inspectionDialogTitle: "",
+ inspectionDialogType: "add",
+ // 鏁存敼璺熻釜
+ rectificationSearchForm: { status: "" },
+ rectificationTableLoading: false,
+ rectificationPage: { current: 1, size: 20, total: 0 },
+ rectificationTableData: [],
+ rectificationForm: {
+ id: null, inspectionId: null, facilityId: null, problemDesc: "",
+ problemLevel: "", rectifyDesc: "", verifyDesc: ""
+ },
+ rectificationDialogVisible: false,
+ rectificationDialogTitle: "",
+ rectificationDialogType: "add"
+});
+
+const {
+ activeTab,
+ ledgerSearchForm, ledgerTableLoading, ledgerPage, ledgerTableData, ledgerSelectedIds,
+ ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType,
+ inspectionSearchForm, inspectionTableLoading, inspectionPage, inspectionTableData,
+ inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType,
+ rectificationSearchForm, rectificationTableLoading, rectificationPage, rectificationTableData,
+ rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType
+} = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const ledgerFormRef = ref();
+const inspectionFormRef = ref();
+const rectificationFormRef = ref();
+
+// 璁炬柦鍙拌处琛ㄦ牸鍒楅厤缃�
+const ledgerTableColumn = ref([
+ { label: "璁炬柦缂栧彿", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
+ { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
+ { label: "璁炬柦绫诲瀷", prop: "facilityType", showOverflowTooltip: true, minWidth: 100 },
+ { label: "瑙勬牸鍨嬪彿", prop: "facilitySpec", showOverflowTooltip: true, minWidth: 120 },
+ { label: "瀹夎浣嶇疆", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 },
+ { label: "瀹夎鏃堕棿", prop: "installTime", minWidth: 120 },
+ { label: "涓嬫妫�鏌ユ椂闂�", prop: "nextCheckTime", minWidth: 120 },
+ {
+ label: "鐘舵��", prop: "status", minWidth: 80, dataType: "tag",
+ formatType: params => {
+ const map = { 姝e父: "success", 寮傚父: "danger", 鎶ュ簾: "info" };
+ return map[params] || "info";
+ }
+ },
+ {
+ dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+ operation: [
+ { name: "缂栬緫", type: "text", clickFun: row => openLedgerForm("edit", row) },
+ { name: "鍙戣捣宸℃", type: "text", clickFun: row => openInspectionForm("add", row) },
+ { name: "鍒犻櫎", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteLedger(row) }
+ ]
+ }
+]);
+
+// 宸℃璁板綍琛ㄦ牸鍒楅厤缃�
+const inspectionTableColumn = ref([
+ { label: "宸℃缂栧彿", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
+ { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
+ { label: "璁炬柦缂栧彿", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
+ { label: "宸℃绫诲瀷", prop: "inspectionType", minWidth: 100 },
+ { label: "璁″垝宸℃鏃堕棿", prop: "planTime", minWidth: 180 },
+ { label: "宸℃浜�", prop: "inspectorName", minWidth: 100 },
+ { label: "瀹為檯宸℃鏃堕棿", prop: "actualTime", minWidth: 180 },
+ {
+ label: "妫�鏌ョ粨鏋�", prop: "checkResult", minWidth: 100, dataType: "tag",
+ formatType: params => params === "姝e父" ? "success" : "danger"
+ },
+ {
+ label: "鐘舵��", prop: "status", minWidth: 100, dataType: "tag",
+ formatType: params => params === "寰呭贰妫�" ? "info" : "success"
+ },
+ {
+ dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+ operation: [
+ {
+ name: "宸℃", type: "text",
+ clickFun: row => openInspectionForm("do", row),
+ show: row => row.status === "寰呭贰妫�"
+ },
+ {
+ name: "鏌ョ湅", type: "text",
+ clickFun: row => openInspectionForm("view", row),
+ show: row => row.status !== "寰呭贰妫�"
+ },
+ {
+ name: "鏁存敼", type: "text",
+ clickFun: row => openRectificationForm("add", row),
+ show: row => row.checkResult === "寮傚父"
+ },
+ { name: "鍒犻櫎", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteInspection(row) }
+ ]
+ }
+]);
+
+// 鏁存敼璺熻釜琛ㄦ牸鍒楅厤缃�
+const rectificationTableColumn = ref([
+ { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
+ { label: "闂鎻忚堪", prop: "problemDesc", showOverflowTooltip: true, minWidth: 200 },
+ {
+ label: "闂绛夌骇", prop: "problemLevel", minWidth: 100, dataType: "tag",
+ formatType: params => params === "閲嶅ぇ" ? "danger" : "warning"
+ },
+ { label: "鏁存敼璐d换浜�", prop: "rectifyUserName", minWidth: 120 },
+ { label: "璁″垝鏁存敼鏃堕棿", prop: "planTime", minWidth: 180 },
+ {
+ label: "鐘舵��", prop: "status", minWidth: 100, dataType: "tag",
+ formatType: params => {
+ const map = { 寰呮暣鏀�: "danger", 鏁存敼涓�: "warning", 宸叉暣鏀�: "success", 宸查獙鏀�: "info" };
+ return map[params] || "info";
+ }
+ },
+ { label: "楠屾敹浜�", prop: "verifyUserName", minWidth: 120 },
+ {
+ dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+ operation: [
+ {
+ name: "鏁存敼", type: "text",
+ clickFun: row => openRectificationForm("do", row),
+ show: row => row.status === "寰呮暣鏀�" || row.status === "鏁存敼涓�"
+ },
+ {
+ name: "楠屾敹", type: "text",
+ clickFun: row => openRectificationForm("verify", row),
+ show: row => row.status === "宸叉暣鏀�"
+ },
+ { name: "鏌ョ湅", type: "text", clickFun: row => openRectificationForm("view", row) }
+ ]
+ }
+]);
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+ getLedgerList();
+});
+
+// 鏍囩椤靛垏鎹�
+const handleTabClick = () => {
+ if (activeTab.value === "ledger") getLedgerList();
+ else if (activeTab.value === "inspection") getInspectionList();
+ else if (activeTab.value === "rectification") getRectificationList();
+};
+
+// ============ 璁炬柦鍙拌处鏂规硶 ============
+
+const handleLedgerQuery = () => {
+ ledgerPage.value.current = 1;
+ getLedgerList();
+};
+
+const getLedgerList = () => {
+ ledgerTableLoading.value = true;
+ getFacilityLedgerList({ ...ledgerPage.value, ...ledgerSearchForm.value })
+ .then(res => {
+ ledgerTableLoading.value = false;
+ ledgerTableData.value = res.data.records;
+ ledgerPage.value.total = res.data.total;
+ })
+ .catch(() => { ledgerTableLoading.value = false; });
+};
+
+const ledgerPagination = obj => {
+ ledgerPage.value.current = obj.page;
+ ledgerPage.value.size = obj.limit;
+ getLedgerList();
+};
+
+const handleLedgerSelectionChange = selection => {
+ ledgerSelectedIds.value = selection.map(item => item.id);
+};
+
+const openLedgerForm = (type, row = null) => {
+ ledgerDialogType.value = type;
+ if (type === "add") {
+ ledgerDialogTitle.value = "鏂板璁炬柦";
+ Object.assign(ledgerForm.value, {
+ id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
+ installLocation: "", installTime: "", productionDate: "", validPeriod: null,
+ status: "姝e父", remark: ""
+ });
+ } else {
+ ledgerDialogTitle.value = "缂栬緫璁炬柦";
+ Object.assign(ledgerForm.value, { ...row });
+ }
+ ledgerDialogVisible.value = true;
+};
+
+const submitLedgerForm = async () => {
+ try {
+ await ledgerFormRef.value.validate();
+ const api = ledgerDialogType.value === "add" ? addFacilityLedger : updateFacilityLedger;
+ const res = await api({ ...ledgerForm.value });
+ if (res.code === 200) {
+ ElMessage.success(ledgerDialogType.value === "add" ? "娣诲姞鎴愬姛" : "鏇存柊鎴愬姛");
+ ledgerDialogVisible.value = false;
+ getLedgerList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+ }
+};
+
+const handleDeleteLedger = row => {
+ ElMessageBox.confirm("纭鍒犻櫎璇ヨ鏂藉悧锛�", "鍒犻櫎", {
+ confirmButtonText: "纭", cancelButtonText: "鍙栨秷", type: "warning"
+ }).then(async () => {
+ const res = await deleteFacilityLedger([row.id]);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getLedgerList();
+ }
+ }).catch(() => {});
+};
+
+// ============ 宸℃璁板綍鏂规硶 ============
+
+const handleInspectionQuery = () => {
+ inspectionPage.value.current = 1;
+ getInspectionList();
+};
+
+const getInspectionList = () => {
+ inspectionTableLoading.value = true;
+ getFacilityInspectionList({ ...inspectionPage.value, ...inspectionSearchForm.value })
+ .then(res => {
+ inspectionTableLoading.value = false;
+ inspectionTableData.value = res.data.records;
+ inspectionPage.value.total = res.data.total;
+ })
+ .catch(() => { inspectionTableLoading.value = false; });
+};
+
+const inspectionPagination = obj => {
+ inspectionPage.value.current = obj.page;
+ inspectionPage.value.size = obj.limit;
+ getInspectionList();
+};
+
+const openInspectionForm = (type, row = null) => {
+ inspectionDialogType.value = type;
+ if (type === "add") {
+ inspectionDialogTitle.value = "鍙戣捣宸℃";
+ Object.assign(inspectionForm.value, {
+ id: null, facilityId: row.id, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
+ planTime: "", checkResult: "", checkDesc: ""
+ });
+ } else if (type === "do") {
+ inspectionDialogTitle.value = "宸℃";
+ Object.assign(inspectionForm.value, {
+ id: row.id, facilityId: row.facilityId, inspectionCode: row.inspectionCode,
+ inspectionType: row.inspectionType, planTime: row.planTime, checkResult: "", checkDesc: ""
+ });
+ } else {
+ inspectionDialogTitle.value = "鏌ョ湅宸℃";
+ Object.assign(inspectionForm.value, { ...row });
+ }
+ inspectionDialogVisible.value = true;
+};
+
+const submitInspectionForm = async () => {
+ try {
+ await inspectionFormRef.value.validate();
+ if (inspectionDialogTitle.value === "宸℃") {
+ inspectionForm.value.status = "宸插贰妫�";
+ inspectionForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
+ }
+ const api = inspectionForm.value.id ? updateFacilityInspection : addFacilityInspection;
+ const res = await api({ ...inspectionForm.value });
+ if (res.code === 200) {
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ inspectionDialogVisible.value = false;
+ getInspectionList();
+ }
+ } catch (error) {
+ console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+ }
+};
+
+const handleDeleteInspection = row => {
+ ElMessageBox.confirm("纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵", "鍒犻櫎", {
+ confirmButtonText: "纭", cancelButtonText: "鍙栨秷", type: "warning"
+ }).then(async () => {
+ const res = await deleteFacilityInspection([row.id]);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getInspectionList();
+ }
+ }).catch(() => {});
+};
+
+// ============ 鏁存敼璺熻釜鏂规硶 ============
+
+const handleRectificationQuery = () => {
+ rectificationPage.value.current = 1;
+ getRectificationList();
+};
+
+const getRectificationList = () => {
+ rectificationTableLoading.value = true;
+ getFacilityRectificationList({ ...rectificationPage.value, ...rectificationSearchForm.value })
+ .then(res => {
+ rectificationTableLoading.value = false;
+ rectificationTableData.value = res.data.records;
+ rectificationPage.value.total = res.data.total;
+ })
+ .catch(() => { rectificationTableLoading.value = false; });
+};
+
+const rectificationPagination = obj => {
+ rectificationPage.value.current = obj.page;
+ rectificationPage.value.size = obj.limit;
+ getRectificationList();
+};
+
+const openRectificationForm = (type, row = null) => {
+ rectificationDialogType.value = type;
+ if (type === "add") {
+ rectificationDialogTitle.value = "鏂板鏁存敼";
+ Object.assign(rectificationForm.value, {
+ id: null, inspectionId: row.id, facilityId: row.facilityId,
+ problemDesc: "", problemLevel: "", rectifyDesc: "", verifyDesc: ""
+ });
+ } else if (type === "do") {
+ rectificationDialogTitle.value = "鏁存敼";
+ Object.assign(rectificationForm.value, {
+ id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
+ problemDesc: row.problemDesc, problemLevel: row.problemLevel, rectifyDesc: "", verifyDesc: ""
+ });
+ } else if (type === "verify") {
+ rectificationDialogTitle.value = "楠屾敹";
+ Object.assign(rectificationForm.value, {
+ id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
+ problemDesc: row.problemDesc, problemLevel: row.problemLevel,
+ rectifyDesc: row.rectifyDesc, verifyDesc: ""
+ });
+ } else {
+ rectificationDialogTitle.value = "鏌ョ湅鏁存敼";
+ Object.assign(rectificationForm.value, { ...row });
+ }
+ rectificationDialogVisible.value = true;
+};
+
+const submitRectificationForm = async () => {
+ if (rectificationDialogType.value === "view") {
+ rectificationDialogVisible.value = false;
+ return;
+ }
+ if (rectificationDialogTitle.value === "鏁存敼") {
+ rectificationForm.value.status = "宸叉暣鏀�";
+ rectificationForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
+ } else if (rectificationDialogTitle.value === "楠屾敹") {
+ rectificationForm.value.status = "宸查獙鏀�";
+ rectificationForm.value.verifyTime = new Date().toISOString().replace("T", " ").substring(0, 19);
+ }
+ const api = rectificationForm.value.id ? updateFacilityRectification : addFacilityRectification;
+ const res = await api({ ...rectificationForm.value });
+ if (res.code === 200) {
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ rectificationDialogVisible.value = false;
+ getRectificationList();
+ }
+};
+</script>
+
+<style scoped>
+.search_title {
+ font-size: 14px;
+ color: #606266;
+}
+
+.mb20 {
+ margin-bottom: 20px;
+}
+
+.ml10 {
+ margin-left: 10px;
+}
+</style>
--
Gitblit v1.9.3