From e01f84ba06a75b2f2e77b2f59923b8f0cf10a46e Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 30 七月 2026 11:52:31 +0800
Subject: [PATCH] fix: 线路巡检调整

---
 src/api/safeProduction/lineInspection.js          |   50 +
 src/views/safeProduction/lineInspection/index.vue | 2574 +++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 2,033 insertions(+), 591 deletions(-)

diff --git a/src/api/safeProduction/lineInspection.js b/src/api/safeProduction/lineInspection.js
index ec68054..2a81d2e 100644
--- a/src/api/safeProduction/lineInspection.js
+++ b/src/api/safeProduction/lineInspection.js
@@ -4,6 +4,49 @@
  * 绾胯矾宸℃API鎺ュ彛
  */
 
+// 鑾峰彇绾胯矾瀹氭椂宸℃浠诲姟鍒楄〃
+export function getLineInspectionTaskList(params) {
+  return request({
+    url: "/safeLineInspectionTask/page",
+    method: "get",
+    params,
+  });
+}
+
+// 鏍规嵁ID鑾峰彇绾胯矾瀹氭椂宸℃浠诲姟璇︽儏
+export function getLineInspectionTaskById(id) {
+  return request({
+    url: `/safeLineInspectionTask/${id}`,
+    method: "get",
+  });
+}
+
+// 鏂板绾胯矾瀹氭椂宸℃浠诲姟
+export function addLineInspectionTask(data) {
+  return request({
+    url: "/safeLineInspectionTask",
+    method: "post",
+    data,
+  });
+}
+
+// 淇敼绾胯矾瀹氭椂宸℃浠诲姟
+export function updateLineInspectionTask(data) {
+  return request({
+    url: "/safeLineInspectionTask",
+    method: "put",
+    data,
+  });
+}
+
+// 鍒犻櫎绾胯矾瀹氭椂宸℃浠诲姟
+export function deleteLineInspectionTask(ids) {
+  return request({
+    url: "/safeLineInspectionTask/" + ids.join(","),
+    method: "delete",
+  });
+}
+
 // 鑾峰彇绾胯矾宸℃鍒楄〃
 export function getLineInspectionList(params) {
   return request({
@@ -47,11 +90,12 @@
   });
 }
 
