From 6f1acfd2086a1f8c2cb80afd3db4e534e44d545e Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 14 八月 2026 10:33:51 +0800
Subject: [PATCH] fix: 报工明细创建日期格式化

---
 src/views/safeProduction/safetyFacility/index.vue | 1755 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 1,572 insertions(+), 183 deletions(-)

diff --git a/src/views/safeProduction/safetyFacility/index.vue b/src/views/safeProduction/safetyFacility/index.vue
index f1f8b56..3f81c80 100644
--- a/src/views/safeProduction/safetyFacility/index.vue
+++ b/src/views/safeProduction/safetyFacility/index.vue
@@ -1,10 +1,12 @@
 <template>
-  <div class="app-container">
-    <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+  <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="search_form mb20">
-          <div>
+        <div class="facility-toolbar">
+          <div class="toolbar-filters">
             <span class="search_title">璁炬柦缂栧彿锛�</span>
             <el-input v-model="ledgerSearchForm.facilityCode"
                       style="width: 200px"
@@ -39,12 +41,16 @@
               <el-option label="鎶ュ簾" value="鎶ュ簾" />
             </el-select>
             <el-button type="primary"
-                       @click="handleLedgerQuery"
-                       style="margin-left: 10px">
+                       @click="handleLedgerQuery">
               鎼滅储
             </el-button>
+            <el-button @click="resetLedgerQuery">閲嶇疆</el-button>
           </div>
-          <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>
@@ -63,10 +69,65 @@
         </div>
       </el-tab-pane>
 
-      <!-- 瀹夊叏璁炬柦宸℃ -->
-      <el-tab-pane label="瀹夊叏璁炬柦宸℃" name="inspection">
-        <div class="search_form mb20">
-          <div>
+      <!-- 宸℃浠诲姟 -->
+      <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="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-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"
@@ -83,10 +144,10 @@
               <el-option label="宸插贰妫�" value="宸插贰妫�" />
             </el-select>
             <el-button type="primary"
-                       @click="handleInspectionQuery"
-                       style="margin-left: 10px">
+                       @click="handleInspectionQuery">
               鎼滅储
             </el-button>
+            <el-button @click="resetInspectionQuery">閲嶇疆</el-button>
           </div>
         </div>
 
@@ -104,8 +165,8 @@
 
       <!-- 鏁存敼璺熻釜 -->
       <el-tab-pane label="鏁存敼璺熻釜" name="rectification">
-        <div class="search_form mb20">
-          <div>
+        <div class="facility-toolbar">
+          <div class="toolbar-filters">
             <span class="search_title">鐘舵�侊細</span>
             <el-select v-model="rectificationSearchForm.status"
                        clearable
@@ -117,10 +178,10 @@
               <el-option label="宸查獙鏀�" value="宸查獙鏀�" />
             </el-select>
             <el-button type="primary"
-                       @click="handleRectificationQuery"
-                       style="margin-left: 10px">
+                       @click="handleRectificationQuery">
               鎼滅储
             </el-button>
+            <el-button @click="resetRectificationQuery">閲嶇疆</el-button>
           </div>
         </div>
 
@@ -217,22 +278,6 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="鏈夋晥鏈�(澶�)"
-                          prop="validPeriod">
-              <el-input-number v-model="ledgerForm.validPeriod"
-                               :min="0"
-                               placeholder="璇疯緭鍏ユ湁鏁堟湡"
-                               style="width: 100%" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="涓嬫妫�鏌ユ椂闂�">
-              <el-input :value="computedNextCheckTime" disabled placeholder="鏍规嵁瀹夎鏃堕棿+鏈夋晥鏈熻嚜鍔ㄨ绠�" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
             <el-form-item label="鐘舵��"
                           prop="status">
               <el-select v-model="ledgerForm.status"
@@ -262,47 +307,297 @@
       </template>
     </el-dialog>
 
