huminmin
2026-06-29 cdf69116241fbcbb4725aa68ae06a6be578dcd73
Merge branch 'dev_兴盛旺海' of http://114.132.189.42:9002/r/product-inventory-management into dev_兴盛旺海
已添加6个文件
2582 ■■■■■ 文件已修改
src/api/safeProduction/hazardReport.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/safeProduction/lineInspection.js 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/safeProduction/safetyFacility.js 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/hazardReport/index.vue 529 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/lineInspection/index.vue 918 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/safetyFacility/index.vue 810 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/safeProduction/hazardReport.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
import request from "@/utils/request";
/**
 * é𐿂£ä¸ŠæŠ¥API接口
 */
// èŽ·å–éšæ‚£ä¸ŠæŠ¥åˆ—è¡¨
export function getHazardReportList(params) {
  return request({
    url: "/device/hazardReport/list",
    method: "get",
    params,
  });
}
// æ–°å¢žé𐿂£ä¸ŠæŠ¥
export function addHazardReport(data) {
  return request({
    url: "/device/hazardReport/add",
    method: "post",
    data,
  });
}
// è®°å½•整改结果
export function rectifyHazardReport(data) {
  return request({
    url: "/device/hazardReport/rectify",
    method: "post",
    data,
  });
}
// è®°å½•验收结果
export function acceptHazardReport(data) {
  return request({
    url: "/device/hazardReport/accept",
    method: "post",
    data,
  });
}
// åˆ é™¤é𐿂£ä¸ŠæŠ¥è®°å½•
export function deleteHazardReport(ids) {
  return request({
    url: "/device/hazardReport/delete",
    method: "delete",
    data: ids,
  });
}
// å¯¼å‡ºé𐿂£ä¸ŠæŠ¥è®°å½•
export function exportHazardReport(params) {
  return request({
    url: "/device/hazardReport/export",
    method: "post",
    params,
    responseType: 'blob',
  });
}
src/api/safeProduction/lineInspection.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
import request from "@/utils/request";
/**
 * çº¿è·¯å·¡æ£€API接口
 */
// èŽ·å–çº¿è·¯å·¡æ£€åˆ—è¡¨
export function getLineInspectionList(params) {
  return request({
    url: "/safeLineInspection/page",
    method: "get",
    params,
  });
}
// æ ¹æ®ID获取线路巡检详情
export function getLineInspectionById(id) {
  return request({
    url: `/safeLineInspection/${id}`,
    method: "get",
  });
}
// æ–°å¢žçº¿è·¯å·¡æ£€
export function addLineInspection(data) {
  return request({
    url: "/safeLineInspection",
    method: "post",
    data,
  });
}
// ä¿®æ”¹çº¿è·¯å·¡æ£€
export function updateLineInspection(data) {
  return request({
    url: "/safeLineInspection",
    method: "put",
    data,
  });
}
// åˆ é™¤çº¿è·¯å·¡æ£€
export function deleteLineInspection(ids) {
  return request({
    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,
  });
}
// æ ¹æ®å·¡æ£€ä»»åŠ¡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
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,140 @@
import request from "@/utils/request";
/**
 * å®‰å…¨è®¾æ–½å·¡æ£€API接口
 */
