From bd5a3ab76c08bc0753d36bfe8d7bab5ed812dca9 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期三, 29 七月 2026 14:53:48 +0800
Subject: [PATCH] fix: 隐患整改调整

---
 src/views/safeProduction/specialEquipmentManagement/index.vue |  237 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 192 insertions(+), 45 deletions(-)

diff --git a/src/views/safeProduction/specialEquipmentManagement/index.vue b/src/views/safeProduction/specialEquipmentManagement/index.vue
index 2f93d51..c636ff6 100644
--- a/src/views/safeProduction/specialEquipmentManagement/index.vue
+++ b/src/views/safeProduction/specialEquipmentManagement/index.vue
@@ -119,35 +119,50 @@
 
     <el-dialog v-model="rectDialogVisible" :title="rectDialogTitle" width="900px" :close-on-click-modal="false">
       <el-form ref="rectFormRef" :model="rectForm" label-position="top" :rules="rectRules">
+        <el-divider content-position="left">闅愭偅浠诲姟</el-divider>
         <el-row :gutter="20">
-          <el-col :span="12"><el-form-item label="鍏宠仈璁惧" prop="equipmentId"><el-select v-model="rectForm.equipmentId" filterable clearable style="width: 100%" placeholder="璇烽�夋嫨璁惧"><el-option v-for="item in activeLedgerOptions" :key="item.id" :label="item.equipmentName" :value="item.id" /></el-select></el-form-item></el-col>
-          <el-col :span="12"><el-form-item label="椋庨櫓绛夌骇" prop="riskLevel"><el-select v-model="rectForm.riskLevel" clearable style="width: 100%" placeholder="璇烽�夋嫨椋庨櫓绛夌骇"><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="equipmentId"><el-select v-model="rectForm.equipmentId" filterable clearable style="width: 100%" placeholder="璇烽�夋嫨璁惧" :disabled="!canEditRectTask"><el-option v-for="item in activeLedgerOptions" :key="item.id" :label="item.equipmentName" :value="item.id" /></el-select></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="椋庨櫓绛夌骇" prop="riskLevel"><el-select v-model="rectForm.riskLevel" clearable style="width: 100%" placeholder="璇烽�夋嫨椋庨櫓绛夌骇" :disabled="!canEditRectTask"><el-option label="浣�" value="浣�" /><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="discoveredDate"><el-date-picker v-model="rectForm.discoveredDate" value-format="YYYY-MM-DD" type="date" style="width: 100%" /></el-form-item></el-col>
-          <el-col :span="12"><el-form-item label="鏁存敼鏈熼檺" prop="rectificationDeadline"><el-date-picker v-model="rectForm.rectificationDeadline" value-format="YYYY-MM-DD" type="date" style="width: 100%" /></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="鍙戠幇鏃ユ湡" prop="discoveredDate"><el-date-picker v-model="rectForm.discoveredDate" value-format="YYYY-MM-DD" type="date" style="width: 100%" :disabled="!canEditRectTask" /></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="鏁存敼鏈熼檺" prop="rectificationDeadline"><el-date-picker v-model="rectForm.rectificationDeadline" value-format="YYYY-MM-DD" type="date" style="width: 100%" :disabled="!canEditRectTask" /></el-form-item></el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="鏁存敼璐d换浜�" prop="responsibleUserId">
-              <el-select v-model="rectForm.responsibleUserId" filterable clearable style="width: 100%" placeholder="璇烽�夋嫨鏁存敼璐d换浜�" @change="handleResponsibleUserChange">
+              <el-select v-model="rectForm.responsibleUserId" filterable clearable style="width: 100%" placeholder="璇烽�夋嫨鏁存敼璐d换浜�" :disabled="!canEditRectTask" @change="handleResponsibleUserChange">
                 <el-option v-for="item in activeUserOptions" :key="item.userId" :label="item.nickName || item.userName" :value="item.userId" />
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12"><el-form-item label="鏁存敼鐘舵��" prop="rectificationStatus"><el-select v-model="rectForm.rectificationStatus" clearable style="width: 100%" placeholder="璇烽�夋嫨鏁存敼鐘舵��"><el-option label="寰呮暣鏀�" :value="1" /><el-option label="鏁存敼涓�" :value="2" /><el-option label="寰呭鏍�" :value="3" /><el-option label="宸查棴鐜�" :value="4" /></el-select></el-form-item></el-col>
+          <el-col :span="12">
+            <el-form-item label="鏁存敼鐘舵��">
+              <el-tag :type="getRectStatusType(rectForm.rectificationStatus)">{{ formatRectStatus(rectForm.rectificationStatus) }}</el-tag>
+            </el-form-item>
+          </el-col>
         </el-row>