-    <!-- 宸℃琛ㄥ崟寮圭獥 -->
-    <el-dialog v-model="inspectionDialogVisible"
-               :title="inspectionDialogTitle"
-               width="600px"
-               :close-on-click-modal="false">
-      <el-form ref="inspectionFormRef"
-               :model="inspectionForm"
-               :rules="inspectionRules"
+    <!-- 璁炬柦鍙拌处璇︽儏寮圭獥 -->
+    <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="inspectionCode">
-              <el-input v-model="inspectionForm.inspectionCode"
-                        placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
-                        :disabled="isInspectionView" />
+            <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="inspectionType">
-              <el-select v-model="inspectionForm.inspectionType"
-                         placeholder="璇烽�夋嫨宸℃绫诲瀷"
+            <el-form-item label="瀹夊叏璁炬柦"
+                          prop="facilityId">
+              <el-select v-model="taskForm.facilityId"
+                         placeholder="璇烽�夋嫨瀹夊叏璁炬柦"
+                         filterable
+                         clearable
                          style="width: 100%"
-                         :disabled="isInspectionView">
-                <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
-                <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+                         @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-form-item label="璁″垝宸℃鏃堕棿"
-                      prop="planTime">
-          <el-date-picker v-model="inspectionForm.planTime"
-                          type="datetime"
-                          placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
-                          format="YYYY-MM-DD HH:mm:ss"
-                          value-format="YYYY-MM-DD HH:mm:ss"
-                          style="width: 100%"
-                          :disabled="isInspectionView" />
-        </el-form-item>
+        <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">
@@ -311,7 +606,8 @@
               <el-radio label="寮傚父">寮傚父</el-radio>
             </el-radio-group>
           </el-form-item>
-          <el-form-item label="妫�鏌ヨ鏄�">
+          <el-form-item label="妫�鏌ヨ鏄�"
+                        prop="checkDesc">
             <el-input v-model="inspectionForm.checkDesc"
                       type="textarea"
                       :rows="3"
@@ -336,6 +632,45 @@
       </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"
@@ -343,47 +678,111 @@
                :close-on-click-modal="false">
       <el-form ref="rectificationFormRef"
                :model="rectificationForm"
+               :rules="rectificationRules"
                label-width="120px">
-        <template v-if="rectificationDialogTitle !== '楠屾敹'">
-          <el-form-item label="闂鎻忚堪">
-            <el-input v-model="rectificationForm.problemDesc"
-                      type="textarea"
-                      :rows="3"
-                      placeholder="璇疯緭鍏ラ棶棰樻弿杩�"
-                      :disabled="isRectificationView" />
-          </el-form-item>
-          <el-form-item label="闂绛夌骇">
-            <el-select v-model="rectificationForm.problemLevel"
-                       placeholder="璇烽�夋嫨闂绛夌骇"
-                       style="width: 100%"
-                       :disabled="isRectificationView">
-              <el-option label="涓�鑸�" value="涓�鑸�" />
-              <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="璁″垝鏁存敼鏃堕棿">
-            <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="isRectificationView" />
-          </el-form-item>
-        </template>
-        <el-form-item label="鏁存敼璇存槑" v-if="rectificationDialogTitle === '鏁存敼'">
+        <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 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="闂绛夌骇"
+                      :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="isRectificationView" />
+                    :disabled="!isRectificationFix" />
         </el-form-item>
-        <el-form-item label="楠屾敹璇存槑" v-if="rectificationDialogTitle === '楠屾敹'">
+        <el-form-item v-if="showVerifyDesc"
+                      label="楠屾敹璇存槑"
+                      :prop="isRectificationVerify ? 'verifyDesc' : undefined">
           <el-input v-model="rectificationForm.verifyDesc"
                     type="textarea"
                     :rows="3"
                     placeholder="璇疯緭鍏ラ獙鏀惰鏄�"
-                    :disabled="isRectificationView" />
+                    :disabled="!isRectificationVerify" />
         </el-form-item>
       </el-form>
       <template #footer>
