From bd7f920a53ba17016ee4f6324d155eef2bc4cece Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 03 八月 2026 17:00:37 +0800
Subject: [PATCH] feat: 发货信息展示源单号

---
 src/views/safeProduction/safetyFacility/index.vue | 2559 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 2,188 insertions(+), 371 deletions(-)

diff --git a/src/views/safeProduction/safetyFacility/index.vue b/src/views/safeProduction/safetyFacility/index.vue
index 02a0342..3f81c80 100644
--- a/src/views/safeProduction/safetyFacility/index.vue
+++ b/src/views/safeProduction/safetyFacility/index.vue
@@ -1,151 +1,840 @@
 <template>
-  <div class="safety-facility">
-    <!-- 鎼滅储鍖哄煙 -->
-    <div class="search-area">
-      <el-form :inline="true" :model="searchForm">
-        <el-form-item label="璁炬柦鍚嶇О">
-          <el-input v-model="searchForm.facilityName" placeholder="璇疯緭鍏ヨ鏂藉悕绉�" clearable />
-        </el-form-item>
-        <el-form-item label="璁炬柦绫诲瀷">
-          <el-select v-model="searchForm.facilityType" placeholder="璇烽�夋嫨绫诲瀷" clearable>
-            <el-option label="娑堥槻鍣ㄦ潗" value="娑堥槻鍣ㄦ潗" />
-            <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.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
-            <el-option label="姝e父" value="姝e父" />
-            <el-option label="寮傚父" value="寮傚父" />
-            <el-option label="鍋滅敤" value="鍋滅敤" />
-          </el-select>
-        </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="app-container safety-facility-page">
+    <el-tabs v-model="activeTab"
+             class="facility-tabs"
+             @tab-click="handleTabClick">
+      <!-- 瀹夊叏璁炬柦鍙拌处 -->
+      <el-tab-pane label="瀹夊叏璁炬柦鍙拌处" name="ledger">
+        <div class="facility-toolbar">
+          <div class="toolbar-filters">
+            <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">
+              鎼滅储
+            </el-button>
+            <el-button @click="resetLedgerQuery">閲嶇疆</el-button>
+          </div>
+          <div class="toolbar-actions">
+            <el-button type="danger"
+                       plain
+                       :disabled="ledgerSelectedIds.length === 0"
+                       @click="handleBatchDeleteLedger">鎵归噺鍒犻櫎</el-button>
+            <el-button type="primary"
+                       @click="openLedgerForm('add')">鏂板璁炬柦</el-button>
+          </div>
+        </div>
 
-    <!-- 鎿嶄綔鎸夐挳 -->
-    <div class="actions">
-      <el-button type="primary" @click="handleAdd">鏂板璁炬柦</el-button>
-      <el-button type="success" @click="handleExport">瀵煎嚭</el-button>
-    </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-table :data="facilityList" style="width: 100%; margin-top: 10px;" border>
-      <el-table-column prop="facilityName" label="璁炬柦鍚嶇О" width="180" />
-      <el-table-column prop="facilityType" label="璁炬柦绫诲瀷" width="120" />
-      <el-table-column prop="location" label="鎵�鍦ㄤ綅缃�" width="200" />
-      <el-table-column prop="deviceName" label="鍏宠仈璁惧" width="150" />
-      <el-table-column prop="status" label="鐘舵��" width="100">
-        <template #default="{ row }">
-          <el-tag :type="getFacilityStatusType(row.status)">
-            {{ row.status }}
-          </el-tag>
-        </template>
-      </el-table-column>
-      <el-table-column prop="lastInspectionTime" label="涓婃宸℃" width="180" />
-      <el-table-column prop="nextInspectionTime" label="涓嬫宸℃" width="180" />
-      <el-table-column prop="responsibilityPerson" label="璐d换浜�" width="120" />
-      <el-table-column label="鎿嶄綔" width="250" fixed="right">
-        <template #default="{ row }">
-          <el-button type="primary" link @click="handleEdit(row)">缂栬緫</el-button>
-          <el-button type="warning" link @click="handleInspection(row)">宸℃</el-button>
-          <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
+      <!-- 宸℃浠诲姟 -->
+      <el-tab-pane label="宸℃浠诲姟" name="task">
+        <div class="facility-toolbar">
+          <div class="toolbar-filters">
+            <span class="search_title">宸℃浠诲姟鍚嶇О锛�</span>
+            <el-input v-model="taskSearchForm.inspectionName"
+                      style="width: 220px"
+                      placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О"
+                      @change="handleTaskQuery"
+                      clearable
+                      :prefix-icon="Search" />
+            <span class="search_title ml10">璁炬柦鍚嶇О锛�</span>
+            <el-input v-model="taskSearchForm.facilityName"
+                      style="width: 200px"
+                      placeholder="璇疯緭鍏ヨ鏂藉悕绉�"
+                      @change="handleTaskQuery"
+                      clearable
+                      :prefix-icon="Search" />
+            <span class="search_title ml10">鏄惁鍚敤锛�</span>
+            <el-select v-model="taskSearchForm.isEnabled"
+                       clearable
+                       @change="handleTaskQuery"
+                       style="width: 150px">
+              <el-option label="鏄�" :value="1" />
+              <el-option label="鍚�" :value="0" />
+            </el-select>
+            <el-button type="primary"
+                       @click="handleTaskQuery">
+              鎼滅储
+            </el-button>
+            <el-button @click="resetTaskQuery">閲嶇疆</el-button>
+          </div>
+          <div class="toolbar-actions">
+            <el-button type="danger"
+                       plain
+                       :disabled="taskSelectedIds.length === 0"
+                       @click="handleBatchDeleteTask">鍒犻櫎</el-button>
+            <el-button type="primary"
+                       @click="openTaskDialog('add')">鏂板宸℃浠诲姟</el-button>
+          </div>
+        </div>
 
-    <!-- 鍒嗛〉 -->
-    <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>
+        <div class="table_list">
+          <PIMTable rowKey="id"
+                    :column="taskTableColumn"
+                    :tableData="taskTableData"
+                    :page="taskPage"
+                    :isSelection="true"
+                    @selection-change="handleTaskSelectionChange"
+                    :tableLoading="taskTableLoading"
+                    @pagination="taskPagination"
+                    :total="taskPage.total"></PIMTable>
+        </div>
+      </el-tab-pane>
 
-    <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
-    <el-dialog :title="dialogTitle" v-model="showDialog" width="600px">
-      <el-form :model="form" :rules="formRules" ref="formRef" label-width="100px">
-        <el-form-item label="璁炬柦鍚嶇О" prop="facilityName">
-          <el-input v-model="form.facilityName" placeholder="璇疯緭鍏ヨ鏂藉悕绉�" />
-        </el-form-item>
-        <el-form-item label="璁炬柦绫诲瀷" prop="facilityType">
-          <el-select v-model="form.facilityType" placeholder="璇烽�夋嫨绫诲瀷">
-            <el-option label="娑堥槻鍣ㄦ潗" value="娑堥槻鍣ㄦ潗" />
-            <el-option label="瀹夊叏璁惧" value="瀹夊叏璁惧" />
-            <el-option label="闃叉姢鐢ㄥ搧" value="闃叉姢鐢ㄥ搧" />
-            <el-option label="鐩戞帶璁惧" value="鐩戞帶璁惧" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="鎵�鍦ㄤ綅缃�" prop="location">
-          <el-input v-model="form.location" placeholder="璇疯緭鍏ユ墍鍦ㄤ綅缃�" />
-        </el-form-item>
-        <el-form-item label="鍏宠仈璁惧">
-          <el-select v-model="form.deviceId" placeholder="璇烽�夋嫨璁惧" clearable>
-            <el-option
-              v-for="item in deviceOptions"
-              :key="item.id"
-              :label="item.deviceName"
-              :value="item.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="璐d换閮ㄩ棬">
-          <el-input v-model="form.responsibilityDept" placeholder="璇疯緭鍏ヨ矗浠婚儴闂�" />
-        </el-form-item>
-        <el-form-item label="璐d换浜�">
-          <el-input v-model="form.responsibilityPerson" placeholder="璇疯緭鍏ヨ矗浠讳汉" />
-        </el-form-item>
-        <el-form-item label="涓嬫宸℃">
-          <el-date-picker
-            v-model="form.nextInspectionTime"
-            type="datetime"
-            placeholder="璇烽�夋嫨涓嬫宸℃鏃堕棿"
-            format="YYYY-MM-DD HH:mm:ss"
-            value-format="YYYY-MM-DD HH:mm:ss"
-          />
-        </el-form-item>
-        <el-form-item label="澶囨敞">
-          <el-input type="textarea" v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" />
+      <!-- 宸℃璁板綍 -->
+      <el-tab-pane label="宸℃璁板綍" name="inspection">
+        <div class="facility-toolbar">
+          <div class="toolbar-filters">
+            <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">
+              鎼滅储
+            </el-button>
+            <el-button @click="resetInspectionQuery">閲嶇疆</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="facility-toolbar">
+          <div class="toolbar-filters">
+            <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">
+              鎼滅储
+            </el-button>
+            <el-button @click="resetRectificationQuery">閲嶇疆</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="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="submitForm">纭畾</el-button>
-          <el-button @click="showDialog = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="submitLedgerForm">纭畾</el-button>
+          <el-button @click="ledgerDialogVisible = false">鍙栨秷</el-button>
         </span>
       </template>
     </el-dialog>
 