-        <el-form-item label="闅愭偅鎻忚堪" prop="hazardDescription"><el-input v-model="rectForm.hazardDescription" type="textarea" :rows="3" /></el-form-item>
-        <el-form-item label="鏁存敼鎺柦" prop="rectificationMeasures"><el-input v-model="rectForm.rectificationMeasures" type="textarea" :rows="3" /></el-form-item>
-        <el-form-item label="鏁存敼缁撴灉" prop="rectificationResult"><el-input v-model="rectForm.rectificationResult" type="textarea" :rows="3" /></el-form-item>
-        <el-form-item label="鏁存敼闄勪欢">
-          <FileUpload v-model:file-list="rectForm.storageBlobDTOs" :limit="6" />
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="remarks"><el-input v-model="rectForm.remarks" type="textarea" :rows="2" /></el-form-item>
+        <el-form-item label="闅愭偅鎻忚堪" prop="hazardDescription"><el-input v-model="rectForm.hazardDescription" type="textarea" :rows="3" :disabled="!canEditRectTask" /></el-form-item>
+        <el-form-item label="澶囨敞" prop="remarks"><el-input v-model="rectForm.remarks" type="textarea" :rows="2" :disabled="!canEditRectTask" /></el-form-item>
+        <template v-if="showRectProcess">
+          <el-divider content-position="left">鏁存敼澶勭悊</el-divider>
+          <el-row v-if="rectForm.closedDate" :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="闂幆鏃ユ湡">
+                <el-date-picker v-model="rectForm.closedDate" value-format="YYYY-MM-DD" type="date" style="width: 100%" disabled />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-form-item label="鏁存敼鎺柦" prop="rectificationMeasures"><el-input v-model="rectForm.rectificationMeasures" type="textarea" :rows="3" placeholder="璇疯緭鍏ユ暣鏀规帾鏂�" :disabled="!canEditRectProcess" /></el-form-item>
+          <el-form-item label="鏁存敼缁撴灉" prop="rectificationResult"><el-input v-model="rectForm.rectificationResult" type="textarea" :rows="3" placeholder="璇疯緭鍏ユ暣鏀圭粨鏋�" :disabled="!canEditRectProcess" /></el-form-item>
+          <el-form-item label="鏁存敼闄勪欢">
+            <FileUpload v-model:file-list="rectForm.storageBlobDTOs" :limit="6" :disabled="!canEditRectProcess" />
+          </el-form-item>
+        </template>
       </el-form>
       <template #footer>
-        <el-button type="primary" @click="submitRectForm">纭畾</el-button>
-        <el-button @click="rectDialogVisible = false">鍙栨秷</el-button>
+        <el-button v-if="!isRectView" type="primary" @click="submitRectForm">纭畾</el-button>
+        <el-button @click="rectDialogVisible = false">{{ isRectView ? "鍏抽棴" : "鍙栨秷" }}</el-button>
       </template>
     </el-dialog>
   </div>
@@ -171,13 +186,17 @@
   specialEquipmentRectificationListPage,
   specialEquipmentRectificationAdd,
   specialEquipmentRectificationUpdate,
+  specialEquipmentRectificationClose,
   specialEquipmentRectificationDel,
 } from "@/api/safeProduction/specialEquipmentManagement.js";
 import { userListNoPageByTenantId } from "@/api/system/user.js";
