liding
2026-06-29 0457ff29c076e9986df9941b784be35f80e67e2a
feat: 添加线路巡检和安全设施巡检模块
已修改4个文件
2504 ■■■■ 文件已修改
src/api/safeProduction/lineInspection.js 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/safeProduction/safetyFacility.js 130 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/lineInspection/index.vue 1166 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/safetyFacility/index.vue 1099 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/safeProduction/lineInspection.js
@@ -7,36 +7,119 @@
// 获取线路巡检列表
export function getLineInspectionList(params) {
  return request({
    url: "/device/lineInspection/list",
    url: "/safeLineInspection/page",
    method: "get",
    params,
  });
}
// 新增或修改线路巡检记录
export function addOrEditLineInspection(data) {
// 根据ID获取线路巡检详情
export function getLineInspectionById(id) {
  return request({
    url: "/device/lineInspection/addOrEdit",
    url: `/safeLineInspection/${id}`,
    method: "get",
  });
}
// 新增线路巡检
export function addLineInspection(data) {
  return request({
    url: "/safeLineInspection",
    method: "post",
    data,
  });
}
// 删除线路巡检记录
export function deleteLineInspection(ids) {
// 修改线路巡检
export function updateLineInspection(data) {
  return request({
    url: "/device/lineInspection/delete",
    method: "delete",
    data: ids,
    url: "/safeLineInspection",
    method: "put",
    data,
  });
}
// 导出线路巡检记录
export function exportLineInspection(params) {
// 删除线路巡检
export function deleteLineInspection(ids) {
  return request({
    url: "/device/lineInspection/export",
    url: "/safeLineInspection/" + ids.join(","),
    method: "delete",
  });
}
// 完成巡检
export function completeLineInspection(id) {
  return request({
    url: `/safeLineInspection/complete/${id}`,
    method: "put",
  });
}
// 获取巡检记录列表
export function getInspectionRecords(inspectionId) {
  return request({
    url: `/safeLineInspectionRecord/list/${inspectionId}`,
    method: "get",
  });
}
// 新增巡检记录
export function addInspectionRecord(data) {
  return request({
    url: "/safeLineInspectionRecord",
    method: "post",
    data,
  });
}
// 批量新增巡检记录
export function batchAddInspectionRecords(data) {
  return request({
    url: "/safeLineInspectionRecord/batch",
    method: "post",
    data,
  });
}
// 获取巡检隐患列表
export function getInspectionHazards(params) {
  return request({
    url: "/safeLineInspectionHazard/page",
    method: "get",
    params,
    responseType: 'blob',
  });
}
// 根据巡检任务ID获取隐患列表
export function getHazardsByInspectionId(inspectionId) {
  return request({
    url: `/safeLineInspectionHazard/list/${inspectionId}`,
    method: "get",
  });
}
// 新增隐患
export function addInspectionHazard(data) {
  return request({
    url: "/safeLineInspectionHazard",
    method: "post",
    data,
  });
}
// 修改隐患
export function updateInspectionHazard(data) {
  return request({
    url: "/safeLineInspectionHazard",
    method: "put",
    data,
  });
}
// 删除隐患
export function deleteInspectionHazard(ids) {
  return request({
    url: "/safeLineInspectionHazard/" + ids.join(","),
    method: "delete",
  });
}
src/api/safeProduction/safetyFacility.js
@@ -4,39 +4,137 @@
 * 安全设施巡检API接口
 */
// 获取安全设施列表
export function getSafetyFacilityList(params) {
// ============ 安全设施台账 ============
// 获取安全设施台账列表
export function getFacilityLedgerList(params) {
  return request({
    url: "/device/safetyFacility/list",
    url: "/safeFacilityLedger/page",
    method: "get",
    params,
  });
}
// 新增或修改安全设施
export function addOrEditSafetyFacility(data) {
// 根据ID获取安全设施台账详情
export function getFacilityLedgerById(id) {
  return request({
    url: "/device/safetyFacility/addOrEdit",
    url: `/safeFacilityLedger/${id}`,
    method: "get",
  });
}
// 新增安全设施台账
export function addFacilityLedger(data) {
  return request({
    url: "/safeFacilityLedger",
    method: "post",
    data,
  });
}
// 删除安全设施
export function deleteSafetyFacility(ids) {
// 修改安全设施台账
export function updateFacilityLedger(data) {
  return request({
    url: "/device/safetyFacility/delete",
    method: "delete",
    data: ids,
    url: "/safeFacilityLedger",
    method: "put",
    data,
  });
}
// 导出安全设施记录
export function exportSafetyFacility(params) {
// 删除安全设施台账
export function deleteFacilityLedger(ids) {
  return request({
    url: "/device/safetyFacility/export",
    method: "post",
    url: "/safeFacilityLedger/" + ids.join(","),
    method: "delete",
  });
}
// ============ 安全设施巡检 ============
// 获取安全设施巡检列表
export function getFacilityInspectionList(params) {
  return request({
    url: "/safeFacilityInspection/page",
    method: "get",
    params,
    responseType: 'blob',
  });
}
// 根据ID获取安全设施巡检详情
export function getFacilityInspectionById(id) {
  return request({
    url: `/safeFacilityInspection/${id}`,
    method: "get",
  });
}
// 新增安全设施巡检
export function addFacilityInspection(data) {
  return request({
    url: "/safeFacilityInspection",
    method: "post",
    data,
  });
}
// 修改安全设施巡检
export function updateFacilityInspection(data) {
  return request({
    url: "/safeFacilityInspection",
    method: "put",
    data,
  });
}
// 删除安全设施巡检
export function deleteFacilityInspection(ids) {
  return request({
    url: "/safeFacilityInspection/" + ids.join(","),
    method: "delete",
  });
}
// ============ 安全设施整改 ============
// 获取安全设施整改列表
export function getFacilityRectificationList(params) {
  return request({
    url: "/safeFacilityRectification/page",
    method: "get",
    params,
  });
}
// 根据ID获取安全设施整改详情
export function getFacilityRectificationById(id) {
  return request({
    url: `/safeFacilityRectification/${id}`,
    method: "get",
  });
}
// 新增安全设施整改
export function addFacilityRectification(data) {
  return request({
    url: "/safeFacilityRectification",
    method: "post",
    data,
  });
}
// 修改安全设施整改
export function updateFacilityRectification(data) {
  return request({
    url: "/safeFacilityRectification",
    method: "put",
    data,
  });
}
// 删除安全设施整改
export function deleteFacilityRectification(ids) {
  return request({
    url: "/safeFacilityRectification/" + ids.join(","),
    method: "delete",
  });
}
src/views/safeProduction/lineInspection/index.vue
@@ -1,374 +1,918 @@
<template>
  <div class="line-inspection">
    <!-- 搜索区域 -->
    <div class="search-area">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="任务名称">
          <el-input v-model="searchForm.taskName" placeholder="请输入任务名称" clearable />
        </el-form-item>
        <el-form-item label="线路名称">
          <el-input v-model="searchForm.routeName" placeholder="请输入线路名称" clearable />
        </el-form-item>
        <el-form-item label="巡检人">
          <el-input v-model="searchForm.inspector" placeholder="请输入巡检人" clearable />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
  <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-option label="已完成" value="已完成" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">
          搜索
        </el-button>
      </div>
      <div>
        <el-button type="primary"
                   @click="openForm('add')">新增巡检任务</el-button>
      </div>
    </div>
    <!-- 操作按钮 -->
    <div class="actions">
      <el-button type="primary" @click="handleAdd">新增巡检</el-button>
      <el-button type="success" @click="handleExport">导出</el-button>
    <div 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>
    <!-- 巡检列表 -->
    <el-table :data="inspectionList" style="width: 100%; margin-top: 10px;" border>
      <el-table-column prop="taskName" label="任务名称" width="180" />
      <el-table-column prop="routeName" label="线路名称" width="180" />
      <el-table-column prop="deviceName" label="关联设备" width="150" />
      <el-table-column prop="inspector" label="巡检人" width="120" />
      <el-table-column prop="inspectionTime" label="巡检时间" width="180" />
      <el-table-column prop="inspectionResult" label="巡检结果" width="120">
        <template #default="{ row }">
          <el-tag :type="row.inspectionResult === '正常' ? 'success' : 'danger'">
            {{ row.inspectionResult || '未巡检' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="status" label="状态" width="120">
        <template #default="{ row }">
          <el-tag :type="getStatusType(row.status)">
            {{ row.status }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="200" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
          <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        v-model:current-page="pagination.currentPage"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" v-model="showDialog" width="600px">
      <el-form :model="form" :rules="formRules" ref="formRef" label-width="100px">
        <el-form-item label="任务名称" prop="taskName">
          <el-input v-model="form.taskName" placeholder="请输入任务名称" />
    <!-- 新增/编辑巡检任务弹窗 -->
    <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-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="巡检编号"
                          prop="inspectionCode">
              <el-input v-model="form.inspectionCode"
                        placeholder="请输入巡检编号" />
        </el-form-item>
        <el-form-item label="线路名称" prop="routeName">
          <el-input v-model="form.routeName" placeholder="请输入线路名称" />
          </el-col>
          <el-col :span="12">
            <el-form-item label="巡检名称"
                          prop="inspectionName">
              <el-input v-model="form.inspectionName"
                        placeholder="请输入巡检名称" />
        </el-form-item>
        <el-form-item label="关联设备">
          <el-select v-model="form.deviceId" placeholder="请选择设备" clearable>
            <el-option
              v-for="item in deviceOptions"
              :key="item.id"
              :label="item.deviceName"
              :value="item.id"
            />
          </el-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>
          </el-col>
          <el-col :span="12">
            <el-form-item label="巡检类型"
                          prop="inspectionType">
              <el-select v-model="form.inspectionType"
                         placeholder="请选择巡检类型"
                         style="width: 100%">
                <el-option label="定期巡检" value="定期巡检" />
                <el-option label="临时巡检" value="临时巡检" />
          </el-select>
        </el-form-item>
        <el-form-item label="巡检人" prop="inspector">
          <el-input v-model="form.inspector" placeholder="请输入巡检人" />
        </el-form-item>
        <el-form-item label="巡检时间">
          <el-date-picker
            v-model="form.inspectionTime"
          </el-col>
        </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="请选择巡检时间"
                              placeholder="请选择计划巡检时间"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
                              style="width: 100%" />
        </el-form-item>
        <el-form-item label="巡检结果">
          <el-radio-group v-model="form.inspectionResult">
            <el-radio label="正常">正常</el-radio>
            <el-radio label="异常">异常</el-radio>
          </el-radio-group>
          </el-col>
          <el-col :span="12">
            <el-form-item label="巡检人"
                          prop="inspectorId">
              <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-select>
        </el-form-item>
        <el-form-item label="隐患描述" v-if="form.inspectionResult === '异常'">
          <el-input type="textarea" v-model="form.hazardDescription" placeholder="请输入隐患描述" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input type="textarea" v-model="form.remarks" placeholder="请输入备注" />
          </el-col>
        </el-row>
        <el-form-item label="备注"
                      prop="remark">
          <el-input v-model="form.remark"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitForm">确定</el-button>
          <el-button @click="showDialog = false">取消</el-button>
          <el-button type="primary"
                     @click="submitForm">确定</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 巡检记录弹窗 -->
    <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"
                   @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-column prop="checkContent" label="检查内容" min-width="200" show-overflow-tooltip />
          <el-table-column prop="checkResult" label="检查结果" width="100">
            <template #default="{ row }">
              <el-tag :type="row.checkResult === '正常' ? 'success' : 'danger'">
                {{ row.checkResult }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="checkDesc" label="检查说明" width="200" show-overflow-tooltip />
          <el-table-column prop="checkTime" label="检查时间" width="180" />
        </el-table>
      </div>
      <!-- 新增记录表单 -->
      <el-dialog v-model="recordFormVisible"
                 title="新增巡检记录"
                 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>
            </el-col>
            <el-col :span="12">
              <el-form-item label="检查结果"
                            prop="checkResult">
                <el-radio-group v-model="recordForm.checkResult">
                  <el-radio label="正常">正常</el-radio>
                  <el-radio label="异常">异常</el-radio>
                </el-radio-group>
              </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>
          <el-form-item label="检查说明">
            <el-input v-model="recordForm.checkDesc"
                      type="textarea"
                      :rows="2"
                      placeholder="请输入检查说明" />
          </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-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <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">
      <div class="mb10">
        <el-button type="primary"
                   size="small"
                   @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-column prop="hazardDesc" label="隐患描述" min-width="200" show-overflow-tooltip />
          <el-table-column prop="hazardLevel" label="隐患等级" width="100">
            <template #default="{ row }">
              <el-tag :type="row.hazardLevel === '重大' ? 'danger' : 'warning'">
                {{ row.hazardLevel }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="hazardLocation" label="隐患位置" width="150" show-overflow-tooltip />
          <el-table-column prop="status" label="状态" width="100">
            <template #default="{ row }">
              <el-tag :type="getHazardStatusType(row.status)">
                {{ row.status }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="rectifyUserName" label="整改责任人" width="120" />
          <el-table-column label="操作" width="150" fixed="right">
            <template #default="{ row }">
              <el-button type="primary" link @click="openHazardForm('edit', row)">编辑</el-button>
              <el-button type="success" link @click="handleRectify(row)" v-if="row.status !== '已整改'">整改</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="请输入隐患描述" />
          </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-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="请输入隐患位置" />
              </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 @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>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from "@element-plus/icons-vue";
import { nextTick, onMounted, ref, reactive, toRefs } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import { userListNoPage } from "@/api/system/user.js";
import {
  getLineInspectionList,
  addOrEditLineInspection,
  addLineInspection,
  updateLineInspection,
  deleteLineInspection,
  exportLineInspection
} from '@/api/safeProduction/lineInspection'
import { getDeviceLedger } from '@/api/equipmentManagement/ledger'
// 搜索表单
const searchForm = reactive({
  taskName: '',
  routeName: '',
  inspector: '',
  status: ''
})
// 分页数据
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})
// 列表数据
const inspectionList = ref([])
// 设备选项
const deviceOptions = ref([])
// 对话框状态
const showDialog = ref(false)
const dialogTitle = ref('新增巡检')
// 表单数据
const form = reactive({
  id: null,
  taskName: '',
  routeName: '',
  deviceId: null,
  inspector: '',
  inspectionTime: '',
  inspectionResult: '',
  hazardDescription: '',
  remarks: ''
})
  completeLineInspection,
  getInspectionRecords,
  addInspectionRecord,
  getHazardsByInspectionId,
  addInspectionHazard,
  updateInspectionHazard
} from "@/api/safeProduction/lineInspection";
// 表单验证规则
const formRules = reactive({
  taskName: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
  routeName: [{ required: true, message: '请输入线路名称', trigger: 'blur' }],
  inspector: [{ required: true, message: '请输入巡检人', trigger: 'blur' }]
})
const rules = {
  inspectionCode: [{ required: true, message: "请输入巡检编号", trigger: "blur" }],
  inspectionName: [{ required: true, message: "请输入巡检名称", trigger: "blur" }],
  lineName: [{ required: true, message: "请输入线路名称", trigger: "blur" }]
};
const formRef = ref(null)
const recordRules = {
  checkPoint: [{ required: true, message: "请输入检查点", trigger: "blur" }],
  checkContent: [{ required: true, message: "请输入检查内容", trigger: "blur" }],
  checkResult: [{ required: true, message: "请选择检查结果", trigger: "change" }]
};
// 获取状态标签类型
const getStatusType = (status) => {
  const map = {
    '待巡检': 'info',
    '进行中': 'warning',
    '已完成': 'success'
  }
  return map[status] || 'info'
}
const hazardRules = {
  hazardDesc: [{ required: true, message: "请输入隐患描述", trigger: "blur" }],
  hazardLevel: [{ required: true, message: "请选择隐患等级", trigger: "change" }],
  hazardLocation: [{ required: true, message: "请输入隐患位置", trigger: "blur" }]
};
// 获取巡检列表
const fetchList = async () => {
  try {
    const params = {
      ...searchForm,
      current: pagination.currentPage,
      size: pagination.pageSize
    }
    const res = await getLineInspectionList(params)
    if (res.code === 200) {
      inspectionList.value = res.data.records || []
      pagination.total = res.data.total || 0
    } else {
      ElMessage.error(res.message || '获取列表失败')
    }
  } catch (error) {
    ElMessage.error('获取列表失败')
  }
}
// 获取设备列表
const fetchDeviceOptions = async () => {
  try {
    const res = await getDeviceLedger()
    if (res.code === 200) {
      deviceOptions.value = res.data || []
    }
  } catch (error) {
    console.error('获取设备列表失败')
  }
}
// 搜索
const handleSearch = () => {
  pagination.currentPage = 1
  fetchList()
}
// 重置搜索
const resetSearch = () => {
  Object.assign(searchForm, {
    taskName: '',
    routeName: '',
    inspector: '',
    status: ''
  })
  handleSearch()
}
// 新增
const handleAdd = () => {
  dialogTitle.value = '新增巡检'
  Object.assign(form, {
// 响应式数据
const data = reactive({
  searchForm: {
    inspectionCode: "",
    inspectionName: "",
    lineName: "",
    status: ""
  },
  tableLoading: false,
  page: {
    current: 1,
    size: 20,
    total: 0
  },
  tableData: [],
  selectedIds: [],
  form: {
    id: null,
    taskName: '',
    routeName: '',
    deviceId: null,
    inspector: '',
    inspectionTime: '',
    inspectionResult: '',
    hazardDescription: '',
    remarks: ''
  })
  showDialog.value = true
    inspectionCode: "",
    inspectionName: "",
    lineName: "",
    inspectionType: "",
    planTime: "",
    inspectorId: "",
    inspectorIds: [],
    remark: ""
  },
  dialogVisible: false,
  dialogTitle: "",
  dialogType: "add",
  // 巡检记录
  currentInspectionId: null,
  recordDialogVisible: false,
  recordFormVisible: false,
  recordList: [],
  recordForm: {
    inspectionId: null,
    checkPoint: "",
    checkContent: "",
    checkResult: "正常",
    checkDesc: "",
    checkTime: ""
  },
  // 隐患管理
  hazardDialogVisible: false,
  hazardFormVisible: false,
  hazardDialogTitle: "上报隐患",
  hazardList: [],
  hazardForm: {
    id: null,
    inspectionId: null,
    hazardDesc: "",
    hazardLevel: "",
    hazardLocation: ""
  },
  rectifyFormVisible: false,
  rectifyForm: {
    id: null,
    rectifyDesc: ""
}
});
// 编辑
const handleEdit = (row) => {
  dialogTitle.value = '编辑巡检'
  Object.assign(form, {
const {
  searchForm,
  tableLoading,
  page,
  tableData,
  selectedIds,
  form,
  dialogVisible,
  dialogTitle,
  dialogType,
  currentInspectionId,
  recordDialogVisible,
  recordFormVisible,
  recordList,
  recordForm,
  hazardDialogVisible,
  hazardFormVisible,
  hazardDialogTitle,
  hazardList,
  hazardForm,
  rectifyFormVisible,
  rectifyForm
} = toRefs(data);
// 表单引用
const formRef = ref();
const recordFormRef = ref();
const hazardFormRef = ref();
const rectifyFormRef = ref();
const userList = ref([]);
// 表格列配置
const tableColumn = ref([
  {
    label: "巡检编号",
    prop: "inspectionCode",
    showOverflowTooltip: true,
    minWidth: 150
  },
  {
    label: "巡检名称",
    prop: "inspectionName",
    showOverflowTooltip: true,
    minWidth: 180
  },
  {
    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";
    }
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 350,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: row => {
          openForm("edit", row);
        },
        show: 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 === "巡检中"
      },
      {
        name: "删除",
        type: "text",
        style: { color: "#F56C6C" },
        clickFun: row => {
          handleDelete(row);
        },
        show: row => row.status === "待巡检"
      }
    ]
  }
]);
// 生命周期
onMounted(() => {
  getList();
  userListNoPage().then(res => {
    userList.value = res.data;
  });
});
// 弹窗固定高度处理
const setDialogFixedHeight = () => {
  setTimeout(() => {
    // 直接在 body 上找所有 el-dialog(teleport 渲染到 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 = () => {
  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;
    });
};
// 分页处理
const pagination = obj => {
  page.value.current = obj.page;
  page.value.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 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 = "编辑巡检任务";
    // 将逗号分隔的ID字符串转换为数组
    const inspectorIds = row.inspectorId
      ? row.inspectorId.split(",").map(id => parseInt(id.trim())).filter(id => !isNaN(id))
      : [];
    Object.assign(form.value, {
    id: row.id,
    taskName: row.taskName,
    routeName: row.routeName,
    deviceId: row.deviceId,
    inspector: row.inspector,
    inspectionTime: row.inspectionTime,
    inspectionResult: row.inspectionResult,
    hazardDescription: row.hazardDescription,
    remarks: row.remarks
  })
  showDialog.value = true
      inspectionCode: row.inspectionCode,
      inspectionName: row.inspectionName,
      lineName: row.lineName,
      inspectionType: row.inspectionType,
      planTime: row.planTime,
      inspectorId: row.inspectorId,
      inspectorIds: inspectorIds,
      remark: row.remark
    });
}
// 删除
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确认删除该巡检记录吗?', '提示', {
      type: 'warning'
    })
    const res = await deleteLineInspection([row.id])
    if (res.code === 200) {
      ElMessage.success('删除成功')
      fetchList()
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error) {
    // 取消删除
  }
}
  dialogVisible.value = true;
};
// 提交表单
const submitForm = async () => {
  if (!formRef.value) return
  try {
    await formRef.value.validate()
    const res = await addOrEditLineInspection(form)
    await formRef.value.validate();
    // 将数组转换为逗号分隔的字符串
    const submitData = {
      ...form.value,
      inspectorId: form.value.inspectorIds ? form.value.inspectorIds.join(",") : ""
    };
    delete submitData.inspectorIds;
    const api = dialogType.value === "add" ? addLineInspection : updateLineInspection;
    const res = await api(submitData);
    if (res.code === 200) {
      ElMessage.success('操作成功')
      showDialog.value = false
      fetchList()
      ElMessage.success(dialogType.value === "add" ? "添加成功" : "更新成功");
      dialogVisible.value = false;
      getList();
    } else {
      ElMessage.error(res.message || '操作失败')
      ElMessage.error(res.msg || "操作失败");
    }
  } catch (error) {
    ElMessage.error('请填写完整表单信息')
    console.error("表单验证失败:", error);
  }
}
};
// 导出
const handleExport = async () => {
  try {
    const res = await exportLineInspection(searchForm)
    const blob = new Blob([res])
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '线路巡检记录.xlsx'
    link.click()
    window.URL.revokeObjectURL(url)
    ElMessage.success('导出成功')
  } catch (error) {
    ElMessage.error('导出失败')
  }
}
// 分页大小改变
const handleSizeChange = (val) => {
  pagination.pageSize = val
  fetchList()
}
// 当前页改变
const handleCurrentChange = (val) => {
  pagination.currentPage = val
  fetchList()
}
onMounted(() => {
  fetchList()
  fetchDeviceOptions()
// 删除
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 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 openRecordDialog = row => {
  currentInspectionId.value = row.id;
  fetchRecords(row.id);
  recordDialogVisible.value = true;
};
// 获取巡检记录
const fetchRecords = async inspectionId => {
  const res = await getInspectionRecords(inspectionId);
  if (res.code === 200) {
    recordList.value = res.data || [];
  }
};
// 打开记录表单
const openRecordForm = () => {
  Object.assign(recordForm.value, {
    inspectionId: currentInspectionId.value,
    checkPoint: "",
    checkContent: "",
    checkResult: "正常",
    checkDesc: "",
    checkTime: ""
  });
  recordFormVisible.value = true;
};
// 提交记录表单
const submitRecordForm = async () => {
  try {
    await recordFormRef.value.validate();
    const res = await addInspectionRecord({ ...recordForm.value });
    if (res.code === 200) {
      ElMessage.success("添加成功");
      recordFormVisible.value = false;
      fetchRecords(currentInspectionId.value);
    } else {
      ElMessage.error(res.msg || "添加失败");
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
// 打开隐患管理弹窗
const openHazardDialog = row => {
  currentInspectionId.value = row.id;
  fetchHazards(row.id);
  hazardDialogVisible.value = true;
};
// 获取隐患列表
const fetchHazards = async inspectionId => {
  const res = await getHazardsByInspectionId(inspectionId);
  if (res.code === 200) {
    hazardList.value = res.data || [];
  }
};
// 打开隐患表单
const openHazardForm = (type, row = null) => {
  if (type === "add") {
    hazardDialogTitle.value = "上报隐患";
    Object.assign(hazardForm.value, {
      id: null,
      inspectionId: currentInspectionId.value,
      hazardDesc: "",
      hazardLevel: "",
      hazardLocation: ""
    });
  } else {
    hazardDialogTitle.value = "编辑隐患";
    Object.assign(hazardForm.value, {
      id: row.id,
      inspectionId: row.inspectionId,
      hazardDesc: row.hazardDesc,
      hazardLevel: row.hazardLevel,
      hazardLocation: row.hazardLocation
    });
  }
  hazardFormVisible.value = true;
};
// 提交隐患表单
const submitHazardForm = async () => {
  try {
    await hazardFormRef.value.validate();
    const api = hazardForm.value.id ? updateInspectionHazard : addInspectionHazard;
    const res = await api({ ...hazardForm.value });
    if (res.code === 200) {
      ElMessage.success("操作成功");
      hazardFormVisible.value = false;
      fetchHazards(currentInspectionId.value);
    } else {
      ElMessage.error(res.msg || "操作失败");
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
// 整改
const handleRectify = row => {
  Object.assign(rectifyForm.value, {
    id: row.id,
    rectifyDesc: ""
  });
  rectifyFormVisible.value = true;
};
// 提交整改表单
const submitRectifyForm = async () => {
  const res = await updateInspectionHazard({
    id: rectifyForm.value.id,
    status: "已整改",
    rectifyDesc: rectifyForm.value.rectifyDesc
  });
  if (res.code === 200) {
    ElMessage.success("整改成功");
    rectifyFormVisible.value = false;
    fetchHazards(currentInspectionId.value);
  } else {
    ElMessage.error(res.msg || "整改失败");
  }
};
</script>
<style scoped>
.line-inspection {
  padding: 20px;
.search_title {
  font-size: 14px;
  color: #606266;
}
.search-area {
  background: #f5f7fa;
  padding: 20px;
  border-radius: 4px;
  margin-bottom: 15px;
.mb10 {
  margin-bottom: 10px;
}
.actions {
  margin-bottom: 15px;
.mb20 {
  margin-bottom: 20px;
}
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
.ml10 {
  margin-left: 10px;
}
</style>
src/views/safeProduction/safetyFacility/index.vue
@@ -1,151 +1,367 @@
<template>
  <div class="safety-facility">
    <!-- 搜索区域 -->
    <div class="search-area">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="设施名称">
          <el-input v-model="searchForm.facilityName" placeholder="请输入设施名称" clearable />
        </el-form-item>
        <el-form-item label="设施类型">
          <el-select v-model="searchForm.facilityType" placeholder="请选择类型" clearable>
  <div class="app-container">
    <el-tabs v-model="activeTab" @tab-click="handleTabClick">
      <!-- 安全设施台账 -->
      <el-tab-pane label="安全设施台账" name="ledger">
        <div class="search_form mb20">
          <div>
            <span class="search_title">设施编号:</span>
            <el-input v-model="ledgerSearchForm.facilityCode"
                      style="width: 200px"
                      placeholder="请输入设施编号"
                      @change="handleLedgerQuery"
                      clearable
                      :prefix-icon="Search" />
            <span class="search_title ml10">设施名称:</span>
            <el-input v-model="ledgerSearchForm.facilityName"
                      style="width: 200px"
                      placeholder="请输入设施名称"
                      @change="handleLedgerQuery"
                      clearable
                      :prefix-icon="Search" />
            <span class="search_title ml10">设施类型:</span>
            <el-select v-model="ledgerSearchForm.facilityType"
                       clearable
                       @change="handleLedgerQuery"
                       style="width: 150px">
            <el-option label="消防器材" value="消防器材" />
            <el-option label="安全设备" value="安全设备" />
            <el-option label="防护用品" value="防护用品" />
            <el-option label="监控设备" value="监控设备" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
            <span class="search_title ml10">状态:</span>
            <el-select v-model="ledgerSearchForm.status"
                       clearable
                       @change="handleLedgerQuery"
                       style="width: 120px">
            <el-option label="正常" value="正常" />
            <el-option label="异常" value="异常" />
            <el-option label="停用" value="停用" />
              <el-option label="报废" value="报废" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
            <el-button type="primary"
                       @click="handleLedgerQuery"
                       style="margin-left: 10px">
              搜索
            </el-button>
          </div>
          <div>
            <el-button type="primary"
                       @click="openLedgerForm('add')">新增设施</el-button>
          </div>
    </div>
    <!-- 操作按钮 -->
    <div class="actions">
      <el-button type="primary" @click="handleAdd">新增设施</el-button>
      <el-button type="success" @click="handleExport">导出</el-button>
        <div class="table_list">
          <PIMTable rowKey="id"
                    :column="ledgerTableColumn"
                    :tableData="ledgerTableData"
                    :page="ledgerPage"
                    :isSelection="true"
                    @selection-change="handleLedgerSelectionChange"
                    :tableLoading="ledgerTableLoading"
                    @pagination="ledgerPagination"
                    :total="ledgerPage.total"></PIMTable>
        </div>
      </el-tab-pane>
      <!-- 安全设施巡检 -->
      <el-tab-pane label="安全设施巡检" name="inspection">
        <div class="search_form mb20">
          <div>
            <span class="search_title">巡检编号:</span>
            <el-input v-model="inspectionSearchForm.inspectionCode"
                      style="width: 200px"
                      placeholder="请输入巡检编号"
                      @change="handleInspectionQuery"
                      clearable
                      :prefix-icon="Search" />
            <span class="search_title ml10">状态:</span>
            <el-select v-model="inspectionSearchForm.status"
                       clearable
                       @change="handleInspectionQuery"
                       style="width: 150px">
              <el-option label="待巡检" value="待巡检" />
              <el-option label="已巡检" value="已巡检" />
            </el-select>
            <el-button type="primary"
                       @click="handleInspectionQuery"
                       style="margin-left: 10px">
              搜索
            </el-button>
          </div>
    </div>
    <!-- 设施列表 -->
    <el-table :data="facilityList" style="width: 100%; margin-top: 10px;" border>
      <el-table-column prop="facilityName" label="设施名称" width="180" />
      <el-table-column prop="facilityType" label="设施类型" width="120" />
      <el-table-column prop="location" label="所在位置" width="200" />
      <el-table-column prop="deviceName" label="关联设备" width="150" />
      <el-table-column prop="status" label="状态" width="100">
        <template #default="{ row }">
          <el-tag :type="getFacilityStatusType(row.status)">
            {{ row.status }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="lastInspectionTime" label="上次巡检" width="180" />
      <el-table-column prop="nextInspectionTime" label="下次巡检" width="180" />
      <el-table-column prop="responsibilityPerson" label="责任人" width="120" />
      <el-table-column label="操作" width="250" fixed="right">
        <template #default="{ row }">
          <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
          <el-button type="warning" link @click="handleInspection(row)">巡检</el-button>
          <el-button type="danger" link @click="handleDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
        <div class="table_list">
          <PIMTable rowKey="id"
                    :column="inspectionTableColumn"
                    :tableData="inspectionTableData"
                    :page="inspectionPage"
                    :isSelection="false"
                    :tableLoading="inspectionTableLoading"
                    @pagination="inspectionPagination"
                    :total="inspectionPage.total"></PIMTable>
        </div>
      </el-tab-pane>
    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        v-model:current-page="pagination.currentPage"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
      <!-- 整改跟踪 -->
      <el-tab-pane label="整改跟踪" name="rectification">
        <div class="search_form mb20">
          <div>
            <span class="search_title">状态:</span>
            <el-select v-model="rectificationSearchForm.status"
                       clearable
                       @change="handleRectificationQuery"
                       style="width: 150px">
              <el-option label="待整改" value="待整改" />
              <el-option label="整改中" value="整改中" />
              <el-option label="已整改" value="已整改" />
              <el-option label="已验收" value="已验收" />
            </el-select>
            <el-button type="primary"
                       @click="handleRectificationQuery"
                       style="margin-left: 10px">
              搜索
            </el-button>
          </div>
    </div>
    <!-- 新增/编辑对话框 -->
    <el-dialog :title="dialogTitle" v-model="showDialog" width="600px">
      <el-form :model="form" :rules="formRules" ref="formRef" label-width="100px">
        <el-form-item label="设施名称" prop="facilityName">
          <el-input v-model="form.facilityName" placeholder="请输入设施名称" />
        <div class="table_list">
          <PIMTable rowKey="id"
                    :column="rectificationTableColumn"
                    :tableData="rectificationTableData"
                    :page="rectificationPage"
                    :isSelection="false"
                    :tableLoading="rectificationTableLoading"
                    @pagination="rectificationPagination"
                    :total="rectificationPage.total"></PIMTable>
        </div>
      </el-tab-pane>
    </el-tabs>
    <!-- 设施台账表单弹窗 -->
    <el-dialog v-model="ledgerDialogVisible"
               :title="ledgerDialogTitle"
               width="800px"
               :close-on-click-modal="false">
      <el-form ref="ledgerFormRef"
               :model="ledgerForm"
               :rules="ledgerRules"
               label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="设施编号"
                          prop="facilityCode">
              <el-input v-model="ledgerForm.facilityCode"
                        placeholder="请输入设施编号" />
        </el-form-item>
        <el-form-item label="设施类型" prop="facilityType">
          <el-select v-model="form.facilityType" placeholder="请选择类型">
          </el-col>
          <el-col :span="12">
            <el-form-item label="设施名称"
                          prop="facilityName">
              <el-input v-model="ledgerForm.facilityName"
                        placeholder="请输入设施名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="设施类型"
                          prop="facilityType">
              <el-select v-model="ledgerForm.facilityType"
                         placeholder="请选择设施类型"
                         style="width: 100%">
            <el-option label="消防器材" value="消防器材" />
            <el-option label="安全设备" value="安全设备" />
            <el-option label="防护用品" value="防护用品" />
            <el-option label="监控设备" value="监控设备" />
          </el-select>
        </el-form-item>
        <el-form-item label="所在位置" prop="location">
          <el-input v-model="form.location" placeholder="请输入所在位置" />
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号"
                          prop="facilitySpec">
              <el-input v-model="ledgerForm.facilitySpec"
                        placeholder="请输入规格型号" />
        </el-form-item>
        <el-form-item label="关联设备">
          <el-select v-model="form.deviceId" placeholder="请选择设备" clearable>
            <el-option
              v-for="item in deviceOptions"
              :key="item.id"
              :label="item.deviceName"
              :value="item.id"
            />
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="安装位置"
                          prop="installLocation">
              <el-input v-model="ledgerForm.installLocation"
                        placeholder="请输入安装位置" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="安装时间"
                          prop="installTime">
              <el-date-picker v-model="ledgerForm.installTime"
                              type="date"
                              placeholder="请选择安装时间"
                              format="YYYY-MM-DD"
                              value-format="YYYY-MM-DD"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="生产日期"
                          prop="productionDate">
              <el-date-picker v-model="ledgerForm.productionDate"
                              type="date"
                              placeholder="请选择生产日期"
                              format="YYYY-MM-DD"
                              value-format="YYYY-MM-DD"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="有效期(天)"
                          prop="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"
                         placeholder="请选择状态"
                         style="width: 100%">
                <el-option label="正常" value="正常" />
                <el-option label="异常" value="异常" />
                <el-option label="报废" value="报废" />
          </el-select>
        </el-form-item>
        <el-form-item label="责任部门">
          <el-input v-model="form.responsibilityDept" placeholder="请输入责任部门" />
        </el-form-item>
        <el-form-item label="责任人">
          <el-input v-model="form.responsibilityPerson" placeholder="请输入责任人" />
        </el-form-item>
        <el-form-item label="下次巡检">
          <el-date-picker
            v-model="form.nextInspectionTime"
            type="datetime"
            placeholder="请选择下次巡检时间"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss"
          />
        </el-form-item>
        <el-form-item label="备注">
          <el-input type="textarea" v-model="form.remarks" placeholder="请输入备注" />
          </el-col>
        </el-row>
        <el-form-item label="备注"
                      prop="remark">
          <el-input v-model="ledgerForm.remark"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitForm">确定</el-button>
          <el-button @click="showDialog = false">取消</el-button>
          <el-button type="primary"
                     @click="submitLedgerForm">确定</el-button>
          <el-button @click="ledgerDialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 巡检记录对话框 -->
    <el-dialog title="记录巡检结果" v-model="showInspectionDialog" width="500px">
      <el-form :model="inspectionForm" label-width="100px">
        <el-form-item label="设施名称">
          <el-input v-model="inspectionForm.facilityName" disabled />
    <!-- 巡检表单弹窗 -->
    <el-dialog v-model="inspectionDialogVisible"
               :title="inspectionDialogTitle"
               width="600px"
               :close-on-click-modal="false">
      <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-form-item label="巡检结果">
          <el-radio-group v-model="inspectionForm.status">
          </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>
            </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-form-item label="检查结果"
                        prop="checkResult">
            <el-radio-group v-model="inspectionForm.checkResult">
            <el-radio label="正常">正常</el-radio>
            <el-radio label="异常">异常</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="巡检说明" v-if="inspectionForm.status === '异常'">
          <el-input type="textarea" v-model="inspectionForm.description" placeholder="请输入异常说明" />
          <el-form-item label="检查说明">
            <el-input v-model="inspectionForm.checkDesc"
                      type="textarea"
                      :rows="3"
                      placeholder="请输入检查说明" />
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
                     @click="submitInspectionForm">确定</el-button>
          <el-button @click="inspectionDialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 整改表单弹窗 -->
    <el-dialog v-model="rectificationDialogVisible"
               :title="rectificationDialogTitle"
               width="600px"
               :close-on-click-modal="false">
      <el-form ref="rectificationFormRef"
               :model="rectificationForm"
               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 === '整改'">
          <el-input v-model="rectificationForm.rectifyDesc"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入整改说明" />
        </el-form-item>
        <el-form-item label="验收说明" v-if="rectificationDialogTitle === '验收'">
          <el-input v-model="rectificationForm.verifyDesc"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入验收说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitInspection">确定</el-button>
          <el-button @click="showInspectionDialog = false">取消</el-button>
          <el-button type="primary"
                     @click="submitRectificationForm">确定</el-button>
          <el-button @click="rectificationDialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
@@ -153,287 +369,442 @@
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, toRefs } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import {
  getSafetyFacilityList,
  addOrEditSafetyFacility,
  deleteSafetyFacility,
  exportSafetyFacility
} from '@/api/safeProduction/safetyFacility'
import { getDeviceLedger } from '@/api/equipmentManagement/ledger'
// 搜索表单
const searchForm = reactive({
  facilityName: '',
  facilityType: '',
  status: ''
})
// 分页数据
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})
// 列表数据
const facilityList = ref([])
// 设备选项
const deviceOptions = ref([])
// 对话框状态
const showDialog = ref(false)
const dialogTitle = ref('新增设施')
// 巡检对话框状态
const showInspectionDialog = ref(false)
// 表单数据
const form = reactive({
  id: null,
  facilityName: '',
  facilityType: '',
  location: '',
  deviceId: null,
  responsibilityDept: '',
  responsibilityPerson: '',
  nextInspectionTime: '',
  remarks: ''
})
// 巡检表单数据
const inspectionForm = reactive({
  id: null,
  facilityName: '',
  status: '正常',
  description: ''
})
  getFacilityLedgerList,
  addFacilityLedger,
  updateFacilityLedger,
  deleteFacilityLedger,
  getFacilityInspectionList,
  addFacilityInspection,
  updateFacilityInspection,
  deleteFacilityInspection,
  getFacilityRectificationList,
  addFacilityRectification,
  updateFacilityRectification
} from "@/api/safeProduction/safetyFacility";
// 表单验证规则
const formRules = reactive({
  facilityName: [{ required: true, message: '请输入设施名称', trigger: 'blur' }],
  facilityType: [{ required: true, message: '请选择设施类型', trigger: 'change' }],
  location: [{ required: true, message: '请输入所在位置', trigger: 'blur' }]
})
const ledgerRules = {
  facilityCode: [{ required: true, message: "请输入设施编号", trigger: "blur" }],
  facilityName: [{ required: true, message: "请输入设施名称", trigger: "blur" }],
  facilityType: [{ required: true, message: "请选择设施类型", trigger: "change" }],
  installLocation: [{ required: true, message: "请输入安装位置", trigger: "blur" }]
};
const formRef = ref(null)
const inspectionRules = {
  inspectionCode: [{ required: true, message: "请输入巡检编号", trigger: "blur" }]
};
// 获取状态标签类型
const getFacilityStatusType = (status) => {
  const map = {
    '正常': 'success',
    '异常': 'danger',
    '停用': 'info'
  }
  return map[status] || 'info'
}
// 响应式数据
const data = reactive({
  activeTab: "ledger",
  // 设施台账
  ledgerSearchForm: { facilityCode: "", facilityName: "", facilityType: "", status: "" },
  ledgerTableLoading: false,
  ledgerPage: { current: 1, size: 20, total: 0 },
  ledgerTableData: [],
  ledgerSelectedIds: [],
  ledgerForm: {
    id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
    installLocation: "", installTime: "", productionDate: "", validPeriod: null,
    status: "正常", remark: ""
  },
  ledgerDialogVisible: false,
  ledgerDialogTitle: "",
  ledgerDialogType: "add",
  // 巡检记录
  inspectionSearchForm: { inspectionCode: "", status: "" },
  inspectionTableLoading: false,
  inspectionPage: { current: 1, size: 20, total: 0 },
  inspectionTableData: [],
  inspectionForm: {
    id: null, facilityId: null, inspectionCode: "", inspectionType: "定期巡检",
    planTime: "", checkResult: "", checkDesc: ""
  },
  inspectionDialogVisible: false,
  inspectionDialogTitle: "",
  inspectionDialogType: "add",
  // 整改跟踪
  rectificationSearchForm: { status: "" },
  rectificationTableLoading: false,
  rectificationPage: { current: 1, size: 20, total: 0 },
  rectificationTableData: [],
  rectificationForm: {
    id: null, inspectionId: null, facilityId: null, problemDesc: "",
    problemLevel: "", rectifyDesc: "", verifyDesc: ""
  },
  rectificationDialogVisible: false,
  rectificationDialogTitle: "",
  rectificationDialogType: "add"
});
// 获取设施列表
const fetchList = async () => {
  try {
    const params = {
      ...searchForm,
      current: pagination.currentPage,
      size: pagination.pageSize
    }
    const res = await getSafetyFacilityList(params)
    if (res.code === 200) {
      facilityList.value = res.data.records || []
      pagination.total = res.data.total || 0
    } else {
      ElMessage.error(res.message || '获取列表失败')
    }
  } catch (error) {
    ElMessage.error('获取列表失败')
  }
}
const {
  activeTab,
  ledgerSearchForm, ledgerTableLoading, ledgerPage, ledgerTableData, ledgerSelectedIds,
  ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType,
  inspectionSearchForm, inspectionTableLoading, inspectionPage, inspectionTableData,
  inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType,
  rectificationSearchForm, rectificationTableLoading, rectificationPage, rectificationTableData,
  rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType
} = toRefs(data);
// 获取设备列表
const fetchDeviceOptions = async () => {
  try {
    const res = await getDeviceLedger()
    if (res.code === 200) {
      deviceOptions.value = res.data || []
    }
  } catch (error) {
    console.error('获取设备列表失败')
  }
}
// 表单引用
const ledgerFormRef = ref();
const inspectionFormRef = ref();
const rectificationFormRef = ref();
// 搜索
const handleSearch = () => {
  pagination.currentPage = 1
  fetchList()
// 设施台账表格列配置
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",
    formatType: params => {
      const map = { 正常: "success", 异常: "danger", 报废: "info" };
      return map[params] || "info";
}
  },
  {
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 200,
    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) }
    ]
  }
]);
// 重置搜索
const resetSearch = () => {
  Object.assign(searchForm, {
    facilityName: '',
    facilityType: '',
    status: ''
  })
  handleSearch()
// 巡检记录表格列配置
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: "检查结果", prop: "checkResult", minWidth: 100, dataType: "tag",
    formatType: params => params === "正常" ? "success" : "danger"
  },
  {
    label: "状态", prop: "status", minWidth: 100, dataType: "tag",
    formatType: params => params === "待巡检" ? "info" : "success"
  },
  {
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 200,
    operation: [
      {
        name: "巡检", type: "text",
        clickFun: row => openInspectionForm("do", row),
        show: row => row.status === "待巡检"
      },
      {
        name: "查看", type: "text",
        clickFun: row => openInspectionForm("view", row),
        show: row => row.status !== "待巡检"
      },
      {
        name: "整改", type: "text",
        clickFun: row => openRectificationForm("add", row),
        show: row => row.checkResult === "异常"
      },
      { name: "删除", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteInspection(row) }
    ]
}
]);
// 新增
const handleAdd = () => {
  dialogTitle.value = '新增设施'
  Object.assign(form, {
    id: null,
    facilityName: '',
    facilityType: '',
    location: '',
    deviceId: null,
    responsibilityDept: '',
    responsibilityPerson: '',
    nextInspectionTime: '',
    remarks: ''
  })
  showDialog.value = true
// 整改跟踪表格列配置
const rectificationTableColumn = ref([
  { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
  { label: "问题描述", prop: "problemDesc", showOverflowTooltip: true, minWidth: 200 },
  {
    label: "问题等级", prop: "problemLevel", minWidth: 100, dataType: "tag",
    formatType: params => params === "重大" ? "danger" : "warning"
  },
  { label: "整改责任人", prop: "rectifyUserName", minWidth: 120 },
  { label: "计划整改时间", prop: "planTime", minWidth: 180 },
  {
    label: "状态", prop: "status", minWidth: 100, dataType: "tag",
    formatType: params => {
      const map = { 待整改: "danger", 整改中: "warning", 已整改: "success", 已验收: "info" };
      return map[params] || "info";
}
  },
  { label: "验收人", prop: "verifyUserName", minWidth: 120 },
  {
    dataType: "action", label: "操作", align: "center", fixed: "right", width: 200,
    operation: [
      {
        name: "整改", type: "text",
        clickFun: row => openRectificationForm("do", row),
        show: row => row.status === "待整改" || row.status === "整改中"
      },
      {
        name: "验收", type: "text",
        clickFun: row => openRectificationForm("verify", row),
        show: row => row.status === "已整改"
      },
      { name: "查看", type: "text", clickFun: row => openRectificationForm("view", row) }
    ]
  }
]);
// 编辑
const handleEdit = (row) => {
  dialogTitle.value = '编辑设施'
  Object.assign(form, {
    id: row.id,
    facilityName: row.facilityName,
    facilityType: row.facilityType,
    location: row.location,
    deviceId: row.deviceId,
    responsibilityDept: row.responsibilityDept,
    responsibilityPerson: row.responsibilityPerson,
    nextInspectionTime: row.nextInspectionTime,
    remarks: row.remarks
  })
  showDialog.value = true
}
// 巡检
const handleInspection = (row) => {
  Object.assign(inspectionForm, {
    id: row.id,
    facilityName: row.facilityName,
    status: '正常',
    description: ''
  })
  showInspectionDialog.value = true
}
// 删除
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确认删除该设施吗?', '提示', {
      type: 'warning'
    })
    const res = await deleteSafetyFacility([row.id])
    if (res.code === 200) {
      ElMessage.success('删除成功')
      fetchList()
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error) {
    // 取消删除
  }
}
// 提交表单
const submitForm = async () => {
  if (!formRef.value) return
  try {
    await formRef.value.validate()
    const res = await addOrEditSafetyFacility(form)
    if (res.code === 200) {
      ElMessage.success('操作成功')
      showDialog.value = false
      fetchList()
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error) {
    ElMessage.error('请填写完整表单信息')
  }
}
// 提交巡检结果
const submitInspection = async () => {
  try {
    const data = {
      id: inspectionForm.id,
      status: inspectionForm.status,
      lastInspectionTime: new Date().toISOString()
    }
    const res = await addOrEditSafetyFacility(data)
    if (res.code === 200) {
      ElMessage.success('巡检记录成功')
      showInspectionDialog.value = false
      fetchList()
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error) {
    ElMessage.error('操作失败')
  }
}
// 导出
const handleExport = async () => {
  try {
    const res = await exportSafetyFacility(searchForm)
    const blob = new Blob([res])
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '安全设施台账.xlsx'
    link.click()
    window.URL.revokeObjectURL(url)
    ElMessage.success('导出成功')
  } catch (error) {
    ElMessage.error('导出失败')
  }
}
// 分页大小改变
const handleSizeChange = (val) => {
  pagination.pageSize = val
  fetchList()
}
// 当前页改变
const handleCurrentChange = (val) => {
  pagination.currentPage = val
  fetchList()
}
// 生命周期
onMounted(() => {
  fetchList()
  fetchDeviceOptions()
  getLedgerList();
});
// 标签页切换
const handleTabClick = () => {
  if (activeTab.value === "ledger") getLedgerList();
  else if (activeTab.value === "inspection") getInspectionList();
  else if (activeTab.value === "rectification") getRectificationList();
};
// ============ 设施台账方法 ============
const handleLedgerQuery = () => {
  ledgerPage.value.current = 1;
  getLedgerList();
};
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;
})
    .catch(() => { ledgerTableLoading.value = false; });
};
const ledgerPagination = obj => {
  ledgerPage.value.current = obj.page;
  ledgerPage.value.size = obj.limit;
  getLedgerList();
};
const handleLedgerSelectionChange = selection => {
  ledgerSelectedIds.value = selection.map(item => item.id);
};
const 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,
      status: "正常", remark: ""
    });
  } else {
    ledgerDialogTitle.value = "编辑设施";
    Object.assign(ledgerForm.value, { ...row });
  }
  ledgerDialogVisible.value = true;
};
const submitLedgerForm = async () => {
  try {
    await ledgerFormRef.value.validate();
    const api = ledgerDialogType.value === "add" ? addFacilityLedger : updateFacilityLedger;
    const res = await api({ ...ledgerForm.value });
    if (res.code === 200) {
      ElMessage.success(ledgerDialogType.value === "add" ? "添加成功" : "更新成功");
      ledgerDialogVisible.value = false;
      getLedgerList();
    } else {
      ElMessage.error(res.msg || "操作失败");
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
const handleDeleteLedger = row => {
  ElMessageBox.confirm("确认删除该设施吗?", "删除", {
    confirmButtonText: "确认", cancelButtonText: "取消", type: "warning"
  }).then(async () => {
    const res = await deleteFacilityLedger([row.id]);
    if (res.code === 200) {
      ElMessage.success("删除成功");
      getLedgerList();
    }
  }).catch(() => {});
};
// ============ 巡检记录方法 ============
const handleInspectionQuery = () => {
  inspectionPage.value.current = 1;
  getInspectionList();
};
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;
    })
    .catch(() => { inspectionTableLoading.value = false; });
};
const inspectionPagination = obj => {
  inspectionPage.value.current = obj.page;
  inspectionPage.value.size = obj.limit;
  getInspectionList();
};
const openInspectionForm = (type, row = null) => {
  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") {
    inspectionDialogTitle.value = "巡检";
    Object.assign(inspectionForm.value, {
      id: row.id, facilityId: row.facilityId, inspectionCode: row.inspectionCode,
      inspectionType: row.inspectionType, planTime: row.planTime, checkResult: "", checkDesc: ""
    });
  } else {
    inspectionDialogTitle.value = "查看巡检";
    Object.assign(inspectionForm.value, { ...row });
  }
  inspectionDialogVisible.value = true;
};
const submitInspectionForm = async () => {
  try {
    await inspectionFormRef.value.validate();
    if (inspectionDialogTitle.value === "巡检") {
      inspectionForm.value.status = "已巡检";
      inspectionForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
    }
    const api = inspectionForm.value.id ? updateFacilityInspection : addFacilityInspection;
    const res = await api({ ...inspectionForm.value });
    if (res.code === 200) {
      ElMessage.success("操作成功");
      inspectionDialogVisible.value = false;
      getInspectionList();
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
const handleDeleteInspection = row => {
  ElMessageBox.confirm("确认删除该巡检记录吗?", "删除", {
    confirmButtonText: "确认", cancelButtonText: "取消", type: "warning"
  }).then(async () => {
    const res = await deleteFacilityInspection([row.id]);
    if (res.code === 200) {
      ElMessage.success("删除成功");
      getInspectionList();
    }
  }).catch(() => {});
};
// ============ 整改跟踪方法 ============
const handleRectificationQuery = () => {
  rectificationPage.value.current = 1;
  getRectificationList();
};
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;
    })
    .catch(() => { rectificationTableLoading.value = false; });
};
const rectificationPagination = obj => {
  rectificationPage.value.current = obj.page;
  rectificationPage.value.size = obj.limit;
  getRectificationList();
};
const openRectificationForm = (type, row = null) => {
  rectificationDialogType.value = type;
  if (type === "add") {
    rectificationDialogTitle.value = "新增整改";
    Object.assign(rectificationForm.value, {
      id: null, inspectionId: row.id, facilityId: row.facilityId,
      problemDesc: "", problemLevel: "", rectifyDesc: "", verifyDesc: ""
    });
  } 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: ""
    });
  } 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: ""
    });
  } else {
    rectificationDialogTitle.value = "查看整改";
    Object.assign(rectificationForm.value, { ...row });
  }
  rectificationDialogVisible.value = true;
};
const submitRectificationForm = async () => {
  if (rectificationDialogType.value === "view") {
    rectificationDialogVisible.value = false;
    return;
  }
  if (rectificationDialogTitle.value === "整改") {
    rectificationForm.value.status = "已整改";
    rectificationForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
  } else if (rectificationDialogTitle.value === "验收") {
    rectificationForm.value.status = "已验收";
    rectificationForm.value.verifyTime = new Date().toISOString().replace("T", " ").substring(0, 19);
  }
  const api = rectificationForm.value.id ? updateFacilityRectification : addFacilityRectification;
  const res = await api({ ...rectificationForm.value });
  if (res.code === 200) {
    ElMessage.success("操作成功");
    rectificationDialogVisible.value = false;
    getRectificationList();
  }
};
</script>
<style scoped>
.safety-facility {
  padding: 20px;
.search_title {
  font-size: 14px;
  color: #606266;
}
.search-area {
  background: #f5f7fa;
  padding: 20px;
  border-radius: 4px;
  margin-bottom: 15px;
.mb20 {
  margin-bottom: 20px;
}
.actions {
  margin-bottom: 15px;
}
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
.ml10 {
  margin-left: 10px;
}
</style>