-// 瀹屾垚宸℃
-export function completeLineInspection(id) {
+// 鎵ц宸℃
+export function executeLineInspection(data) {
   return request({
-    url: `/safeLineInspection/complete/${id}`,
+    url: "/safeLineInspection/execute",
     method: "put",
+    data,
   });
 }
 
diff --git a/src/views/safeProduction/lineInspection/index.vue b/src/views/safeProduction/lineInspection/index.vue
index 66090fb..e758125 100644
--- a/src/views/safeProduction/lineInspection/index.vue
+++ b/src/views/safeProduction/lineInspection/index.vue
@@ -1,100 +1,774 @@
 <template>
-  <div class="app-container">
-    <div class="search_form mb20">
-      <div>
-        <span class="search_title">宸℃缂栧彿锛�</span>
-        <el-input v-model="searchForm.inspectionCode"
-                  style="width: 200px"
-                  placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
-                  @change="handleQuery"
-                  clearable
-                  :prefix-icon="Search" />
-        <span class="search_title ml10">宸℃鍚嶇О锛�</span>
-        <el-input v-model="searchForm.inspectionName"
-                  style="width: 200px"
-                  placeholder="璇疯緭鍏ュ贰妫�鍚嶇О"
-                  @change="handleQuery"
-                  clearable
-                  :prefix-icon="Search" />
-        <span class="search_title ml10">绾胯矾鍚嶇О锛�</span>
-        <el-input v-model="searchForm.lineName"
-                  style="width: 200px"
-                  placeholder="璇疯緭鍏ョ嚎璺悕绉�"
-                  @change="handleQuery"
-                  clearable
-                  :prefix-icon="Search" />
-        <span class="search_title ml10">鐘舵�侊細</span>
-        <el-select v-model="searchForm.status"
-                   clearable
-                   @change="handleQuery"
-                   style="width: 150px">
-          <el-option label="寰呭贰妫�" value="寰呭贰妫�" />
-          <el-option label="宸℃涓�" value="宸℃涓�" />
-          <el-option label="宸插畬鎴�" value="宸插畬鎴�" />
-        </el-select>
-        <el-button type="primary"
-                   @click="handleQuery"
-                   style="margin-left: 10px">
-          鎼滅储
-        </el-button>
-      </div>
-      <div>
-        <el-button type="primary"
-                   @click="openForm('add')">鏂板宸℃浠诲姟</el-button>
+  <div class="app-container line-inspection-page">
+    <div class="module-tabs">
+      <button
+        v-for="tab in moduleTabs"
+        :key="tab.value"
+        class="module-tab"
+        :class="{ active: activeTab === tab.value }"
+        type="button"
+        @click="handleModuleTabChange(tab.value)"
+      >
+        {{ tab.label }}
+      </button>
+    </div>
+
+    <div class="search_form line-search-panel mb20">
+      <div class="search-left">
+        <template v-if="activeTab === 'task'">
+          <div class="filter-item">
+            <span class="search_title">宸℃浠诲姟鍚嶇О锛�</span>
+            <el-input
+              v-model="taskSearchForm.inspectionName"
+              class="filter-control is-wide"
+              placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+          <div class="filter-item">
+            <span class="search_title">绾胯矾鍚嶇О锛�</span>
+            <el-input
+              v-model="taskSearchForm.lineName"
+              class="filter-control"
+              placeholder="璇疯緭鍏ョ嚎璺悕绉�"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+          <div class="filter-item">
+            <span class="search_title">鏄惁鍚敤锛�</span>
+            <el-select
+              v-model="taskSearchForm.isEnabled"
+              class="filter-control is-short"
+              clearable
+              placeholder="璇烽�夋嫨"
+              @change="handleQuery"
+            >
+              <el-option label="鏄�" :value="1" />
+              <el-option label="鍚�" :value="0" />
+            </el-select>
+          </div>
+        </template>
+        <template v-else-if="activeTab === 'record'">
+          <div class="filter-item">
+            <span class="search_title">宸℃缂栧彿锛�</span>
+            <el-input
+              v-model="recordSearchForm.inspectionCode"
+              class="filter-control"
+              placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+          <div class="filter-item">
+            <span class="search_title">宸℃鍚嶇О锛�</span>
+            <el-input
+              v-model="recordSearchForm.inspectionName"
+              class="filter-control"
+              placeholder="璇疯緭鍏ュ贰妫�鍚嶇О"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+          <div class="filter-item">
+            <span class="search_title">绾胯矾鍚嶇О锛�</span>
+            <el-input
+              v-model="recordSearchForm.lineName"
+              class="filter-control"
+              placeholder="璇疯緭鍏ョ嚎璺悕绉�"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+        </template>
+        <template v-else>
+          <div class="filter-item">
+            <span class="search_title">闅愭偅缂栧彿锛�</span>
+            <el-input
+              v-model="rectifySearchForm.hazardCode"
+              class="filter-control"
+              placeholder="璇疯緭鍏ラ殣鎮g紪鍙�"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+          <div class="filter-item">
+            <span class="search_title">闅愭偅鎻忚堪锛�</span>
+            <el-input
+              v-model="rectifySearchForm.hazardDesc"
+              class="filter-control"
+              placeholder="璇疯緭鍏ラ殣鎮f弿杩�"
+              clearable
+              :prefix-icon="Search"
+              @change="handleQuery"
+            />
+          </div>
+          <div class="filter-item">
+            <span class="search_title">鏁存敼鐘舵�侊細</span>
+            <el-select
+              v-model="rectifySearchForm.status"
+              class="filter-control is-short"
+              clearable
+              placeholder="璇烽�夋嫨"
+              @change="handleQuery"
+            >
+              <el-option label="寰呮暣鏀�" value="寰呮暣鏀�" />
+              <el-option label="鏁存敼涓�" value="鏁存敼涓�" />
+              <el-option label="宸叉暣鏀�" value="宸叉暣鏀�" />
+            </el-select>
+          </div>
+        </template>
+        <div class="filter-buttons">
+          <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+          <el-button @click="resetQuery">閲嶇疆</el-button>
+        </div>
       </div>
     </div>
 
     <div class="table_list">
-      <PIMTable rowKey="id"
-                :column="tableColumn"
-                :tableData="tableData"
-                :page="page"
-                :isSelection="true"
-                @selection-change="handleSelectionChange"
-                :tableLoading="tableLoading"
-                @pagination="pagination"
-                :total="page.total"></PIMTable>
+      <div class="table-toolbar" v-if="activeTab === 'task'">
+        <div></div>
+        <div class="toolbar-actions">
+          <el-button type="primary" :icon="Plus" @click="openTaskDialog('add')">鏂板宸℃浠诲姟</el-button>
+          <el-button type="danger" :icon="Delete" :disabled="selectedIds.length === 0" @click="handleBatchDeleteTask">鍒犻櫎</el-button>
+        </div>
+      </div>
+      <PIMTable
+        rowKey="id"
+        :column="tableColumns"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        :tableLoading="tableLoading"
+        :total="page.total"
+        :height="'calc(100vh - 25em)'"
+        :table-style="{ width: '100%' }"
+        @selection-change="handleSelectionChange"
+        @pagination="pagination"
+      >
+        <template #taskName="{ row }">
+          <el-button class="task-name-link" type="primary" link @click="openTaskDetail(row)">
+            {{ row.inspectionName || "--" }}
+          </el-button>
+        </template>
+        <template #inspectionCode="{ row }">
+          <el-button class="code-link" type="primary" link @click="openInspectionDetailEntry(row)">
+            {{ row.inspectionCode || "--" }}
+          </el-button>
+        </template>
+        <template #inspectionResult="{ row }">
+          <el-tag :type="getInspectionResultType(row.inspectionResult)" size="small">
+            {{ row.inspectionResult || "鏈贰妫�" }}
+          </el-tag>
+        </template>
+        <template #inspectorName="{ row }">
+          <div class="person-tags">
+            <template v-if="getInspectorNames(row).length">
+              <el-tag
+                v-for="name in getInspectorNames(row)"
+                :key="name"
+                size="small"
+                type="primary"
+                class="person-tag"
+              >
+                {{ name }}
+              </el-tag>
+            </template>
+            <span v-else class="no-data">--</span>
+          </div>
+        </template>
+        <template #isEnabled="{ row }">
+          <el-tag :type="row.isEnabled === 1 ? 'success' : 'info'" size="small">
+            {{ row.isEnabled === 1 ? "鏄�" : "鍚�" }}
+          </el-tag>
+        </template>
+        <template #status="{ row }">
+          <el-tag :type="getInspectionStatusType(row.status)" size="small">
+            {{ row.status || "--" }}
+          </el-tag>
+        </template>
+        <template #hazardLevel="{ row }">
+          <el-tag :type="getRiskLevelType(row.hazardLevel)" size="small">
+            {{ row.hazardLevel || "--" }}
+          </el-tag>
+        </template>
+        <template #hazardStatus="{ row }">
+          <el-tag :type="getHazardStatusType(row.status)" size="small">
+            {{ row.status || "--" }}
+          </el-tag>
+        </template>
+        <template #rectifyPhotos="{ row }">
+          <el-tag :type="hasAttachments(getAttachments(row)) ? 'success' : 'info'" size="small">
+            {{ hasAttachments(getAttachments(row)) ? "宸蹭笂浼�" : "鏈笂浼�" }}
+          </el-tag>
+        </template>
+      </PIMTable>
     </div>
 
-    <!-- 鏂板/缂栬緫宸℃浠诲姟寮圭獥 -->
-    <el-dialog v-model="dialogVisible"
-               :title="dialogTitle"
-               width="800px"
-               :close-on-click-modal="false">
-      <el-form ref="formRef"
-               :model="form"
-               :rules="rules"
-               label-width="120px">
+    <el-dialog
+      v-model="taskDetailVisible"
+      title="宸℃浠诲姟璇︽儏"
+      width="780px"
+      :close-on-click-modal="false"
+    >
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="宸℃浠诲姟鍚嶇О">
+          {{ taskDetail.inspectionName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="绾胯矾鍚嶇О">
+          {{ taskDetail.lineName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鎵ц宸℃浜�">
+          {{ getInspectorNames(taskDetail).join("銆�") || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鏄惁鍚敤">
+          <el-tag :type="taskDetail.isEnabled === 1 ? 'success' : 'info'" size="small">
+            {{ taskDetail.isEnabled === 1 ? "鏄�" : "鍚�" }}
+          </el-tag>
+        </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="鏈�鍚庢墽琛屾椂闂�">
+          {{ taskDetail.lastExecutionTime || "--" }}
+        </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="1280px"
+      :close-on-click-modal="false"
+    >
+      <el-descriptions class="history-summary" :column="3" border>
+        <el-descriptions-item label="宸℃浠诲姟鍚嶇О">
+          {{ taskHistoryTask.inspectionName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="绾胯矾鍚嶇О">
+          {{ taskHistoryTask.lineName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="棰戞">
+          {{ frequencyTypeMap[taskHistoryTask.frequencyType] || taskHistoryTask.frequencyType || "--" }}
+        </el-descriptions-item>
+      </el-descriptions>
+      <PIMTable
+        rowKey="id"
+        :column="taskHistoryColumns"
+        :tableData="taskHistoryData"
+        :page="taskHistoryPage"
+        :tableLoading="taskHistoryLoading"
+        :total="taskHistoryPage.total"
+        :height="420"
+        :table-style="{ width: '100%' }"
+        @pagination="taskHistoryPagination"
+      >
+        <template #inspectionCode="{ row }">
+          <el-button class="code-link" type="primary" link @click="openInspectionDetail(row)">
+            {{ row.inspectionCode || "--" }}
+          </el-button>
+        </template>
+        <template #inspectionResult="{ row }">
+          <el-tag :type="getInspectionResultType(row.inspectionResult)" size="small">
+            {{ row.inspectionResult || "鏈贰妫�" }}
+          </el-tag>
+        </template>
+        <template #inspectorName="{ row }">
+          <div class="person-tags">
+            <template v-if="getInspectorNames(row).length">
+              <el-tag
+                v-for="name in getInspectorNames(row)"
+                :key="name"
+                size="small"
+                type="primary"
+                class="person-tag"
+              >
+                {{ name }}
+              </el-tag>
+            </template>
+            <span v-else class="no-data">--</span>
+          </div>
+        </template>
+        <template #status="{ row }">
+          <el-tag :type="getInspectionStatusType(row.status)" size="small">
+            {{ row.status || "--" }}
+          </el-tag>
+        </template>
+      </PIMTable>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="taskHistoryVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      v-model="inspectionDetailVisible"
+      title="宸℃璇︽儏"
+      width="960px"
+      :close-on-click-modal="false"
+    >
+      <el-descriptions :column="3" border>
+        <el-descriptions-item label="宸℃缂栧彿">
+          {{ inspectionDetail.inspectionCode || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃鍚嶇О">
+          {{ inspectionDetail.inspectionName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="绾胯矾鍚嶇О">
+          {{ inspectionDetail.lineName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="璁″垝宸℃鏃堕棿">
+          {{ inspectionDetail.planTime || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="瀹為檯宸℃鏃堕棿">
+          {{ inspectionDetail.actualInspectionTime || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃缁撴灉">
+          <el-tag :type="getInspectionResultType(inspectionDetail.inspectionResult)" size="small">
+            {{ inspectionDetail.inspectionResult || "鏈贰妫�" }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃浜�">
+          {{ getInspectorNames(inspectionDetail).join("銆�") || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鐘舵��">
+          <el-tag :type="getInspectionStatusType(inspectionDetail.status)" size="small">
+            {{ inspectionDetail.status || "--" }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃绫诲瀷">
+          {{ inspectionDetail.inspectionType || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃椤圭洰" :span="3">
+          {{ inspectionDetail.inspectionProject || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="澶囨敞" :span="3">
+          {{ inspectionDetail.remark || "--" }}
+        </el-descriptions-item>
+      </el-descriptions>
+
+      <div class="detail-section-title">宸℃鎵ц璁板綍</div>
+      <el-table v-loading="inspectionDetailLoading" :data="inspectionDetailRecords" border>
+        <el-table-column prop="checkResult" label="缁撴灉" width="90" align="center">
+          <template #default="{ row }">
+            <el-tag :type="row.checkResult === '姝e父' ? 'success' : 'danger'" size="small">
+              {{ row.checkResult || "--" }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="checkContent" label="宸℃椤圭洰" min-width="180" show-overflow-tooltip />
+        <el-table-column prop="checkDesc" label="宸℃璇存槑" min-width="180" show-overflow-tooltip />
+        <el-table-column prop="checkTime" label="宸℃鏃堕棿" width="170" align="center" />
+        <el-table-column label="鐜板満鐓х墖" min-width="180" align="center">
+          <template #default="{ row }">
+            <div v-if="getAttachments(row).length" class="photo-list">
+              <el-image
+                v-for="(item, index) in getAttachments(row)"
+                :key="item.storageAttachmentId || item.id || index"
+                class="record-photo"
+                :src="getAttachmentPreviewUrl(item)"
+                :preview-src-list="getAttachmentPreviewUrls(row)"
+                fit="cover"
+                preview-teleported
+              />
+            </div>
+            <span v-else class="no-data">--</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="detail-section-title">鏁存敼璺熻釜</div>
+      <el-table v-loading="inspectionDetailLoading" :data="inspectionDetailHazards" border>
+        <el-table-column prop="hazardCode" label="闅愭偅缂栧彿" width="145" align="center" show-overflow-tooltip />
+        <el-table-column prop="hazardDesc" label="寮傚父鎻忚堪" min-width="170" show-overflow-tooltip />
+        <el-table-column prop="hazardLocation" label="寮傚父浣嶇疆" min-width="130" show-overflow-tooltip />
+        <el-table-column prop="hazardLevel" label="椋庨櫓绛夌骇" width="105" align="center">
+          <template #default="{ row }">
+            <el-tag :type="getRiskLevelType(row.hazardLevel)" size="small">
+              {{ row.hazardLevel || "--" }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="rectifyUserName" label="鏁存敼璐d换浜�" width="120" align="center" show-overflow-tooltip />
+        <el-table-column prop="rectifyDeadline" label="鏁存敼鏈熼檺" width="120" align="center" />
+        <el-table-column prop="rectifyDesc" label="鏁存敼璇存槑" min-width="170" show-overflow-tooltip>
+          <template #default="{ row }">
+            {{ row.rectifyDesc || "--" }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="rectifyTime" label="鏁存敼鏃堕棿" width="165" align="center">
+          <template #default="{ row }">
+            {{ row.rectifyTime || "--" }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鏁存敼鐓х墖" min-width="150" align="center">
+          <template #default="{ row }">
+            <div v-if="getAttachments(row).length" class="photo-list">
+              <el-image
+                v-for="(item, index) in getAttachments(row)"
+                :key="item.storageAttachmentId || item.id || index"
+                class="record-photo"
+                :src="getAttachmentPreviewUrl(item)"
+                :preview-src-list="getAttachmentPreviewUrls(row)"
+                fit="cover"
+                preview-teleported
+              />
+            </div>
+            <span v-else class="no-data">--</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="status" label="鏁存敼鐘舵��" width="100" align="center">
+          <template #default="{ row }">
+            <el-tag :type="getHazardStatusType(row.status)" size="small">
+              {{ row.status || "--" }}
+            </el-tag>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="inspectionDetailVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      v-model="executeDialogVisible"
+      title="鎵ц宸℃"
+      width="820px"
+      :close-on-click-modal="false"
+      @closed="resetExecuteForm"
+    >
+      <el-descriptions :column="2" border class="execute-summary">
+        <el-descriptions-item label="宸℃缂栧彿">
+          {{ currentInspection.inspectionCode || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃鍚嶇О">
+          {{ currentInspection.inspectionName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="绾胯矾鍚嶇О">
+          {{ currentInspection.lineName || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="璁″垝鏃堕棿">
+          {{ currentInspection.planTime || "--" }}
+        </el-descriptions-item>
+        <el-descriptions-item label="宸℃椤圭洰" :span="2">
+          {{ currentInspection.inspectionProject || "--" }}
+        </el-descriptions-item>
+      </el-descriptions>
+
+      <el-form ref="executeFormRef" :model="executeForm" :rules="executeRules" label-width="120px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="宸℃缂栧彿"
-                          prop="inspectionCode">
-              <el-input v-model="form.inspectionCode"
-                        placeholder="璇疯緭鍏ュ贰妫�缂栧彿" />
+            <el-form-item label="宸℃缁撴灉" prop="checkResult">
+              <el-radio-group v-model="executeForm.checkResult" @change="handleExecuteResultChange">
+                <el-radio label="姝e父">姝e父</el-radio>
+                <el-radio label="寮傚父">寮傚父</el-radio>
+              </el-radio-group>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="宸℃鍚嶇О"
-                          prop="inspectionName">
-              <el-input v-model="form.inspectionName"
-                        placeholder="璇疯緭鍏ュ贰妫�鍚嶇О" />
+            <el-form-item label="宸℃鏃堕棿" prop="checkTime">
+              <el-date-picker
+                v-model="executeForm.checkTime"
+                type="datetime"
+                placeholder="璇烽�夋嫨宸℃鏃堕棿"
+                format="YYYY-MM-DD HH:mm:ss"
+                value-format="YYYY-MM-DD HH:mm:ss"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item v-if="executeForm.checkResult === '姝e父'" label="宸℃璇存槑" prop="checkDesc">
+          <el-input
+            v-model="executeForm.checkDesc"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ユ甯稿贰妫�鎯呭喌璇存槑"
+          />
+        </el-form-item>
+
+        <template v-if="executeForm.checkResult === '寮傚父'">
+          <el-form-item label="寮傚父鐓х墖" prop="storageBlobDTOs">
+            <ImageUpload v-model:file-list="executeForm.storageBlobDTOs" :limit="6" button-text="涓婁紶鐓х墖" />
+          </el-form-item>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="闅愭偅绫诲瀷" prop="hiddenType">
+                <el-select v-model="executeForm.hiddenType" placeholder="璇烽�夋嫨闅愭偅绫诲瀷" clearable style="width: 100%">
+                  <el-option
+                    v-for="item in hiddenTypeOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="椋庨櫓绛夌骇" prop="riskLevel">
+                <el-select v-model="executeForm.riskLevel" placeholder="璇烽�夋嫨椋庨櫓绛夌骇" clearable style="width: 100%">
+                  <el-option v-for="item in riskLevelList" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="闅愭偅浣嶇疆" prop="hazardLocation">
+                <el-input v-model="executeForm.hazardLocation" placeholder="璇疯緭鍏ラ殣鎮d綅缃�" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="鏁存敼璐d换浜�" prop="rectifyUserId">
+                <el-select
+                  v-model="executeForm.rectifyUserId"
+                  placeholder="璇烽�夋嫨鏁存敼璐d换浜�"
+                  filterable
+                  clearable
+                  style="width: 100%"
+                  @change="handleRectifyUserChange"
+                >
+                  <el-option
+                    v-for="item in userList"
+                    :key="item.userId"
+                    :label="item.nickName"
+                    :value="item.userId"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="鏁存敼鏈熼檺" prop="rectifyTime">
+                <el-date-picker
+                  v-model="executeForm.rectifyTime"
+                  type="date"
+                  placeholder="璇烽�夋嫨鏁存敼鏈熼檺"
+                  format="YYYY-MM-DD"
+                  value-format="YYYY-MM-DD"
+                  style="width: 100%"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-form-item label="寮傚父鎻忚堪/鏁存敼瑕佹眰" prop="hazardDesc">
+            <el-input
+              v-model="executeForm.hazardDesc"
+              type="textarea"
+              :rows="3"
+              placeholder="璇锋弿杩板紓甯告儏鍐靛拰鏁存敼瑕佹眰"
+            />
+          </el-form-item>
+        </template>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="submitExecuteForm">鎻愪氦</el-button>
+          <el-button @click="executeDialogVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      v-model="taskDialogVisible"
+      :title="taskDialogTitle"
+      width="960px"
+      :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="lineName">
+              <el-input v-model="taskForm.lineName" placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="绾胯矾鍚嶇О"
-                          prop="lineName">
-              <el-input v-model="form.lineName"
-                        placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
+            <el-form-item label="宸℃浜�" prop="inspectorIds">
+              <el-select
+                v-model="taskForm.inspectorIds"
+                placeholder="璇烽�夋嫨宸℃浜�"
+                filterable
+                multiple
+                collapse-tags
+                collapse-tags-tooltip
+                clearable
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in userList"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId"
+                />
+              </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="宸℃绫诲瀷"
-                          prop="inspectionType">
-              <el-select v-model="form.inspectionType"
-                         placeholder="璇烽�夋嫨宸℃绫诲瀷"
-                         style="width: 100%">
+            <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="inspectionDialogVisible"
+      title="缂栬緫宸℃璁板綍"
+      width="800px"
+      :close-on-click-modal="false"
+      @closed="resetInspectionForm"
+    >
+      <el-form ref="inspectionFormRef" :model="inspectionForm" :rules="inspectionRules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="宸℃缂栧彿" prop="inspectionCode">
+              <el-input v-model="inspectionForm.inspectionCode" placeholder="璇疯緭鍏ュ贰妫�缂栧彿" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="宸℃鍚嶇О" prop="inspectionName">
+              <el-input v-model="inspectionForm.inspectionName" placeholder="璇疯緭鍏ュ贰妫�鍚嶇О" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="绾胯矾鍚嶇О" prop="lineName">
+              <el-input v-model="inspectionForm.lineName" placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="宸℃绫诲瀷" prop="inspectionType">
+              <el-select v-model="inspectionForm.inspectionType" placeholder="璇烽�夋嫨宸℃绫诲瀷" style="width: 100%">
                 <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
                 <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
               </el-select>
@@ -103,70 +777,80 @@
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="璁″垝宸℃鏃堕棿"
-                          prop="planTime">
-              <el-date-picker v-model="form.planTime"
-                              type="datetime"
-                              placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
-                              format="YYYY-MM-DD HH:mm:ss"
-                              value-format="YYYY-MM-DD HH:mm:ss"
-                              style="width: 100%" />
+            <el-form-item label="璁″垝宸℃鏃堕棿" prop="planTime">
+              <el-date-picker
+                v-model="inspectionForm.planTime"
+                type="datetime"
+                placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
+                format="YYYY-MM-DD HH:mm:ss"
+                value-format="YYYY-MM-DD HH:mm:ss"
+                style="width: 100%"
+              />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="宸℃浜�"
-                          prop="inspectorIds">
-              <el-select v-model="form.inspectorIds"
-                         placeholder="璇烽�夋嫨宸℃浜猴紙鍙閫夛級"
-                         filterable
-                         multiple
-                         collapse-tags
-                         collapse-tags-tooltip
-                         clearable
-                         style="width: 100%">
-                <el-option v-for="item in userList"
-                           :key="item.userId"
-                           :label="item.nickName"
-                           :value="item.userId" />
+            <el-form-item label="宸℃浜�" prop="inspectorIds">
+              <el-select
+                v-model="inspectionForm.inspectorIds"
+                placeholder="璇烽�夋嫨宸℃浜�"
+                filterable
+                multiple
+                collapse-tags
+                collapse-tags-tooltip
+                clearable
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in userList"
+                  :key="item.userId"
+                  :label="item.nickName"
+                  :value="item.userId"
+                />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
-        <el-form-item label="澶囨敞"
-                      prop="remark">
-          <el-input v-model="form.remark"
-                    type="textarea"
-                    :rows="3"
-                    placeholder="璇疯緭鍏ュ娉�" />
+        <el-form-item label="宸℃椤圭洰">
+          <el-input
+            v-model="inspectionForm.inspectionProject"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ュ贰妫�椤圭洰"
+          />
+        </el-form-item>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="inspectionForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
         </el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button type="primary"
-                     @click="submitForm">纭畾</el-button>
-          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitInspectionForm">纭畾</el-button>
+          <el-button @click="inspectionDialogVisible = false">鍙栨秷</el-button>
         </span>
       </template>
     </el-dialog>
 
-    <!-- 宸℃璁板綍寮圭獥 -->
-    <el-dialog ref="recordDialogRef"
-               v-model="recordDialogVisible"
-               title="宸℃璁板綍"
-               width="70vw"
-               :close-on-click-modal="false"
-               @open="onRecordDialogOpen">
+    <el-dialog
+      ref="recordDialogRef"
+      v-model="recordDialogVisible"
+      title="宸℃璁板綍"
+      width="70vw"
+      :close-on-click-modal="false"
+      @open="onRecordDialogOpen"
+    >
       <div class="mb10">
-        <el-button type="primary"
-                   size="small"
-                   :disabled="currentInspectionStatus === '宸插畬鎴�'"
-                   @click="openRecordForm">鏂板璁板綍</el-button>
+        <el-button
+          type="primary"
+          size="small"
+          :disabled="currentInspectionStatus === '宸插畬鎴�'"
+          @click="openRecordForm"
+        >
+          鏂板璁板綍
+        </el-button>
       </div>
       <div class="dialog-table-wrapper">
-        <el-table :data="recordList"
-                  border
-                  style="width: 100%">
-          <el-table-column prop="checkPoint" label="妫�鏌ョ偣" width="150" show-overflow-tooltip />
+        <el-table :data="recordList" border style="width: 100%">
+          <el-table-column prop="checkPoint" label="妫�鏌ョ偣" min-width="140" show-overflow-tooltip />
           <el-table-column prop="checkContent" label="妫�鏌ュ唴瀹�" min-width="200" show-overflow-tooltip />
           <el-table-column prop="checkResult" label="妫�鏌ョ粨鏋�" width="100">
             <template #default="{ row }">
@@ -175,16 +859,16 @@
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column prop="checkDesc" label="妫�鏌ヨ鏄�" width="200" show-overflow-tooltip />
+          <el-table-column prop="checkDesc" label="妫�鏌ヨ鏄�" min-width="180" show-overflow-tooltip />
           <el-table-column label="鐜板満鐓х墖" width="100">
             <template #default="{ row }">
               <el-tag :type="hasAttachments(row.storageBlobVOs) ? 'success' : 'info'">
-                {{ hasAttachments(row.storageBlobVOs) ? '宸蹭笂浼�' : '鏈笂浼�' }}
+                {{ hasAttachments(row.storageBlobVOs) ? "宸蹭笂浼�" : "鏈笂浼�" }}
               </el-tag>
             </template>
           </el-table-column>
           <el-table-column prop="checkTime" label="妫�鏌ユ椂闂�" width="180" />
-          <el-table-column label="鎿嶄綔" width="120" fixed="right">
+          <el-table-column label="鎿嶄綔" width="130" fixed="right">
             <template #default="{ row }">
               <el-button type="primary" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="openEditRecordForm(row)">缂栬緫</el-button>
               <el-button type="danger" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="handleDeleteRecord(row)">鍒犻櫎</el-button>
@@ -193,27 +877,22 @@
         </el-table>
       </div>
 
-      <!-- 鏂板璁板綍琛ㄥ崟 -->
-      <el-dialog v-model="recordFormVisible"
-                 :title="recordForm.id ? '缂栬緫宸℃璁板綍' : '鏂板宸℃璁板綍'"
-                 width="600px"
-                 append-to-body
-                 :close-on-click-modal="false">
-        <el-form ref="recordFormRef"
-                 :model="recordForm"
-                 :rules="recordRules"
-                 label-width="100px">
+      <el-dialog
+        v-model="recordFormVisible"
+        :title="recordForm.id ? '缂栬緫宸℃璁板綍' : '鏂板宸℃璁板綍'"
+        width="600px"
+        append-to-body
+        :close-on-click-modal="false"
+      >
+        <el-form ref="recordFormRef" :model="recordForm" :rules="recordRules" label-width="100px">
           <el-row :gutter="20">
             <el-col :span="12">
-              <el-form-item label="妫�鏌ョ偣"
-                            prop="checkPoint">
-                <el-input v-model="recordForm.checkPoint"
-                          placeholder="璇疯緭鍏ユ鏌ョ偣" />
+              <el-form-item label="妫�鏌ョ偣" prop="checkPoint">
+                <el-input v-model="recordForm.checkPoint" placeholder="璇疯緭鍏ユ鏌ョ偣" />
               </el-form-item>
             </el-col>
             <el-col :span="12">
-              <el-form-item label="妫�鏌ョ粨鏋�"
-                            prop="checkResult">
+              <el-form-item label="妫�鏌ョ粨鏋�" prop="checkResult">
                 <el-radio-group v-model="recordForm.checkResult">
                   <el-radio label="姝e父">姝e父</el-radio>
                   <el-radio label="寮傚父">寮傚父</el-radio>
@@ -221,61 +900,56 @@
               </el-form-item>
             </el-col>
           </el-row>
-          <el-form-item label="妫�鏌ュ唴瀹�"
-                        prop="checkContent">
-            <el-input v-model="recordForm.checkContent"
-                      type="textarea"
-                      :rows="3"
-                      placeholder="璇疯緭鍏ユ鏌ュ唴瀹�" />
+          <el-form-item label="妫�鏌ュ唴瀹�" prop="checkContent">
+            <el-input v-model="recordForm.checkContent" type="textarea" :rows="3" placeholder="璇疯緭鍏ユ鏌ュ唴瀹�" />
           </el-form-item>
           <el-form-item label="妫�鏌ヨ鏄�">
-            <el-input v-model="recordForm.checkDesc"
-                      type="textarea"
-                      :rows="2"
-                      placeholder="璇疯緭鍏ユ鏌ヨ鏄�" />
+            <el-input v-model="recordForm.checkDesc" type="textarea" :rows="2" placeholder="璇疯緭鍏ユ鏌ヨ鏄�" />
           </el-form-item>
           <el-form-item v-if="recordForm.checkResult === '寮傚父'" label="鐜板満鐓х墖">
-            <ImageUpload v-model:file-list="recordForm.storageBlobDTOs"
-                         :limit="6"
-                         button-text="涓婁紶鐓х墖" />
+            <ImageUpload v-model:file-list="recordForm.storageBlobDTOs" :limit="6" button-text="涓婁紶鐓х墖" />
           </el-form-item>
           <el-form-item label="妫�鏌ユ椂闂�">
-            <el-date-picker v-model="recordForm.checkTime"
-                            type="datetime"
-                            placeholder="璇烽�夋嫨妫�鏌ユ椂闂�"
-                            format="YYYY-MM-DD HH:mm:ss"
-                            value-format="YYYY-MM-DD HH:mm:ss"
-                            style="width: 100%" />
+            <el-date-picker
+              v-model="recordForm.checkTime"
+              type="datetime"
+              placeholder="璇烽�夋嫨妫�鏌ユ椂闂�"
+              format="YYYY-MM-DD HH:mm:ss"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              style="width: 100%"
+            />
           </el-form-item>
         </el-form>
         <template #footer>
           <span class="dialog-footer">
-            <el-button type="primary"
-                       @click="submitRecordForm">纭畾</el-button>
+            <el-button type="primary" @click="submitRecordForm">纭畾</el-button>
             <el-button @click="recordFormVisible = false">鍙栨秷</el-button>
           </span>
         </template>
       </el-dialog>
     </el-dialog>
 
-    <!-- 闅愭偅绠$悊寮圭獥 -->
-    <el-dialog ref="hazardDialogRef"
-               v-model="hazardDialogVisible"
-               title="闅愭偅绠$悊"
-               width="75vw"
-               :close-on-click-modal="false"
-               @open="onHazardDialogOpen">
+    <el-dialog
+      ref="hazardDialogRef"
+      v-model="hazardDialogVisible"
+      title="闅愭偅绠$悊"
+      width="75vw"
+      :close-on-click-modal="false"
+      @open="onHazardDialogOpen"
+    >
       <div class="mb10">
-        <el-button type="primary"
-                   size="small"
-                   :disabled="currentInspectionStatus === '宸插畬鎴�'"
-                   @click="openHazardForm('add')">涓婃姤闅愭偅</el-button>
+        <el-button
+          type="primary"
+          size="small"
+          :disabled="currentInspectionStatus === '宸插畬鎴�'"
+          @click="openHazardForm('add')"
+        >
+          涓婃姤闅愭偅
+        </el-button>
       </div>
       <div class="dialog-table-wrapper">
-        <el-table :data="hazardList"
-                  border
-                  style="width: 100%">
-          <el-table-column prop="hazardCode" label="闅愭偅缂栧彿" width="120" show-overflow-tooltip />
+        <el-table :data="hazardList" border style="width: 100%">
+          <el-table-column prop="hazardCode" label="闅愭偅缂栧彿" min-width="120" show-overflow-tooltip />
           <el-table-column prop="hazardDesc" label="闅愭偅鎻忚堪" min-width="200" show-overflow-tooltip />
           <el-table-column prop="hazardLevel" label="闅愭偅绛夌骇" width="100">
             <template #default="{ row }">
@@ -284,7 +958,7 @@
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column prop="hazardLocation" label="闅愭偅浣嶇疆" width="150" show-overflow-tooltip />
+          <el-table-column prop="hazardLocation" label="闅愭偅浣嶇疆" min-width="150" show-overflow-tooltip />
           <el-table-column prop="status" label="鐘舵��" width="100">
             <template #default="{ row }">
               <el-tag :type="getHazardStatusType(row.status)">
@@ -292,120 +966,334 @@
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column prop="rectifyUserName" label="鏁存敼璐d换浜�" width="120" />
+          <el-table-column prop="rectifyUserName" label="鏁存敼璐d换浜�" min-width="120" />
           <el-table-column label="鎿嶄綔" width="150" fixed="right">
             <template #default="{ row }">
               <el-button type="primary" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="openHazardForm('edit', row)">缂栬緫</el-button>
-              <el-button type="success" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="handleRectify(row)" v-if="row.status !== '宸叉暣鏀�'">鏁存敼</el-button>
+              <el-button
+                v-if="row.status !== '宸叉暣鏀�'"
+                type="success"
+                link
+                :disabled="currentInspectionStatus === '宸插畬鎴�'"
+                @click="handleRectify(row)"
+              >
+                鏁存敼
+              </el-button>
             </template>
           </el-table-column>
         </el-table>
       </div>
 
-      <!-- 闅愭偅琛ㄥ崟 -->
-      <el-dialog v-model="hazardFormVisible"
-                 :title="hazardDialogTitle"
-                 width="600px"
-                 append-to-body
-                 :close-on-click-modal="false">
-        <el-form ref="hazardFormRef"
-                 :model="hazardForm"
-                 :rules="hazardRules"
-                 label-width="100px">
-          <el-form-item label="闅愭偅鎻忚堪"
-                        prop="hazardDesc">
-            <el-input v-model="hazardForm.hazardDesc"
-                      type="textarea"
-                      :rows="3"
-                      placeholder="璇疯緭鍏ラ殣鎮f弿杩�" />
+      <el-dialog
+        v-model="hazardFormVisible"
+        :title="hazardDialogTitle"
+        width="600px"
+        append-to-body
+        :close-on-click-modal="false"
+      >
+        <el-form ref="hazardFormRef" :model="hazardForm" :rules="hazardRules" label-width="100px">
+          <el-form-item label="闅愭偅鎻忚堪" prop="hazardDesc">
+            <el-input v-model="hazardForm.hazardDesc" type="textarea" :rows="3" placeholder="璇疯緭鍏ラ殣鎮f弿杩�" />
           </el-form-item>
           <el-row :gutter="20">
             <el-col :span="12">
-              <el-form-item label="闅愭偅绛夌骇"
-                            prop="hazardLevel">
-                <el-select v-model="hazardForm.hazardLevel"
-                           placeholder="璇烽�夋嫨闅愭偅绛夌骇"
-                           style="width: 100%">
+              <el-form-item label="闅愭偅绛夌骇" prop="hazardLevel">
+                <el-select v-model="hazardForm.hazardLevel" placeholder="璇烽�夋嫨闅愭偅绛夌骇" style="width: 100%">
                   <el-option label="涓�鑸�" value="涓�鑸�" />
                   <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="12">
-              <el-form-item label="闅愭偅浣嶇疆"
-                            prop="hazardLocation">
-                <el-input v-model="hazardForm.hazardLocation"
-                          placeholder="璇疯緭鍏ラ殣鎮d綅缃�" />
+              <el-form-item label="闅愭偅浣嶇疆" prop="hazardLocation">
+                <el-input v-model="hazardForm.hazardLocation" placeholder="璇疯緭鍏ラ殣鎮d綅缃�" />
               </el-form-item>
             </el-col>
           </el-row>
         </el-form>
         <template #footer>
           <span class="dialog-footer">
-            <el-button type="primary"
-                       @click="submitHazardForm">纭畾</el-button>
+            <el-button type="primary" @click="submitHazardForm">纭畾</el-button>
             <el-button @click="hazardFormVisible = false">鍙栨秷</el-button>
           </span>
         </template>
       </el-dialog>
 
-      <!-- 鏁存敼琛ㄥ崟 -->
-      <el-dialog v-model="rectifyFormVisible"
-                 title="鏁存敼"
-                 width="500px"
-                 append-to-body
-                 :close-on-click-modal="false">
-        <el-form ref="rectifyFormRef"
-                 :model="rectifyForm"
-                 label-width="100px">
-          <el-form-item label="鏁存敼璇存槑"
-                        prop="rectifyDesc">
-            <el-input v-model="rectifyForm.rectifyDesc"
-                      type="textarea"
-                      :rows="4"
-                      placeholder="璇疯緭鍏ユ暣鏀硅鏄�" />
-          </el-form-item>
-        </el-form>
-        <template #footer>
-          <span class="dialog-footer">
-            <el-button type="primary"
-                       @click="submitRectifyForm">纭畾</el-button>
-            <el-button @click="rectifyFormVisible = false">鍙栨秷</el-button>
-          </span>
-        </template>
-      </el-dialog>
+    </el-dialog>
+
+    <el-dialog
+      v-model="rectifyFormVisible"
+      title="鏁存敼"
+      width="620px"
+      append-to-body
+      :close-on-click-modal="false"
+      @closed="resetRectifyForm"
+    >
+      <el-form ref="rectifyFormRef" :model="rectifyForm" :rules="rectifyRules" label-width="100px">
+        <el-form-item label="鏁存敼璇存槑" prop="rectifyDesc">
+          <el-input v-model="rectifyForm.rectifyDesc" type="textarea" :rows="4" placeholder="璇疯緭鍏ユ暣鏀硅鏄�" />
+        </el-form-item>
+        <el-form-item label="鏁存敼鍚庣収鐗�" prop="storageBlobDTOs">
+          <ImageUpload v-model:file-list="rectifyForm.storageBlobDTOs" :limit="6" button-text="涓婁紶鐓х墖" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary" @click="submitRectifyForm">纭畾</el-button>
+          <el-button @click="rectifyFormVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
     </el-dialog>
   </div>
 </template>
 
 <script setup>
-import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs } from "vue";
+import { computed, getCurrentInstance, onMounted, reactive, ref } from "vue";
+import { Delete, Plus, Search } from "@element-plus/icons-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 {
+  getLineInspectionTaskList,
+  addLineInspectionTask,
+  updateLineInspectionTask,
+  deleteLineInspectionTask,
   getLineInspectionList,
-  addLineInspection,
+  getLineInspectionById,
   updateLineInspection,
   deleteLineInspection,
-  completeLineInspection,
+  executeLineInspection,
   getInspectionRecords,
   addInspectionRecord,
   updateInspectionRecord,
   deleteInspectionRecord,
+  getInspectionHazards,
   getHazardsByInspectionId,
   addInspectionHazard,
   updateInspectionHazard
 } from "@/api/safeProduction/lineInspection";
 
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const rules = {
+const ENABLED = 1;
+const { proxy } = getCurrentInstance();
+const { hidden_danger_type } = proxy.useDict("hidden_danger_type");
+const userStore = useUserStore();
+const currentUserId = computed(() => Number(userStore.id));
+
+const activeTab = ref("task");
+const tableLoading = ref(false);
+const tableData = ref([]);
+const selectedIds = ref([]);
+const userList = ref([]);
+const taskDialogVisible = ref(false);
+const taskDetailVisible = ref(false);
+const taskHistoryVisible = ref(false);
+const taskHistoryLoading = ref(false);
+const inspectionDetailVisible = ref(false);
+const inspectionDetailLoading = ref(false);
+const executeDialogVisible = ref(false);
+const inspectionDialogVisible = ref(false);
+const recordDialogVisible = ref(false);
+const recordFormVisible = ref(false);
+const hazardDialogVisible = ref(false);
+const hazardFormVisible = ref(false);
+const rectifyFormVisible = ref(false);
+const taskDialogTitle = ref("鏂板宸℃浠诲姟");
+const hazardDialogTitle = ref("涓婃姤闅愭偅");
+const currentInspectionId = ref(null);
+const currentInspectionStatus = ref("");
+const currentInspection = ref({});
+const inspectionDetail = ref({});
+const taskHistoryTask = ref({});
+const taskHistoryData = ref([]);
+const inspectionDetailRecords = ref([]);
+const inspectionDetailHazards = ref([]);
+const recordList = ref([]);
+const hazardList = ref([]);
+
+const taskFormRef = ref();
+const inspectionFormRef = ref();
+const recordFormRef = ref();
+const hazardFormRef = ref();
+const executeFormRef = ref();
+const rectifyFormRef = ref();
+
+const moduleTabs = [
+  { label: "宸℃浠诲姟", value: "task" },
+  { label: "宸℃璁板綍", value: "record" },
+  { label: "鏁存敼璺熻釜", value: "rectify" }
+];
+
+const page = reactive({
+  current: 1,
+  size: 20,
+  total: 0,
+  layout: "total, sizes, prev, pager, next, jumper"
+});
+
+const taskHistoryPage = reactive({
+  current: 1,
+  size: 10,
+  total: 0,
+  layout: "total, sizes, prev, pager, next, jumper"
+});
+
+const taskSearchForm = reactive({
+  inspectionName: "",
+  lineName: "",
+  isEnabled: ""
+});
+
+const recordSearchForm = reactive({
+  inspectionCode: "",
+  inspectionName: "",
+  lineName: ""
+});
+
+const rectifySearchForm = reactive({
+  hazardCode: "",
+  hazardDesc: "",
+  status: ""
+});
+
+const createTaskForm = () => ({
+  id: null,
+  inspectionName: "",
+  lineName: "",
+  inspectionProject: "",
+  inspectorId: "",
+  inspectorIds: [],
+  frequencyType: "",
+  frequencyDetail: "",
+  week: "",
+  day: "",
+  time: "",
+  isEnabled: ENABLED,
+  remark: ""
+});
+
+const createInspectionForm = () => ({
+  id: null,
+  scheduleTaskId: null,
+  inspectionCode: "",
+  inspectionName: "",
+  lineName: "",
+  inspectionType: "瀹氭湡宸℃",
+  inspectionProject: "",
+  planTime: "",
+  inspectorId: "",
+  inspectorIds: [],
+  status: "",
+  remark: ""
+});
+
+const taskForm = reactive(createTaskForm());
+const taskDetail = ref({});
+const inspectionForm = reactive(createInspectionForm());
+
+const recordForm = reactive({
+  id: null,
+  inspectionId: null,
+  checkPoint: "",
+  checkContent: "",
+  checkResult: "姝e父",
+  checkDesc: "",
+  checkTime: "",
+  storageBlobDTOs: []
+});
+
+const hazardForm = reactive({
+  id: null,
+  inspectionId: null,
+  hazardDesc: "",
+  hazardLevel: "",
+  hazardLocation: ""
+});
+
+const rectifyForm = reactive({
+  id: null,
+  rectifyDesc: "",
+  storageBlobDTOs: []
+});
+
+const createExecuteForm = () => ({
+  inspectionId: null,
+  checkResult: "姝e父",
+  checkDesc: "",
+  checkTime: "",
+  storageBlobDTOs: [],
+  hiddenType: "",
+  riskLevel: "",
+  hazardLocation: "",
+  hazardDesc: "",
+  rectifyUserId: "",
+  rectifyUserMobile: "",
+  rectifyTime: ""
+});
+
+const executeForm = reactive(createExecuteForm());
+
+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 validateFrequencyDetail = (rule, value, callback) => {
+  if (!taskForm.frequencyType) {
+    callback(new Error("璇烽�夋嫨浠诲姟棰戠巼"));
+    return;
+  }
+  if (taskForm.frequencyType === "DAILY" && !taskForm.frequencyDetail) {
+    callback(new Error("璇烽�夋嫨鏃堕棿"));
+    return;
+  }
+  if (taskForm.frequencyType === "WEEKLY" && (!taskForm.week || !taskForm.time)) {
+    callback(new Error("璇烽�夋嫨鏄熸湡鍜屾椂闂�"));
+    return;
+  }
+  if (taskForm.frequencyType === "MONTHLY" && (!taskForm.day || !taskForm.time)) {
+    callback(new Error("璇烽�夋嫨鏃ユ湡鍜屾椂闂�"));
+    return;
+  }
+  callback();
+};
+
+const taskRules = {
+  inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О", trigger: "blur" }],
+  lineName: [{ required: true, message: "璇疯緭鍏ョ嚎璺悕绉�", trigger: "blur" }],
+  inspectionProject: [{ required: true, message: "璇疯緭鍏ュ贰妫�椤圭洰", trigger: "blur" }],
+  inspectorIds: [{ type: "array", 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" }],
   inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�鍚嶇О", trigger: "blur" }],
   lineName: [{ required: true, message: "璇疯緭鍏ョ嚎璺悕绉�", trigger: "blur" }],
-  inspectorIds: [{ required: true, message: "璇烽�夋嫨宸℃浜�", trigger: "change" }]
+  inspectorIds: [{ type: "array", required: true, message: "璇烽�夋嫨宸℃浜�", trigger: "change" }]
 };
 
 const recordRules = {
@@ -420,388 +1308,570 @@
   hazardLocation: [{ required: true, message: "璇疯緭鍏ラ殣鎮d綅缃�", trigger: "blur" }]
 };
 
-// 鍝嶅簲寮忔暟鎹�
-const data = reactive({
-  searchForm: {
-    inspectionCode: "",
-    inspectionName: "",
-    lineName: "",
-    status: ""
-  },
-  tableLoading: false,
-  page: {
-    current: 1,
-    size: 20,
-    total: 0
-  },
-  tableData: [],
-  selectedIds: [],
-  form: {
-    id: null,
-    inspectionCode: "",
-    inspectionName: "",
-    lineName: "",
-    inspectionType: "",
-    planTime: "",
-    inspectorId: "",
-    inspectorIds: [],
-    remark: ""
-  },
-  dialogVisible: false,
-  dialogTitle: "",
-  dialogType: "add",
-  // 宸℃璁板綍
-  currentInspectionId: null,
-  currentInspectionStatus: "",
-  recordDialogVisible: false,
-  recordFormVisible: false,
-  recordList: [],
-  recordForm: {
-    id: null,
-    inspectionId: null,
-    checkPoint: "",
-    checkContent: "",
-    checkResult: "姝e父",
-    checkDesc: "",
-    checkTime: "",
-    storageBlobDTOs: []
-  },
-  // 闅愭偅绠$悊
-  hazardDialogVisible: false,
-  hazardFormVisible: false,
-  hazardDialogTitle: "涓婃姤闅愭偅",
-  hazardList: [],
-  hazardForm: {
-    id: null,
-    inspectionId: null,
-    hazardDesc: "",
-    hazardLevel: "",
-    hazardLocation: ""
-  },
-  rectifyFormVisible: false,
-  rectifyForm: {
-    id: null,
-    rectifyDesc: ""
-  }
+const rectifyRules = {
+  rectifyDesc: [{ required: true, message: "璇疯緭鍏ユ暣鏀硅鏄�", trigger: "blur" }],
+  storageBlobDTOs: [{ required: true, message: "璇蜂笂浼犳暣鏀瑰悗鐓х墖", trigger: "change" }]
+};
+
+const riskLevelList = [
+  { value: "閲嶅ぇ椋庨櫓", label: "閲嶅ぇ椋庨櫓" },
+  { value: "杈冨ぇ椋庨櫓", label: "杈冨ぇ椋庨櫓" },
+  { value: "涓�鑸闄�", label: "涓�鑸闄�" },
+  { value: "浣庨闄�", label: "浣庨闄�" }
+];
+
+const hiddenTypeOptions = computed(() => {
+  const list = hidden_danger_type?.value || [];
+  return list.length ? list : [{ label: "绾胯矾宸℃", value: "绾胯矾宸℃" }];
 });
 
-const {
-  searchForm,
-  tableLoading,
-  page,
-  tableData,
-  selectedIds,
-  form,
-  dialogVisible,
-  dialogTitle,
-  dialogType,
-  currentInspectionId,
-  currentInspectionStatus,
-  recordDialogVisible,
-  recordFormVisible,
-  recordList,
-  recordForm,
-  hazardDialogVisible,
-  hazardFormVisible,
-  hazardDialogTitle,
-  hazardList,
-  hazardForm,
-  rectifyFormVisible,
-  rectifyForm
-} = toRefs(data);
+const validateAbnormalRequired = message => (rule, value, callback) => {
+  if (executeForm.checkResult !== "寮傚父") {
+    callback();
+    return;
+  }
+  if (Array.isArray(value) ? value.length === 0 : value === "" || value === null || value === undefined) {
+    callback(new Error(message));
+    return;
+  }
+  callback();
+};
 
-// 琛ㄥ崟寮曠敤
-const formRef = ref();
-const recordFormRef = ref();
-const hazardFormRef = ref();
-const rectifyFormRef = ref();
-const userList = ref([]);
+const executeRules = {
+  checkResult: [{ required: true, message: "璇烽�夋嫨宸℃缁撴灉", trigger: "change" }],
+  checkTime: [{ required: true, message: "璇烽�夋嫨宸℃鏃堕棿", trigger: "change" }],
+  storageBlobDTOs: [{ validator: validateAbnormalRequired("宸℃寮傚父鏃惰涓婁紶寮傚父鐓х墖"), trigger: "change" }],
+  hiddenType: [{ validator: validateAbnormalRequired("璇烽�夋嫨闅愭偅绫诲瀷"), trigger: "change" }],
+  riskLevel: [{ validator: validateAbnormalRequired("璇烽�夋嫨椋庨櫓绛夌骇"), trigger: "change" }],
+  hazardLocation: [{ validator: validateAbnormalRequired("璇疯緭鍏ラ殣鎮d綅缃�"), trigger: "blur" }],
+  hazardDesc: [{ validator: validateAbnormalRequired("璇疯緭鍏ュ紓甯告弿杩�/鏁存敼瑕佹眰"), trigger: "blur" }],
+  rectifyUserId: [{ validator: validateAbnormalRequired("璇烽�夋嫨鏁存敼璐d换浜�"), trigger: "change" }],
+  rectifyTime: [{ validator: validateAbnormalRequired("璇烽�夋嫨鏁存敼鏈熼檺"), trigger: "change" }]
+};
 
-// 琛ㄦ牸鍒楅厤缃�
-const tableColumn = ref([
+const taskColumns = [
+  { label: "宸℃浠诲姟鍚嶇О", prop: "inspectionName", minWidth: 165, dataType: "slot", slot: "taskName", align: "left" },
+  { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 150, showOverflowTooltip: true, align: "left" },
+  { label: "宸℃椤圭洰", prop: "inspectionProject", minWidth: 175, showOverflowTooltip: true, align: "left" },
+  { label: "鎵ц宸℃浜�", prop: "inspectorName", minWidth: 145, dataType: "slot", slot: "inspectorName", align: "center" },
+  { label: "鏄惁鍚敤", prop: "isEnabled", minWidth: 90, dataType: "slot", slot: "isEnabled", align: "center" },
   {
-    label: "宸℃缂栧彿",
-    prop: "inspectionCode",
-    showOverflowTooltip: true,
-    minWidth: 150
+    label: "棰戞",
+    prop: "frequencyType",
+    minWidth: 85,
+    align: "center",
+    formatData: value => frequencyTypeMap[value] || value || "--"
   },
   {
-    label: "宸℃鍚嶇О",
-    prop: "inspectionName",
-    showOverflowTooltip: true,
-    minWidth: 180
+    label: "寮�濮嬫棩鏈熶笌鏃堕棿",
+    prop: "frequencyDetail",
+    minWidth: 150,
+    align: "center",
+    formatData: value => formatFrequencyDetail(value)
   },
-  {
-    label: "绾胯矾鍚嶇О",
-    prop: "lineName",
-    showOverflowTooltip: true,
-    minWidth: 150
-  },
-  {
-    label: "宸℃绫诲瀷",
-    prop: "inspectionType",
-    showOverflowTooltip: true,
-    minWidth: 100
-  },
-  {
-    label: "璁″垝宸℃鏃堕棿",
-    prop: "planTime",
-    showOverflowTooltip: true,
-    minWidth: 180
-  },
-  {
-    label: "宸℃浜�",
-    prop: "inspectorName",
-    showOverflowTooltip: true,
-    minWidth: 100
-  },
-  {
-    label: "鐘舵��",
-    prop: "status",
-    minWidth: 100,
-    dataType: "tag",
-    formatType: params => {
-      const typeMap = {
-        寰呭贰妫�: "info",
-        宸℃涓�: "warning",
-        宸插畬鎴�: "success"
-      };
-      return typeMap[params] || "info";
-    }
-  },
+  { label: "涓嬫鎵ц鏃堕棿", prop: "nextExecutionTime", minWidth: 170, showOverflowTooltip: true, align: "center" },
   {
     dataType: "action",
     label: "鎿嶄綔",
     align: "center",
     fixed: "right",
-    width: 350,
+    width: 220,
     operation: [
+      {
+        name: "鍘嗗彶宸℃",
+        type: "text",
+        clickFun: row => openTaskHistory(row)
+      },
       {
         name: "缂栬緫",
         type: "text",
-        clickFun: row => {
-          openForm("edit", row);
-        },
-        disabled: row => row.status !== "寰呭贰妫�"
-      },
-      {
-        name: "宸℃璁板綍",
-        type: "text",
-        clickFun: row => {
-          openRecordDialog(row);
-        }
-      },
-      {
-        name: "闅愭偅绠$悊",
-        type: "text",
-        clickFun: row => {
-          openHazardDialog(row);
-        }
-      },
-      {
-        name: "瀹屾垚宸℃",
-        type: "text",
-        style: { color: "#67C23A" },
-        clickFun: row => {
-          handleComplete(row);
-        },
-        show: row => row.status === "宸℃涓�"
+        clickFun: row => openTaskDialog("edit", row)
       },
       {
         name: "鍒犻櫎",
         type: "text",
         style: { color: "#F56C6C" },
-        clickFun: row => {
-          handleDelete(row);
-        },
+        clickFun: row => handleDeleteTask(row)
+      }
+    ]
+  }
+];
+
+const taskHistoryColumns = [
+  { label: "宸℃缂栧彿", prop: "inspectionCode", width: 190, dataType: "slot", slot: "inspectionCode", align: "center" },
+  { label: "宸℃鍚嶇О", prop: "inspectionName", minWidth: 135, showOverflowTooltip: true, align: "left" },
+  { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 130, showOverflowTooltip: true, align: "left" },
+  { label: "宸℃椤圭洰", prop: "inspectionProject", minWidth: 150, showOverflowTooltip: true, align: "left" },
+  { label: "璁″垝宸℃鏃堕棿", prop: "planTime", width: 165, showOverflowTooltip: true, align: "center" },
+  { label: "宸℃缁撴灉", prop: "inspectionResult", width: 90, dataType: "slot", slot: "inspectionResult", align: "center" },
+  { label: "瀹為檯宸℃鏃堕棿", prop: "actualInspectionTime", width: 165, showOverflowTooltip: true, align: "center" },
+  { label: "宸℃浜�", prop: "inspectorName", minWidth: 105, dataType: "slot", slot: "inspectorName", align: "center" },
+  { label: "鐘舵��", prop: "status", width: 90, dataType: "slot", slot: "status", align: "center" }
+];
+
+const recordColumns = [
+  { label: "宸℃缂栧彿", prop: "inspectionCode", width: 190, dataType: "slot", slot: "inspectionCode", align: "center" },
+  { label: "宸℃鍚嶇О", prop: "inspectionName", minWidth: 135, showOverflowTooltip: true, align: "left" },
+  { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 130, showOverflowTooltip: true, align: "left" },
+  { label: "宸℃椤圭洰", prop: "inspectionProject", minWidth: 145, showOverflowTooltip: true, align: "left" },
+  { label: "璁″垝宸℃鏃堕棿", prop: "planTime", width: 165, showOverflowTooltip: true, align: "center" },
+  { label: "宸℃缁撴灉", prop: "inspectionResult", width: 90, dataType: "slot", slot: "inspectionResult", align: "center" },
+  { label: "瀹為檯宸℃鏃堕棿", prop: "actualInspectionTime", width: 165, showOverflowTooltip: true, align: "center" },
+  { label: "宸℃浜�", prop: "inspectorName", minWidth: 105, dataType: "slot", slot: "inspectorName", align: "center" },
+  { label: "鐘舵��", prop: "status", width: 90, dataType: "slot", slot: "status", align: "center" },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 125,
+    operation: [
+      {
+        name: "鎵ц宸℃",
+        type: "text",
+        clickFun: row => openExecuteDialog(row),
+        show: row => row.status !== "宸插畬鎴�" && row.status !== "寰呮暣鏀�"
+      },
+      {
+        name: "鍒犻櫎",
+        type: "text",
+        style: { color: "#F56C6C" },
+        clickFun: row => handleDeleteInspection(row),
         disabled: row => row.status !== "寰呭贰妫�"
       }
     ]
   }
-]);
+];
 
-// 鐢熷懡鍛ㄦ湡
+const rectifyColumns = [
+  { label: "闅愭偅缂栧彿", prop: "hazardCode", width: 135, showOverflowTooltip: true, align: "center" },
+  { label: "宸℃缂栧彿", prop: "inspectionCode", width: 190, dataType: "slot", slot: "inspectionCode", align: "center" },
+  { label: "宸℃鍚嶇О", prop: "inspectionName", minWidth: 120, showOverflowTooltip: true, align: "left" },
+  { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 120, showOverflowTooltip: true, align: "left" },
+  { label: "寮傚父鎻忚堪", prop: "hazardDesc", minWidth: 160, showOverflowTooltip: true, align: "left" },
+  { label: "寮傚父浣嶇疆", prop: "hazardLocation", minWidth: 130, showOverflowTooltip: true, align: "left" },
+  { label: "椋庨櫓绛夌骇", prop: "hazardLevel", width: 95, dataType: "slot", slot: "hazardLevel", align: "center" },
+  { label: "鏁存敼璐d换浜�", prop: "rectifyUserName", minWidth: 110, showOverflowTooltip: true, align: "center" },
+  { label: "鏁存敼鏈熼檺", prop: "rectifyDeadline", width: 110, showOverflowTooltip: true, align: "center" },
+  { label: "鏁存敼鐘舵��", prop: "status", width: 95, dataType: "slot", slot: "hazardStatus", align: "center" },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 85,
+    operation: [
+      {
+        name: "鏁存敼",
+        type: "text",
+        color: "#67C23A",
+        clickFun: row => handleRectify(row),
+        show: row => row.status !== "宸叉暣鏀�" && canRectify(row)
+      }
+    ]
+  }
+];
+
+const tableColumns = computed(() => {
+  if (activeTab.value === "task") {
+    return taskColumns;
+  }
+  if (activeTab.value === "record") {
+    return recordColumns;
+  }
+  return rectifyColumns;
+});
+
 onMounted(() => {
   getList();
   userListNoPage().then(res => {
-    userList.value = res.data;
+    userList.value = res.data || [];
   });
 });
 
-// 寮圭獥鍥哄畾楂樺害澶勭悊
-const setDialogFixedHeight = () => {
-  setTimeout(() => {
-    // 鐩存帴鍦� body 涓婃壘鎵�鏈� el-dialog锛坱eleport 娓叉煋鍒� body锛�
-    const dialogs = document.body.querySelectorAll('.el-dialog');
-    const dialog = dialogs[dialogs.length - 1]; // 鏈�鍚庝竴涓氨鏄垰鎵撳紑鐨�
-    if (!dialog) return;
-    Object.assign(dialog.style, {
-      height: '70vh',
-      maxHeight: '70vh',
-      overflow: 'hidden',
-      display: 'flex',
-      flexDirection: 'column'
-    });
-    const body = dialog.querySelector('.el-dialog__body');
-    if (body) {
-      Object.assign(body.style, { flex: '1', overflow: 'hidden' });
-    }
-    const wrapper = dialog.querySelector('.dialog-table-wrapper');
-    if (wrapper) {
-      Object.assign(wrapper.style, { flex: '1', overflowY: 'auto' });
-    }
-  }, 100);
-};
-
-const recordDialogRef = ref(null);
-const hazardDialogRef = ref(null);
-
-const onRecordDialogOpen = () => setDialogFixedHeight();
-const onHazardDialogOpen = () => setDialogFixedHeight();
-const handleQuery = () => {
-  page.value.current = 1;
-  getList();
-};
-
-const getList = () => {
+const getList = async () => {
   tableLoading.value = true;
-  getLineInspectionList({ ...page.value, ...searchForm.value })
-    .then(res => {
-      tableLoading.value = false;
-      tableData.value = res.data.records;
-      page.value.total = res.data.total;
-    })
-    .catch(() => {
-      tableLoading.value = false;
+  try {
+    const params = cleanParams({
+      current: page.current,
+      size: page.size,
+      ...getActiveSearchForm()
     });
+    const api = getActiveListApi();
+    const res = await api(params);
+    tableData.value = res.data?.records || [];
+    page.total = res.data?.total || 0;
+  } finally {
+    tableLoading.value = false;
+  }
 };
 
-// 鍒嗛〉澶勭悊
-const pagination = obj => {
-  page.value.current = obj.page;
-  page.value.size = obj.limit;
+const getActiveSearchForm = () => {
+  if (activeTab.value === "task") {
+    return taskSearchForm;
+  }
+  if (activeTab.value === "record") {
+    return recordSearchForm;
+  }
+  return rectifySearchForm;
+};
+
+const getActiveListApi = () => {
+  if (activeTab.value === "task") {
+    return getLineInspectionTaskList;
+  }
+  if (activeTab.value === "record") {
+    return getLineInspectionList;
+  }
+  return getInspectionHazards;
+};
+
+const handleQuery = () => {
+  page.current = 1;
   getList();
 };
 
-// 閫夋嫨鍙樺寲澶勭悊
+const resetQuery = () => {
+  page.current = 1;
+  if (activeTab.value === "task") {
+    Object.assign(taskSearchForm, { inspectionName: "", lineName: "", isEnabled: "" });
+  } else if (activeTab.value === "record") {
+    Object.assign(recordSearchForm, { inspectionCode: "", inspectionName: "", lineName: "" });
+  } else {
+    Object.assign(rectifySearchForm, { hazardCode: "", hazardDesc: "", status: "" });
+  }
+  getList();
+};
+
+const handleTabChange = () => {
+  selectedIds.value = [];
+  page.current = 1;
+  getList();
+};
+
+const handleModuleTabChange = tab => {
+  if (activeTab.value === tab) {
+    return;
+  }
+  activeTab.value = tab;
+  handleTabChange();
+};
+
+const pagination = obj => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+
 const handleSelectionChange = selection => {
   selectedIds.value = selection.map(item => item.id);
 };
 
-// 鑾峰彇闅愭偅鐘舵�佺被鍨�
-const getHazardStatusType = status => {
-  const map = {
-    寰呮暣鏀�: "danger",
-    鏁存敼涓�: "warning",
-    宸叉暣鏀�: "success"
-  };
-  return map[status] || "info";
+const openTaskDetail = row => {
+  taskDetail.value = { ...row };
+  taskDetailVisible.value = true;
 };
 
-const getAttachments = row => row?.storageBlobDTOs || row?.storageBlobVOs || [];
-const hasAttachments = attachments => Array.isArray(attachments) && attachments.length > 0;
+const openTaskHistory = row => {
+  taskHistoryTask.value = { ...row };
+  taskHistoryPage.current = 1;
+  taskHistoryVisible.value = true;
+  fetchTaskHistory();
+};
 
-// 鎵撳紑琛ㄥ崟
-const openForm = (type, row = null) => {
-  dialogType.value = type;
-  if (type === "add") {
-    dialogTitle.value = "鏂板宸℃浠诲姟";
-    Object.assign(form.value, {
-      id: null,
-      inspectionCode: "",
-      inspectionName: "",
-      lineName: "",
-      inspectionType: "",
-      planTime: "",
-      inspectorId: "",
-      inspectorIds: [],
-      remark: ""
-    });
-  } else if (type === "edit" && row) {
-    dialogTitle.value = "缂栬緫宸℃浠诲姟";
-    // 灏嗛�楀彿鍒嗛殧鐨処D瀛楃涓茶浆鎹负鏁扮粍
-    const inspectorIds = row.inspectorId
-      ? row.inspectorId.split(",").map(id => parseInt(id.trim())).filter(id => !isNaN(id))
-      : [];
-    Object.assign(form.value, {
+const fetchTaskHistory = async () => {
+  if (!taskHistoryTask.value?.id) {
+    taskHistoryData.value = [];
+    taskHistoryPage.total = 0;
+    return;
+  }
+  taskHistoryLoading.value = true;
+  try {
+    const res = await getLineInspectionList(
+      cleanParams({
+        current: taskHistoryPage.current,
+        size: taskHistoryPage.size,
+        scheduleTaskId: taskHistoryTask.value.id
+      })
+    );
+    taskHistoryData.value = res.data?.records || [];
+    taskHistoryPage.total = res.data?.total || 0;
+  } finally {
+    taskHistoryLoading.value = false;
+  }
+};
+
+const taskHistoryPagination = obj => {
+  taskHistoryPage.current = obj.page;
+  taskHistoryPage.size = obj.limit;
+  fetchTaskHistory();
+};
+
+const openInspectionDetailEntry = row => {
+  if (activeTab.value === "rectify") {
+    openInspectionDetailById(row.inspectionId, row);
+    return;
+  }
+  openInspectionDetail(row);
+};
+
+const openInspectionDetailById = async (inspectionId, fallback = {}) => {
+  let row = {
+    id: inspectionId,
+    inspectionCode: fallback.inspectionCode,
+    inspectionName: fallback.inspectionName,
+    lineName: fallback.lineName
+  };
+  if (inspectionId) {
+    const res = await getLineInspectionById(inspectionId);
+    if (res.code === 200 && res.data) {
+      row = { ...row, ...res.data };
+    }
+  }
+  openInspectionDetail(row);
+};
+
+const openInspectionDetail = async row => {
+  if (!row?.id) {
+    ElMessage.warning("宸℃璁板綍涓嶅瓨鍦�");
+    return;
+  }
+  inspectionDetail.value = { ...row };
+  inspectionDetailVisible.value = true;
+  inspectionDetailLoading.value = true;
+  try {
+    const [recordsRes, hazardsRes] = await Promise.all([
+      getInspectionRecords(row.id),
+      getHazardsByInspectionId(row.id)
+    ]);
+    inspectionDetailRecords.value = recordsRes.code === 200 ? recordsRes.data || [] : [];
+    inspectionDetailHazards.value = hazardsRes.code === 200 ? hazardsRes.data || [] : [];
+  } finally {
+    inspectionDetailLoading.value = false;
+  }
+};
+
+const openExecuteDialog = row => {
+  currentInspection.value = { ...row };
+  Object.assign(executeForm, createExecuteForm(), {
+    inspectionId: row.id,
+    checkTime: formatDateTime(new Date()),
+    hazardLocation: row.lineName || ""
+  });
+  executeDialogVisible.value = true;
+};
+
+const resetExecuteForm = () => {
+  Object.assign(executeForm, createExecuteForm());
+  currentInspection.value = {};
+  executeFormRef.value?.clearValidate?.();
+};
+
+const handleExecuteResultChange = () => {
+  if (executeForm.checkResult === "寮傚父") {
+    executeForm.hazardLocation = executeForm.hazardLocation || currentInspection.value.lineName || "";
+    executeForm.checkDesc = "";
+  }
+  executeFormRef.value?.clearValidate?.();
+};
+
+const handleRectifyUserChange = userId => {
+  const selectedUser = userList.value.find(user => Number(user.userId) === Number(userId));
+  executeForm.rectifyUserMobile = selectedUser?.phonenumber || "";
+};
+
+const submitExecuteForm = async () => {
+  try {
+    await executeFormRef.value.validate();
+    const payload = { ...executeForm };
+    if (payload.checkResult === "姝e父") {
+      Object.assign(payload, {
+        storageBlobDTOs: [],
+        hiddenType: "",
+        riskLevel: "",
+        hazardLocation: "",
+        hazardDesc: "",
+        rectifyUserId: "",
+        rectifyUserMobile: "",
+        rectifyTime: ""
+      });
+    } else {
+      payload.checkDesc = "";
+    }
+    const res = await executeLineInspection(payload);
+    if (res.code === 200) {
+      ElMessage.success(payload.checkResult === "寮傚父" ? "寮傚父宸蹭笂鎶ユ暣鏀�" : "宸℃宸插畬鎴�");
+      executeDialogVisible.value = false;
+      getList();
+    } else {
+      ElMessage.error(res.msg || "宸℃鎻愪氦澶辫触");
+    }
+  } catch (error) {
+    console.error("鎵ц宸℃琛ㄥ崟鏍¢獙澶辫触:", error);
+  }
+};
+
+const openTaskDialog = (type, row = null) => {
+  resetTaskForm();
+  taskDialogTitle.value = type === "add" ? "鏂板宸℃浠诲姟" : "缂栬緫宸℃浠诲姟";
+  if (type === "edit" && row) {
+    Object.assign(taskForm, {
       id: row.id,
-      inspectionCode: row.inspectionCode,
       inspectionName: row.inspectionName,
       lineName: row.lineName,
-      inspectionType: row.inspectionType,
-      planTime: row.planTime,
+      inspectionProject: row.inspectionProject,
       inspectorId: row.inspectorId,
-      inspectorIds: inspectorIds,
+      inspectorIds: parseInspectorIds(row.inspectorId),
+      frequencyType: row.frequencyType,
+      frequencyDetail: row.frequencyDetail,
+      isEnabled: row.isEnabled ?? ENABLED,
       remark: row.remark
     });
+    parseFrequencyDetail(row.frequencyType, row.frequencyDetail);
   }
-  dialogVisible.value = true;
+  taskDialogVisible.value = true;
 };
 
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
-  try {
-    await formRef.value.validate();
-    // 灏嗘暟缁勮浆鎹负閫楀彿鍒嗛殧鐨勫瓧绗︿覆
-    const submitData = {
-      ...form.value,
-      inspectorId: form.value.inspectorIds ? form.value.inspectorIds.join(",") : ""
-    };
-    delete submitData.inspectorIds;
+const resetTaskForm = () => {
+  Object.assign(taskForm, createTaskForm());
+  taskFormRef.value?.clearValidate?.();
+};
 
-    const api = dialogType.value === "add" ? addLineInspection : updateLineInspection;
-    const res = await api(submitData);
+const handleFrequencyTypeChange = () => {
+  Object.assign(taskForm, { frequencyDetail: "", week: "", day: "", time: "" });
+  taskFormRef.value?.clearValidate?.("frequencyDetail");
+};
+
+const parseFrequencyDetail = (frequencyType, frequencyDetail) => {
+  if (!frequencyDetail) {
+    return;
+  }
+  if (frequencyType === "DAILY") {
+    taskForm.frequencyDetail = frequencyDetail;
+    return;
+  }
+  const [firstPart, timePart] = frequencyDetail.split(",");
+  taskForm.frequencyDetail = "";
+  taskForm.time = timePart || "";
+  if (frequencyType === "WEEKLY") {
+    taskForm.week = firstPart || "";
+  }
+  if (frequencyType === "MONTHLY") {
+    taskForm.day = String(firstPart || "").padStart(2, "0");
+  }
+};
+
+const submitTaskForm = async () => {
+  try {
+    await taskFormRef.value.validate();
+    const payload = {
+      id: taskForm.id,
+      inspectionName: taskForm.inspectionName,
+      lineName: taskForm.lineName,
+      inspectionProject: taskForm.inspectionProject,
+      inspectorId: taskForm.inspectorIds.join(","),
+      frequencyType: taskForm.frequencyType,
+      frequencyDetail: buildFrequencyDetail(),
+      isEnabled: taskForm.isEnabled,
+      remark: taskForm.remark
+    };
+    const api = taskForm.id ? updateLineInspectionTask : addLineInspectionTask;
+    const res = await api(payload);
     if (res.code === 200) {
-      ElMessage.success(dialogType.value === "add" ? "娣诲姞鎴愬姛" : "鏇存柊鎴愬姛");
-      dialogVisible.value = false;
+      ElMessage.success(taskForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      taskDialogVisible.value = false;
       getList();
     } else {
       ElMessage.error(res.msg || "鎿嶄綔澶辫触");
     }
   } catch (error) {
-    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+    console.error("浠诲姟琛ㄥ崟鏍¢獙澶辫触:", error);
   }
 };
 
-// 鍒犻櫎
-const handleDelete = row => {
-  ElMessageBox.confirm("纭鍒犻櫎璇ュ贰妫�浠诲姟鍚楋紵", "鍒犻櫎", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning"
-  })
-    .then(async () => {
-      const res = await deleteLineInspection([row.id]);
-      if (res.code === 200) {
-        ElMessage.success("鍒犻櫎鎴愬姛");
-        getList();
-      } else {
-        ElMessage.error(res.msg || "鍒犻櫎澶辫触");
-      }
-    })
-    .catch(() => {});
+const buildFrequencyDetail = () => {
+  if (taskForm.frequencyType === "DAILY") {
+    return taskForm.frequencyDetail;
+  }
+  if (taskForm.frequencyType === "WEEKLY") {
+    return `${taskForm.week},${taskForm.time}`;
+  }
+  if (taskForm.frequencyType === "MONTHLY") {
+    return `${taskForm.day},${taskForm.time}`;
+  }
+  return "";
 };
 
-// 瀹屾垚宸℃
-const handleComplete = row => {
-  ElMessageBox.confirm("纭瀹屾垚璇ュ贰妫�浠诲姟鍚楋紵", "瀹屾垚宸℃", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning"
-  })
-    .then(async () => {
-      const res = await completeLineInspection(row.id);
-      if (res.code === 200) {
-        ElMessage.success("宸℃宸插畬鎴�");
-        getList();
-      } else {
-        ElMessage.error(res.msg || "鎿嶄綔澶辫触");
-      }
-    })
-    .catch(() => {});
+const handleDeleteTask = row => {
+  confirmDelete("纭鍒犻櫎璇ュ畾鏃跺贰妫�浠诲姟鍚楋紵", async () => {
+    const res = await deleteLineInspectionTask([row.id]);
+    handleDeleteResult(res);
+  });
 };
 
-// 鎵撳紑宸℃璁板綍寮圭獥
+const handleBatchDeleteTask = () => {
+  if (selectedIds.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑宸℃浠诲姟");
+    return;
+  }
+  confirmDelete("纭鍒犻櫎閫変腑鐨勫畾鏃跺贰妫�浠诲姟鍚楋紵", async () => {
+    const res = await deleteLineInspectionTask(selectedIds.value);
+    handleDeleteResult(res);
+  });
+};
+
+const openInspectionDialog = row => {
+  resetInspectionForm();
+  Object.assign(inspectionForm, {
+    id: row.id,
+    scheduleTaskId: row.scheduleTaskId,
+    inspectionCode: row.inspectionCode,
+    inspectionName: row.inspectionName,
+    lineName: row.lineName,
+    inspectionType: row.inspectionType,
+    inspectionProject: row.inspectionProject,
+    planTime: row.planTime,
+    inspectorId: row.inspectorId,
+    inspectorIds: parseInspectorIds(row.inspectorId),
+    status: row.status,
+    remark: row.remark
+  });
+  inspectionDialogVisible.value = true;
+};
+
+const resetInspectionForm = () => {
+  Object.assign(inspectionForm, createInspectionForm());
+  inspectionFormRef.value?.clearValidate?.();
+};
+
+const submitInspectionForm = async () => {
+  try {
+    await inspectionFormRef.value.validate();
+    const payload = {
+      ...inspectionForm,
+      inspectorId: inspectionForm.inspectorIds.join(",")
+    };
+    delete payload.inspectorIds;
+    const res = await updateLineInspection(payload);
+    if (res.code === 200) {
+      ElMessage.success("淇敼鎴愬姛");
+      inspectionDialogVisible.value = false;
+      getList();
+    } else {
+      ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+    }
+  } catch (error) {
+    console.error("宸℃璁板綍琛ㄥ崟鏍¢獙澶辫触:", error);
+  }
+};
+
+const handleDeleteInspection = row => {
+  confirmDelete("纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵", async () => {
+    const res = await deleteLineInspection([row.id]);
+    handleDeleteResult(res);
+  });
+};
+
 const openRecordDialog = row => {
   currentInspectionId.value = row.id;
   currentInspectionStatus.value = row.status;
@@ -809,7 +1879,6 @@
   recordDialogVisible.value = true;
 };
 
-// 鑾峰彇宸℃璁板綍
 const fetchRecords = async inspectionId => {
   const res = await getInspectionRecords(inspectionId);
   if (res.code === 200) {
@@ -817,9 +1886,8 @@
   }
 };
 
-// 鎵撳紑璁板綍琛ㄥ崟
 const openRecordForm = () => {
-  Object.assign(recordForm.value, {
+  Object.assign(recordForm, {
     id: null,
     inspectionId: currentInspectionId.value,
     checkPoint: "",
@@ -832,9 +1900,8 @@
   recordFormVisible.value = true;
 };
 
-// 鎵撳紑缂栬緫璁板綍琛ㄥ崟
-const openEditRecordForm = (row) => {
-  Object.assign(recordForm.value, {
+const openEditRecordForm = row => {
+  Object.assign(recordForm, {
     id: row.id,
     inspectionId: row.inspectionId,
     checkPoint: row.checkPoint,
@@ -847,13 +1914,8 @@
   recordFormVisible.value = true;
 };
 
-// 鍒犻櫎宸℃璁板綍
-const handleDeleteRecord = (row) => {
-  ElMessageBox.confirm("纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵", "鍒犻櫎", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning"
-  }).then(async () => {
+const handleDeleteRecord = row => {
+  confirmDelete("纭鍒犻櫎璇ュ贰妫�璁板綍鏄庣粏鍚楋紵", async () => {
     const res = await deleteInspectionRecord([row.id]);
     if (res.code === 200) {
       ElMessage.success("鍒犻櫎鎴愬姛");
@@ -861,32 +1923,31 @@
     } else {
       ElMessage.error(res.msg || "鍒犻櫎澶辫触");
     }
-  }).catch(() => {});
+  });
 };
 
-// 鎻愪氦璁板綍琛ㄥ崟
 const submitRecordForm = async () => {
   try {
     await recordFormRef.value.validate();
-    if (recordForm.value.checkResult === "寮傚父" && !hasAttachments(recordForm.value.storageBlobDTOs)) {
+    if (recordForm.checkResult === "寮傚父" && !hasAttachments(recordForm.storageBlobDTOs)) {
       ElMessage.warning("宸℃缁撴灉寮傚父鏃惰涓婁紶鐜板満鐓х墖");
       return;
     }
-    const api = recordForm.value.id ? updateInspectionRecord : addInspectionRecord;
-    const res = await api({ ...recordForm.value });
+    const api = recordForm.id ? updateInspectionRecord : addInspectionRecord;
+    const res = await api({ ...recordForm });
     if (res.code === 200) {
-      ElMessage.success(recordForm.value.id ? "淇敼鎴愬姛" : "娣诲姞鎴愬姛");
+      ElMessage.success(recordForm.id ? "淇敼鎴愬姛" : "娣诲姞鎴愬姛");
       recordFormVisible.value = false;
       fetchRecords(currentInspectionId.value);
+      getList();
     } else {
       ElMessage.error(res.msg || "鎿嶄綔澶辫触");
     }
   } catch (error) {
-    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+    console.error("宸℃璁板綍鏄庣粏琛ㄥ崟鏍¢獙澶辫触:", error);
   }
 };
 
-// 鎵撳紑闅愭偅绠$悊寮圭獥
 const openHazardDialog = row => {
   currentInspectionId.value = row.id;
   currentInspectionStatus.value = row.status;
@@ -894,7 +1955,6 @@
   hazardDialogVisible.value = true;
 };
 
-// 鑾峰彇闅愭偅鍒楄〃
 const fetchHazards = async inspectionId => {
   const res = await getHazardsByInspectionId(inspectionId);
   if (res.code === 200) {
@@ -902,11 +1962,10 @@
   }
 };
 
-// 鎵撳紑闅愭偅琛ㄥ崟
 const openHazardForm = (type, row = null) => {
   if (type === "add") {
     hazardDialogTitle.value = "涓婃姤闅愭偅";
-    Object.assign(hazardForm.value, {
+    Object.assign(hazardForm, {
       id: null,
       inspectionId: currentInspectionId.value,
       hazardDesc: "",
@@ -915,7 +1974,7 @@
     });
   } else {
     hazardDialogTitle.value = "缂栬緫闅愭偅";
-    Object.assign(hazardForm.value, {
+    Object.assign(hazardForm, {
       id: row.id,
       inspectionId: row.inspectionId,
       hazardDesc: row.hazardDesc,
@@ -926,12 +1985,11 @@
   hazardFormVisible.value = true;
 };
 
-// 鎻愪氦闅愭偅琛ㄥ崟
 const submitHazardForm = async () => {
   try {
     await hazardFormRef.value.validate();
-    const api = hazardForm.value.id ? updateInspectionHazard : addInspectionHazard;
-    const res = await api({ ...hazardForm.value });
+    const api = hazardForm.id ? updateInspectionHazard : addInspectionHazard;
+    const res = await api({ ...hazardForm });
     if (res.code === 200) {
       ElMessage.success("鎿嶄綔鎴愬姛");
       hazardFormVisible.value = false;
@@ -940,40 +1998,370 @@
       ElMessage.error(res.msg || "鎿嶄綔澶辫触");
     }
   } catch (error) {
-    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+    console.error("闅愭偅琛ㄥ崟鏍¢獙澶辫触:", error);
   }
 };
 
-// 鏁存敼
 const handleRectify = row => {
-  Object.assign(rectifyForm.value, {
+  if (!canRectify(row)) {
+    ElMessage.warning("鍙湁鏁存敼璐d换浜哄彲浠ヨ繘琛屾暣鏀�");
+    return;
+  }
+  currentInspectionId.value = row.inspectionId || currentInspectionId.value;
+  Object.assign(rectifyForm, {
     id: row.id,
-    rectifyDesc: ""
+    rectifyDesc: "",
+    storageBlobDTOs: []
   });
   rectifyFormVisible.value = true;
 };
 
-// 鎻愪氦鏁存敼琛ㄥ崟
+const resetRectifyForm = () => {
+  Object.assign(rectifyForm, {
+    id: null,
+    rectifyDesc: "",
+    storageBlobDTOs: []
+  });
+  rectifyFormRef.value?.clearValidate?.();
+};
+
 const submitRectifyForm = async () => {
+  await rectifyFormRef.value.validate();
+  if (!hasAttachments(rectifyForm.storageBlobDTOs)) {
+    ElMessage.warning("璇蜂笂浼犳暣鏀瑰悗鐓х墖");
+    return;
+  }
   const res = await updateInspectionHazard({
-    id: rectifyForm.value.id,
+    id: rectifyForm.id,
     status: "宸叉暣鏀�",
-    rectifyDesc: rectifyForm.value.rectifyDesc
+    rectifyDesc: rectifyForm.rectifyDesc,
+    storageBlobDTOs: rectifyForm.storageBlobDTOs
   });
   if (res.code === 200) {
     ElMessage.success("鏁存敼鎴愬姛");
     rectifyFormVisible.value = false;
-    fetchHazards(currentInspectionId.value);
+    if (currentInspectionId.value) {
+      fetchHazards(currentInspectionId.value);
+    }
+    getList();
   } else {
     ElMessage.error(res.msg || "鏁存敼澶辫触");
   }
 };
+
+const canRectify = row => {
+  return Number(row?.rectifyUserId) === currentUserId.value;
+};
+
+const confirmDelete = (message, onConfirm) => {
+  ElMessageBox.confirm(message, "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  })
+    .then(onConfirm)
+    .catch(() => {});
+};
+
+const handleDeleteResult = res => {
+  if (res.code === 200) {
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    selectedIds.value = [];
+    getList();
+  } else {
+    ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+  }
+};
+
+const cleanParams = params => {
+  return Object.fromEntries(
+    Object.entries(params).filter(([, value]) => value !== "" && value !== null && value !== undefined)
+  );
+};
+
+const getInspectionStatusType = status => {
+  const map = {
+    寰呭贰妫�: "info",
+    宸℃涓�: "warning",
+    寰呮暣鏀�: "danger",
+    宸插畬鎴�: "success"
+  };
+  return map[status] || "info";
+};
+
+const getInspectionResultType = result => {
+  const map = {
+    姝e父: "success",
+    寮傚父: "danger"
+  };
+  return map[result] || "info";
+};
+
+const getHazardStatusType = status => {
+  const map = {
+    寰呮暣鏀�: "danger",
+    鏁存敼涓�: "warning",
+    宸叉暣鏀�: "success"
+  };
+  return map[status] || "info";
+};
+
+const getRiskLevelType = level => {
+  const map = {
+    閲嶅ぇ椋庨櫓: "danger",
+    杈冨ぇ椋庨櫓: "warning",
+    涓�鑸闄�: "primary",
+    浣庨闄�: "info",
+    閲嶅ぇ: "danger",
+    涓�鑸�: "warning"
+  };
+  return map[level] || "info";
+};
+
+const getInspectorNames = row => {
+  if (Array.isArray(row.inspector)) {
+    return row.inspector.filter(Boolean);
+  }
+  if (!row.inspectorName && row.inspectorId) {
+    return parseInspectorIds(row.inspectorId)
+      .map(id => userList.value.find(user => Number(user.userId) === Number(id))?.nickName)
+      .filter(Boolean);
+  }
+  return String(row.inspectorName || "")
+    .split(",")
+    .map(item => item.trim())
+    .filter(Boolean);
+};
+
+const parseInspectorIds = inspectorId => {
+  return String(inspectorId || "")
+    .split(",")
+    .map(item => Number(item.trim()))
+    .filter(item => !Number.isNaN(item));
+};
+
+const formatFrequencyDetail = value => {
+  if (!value) {
+    return "--";
+  }
+  return String(value).replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => weekLabelMap[match] || match);
+};
+
+const getAttachments = row => row?.storageBlobDTOs || row?.storageBlobVOs || [];
+const hasAttachments = attachments => Array.isArray(attachments) && attachments.length > 0;
+const getAttachmentPreviewUrl = row => row?.previewURL || row?.previewUrl || row?.url || row?.downloadURL || row?.downloadUrl || "";
+const getAttachmentPreviewUrls = row => getAttachments(row).map(getAttachmentPreviewUrl).filter(Boolean);
+
+const formatDateTime = date => {
+  const pad = value => String(value).padStart(2, "0");
+  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
+};
+
+const setDialogFixedHeight = () => {
+  setTimeout(() => {
+    const dialogs = document.body.querySelectorAll(".el-dialog");
+    const dialog = dialogs[dialogs.length - 1];
+    if (!dialog) return;
+    Object.assign(dialog.style, {
+      height: "70vh",
+      maxHeight: "70vh",
+      overflow: "hidden",
+      display: "flex",
+      flexDirection: "column"
+    });
+    const body = dialog.querySelector(".el-dialog__body");
+    if (body) {
+      Object.assign(body.style, { flex: "1", overflow: "hidden" });
+    }
+    const wrapper = dialog.querySelector(".dialog-table-wrapper");
+    if (wrapper) {
+      Object.assign(wrapper.style, { flex: "1", overflowY: "auto" });
+    }
+  }, 100);
+};
+
+const onRecordDialogOpen = () => setDialogFixedHeight();
+const onHazardDialogOpen = () => setDialogFixedHeight();
 </script>
 
 <style scoped>
+.line-inspection-page :deep(.table_list) {
+  width: 100%;
+}
+
+.module-tabs {
+  display: flex;
+  align-items: center;
+  gap: 42px;
+  min-height: 58px;
+  margin-bottom: 16px;
+  padding: 0 28px;
+  border-bottom: 1px solid #d7e2f1;
+}
+
+.module-tab {
+  position: relative;
+  border: 0;
+  background: transparent;
+  color: #1f2d3d;
+  font-size: 16px;
+  line-height: 58px;
+  cursor: pointer;
+  padding: 0;
+}
+
+.module-tab.active {
+  color: #003bb3;
+  font-weight: 600;
+}
+
+.module-tab.active::after {
+  position: absolute;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  height: 2px;
+  background: #003bb3;
+  content: "";
+}
+
+.line-search-panel {
+  justify-content: flex-start;
+  align-items: center;
+  gap: 16px;
+  min-height: 44px;
+  overflow: hidden;
+}
+
+.search-left {
+  display: flex;
+  flex: 1 1 auto;
+  flex-wrap: nowrap;
+  align-items: center;
+  gap: 14px;
+  min-width: 0;
+  padding-right: 12px;
+}
+
+.filter-item,
+.filter-buttons,
+.toolbar-actions {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  flex: 0 0 auto;
+}
+
+.filter-control {
+  width: 210px;
+}
+
+.filter-control.is-wide {
+  width: 240px;
+}
+
+.filter-control.is-short {
+  width: 150px;
+}
+
+.table-toolbar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 16px;
+  margin-bottom: 12px;
+  min-height: 40px;
+}
+
 .search_title {
   font-size: 14px;
   color: #606266;
+  white-space: nowrap;
+}
+
+.person-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px;
+  align-items: center;
+  justify-content: center;
+}
+
+.person-tag {
+  margin: 0;
+}
+
+.task-name-link {
+  max-width: 100%;
+  padding: 0;
+  font-weight: 600;
+  vertical-align: middle;
+}
+
+.task-name-link :deep(span),
+.code-link :deep(span) {
+  display: inline-block;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.code-link {
+  max-width: 100%;
+  padding: 0;
+  font-weight: 600;
+  vertical-align: middle;
+}
+
+.detail-section-title {
+  margin: 18px 0 10px;
+  color: #1f2d3d;
+  font-size: 15px;
+  font-weight: 600;
+}
+
+.history-summary {
+  margin-bottom: 14px;
+}
+
+.execute-summary {
+  margin-bottom: 18px;
+}
+
+.photo-list {
+  display: flex;
+  justify-content: center;
+  gap: 6px;
+  flex-wrap: wrap;
+}
+
+.record-photo {
+  width: 46px;
+  height: 46px;
+  border-radius: 4px;
+  border: 1px solid #dcdfe6;
+}
+
+.frequency-row {
+  display: grid;
+  grid-template-columns: 132px minmax(170px, 1fr);
+  gap: 10px;
+  width: 100%;
+}
+
+.frequency-day-select,
+.frequency-time-picker {
+  width: 100%;
+}
+
+:deep(.frequency-detail-item .el-form-item__label) {
+  width: 72px !important;
+  flex: 0 0 72px;
+}
+
+.no-data {
+  color: #909399;
 }
 
 .mb10 {
@@ -987,4 +2375,14 @@
 .ml10 {
   margin-left: 10px;
 }
+
+@media (max-width: 1500px) {
+  .line-search-panel {
+    align-items: flex-start;
+  }
+
+  .search-left {
+    flex-wrap: wrap;
+  }
+}
 </style>

--
Gitblit v1.9.3