+import useUserStore from "@/store/modules/user.js";
 import FileUpload from "@/components/AttachmentUpload/file/index.vue";
 
 const activeTab = ref("ledger");
 const userOptions = ref([]);
+const userStore = useUserStore();
+const currentUserId = computed(() => Number(userStore.id) || null);
 
 const ledgerSearch = reactive({ equipmentName: "" });
 const recordSearch = reactive({ recordType: "" });
@@ -238,6 +257,7 @@
 };
 const rectDialogVisible = ref(false);
 const rectDialogTitle = ref("");
+const rectDialogMode = ref("create");
 const rectFormRef = ref();
 const rectForm = reactive({
   equipmentId: "",
@@ -250,19 +270,37 @@
   rectificationStatus: 1,
   rectificationMeasures: "",
   rectificationResult: "",
+  closedDate: "",
   storageBlobDTOs: [],
   remarks: "",
 });
 const rectRules = {
   equipmentId: [{ required: true, message: "璇烽�夋嫨鍏宠仈璁惧", trigger: "change" }],
+  riskLevel: [{ required: true, message: "璇烽�夋嫨椋庨櫓绛夌骇", trigger: "change" }],
   hazardDescription: [{ required: true, message: "璇疯緭鍏ラ殣鎮f弿杩�", trigger: "blur" }],
+  responsibleUserId: [{ required: true, message: "璇烽�夋嫨鏁存敼璐d换浜�", trigger: "change" }],
   discoveredDate: [{ required: true, message: "璇烽�夋嫨鍙戠幇鏃ユ湡", trigger: "change" }],
   rectificationDeadline: [{ required: true, message: "璇烽�夋嫨鏁存敼鏈熼檺", trigger: "change" }],
 };
 const ledgerOptions = ref([]);
 const activeLedgerOptions = computed(() => ledgerOptions.value);
 const activeUserOptions = computed(() => userOptions.value || []);
+const isRectView = computed(() => rectDialogMode.value === "view");
+const canEditRectTask = computed(() => ["create", "edit"].includes(rectDialogMode.value));
+const canEditRectProcess = computed(() => rectDialogMode.value === "rectify");
+const showRectProcess = computed(() => {
+  const status = Number(rectForm.rectificationStatus);
+  return (
+    canEditRectProcess.value ||
+    isRectView.value ||
+    status >= 3 ||
+    !!rectForm.rectificationMeasures ||
+    !!rectForm.rectificationResult ||
+    getAttachments(rectForm).length > 0
+  );
+});
 const getAttachments = row => row?.storageBlobDTOs || row?.storageBlobVOs || [];
+const rectStatusMap = { 1: "寰呮暣鏀�", 2: "鏁存敼涓�", 3: "寰呭鏍�", 4: "宸查棴鐜�" };
 
 const getDueDays = (dateValue) => {
   if (!dateValue) return null;
@@ -296,16 +334,37 @@
   return map[status] || "info";
 };
 
