gongchunyi
2026-08-03 bd7f920a53ba17016ee4f6324d155eef2bc4cece
src/views/safeProduction/safetyFacility/index.vue
@@ -1,10 +1,12 @@
<template>
  <div class="app-container">
    <el-tabs v-model="activeTab" @tab-click="handleTabClick">
  <div class="app-container safety-facility-page">
    <el-tabs v-model="activeTab"
             class="facility-tabs"
             @tab-click="handleTabClick">
      <!-- 安全设施台账 -->
      <el-tab-pane label="安全设施台账" name="ledger">
        <div class="search_form mb20">
          <div>
        <div class="facility-toolbar">
          <div class="toolbar-filters">
            <span class="search_title">设施编号:</span>
            <el-input v-model="ledgerSearchForm.facilityCode"
                      style="width: 200px"
@@ -39,12 +41,16 @@
              <el-option label="报废" value="报废" />
            </el-select>
            <el-button type="primary"
                       @click="handleLedgerQuery"
                       style="margin-left: 10px">
                       @click="handleLedgerQuery">
              搜索
            </el-button>
            <el-button @click="resetLedgerQuery">重置</el-button>
          </div>
          <div>
          <div class="toolbar-actions">
            <el-button type="danger"
                       plain
                       :disabled="ledgerSelectedIds.length === 0"
                       @click="handleBatchDeleteLedger">批量删除</el-button>
            <el-button type="primary"
                       @click="openLedgerForm('add')">新增设施</el-button>
          </div>
@@ -63,10 +69,65 @@
        </div>
      </el-tab-pane>
      <!-- 安全设施巡检 -->
      <el-tab-pane label="安全设施巡检" name="inspection">
        <div class="search_form mb20">
          <div>
      <!-- 巡检任务 -->
      <el-tab-pane label="巡检任务" name="task">
        <div class="facility-toolbar">
          <div class="toolbar-filters">
            <span class="search_title">巡检任务名称:</span>
            <el-input v-model="taskSearchForm.inspectionName"
                      style="width: 220px"
                      placeholder="请输入巡检任务名称"
                      @change="handleTaskQuery"
                      clearable
                      :prefix-icon="Search" />
            <span class="search_title ml10">设施名称:</span>
            <el-input v-model="taskSearchForm.facilityName"
                      style="width: 200px"
                      placeholder="请输入设施名称"
                      @change="handleTaskQuery"
                      clearable
                      :prefix-icon="Search" />
            <span class="search_title ml10">是否启用:</span>
            <el-select v-model="taskSearchForm.isEnabled"
                       clearable
                       @change="handleTaskQuery"
                       style="width: 150px">
              <el-option label="是" :value="1" />
              <el-option label="否" :value="0" />
            </el-select>
            <el-button type="primary"
                       @click="handleTaskQuery">
              搜索
            </el-button>
            <el-button @click="resetTaskQuery">重置</el-button>
          </div>
          <div class="toolbar-actions">
            <el-button type="danger"
                       plain
                       :disabled="taskSelectedIds.length === 0"
                       @click="handleBatchDeleteTask">删除</el-button>
            <el-button type="primary"
                       @click="openTaskDialog('add')">新增巡检任务</el-button>
          </div>
        </div>
        <div class="table_list">
          <PIMTable rowKey="id"
                    :column="taskTableColumn"
                    :tableData="taskTableData"
                    :page="taskPage"
                    :isSelection="true"
                    @selection-change="handleTaskSelectionChange"
                    :tableLoading="taskTableLoading"
                    @pagination="taskPagination"
                    :total="taskPage.total"></PIMTable>
        </div>
      </el-tab-pane>
      <!-- 巡检记录 -->
      <el-tab-pane label="巡检记录" name="inspection">
        <div class="facility-toolbar">
          <div class="toolbar-filters">
            <span class="search_title">巡检编号:</span>
            <el-input v-model="inspectionSearchForm.inspectionCode"
                      style="width: 200px"
@@ -83,10 +144,10 @@
              <el-option label="已巡检" value="已巡检" />
            </el-select>
            <el-button type="primary"
                       @click="handleInspectionQuery"
                       style="margin-left: 10px">
                       @click="handleInspectionQuery">
              搜索
            </el-button>
            <el-button @click="resetInspectionQuery">重置</el-button>
          </div>
        </div>
@@ -104,8 +165,8 @@
      <!-- 整改跟踪 -->
      <el-tab-pane label="整改跟踪" name="rectification">
        <div class="search_form mb20">
          <div>
        <div class="facility-toolbar">
          <div class="toolbar-filters">
            <span class="search_title">状态:</span>
            <el-select v-model="rectificationSearchForm.status"
                       clearable
@@ -117,10 +178,10 @@
              <el-option label="已验收" value="已验收" />
            </el-select>
            <el-button type="primary"
                       @click="handleRectificationQuery"
                       style="margin-left: 10px">
                       @click="handleRectificationQuery">
              搜索
            </el-button>
            <el-button @click="resetRectificationQuery">重置</el-button>
          </div>
        </div>
@@ -217,17 +278,6 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="有效期(天)"
                          prop="validPeriod">
              <el-input-number v-model="ledgerForm.validPeriod"
                               :min="0"
                               placeholder="请输入有效期"
                               style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="状态"
                          prop="status">
              <el-select v-model="ledgerForm.status"