-    <!-- 宸℃璁板綍瀵硅瘽妗� -->
-    <el-dialog title="璁板綍宸℃缁撴灉" v-model="showInspectionDialog" width="500px">
-      <el-form :model="inspectionForm" label-width="100px">
-        <el-form-item label="璁炬柦鍚嶇О">
-          <el-input v-model="inspectionForm.facilityName" disabled />
+    <!-- 璁炬柦鍙拌处璇︽儏寮圭獥 -->
+    <el-dialog v-model="ledgerDetailVisible"
+               title="璁炬柦璇︽儏"
+               width="760px"
+               class="detail-dialog">
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="璁炬柦缂栧彿">{{ ledgerDetail.facilityCode || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁炬柦鍚嶇О">{{ ledgerDetail.facilityName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁炬柦绫诲瀷">{{ ledgerDetail.facilityType || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瑙勬牸鍨嬪彿">{{ ledgerDetail.facilitySpec || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瀹夎浣嶇疆">{{ ledgerDetail.installLocation || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瀹夎鏃堕棿">{{ ledgerDetail.installTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鐢熶骇鏃ユ湡">{{ ledgerDetail.productionDate || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鐘舵��">
+          <el-tag :type="ledgerStatusType(ledgerDetail.status)">{{ ledgerDetail.status || '-' }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="澶囨敞" :span="2">{{ ledgerDetail.remark || '-' }}</el-descriptions-item>
+      </el-descriptions>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="ledgerDetailVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 宸℃浠诲姟琛ㄥ崟寮圭獥 -->
+    <el-dialog v-model="taskDialogVisible"
+               :title="taskDialogTitle"
+               width="920px"
+               :close-on-click-modal="false"
+               @closed="resetTaskForm">
+      <el-form ref="taskFormRef"
+               :model="taskForm"
+               :rules="taskRules"
+               label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="宸℃浠诲姟鍚嶇О"
+                          prop="inspectionName">
+              <el-input v-model="taskForm.inspectionName"
+                        placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹夊叏璁炬柦"
+                          prop="facilityId">
+              <el-select v-model="taskForm.facilityId"
+                         placeholder="璇烽�夋嫨瀹夊叏璁炬柦"
+                         filterable
+                         clearable
+                         style="width: 100%"
+                         @change="handleTaskFacilityChange">
+                <el-option v-for="item in facilityOptions"
+                           :key="item.id"
+                           :label="`${item.facilityName}锛�${item.facilityCode || '-'}锛塦"
+                           :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="宸℃浜�"
+                          prop="inspectorId">
+              <el-select v-model="taskForm.inspectorId"
+                         placeholder="璇烽�夋嫨宸℃浜�"
+                         filterable
+                         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-col :span="12">
+            <el-form-item label="鏄惁鍚敤"
+                          prop="isEnabled">
+              <el-radio-group v-model="taskForm.isEnabled">
+                <el-radio :label="1">鏄�</el-radio>
+                <el-radio :label="0">鍚�</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="宸℃椤圭洰"
+                          prop="inspectionProject">
+              <el-input v-model="taskForm.inspectionProject"
+                        type="textarea"
+                        :autosize="{ minRows: 3, maxRows: 6 }"
+                        placeholder="璇疯緭鍏ュ贰妫�椤圭洰" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="澶囨敞">
+              <el-input v-model="taskForm.remark"
+                        type="textarea"
+                        :autosize="{ minRows: 3, maxRows: 6 }"
+                        placeholder="璇疯緭鍏ュ娉�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠诲姟棰戠巼"
+                          prop="frequencyType">
+              <el-select v-model="taskForm.frequencyType"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         style="width: 100%"
+                         @change="handleFrequencyTypeChange">
+                <el-option label="姣忔棩" value="DAILY" />
+                <el-option label="姣忓懆" value="WEEKLY" />
+                <el-option label="姣忔湀" value="MONTHLY" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col v-if="taskForm.frequencyType === 'DAILY'" :span="12">
+            <el-form-item class="frequency-detail-item"
+                          label="鎵ц鏃堕棿"
+                          prop="frequencyDetail">
+              <el-time-picker v-model="taskForm.frequencyDetail"
+                              placeholder="閫夋嫨鏃堕棿"
+                              format="HH:mm"
+                              value-format="HH:mm"
+                              style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col v-if="taskForm.frequencyType === 'WEEKLY'" :span="12">
+            <el-form-item class="frequency-detail-item"
+                          label="鎵ц鏃堕棿"
+                          prop="frequencyDetail">
+              <div class="frequency-row">
+                <el-select v-model="taskForm.week"
+                           class="frequency-day-select"
+                           placeholder="璇烽�夋嫨鏄熸湡"
+                           clearable>
+                  <el-option v-for="item in weekOptions"
+                             :key="item.value"
+                             :label="item.label"
+                             :value="item.value" />
+                </el-select>
+                <el-time-picker v-model="taskForm.time"
+                                class="frequency-time-picker"
+                                placeholder="閫夋嫨鏃堕棿"
+                                format="HH:mm"
+                                value-format="HH:mm" />
+              </div>
+            </el-form-item>
+          </el-col>
+          <el-col v-if="taskForm.frequencyType === 'MONTHLY'" :span="12">
+            <el-form-item class="frequency-detail-item"
+                          label="鎵ц鏃堕棿"
+                          prop="frequencyDetail">
+              <div class="frequency-row">
+                <el-select v-model="taskForm.day"
+                           class="frequency-day-select"
+                           placeholder="璇烽�夋嫨鏃ユ湡"
+                           clearable>
+                  <el-option v-for="item in dayOptions"
+                             :key="item.value"
+                             :label="item.label"
+                             :value="item.value" />
+                </el-select>
+                <el-time-picker v-model="taskForm.time"
+                                class="frequency-time-picker"
+                                placeholder="閫夋嫨鏃堕棿"
+                                format="HH:mm"
+                                value-format="HH:mm" />
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitTaskForm">淇濆瓨</el-button>
+          <el-button @click="taskDialogVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 宸℃浠诲姟璇︽儏 -->
+    <el-dialog v-model="taskDetailVisible"
+               title="宸℃浠诲姟璇︽儏"
+               width="860px">
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="宸℃浠诲姟鍚嶇О">{{ taskDetail.inspectionName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瀹夊叏璁炬柦">{{ taskDetail.facilityName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁炬柦缂栧彿">{{ taskDetail.facilityCode || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="宸℃浜�">{{ taskDetail.inspectorName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鏄惁鍚敤">{{ taskDetail.isEnabled === 1 ? '鏄�' : '鍚�' }}</el-descriptions-item>
+        <el-descriptions-item label="棰戞">{{ frequencyTypeMap[taskDetail.frequencyType] || taskDetail.frequencyType || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鎵ц鏃堕棿">{{ formatFrequencyDetail(taskDetail.frequencyDetail) }}</el-descriptions-item>
+        <el-descriptions-item label="涓嬫鎵ц鏃堕棿">{{ taskDetail.nextExecutionTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="宸℃椤圭洰" :span="2">{{ taskDetail.inspectionProject || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="澶囨敞" :span="2">{{ taskDetail.remark || '-' }}</el-descriptions-item>
+      </el-descriptions>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="taskDetailVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 鍘嗗彶宸℃璁板綍 -->
+    <el-dialog v-model="taskHistoryVisible"
+               title="鍘嗗彶宸℃璁板綍"
+               width="1100px">
+      <el-descriptions class="history-summary" :column="3" border>
+        <el-descriptions-item label="宸℃浠诲姟鍚嶇О">{{ taskHistoryTask.inspectionName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瀹夊叏璁炬柦">{{ taskHistoryTask.facilityName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="棰戞">{{ frequencyTypeMap[taskHistoryTask.frequencyType] || taskHistoryTask.frequencyType || '-' }}</el-descriptions-item>
+      </el-descriptions>
+      <PIMTable rowKey="id"
+                :column="taskHistoryTableColumn"
+                :tableData="taskHistoryTableData"
+                :page="taskHistoryPage"
+                :isSelection="false"
+                :tableLoading="taskHistoryTableLoading"
+                @pagination="taskHistoryPagination"
+                :total="taskHistoryPage.total"></PIMTable>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="taskHistoryVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 宸℃琛ㄥ崟寮圭獥 -->
+    <el-dialog v-model="inspectionDialogVisible"
+               :title="inspectionDialogTitle"
+               width="720px"
+               class="facility-form-dialog"
+               :close-on-click-modal="false">
+      <el-form ref="inspectionFormRef"
+               :model="inspectionForm"
+               :rules="inspectionRules"
+               label-position="top"
+               class="inspection-form">
+        <div v-if="inspectionForm.facilityName || inspectionForm.facilityCode"
+             class="dialog-summary">
+          <div class="summary-item">
+            <span>璁炬柦鍚嶇О</span>
+            <strong>{{ inspectionForm.facilityName || '-' }}</strong>
+          </div>
+          <div class="summary-item">
+            <span>璁炬柦缂栧彿</span>
+            <strong>{{ inspectionForm.facilityCode || '-' }}</strong>
+          </div>
+        </div>
+        <div class="inspection-form-grid">
+          <el-form-item label="宸℃缂栧彿"
+                        prop="inspectionCode">
+            <el-input v-model="inspectionForm.inspectionCode"
+                      placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
+                      :disabled="isInspectionBaseReadonly" />
+          </el-form-item>
+          <el-form-item label="宸℃绫诲瀷"
+                        prop="inspectionType">
+            <el-select v-model="inspectionForm.inspectionType"
+                       placeholder="璇烽�夋嫨宸℃绫诲瀷"
+                       style="width: 100%"
+                       :disabled="isInspectionBaseReadonly">
+              <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
+              <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="璁″垝宸℃鏃堕棿"
+                        prop="planTime"
+                        class="form-grid-full">
+            <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%"
+                            :disabled="isInspectionBaseReadonly" />
+          </el-form-item>
+          <el-form-item label="宸℃椤圭洰"
+                        class="form-grid-full">
+            <el-input v-model="inspectionForm.inspectionProject"
+                      type="textarea"
+                      :rows="3"
+                      disabled />
+          </el-form-item>
+        </div>
+        <template v-if="inspectionDialogType !== 'add'">
+          <el-form-item label="妫�鏌ョ粨鏋�"
+                        prop="checkResult">
+            <el-radio-group v-model="inspectionForm.checkResult" :disabled="isInspectionView">
+              <el-radio label="姝e父">姝e父</el-radio>
+              <el-radio label="寮傚父">寮傚父</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="妫�鏌ヨ鏄�"
+                        prop="checkDesc">
+            <el-input v-model="inspectionForm.checkDesc"
+                      type="textarea"
+                      :rows="3"
+                      placeholder="璇疯緭鍏ユ鏌ヨ鏄�"
+                      :disabled="isInspectionView" />
+          </el-form-item>
+          <el-form-item v-if="inspectionForm.checkResult === '寮傚父'" label="鐜板満鐓х墖">
+            <ImageUpload v-model:file-list="inspectionForm.storageBlobDTOs"
+                         :limit="6"
+                         button-text="涓婁紶鐓х墖"
+                         :disabled="isInspectionView" />
+          </el-form-item>
+        </template>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button v-if="!isInspectionView"
+                     type="primary"
+                     @click="submitInspectionForm">纭畾</el-button>
+          <el-button @click="inspectionDialogVisible = false">{{ isInspectionView ? '鍏抽棴' : '鍙栨秷' }}</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 宸℃璇︽儏寮圭獥 -->
+    <el-dialog v-model="inspectionDetailVisible"
+               title="宸℃璇︽儏"
+               width="920px"
+               class="detail-dialog">
+      <el-descriptions :column="3" border>
+        <el-descriptions-item label="宸℃缂栧彿">{{ inspectionDetail.inspectionCode || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁炬柦鍚嶇О">{{ inspectionDetail.facilityName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="宸℃浜�">{{ inspectionDetail.inspectorName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁″垝宸℃鏃堕棿">{{ inspectionDetail.planTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瀹為檯宸℃鏃堕棿">{{ inspectionDetail.actualTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鐘舵��">
+          <el-tag :type="inspectionStatusType(inspectionDetail.status)">{{ inspectionDetail.status || '-' }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="妫�鏌ョ粨鏋�">
+          <el-tag :type="inspectionResultType(inspectionDetail.checkResult)">{{ inspectionDetail.checkResult || '鏈~鍐�' }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃椤圭洰" :span="2">{{ inspectionDetail.inspectionProject || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="妫�鏌ヨ鏄�" :span="3">{{ inspectionDetail.checkDesc || '-' }}</el-descriptions-item>
+      </el-descriptions>
+      <div v-if="inspectionDetailImageUrls.length" class="detail-section">
+        <div class="detail-section-title">鐜板満鐓х墖</div>
+        <div class="detail-image-list">
+          <el-image v-for="(url, index) in inspectionDetailImageUrls"
+                    :key="`${url}-${index}`"
+                    :src="url"
+                    :preview-src-list="inspectionDetailImageUrls"
+                    :initial-index="index"
+                    fit="cover"
+                    class="detail-image" />
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="inspectionDetailVisible = 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"
+               :rules="rectificationRules"
+               label-width="120px">
+        <div v-if="rectificationForm.facilityName || rectificationForm.inspectionCode"
+             class="dialog-summary">
+          <div class="summary-item">
+            <span>璁炬柦鍚嶇О</span>
+            <strong>{{ rectificationForm.facilityName || '-' }}</strong>
+          </div>
+          <div class="summary-item">
+            <span>宸℃缂栧彿</span>
+            <strong>{{ rectificationForm.inspectionCode || '-' }}</strong>
+          </div>
+        </div>
+        <el-form-item label="闂鎻忚堪"
+                      :prop="isRectificationCreate ? 'problemDesc' : undefined">
+          <el-input v-model="rectificationForm.problemDesc"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="璇疯緭鍏ラ棶棰樻弿杩�"
+                    :disabled="!isRectificationCreate" />
         </el-form-item>
-        <el-form-item label="宸℃缁撴灉">
-          <el-radio-group v-model="inspectionForm.status">
-            <el-radio label="姝e父">姝e父</el-radio>
-            <el-radio label="寮傚父">寮傚父</el-radio>
-          </el-radio-group>
+        <el-form-item v-if="rectificationInspectionImageUrls.length"
+                      label="宸℃寮傚父鍥剧墖">
+          <div class="rectification-image-list">
+            <el-image v-for="(url, index) in rectificationInspectionImageUrls"
+                      :key="`${url}-${index}`"
+                      :src="url"
+                      :preview-src-list="rectificationInspectionImageUrls"
+                      :initial-index="index"
+                      fit="cover"
+                      class="rectification-image" />
+          </div>
         </el-form-item>
-        <el-form-item label="宸℃璇存槑" v-if="inspectionForm.status === '寮傚父'">
-          <el-input type="textarea" v-model="inspectionForm.description" placeholder="璇疯緭鍏ュ紓甯歌鏄�" />
+        <el-form-item label="闂绛夌骇"
+                      :prop="isRectificationCreate ? 'problemLevel' : undefined">
+          <el-select v-model="rectificationForm.problemLevel"
+                     placeholder="璇烽�夋嫨闂绛夌骇"
+                     style="width: 100%"
+                     :disabled="!isRectificationCreate">
+            <el-option label="涓�鑸�" value="涓�鑸�" />
+            <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="璁″垝鏁存敼鏃堕棿"
+                      :prop="isRectificationCreate ? 'planTime' : undefined">
+          <el-date-picker v-model="rectificationForm.planTime"
+                          type="datetime"
+                          placeholder="璇烽�夋嫨璁″垝鏁存敼鏃堕棿"
+                          format="YYYY-MM-DD HH:mm:ss"
+                          value-format="YYYY-MM-DD HH:mm:ss"
+                          style="width: 100%"
+                          :disabled="!isRectificationCreate" />
+        </el-form-item>
+        <el-form-item label="鏁存敼璐d换浜�"
+                      :prop="isRectificationCreate ? 'rectifyUserId' : undefined">
+          <el-select v-if="isRectificationCreate"
+                     v-model="rectificationForm.rectifyUserId"
+                     placeholder="璇烽�夋嫨鏁存敼璐d换浜�"
+                     filterable
+                     clearable
+                     style="width: 100%">
+            <el-option v-for="item in userList"
+                       :key="item.userId"
+                       :label="item.nickName"
+                       :value="item.userId" />
+          </el-select>
+          <el-input v-else
+                    :model-value="rectificationForm.rectifyUserName || getUserName(rectificationForm.rectifyUserId) || '-'"
+                    disabled />
+        </el-form-item>
+        <el-form-item v-if="showVerifyUser"
+                      label="楠屾敹浜�"
+                      :prop="isRectificationFix ? 'verifyUserId' : undefined">
+          <el-select v-if="isRectificationFix"
+                     v-model="rectificationForm.verifyUserId"
+                     placeholder="璇烽�夋嫨楠屾敹浜�"
+                     filterable
+                     clearable
+                     style="width: 100%">
+            <el-option v-for="item in userList"
+                       :key="item.userId"
+                       :label="item.nickName"
+                       :value="item.userId" />
+          </el-select>
+          <el-input v-else
+                    :model-value="rectificationForm.verifyUserName || getUserName(rectificationForm.verifyUserId) || '-'"
+                    disabled />
+        </el-form-item>
+        <el-form-item v-if="showRectifyDesc"
+                      label="鏁存敼璇存槑"
+                      :prop="isRectificationFix ? 'rectifyDesc' : undefined">
+          <el-input v-model="rectificationForm.rectifyDesc"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="璇疯緭鍏ユ暣鏀硅鏄�"
+                    :disabled="!isRectificationFix" />
+        </el-form-item>
+        <el-form-item v-if="showVerifyDesc"
+                      label="楠屾敹璇存槑"
+                      :prop="isRectificationVerify ? 'verifyDesc' : undefined">
+          <el-input v-model="rectificationForm.verifyDesc"
+                    type="textarea"
+                    :rows="3"
+                    placeholder="璇疯緭鍏ラ獙鏀惰鏄�"
+                    :disabled="!isRectificationVerify" />
         </el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button type="primary" @click="submitInspection">纭畾</el-button>
-          <el-button @click="showInspectionDialog = false">鍙栨秷</el-button>
+          <el-button v-if="!isRectificationView"
+                     type="primary"
+                     @click="submitRectificationForm">纭畾</el-button>
+          <el-button @click="rectificationDialogVisible = false">{{ isRectificationView ? '鍏抽棴' : '鍙栨秷' }}</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 鏁存敼璇︽儏寮圭獥 -->
+    <el-dialog v-model="rectificationDetailVisible"
+               title="鏁存敼璇︽儏"
+               width="920px"
+               class="detail-dialog">
+      <el-descriptions :column="3" border>
+        <el-descriptions-item label="宸℃缂栧彿">{{ rectificationDetail.inspectionCode || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁炬柦鍚嶇О">{{ rectificationDetail.facilityName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="闂绛夌骇">
+          <el-tag :type="rectificationLevelType(rectificationDetail.problemLevel)">
+            {{ rectificationDetail.problemLevel || '-' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="鏁存敼璐d换浜�">{{ rectificationDetail.rectifyUserName || getUserName(rectificationDetail.rectifyUserId) || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="璁″垝鏁存敼鏃堕棿">{{ rectificationDetail.planTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="瀹為檯鏁存敼鏃堕棿">{{ rectificationDetail.actualTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鐘舵��">
+          <el-tag :type="rectificationStatusType(rectificationDetail.status)">{{ rectificationDetail.status || '-' }}</el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="楠屾敹浜�">{{ rectificationDetail.verifyUserName || getUserName(rectificationDetail.verifyUserId) || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="楠屾敹鏃堕棿">{{ rectificationDetail.verifyTime || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="闂鎻忚堪" :span="3">{{ rectificationDetail.problemDesc || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鏁存敼璇存槑" :span="3">{{ rectificationDetail.rectifyDesc || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="楠屾敹璇存槑" :span="3">{{ rectificationDetail.verifyDesc || '-' }}</el-descriptions-item>
+      </el-descriptions>
+      <div v-if="rectificationDetailImageUrls.length" class="detail-section">
+        <div class="detail-section-title">宸℃寮傚父鍥剧墖</div>
+        <div class="detail-image-list">
+          <el-image v-for="(url, index) in rectificationDetailImageUrls"
+                    :key="`${url}-${index}`"
+                    :src="url"
+                    :preview-src-list="rectificationDetailImageUrls"
+                    :initial-index="index"
+                    fit="cover"
+                    class="detail-image" />
+        </div>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="rectificationDetailVisible = false">鍏抽棴</el-button>
         </span>
       </template>
     </el-dialog>
@@ -153,287 +842,1415 @@
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs, computed, provide } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
+import { userListNoPage } from "@/api/system/user.js";
+import useUserStore from "@/store/modules/user";
 import {
-  getSafetyFacilityList,
-  addOrEditSafetyFacility,
-  deleteSafetyFacility,
-  exportSafetyFacility
-} from '@/api/safeProduction/safetyFacility'
-import { getDeviceLedger } from '@/api/equipmentManagement/ledger'
+  getFacilityLedgerList,
+  addFacilityLedger,
+  updateFacilityLedger,
+  deleteFacilityLedger,
+  getFacilityInspectionTaskList,
+  addFacilityInspectionTask,
+  updateFacilityInspectionTask,
+  deleteFacilityInspectionTask,
+  getFacilityInspectionList,
+  updateFacilityInspection,
+  deleteFacilityInspection,
+  getFacilityRectificationList,
+  addFacilityRectification,
+  updateFacilityRectification
+} from "@/api/safeProduction/safetyFacility";
 
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
-  facilityName: '',
-  facilityType: '',
-  status: ''
-})
+const userStore = useUserStore();
+const userList = ref([]);
+const currentUserId = computed(() => Number(userStore.id) || null);
+const ENABLED = 1;
 
-// 鍒嗛〉鏁版嵁
-const pagination = reactive({
-  currentPage: 1,
-  pageSize: 10,
-  total: 0
-})
+const weekOptions = [
+  { label: "鍛ㄤ竴", value: "MON" },
+  { label: "鍛ㄤ簩", value: "TUE" },
+  { label: "鍛ㄤ笁", value: "WED" },
+  { label: "鍛ㄥ洓", value: "THU" },
+  { label: "鍛ㄤ簲", value: "FRI" },
+  { label: "鍛ㄥ叚", value: "SAT" },
+  { label: "鍛ㄦ棩", value: "SUN" }
+];
 
-// 鍒楄〃鏁版嵁
-const facilityList = ref([])
+const dayOptions = Array.from({ length: 31 }, (_, index) => {
+  const value = String(index + 1).padStart(2, "0");
+  return { label: `${index + 1}鏃, value };
+});
 
-// 璁惧閫夐」
-const deviceOptions = ref([])
+const frequencyTypeMap = {
+  DAILY: "姣忔棩",
+  WEEKLY: "姣忓懆",
+  MONTHLY: "姣忔湀"
+};
 
-// 瀵硅瘽妗嗙姸鎬�
-const showDialog = ref(false)
-const dialogTitle = ref('鏂板璁炬柦')
+const weekLabelMap = weekOptions.reduce((map, item) => {
+  map[item.value] = item.label;
+  return map;
+}, {});
 
-// 宸℃瀵硅瘽妗嗙姸鎬�
-const showInspectionDialog = ref(false)
-
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
+const createTaskForm = () => ({
   id: null,
-  facilityName: '',
-  facilityType: '',
-  location: '',
-  deviceId: null,
-  responsibilityDept: '',
-  responsibilityPerson: '',
-  nextInspectionTime: '',
-  remarks: ''
-})
+  inspectionName: "",
+  facilityId: null,
+  facilityCode: "",
+  facilityName: "",
+  inspectionProject: "",
+  inspectorId: "",
+  frequencyType: "",
+  frequencyDetail: "",
+  week: "",
+  day: "",
+  time: "",
+  isEnabled: ENABLED,
+  remark: ""
+});
 
-// 宸℃琛ㄥ崟鏁版嵁
-const inspectionForm = reactive({
-  id: null,
-  facilityName: '',
-  status: '姝e父',
-  description: ''
-})
+const validateFrequencyDetail = (rule, value, callback) => {
+  if (!taskForm.value.frequencyType) {
+    callback(new Error("璇烽�夋嫨浠诲姟棰戠巼"));
+    return;
+  }
+  if (taskForm.value.frequencyType === "DAILY" && !taskForm.value.frequencyDetail) {
+    callback(new Error("璇烽�夋嫨鎵ц鏃堕棿"));
+    return;
+  }
+  if (taskForm.value.frequencyType === "WEEKLY" && (!taskForm.value.week || !taskForm.value.time)) {
+    callback(new Error("璇烽�夋嫨鏄熸湡鍜屾椂闂�"));
+    return;
+  }
+  if (taskForm.value.frequencyType === "MONTHLY" && (!taskForm.value.day || !taskForm.value.time)) {
+    callback(new Error("璇烽�夋嫨鏃ユ湡鍜屾椂闂�"));
+    return;
+  }
+  callback();
+};
 
 // 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = reactive({
-  facilityName: [{ required: true, message: '璇疯緭鍏ヨ鏂藉悕绉�', trigger: 'blur' }],
-  facilityType: [{ required: true, message: '璇烽�夋嫨璁炬柦绫诲瀷', trigger: 'change' }],
-  location: [{ required: true, message: '璇疯緭鍏ユ墍鍦ㄤ綅缃�', trigger: 'blur' }]
-})
+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 formRef = ref(null)
+const taskRules = {
+  inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О", trigger: "blur" }],
+  facilityId: [{ required: true, message: "璇烽�夋嫨瀹夊叏璁炬柦", trigger: "change" }],
+  inspectionProject: [{ required: true, message: "璇疯緭鍏ュ贰妫�椤圭洰", trigger: "blur" }],
+  inspectorId: [{ required: true, message: "璇烽�夋嫨宸℃浜�", trigger: "change" }],
+  frequencyType: [{ required: true, message: "璇烽�夋嫨浠诲姟棰戠巼", trigger: "change" }],
+  frequencyDetail: [{ required: true, validator: validateFrequencyDetail, trigger: "change" }]
+};
 
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getFacilityStatusType = (status) => {
-  const map = {
-    '姝e父': 'success',
-    '寮傚父': 'danger',
-    '鍋滅敤': 'info'
+const inspectionRules = {
+  inspectionCode: [{ required: true, message: "璇疯緭鍏ュ贰妫�缂栧彿", trigger: "blur" }],
+  inspectionType: [{ required: true, message: "璇烽�夋嫨宸℃绫诲瀷", trigger: "change" }],
+  planTime: [{ required: true, message: "璇烽�夋嫨璁″垝宸℃鏃堕棿", trigger: "change" }],
+  checkResult: [{ required: true, message: "璇烽�夋嫨妫�鏌ョ粨鏋�", trigger: "change" }]
+};
+
+const rectificationRules = {
+  problemDesc: [{ required: true, message: "璇疯緭鍏ラ棶棰樻弿杩�", trigger: "blur" }],
+  problemLevel: [{ required: true, message: "璇烽�夋嫨闂绛夌骇", trigger: "change" }],
+  planTime: [{ required: true, message: "璇烽�夋嫨璁″垝鏁存敼鏃堕棿", trigger: "change" }],
+  rectifyUserId: [{ required: true, message: "璇烽�夋嫨鏁存敼璐d换浜�", trigger: "change" }],
+  verifyUserId: [{ required: true, message: "璇烽�夋嫨楠屾敹浜�", trigger: "change" }],
+  rectifyDesc: [{ required: true, message: "璇疯緭鍏ユ暣鏀硅鏄�", trigger: "blur" }],
+  verifyDesc: [{ 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: "",
+    status: "姝e父", remark: ""
+  },
+  ledgerDialogVisible: false,
+  ledgerDialogTitle: "",
+  ledgerDialogType: "add",
+  ledgerDetailVisible: false,
+  ledgerDetail: {},
+  // 宸℃浠诲姟
+  taskSearchForm: { inspectionName: "", facilityName: "", isEnabled: "" },
+  taskTableLoading: false,
+  taskPage: { current: 1, size: 20, total: 0 },
+  taskTableData: [],
+  taskSelectedIds: [],
+  taskForm: createTaskForm(),
+  taskDialogVisible: false,
+  taskDialogTitle: "鏂板宸℃浠诲姟",
+  taskDetailVisible: false,
+  taskDetail: {},
+  taskHistoryVisible: false,
+  taskHistoryTask: {},
+  taskHistoryTableLoading: false,
+  taskHistoryPage: { current: 1, size: 10, total: 0 },
+  taskHistoryTableData: [],
+  facilityOptions: [],
+  // 宸℃璁板綍
+  inspectionSearchForm: { inspectionCode: "", status: "" },
+  inspectionTableLoading: false,
+  inspectionPage: { current: 1, size: 20, total: 0 },
+  inspectionTableData: [],
+  inspectionForm: {
+    id: null, scheduleTaskId: null, facilityId: null, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
+    facilityCode: "", facilityName: "", inspectionProject: "", planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: []
+  },
+  inspectionDialogVisible: false,
+  inspectionDialogTitle: "",
+  inspectionDialogType: "do",
+  inspectionDetailVisible: false,
+  inspectionDetail: {},
+  // 鏁存敼璺熻釜
+  rectificationSearchForm: { status: "" },
+  rectificationTableLoading: false,
+  rectificationPage: { current: 1, size: 20, total: 0 },
+  rectificationTableData: [],
+  rectificationForm: {
+    id: null, inspectionId: null, facilityId: null, problemDesc: "",
+    problemLevel: "", rectifyUserId: "", rectifyUserName: "", verifyUserId: "",
+    verifyUserName: "", facilityName: "", facilityCode: "", inspectionCode: "",
+    planTime: "", actualTime: "", rectifyDesc: "", verifyTime: "", verifyDesc: "",
+    status: "", storageBlobVOs: []
+  },
+  rectificationDialogVisible: false,
+  rectificationDialogTitle: "",
+  rectificationDialogType: "add",
+  rectificationDetailVisible: false,
+  rectificationDetail: {}
+});
+
+const {
+  activeTab,
+  ledgerSearchForm, ledgerTableLoading, ledgerPage, ledgerTableData, ledgerSelectedIds,
+  ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType, ledgerDetailVisible, ledgerDetail,
+  taskSearchForm, taskTableLoading, taskPage, taskTableData, taskSelectedIds,
+  taskForm, taskDialogVisible, taskDialogTitle, taskDetailVisible, taskDetail,
+  taskHistoryVisible, taskHistoryTask, taskHistoryTableLoading, taskHistoryPage, taskHistoryTableData,
+  facilityOptions,
+  inspectionSearchForm, inspectionTableLoading, inspectionPage, inspectionTableData,
+  inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType, inspectionDetailVisible, inspectionDetail,
+  rectificationSearchForm, rectificationTableLoading, rectificationPage, rectificationTableData,
+  rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType,
+  rectificationDetailVisible, rectificationDetail
+} = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const ledgerFormRef = ref();
+const taskFormRef = ref();
+const inspectionFormRef = ref();
+const rectificationFormRef = ref();
+const isInspectionView = computed(() => inspectionDialogType.value === "view");
+const isInspectionBaseReadonly = computed(() => inspectionDialogType.value !== "add");
+const isRectificationView = computed(() => rectificationDialogType.value === "view");
+const isRectificationCreate = computed(() => rectificationDialogType.value === "add");
+const isRectificationFix = computed(() => rectificationDialogType.value === "do");
+const isRectificationVerify = computed(() => rectificationDialogType.value === "verify");
+const showRectifyDesc = computed(
+  () =>
+    isRectificationFix.value ||
+    isRectificationVerify.value ||
+    (isRectificationView.value && !!rectificationForm.value.rectifyDesc)
+);
+const showVerifyDesc = computed(
+  () =>
+    isRectificationVerify.value ||
+    (isRectificationView.value &&
+      (rectificationForm.value.status === "宸查獙鏀�" || !!rectificationForm.value.verifyDesc))
+);
+const showVerifyUser = computed(
+  () =>
+    isRectificationFix.value ||
+    isRectificationVerify.value ||
+    isRectificationView.value ||
+    !!rectificationForm.value.verifyUserId
+);
+const getAttachmentUrl = item => {
+  if (!item) return "";
+  if (typeof item === "string") return item;
+  return item.url || item.previewURL || item.previewUrl || item.downloadURL || "";
+};
+const rectificationInspectionImageUrls = computed(() => {
+  const list = rectificationForm.value.storageBlobVOs || rectificationForm.value.storageBlobDTOs || [];
+  return list.map(getAttachmentUrl).filter(Boolean);
+});
+const inspectionDetailImageUrls = computed(() => {
+  const list = inspectionDetail.value.storageBlobVOs || inspectionDetail.value.storageBlobDTOs || [];
+  return list.map(getAttachmentUrl).filter(Boolean);
+});
+const rectificationDetailImageUrls = computed(() => {
+  const list = rectificationDetail.value.storageBlobVOs || rectificationDetail.value.storageBlobDTOs || [];
+  return list.map(getAttachmentUrl).filter(Boolean);
+});
+
+const ledgerStatusType = value => {
+  const map = { 姝e父: "success", 寮傚父: "danger", 鎶ュ簾: "info" };
+  return map[value] || "info";
+};
+const inspectionResultType = value => {
+  const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+  return map[value || "鏈~鍐�"] || "info";
+};
+const inspectionStatusType = value => value === "寰呭贰妫�" ? "info" : "success";
+const rectificationLevelType = value => value === "閲嶅ぇ" ? "danger" : "warning";
+const rectificationStatusType = value => {
+  const map = { 寰呮暣鏀�: "danger", 鏁存敼涓�: "warning", 宸叉暣鏀�: "success", 宸查獙鏀�: "info" };
+  return map[value] || "info";
+};
+
+const padTime = value => String(value).padStart(2, "0");
+const formatDateTime = (date = new Date()) => {
+  const target = date instanceof Date ? date : new Date(date);
+  return `${target.getFullYear()}-${padTime(target.getMonth() + 1)}-${padTime(target.getDate())} ${padTime(target.getHours())}:${padTime(target.getMinutes())}:${padTime(target.getSeconds())}`;
+};
+const addDaysDateTime = days => {
+  const target = new Date();
+  target.setDate(target.getDate() + days);
+  target.setHours(18, 0, 0, 0);
+  return formatDateTime(target);
+};
+const getUserName = userId => {
+  const user = userList.value.find(item => Number(item.userId) === Number(userId));
+  return user?.nickName || "";
+};
+const formatFrequencyDetail = value => {
+  if (!value) return "--";
+  if (!value.includes(",")) return value;
+  const [firstPart, timePart] = value.split(",");
+  if (weekLabelMap[firstPart]) {
+    return `${weekLabelMap[firstPart]} ${timePart || ""}`.trim();
   }
-  return map[status] || 'info'
-}
-
-// 鑾峰彇璁炬柦鍒楄〃
-const fetchList = async () => {
-  try {
-    const params = {
-      ...searchForm,
-      current: pagination.currentPage,
-      size: pagination.pageSize
-    }
-    const res = await getSafetyFacilityList(params)
-    if (res.code === 200) {
-      facilityList.value = res.data.records || []
-      pagination.total = res.data.total || 0
-    } else {
-      ElMessage.error(res.message || '鑾峰彇鍒楄〃澶辫触')
-    }
-  } catch (error) {
-    ElMessage.error('鑾峰彇鍒楄〃澶辫触')
+  if (firstPart) {
+    return `${Number(firstPart)}鏃� ${timePart || ""}`.trim();
   }
-}
+  return value;
+};
+const isPendingInspection = row => row?.status === "寰呭贰妫�";
+const isCheckedInspection = row => row?.status === "宸插贰妫�";
+const isAbnormalInspection = row => row?.checkResult === "寮傚父";
+const isPendingRectification = row => row?.status === "寰呮暣鏀�" || row?.status === "鏁存敼涓�";
+const isRectified = row => row?.status === "宸叉暣鏀�";
+const isNotAssignedVerifier = row =>
+  row?.verifyUserId && Number(row.verifyUserId) !== Number(currentUserId.value);
 
-// 鑾峰彇璁惧鍒楄〃
-const fetchDeviceOptions = async () => {
-  try {
-    const res = await getDeviceLedger()
-    if (res.code === 200) {
-      deviceOptions.value = res.data || []
+provide("parentMethods", {
+  openLedgerDetail: row => openLedgerDetail(row),
+  openTaskDetail: row => openTaskDetail(row),
+  openInspectionDetail: row => openInspectionDetail(row)
+});
+
+// 璁炬柦鍙拌处琛ㄦ牸鍒楅厤缃�
+const ledgerTableColumn = ref([
+  {
+    label: "璁炬柦缂栧彿",
+    prop: "facilityCode",
+    dataType: "link",
+    linkMethod: "openLedgerDetail",
+    showOverflowTooltip: true,
+    minWidth: 120,
+    align: "center",
+  },
+  { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 , align: "center"},
+  { label: "璁炬柦绫诲瀷", prop: "facilityType", showOverflowTooltip: true, minWidth: 120 , align: "center"},
+  { label: "瀹夎浣嶇疆", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 , align: "center"},
+  { label: "瀹夎鏃堕棿", prop: "installTime", minWidth: 120 , align: "center"},
+  {
+    label: "鐘舵��", prop: "status", minWidth: 100, dataType: "tag", align: "center",
+    formatType: params => {
+      const map = { 姝e父: "success", 寮傚父: "danger", 鎶ュ簾: "info" };
+      return map[params] || "info";
     }
-  } catch (error) {
-    console.error('鑾峰彇璁惧鍒楄〃澶辫触')
+  },
+  {
+    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 140,
+    operation: [
+      { name: "缂栬緫", type: "text", clickFun: row => openLedgerForm("edit", row) },
+      { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteLedger(row) }
+    ]
   }
-}
+]);
 
-// 鎼滅储
-const handleSearch = () => {
-  pagination.currentPage = 1
-  fetchList()
-}
+// 宸℃浠诲姟琛ㄦ牸鍒楅厤缃�
+const taskTableColumn = ref([
+  {
+    label: "宸℃浠诲姟鍚嶇О",
+    prop: "inspectionName",
+    dataType: "link",
+    linkMethod: "openTaskDetail",
+    showOverflowTooltip: true,
+    minWidth: 170,
+    align: "left"
+  },
+  { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 155, align: "left" },
+  { label: "宸℃椤圭洰", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 190, align: "left" },
+  { label: "鎵ц宸℃浜�", prop: "inspectorName", minWidth: 120, align: "center" },
+  {
+    label: "鏄惁鍚敤",
+    prop: "isEnabled",
+    minWidth: 90,
+    align: "center",
+    dataType: "tag",
+    formatData: value => value === 1 ? "鏄�" : "鍚�",
+    formatType: value => value === 1 ? "success" : "info"
+  },
+  {
+    label: "棰戞",
+    prop: "frequencyType",
+    minWidth: 90,
+    align: "center",
+    formatData: value => frequencyTypeMap[value] || value || "--"
+  },
+  {
+    label: "鎵ц鏃堕棿",
+    prop: "frequencyDetail",
+    minWidth: 120,
+    align: "center",
+    formatData: value => formatFrequencyDetail(value)
+  },
+  { label: "涓嬫鎵ц鏃堕棿", prop: "nextExecutionTime", minWidth: 170, showOverflowTooltip: true, align: "center" },
+  {
+    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 220,
+    operation: [
+      { name: "鍘嗗彶宸℃", type: "text", clickFun: row => openTaskHistory(row) },
+      { name: "缂栬緫", type: "text", clickFun: row => openTaskDialog("edit", row) },
+      { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteTask(row) }
+    ]
+  }
+]);
 
-// 閲嶇疆鎼滅储
-const resetSearch = () => {
-  Object.assign(searchForm, {
-    facilityName: '',
-    facilityType: '',
-    status: ''
-  })
-  handleSearch()
-}
-
-// 鏂板
-const handleAdd = () => {
-  dialogTitle.value = '鏂板璁炬柦'
-  Object.assign(form, {
-    id: null,
-    facilityName: '',
-    facilityType: '',
-    location: '',
-    deviceId: null,
-    responsibilityDept: '',
-    responsibilityPerson: '',
-    nextInspectionTime: '',
-    remarks: ''
-  })
-  showDialog.value = true
-}
-
-// 缂栬緫
-const handleEdit = (row) => {
-  dialogTitle.value = '缂栬緫璁炬柦'
-  Object.assign(form, {
-    id: row.id,
-    facilityName: row.facilityName,
-    facilityType: row.facilityType,
-    location: row.location,
-    deviceId: row.deviceId,
-    responsibilityDept: row.responsibilityDept,
-    responsibilityPerson: row.responsibilityPerson,
-    nextInspectionTime: row.nextInspectionTime,
-    remarks: row.remarks
-  })
-  showDialog.value = true
-}
-
-// 宸℃
-const handleInspection = (row) => {
-  Object.assign(inspectionForm, {
-    id: row.id,
-    facilityName: row.facilityName,
-    status: '姝e父',
-    description: ''
-  })
-  showInspectionDialog.value = true
-}
-
-// 鍒犻櫎
-const handleDelete = async (row) => {
-  try {
-    await ElMessageBox.confirm('纭鍒犻櫎璇ヨ鏂藉悧锛�', '鎻愮ず', {
-      type: 'warning'
-    })
-    const res = await deleteSafetyFacility([row.id])
-    if (res.code === 200) {
-      ElMessage.success('鍒犻櫎鎴愬姛')
-      fetchList()
-    } else {
-      ElMessage.error(res.message || '鍒犻櫎澶辫触')
+const taskHistoryTableColumn = ref([
+  {
+    label: "宸℃缂栧彿",
+    prop: "inspectionCode",
+    dataType: "link",
+    linkMethod: "openInspectionDetail",
+    showOverflowTooltip: true,
+    minWidth: 180,
+    align: "center"
+  },
+  { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150, align: "left" },
+  { label: "宸℃椤圭洰", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 180, align: "left" },
+  { label: "璁″垝宸℃鏃堕棿", prop: "planTime", minWidth: 170, align: "center" },
+  { label: "宸℃浜�", prop: "inspectorName", minWidth: 110, align: "center" },
+  { label: "瀹為檯宸℃鏃堕棿", prop: "actualTime", minWidth: 170, align: "center" },
+  {
+    label: "妫�鏌ョ粨鏋�", prop: "checkResult", minWidth: 100, align: "center", dataType: "tag",
+    formatData: params => params || "鏈~鍐�",
+    formatType: params => {
+      const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+      return map[params] || "info";
     }
-  } catch (error) {
-    // 鍙栨秷鍒犻櫎
+  },
+  {
+    label: "鐘舵��", prop: "status", minWidth: 100, align: "center", dataType: "tag",
+    formatType: params => params === "寰呭贰妫�" ? "info" : "success"
   }
-}
+]);
 
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
-  if (!formRef.value) return
-  try {
-    await formRef.value.validate()
-    const res = await addOrEditSafetyFacility(form)
-    if (res.code === 200) {
-      ElMessage.success('鎿嶄綔鎴愬姛')
-      showDialog.value = false
-      fetchList()
-    } else {
-      ElMessage.error(res.message || '鎿嶄綔澶辫触')
+// 宸℃璁板綍琛ㄦ牸鍒楅厤缃�
+const inspectionTableColumn = ref([
+  {
+    label: "宸℃缂栧彿",
+    dataType: "link",
+    linkMethod: "openInspectionDetail",
+    width: 200,
+    align: "center",
+    prop: "inspectionCode",
+    showOverflowTooltip: true,
+    minWidth: 150
+  },
+  {
+    label: "璁炬柦鍚嶇О",
+    prop: "facilityName",
+    showOverflowTooltip: true,
+    minWidth: 150
+  },
+  {
+    label: "宸℃椤圭洰",
+    prop: "inspectionProject",
+    showOverflowTooltip: true,
+    minWidth: 180
+  },
+  {
+    label: "璁″垝宸℃鏃堕棿",
+    prop: "planTime",
+    minWidth: 180
+  },
+  {
+    label: "宸℃浜�",
+    prop: "inspectorName",
+    minWidth: 100
+  },
+  {
+    label: "瀹為檯宸℃鏃堕棿",
+    prop: "actualTime",
+    minWidth: 180
+  },
+  {
+    label: "妫�鏌ョ粨鏋�", prop: "checkResult", minWidth: 100, dataType: "tag",
+    formatData: params => params || "鏈~鍐�",
+    formatType: params => {
+      const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+      return map[params] || "info";
     }
-  } catch (error) {
-    ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�')
+  },
+  {
+    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: isPendingInspection
+      },
+      {
+        name: "鏌ョ湅", type: "text",
+        clickFun: row => openInspectionDetail(row),
+        show: isCheckedInspection
+      },
+      {
+        name: "鏁存敼", type: "text",
+        clickFun: row => openRectificationFromInspection(row),
+        show: row => isCheckedInspection(row) && isAbnormalInspection(row)
+      },
+      { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteInspection(row), show: isPendingInspection }
+    ]
   }
-}
+]);
 
-// 鎻愪氦宸℃缁撴灉
-const submitInspection = async () => {
-  try {
-    const data = {
-      id: inspectionForm.id,
-      status: inspectionForm.status,
-      lastInspectionTime: new Date().toISOString()
+// 鏁存敼璺熻釜琛ㄦ牸鍒楅厤缃�
+const rectificationTableColumn = ref([
+  { label: "宸℃缂栧彿", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
+  { 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";
     }
-    const res = await addOrEditSafetyFacility(data)
-    if (res.code === 200) {
-      ElMessage.success('宸℃璁板綍鎴愬姛')
-      showInspectionDialog.value = false
-      fetchList()
-    } else {
-      ElMessage.error(res.message || '鎿嶄綔澶辫触')
-    }
-  } catch (error) {
-    ElMessage.error('鎿嶄綔澶辫触')
+  },
+  {
+    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 180,
+    operation: [
+      {
+        name: "鏁存敼", type: "text",
+        clickFun: row => openRectificationForm("do", row),
+        show: isPendingRectification
+      },
+      {
+        name: "楠屾敹", type: "text",
+        clickFun: row => openRectificationForm("verify", row),
+        show: isRectified,
+        disabled: isNotAssignedVerifier
+      },
+      { name: "鏌ョ湅", type: "text", clickFun: row => openRectificationDetail(row) }
+    ]
   }
-}
+]);
 
-// 瀵煎嚭
-const handleExport = async () => {
-  try {
-    const res = await exportSafetyFacility(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()
-  fetchDeviceOptions()
-})
+  getLedgerList();
+  getTaskList();
+  getInspectionList();
+  getRectificationList();
+  getFacilityOptionList();
+  getUserList();
+});
+
+// 鏍囩椤靛垏鎹�
+const handleTabClick = () => {
+  if (activeTab.value === "ledger") getLedgerList();
+  else if (activeTab.value === "task") getTaskList();
+  else if (activeTab.value === "inspection") getInspectionList();
+  else if (activeTab.value === "rectification") getRectificationList();
+};
+
+const getUserList = () => {
+  userListNoPage().then(res => {
+    userList.value = res.data || [];
+  });
+};
+
+const getFacilityOptionList = () => {
+  getFacilityLedgerList({ current: 1, size: 1000 }).then(res => {
+    facilityOptions.value = (res.data?.records || []).filter(item => item.status !== "鎶ュ簾");
+  });
+};
+
+// ============ 璁炬柦鍙拌处鏂规硶 ============
+
+const handleLedgerQuery = () => {
+  ledgerPage.value.current = 1;
+  getLedgerList();
+};
+
+const resetLedgerQuery = () => {
+  Object.assign(ledgerSearchForm.value, {
+    facilityCode: "",
+    facilityName: "",
+    facilityType: "",
+    status: ""
+  });
+  handleLedgerQuery();
+};
+
+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 || 0;
+    })
+    .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 openLedgerDetail = row => {
+  ledgerDetail.value = { ...row };
+  ledgerDetailVisible.value = true;
+};
+
+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: "",
+      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();
+      getFacilityOptionList();
+    } 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();
+      getFacilityOptionList();
+    } else {
+      ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+    }
+  }).catch(() => {});
+};
+
+const handleBatchDeleteLedger = () => {
+  if (ledgerSelectedIds.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑璁炬柦");
+    return;
+  }
+  ElMessageBox.confirm("纭鍒犻櫎閫変腑鐨勮鏂藉悧锛熷凡浜х敓宸℃璁板綍鐨勮鏂戒笉浼氳鍚庣鍏佽鍒犻櫎銆�", "鎵归噺鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    const res = await deleteFacilityLedger(ledgerSelectedIds.value);
+    if (res.code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      ledgerSelectedIds.value = [];
+      getLedgerList();
+      getFacilityOptionList();
+    } else {
+      ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+    }
+  }).catch(() => {});
+};
+
+// ============ 宸℃浠诲姟鏂规硶 ============
+
+const handleTaskQuery = () => {
+  taskPage.value.current = 1;
+  getTaskList();
+};
+
+const resetTaskQuery = () => {
+  Object.assign(taskSearchForm.value, {
+    inspectionName: "",
+    facilityName: "",
+    isEnabled: ""
+  });
+  handleTaskQuery();
+};
+
+const getTaskList = () => {
+  taskTableLoading.value = true;
+  getFacilityInspectionTaskList({ ...taskPage.value, ...taskSearchForm.value })
+    .then(res => {
+      taskTableLoading.value = false;
+      taskTableData.value = res.data?.records || [];
+      taskPage.value.total = res.data?.total || 0;
+    })
+    .catch(() => { taskTableLoading.value = false; });
+};
+
+const taskPagination = obj => {
+  taskPage.value.current = obj.page;
+  taskPage.value.size = obj.limit;
+  getTaskList();
+};
+
+const handleTaskSelectionChange = selection => {
+  taskSelectedIds.value = selection.map(item => item.id);
+};
+
+const openTaskDetail = row => {
+  taskDetail.value = { ...row };
+  taskDetailVisible.value = true;
+};
+
+const openTaskDialog = (type, row = null) => {
+  resetTaskForm();
+  taskDialogTitle.value = type === "add" ? "鏂板宸℃浠诲姟" : "缂栬緫宸℃浠诲姟";
+  if (type === "edit" && row) {
+    Object.assign(taskForm.value, {
+      id: row.id,
+      inspectionName: row.inspectionName,
+      facilityId: row.facilityId,
+      facilityCode: row.facilityCode,
+      facilityName: row.facilityName,
+      inspectionProject: row.inspectionProject,
+      inspectorId: row.inspectorId,
+      frequencyType: row.frequencyType,
+      frequencyDetail: row.frequencyDetail,
+      isEnabled: row.isEnabled ?? ENABLED,
+      remark: row.remark
+    });
+    parseFrequencyDetail(row.frequencyType, row.frequencyDetail);
+  }
+  taskDialogVisible.value = true;
+};
+
+const resetTaskForm = () => {
+  Object.assign(taskForm.value, createTaskForm());
+  taskFormRef.value?.clearValidate?.();
+};
+
+const handleTaskFacilityChange = facilityId => {
+  const facility = facilityOptions.value.find(item => Number(item.id) === Number(facilityId));
+  taskForm.value.facilityCode = facility?.facilityCode || "";
+  taskForm.value.facilityName = facility?.facilityName || "";
+};
+
+const handleFrequencyTypeChange = () => {
+  Object.assign(taskForm.value, { frequencyDetail: "", week: "", day: "", time: "" });
+  taskFormRef.value?.clearValidate?.("frequencyDetail");
+};
+
+const parseFrequencyDetail = (frequencyType, frequencyDetail) => {
+  if (!frequencyDetail) return;
+  if (frequencyType === "DAILY") {
+    taskForm.value.frequencyDetail = frequencyDetail;
+    return;
+  }
+  const [firstPart, timePart] = frequencyDetail.split(",");
+  taskForm.value.frequencyDetail = "";
+  taskForm.value.time = timePart || "";
+  if (frequencyType === "WEEKLY") {
+    taskForm.value.week = firstPart || "";
+  }
+  if (frequencyType === "MONTHLY") {
+    taskForm.value.day = String(firstPart || "").padStart(2, "0");
+  }
+};
+
+const buildFrequencyDetail = () => {
+  if (taskForm.value.frequencyType === "DAILY") {
+    return taskForm.value.frequencyDetail;
+  }
+  if (taskForm.value.frequencyType === "WEEKLY") {
+    return `${taskForm.value.week},${taskForm.value.time}`;
+  }
+  if (taskForm.value.frequencyType === "MONTHLY") {
+    return `${taskForm.value.day},${taskForm.value.time}`;
+  }
+  return "";
+};
+
+const submitTaskForm = async () => {
+  try {
+    await taskFormRef.value.validate();
+    const payload = {
+      id: taskForm.value.id,
+      inspectionName: taskForm.value.inspectionName,
+      facilityId: taskForm.value.facilityId,
+      facilityCode: taskForm.value.facilityCode,
+      facilityName: taskForm.value.facilityName,
+      inspectionProject: taskForm.value.inspectionProject,
+      inspectorId: taskForm.value.inspectorId,
+      frequencyType: taskForm.value.frequencyType,
+      frequencyDetail: buildFrequencyDetail(),
+      isEnabled: taskForm.value.isEnabled,
+      remark: taskForm.value.remark
+    };
+    const api = payload.id ? updateFacilityInspectionTask : addFacilityInspectionTask;
+    const res = await api(payload);
+    if (res.code === 200) {
+      ElMessage.success(payload.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      taskDialogVisible.value = false;
+      activeTab.value = "task";
+      getTaskList();
+    } else {
+      ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+    }
+  } catch (error) {
+    console.error("浠诲姟琛ㄥ崟鏍¢獙澶辫触:", error);
+  }
+};
+
+const handleDeleteTask = row => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ュ畾鏃跺贰妫�浠诲姟鍚楋紵", "鍒犻櫎", {
+    confirmButtonText: "纭", cancelButtonText: "鍙栨秷", type: "warning"
+  }).then(async () => {
+    const res = await deleteFacilityInspectionTask([row.id]);
+    if (res.code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      getTaskList();
+    } else {
+      ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+    }
+  }).catch(() => {});
+};
+
+const handleBatchDeleteTask = () => {
+  if (taskSelectedIds.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑宸℃浠诲姟");
+    return;
+  }
+  ElMessageBox.confirm("纭鍒犻櫎閫変腑鐨勫畾鏃跺贰妫�浠诲姟鍚楋紵", "鎵归噺鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(async () => {
+    const res = await deleteFacilityInspectionTask(taskSelectedIds.value);
+    if (res.code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      taskSelectedIds.value = [];
+      getTaskList();
+    } else {
+      ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+    }
+  }).catch(() => {});
+};
+
+const openTaskHistory = row => {
+  taskHistoryTask.value = { ...row };
+  taskHistoryPage.value.current = 1;
+  taskHistoryVisible.value = true;
+  getTaskHistoryList();
+};
+
+const getTaskHistoryList = () => {
+  if (!taskHistoryTask.value?.id) {
+    taskHistoryTableData.value = [];
+    taskHistoryPage.value.total = 0;
+    return;
+  }
+  taskHistoryTableLoading.value = true;
+  getFacilityInspectionList({
+    current: taskHistoryPage.value.current,
+    size: taskHistoryPage.value.size,
+    scheduleTaskId: taskHistoryTask.value.id
+  })
+    .then(res => {
+      taskHistoryTableLoading.value = false;
+      taskHistoryTableData.value = res.data?.records || [];
+      taskHistoryPage.value.total = res.data?.total || 0;
+    })
+    .catch(() => { taskHistoryTableLoading.value = false; });
+};
+
+const taskHistoryPagination = obj => {
+  taskHistoryPage.value.current = obj.page;
+  taskHistoryPage.value.size = obj.limit;
+  getTaskHistoryList();
+};
+
+// ============ 宸℃璁板綍鏂规硶 ============
+
+const handleInspectionQuery = () => {
+  inspectionPage.value.current = 1;
+  getInspectionList();
+};
+
+const resetInspectionQuery = () => {
+  Object.assign(inspectionSearchForm.value, {
+    inspectionCode: "",
+    status: ""
+  });
+  handleInspectionQuery();
+};
+
+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 || 0;
+    })
+    .catch(() => { inspectionTableLoading.value = false; });
+};
+
+const inspectionPagination = obj => {
+  inspectionPage.value.current = obj.page;
+  inspectionPage.value.size = obj.limit;
+  getInspectionList();
+};
+
+const openInspectionDetail = row => {
+  inspectionDetail.value = {
+    ...row,
+    storageBlobDTOs: row.storageBlobVOs || row.storageBlobDTOs || []
+  };
+  inspectionDetailVisible.value = true;
+};
+
+const openInspectionForm = (type, row = null) => {
+  if (type === "view") {
+    openInspectionDetail(row);
+    return;
+  }
+  inspectionDialogType.value = type;
+  if (type === "do") {
+    inspectionDialogTitle.value = "宸℃";
+    Object.assign(inspectionForm.value, {
+      id: row.id,
+      scheduleTaskId: row.scheduleTaskId,
+      facilityId: row.facilityId,
+      facilityCode: row.facilityCode,
+      facilityName: row.facilityName,
+      inspectionCode: row.inspectionCode,
+      inspectionType: row.inspectionType,
+      inspectionProject: row.inspectionProject,
+      planTime: row.planTime,
+      checkResult: "",
+      checkDesc: "",
+      storageBlobDTOs: []
+    });
+  }
+  inspectionDialogVisible.value = true;
+};
+
+const submitInspectionForm = async () => {
+  try {
+    await inspectionFormRef.value.validate();
+    if (inspectionDialogType.value === "do") {
+      if (!inspectionForm.value.checkResult) {
+        ElMessage.warning("璇烽�夋嫨妫�鏌ョ粨鏋�");
+        return;
+      }
+      if (inspectionForm.value.checkResult === "寮傚父" && !inspectionForm.value.checkDesc) {
+        ElMessage.warning("妫�鏌ョ粨鏋滃紓甯告椂璇峰~鍐欐鏌ヨ鏄�");
+        return;
+      }
+      if (inspectionForm.value.checkResult === "寮傚父" && !hasAttachments(inspectionForm.value.storageBlobDTOs)) {
+        ElMessage.warning("妫�鏌ョ粨鏋滃紓甯告椂璇蜂笂浼犵幇鍦虹収鐗�");
+        return;
+      }
+      inspectionForm.value.status = "宸插贰妫�";
+      inspectionForm.value.actualTime = formatDateTime();
+    }
+    const res = await updateFacilityInspection({ ...inspectionForm.value });
+    if (res.code === 200) {
+      ElMessage.success("鎿嶄綔鎴愬姛");
+      inspectionDialogVisible.value = false;
+      getInspectionList();
+      if (inspectionDialogType.value === "do" && inspectionForm.value.checkResult === "寮傚父") {
+        ElMessageBox.confirm("鏈宸℃缁撴灉涓哄紓甯革紝鏄惁绔嬪嵆鍒涘缓鏁存敼璺熻釜锛�", "鍒涘缓鏁存敼", {
+          confirmButtonText: "鍒涘缓鏁存敼",
+          cancelButtonText: "绋嶅悗澶勭悊",
+          type: "warning"
+        }).then(() => {
+          openRectificationFromInspection({ ...inspectionForm.value });
+        }).catch(() => {});
+      }
+    } else {
+      ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+    }
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+const hasAttachments = attachments => Array.isArray(attachments) && attachments.length > 0;
+
+const handleDeleteInspection = row => {
+  ElMessageBox.confirm("纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵", "鍒犻櫎", {
+    confirmButtonText: "纭", cancelButtonText: "鍙栨秷", type: "warning"
+  }).then(async () => {
+    const res = await deleteFacilityInspection([row.id]);
+    if (res.code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      getInspectionList();
+    } else {
+      ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+    }
+  }).catch(() => {});
+};
+
+// ============ 鏁存敼璺熻釜鏂规硶 ============
+
+const handleRectificationQuery = () => {
+  rectificationPage.value.current = 1;
+  getRectificationList();
+};
+
+const resetRectificationQuery = () => {
+  Object.assign(rectificationSearchForm.value, {
+    status: ""
+  });
+  handleRectificationQuery();
+};
+
+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 || 0;
+    })
+    .catch(() => { rectificationTableLoading.value = false; });
+};
+
+const rectificationPagination = obj => {
+  rectificationPage.value.current = obj.page;
+  rectificationPage.value.size = obj.limit;
+  getRectificationList();
+};
+
+const getExistingRectification = async inspectionId => {
+  if (!inspectionId) return null;
+  const res = await getFacilityRectificationList({ current: 1, size: 1, inspectionId });
+  return res.data?.records?.[0] || null;
+};
+
+const getRectificationDialogType = row => {
+  if (isPendingRectification(row)) return "do";
+  if (isRectified(row)) return "verify";
+  return "view";
+};
+
+const openRectificationDetail = row => {
+  rectificationDetail.value = {
+    ...row,
+    storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
+  };
+  rectificationDetailVisible.value = true;
+};
+
+const openRectificationFromInspection = async row => {
+  const existing = await getExistingRectification(row.id);
+  activeTab.value = "rectification";
+  if (existing) {
+    ElMessage.info("璇ュ贰妫�宸插瓨鍦ㄦ暣鏀硅褰曪紝宸蹭负浣犳墦寮�瀵瑰簲澶勭悊绐楀彛");
+    existing.inspectionCode = existing.inspectionCode || row.inspectionCode;
+    existing.facilityCode = existing.facilityCode || row.facilityCode;
+    existing.facilityName = existing.facilityName || row.facilityName;
+    openRectificationForm(getRectificationDialogType(existing), existing);
+    return;
+  }
+  openRectificationForm("add", row);
+};
+
+const openRectificationForm = (type, row = null) => {
+  if (type === "view") {
+    openRectificationDetail(row);
+    return;
+  }
+  rectificationDialogType.value = type;
+  if (type === "add") {
+    rectificationDialogTitle.value = "鏂板鏁存敼";
+    Object.assign(rectificationForm.value, {
+      id: null,
+      inspectionId: row.id,
+      facilityId: row.facilityId,
+      facilityName: row.facilityName || "",
+      facilityCode: row.facilityCode || "",
+      inspectionCode: row.inspectionCode || "",
+      problemDesc: row.checkDesc || "",
+      problemLevel: "涓�鑸�",
+      rectifyUserId: currentUserId.value || "",
+      rectifyUserName: getUserName(currentUserId.value),
+      verifyUserId: "",
+      verifyUserName: "",
+      planTime: addDaysDateTime(1),
+      actualTime: "",
+      rectifyDesc: "",
+      verifyTime: "",
+      verifyDesc: "",
+      status: "寰呮暣鏀�",
+      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
+    });
+  } else if (type === "do") {
+    rectificationDialogTitle.value = "鏁存敼";
+    Object.assign(rectificationForm.value, {
+      ...row,
+      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
+      rectifyDesc: row.rectifyDesc || "",
+      verifyDesc: row.verifyDesc || ""
+    });
+  } else if (type === "verify") {
+    rectificationDialogTitle.value = "楠屾敹";
+    Object.assign(rectificationForm.value, {
+      ...row,
+      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
+      verifyDesc: row.verifyDesc || ""
+    });
+  } else {
+    rectificationDialogTitle.value = "鏌ョ湅鏁存敼";
+    Object.assign(rectificationForm.value, {
+      ...row,
+      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
+    });
+  }
+  rectificationDialogVisible.value = true;
+};
+
+const buildRectificationPayload = () => {
+  const {
+    id,
+    inspectionId,
+    facilityId,
+    problemDesc,
+    problemLevel,
+    problemImage,
+    rectifyUserId,
+    planTime,
+    actualTime,
+    rectifyDesc,
+    rectifyImage,
+    status,
+    verifyUserId,
+    verifyTime,
+    verifyDesc
+  } = rectificationForm.value;
+  return {
+    id,
+    inspectionId,
+    facilityId,
+    problemDesc,
+    problemLevel,
+    problemImage,
+    rectifyUserId,
+    planTime,
+    actualTime,
+    rectifyDesc,
+    rectifyImage,
+    status,
+    verifyUserId,
+    verifyTime,
+    verifyDesc
+  };
+};
+
+const submitRectificationForm = async () => {
+  if (rectificationDialogType.value === "view") {
+    rectificationDialogVisible.value = false;
+    return;
+  }
+  try {
+    await rectificationFormRef.value.validate();
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+    return;
+  }
+  if (rectificationDialogType.value === "do") {
+    rectificationForm.value.status = "宸叉暣鏀�";
+    rectificationForm.value.actualTime = formatDateTime();
+  } else if (rectificationDialogType.value === "verify") {
+    rectificationForm.value.status = "宸查獙鏀�";
+    rectificationForm.value.verifyTime = formatDateTime();
+  }
+  const api = rectificationForm.value.id ? updateFacilityRectification : addFacilityRectification;
+  const res = await api(buildRectificationPayload());
+  if (res.code === 200) {
+    ElMessage.success("鎿嶄綔鎴愬姛");
+    rectificationDialogVisible.value = false;
+    getRectificationList();
+    getInspectionList();
+  } else {
+    ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+  }
+};
 </script>
 
 <style scoped>
-.safety-facility {
-  padding: 20px;
+.safety-facility-page {
+  padding-top: 4px;
 }
 
-.search-area {
-  background: #f5f7fa;
-  padding: 20px;
-  border-radius: 4px;
-  margin-bottom: 15px;
+.facility-tabs {
+  width: 100%;
 }
 
-.actions {
-  margin-bottom: 15px;
+.facility-tabs :deep(.el-tabs__header) {
+  margin-bottom: 18px;
 }
 
-.pagination {
-  margin-top: 20px;
+.facility-tabs :deep(.el-tabs__nav-wrap::after) {
+  height: 1px;
+  background-color: #d8e2ef;
+}
+
+.facility-toolbar {
   display: flex;
-  justify-content: flex-end;
+  align-items: center;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  gap: 14px 18px;
+  min-height: 44px;
+  margin-bottom: 18px;
+}
+
+.toolbar-filters,
+.toolbar-actions {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 10px 12px;
+}
+
+.toolbar-actions {
+  margin-left: auto;
+}
+
+.table_list {
+  padding-top: 6px;
+}
+
+.history-summary {
+  margin-bottom: 16px;
+}
+
+.table_list :deep(.link) {
+  color: var(--el-color-primary);
+  cursor: pointer;
+  font-weight: 600;
+}
+
+.table_list :deep(.link:hover) {
+  text-decoration: underline;
+}
+
+.search_title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #606266;
+  white-space: nowrap;
+}
+
+.mb20 {
+  margin-bottom: 20px;
+}
+
+.ml10 {
+  margin-left: 10px;
+}
+
+.toolbar-filters .ml10 {
+  margin-left: 0;
+}
+
+.facility-form-dialog :deep(.el-dialog__body) {
+  padding: 24px 32px 10px;
+}
+
+.facility-form-dialog :deep(.el-dialog__footer) {
+  padding: 8px 32px 26px;
+}
+
+.dialog-summary {
+  display: grid;
+  grid-template-columns: repeat(2, minmax(0, 1fr));
+  gap: 12px;
+  margin-bottom: 20px;
+  padding: 14px 18px;
+  border: 1px solid #e4eaf3;
+  border-radius: 6px;
+  background: #f7faff;
+}
+
+.summary-item {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  min-width: 0;
+}
+
+.summary-item span {
+  flex: 0 0 auto;
+  color: #7a8599;
+}
+
+.summary-item strong {
+  min-width: 0;
+  overflow: hidden;
+  color: #25324b;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.inspection-form-grid {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr) minmax(220px, 0.8fr);
+  column-gap: 20px;
+}
+
+.inspection-form-grid .form-grid-full {
+  grid-column: 1 / -1;
+}
+
+.inspection-form :deep(.el-form-item) {
+  margin-bottom: 20px;
+}
+
+.inspection-form :deep(.el-form-item__label) {
+  margin-bottom: 8px;
+  padding: 0;
+  font-weight: 600;
+  color: #25324b;
+  line-height: 1.2;
+}
+
+.rectification-image-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.rectification-image {
+  width: 96px;
+  height: 96px;
+  border: 1px solid #dbe4f0;
+  border-radius: 6px;
+  background: #f8fafc;
+}
+
+.detail-dialog :deep(.el-dialog__body) {
+  padding: 24px 32px 8px;
+}
+
+.detail-dialog :deep(.el-descriptions__label) {
+  width: 130px;
+  color: #4d5b73;
+  font-weight: 600;
+  background: #f4f7fb;
+}
+
+.detail-dialog :deep(.el-descriptions__content) {
+  color: #25324b;
+  word-break: break-word;
+}
+
+.detail-section {
+  margin-top: 18px;
+}
+
+.detail-section-title {
+  margin-bottom: 10px;
+  color: #25324b;
+  font-weight: 600;
+}
+
+.detail-image-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.detail-image {
+  width: 96px;
+  height: 96px;
+  border: 1px solid #dbe4f0;
+  border-radius: 6px;
+  background: #f8fafc;
+}
+
+.frequency-row {
+  display: flex;
+  width: 100%;
+  align-items: center;
+  gap: 12px;
+}
+
+.frequency-time-picker {
+  min-width: 0;
+  flex: 1;
+}
+
+.frequency-day-select {
+  flex: 0 0 132px;
+  width: 132px;
+}
+
+@media (max-width: 900px) {
+  .inspection-form-grid,
+  .dialog-summary {
+    grid-template-columns: 1fr;
+  }
 }
 </style>

--
Gitblit v1.9.3