// ============ å®‰å…¨è®¾æ–½å°è´¦ ============
// èŽ·å–å®‰å…¨è®¾æ–½å°è´¦åˆ—è¡¨
export function getFacilityLedgerList(params) {
  return request({
    url: "/safeFacilityLedger/page",
    method: "get",
    params,
  });
}
// æ ¹æ®ID获取安全设施台账详情
export function getFacilityLedgerById(id) {
  return request({
    url: `/safeFacilityLedger/${id}`,
    method: "get",
  });
}
// æ–°å¢žå®‰å…¨è®¾æ–½å°è´¦
export function addFacilityLedger(data) {
  return request({
    url: "/safeFacilityLedger",
    method: "post",
    data,
  });
}
// ä¿®æ”¹å®‰å…¨è®¾æ–½å°è´¦
export function updateFacilityLedger(data) {
  return request({
    url: "/safeFacilityLedger",
    method: "put",
    data,
  });
}
// åˆ é™¤å®‰å…¨è®¾æ–½å°è´¦
export function deleteFacilityLedger(ids) {
  return request({
    url: "/safeFacilityLedger/" + ids.join(","),
    method: "delete",
  });
}
// ============ å®‰å…¨è®¾æ–½å·¡æ£€ ============
// èŽ·å–å®‰å…¨è®¾æ–½å·¡æ£€åˆ—è¡¨
export function getFacilityInspectionList(params) {
  return request({
    url: "/safeFacilityInspection/page",
    method: "get",
    params,
  });
}
// æ ¹æ®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/hazardReport/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,529 @@
<template>
  <div class="hazard-report">
    <!-- æœç´¢åŒºåŸŸ -->
    <div class="search-area">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="上报类型">
          <el-select v-model="searchForm.reportType" placeholder="请选择类型" clearable>
            <el-option label="线路巡检" value="线路巡检" />
            <el-option label="安全设施巡检" value="安全设施巡检" />
          </el-select>
        </el-form-item>
        <el-form-item label="严重程度">
          <el-select v-model="searchForm.severity" placeholder="请选择程度" clearable>
            <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.rectificationStatus" placeholder="请选择状态" clearable>
            <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="searchForm.reporter" placeholder="请输入上报人" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- æ“ä½œæŒ‰é’® -->
    <div class="actions">
      <el-button type="primary" @click="handleAdd">上报隐患</el-button>
      <el-button type="success" @click="handleExport">导出</el-button>
    </div>
    <!-- é𐿂£åˆ—表 -->
    <el-table :data="reportList" style="width: 100%; margin-top: 10px;" border>
      <el-table-column prop="reportType" label="上报类型" width="150" />
      <el-table-column prop="facilityName" label="关联设施" width="150" />
      <el-table-column prop="hazardDescription" label="隐患描述" min-width="200" show-overflow-tooltip />
      <el-table-column prop="severity" label="严重程度" width="120">
        <template #default="{ row }">
          <el-tag :type="getSeverityType(row.severity)">
            {{ row.severity }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="reporter" label="上报人" width="120" />
      <el-table-column prop="reportTime" label="上报时间" width="180" />
      <el-table-column prop="rectificationStatus" label="整改状态" width="120">
        <template #default="{ row }">
          <el-tag :type="getRectificationStatusType(row.rectificationStatus)">
            {{ row.rectificationStatus }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="rectificationPerson" label="整改责任人" width="120" />
      <el-table-column label="操作" width="280" fixed="right">
        <template #default="{ row }">
          <el-button
            v-if="row.rectificationStatus === '待整改'"
            type="warning"
            link
            @click="handleRectify(row)"
          >
            æ•´æ”¹
          </el-button>
          <el-button
            v-if="row.rectificationStatus === '已完成' && !row.acceptancePerson"
            type="success"
            link
            @click="handleAccept(row)"
          >
            éªŒæ”¶
          </el-button>
          <el-button type="primary" link @click="handleView(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="上报隐患" v-model="showAddDialog" width="600px">
      <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px">
        <el-form-item label="上报类型" prop="reportType">
          <el-select v-model="addForm.reportType" placeholder="请选择类型">
            <el-option label="线路巡检" value="线路巡检" />
            <el-option label="安全设施巡检" value="安全设施巡检" />
          </el-select>
        </el-form-item>
        <el-form-item label="关联设施">
          <el-select v-model="addForm.facilityId" placeholder="请选择设施" clearable>
            <el-option
              v-for="item in facilityOptions"
              :key="item.id"
              :label="item.facilityName"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="隐患描述" prop="hazardDescription">
          <el-input type="textarea" v-model="addForm.hazardDescription" placeholder="请输入隐患描述" />
        </el-form-item>
        <el-form-item label="严重程度" prop="severity">
          <el-select v-model="addForm.severity" placeholder="请选择程度">
            <el-option label="轻微" value="轻微" />
            <el-option label="一般" value="一般" />
            <el-option label="严重" value="严重" />
          </el-select>
        </el-form-item>
        <el-form-item label="上报人" prop="reporter">
          <el-input v-model="addForm.reporter" placeholder="请输入上报人" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input type="textarea" v-model="addForm.remarks" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitAddForm">确定</el-button>
          <el-button @click="showAddDialog = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- æ•´æ”¹å¯¹è¯æ¡† -->
    <el-dialog title="记录整改结果" v-model="showRectifyDialog" width="500px">
      <el-form :model="rectifyForm" label-width="100px">
        <el-form-item label="隐患描述">
          <el-input type="textarea" v-model="rectifyForm.hazardDescription" disabled />
        </el-form-item>
        <el-form-item label="整改责任人">
          <el-input v-model="rectifyForm.rectificationPerson" placeholder="请输入整改责任人" />
        </el-form-item>
        <el-form-item label="整改描述">
          <el-input type="textarea" v-model="rectifyForm.rectificationDescription" placeholder="请输入整改措施" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitRectify">确定</el-button>
          <el-button @click="showRectifyDialog = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- éªŒæ”¶å¯¹è¯æ¡† -->
    <el-dialog title="记录验收结果" v-model="showAcceptDialog" width="500px">
      <el-form :model="acceptForm" label-width="100px">
        <el-form-item label="整改描述">
          <el-input type="textarea" v-model="acceptForm.rectificationDescription" disabled />
        </el-form-item>
        <el-form-item label="验收人">
          <el-input v-model="acceptForm.acceptancePerson" placeholder="请输入验收人" />
        </el-form-item>
        <el-form-item label="验收结果">
          <el-radio-group v-model="acceptForm.acceptanceResult">
            <el-radio label="通过">通过</el-radio>
            <el-radio label="不通过">不通过</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submitAccept">确定</el-button>
          <el-button @click="showAcceptDialog = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- æŸ¥çœ‹è¯¦æƒ…对话框 -->
    <el-dialog title="隐患详情" v-model="showViewDialog" width="600px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="上报类型">{{ viewData.reportType }}</el-descriptions-item>
        <el-descriptions-item label="关联设施">{{ viewData.facilityName }}</el-descriptions-item>
        <el-descriptions-item label="隐患描述" :span="2">{{ viewData.hazardDescription }}</el-descriptions-item>
        <el-descriptions-item label="严重程度">{{ viewData.severity }}</el-descriptions-item>
        <el-descriptions-item label="上报人">{{ viewData.reporter }}</el-descriptions-item>
        <el-descriptions-item label="上报时间">{{ viewData.reportTime }}</el-descriptions-item>
        <el-descriptions-item label="整改状态">{{ viewData.rectificationStatus }}</el-descriptions-item>
        <el-descriptions-item label="整改责任人">{{ viewData.rectificationPerson }}</el-descriptions-item>
        <el-descriptions-item label="整改时间">{{ viewData.rectificationTime }}</el-descriptions-item>
        <el-descriptions-item label="整改描述" :span="2">{{ viewData.rectificationDescription }}</el-descriptions-item>
        <el-descriptions-item label="验收人">{{ viewData.acceptancePerson }}</el-descriptions-item>
        <el-descriptions-item label="验收时间">{{ viewData.acceptanceTime }}</el-descriptions-item>
        <el-descriptions-item label="验收结果">{{ viewData.acceptanceResult }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showViewDialog = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getHazardReportList,
  addHazardReport,
  rectifyHazardReport,
  acceptHazardReport,
  deleteHazardReport,
  exportHazardReport
} from '@/api/safeProduction/hazardReport'
import { getSafetyFacilityList } from '@/api/equipmentManagement/safetyFacility'
// æœç´¢è¡¨å•
const searchForm = reactive({
  reportType: '',
  severity: '',
  rectificationStatus: '',
  reporter: ''
})
// åˆ†é¡µæ•°æ®
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})
// åˆ—表数据
const reportList = ref([])
// è®¾æ–½é€‰é¡¹
const facilityOptions = ref([])
// å¯¹è¯æ¡†çŠ¶æ€
const showAddDialog = ref(false)
const showRectifyDialog = ref(false)
const showAcceptDialog = ref(false)
const showViewDialog = ref(false)
// ä¸ŠæŠ¥è¡¨å•
const addForm = reactive({
  reportType: '',
  facilityId: null,
  hazardDescription: '',
  severity: '',
  reporter: '',
  remarks: ''
})
// ä¸ŠæŠ¥è¡¨å•验证规则
const addFormRules = reactive({
  reportType: [{ required: true, message: '请选择上报类型', trigger: 'change' }],
  hazardDescription: [{ required: true, message: '请输入隐患描述', trigger: 'blur' }],
  severity: [{ required: true, message: '请选择严重程度', trigger: 'change' }],
  reporter: [{ required: true, message: '请输入上报人', trigger: 'blur' }]
})
const addFormRef = ref(null)
// æ•´æ”¹è¡¨å•
const rectifyForm = reactive({
  id: null,
  hazardDescription: '',
  rectificationPerson: '',
  rectificationDescription: ''
})
// éªŒæ”¶è¡¨å•
const acceptForm = reactive({
  id: null,
  rectificationDescription: '',
  acceptancePerson: '',
  acceptanceResult: '通过'
})
// æŸ¥çœ‹æ•°æ®
const viewData = ref({})
// èŽ·å–ä¸¥é‡ç¨‹åº¦æ ‡ç­¾ç±»åž‹
const getSeverityType = (severity) => {
  const map = {
    '轻微': 'info',
    '一般': 'warning',
    '严重': 'danger'
  }
  return map[severity] || 'info'
}
// èŽ·å–æ•´æ”¹çŠ¶æ€æ ‡ç­¾ç±»åž‹
const getRectificationStatusType = (status) => {
  const map = {
    '待整改': 'danger',
    '整改中': 'warning',
    '已完成': 'success'
  }
  return map[status] || 'info'
}
// èŽ·å–éšæ‚£åˆ—è¡¨
const fetchList = async () => {
  try {
    const params = {
      ...searchForm,
      current: pagination.currentPage,
      size: pagination.pageSize
    }
    const res = await getHazardReportList(params)
    if (res.code === 200) {
      reportList.value = res.data.records || []
      pagination.total = res.data.total || 0
    } else {
      ElMessage.error(res.message || '获取列表失败')
    }
  } catch (error) {
    ElMessage.error('获取列表失败')
  }
}
// èŽ·å–è®¾æ–½åˆ—è¡¨
const fetchFacilityOptions = async () => {
  try {
    const res = await getSafetyFacilityList({ size: 1000 })
    if (res.code === 200) {
      facilityOptions.value = res.data.records || []
    }
  } catch (error) {
    console.error('获取设施列表失败')
  }
}
// æœç´¢
const handleSearch = () => {
  pagination.currentPage = 1
  fetchList()
}
// é‡ç½®æœç´¢
const resetSearch = () => {
  Object.assign(searchForm, {
    reportType: '',
    severity: '',
    rectificationStatus: '',
    reporter: ''
  })
  handleSearch()
}
// ä¸ŠæŠ¥é𐿂£
const handleAdd = () => {
  Object.assign(addForm, {
    reportType: '',
    facilityId: null,
    hazardDescription: '',
    severity: '',
    reporter: '',
    remarks: ''
  })
  showAddDialog.value = true
}
// æ•´æ”¹
const handleRectify = (row) => {
  Object.assign(rectifyForm, {
    id: row.id,
    hazardDescription: row.hazardDescription,
    rectificationPerson: '',
    rectificationDescription: ''
  })
  showRectifyDialog.value = true
}
// éªŒæ”¶
const handleAccept = (row) => {
  Object.assign(acceptForm, {
    id: row.id,
    rectificationDescription: row.rectificationDescription,
    acceptancePerson: '',
    acceptanceResult: '通过'
  })
  showAcceptDialog.value = true
}
// æŸ¥çœ‹è¯¦æƒ…
const handleView = (row) => {
  viewData.value = { ...row }
  showViewDialog.value = true
}
// åˆ é™¤
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确认删除该隐患记录吗?', '提示', {
      type: 'warning'
    })
    const res = await deleteHazardReport([row.id])
    if (res.code === 200) {
      ElMessage.success('删除成功')
      fetchList()
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error) {
    // å–消删除
  }
}
// æäº¤ä¸ŠæŠ¥è¡¨å•
const submitAddForm = async () => {
  if (!addFormRef.value) return
  try {
    await addFormRef.value.validate()
    const res = await addHazardReport(addForm)
    if (res.code === 200) {
      ElMessage.success('上报成功')
      showAddDialog.value = false
      fetchList()
    } else {
      ElMessage.error(res.message || '上报失败')
    }
  } catch (error) {
    ElMessage.error('请填写完整表单信息')
  }
}
// æäº¤æ•´æ”¹
const submitRectify = async () => {
  try {
    const res = await rectifyHazardReport(rectifyForm)
    if (res.code === 200) {
      ElMessage.success('整改记录成功')
      showRectifyDialog.value = false
      fetchList()
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error) {
    ElMessage.error('操作失败')
  }
}
// æäº¤éªŒæ”¶
const submitAccept = async () => {
  try {
    const res = await acceptHazardReport(acceptForm)
    if (res.code === 200) {
      ElMessage.success('验收记录成功')
      showAcceptDialog.value = false
      fetchList()
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error) {
    ElMessage.error('操作失败')
  }
}
// å¯¼å‡º
const handleExport = async () => {
  try {
    const res = await exportHazardReport(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()
  fetchFacilityOptions()
})
</script>
<style scoped>
.hazard-report {
  padding: 20px;
}
.search-area {
  background: #f5f7fa;
  padding: 20px;
  border-radius: 4px;
  margin-bottom: 15px;
}
.actions {
  margin-bottom: 15px;
}
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}
</style>
src/views/safeProduction/lineInspection/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,918 @@
<template>
  <div class="app-container">
    <div class="search_form mb20">
      <div>
        <span class="search_title">巡检编号:</span>
        <el-input v-model="searchForm.inspectionCode"
                  style="width: 200px"
                  placeholder="请输入巡检编号"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span class="search_title ml10">巡检名称:</span>
        <el-input v-model="searchForm.inspectionName"
                  style="width: 200px"
                  placeholder="请输入巡检名称"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span class="search_title ml10">线路名称:</span>
        <el-input v-model="searchForm.lineName"
                  style="width: 200px"
                  placeholder="请输入线路名称"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span class="search_title ml10">状态:</span>
        <el-select v-model="searchForm.status"
                   clearable
                   @change="handleQuery"
                   style="width: 150px">
          <el-option label="待巡检" value="待巡检" />
          <el-option label="巡检中" value="巡检中" />
          <el-option label="已完成" value="已完成" />
        </el-select>
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">
          æœç´¢
        </el-button>
      </div>
      <div>
        <el-button type="primary"
                   @click="openForm('add')">新增巡检任务</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"
                :total="page.total"></PIMTable>
    </div>
    <!-- æ–°å¢ž/编辑巡检任务弹窗 -->
    <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-col>
          <el-col :span="12">
            <el-form-item label="巡检名称"
                          prop="inspectionName">
              <el-input v-model="form.inspectionName"
                        placeholder="请输入巡检名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="线路名称"
                          prop="lineName">
              <el-input v-model="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-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="请选择计划巡检时间"
                              format="YYYY-MM-DD HH:mm:ss"
                              value-format="YYYY-MM-DD HH:mm:ss"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="巡检人"
                          prop="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-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="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 { 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,
  addLineInspection,
  updateLineInspection,
  deleteLineInspection,
  completeLineInspection,
  getInspectionRecords,
  addInspectionRecord,
  getHazardsByInspectionId,
  addInspectionHazard,
  updateInspectionHazard
} from "@/api/safeProduction/lineInspection";
// è¡¨å•验证规则
const rules = {
  inspectionCode: [{ required: true, message: "请输入巡检编号", trigger: "blur" }],
  inspectionName: [{ required: true, message: "请输入巡检名称", trigger: "blur" }],
  lineName: [{ required: true, message: "请输入线路名称", trigger: "blur" }]
};
const recordRules = {
  checkPoint: [{ required: true, message: "请输入检查点", trigger: "blur" }],
  checkContent: [{ required: true, message: "请输入检查内容", trigger: "blur" }],
  checkResult: [{ required: true, message: "请选择检查结果", trigger: "change" }]
};
const hazardRules = {
  hazardDesc: [{ required: true, message: "请输入隐患描述", trigger: "blur" }],
  hazardLevel: [{ required: true, message: "请选择隐患等级", trigger: "change" }],
  hazardLocation: [{ required: true, message: "请输入隐患位置", trigger: "blur" }]
};
// å“åº”式数据
const data = reactive({
  searchForm: {
    inspectionCode: "",
    inspectionName: "",
    lineName: "",
    status: ""
  },
  tableLoading: false,
  page: {
    current: 1,
    size: 20,
    total: 0
  },
  tableData: [],
  selectedIds: [],
  form: {
    id: null,
    inspectionCode: "",
    inspectionName: "",
    lineName: "",
    inspectionType: "",
    planTime: "",
    inspectorId: "",
    inspectorIds: [],
    remark: ""
  },
  dialogVisible: false,
  dialogTitle: "",
  dialogType: "add",
  // å·¡æ£€è®°å½•
  currentInspectionId: null,
  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 {
  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,
      inspectionCode: row.inspectionCode,
      inspectionName: row.inspectionName,
      lineName: row.lineName,
      inspectionType: row.inspectionType,
      planTime: row.planTime,
      inspectorId: row.inspectorId,
      inspectorIds: inspectorIds,
      remark: row.remark
    });
  }
  dialogVisible.value = true;
};
// æäº¤è¡¨å•
const submitForm = async () => {
  try {
    await formRef.value.validate();
    // å°†æ•°ç»„转换为逗号分隔的字符串
    const submitData = {
      ...form.value,
      inspectorId: form.value.inspectorIds ? form.value.inspectorIds.join(",") : ""
    };
    delete submitData.inspectorIds;
    const api = dialogType.value === "add" ? addLineInspection : updateLineInspection;
    const res = await api(submitData);
    if (res.code === 200) {
      ElMessage.success(dialogType.value === "add" ? "添加成功" : "更新成功");
      dialogVisible.value = false;
      getList();
    } else {
      ElMessage.error(res.msg || "操作失败");
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
// åˆ é™¤
const handleDelete = row => {
  ElMessageBox.confirm("确认删除该巡检任务吗?", "删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      const res = await deleteLineInspection([row.id]);
      if (res.code === 200) {
        ElMessage.success("删除成功");
        getList();
      } else {
        ElMessage.error(res.msg || "删除失败");
      }
    })
    .catch(() => {});
};
// å®Œæˆå·¡æ£€
const 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>
.search_title {
  font-size: 14px;
  color: #606266;
}
.mb10 {
  margin-bottom: 10px;
}
.mb20 {
  margin-bottom: 20px;
}
.ml10 {
  margin-left: 10px;
}
</style>
src/views/safeProduction/safetyFacility/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,810 @@
<template>
  <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>
            <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-select>
            <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="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>
        <div class="table_list">
          <PIMTable rowKey="id"
                    :column="inspectionTableColumn"
                    :tableData="inspectionTableData"
                    :page="inspectionPage"
                    :isSelection="false"
                    :tableLoading="inspectionTableLoading"
                    @pagination="inspectionPagination"
                    :total="inspectionPage.total"></PIMTable>
        </div>
      </el-tab-pane>
      <!-- æ•´æ”¹è·Ÿè¸ª -->
      <el-tab-pane label="整改跟踪" name="rectification">
        <div class="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>
        <div class="table_list">
          <PIMTable rowKey="id"
                    :column="rectificationTableColumn"
                    :tableData="rectificationTableData"
                    :page="rectificationPage"
                    :isSelection="false"
                    :tableLoading="rectificationTableLoading"
                    @pagination="rectificationPagination"
                    :total="rectificationPage.total"></PIMTable>
        </div>
      </el-tab-pane>
    </el-tabs>
    <!-- è®¾æ–½å°è´¦è¡¨å•弹窗 -->
    <el-dialog v-model="ledgerDialogVisible"
               :title="ledgerDialogTitle"
               width="800px"
               :close-on-click-modal="false">
      <el-form ref="ledgerFormRef"
               :model="ledgerForm"
               :rules="ledgerRules"
               label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="设施编号"
                          prop="facilityCode">
              <el-input v-model="ledgerForm.facilityCode"
                        placeholder="请输入设施编号" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设施名称"
                          prop="facilityName">
              <el-input v-model="ledgerForm.facilityName"
                        placeholder="请输入设施名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="设施类型"
                          prop="facilityType">
              <el-select v-model="ledgerForm.facilityType"
                         placeholder="请选择设施类型"
                         style="width: 100%">
                <el-option label="消防器材" value="消防器材" />
                <el-option label="安全设备" value="安全设备" />
                <el-option label="防护用品" value="防护用品" />
                <el-option label="监控设备" value="监控设备" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号"
                          prop="facilitySpec">
              <el-input v-model="ledgerForm.facilitySpec"
                        placeholder="请输入规格型号" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="安装位置"
                          prop="installLocation">
              <el-input v-model="ledgerForm.installLocation"
                        placeholder="请输入安装位置" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="安装时间"
                          prop="installTime">
              <el-date-picker v-model="ledgerForm.installTime"
                              type="date"
                              placeholder="请选择安装时间"
                              format="YYYY-MM-DD"
                              value-format="YYYY-MM-DD"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="生产日期"
                          prop="productionDate">
              <el-date-picker v-model="ledgerForm.productionDate"
                              type="date"
                              placeholder="请选择生产日期"
                              format="YYYY-MM-DD"
                              value-format="YYYY-MM-DD"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="有效期(天)"
                          prop="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-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="submitLedgerForm">确定</el-button>
          <el-button @click="ledgerDialogVisible = false">取消</el-button>
        </span>
      </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"
               label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="巡检编号"
                          prop="inspectionCode">
              <el-input v-model="inspectionForm.inspectionCode"
                        placeholder="请输入巡检编号" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="巡检类型"
                          prop="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="检查说明">
            <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="submitRectificationForm">确定</el-button>
          <el-button @click="rectificationDialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, toRefs } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import {
  getFacilityLedgerList,
  addFacilityLedger,
  updateFacilityLedger,
  deleteFacilityLedger,
  getFacilityInspectionList,
  addFacilityInspection,
  updateFacilityInspection,
  deleteFacilityInspection,
  getFacilityRectificationList,
  addFacilityRectification,
  updateFacilityRectification
} from "@/api/safeProduction/safetyFacility";
// è¡¨å•验证规则
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 inspectionRules = {
  inspectionCode: [{ required: true, message: "请输入巡检编号", trigger: "blur" }]
};
// å“åº”式数据
const data = reactive({
  activeTab: "ledger",
  // è®¾æ–½å°è´¦
  ledgerSearchForm: { facilityCode: "", facilityName: "", facilityType: "", status: "" },
  ledgerTableLoading: false,
  ledgerPage: { current: 1, size: 20, total: 0 },
  ledgerTableData: [],
  ledgerSelectedIds: [],
  ledgerForm: {
    id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
    installLocation: "", installTime: "", productionDate: "", 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 {
  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 ledgerFormRef = ref();
const inspectionFormRef = ref();
const rectificationFormRef = ref();
// è®¾æ–½å°è´¦è¡¨æ ¼åˆ—配置
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 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 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) }
    ]
  }
]);
// ç”Ÿå‘½å‘¨æœŸ
onMounted(() => {
  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>
.search_title {
  font-size: 14px;
  color: #606266;
}
.mb20 {
  margin-bottom: 20px;
}
.ml10 {
  margin-left: 10px;
}
</style>