@@ -395,28 +794,145 @@
         </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>
   </div>
 </template>
 
 <script setup>
 import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs, computed } from "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 {
   getFacilityLedgerList,
   addFacilityLedger,
   updateFacilityLedger,
   deleteFacilityLedger,
+  getFacilityInspectionTaskList,
+  addFacilityInspectionTask,
+  updateFacilityInspectionTask,
+  deleteFacilityInspectionTask,
   getFacilityInspectionList,
-  addFacilityInspection,
   updateFacilityInspection,
   deleteFacilityInspection,
   getFacilityRectificationList,
   addFacilityRectification,
   updateFacilityRectification
 } from "@/api/safeProduction/safetyFacility";
+
+const userStore = useUserStore();
+const userList = ref([]);
+const currentUserId = computed(() => Number(userStore.id) || null);
+const ENABLED = 1;
+
+const weekOptions = [
+  { label: "鍛ㄤ竴", value: "MON" },
+  { label: "鍛ㄤ簩", value: "TUE" },
+  { label: "鍛ㄤ笁", value: "WED" },
+  { label: "鍛ㄥ洓", value: "THU" },
+  { label: "鍛ㄤ簲", value: "FRI" },
+  { label: "鍛ㄥ叚", value: "SAT" },
+  { label: "鍛ㄦ棩", value: "SUN" }
+];
+
+const dayOptions = Array.from({ length: 31 }, (_, index) => {
+  const value = String(index + 1).padStart(2, "0");
+  return { label: `${index + 1}鏃, value };
+});
+
+const frequencyTypeMap = {
+  DAILY: "姣忔棩",
+  WEEKLY: "姣忓懆",
+  MONTHLY: "姣忔湀"
+};
+
+const weekLabelMap = weekOptions.reduce((map, item) => {
+  map[item.value] = item.label;
+  return map;
+}, {});
+
+const createTaskForm = () => ({
+  id: null,
+  inspectionName: "",
+  facilityId: null,
+  facilityCode: "",
+  facilityName: "",
+  inspectionProject: "",
+  inspectorId: "",
+  frequencyType: "",
+  frequencyDetail: "",
+  week: "",
+  day: "",
+  time: "",
+  isEnabled: ENABLED,
+  remark: ""
+});
+
+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 ledgerRules = {
@@ -426,8 +942,30 @@
   installLocation: [{ required: true, message: "璇疯緭鍏ュ畨瑁呬綅缃�", trigger: "blur" }]
 };
 
+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 inspectionRules = {
-  inspectionCode: [{ required: true, message: "璇疯緭鍏ュ贰妫�缂栧彿", trigger: "blur" }]
+  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" }]
 };
 
 // 鍝嶅簲寮忔暟鎹�
@@ -441,24 +979,45 @@
   ledgerSelectedIds: [],
   ledgerForm: {
     id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
-    installLocation: "", installTime: "", productionDate: "", validPeriod: null,
+    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, facilityId: null, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
-    planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: []
+    id: null, scheduleTaskId: null, facilityId: null, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
+    facilityCode: "", facilityName: "", inspectionProject: "", planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: []
   },
   inspectionDialogVisible: false,
   inspectionDialogTitle: "",
-  inspectionDialogType: "add",
+  inspectionDialogType: "do",
+  inspectionDetailVisible: false,
+  inspectionDetail: {},
   // 鏁存敼璺熻釜
   rectificationSearchForm: { status: "" },
   rectificationTableLoading: false,
@@ -466,77 +1025,291 @@
   rectificationTableData: [],
   rectificationForm: {
     id: null, inspectionId: null, facilityId: null, problemDesc: "",
-    problemLevel: "", planTime: "", rectifyDesc: "", verifyDesc: ""
+    problemLevel: "", rectifyUserId: "", rectifyUserName: "", verifyUserId: "",
+    verifyUserName: "", facilityName: "", facilityCode: "", inspectionCode: "",
+    planTime: "", actualTime: "", rectifyDesc: "", verifyTime: "", verifyDesc: "",
+    status: "", storageBlobVOs: []
   },
   rectificationDialogVisible: false,
   rectificationDialogTitle: "",
-  rectificationDialogType: "add"
+  rectificationDialogType: "add",
+  rectificationDetailVisible: false,
+  rectificationDetail: {}
 });
 
 const {
   activeTab,
   ledgerSearchForm, ledgerTableLoading, ledgerPage, ledgerTableData, ledgerSelectedIds,
-  ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType,
+  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,
+  inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType, inspectionDetailVisible, inspectionDetail,
   rectificationSearchForm, rectificationTableLoading, rectificationPage, rectificationTableData,
-  rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType
+  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 computedNextCheckTime = computed(() => {
-  const { installTime, validPeriod } = ledgerForm.value;
-  if (!installTime || !validPeriod) return "";
-  const date = new Date(installTime);
-  date.setDate(date.getDate() + validPeriod);
-  return date.toISOString().split("T")[0];
+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();
+  }
+  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);
+
+provide("parentMethods", {
+  openLedgerDetail: row => openLedgerDetail(row),
+  openTaskDetail: row => openTaskDetail(row),
+  openInspectionDetail: row => openInspectionDetail(row)
 });
 
 // 璁炬柦鍙拌处琛ㄦ牸鍒楅厤缃�
 const ledgerTableColumn = ref([
-  { label: "璁炬柦缂栧彿", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
-  { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
-  { label: "璁炬柦绫诲瀷", prop: "facilityType", showOverflowTooltip: true, minWidth: 100 },
-  { label: "瑙勬牸鍨嬪彿", prop: "facilitySpec", showOverflowTooltip: true, minWidth: 120 },
-  { label: "瀹夎浣嶇疆", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 },
-  { label: "瀹夎鏃堕棿", prop: "installTime", minWidth: 120 },
-  { label: "涓嬫妫�鏌ユ椂闂�", prop: "nextCheckTime", minWidth: 120 },
   {
-    label: "鐘舵��", prop: "status", minWidth: 80, dataType: "tag",
+    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";
     }
   },
   {
-    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 140,
     operation: [
       { name: "缂栬緫", type: "text", clickFun: row => openLedgerForm("edit", row) },
-      { name: "鍙戣捣宸℃", type: "text", clickFun: row => openInspectionForm("add", row) },
-      { name: "鍒犻櫎", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteLedger(row) }
+      { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteLedger(row) }
     ]
+  }
+]);
+
+// 宸℃浠诲姟琛ㄦ牸鍒楅厤缃�
+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 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";
+    }
+  },
+  {
+    label: "鐘舵��", prop: "status", minWidth: 100, align: "center", dataType: "tag",
+    formatType: params => params === "寰呭贰妫�" ? "info" : "success"
   }
 ]);
 
 // 宸℃璁板綍琛ㄦ牸鍒楅厤缃�
 const inspectionTableColumn = ref([
-  { label: "宸℃缂栧彿", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
-  { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
-  { label: "璁炬柦缂栧彿", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
-  { label: "宸℃绫诲瀷", prop: "inspectionType", minWidth: 100 },
-  { label: "璁″垝宸℃鏃堕棿", prop: "planTime", minWidth: 180 },
-  { label: "宸℃浜�", prop: "inspectorName", minWidth: 100 },
-  { label: "瀹為檯宸℃鏃堕棿", prop: "actualTime", minWidth: 180 },
+  {
+    label: "宸℃缂栧彿",
+    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",
-    formatType: params => params === "姝e父" ? "success" : "danger"
+    formatData: params => params || "鏈~鍐�",
+    formatType: params => {
+      const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+      return map[params] || "info";
+    }
   },
   {
     label: "鐘舵��", prop: "status", minWidth: 100, dataType: "tag",
@@ -548,25 +1321,26 @@
       {
         name: "宸℃", type: "text",
         clickFun: row => openInspectionForm("do", row),
-        show: row => row.status === "寰呭贰妫�"
+        show: isPendingInspection
       },
       {
         name: "鏌ョ湅", type: "text",
-        clickFun: row => openInspectionForm("view", row),
-        show: row => row.status !== "寰呭贰妫�"
+        clickFun: row => openInspectionDetail(row),
+        show: isCheckedInspection
       },
       {
         name: "鏁存敼", type: "text",
-        clickFun: row => openRectificationForm("add", row),
-        show: row => row.checkResult === "寮傚父"
+        clickFun: row => openRectificationFromInspection(row),
+        show: row => isCheckedInspection(row) && isAbnormalInspection(row)
       },
-      { name: "鍒犻櫎", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteInspection(row), disabled: row => row.status !== "寰呭贰妫�" }
+      { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteInspection(row), show: isPendingInspection }
     ]
   }
 ]);
 
 // 鏁存敼璺熻釜琛ㄦ牸鍒楅厤缃�
 const rectificationTableColumn = ref([
+  { label: "宸℃缂栧彿", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
   { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
   { label: "闂鎻忚堪", prop: "problemDesc", showOverflowTooltip: true, minWidth: 200 },
   {
@@ -582,21 +1356,21 @@
       return map[params] || "info";
     }
   },
-  { label: "楠屾敹浜�", prop: "verifyUserName", minWidth: 120 },
   {
-    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+    dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 180,
     operation: [
       {
         name: "鏁存敼", type: "text",
         clickFun: row => openRectificationForm("do", row),
-        show: row => row.status === "寰呮暣鏀�" || row.status === "鏁存敼涓�"
+        show: isPendingRectification
       },
       {
         name: "楠屾敹", type: "text",
         clickFun: row => openRectificationForm("verify", row),
-        show: row => row.status === "宸叉暣鏀�"
+        show: isRectified,
+        disabled: isNotAssignedVerifier
       },
-      { name: "鏌ョ湅", type: "text", clickFun: row => openRectificationForm("view", row) }
+      { name: "鏌ョ湅", type: "text", clickFun: row => openRectificationDetail(row) }
     ]
   }
 ]);
@@ -604,15 +1378,31 @@
 // 鐢熷懡鍛ㄦ湡
 onMounted(() => {
   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 !== "鎶ュ簾");
+  });
 };
 
 // ============ 璁炬柦鍙拌处鏂规硶 ============
@@ -622,13 +1412,23 @@
   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;
+      ledgerTableData.value = res.data?.records || [];
+      ledgerPage.value.total = res.data?.total || 0;
     })
     .catch(() => { ledgerTableLoading.value = false; });
 };
@@ -643,13 +1443,18 @@
   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: "", validPeriod: null,
+      installLocation: "", installTime: "", productionDate: "",
       status: "姝e父", remark: ""
     });
   } else {
@@ -662,14 +1467,13 @@
 const submitLedgerForm = async () => {
   try {
     await ledgerFormRef.value.validate();
-    // 鑷姩璁$畻涓嬫妫�鏌ユ椂闂�
-    ledgerForm.value.nextCheckTime = computedNextCheckTime.value || null;
     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 || "鎿嶄綔澶辫触");
     }
@@ -686,10 +1490,242 @@
     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();
 };
 
 // ============ 宸℃璁板綍鏂规硶 ============
@@ -699,13 +1735,21 @@
   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;
+      inspectionTableData.value = res.data?.records || [];
+      inspectionPage.value.total = res.data?.total || 0;
     })
     .catch(() => { inspectionTableLoading.value = false; });
 };
@@ -716,23 +1760,36 @@
   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 === "add") {
-    inspectionDialogTitle.value = "鍙戣捣宸℃";
-    Object.assign(inspectionForm.value, {
-      id: null, facilityId: row.id, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
-      planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: []
-    });
-  } else if (type === "do") {
+  if (type === "do") {
     inspectionDialogTitle.value = "宸℃";
     Object.assign(inspectionForm.value, {
-      id: row.id, facilityId: row.facilityId, inspectionCode: row.inspectionCode,
-      inspectionType: row.inspectionType, planTime: row.planTime, checkResult: "", checkDesc: "", storageBlobDTOs: []
+      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: []
     });
-  } else {
-    inspectionDialogTitle.value = "鏌ョ湅宸℃";
-    Object.assign(inspectionForm.value, { ...row, storageBlobDTOs: row.storageBlobVOs || row.storageBlobDTOs || [] });
   }
   inspectionDialogVisible.value = true;
 };
@@ -740,20 +1797,38 @@
 const submitInspectionForm = async () => {
   try {
     await inspectionFormRef.value.validate();
-    if (inspectionDialogTitle.value === "宸℃") {
+    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 = new Date().toISOString().replace("T", " ").substring(0, 19);
+      inspectionForm.value.actualTime = formatDateTime();
     }
-    const api = inspectionForm.value.id ? updateFacilityInspection : addFacilityInspection;
-    const res = await api({ ...inspectionForm.value });
+    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);
@@ -783,13 +1858,20 @@
   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;
+      rectificationTableData.value = res.data?.records || [];
+      rectificationPage.value.total = res.data?.total || 0;
     })
     .catch(() => { rectificationTableLoading.value = false; });
 };
@@ -800,33 +1882,129 @@
   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,
-      problemDesc: "", problemLevel: "", planTime: "", rectifyDesc: "", verifyDesc: ""
+      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, {
-      id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
-      problemDesc: row.problemDesc, problemLevel: row.problemLevel, planTime: row.planTime || "",
-      rectifyDesc: "", verifyDesc: ""
+      ...row,
+      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
+      rectifyDesc: row.rectifyDesc || "",
+      verifyDesc: row.verifyDesc || ""
     });
   } else if (type === "verify") {
     rectificationDialogTitle.value = "楠屾敹";
     Object.assign(rectificationForm.value, {
-      id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
-      problemDesc: row.problemDesc, problemLevel: row.problemLevel,
-      rectifyDesc: row.rectifyDesc, verifyDesc: ""
+      ...row,
+      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
+      verifyDesc: row.verifyDesc || ""
     });
   } else {
     rectificationDialogTitle.value = "鏌ョ湅鏁存敼";
-    Object.assign(rectificationForm.value, { ...row });
+    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 () => {
@@ -834,27 +2012,95 @@
     rectificationDialogVisible.value = false;
     return;
   }
-  if (rectificationDialogTitle.value === "鏁存敼") {
+  try {
+    await rectificationFormRef.value.validate();
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+    return;
+  }
+  if (rectificationDialogType.value === "do") {
     rectificationForm.value.status = "宸叉暣鏀�";
-    rectificationForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
-  } else if (rectificationDialogTitle.value === "楠屾敹") {
+    rectificationForm.value.actualTime = formatDateTime();
+  } else if (rectificationDialogType.value === "verify") {
     rectificationForm.value.status = "宸查獙鏀�";
-    rectificationForm.value.verifyTime = new Date().toISOString().replace("T", " ").substring(0, 19);
+    rectificationForm.value.verifyTime = formatDateTime();
   }
   const api = rectificationForm.value.id ? updateFacilityRectification : addFacilityRectification;
-  const res = await api({ ...rectificationForm.value });
+  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-page {
+  padding-top: 4px;
+}
+
+.facility-tabs {
+  width: 100%;
+}
+
+.facility-tabs :deep(.el-tabs__header) {
+  margin-bottom: 18px;
+}
+
+.facility-tabs :deep(.el-tabs__nav-wrap::after) {
+  height: 1px;
+  background-color: #d8e2ef;
+}
+
+.facility-toolbar {
+  display: flex;
+  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 {
@@ -864,4 +2110,147 @@
 .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