@@ -257,65 +307,366 @@
      </template>
    </el-dialog>
    <!-- 巡检表单弹窗 -->
    <el-dialog v-model="inspectionDialogVisible"
               :title="inspectionDialogTitle"
               width="600px"
               :close-on-click-modal="false">
      <el-form ref="inspectionFormRef"
               :model="inspectionForm"
               :rules="inspectionRules"
    <!-- 设施台账详情弹窗 -->
    <el-dialog v-model="ledgerDetailVisible"
               title="设施详情"
               width="760px"
               class="detail-dialog">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="设施编号">{{ ledgerDetail.facilityCode || '-' }}</el-descriptions-item>
        <el-descriptions-item label="设施名称">{{ ledgerDetail.facilityName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="设施类型">{{ ledgerDetail.facilityType || '-' }}</el-descriptions-item>
        <el-descriptions-item label="规格型号">{{ ledgerDetail.facilitySpec || '-' }}</el-descriptions-item>
        <el-descriptions-item label="安装位置">{{ ledgerDetail.installLocation || '-' }}</el-descriptions-item>
        <el-descriptions-item label="安装时间">{{ ledgerDetail.installTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="生产日期">{{ ledgerDetail.productionDate || '-' }}</el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="ledgerStatusType(ledgerDetail.status)">{{ ledgerDetail.status || '-' }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="备注" :span="2">{{ ledgerDetail.remark || '-' }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="ledgerDetailVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 巡检任务表单弹窗 -->
    <el-dialog v-model="taskDialogVisible"
               :title="taskDialogTitle"
               width="920px"
               :close-on-click-modal="false"
               @closed="resetTaskForm">
      <el-form ref="taskFormRef"
               :model="taskForm"
               :rules="taskRules"
               label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="巡检编号"
                          prop="inspectionCode">
              <el-input v-model="inspectionForm.inspectionCode"
                        placeholder="请输入巡检编号" />
            <el-form-item label="巡检任务名称"
                          prop="inspectionName">
              <el-input v-model="taskForm.inspectionName"
                        placeholder="请输入巡检任务名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="巡检类型"
                          prop="inspectionType">
              <el-select v-model="inspectionForm.inspectionType"
                         placeholder="请选择巡检类型"
                         style="width: 100%">
                <el-option label="定期巡检" value="定期巡检" />
                <el-option label="临时巡检" value="临时巡检" />
            <el-form-item label="安全设施"
                          prop="facilityId">
              <el-select v-model="taskForm.facilityId"
                         placeholder="请选择安全设施"
                         filterable
                         clearable
                         style="width: 100%"
                         @change="handleTaskFacilityChange">
                <el-option v-for="item in facilityOptions"
                           :key="item.id"
                           :label="`${item.facilityName}(${item.facilityCode || '-'})`"
                           :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="计划巡检时间"
                      prop="planTime">
          <el-date-picker v-model="inspectionForm.planTime"
                          type="datetime"
                          placeholder="请选择计划巡检时间"
                          format="YYYY-MM-DD HH:mm:ss"
                          value-format="YYYY-MM-DD HH:mm:ss"
                          style="width: 100%" />
        </el-form-item>
        <template v-if="inspectionDialogTitle === '巡检'">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="巡检人"
                          prop="inspectorId">
              <el-select v-model="taskForm.inspectorId"
                         placeholder="请选择巡检人"
                         filterable
                         clearable
                         style="width: 100%">
                <el-option v-for="item in userList"
                           :key="item.userId"
                           :label="item.nickName"
                           :value="item.userId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否启用"
                          prop="isEnabled">
              <el-radio-group v-model="taskForm.isEnabled">
                <el-radio :label="1">是</el-radio>
                <el-radio :label="0">否</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="巡检项目"
                          prop="inspectionProject">
              <el-input v-model="taskForm.inspectionProject"
                        type="textarea"
                        :autosize="{ minRows: 3, maxRows: 6 }"
                        placeholder="请输入巡检项目" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="备注">
              <el-input v-model="taskForm.remark"
                        type="textarea"
                        :autosize="{ minRows: 3, maxRows: 6 }"
                        placeholder="请输入备注" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="任务频率"
                          prop="frequencyType">
              <el-select v-model="taskForm.frequencyType"
                         placeholder="请选择"
                         clearable
                         style="width: 100%"
                         @change="handleFrequencyTypeChange">
                <el-option label="每日" value="DAILY" />
                <el-option label="每周" value="WEEKLY" />
                <el-option label="每月" value="MONTHLY" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col v-if="taskForm.frequencyType === 'DAILY'" :span="12">
            <el-form-item class="frequency-detail-item"
                          label="执行时间"
                          prop="frequencyDetail">
              <el-time-picker v-model="taskForm.frequencyDetail"
                              placeholder="选择时间"
                              format="HH:mm"
                              value-format="HH:mm"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col v-if="taskForm.frequencyType === 'WEEKLY'" :span="12">
            <el-form-item class="frequency-detail-item"
                          label="执行时间"
                          prop="frequencyDetail">
              <div class="frequency-row">
                <el-select v-model="taskForm.week"
                           class="frequency-day-select"
                           placeholder="请选择星期"
                           clearable>
                  <el-option v-for="item in weekOptions"
                             :key="item.value"
                             :label="item.label"
                             :value="item.value" />
                </el-select>
                <el-time-picker v-model="taskForm.time"
                                class="frequency-time-picker"
                                placeholder="选择时间"
                                format="HH:mm"
                                value-format="HH:mm" />
              </div>
            </el-form-item>
          </el-col>
          <el-col v-if="taskForm.frequencyType === 'MONTHLY'" :span="12">
            <el-form-item class="frequency-detail-item"
                          label="执行时间"
                          prop="frequencyDetail">
              <div class="frequency-row">
                <el-select v-model="taskForm.day"
                           class="frequency-day-select"
                           placeholder="请选择日期"
                           clearable>
                  <el-option v-for="item in dayOptions"
                             :key="item.value"
                             :label="item.label"
                             :value="item.value" />
                </el-select>
                <el-time-picker v-model="taskForm.time"
                                class="frequency-time-picker"
                                placeholder="选择时间"
                                format="HH:mm"
                                value-format="HH:mm" />
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
                     @click="submitTaskForm">保存</el-button>
          <el-button @click="taskDialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 巡检任务详情 -->
    <el-dialog v-model="taskDetailVisible"
               title="巡检任务详情"
               width="860px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="巡检任务名称">{{ taskDetail.inspectionName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="安全设施">{{ taskDetail.facilityName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="设施编号">{{ taskDetail.facilityCode || '-' }}</el-descriptions-item>
        <el-descriptions-item label="巡检人">{{ taskDetail.inspectorName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="是否启用">{{ taskDetail.isEnabled === 1 ? '是' : '否' }}</el-descriptions-item>
        <el-descriptions-item label="频次">{{ frequencyTypeMap[taskDetail.frequencyType] || taskDetail.frequencyType || '-' }}</el-descriptions-item>
        <el-descriptions-item label="执行时间">{{ formatFrequencyDetail(taskDetail.frequencyDetail) }}</el-descriptions-item>
        <el-descriptions-item label="下次执行时间">{{ taskDetail.nextExecutionTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="巡检项目" :span="2">{{ taskDetail.inspectionProject || '-' }}</el-descriptions-item>
        <el-descriptions-item label="备注" :span="2">{{ taskDetail.remark || '-' }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="taskDetailVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 历史巡检记录 -->
    <el-dialog v-model="taskHistoryVisible"
               title="历史巡检记录"
               width="1100px">
      <el-descriptions class="history-summary" :column="3" border>
        <el-descriptions-item label="巡检任务名称">{{ taskHistoryTask.inspectionName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="安全设施">{{ taskHistoryTask.facilityName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="频次">{{ frequencyTypeMap[taskHistoryTask.frequencyType] || taskHistoryTask.frequencyType || '-' }}</el-descriptions-item>
      </el-descriptions>
      <PIMTable rowKey="id"
                :column="taskHistoryTableColumn"
                :tableData="taskHistoryTableData"
                :page="taskHistoryPage"
                :isSelection="false"
                :tableLoading="taskHistoryTableLoading"
                @pagination="taskHistoryPagination"
                :total="taskHistoryPage.total"></PIMTable>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="taskHistoryVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 巡检表单弹窗 -->
    <el-dialog v-model="inspectionDialogVisible"
               :title="inspectionDialogTitle"
               width="720px"
               class="facility-form-dialog"
               :close-on-click-modal="false">
      <el-form ref="inspectionFormRef"
               :model="inspectionForm"
               :rules="inspectionRules"
               label-position="top"
               class="inspection-form">
        <div v-if="inspectionForm.facilityName || inspectionForm.facilityCode"
             class="dialog-summary">
          <div class="summary-item">
            <span>设施名称</span>
            <strong>{{ inspectionForm.facilityName || '-' }}</strong>
          </div>
          <div class="summary-item">
            <span>设施编号</span>
            <strong>{{ inspectionForm.facilityCode || '-' }}</strong>
          </div>
        </div>
        <div class="inspection-form-grid">
          <el-form-item label="巡检编号"
                        prop="inspectionCode">
            <el-input v-model="inspectionForm.inspectionCode"
                      placeholder="请输入巡检编号"
                      :disabled="isInspectionBaseReadonly" />
          </el-form-item>
          <el-form-item label="巡检类型"
                        prop="inspectionType">
            <el-select v-model="inspectionForm.inspectionType"
                       placeholder="请选择巡检类型"
                       style="width: 100%"
                       :disabled="isInspectionBaseReadonly">
              <el-option label="定期巡检" value="定期巡检" />
              <el-option label="临时巡检" value="临时巡检" />
            </el-select>
          </el-form-item>
          <el-form-item label="计划巡检时间"
                        prop="planTime"
                        class="form-grid-full">
            <el-date-picker v-model="inspectionForm.planTime"
                            type="datetime"
                            placeholder="请选择计划巡检时间"
                            format="YYYY-MM-DD HH:mm:ss"
                            value-format="YYYY-MM-DD HH:mm:ss"
                            style="width: 100%"
                            :disabled="isInspectionBaseReadonly" />
          </el-form-item>
          <el-form-item label="巡检项目"
                        class="form-grid-full">
            <el-input v-model="inspectionForm.inspectionProject"
                      type="textarea"
                      :rows="3"
                      disabled />
          </el-form-item>
        </div>
        <template v-if="inspectionDialogType !== 'add'">
          <el-form-item label="检查结果"
                        prop="checkResult">
            <el-radio-group v-model="inspectionForm.checkResult">
            <el-radio-group v-model="inspectionForm.checkResult" :disabled="isInspectionView">
              <el-radio label="正常">正常</el-radio>
              <el-radio label="异常">异常</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="检查说明">
          <el-form-item label="检查说明"
                        prop="checkDesc">
            <el-input v-model="inspectionForm.checkDesc"
                      type="textarea"
                      :rows="3"
                      placeholder="请输入检查说明" />
                      placeholder="请输入检查说明"
                      :disabled="isInspectionView" />
          </el-form-item>
          <el-form-item v-if="inspectionForm.checkResult === '异常'" label="现场照片">
            <ImageUpload v-model:file-list="inspectionForm.storageBlobDTOs"
                         :limit="6"
                         button-text="上传照片"
                         :disabled="isInspectionView" />
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
          <el-button v-if="!isInspectionView"
                     type="primary"
                     @click="submitInspectionForm">确定</el-button>
          <el-button @click="inspectionDialogVisible = false">取消</el-button>
          <el-button @click="inspectionDialogVisible = false">{{ isInspectionView ? '关闭' : '取消' }}</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 巡检详情弹窗 -->
    <el-dialog v-model="inspectionDetailVisible"
               title="巡检详情"
               width="920px"
               class="detail-dialog">
      <el-descriptions :column="3" border>
        <el-descriptions-item label="巡检编号">{{ inspectionDetail.inspectionCode || '-' }}</el-descriptions-item>
        <el-descriptions-item label="设施名称">{{ inspectionDetail.facilityName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="巡检人">{{ inspectionDetail.inspectorName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="计划巡检时间">{{ inspectionDetail.planTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="实际巡检时间">{{ inspectionDetail.actualTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="inspectionStatusType(inspectionDetail.status)">{{ inspectionDetail.status || '-' }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="检查结果">
          <el-tag :type="inspectionResultType(inspectionDetail.checkResult)">{{ inspectionDetail.checkResult || '未填写' }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="巡检项目" :span="2">{{ inspectionDetail.inspectionProject || '-' }}</el-descriptions-item>
        <el-descriptions-item label="检查说明" :span="3">{{ inspectionDetail.checkDesc || '-' }}</el-descriptions-item>
      </el-descriptions>
      <div v-if="inspectionDetailImageUrls.length" class="detail-section">
        <div class="detail-section-title">现场照片</div>
        <div class="detail-image-list">
          <el-image v-for="(url, index) in inspectionDetailImageUrls"
                    :key="`${url}-${index}`"
                    :src="url"
                    :preview-src-list="inspectionDetailImageUrls"
                    :initial-index="index"
                    fit="cover"
                    class="detail-image" />
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="inspectionDetailVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
@@ -327,41 +678,163 @@
               :close-on-click-modal="false">
      <el-form ref="rectificationFormRef"
               :model="rectificationForm"
               :rules="rectificationRules"
               label-width="120px">
        <template v-if="rectificationDialogTitle !== '验收'">
          <el-form-item label="问题描述">
            <el-input v-model="rectificationForm.problemDesc"
                      type="textarea"
                      :rows="3"
                      placeholder="请输入问题描述" />
          </el-form-item>
          <el-form-item label="问题等级">
            <el-select v-model="rectificationForm.problemLevel"
                       placeholder="请选择问题等级"
                       style="width: 100%">
              <el-option label="一般" value="一般" />
              <el-option label="重大" value="重大" />
            </el-select>
          </el-form-item>
        </template>
        <el-form-item label="整改说明" v-if="rectificationDialogTitle === '整改'">
        <div v-if="rectificationForm.facilityName || rectificationForm.inspectionCode"
             class="dialog-summary">
          <div class="summary-item">
            <span>设施名称</span>
            <strong>{{ rectificationForm.facilityName || '-' }}</strong>
          </div>
          <div class="summary-item">
            <span>巡检编号</span>
            <strong>{{ rectificationForm.inspectionCode || '-' }}</strong>
          </div>
        </div>
        <el-form-item label="问题描述"
                      :prop="isRectificationCreate ? 'problemDesc' : undefined">
          <el-input v-model="rectificationForm.problemDesc"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入问题描述"
                    :disabled="!isRectificationCreate" />
        </el-form-item>
        <el-form-item v-if="rectificationInspectionImageUrls.length"
                      label="巡检异常图片">
          <div class="rectification-image-list">
            <el-image v-for="(url, index) in rectificationInspectionImageUrls"
                      :key="`${url}-${index}`"
                      :src="url"
                      :preview-src-list="rectificationInspectionImageUrls"
                      :initial-index="index"
                      fit="cover"
                      class="rectification-image" />
          </div>
        </el-form-item>
        <el-form-item label="问题等级"
                      :prop="isRectificationCreate ? 'problemLevel' : undefined">
          <el-select v-model="rectificationForm.problemLevel"
                     placeholder="请选择问题等级"
                     style="width: 100%"
                     :disabled="!isRectificationCreate">
            <el-option label="一般" value="一般" />
            <el-option label="重大" value="重大" />
          </el-select>
        </el-form-item>
        <el-form-item label="计划整改时间"
                      :prop="isRectificationCreate ? 'planTime' : undefined">
          <el-date-picker v-model="rectificationForm.planTime"
                          type="datetime"
                          placeholder="请选择计划整改时间"
                          format="YYYY-MM-DD HH:mm:ss"
                          value-format="YYYY-MM-DD HH:mm:ss"
                          style="width: 100%"
                          :disabled="!isRectificationCreate" />
        </el-form-item>
        <el-form-item label="整改责任人"
                      :prop="isRectificationCreate ? 'rectifyUserId' : undefined">
          <el-select v-if="isRectificationCreate"
                     v-model="rectificationForm.rectifyUserId"
                     placeholder="请选择整改责任人"
                     filterable
                     clearable
                     style="width: 100%">
            <el-option v-for="item in userList"
                       :key="item.userId"
                       :label="item.nickName"
                       :value="item.userId" />
          </el-select>
          <el-input v-else
                    :model-value="rectificationForm.rectifyUserName || getUserName(rectificationForm.rectifyUserId) || '-'"
                    disabled />
        </el-form-item>
        <el-form-item v-if="showVerifyUser"
                      label="验收人"
                      :prop="isRectificationFix ? 'verifyUserId' : undefined">
          <el-select v-if="isRectificationFix"
                     v-model="rectificationForm.verifyUserId"
                     placeholder="请选择验收人"
                     filterable
                     clearable
                     style="width: 100%">
            <el-option v-for="item in userList"
                       :key="item.userId"
                       :label="item.nickName"
                       :value="item.userId" />
          </el-select>
          <el-input v-else
                    :model-value="rectificationForm.verifyUserName || getUserName(rectificationForm.verifyUserId) || '-'"
                    disabled />
        </el-form-item>
        <el-form-item v-if="showRectifyDesc"
                      label="整改说明"
                      :prop="isRectificationFix ? 'rectifyDesc' : undefined">
          <el-input v-model="rectificationForm.rectifyDesc"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入整改说明" />
                    placeholder="请输入整改说明"
                    :disabled="!isRectificationFix" />
        </el-form-item>
        <el-form-item label="验收说明" v-if="rectificationDialogTitle === '验收'">
        <el-form-item v-if="showVerifyDesc"
                      label="验收说明"
                      :prop="isRectificationVerify ? 'verifyDesc' : undefined">
          <el-input v-model="rectificationForm.verifyDesc"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入验收说明" />
                    placeholder="请输入验收说明"
                    :disabled="!isRectificationVerify" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
          <el-button v-if="!isRectificationView"
                     type="primary"
                     @click="submitRectificationForm">确定</el-button>
          <el-button @click="rectificationDialogVisible = false">取消</el-button>
          <el-button @click="rectificationDialogVisible = false">{{ isRectificationView ? '关闭' : '取消' }}</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 整改详情弹窗 -->
    <el-dialog v-model="rectificationDetailVisible"
               title="整改详情"
               width="920px"
               class="detail-dialog">
      <el-descriptions :column="3" border>
        <el-descriptions-item label="巡检编号">{{ rectificationDetail.inspectionCode || '-' }}</el-descriptions-item>
        <el-descriptions-item label="设施名称">{{ rectificationDetail.facilityName || '-' }}</el-descriptions-item>
        <el-descriptions-item label="问题等级">
          <el-tag :type="rectificationLevelType(rectificationDetail.problemLevel)">
            {{ rectificationDetail.problemLevel || '-' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="整改责任人">{{ rectificationDetail.rectifyUserName || getUserName(rectificationDetail.rectifyUserId) || '-' }}</el-descriptions-item>
        <el-descriptions-item label="计划整改时间">{{ rectificationDetail.planTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="实际整改时间">{{ rectificationDetail.actualTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="rectificationStatusType(rectificationDetail.status)">{{ rectificationDetail.status || '-' }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="验收人">{{ rectificationDetail.verifyUserName || getUserName(rectificationDetail.verifyUserId) || '-' }}</el-descriptions-item>
        <el-descriptions-item label="验收时间">{{ rectificationDetail.verifyTime || '-' }}</el-descriptions-item>
        <el-descriptions-item label="问题描述" :span="3">{{ rectificationDetail.problemDesc || '-' }}</el-descriptions-item>
        <el-descriptions-item label="整改说明" :span="3">{{ rectificationDetail.rectifyDesc || '-' }}</el-descriptions-item>
        <el-descriptions-item label="验收说明" :span="3">{{ rectificationDetail.verifyDesc || '-' }}</el-descriptions-item>
      </el-descriptions>
      <div v-if="rectificationDetailImageUrls.length" class="detail-section">
        <div class="detail-section-title">巡检异常图片</div>
        <div class="detail-image-list">
          <el-image v-for="(url, index) in rectificationDetailImageUrls"
                    :key="`${url}-${index}`"
                    :src="url"
                    :preview-src-list="rectificationDetailImageUrls"
                    :initial-index="index"
                    fit="cover"
                    class="detail-image" />
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="rectificationDetailVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
@@ -370,22 +843,96 @@
<script setup>
import { Search } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, toRefs } from "vue";
import { onMounted, ref, reactive, toRefs, computed, provide } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
import { userListNoPage } from "@/api/system/user.js";
import useUserStore from "@/store/modules/user";
import {
  getFacilityLedgerList,
  addFacilityLedger,
  updateFacilityLedger,
  deleteFacilityLedger,
  getFacilityInspectionTaskList,
  addFacilityInspectionTask,
  updateFacilityInspectionTask,
  deleteFacilityInspectionTask,
  getFacilityInspectionList,
  addFacilityInspection,
  updateFacilityInspection,
  deleteFacilityInspection,
  getFacilityRectificationList,
  addFacilityRectification,
  updateFacilityRectification
} from "@/api/safeProduction/safetyFacility";
const userStore = useUserStore();
const userList = ref([]);
const currentUserId = computed(() => Number(userStore.id) || null);
const ENABLED = 1;
const weekOptions = [
  { label: "周一", value: "MON" },
  { label: "周二", value: "TUE" },
  { label: "周三", value: "WED" },
  { label: "周四", value: "THU" },
  { label: "周五", value: "FRI" },
  { label: "周六", value: "SAT" },
  { label: "周日", value: "SUN" }
];
const dayOptions = Array.from({ length: 31 }, (_, index) => {
  const value = String(index + 1).padStart(2, "0");
  return { label: `${index + 1}日`, value };
});
const frequencyTypeMap = {
  DAILY: "每日",
  WEEKLY: "每周",
  MONTHLY: "每月"
};
const weekLabelMap = weekOptions.reduce((map, item) => {
  map[item.value] = item.label;
  return map;
}, {});
const createTaskForm = () => ({
  id: null,
  inspectionName: "",
  facilityId: null,
  facilityCode: "",
  facilityName: "",
  inspectionProject: "",
  inspectorId: "",
  frequencyType: "",
  frequencyDetail: "",
  week: "",
  day: "",
  time: "",
  isEnabled: ENABLED,
  remark: ""
});
const validateFrequencyDetail = (rule, value, callback) => {
  if (!taskForm.value.frequencyType) {
    callback(new Error("请选择任务频率"));
    return;
  }
  if (taskForm.value.frequencyType === "DAILY" && !taskForm.value.frequencyDetail) {
    callback(new Error("请选择执行时间"));
    return;
  }
  if (taskForm.value.frequencyType === "WEEKLY" && (!taskForm.value.week || !taskForm.value.time)) {
    callback(new Error("请选择星期和时间"));
    return;
  }
  if (taskForm.value.frequencyType === "MONTHLY" && (!taskForm.value.day || !taskForm.value.time)) {
    callback(new Error("请选择日期和时间"));
    return;
  }
  callback();
};
// 表单验证规则
const ledgerRules = {
@@ -395,8 +942,30 @@
  installLocation: [{ required: true, message: "请输入安装位置", trigger: "blur" }]
};
const taskRules = {
  inspectionName: [{ required: true, message: "请输入巡检任务名称", trigger: "blur" }],
  facilityId: [{ required: true, message: "请选择安全设施", trigger: "change" }],
  inspectionProject: [{ required: true, message: "请输入巡检项目", trigger: "blur" }],
  inspectorId: [{ required: true, message: "请选择巡检人", trigger: "change" }],
  frequencyType: [{ required: true, message: "请选择任务频率", trigger: "change" }],
  frequencyDetail: [{ required: true, validator: validateFrequencyDetail, trigger: "change" }]
};
const inspectionRules = {
  inspectionCode: [{ required: true, message: "请输入巡检编号", trigger: "blur" }]
  inspectionCode: [{ required: true, message: "请输入巡检编号", trigger: "blur" }],
  inspectionType: [{ required: true, message: "请选择巡检类型", trigger: "change" }],
  planTime: [{ required: true, message: "请选择计划巡检时间", trigger: "change" }],
  checkResult: [{ required: true, message: "请选择检查结果", trigger: "change" }]
};
const rectificationRules = {
  problemDesc: [{ required: true, message: "请输入问题描述", trigger: "blur" }],
  problemLevel: [{ required: true, message: "请选择问题等级", trigger: "change" }],
  planTime: [{ required: true, message: "请选择计划整改时间", trigger: "change" }],
  rectifyUserId: [{ required: true, message: "请选择整改责任人", trigger: "change" }],
  verifyUserId: [{ required: true, message: "请选择验收人", trigger: "change" }],
  rectifyDesc: [{ required: true, message: "请输入整改说明", trigger: "blur" }],
  verifyDesc: [{ required: true, message: "请输入验收说明", trigger: "blur" }]
};
// 响应式数据
@@ -410,24 +979,45 @@
  ledgerSelectedIds: [],
  ledgerForm: {
    id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
    installLocation: "", installTime: "", productionDate: "", validPeriod: null,
    installLocation: "", installTime: "", productionDate: "",
    status: "正常", remark: ""
  },
  ledgerDialogVisible: false,
  ledgerDialogTitle: "",
  ledgerDialogType: "add",
  ledgerDetailVisible: false,
  ledgerDetail: {},
  // 巡检任务
  taskSearchForm: { inspectionName: "", facilityName: "", isEnabled: "" },
  taskTableLoading: false,
  taskPage: { current: 1, size: 20, total: 0 },
  taskTableData: [],
  taskSelectedIds: [],
  taskForm: createTaskForm(),
  taskDialogVisible: false,
  taskDialogTitle: "新增巡检任务",
  taskDetailVisible: false,
  taskDetail: {},
  taskHistoryVisible: false,
  taskHistoryTask: {},
  taskHistoryTableLoading: false,
  taskHistoryPage: { current: 1, size: 10, total: 0 },
  taskHistoryTableData: [],
  facilityOptions: [],
  // 巡检记录
  inspectionSearchForm: { inspectionCode: "", status: "" },
  inspectionTableLoading: false,
  inspectionPage: { current: 1, size: 20, total: 0 },
  inspectionTableData: [],
  inspectionForm: {
    id: null, facilityId: null, inspectionCode: "", inspectionType: "定期巡检",
    planTime: "", checkResult: "", checkDesc: ""
    id: null, scheduleTaskId: null, facilityId: null, inspectionCode: "", inspectionType: "定期巡检",
    facilityCode: "", facilityName: "", inspectionProject: "", planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: []
  },
  inspectionDialogVisible: false,
  inspectionDialogTitle: "",
  inspectionDialogType: "add",
  inspectionDialogType: "do",
  inspectionDetailVisible: false,
  inspectionDetail: {},
  // 整改跟踪
  rectificationSearchForm: { status: "" },
  rectificationTableLoading: false,
@@ -435,66 +1025,291 @@
  rectificationTableData: [],
  rectificationForm: {
    id: null, inspectionId: null, facilityId: null, problemDesc: "",
    problemLevel: "", rectifyDesc: "", verifyDesc: ""
    problemLevel: "", rectifyUserId: "", rectifyUserName: "", verifyUserId: "",
    verifyUserName: "", facilityName: "", facilityCode: "", inspectionCode: "",
    planTime: "", actualTime: "", rectifyDesc: "", verifyTime: "", verifyDesc: "",
    status: "", storageBlobVOs: []
  },
  rectificationDialogVisible: false,
  rectificationDialogTitle: "",
  rectificationDialogType: "add"
  rectificationDialogType: "add",
  rectificationDetailVisible: false,
  rectificationDetail: {}
});
const {
  activeTab,
  ledgerSearchForm, ledgerTableLoading, ledgerPage, ledgerTableData, ledgerSelectedIds,
  ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType,
  ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType, ledgerDetailVisible, ledgerDetail,
  taskSearchForm, taskTableLoading, taskPage, taskTableData, taskSelectedIds,
  taskForm, taskDialogVisible, taskDialogTitle, taskDetailVisible, taskDetail,
  taskHistoryVisible, taskHistoryTask, taskHistoryTableLoading, taskHistoryPage, taskHistoryTableData,
  facilityOptions,
  inspectionSearchForm, inspectionTableLoading, inspectionPage, inspectionTableData,
  inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType,
  inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType, inspectionDetailVisible, inspectionDetail,
  rectificationSearchForm, rectificationTableLoading, rectificationPage, rectificationTableData,
  rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType
  rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType,
  rectificationDetailVisible, rectificationDetail
} = toRefs(data);
// 表单引用
const ledgerFormRef = ref();
const taskFormRef = ref();
const inspectionFormRef = ref();
const rectificationFormRef = ref();
const isInspectionView = computed(() => inspectionDialogType.value === "view");
const isInspectionBaseReadonly = computed(() => inspectionDialogType.value !== "add");
const isRectificationView = computed(() => rectificationDialogType.value === "view");
const isRectificationCreate = computed(() => rectificationDialogType.value === "add");
const isRectificationFix = computed(() => rectificationDialogType.value === "do");
const isRectificationVerify = computed(() => rectificationDialogType.value === "verify");
const showRectifyDesc = computed(
  () =>
    isRectificationFix.value ||
    isRectificationVerify.value ||
    (isRectificationView.value && !!rectificationForm.value.rectifyDesc)
);
const showVerifyDesc = computed(
  () =>
    isRectificationVerify.value ||
    (isRectificationView.value &&
      (rectificationForm.value.status === "已验收" || !!rectificationForm.value.verifyDesc))
);
const showVerifyUser = computed(
  () =>
    isRectificationFix.value ||
    isRectificationVerify.value ||
    isRectificationView.value ||
    !!rectificationForm.value.verifyUserId
);
const getAttachmentUrl = item => {
  if (!item) return "";
  if (typeof item === "string") return item;
  return item.url || item.previewURL || item.previewUrl || item.downloadURL || "";
};
const rectificationInspectionImageUrls = computed(() => {
  const list = rectificationForm.value.storageBlobVOs || rectificationForm.value.storageBlobDTOs || [];
  return list.map(getAttachmentUrl).filter(Boolean);
});
const inspectionDetailImageUrls = computed(() => {
  const list = inspectionDetail.value.storageBlobVOs || inspectionDetail.value.storageBlobDTOs || [];
  return list.map(getAttachmentUrl).filter(Boolean);
});
const rectificationDetailImageUrls = computed(() => {
  const list = rectificationDetail.value.storageBlobVOs || rectificationDetail.value.storageBlobDTOs || [];
  return list.map(getAttachmentUrl).filter(Boolean);
});
const ledgerStatusType = value => {
  const map = { 正常: "success", 异常: "danger", 报废: "info" };
  return map[value] || "info";
};
const inspectionResultType = value => {
  const map = { 正常: "success", 异常: "danger", 未填写: "info" };
  return map[value || "未填写"] || "info";
};
const inspectionStatusType = value => value === "待巡检" ? "info" : "success";
const rectificationLevelType = value => value === "重大" ? "danger" : "warning";
const rectificationStatusType = value => {
  const map = { 待整改: "danger", 整改中: "warning", 已整改: "success", 已验收: "info" };
  return map[value] || "info";
};
const padTime = value => String(value).padStart(2, "0");
const formatDateTime = (date = new Date()) => {
  const target = date instanceof Date ? date : new Date(date);
  return `${target.getFullYear()}-${padTime(target.getMonth() + 1)}-${padTime(target.getDate())} ${padTime(target.getHours())}:${padTime(target.getMinutes())}:${padTime(target.getSeconds())}`;
};
const addDaysDateTime = days => {
  const target = new Date();
  target.setDate(target.getDate() + days);
  target.setHours(18, 0, 0, 0);
  return formatDateTime(target);
};
const getUserName = userId => {
  const user = userList.value.find(item => Number(item.userId) === Number(userId));
  return user?.nickName || "";
};
const formatFrequencyDetail = value => {
  if (!value) return "--";
  if (!value.includes(",")) return value;
  const [firstPart, timePart] = value.split(",");
  if (weekLabelMap[firstPart]) {
    return `${weekLabelMap[firstPart]} ${timePart || ""}`.trim();
  }
  if (firstPart) {
    return `${Number(firstPart)}日 ${timePart || ""}`.trim();
  }
  return value;
};
const isPendingInspection = row => row?.status === "待巡检";
const isCheckedInspection = row => row?.status === "已巡检";
const isAbnormalInspection = row => row?.checkResult === "异常";
const isPendingRectification = row => row?.status === "待整改" || row?.status === "整改中";
const isRectified = row => row?.status === "已整改";
const isNotAssignedVerifier = row =>
  row?.verifyUserId && Number(row.verifyUserId) !== Number(currentUserId.value);
provide("parentMethods", {
  openLedgerDetail: row => openLedgerDetail(row),
  openTaskDetail: row => openTaskDetail(row),
  openInspectionDetail: row => openInspectionDetail(row)
});
// 设施台账表格列配置
const ledgerTableColumn = ref([
  { label: "设施编号", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
  { label: "设施类型", prop: "facilityType", showOverflowTooltip: true, minWidth: 100 },
  { label: "规格型号", prop: "facilitySpec", showOverflowTooltip: true, minWidth: 120 },
  { label: "安装位置", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 },
  { label: "安装时间", prop: "installTime", minWidth: 120 },
  { label: "下次检查时间", prop: "nextCheckTime", minWidth: 120 },
  {
    label: "状态", prop: "status", minWidth: 80, dataType: "tag",
    label: "设施编号",
    prop: "facilityCode",
    dataType: "link",
    linkMethod: "openLedgerDetail",
    showOverflowTooltip: true,
    minWidth: 120,
    align: "center",
  },
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 , align: "center"},
  { label: "设施类型", prop: "facilityType", showOverflowTooltip: true, minWidth: 120 , align: "center"},
  { label: "安装位置", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 , align: "center"},
  { label: "安装时间", prop: "installTime", minWidth: 120 , align: "center"},
  {
    label: "状态", prop: "status", minWidth: 100, dataType: "tag", align: "center",
    formatType: params => {
      const map = { 正常: "success", 异常: "danger", 报废: "info" };
      return map[params] || "info";
    }
  },
  {
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 200,
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 140,
    operation: [
      { name: "编辑", type: "text", clickFun: row => openLedgerForm("edit", row) },
      { name: "发起巡检", type: "text", clickFun: row => openInspectionForm("add", row) },
      { name: "删除", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteLedger(row) }
      { name: "删除", type: "text", clickFun: row => handleDeleteLedger(row) }
    ]
  }
]);
// 巡检任务表格列配置
const taskTableColumn = ref([
  {
    label: "巡检任务名称",
    prop: "inspectionName",
    dataType: "link",
    linkMethod: "openTaskDetail",
    showOverflowTooltip: true,
    minWidth: 170,
    align: "left"
  },
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 155, align: "left" },
  { label: "巡检项目", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 190, align: "left" },
  { label: "执行巡检人", prop: "inspectorName", minWidth: 120, align: "center" },
  {
    label: "是否启用",
    prop: "isEnabled",
    minWidth: 90,
    align: "center",
    dataType: "tag",
    formatData: value => value === 1 ? "是" : "否",
    formatType: value => value === 1 ? "success" : "info"
  },
  {
    label: "频次",
    prop: "frequencyType",
    minWidth: 90,
    align: "center",
    formatData: value => frequencyTypeMap[value] || value || "--"
  },
  {
    label: "执行时间",
    prop: "frequencyDetail",
    minWidth: 120,
    align: "center",
    formatData: value => formatFrequencyDetail(value)
  },
  { label: "下次执行时间", prop: "nextExecutionTime", minWidth: 170, showOverflowTooltip: true, align: "center" },
  {
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 220,
    operation: [
      { name: "历史巡检", type: "text", clickFun: row => openTaskHistory(row) },
      { name: "编辑", type: "text", clickFun: row => openTaskDialog("edit", row) },
      { name: "删除", type: "text", clickFun: row => handleDeleteTask(row) }
    ]
  }
]);
const taskHistoryTableColumn = ref([
  {
    label: "巡检编号",
    prop: "inspectionCode",
    dataType: "link",
    linkMethod: "openInspectionDetail",
    showOverflowTooltip: true,
    minWidth: 180,
    align: "center"
  },
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150, align: "left" },
  { label: "巡检项目", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 180, align: "left" },
  { label: "计划巡检时间", prop: "planTime", minWidth: 170, align: "center" },
  { label: "巡检人", prop: "inspectorName", minWidth: 110, align: "center" },
  { label: "实际巡检时间", prop: "actualTime", minWidth: 170, align: "center" },
  {
    label: "检查结果", prop: "checkResult", minWidth: 100, align: "center", dataType: "tag",
    formatData: params => params || "未填写",
    formatType: params => {
      const map = { 正常: "success", 异常: "danger", 未填写: "info" };
      return map[params] || "info";
    }
  },
  {
    label: "状态", prop: "status", minWidth: 100, align: "center", dataType: "tag",
    formatType: params => params === "待巡检" ? "info" : "success"
  }
]);
// 巡检记录表格列配置
const inspectionTableColumn = ref([
  { label: "巡检编号", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
  { label: "设施编号", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
  { label: "巡检类型", prop: "inspectionType", minWidth: 100 },
  { label: "计划巡检时间", prop: "planTime", minWidth: 180 },
  { label: "巡检人", prop: "inspectorName", minWidth: 100 },
  { label: "实际巡检时间", prop: "actualTime", minWidth: 180 },
  {
    label: "巡检编号",
    dataType: "link",
    linkMethod: "openInspectionDetail",
    width: 200,
    align: "center",
    prop: "inspectionCode",
    showOverflowTooltip: true,
    minWidth: 150
  },
  {
    label: "设施名称",
    prop: "facilityName",
    showOverflowTooltip: true,
    minWidth: 150
  },
  {
    label: "巡检项目",
    prop: "inspectionProject",
    showOverflowTooltip: true,
    minWidth: 180
  },
  {
    label: "计划巡检时间",
    prop: "planTime",
    minWidth: 180
  },
  {
    label: "巡检人",
    prop: "inspectorName",
    minWidth: 100
  },
  {
    label: "实际巡检时间",
    prop: "actualTime",
    minWidth: 180
  },
  {
    label: "检查结果", prop: "checkResult", minWidth: 100, dataType: "tag",
    formatType: params => params === "正常" ? "success" : "danger"
    formatData: params => params || "未填写",
    formatType: params => {
      const map = { 正常: "success", 异常: "danger", 未填写: "info" };
      return map[params] || "info";
    }
  },
  {
    label: "状态", prop: "status", minWidth: 100, dataType: "tag",
@@ -506,25 +1321,26 @@
      {
        name: "巡检", type: "text",
        clickFun: row => openInspectionForm("do", row),
        show: row => row.status === "待巡检"
        show: isPendingInspection
      },
      {
        name: "查看", type: "text",
        clickFun: row => openInspectionForm("view", row),
        show: row => row.status !== "待巡检"
        clickFun: row => openInspectionDetail(row),
        show: isCheckedInspection
      },
      {
        name: "整改", type: "text",
        clickFun: row => openRectificationForm("add", row),
        show: row => row.checkResult === "异常"
        clickFun: row => openRectificationFromInspection(row),
        show: row => isCheckedInspection(row) && isAbnormalInspection(row)
      },
      { name: "删除", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteInspection(row) }
      { name: "删除", type: "text", clickFun: row => handleDeleteInspection(row), show: isPendingInspection }
    ]
  }
]);
// 整改跟踪表格列配置
const rectificationTableColumn = ref([
  { label: "巡检编号", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
  { label: "问题描述", prop: "problemDesc", showOverflowTooltip: true, minWidth: 200 },
  {
@@ -540,21 +1356,21 @@
      return map[params] || "info";
    }
  },
  { label: "验收人", prop: "verifyUserName", minWidth: 120 },
  {
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 200,
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 180,
    operation: [
      {
        name: "整改", type: "text",
        clickFun: row => openRectificationForm("do", row),
        show: row => row.status === "待整改" || row.status === "整改中"
        show: isPendingRectification
      },
      {
        name: "验收", type: "text",
        clickFun: row => openRectificationForm("verify", row),
        show: row => row.status === "已整改"
        show: isRectified,
        disabled: isNotAssignedVerifier
      },
      { name: "查看", type: "text", clickFun: row => openRectificationForm("view", row) }
      { name: "查看", type: "text", clickFun: row => openRectificationDetail(row) }
    ]
  }
]);
@@ -562,13 +1378,31 @@
// 生命周期
onMounted(() => {
  getLedgerList();
  getTaskList();
  getInspectionList();
  getRectificationList();
  getFacilityOptionList();
  getUserList();
});
// 标签页切换
const handleTabClick = () => {
  if (activeTab.value === "ledger") getLedgerList();
  else if (activeTab.value === "task") getTaskList();
  else if (activeTab.value === "inspection") getInspectionList();
  else if (activeTab.value === "rectification") getRectificationList();
};
const getUserList = () => {
  userListNoPage().then(res => {
    userList.value = res.data || [];
  });
};
const getFacilityOptionList = () => {
  getFacilityLedgerList({ current: 1, size: 1000 }).then(res => {
    facilityOptions.value = (res.data?.records || []).filter(item => item.status !== "报废");
  });
};
// ============ 设施台账方法 ============
@@ -578,13 +1412,23 @@
  getLedgerList();
};
const resetLedgerQuery = () => {
  Object.assign(ledgerSearchForm.value, {
    facilityCode: "",
    facilityName: "",
    facilityType: "",
    status: ""
  });
  handleLedgerQuery();
};
const getLedgerList = () => {
  ledgerTableLoading.value = true;
  getFacilityLedgerList({ ...ledgerPage.value, ...ledgerSearchForm.value })
    .then(res => {
      ledgerTableLoading.value = false;
      ledgerTableData.value = res.data.records;
      ledgerPage.value.total = res.data.total;
      ledgerTableData.value = res.data?.records || [];
      ledgerPage.value.total = res.data?.total || 0;
    })
    .catch(() => { ledgerTableLoading.value = false; });
};
@@ -599,13 +1443,18 @@
  ledgerSelectedIds.value = selection.map(item => item.id);
};
const openLedgerDetail = row => {
  ledgerDetail.value = { ...row };
  ledgerDetailVisible.value = true;
};
const openLedgerForm = (type, row = null) => {
  ledgerDialogType.value = type;
  if (type === "add") {
    ledgerDialogTitle.value = "新增设施";
    Object.assign(ledgerForm.value, {
      id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
      installLocation: "", installTime: "", productionDate: "", validPeriod: null,
      installLocation: "", installTime: "", productionDate: "",
      status: "正常", remark: ""
    });
  } else {
@@ -624,6 +1473,7 @@
      ElMessage.success(ledgerDialogType.value === "add" ? "添加成功" : "更新成功");
      ledgerDialogVisible.value = false;
      getLedgerList();
      getFacilityOptionList();
    } else {
      ElMessage.error(res.msg || "操作失败");
    }
@@ -640,8 +1490,242 @@
    if (res.code === 200) {
      ElMessage.success("删除成功");
      getLedgerList();
      getFacilityOptionList();
    } else {
      ElMessage.error(res.msg || "删除失败");
    }
  }).catch(() => {});
};
const handleBatchDeleteLedger = () => {
  if (ledgerSelectedIds.value.length === 0) {
    ElMessage.warning("请选择要删除的设施");
    return;
  }
  ElMessageBox.confirm("确认删除选中的设施吗?已产生巡检记录的设施不会被后端允许删除。", "批量删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  }).then(async () => {
    const res = await deleteFacilityLedger(ledgerSelectedIds.value);
    if (res.code === 200) {
      ElMessage.success("删除成功");
      ledgerSelectedIds.value = [];
      getLedgerList();
      getFacilityOptionList();
    } else {
      ElMessage.error(res.msg || "删除失败");
    }
  }).catch(() => {});
};
// ============ 巡检任务方法 ============
const handleTaskQuery = () => {
  taskPage.value.current = 1;
  getTaskList();
};
const resetTaskQuery = () => {
  Object.assign(taskSearchForm.value, {
    inspectionName: "",
    facilityName: "",
    isEnabled: ""
  });
  handleTaskQuery();
};
const getTaskList = () => {
  taskTableLoading.value = true;
  getFacilityInspectionTaskList({ ...taskPage.value, ...taskSearchForm.value })
    .then(res => {
      taskTableLoading.value = false;
      taskTableData.value = res.data?.records || [];
      taskPage.value.total = res.data?.total || 0;
    })
    .catch(() => { taskTableLoading.value = false; });
};
const taskPagination = obj => {
  taskPage.value.current = obj.page;
  taskPage.value.size = obj.limit;
  getTaskList();
};
const handleTaskSelectionChange = selection => {
  taskSelectedIds.value = selection.map(item => item.id);
};
const openTaskDetail = row => {
  taskDetail.value = { ...row };
  taskDetailVisible.value = true;
};
const openTaskDialog = (type, row = null) => {
  resetTaskForm();
  taskDialogTitle.value = type === "add" ? "新增巡检任务" : "编辑巡检任务";
  if (type === "edit" && row) {
    Object.assign(taskForm.value, {
      id: row.id,
      inspectionName: row.inspectionName,
      facilityId: row.facilityId,
      facilityCode: row.facilityCode,
      facilityName: row.facilityName,
      inspectionProject: row.inspectionProject,
      inspectorId: row.inspectorId,
      frequencyType: row.frequencyType,
      frequencyDetail: row.frequencyDetail,
      isEnabled: row.isEnabled ?? ENABLED,
      remark: row.remark
    });
    parseFrequencyDetail(row.frequencyType, row.frequencyDetail);
  }
  taskDialogVisible.value = true;
};
const resetTaskForm = () => {
  Object.assign(taskForm.value, createTaskForm());
  taskFormRef.value?.clearValidate?.();
};
const handleTaskFacilityChange = facilityId => {
  const facility = facilityOptions.value.find(item => Number(item.id) === Number(facilityId));
  taskForm.value.facilityCode = facility?.facilityCode || "";
  taskForm.value.facilityName = facility?.facilityName || "";
};
const handleFrequencyTypeChange = () => {
  Object.assign(taskForm.value, { frequencyDetail: "", week: "", day: "", time: "" });
  taskFormRef.value?.clearValidate?.("frequencyDetail");
};
const parseFrequencyDetail = (frequencyType, frequencyDetail) => {
  if (!frequencyDetail) return;
  if (frequencyType === "DAILY") {
    taskForm.value.frequencyDetail = frequencyDetail;
    return;
  }
  const [firstPart, timePart] = frequencyDetail.split(",");
  taskForm.value.frequencyDetail = "";
  taskForm.value.time = timePart || "";
  if (frequencyType === "WEEKLY") {
    taskForm.value.week = firstPart || "";
  }
  if (frequencyType === "MONTHLY") {
    taskForm.value.day = String(firstPart || "").padStart(2, "0");
  }
};
const buildFrequencyDetail = () => {
  if (taskForm.value.frequencyType === "DAILY") {
    return taskForm.value.frequencyDetail;
  }
  if (taskForm.value.frequencyType === "WEEKLY") {
    return `${taskForm.value.week},${taskForm.value.time}`;
  }
  if (taskForm.value.frequencyType === "MONTHLY") {
    return `${taskForm.value.day},${taskForm.value.time}`;
  }
  return "";
};
const submitTaskForm = async () => {
  try {
    await taskFormRef.value.validate();
    const payload = {
      id: taskForm.value.id,
      inspectionName: taskForm.value.inspectionName,
      facilityId: taskForm.value.facilityId,
      facilityCode: taskForm.value.facilityCode,
      facilityName: taskForm.value.facilityName,
      inspectionProject: taskForm.value.inspectionProject,
      inspectorId: taskForm.value.inspectorId,
      frequencyType: taskForm.value.frequencyType,
      frequencyDetail: buildFrequencyDetail(),
      isEnabled: taskForm.value.isEnabled,
      remark: taskForm.value.remark
    };
    const api = payload.id ? updateFacilityInspectionTask : addFacilityInspectionTask;
    const res = await api(payload);
    if (res.code === 200) {
      ElMessage.success(payload.id ? "修改成功" : "新增成功");
      taskDialogVisible.value = false;
      activeTab.value = "task";
      getTaskList();
    } else {
      ElMessage.error(res.msg || "操作失败");
    }
  } catch (error) {
    console.error("任务表单校验失败:", error);
  }
};
const handleDeleteTask = row => {
  ElMessageBox.confirm("确认删除该定时巡检任务吗?", "删除", {
    confirmButtonText: "确认", cancelButtonText: "取消", type: "warning"
  }).then(async () => {
    const res = await deleteFacilityInspectionTask([row.id]);
    if (res.code === 200) {
      ElMessage.success("删除成功");
      getTaskList();
    } else {
      ElMessage.error(res.msg || "删除失败");
    }
  }).catch(() => {});
};
const handleBatchDeleteTask = () => {
  if (taskSelectedIds.value.length === 0) {
    ElMessage.warning("请选择要删除的巡检任务");
    return;
  }
  ElMessageBox.confirm("确认删除选中的定时巡检任务吗?", "批量删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  }).then(async () => {
    const res = await deleteFacilityInspectionTask(taskSelectedIds.value);
    if (res.code === 200) {
      ElMessage.success("删除成功");
      taskSelectedIds.value = [];
      getTaskList();
    } else {
      ElMessage.error(res.msg || "删除失败");
    }
  }).catch(() => {});
};
const openTaskHistory = row => {
  taskHistoryTask.value = { ...row };
  taskHistoryPage.value.current = 1;
  taskHistoryVisible.value = true;
  getTaskHistoryList();
};
const getTaskHistoryList = () => {
  if (!taskHistoryTask.value?.id) {
    taskHistoryTableData.value = [];
    taskHistoryPage.value.total = 0;
    return;
  }
  taskHistoryTableLoading.value = true;
  getFacilityInspectionList({
    current: taskHistoryPage.value.current,
    size: taskHistoryPage.value.size,
    scheduleTaskId: taskHistoryTask.value.id
  })
    .then(res => {
      taskHistoryTableLoading.value = false;
      taskHistoryTableData.value = res.data?.records || [];
      taskHistoryPage.value.total = res.data?.total || 0;
    })
    .catch(() => { taskHistoryTableLoading.value = false; });
};
const taskHistoryPagination = obj => {
  taskHistoryPage.value.current = obj.page;
  taskHistoryPage.value.size = obj.limit;
  getTaskHistoryList();
};
// ============ 巡检记录方法 ============
@@ -651,13 +1735,21 @@
  getInspectionList();
};
const resetInspectionQuery = () => {
  Object.assign(inspectionSearchForm.value, {
    inspectionCode: "",
    status: ""
  });
  handleInspectionQuery();
};
const getInspectionList = () => {
  inspectionTableLoading.value = true;
  getFacilityInspectionList({ ...inspectionPage.value, ...inspectionSearchForm.value })
    .then(res => {
      inspectionTableLoading.value = false;
      inspectionTableData.value = res.data.records;
      inspectionPage.value.total = res.data.total;
      inspectionTableData.value = res.data?.records || [];
      inspectionPage.value.total = res.data?.total || 0;
    })
    .catch(() => { inspectionTableLoading.value = false; });
};
@@ -668,23 +1760,36 @@
  getInspectionList();
};
const openInspectionDetail = row => {
  inspectionDetail.value = {
    ...row,
    storageBlobDTOs: row.storageBlobVOs || row.storageBlobDTOs || []
  };
  inspectionDetailVisible.value = true;
};
const openInspectionForm = (type, row = null) => {
  if (type === "view") {
    openInspectionDetail(row);
    return;
  }
  inspectionDialogType.value = type;
  if (type === "add") {
    inspectionDialogTitle.value = "发起巡检";
    Object.assign(inspectionForm.value, {
      id: null, facilityId: row.id, inspectionCode: "", inspectionType: "定期巡检",
      planTime: "", checkResult: "", checkDesc: ""
    });
  } else if (type === "do") {
  if (type === "do") {
    inspectionDialogTitle.value = "巡检";
    Object.assign(inspectionForm.value, {
      id: row.id, facilityId: row.facilityId, inspectionCode: row.inspectionCode,
      inspectionType: row.inspectionType, planTime: row.planTime, checkResult: "", checkDesc: ""
      id: row.id,
      scheduleTaskId: row.scheduleTaskId,
      facilityId: row.facilityId,
      facilityCode: row.facilityCode,
      facilityName: row.facilityName,
      inspectionCode: row.inspectionCode,
      inspectionType: row.inspectionType,
      inspectionProject: row.inspectionProject,
      planTime: row.planTime,
      checkResult: "",
      checkDesc: "",
      storageBlobDTOs: []
    });
  } else {
    inspectionDialogTitle.value = "查看巡检";
    Object.assign(inspectionForm.value, { ...row });
  }
  inspectionDialogVisible.value = true;
};
@@ -692,21 +1797,45 @@
const submitInspectionForm = async () => {
  try {
    await inspectionFormRef.value.validate();
    if (inspectionDialogTitle.value === "巡检") {
    if (inspectionDialogType.value === "do") {
      if (!inspectionForm.value.checkResult) {
        ElMessage.warning("请选择检查结果");
        return;
      }
      if (inspectionForm.value.checkResult === "异常" && !inspectionForm.value.checkDesc) {
        ElMessage.warning("检查结果异常时请填写检查说明");
        return;
      }
      if (inspectionForm.value.checkResult === "异常" && !hasAttachments(inspectionForm.value.storageBlobDTOs)) {
        ElMessage.warning("检查结果异常时请上传现场照片");
        return;
      }
      inspectionForm.value.status = "已巡检";
      inspectionForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
      inspectionForm.value.actualTime = formatDateTime();
    }
    const api = inspectionForm.value.id ? updateFacilityInspection : addFacilityInspection;
    const res = await api({ ...inspectionForm.value });
    const res = await updateFacilityInspection({ ...inspectionForm.value });
    if (res.code === 200) {
      ElMessage.success("操作成功");
      inspectionDialogVisible.value = false;
      getInspectionList();
      if (inspectionDialogType.value === "do" && inspectionForm.value.checkResult === "异常") {
        ElMessageBox.confirm("本次巡检结果为异常,是否立即创建整改跟踪?", "创建整改", {
          confirmButtonText: "创建整改",
          cancelButtonText: "稍后处理",
          type: "warning"
        }).then(() => {
          openRectificationFromInspection({ ...inspectionForm.value });
        }).catch(() => {});
      }
    } else {
      ElMessage.error(res.msg || "操作失败");
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
const hasAttachments = attachments => Array.isArray(attachments) && attachments.length > 0;
const handleDeleteInspection = row => {
  ElMessageBox.confirm("确认删除该巡检记录吗?", "删除", {
@@ -716,6 +1845,8 @@
    if (res.code === 200) {
      ElMessage.success("删除成功");
      getInspectionList();
    } else {
      ElMessage.error(res.msg || "删除失败");
    }
  }).catch(() => {});
};
@@ -727,13 +1858,20 @@
  getRectificationList();
};
const resetRectificationQuery = () => {
  Object.assign(rectificationSearchForm.value, {
    status: ""
  });
  handleRectificationQuery();
};
const getRectificationList = () => {
  rectificationTableLoading.value = true;
  getFacilityRectificationList({ ...rectificationPage.value, ...rectificationSearchForm.value })
    .then(res => {
      rectificationTableLoading.value = false;
      rectificationTableData.value = res.data.records;
      rectificationPage.value.total = res.data.total;
      rectificationTableData.value = res.data?.records || [];
      rectificationPage.value.total = res.data?.total || 0;
    })
    .catch(() => { rectificationTableLoading.value = false; });
};
@@ -744,32 +1882,129 @@
  getRectificationList();
};
const getExistingRectification = async inspectionId => {
  if (!inspectionId) return null;
  const res = await getFacilityRectificationList({ current: 1, size: 1, inspectionId });
  return res.data?.records?.[0] || null;
};
const getRectificationDialogType = row => {
  if (isPendingRectification(row)) return "do";
  if (isRectified(row)) return "verify";
  return "view";
};
const openRectificationDetail = row => {
  rectificationDetail.value = {
    ...row,
    storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
  };
  rectificationDetailVisible.value = true;
};
const openRectificationFromInspection = async row => {
  const existing = await getExistingRectification(row.id);
  activeTab.value = "rectification";
  if (existing) {
    ElMessage.info("该巡检已存在整改记录,已为你打开对应处理窗口");
    existing.inspectionCode = existing.inspectionCode || row.inspectionCode;
    existing.facilityCode = existing.facilityCode || row.facilityCode;
    existing.facilityName = existing.facilityName || row.facilityName;
    openRectificationForm(getRectificationDialogType(existing), existing);
    return;
  }
  openRectificationForm("add", row);
};
const openRectificationForm = (type, row = null) => {
  if (type === "view") {
    openRectificationDetail(row);
    return;
  }
  rectificationDialogType.value = type;
  if (type === "add") {
    rectificationDialogTitle.value = "新增整改";
    Object.assign(rectificationForm.value, {
      id: null, inspectionId: row.id, facilityId: row.facilityId,
      problemDesc: "", problemLevel: "", rectifyDesc: "", verifyDesc: ""
      id: null,
      inspectionId: row.id,
      facilityId: row.facilityId,
      facilityName: row.facilityName || "",
      facilityCode: row.facilityCode || "",
      inspectionCode: row.inspectionCode || "",
      problemDesc: row.checkDesc || "",
      problemLevel: "一般",
      rectifyUserId: currentUserId.value || "",
      rectifyUserName: getUserName(currentUserId.value),
      verifyUserId: "",
      verifyUserName: "",
      planTime: addDaysDateTime(1),
      actualTime: "",
      rectifyDesc: "",
      verifyTime: "",
      verifyDesc: "",
      status: "待整改",
      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
    });
  } else if (type === "do") {
    rectificationDialogTitle.value = "整改";
    Object.assign(rectificationForm.value, {
      id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
      problemDesc: row.problemDesc, problemLevel: row.problemLevel, rectifyDesc: "", verifyDesc: ""
      ...row,
      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
      rectifyDesc: row.rectifyDesc || "",
      verifyDesc: row.verifyDesc || ""
    });
  } else if (type === "verify") {
    rectificationDialogTitle.value = "验收";
    Object.assign(rectificationForm.value, {
      id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
      problemDesc: row.problemDesc, problemLevel: row.problemLevel,
      rectifyDesc: row.rectifyDesc, verifyDesc: ""
      ...row,
      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
      verifyDesc: row.verifyDesc || ""
    });
  } else {
    rectificationDialogTitle.value = "查看整改";
    Object.assign(rectificationForm.value, { ...row });
    Object.assign(rectificationForm.value, {
      ...row,
      storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
    });
  }
  rectificationDialogVisible.value = true;
};
const buildRectificationPayload = () => {
  const {
    id,
    inspectionId,
    facilityId,
    problemDesc,
    problemLevel,
    problemImage,
    rectifyUserId,
    planTime,
    actualTime,
    rectifyDesc,
    rectifyImage,
    status,
    verifyUserId,
    verifyTime,
    verifyDesc
  } = rectificationForm.value;
  return {
    id,
    inspectionId,
    facilityId,
    problemDesc,
    problemLevel,
    problemImage,
    rectifyUserId,
    planTime,
    actualTime,
    rectifyDesc,
    rectifyImage,
    status,
    verifyUserId,
    verifyTime,
    verifyDesc
  };
};
const submitRectificationForm = async () => {
@@ -777,27 +2012,95 @@
    rectificationDialogVisible.value = false;
    return;
  }
  if (rectificationDialogTitle.value === "整改") {
  try {
    await rectificationFormRef.value.validate();
  } catch (error) {
    console.error("表单验证失败:", error);
    return;
  }
  if (rectificationDialogType.value === "do") {
    rectificationForm.value.status = "已整改";
    rectificationForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
  } else if (rectificationDialogTitle.value === "验收") {
    rectificationForm.value.actualTime = formatDateTime();
  } else if (rectificationDialogType.value === "verify") {
    rectificationForm.value.status = "已验收";
    rectificationForm.value.verifyTime = new Date().toISOString().replace("T", " ").substring(0, 19);
    rectificationForm.value.verifyTime = formatDateTime();
  }
  const api = rectificationForm.value.id ? updateFacilityRectification : addFacilityRectification;
  const res = await api({ ...rectificationForm.value });
  const res = await api(buildRectificationPayload());
  if (res.code === 200) {
    ElMessage.success("操作成功");
    rectificationDialogVisible.value = false;
    getRectificationList();
    getInspectionList();
  } else {
    ElMessage.error(res.msg || "操作失败");
  }
};
</script>
<style scoped>
.safety-facility-page {
  padding-top: 4px;
}
.facility-tabs {
  width: 100%;
}
.facility-tabs :deep(.el-tabs__header) {
  margin-bottom: 18px;
}
.facility-tabs :deep(.el-tabs__nav-wrap::after) {
  height: 1px;
  background-color: #d8e2ef;
}
.facility-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px 18px;
  min-height: 44px;
  margin-bottom: 18px;
}
.toolbar-filters,
.toolbar-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 12px;
}
.toolbar-actions {
  margin-left: auto;
}
.table_list {
  padding-top: 6px;
}
.history-summary {
  margin-bottom: 16px;
}
.table_list :deep(.link) {
  color: var(--el-color-primary);
  cursor: pointer;
  font-weight: 600;
}
.table_list :deep(.link:hover) {
  text-decoration: underline;
}
.search_title {
  font-size: 14px;
  font-weight: 600;
  color: #606266;
  white-space: nowrap;
}
.mb20 {
@@ -807,4 +2110,147 @@
.ml10 {
  margin-left: 10px;
}
.toolbar-filters .ml10 {
  margin-left: 0;
}
.facility-form-dialog :deep(.el-dialog__body) {
  padding: 24px 32px 10px;
}
.facility-form-dialog :deep(.el-dialog__footer) {
  padding: 8px 32px 26px;
}
.dialog-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 20px;
  padding: 14px 18px;
  border: 1px solid #e4eaf3;
  border-radius: 6px;
  background: #f7faff;
}
.summary-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.summary-item span {
  flex: 0 0 auto;
  color: #7a8599;
}
.summary-item strong {
  min-width: 0;
  overflow: hidden;
  color: #25324b;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.inspection-form-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 0.8fr);
  column-gap: 20px;
}
.inspection-form-grid .form-grid-full {
  grid-column: 1 / -1;
}
.inspection-form :deep(.el-form-item) {
  margin-bottom: 20px;
}
.inspection-form :deep(.el-form-item__label) {
  margin-bottom: 8px;
  padding: 0;
  font-weight: 600;
  color: #25324b;
  line-height: 1.2;
}
.rectification-image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.rectification-image {
  width: 96px;
  height: 96px;
  border: 1px solid #dbe4f0;
  border-radius: 6px;
  background: #f8fafc;
}
.detail-dialog :deep(.el-dialog__body) {
  padding: 24px 32px 8px;
}
.detail-dialog :deep(.el-descriptions__label) {
  width: 130px;
  color: #4d5b73;
  font-weight: 600;
  background: #f4f7fb;
}
.detail-dialog :deep(.el-descriptions__content) {
  color: #25324b;
  word-break: break-word;
}
.detail-section {
  margin-top: 18px;
}
.detail-section-title {
  margin-bottom: 10px;
  color: #25324b;
  font-weight: 600;
}
.detail-image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.detail-image {
  width: 96px;
  height: 96px;
  border: 1px solid #dbe4f0;
  border-radius: 6px;
  background: #f8fafc;
}
.frequency-row {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 12px;
}
.frequency-time-picker {
  min-width: 0;
  flex: 1;
}
.frequency-day-select {
  flex: 0 0 132px;
  width: 132px;
}
@media (max-width: 900px) {
  .inspection-form-grid,
  .dialog-summary {
    grid-template-columns: 1fr;
  }
}
</style>