+const formatRectStatus = status => rectStatusMap[status] || "鏈缃�";
+
+const findLedgerById = equipmentId => {
+  return ledgerOptions.value.find(item => Number(item.id) === Number(equipmentId));
+};
+
+const fillEquipmentName = row => {
+  const equipment = findLedgerById(row?.equipmentId);
+  return {
+    ...row,
+    equipmentName: row?.equipmentName || equipment?.equipmentName || "-",
+  };
+};
+
+const isPendingRect = row => [1, 2].includes(Number(row?.rectificationStatus));
+const isReviewRect = row => Number(row?.rectificationStatus) === 3;
+const canAdjustRectTask = row => Number(row?.rectificationStatus) === 1;
+const isNotResponsibleUser = row =>
+  !!row?.responsibleUserId && Number(row.responsibleUserId) !== Number(currentUserId.value);
+
 const ledgerColumns = [
-  { label: "璁惧缂栧彿", prop: "equipmentNo" },
-  { label: "璁惧鍚嶇О", prop: "equipmentName" },
-  { label: "璁惧绫诲埆", prop: "equipmentType" },
-  { label: "瀹夎浣嶇疆", prop: "installLocation" },
-  { label: "璐熻矗浜�", prop: "managerName" },
+  { label: "璁惧缂栧彿", prop: "equipmentNo", align: "center"},
+  { label: "璁惧鍚嶇О", prop: "equipmentName", align: "center"},
+  { label: "璁惧绫诲埆", prop: "equipmentType", align: "center" },
+  { label: "瀹夎浣嶇疆", prop: "installLocation", align: "center" },
+  { label: "璐熻矗浜�", prop: "managerName", align: "center" },
   {
     label: "鎿嶄綔",
     dataType: "action",
-    width: "180",
+    width: "150",
+    align: "center",
     operation: [
       { name: "缂栬緫", clickFun: (row) => openLedgerForm(row) },
       { name: "鍒犻櫎", clickFun: (row) => deleteLedger(row.id) },
@@ -314,17 +373,18 @@
 ];
 
 const recordColumns = [
-  { label: "璁板綍缂栧彿", prop: "recordNo" },
-  { label: "璁板綍绫诲瀷", prop: "recordType", formatData: { 1: "妫�楠�", 2: "缁翠繚" } },
-  { label: "璁板綍鏃ユ湡", prop: "recordDate" },
-  { label: "鎵ц浜�", prop: "executorName" },
-  { label: "鎵ц缁撴灉", prop: "executeResult" },
-  { label: "涓嬫鍒版湡鏃ユ湡", prop: "nextDueDate" },
-  { label: "鍒版湡鎻愰啋", prop: "nextDueDate", dataType: "tag", formatData: formatDueStatus, formatType: getDueStatusType },
+  { label: "璁板綍缂栧彿", prop: "recordNo", align: "center" },
+  { label: "璁板綍绫诲瀷", prop: "recordType", formatData: { 1: "妫�楠�", 2: "缁翠繚" }, align: "center" },
+  { label: "璁板綍鏃ユ湡", prop: "recordDate", align: "center" },
+  { label: "鎵ц浜�", prop: "executorName", align: "center" },
+  { label: "鎵ц缁撴灉", prop: "executeResult", align: "center" },
+  { label: "涓嬫鍒版湡鏃ユ湡", prop: "nextDueDate", align: "center" },
+  { label: "鍒版湡鎻愰啋", prop: "nextDueDate", dataType: "tag", formatData: formatDueStatus, formatType: getDueStatusType, align: "center" },
   {
     label: "鎿嶄綔",
     dataType: "action",
-    width: "180",
+    width: "150",
+    align: "center",
     operation: [
       { name: "缂栬緫", clickFun: (row) => openRecordForm(row) },
       { name: "鍒犻櫎", clickFun: (row) => deleteRecord(row.id) },
@@ -333,19 +393,29 @@
 ];
 
 const rectColumns = [
-  { label: "闅愭偅鎻忚堪", prop: "hazardDescription" },
-  { label: "椋庨櫓绛夌骇", prop: "riskLevel" },
-  { label: "鍙戠幇鏃ユ湡", prop: "discoveredDate" },
-  { label: "璐d换浜�", prop: "responsibleUserName" },
-  { label: "鏁存敼鏈熼檺", prop: "rectificationDeadline" },
-  { label: "鏁存敼鐘舵��", prop: "rectificationStatus", dataType: "tag", formatData: { 1: "寰呮暣鏀�", 2: "鏁存敼涓�", 3: "寰呭鏍�", 4: "宸查棴鐜�" }, formatType: getRectStatusType },
+  { label: "鍏宠仈璁惧", prop: "equipmentName", align: "center" },
+  { label: "闅愭偅鎻忚堪", prop: "hazardDescription", align: "center" },
+  { label: "椋庨櫓绛夌骇", prop: "riskLevel", align: "center"  },
+  { label: "鍙戠幇鏃ユ湡", prop: "discoveredDate", align: "center"  },
+  { label: "璐d换浜�", prop: "responsibleUserName", align: "center"  },
+  { label: "鏁存敼鏈熼檺", prop: "rectificationDeadline", align: "center"  },
+  { label: "鏁存敼鐘舵��", prop: "rectificationStatus", dataType: "tag", formatData: { 1: "寰呮暣鏀�", 2: "鏁存敼涓�", 3: "寰呭鏍�", 4: "宸查棴鐜�" }, formatType: getRectStatusType, align: "center"  },
   {
     label: "鎿嶄綔",
     dataType: "action",
-    width: "220",
+    width: "260",
+    align: "center",
     operation: [
-      { name: "缂栬緫", clickFun: (row) => openRectForm(row) },
-      { name: "鍒犻櫎", clickFun: (row) => deleteRect(row.id) },
+      { name: "璇︽儏", clickFun: (row) => openRectDetail(row) },
+      {
+        name: "鏁存敼",
+        clickFun: (row) => openRectifyForm(row),
+        show: isPendingRect,
+        disabled: isNotResponsibleUser,
+      },
+      { name: "闂幆", clickFun: (row) => closeRect(row), show: isReviewRect },
+      { name: "缂栬緫", clickFun: (row) => openRectForm(row), show: canAdjustRectTask },
+      { name: "鍒犻櫎", clickFun: (row) => deleteRect(row.id), show: canAdjustRectTask },
     ],
   },
 ];
@@ -361,6 +431,7 @@
 const loadLedgerOptions = async () => {
   const res = await specialEquipmentLedgerList({});
   ledgerOptions.value = res.data || [];
+  rectTableData.value = rectTableData.value.map(fillEquipmentName);
 };
 
 const recordQuery = async () => {
@@ -374,7 +445,8 @@
 const rectQuery = async () => {
   rectLoading.value = true;
   const res = await specialEquipmentRectificationListPage({ ...rectSearch, ...rectPage });
-  rectTableData.value = res.data?.records || res.data?.rows || [];
+  const rows = res.data?.records || res.data?.rows || [];
+  rectTableData.value = rows.map(fillEquipmentName);
   rectPage.total = res.data?.total || 0;
   rectLoading.value = false;
 };
@@ -479,7 +551,8 @@
   recordQuery();
 };
 
-const openRectForm = (row = {}) => {
+const openRectForm = (row = {}, mode = row.id ? "edit" : "create") => {
+  rectDialogMode.value = mode;
   Object.assign(rectForm, {
     id: "",
     equipmentId: "",
@@ -492,6 +565,7 @@
     rectificationStatus: 1,
     rectificationMeasures: "",
     rectificationResult: "",
+    closedDate: "",
     storageBlobDTOs: [],
     remarks: "",
   });
@@ -501,22 +575,95 @@
     const matched = userOptions.value.find((item) => (item.nickName || item.userName) === rectForm.responsibleUserName);
     rectForm.responsibleUserId = matched?.userId || "";
   }
-  rectDialogTitle.value = row.id ? "缂栬緫鏁存敼" : "鏂板鏁存敼";
+  if (mode === "view") {
+    rectDialogTitle.value = "鏁存敼璇︽儏";
+  } else if (mode === "rectify") {
+    rectDialogTitle.value = "鏁存敼澶勭悊";
+  } else {
+    rectDialogTitle.value = row.id ? "缂栬緫鏁存敼" : "鏂板鏁存敼";
+  }
   rectDialogVisible.value = true;
 };
 
+const openRectDetail = (row) => {
+  openRectForm(row, "view");
+};
+
+const openRectifyForm = (row) => {
+  if (isNotResponsibleUser(row)) {
+    return ElMessage.warning("鍙湁鏁存敼璐d换浜哄彲浠ュ鐞嗚鏁存敼浠诲姟");
+  }
+  openRectForm(row, "rectify");
+};
+
+const buildRectTaskPayload = () => ({
+  id: rectForm.id,
+  equipmentId: rectForm.equipmentId,
+  hazardDescription: rectForm.hazardDescription,
+  riskLevel: rectForm.riskLevel,
+  discoveredDate: rectForm.discoveredDate,
+  responsibleUserId: rectForm.responsibleUserId,
+  responsibleUserName: rectForm.responsibleUserName,
+  rectificationDeadline: rectForm.rectificationDeadline,
+  rectificationStatus: 1,
+  rectificationMeasures: "",
+  rectificationResult: "",
+  closedDate: "",
+  storageBlobDTOs: [],
+  remarks: rectForm.remarks,
+});
+
+const buildRectProcessPayload = () => ({
+  id: rectForm.id,
+  equipmentId: rectForm.equipmentId,
+  hazardDescription: rectForm.hazardDescription,
+  riskLevel: rectForm.riskLevel,
+  discoveredDate: rectForm.discoveredDate,
+  responsibleUserId: rectForm.responsibleUserId,
+  responsibleUserName: rectForm.responsibleUserName,
+  rectificationDeadline: rectForm.rectificationDeadline,
+  rectificationStatus: 3,
+  rectificationMeasures: rectForm.rectificationMeasures,
+  rectificationResult: rectForm.rectificationResult,
+  storageBlobDTOs: rectForm.storageBlobDTOs,
+  remarks: rectForm.remarks,
+});
+
 const submitRectForm = async () => {
-  await rectFormRef.value.validate();
-  const api = rectForm.id ? specialEquipmentRectificationUpdate : specialEquipmentRectificationAdd;
-  await api(rectForm);
-  ElMessage.success("淇濆瓨鎴愬姛");
+  if (isRectView.value) return;
+  if (canEditRectProcess.value) {
+    if (!String(rectForm.rectificationMeasures || "").trim()) {
+      return ElMessage.warning("璇疯緭鍏ユ暣鏀规帾鏂�");
+    }
+    if (!String(rectForm.rectificationResult || "").trim()) {
+      return ElMessage.warning("璇疯緭鍏ユ暣鏀圭粨鏋�");
+    }
+    await specialEquipmentRectificationUpdate(buildRectProcessPayload());
+    ElMessage.success("鏁存敼宸叉彁浜わ紝绛夊緟闂幆");
+  } else {
+    await rectFormRef.value.validate();
+    const api = rectForm.id ? specialEquipmentRectificationUpdate : specialEquipmentRectificationAdd;
+    await api(buildRectTaskPayload());
+    ElMessage.success(rectForm.id ? "鏁存敼浠诲姟宸叉洿鏂�" : "鏁存敼浠诲姟宸叉淳鍙�");
+  }
   rectDialogVisible.value = false;
+  rectQuery();
+};
+
+const closeRect = async (row) => {
+  await ElMessageBox.confirm("纭璇ユ暣鏀瑰凡澶嶆牳瀹屾垚骞堕棴鐜悧锛�", "闂幆纭", { type: "warning" });
+  await specialEquipmentRectificationClose({ id: row.id });
+  ElMessage.success("宸查棴鐜�");
   rectQuery();
 };
 
 const deleteRect = async (id) => {
   const ids = id ? [id] : rectSelection.value.map((i) => i.id);
   if (!ids.length) return ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+  const selectedRows = id ? rectTableData.value.filter((item) => item.id === id) : rectSelection.value;
+  if (selectedRows.some((item) => !canAdjustRectTask(item))) {
+    return ElMessage.warning("鍙兘鍒犻櫎寰呮暣鏀圭殑鏁存敼浠诲姟");
+  }
   await ElMessageBox.confirm("纭鍒犻櫎鎵�閫夋暣鏀规暟鎹悧锛�", "鎻愮ず", { type: "warning" });
   await specialEquipmentRectificationDel(ids);
   ElMessage.success("鍒犻櫎鎴愬姛");

--
Gitblit v1.9.3