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