From bd7f920a53ba17016ee4f6324d155eef2bc4cece Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 03 八月 2026 17:00:37 +0800
Subject: [PATCH] feat: 发货信息展示源单号
---
src/views/safeProduction/safetyFacility/index.vue | 1770 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 1,608 insertions(+), 162 deletions(-)
diff --git a/src/views/safeProduction/safetyFacility/index.vue b/src/views/safeProduction/safetyFacility/index.vue
index f707580..3f81c80 100644
--- a/src/views/safeProduction/safetyFacility/index.vue
+++ b/src/views/safeProduction/safetyFacility/index.vue
@@ -1,10 +1,12 @@
<template>
- <div class="app-container">
- <el-tabs v-model="activeTab" @tab-click="handleTabClick">
+ <div class="app-container safety-facility-page">
+ <el-tabs v-model="activeTab"
+ class="facility-tabs"
+ @tab-click="handleTabClick">
<!-- 瀹夊叏璁炬柦鍙拌处 -->
<el-tab-pane label="瀹夊叏璁炬柦鍙拌处" name="ledger">
- <div class="search_form mb20">
- <div>
+ <div class="facility-toolbar">
+ <div class="toolbar-filters">
<span class="search_title">璁炬柦缂栧彿锛�</span>
<el-input v-model="ledgerSearchForm.facilityCode"
style="width: 200px"
@@ -39,12 +41,16 @@
<el-option label="鎶ュ簾" value="鎶ュ簾" />
</el-select>
<el-button type="primary"
- @click="handleLedgerQuery"
- style="margin-left: 10px">
+ @click="handleLedgerQuery">
鎼滅储
</el-button>
+ <el-button @click="resetLedgerQuery">閲嶇疆</el-button>
</div>
- <div>
+ <div class="toolbar-actions">
+ <el-button type="danger"
+ plain
+ :disabled="ledgerSelectedIds.length === 0"
+ @click="handleBatchDeleteLedger">鎵归噺鍒犻櫎</el-button>
<el-button type="primary"
@click="openLedgerForm('add')">鏂板璁炬柦</el-button>
</div>
@@ -63,10 +69,65 @@
</div>
</el-tab-pane>
- <!-- 瀹夊叏璁炬柦宸℃ -->
- <el-tab-pane label="瀹夊叏璁炬柦宸℃" name="inspection">
- <div class="search_form mb20">
- <div>
+ <!-- 宸℃浠诲姟 -->
+ <el-tab-pane label="宸℃浠诲姟" name="task">
+ <div class="facility-toolbar">
+ <div class="toolbar-filters">
+ <span class="search_title">宸℃浠诲姟鍚嶇О锛�</span>
+ <el-input v-model="taskSearchForm.inspectionName"
+ style="width: 220px"
+ placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О"
+ @change="handleTaskQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">璁炬柦鍚嶇О锛�</span>
+ <el-input v-model="taskSearchForm.facilityName"
+ style="width: 200px"
+ placeholder="璇疯緭鍏ヨ鏂藉悕绉�"
+ @change="handleTaskQuery"
+ clearable
+ :prefix-icon="Search" />
+ <span class="search_title ml10">鏄惁鍚敤锛�</span>
+ <el-select v-model="taskSearchForm.isEnabled"
+ clearable
+ @change="handleTaskQuery"
+ style="width: 150px">
+ <el-option label="鏄�" :value="1" />
+ <el-option label="鍚�" :value="0" />
+ </el-select>
+ <el-button type="primary"
+ @click="handleTaskQuery">
+ 鎼滅储
+ </el-button>
+ <el-button @click="resetTaskQuery">閲嶇疆</el-button>
+ </div>
+ <div class="toolbar-actions">
+ <el-button type="danger"
+ plain
+ :disabled="taskSelectedIds.length === 0"
+ @click="handleBatchDeleteTask">鍒犻櫎</el-button>
+ <el-button type="primary"
+ @click="openTaskDialog('add')">鏂板宸℃浠诲姟</el-button>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <PIMTable rowKey="id"
+ :column="taskTableColumn"
+ :tableData="taskTableData"
+ :page="taskPage"
+ :isSelection="true"
+ @selection-change="handleTaskSelectionChange"
+ :tableLoading="taskTableLoading"
+ @pagination="taskPagination"
+ :total="taskPage.total"></PIMTable>
+ </div>
+ </el-tab-pane>
+
+ <!-- 宸℃璁板綍 -->
+ <el-tab-pane label="宸℃璁板綍" name="inspection">
+ <div class="facility-toolbar">
+ <div class="toolbar-filters">
<span class="search_title">宸℃缂栧彿锛�</span>
<el-input v-model="inspectionSearchForm.inspectionCode"
style="width: 200px"
@@ -83,10 +144,10 @@
<el-option label="宸插贰妫�" value="宸插贰妫�" />
</el-select>
<el-button type="primary"
- @click="handleInspectionQuery"
- style="margin-left: 10px">
+ @click="handleInspectionQuery">
鎼滅储
</el-button>
+ <el-button @click="resetInspectionQuery">閲嶇疆</el-button>
</div>
</div>
@@ -104,8 +165,8 @@
<!-- 鏁存敼璺熻釜 -->
<el-tab-pane label="鏁存敼璺熻釜" name="rectification">
- <div class="search_form mb20">
- <div>
+ <div class="facility-toolbar">
+ <div class="toolbar-filters">
<span class="search_title">鐘舵�侊細</span>
<el-select v-model="rectificationSearchForm.status"
clearable
@@ -117,10 +178,10 @@
<el-option label="宸查獙鏀�" value="宸查獙鏀�" />
</el-select>
<el-button type="primary"
- @click="handleRectificationQuery"
- style="margin-left: 10px">
+ @click="handleRectificationQuery">
鎼滅储
</el-button>
+ <el-button @click="resetRectificationQuery">閲嶇疆</el-button>
</div>
</div>
@@ -217,17 +278,6 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鏈夋晥鏈�(澶�)"
- prop="validPeriod">
- <el-input-number v-model="ledgerForm.validPeriod"
- :min="0"
- placeholder="璇疯緭鍏ユ湁鏁堟湡"
- style="width: 100%" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
<el-form-item label="鐘舵��"
prop="status">
<el-select v-model="ledgerForm.status"
@@ -257,65 +307,366 @@
</template>
</el-dialog>
- <!-- 宸℃琛ㄥ崟寮圭獥 -->
- <el-dialog v-model="inspectionDialogVisible"
- :title="inspectionDialogTitle"
- width="600px"
- :close-on-click-modal="false">
- <el-form ref="inspectionFormRef"
- :model="inspectionForm"
- :rules="inspectionRules"
+ <!-- 璁炬柦鍙拌处璇︽儏寮圭獥 -->
+ <el-dialog v-model="ledgerDetailVisible"
+ title="璁炬柦璇︽儏"
+ width="760px"
+ class="detail-dialog">
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="璁炬柦缂栧彿">{{ ledgerDetail.facilityCode || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁炬柦鍚嶇О">{{ ledgerDetail.facilityName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁炬柦绫诲瀷">{{ ledgerDetail.facilityType || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瑙勬牸鍨嬪彿">{{ ledgerDetail.facilitySpec || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹夎浣嶇疆">{{ ledgerDetail.installLocation || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹夎鏃堕棿">{{ ledgerDetail.installTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐢熶骇鏃ユ湡">{{ ledgerDetail.productionDate || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐘舵��">
+ <el-tag :type="ledgerStatusType(ledgerDetail.status)">{{ ledgerDetail.status || '-' }}</el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="澶囨敞" :span="2">{{ ledgerDetail.remark || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="ledgerDetailVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 宸℃浠诲姟琛ㄥ崟寮圭獥 -->
+ <el-dialog v-model="taskDialogVisible"
+ :title="taskDialogTitle"
+ width="920px"
+ :close-on-click-modal="false"
+ @closed="resetTaskForm">
+ <el-form ref="taskFormRef"
+ :model="taskForm"
+ :rules="taskRules"
label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
- <el-form-item label="宸℃缂栧彿"
- prop="inspectionCode">
- <el-input v-model="inspectionForm.inspectionCode"
- placeholder="璇疯緭鍏ュ贰妫�缂栧彿" />
+ <el-form-item label="宸℃浠诲姟鍚嶇О"
+ prop="inspectionName">
+ <el-input v-model="taskForm.inspectionName"
+ placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О" />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="宸℃绫诲瀷"
- prop="inspectionType">
- <el-select v-model="inspectionForm.inspectionType"
- placeholder="璇烽�夋嫨宸℃绫诲瀷"
- style="width: 100%">
- <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
- <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+ <el-form-item label="瀹夊叏璁炬柦"
+ prop="facilityId">
+ <el-select v-model="taskForm.facilityId"
+ placeholder="璇烽�夋嫨瀹夊叏璁炬柦"
+ filterable
+ clearable
+ style="width: 100%"
+ @change="handleTaskFacilityChange">
+ <el-option v-for="item in facilityOptions"
+ :key="item.id"
+ :label="`${item.facilityName}锛�${item.facilityCode || '-'}锛塦"
+ :value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
- <el-form-item label="璁″垝宸℃鏃堕棿"
- prop="planTime">
- <el-date-picker v-model="inspectionForm.planTime"
- type="datetime"
- placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
- format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss"
- style="width: 100%" />
- </el-form-item>
- <template v-if="inspectionDialogTitle === '宸℃'">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃浜�"
+ prop="inspectorId">
+ <el-select v-model="taskForm.inspectorId"
+ placeholder="璇烽�夋嫨宸℃浜�"
+ filterable
+ clearable
+ style="width: 100%">
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏄惁鍚敤"
+ prop="isEnabled">
+ <el-radio-group v-model="taskForm.isEnabled">
+ <el-radio :label="1">鏄�</el-radio>
+ <el-radio :label="0">鍚�</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃椤圭洰"
+ prop="inspectionProject">
+ <el-input v-model="taskForm.inspectionProject"
+ type="textarea"
+ :autosize="{ minRows: 3, maxRows: 6 }"
+ placeholder="璇疯緭鍏ュ贰妫�椤圭洰" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="澶囨敞">
+ <el-input v-model="taskForm.remark"
+ type="textarea"
+ :autosize="{ minRows: 3, maxRows: 6 }"
+ placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="浠诲姟棰戠巼"
+ prop="frequencyType">
+ <el-select v-model="taskForm.frequencyType"
+ placeholder="璇烽�夋嫨"
+ clearable
+ style="width: 100%"
+ @change="handleFrequencyTypeChange">
+ <el-option label="姣忔棩" value="DAILY" />
+ <el-option label="姣忓懆" value="WEEKLY" />
+ <el-option label="姣忔湀" value="MONTHLY" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col v-if="taskForm.frequencyType === 'DAILY'" :span="12">
+ <el-form-item class="frequency-detail-item"
+ label="鎵ц鏃堕棿"
+ prop="frequencyDetail">
+ <el-time-picker v-model="taskForm.frequencyDetail"
+ placeholder="閫夋嫨鏃堕棿"
+ format="HH:mm"
+ value-format="HH:mm"
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ <el-col v-if="taskForm.frequencyType === 'WEEKLY'" :span="12">
+ <el-form-item class="frequency-detail-item"
+ label="鎵ц鏃堕棿"
+ prop="frequencyDetail">
+ <div class="frequency-row">
+ <el-select v-model="taskForm.week"
+ class="frequency-day-select"
+ placeholder="璇烽�夋嫨鏄熸湡"
+ clearable>
+ <el-option v-for="item in weekOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value" />
+ </el-select>
+ <el-time-picker v-model="taskForm.time"
+ class="frequency-time-picker"
+ placeholder="閫夋嫨鏃堕棿"
+ format="HH:mm"
+ value-format="HH:mm" />
+ </div>
+ </el-form-item>
+ </el-col>
+ <el-col v-if="taskForm.frequencyType === 'MONTHLY'" :span="12">
+ <el-form-item class="frequency-detail-item"
+ label="鎵ц鏃堕棿"
+ prop="frequencyDetail">
+ <div class="frequency-row">
+ <el-select v-model="taskForm.day"
+ class="frequency-day-select"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ clearable>
+ <el-option v-for="item in dayOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value" />
+ </el-select>
+ <el-time-picker v-model="taskForm.time"
+ class="frequency-time-picker"
+ placeholder="閫夋嫨鏃堕棿"
+ format="HH:mm"
+ value-format="HH:mm" />
+ </div>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary"
+ @click="submitTaskForm">淇濆瓨</el-button>
+ <el-button @click="taskDialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 宸℃浠诲姟璇︽儏 -->
+ <el-dialog v-model="taskDetailVisible"
+ title="宸℃浠诲姟璇︽儏"
+ width="860px">
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="宸℃浠诲姟鍚嶇О">{{ taskDetail.inspectionName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹夊叏璁炬柦">{{ taskDetail.facilityName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁炬柦缂栧彿">{{ taskDetail.facilityCode || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="宸℃浜�">{{ taskDetail.inspectorName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鏄惁鍚敤">{{ taskDetail.isEnabled === 1 ? '鏄�' : '鍚�' }}</el-descriptions-item>
+ <el-descriptions-item label="棰戞">{{ frequencyTypeMap[taskDetail.frequencyType] || taskDetail.frequencyType || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鎵ц鏃堕棿">{{ formatFrequencyDetail(taskDetail.frequencyDetail) }}</el-descriptions-item>
+ <el-descriptions-item label="涓嬫鎵ц鏃堕棿">{{ taskDetail.nextExecutionTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="宸℃椤圭洰" :span="2">{{ taskDetail.inspectionProject || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="澶囨敞" :span="2">{{ taskDetail.remark || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="taskDetailVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鍘嗗彶宸℃璁板綍 -->
+ <el-dialog v-model="taskHistoryVisible"
+ title="鍘嗗彶宸℃璁板綍"
+ width="1100px">
+ <el-descriptions class="history-summary" :column="3" border>
+ <el-descriptions-item label="宸℃浠诲姟鍚嶇О">{{ taskHistoryTask.inspectionName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹夊叏璁炬柦">{{ taskHistoryTask.facilityName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="棰戞">{{ frequencyTypeMap[taskHistoryTask.frequencyType] || taskHistoryTask.frequencyType || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ <PIMTable rowKey="id"
+ :column="taskHistoryTableColumn"
+ :tableData="taskHistoryTableData"
+ :page="taskHistoryPage"
+ :isSelection="false"
+ :tableLoading="taskHistoryTableLoading"
+ @pagination="taskHistoryPagination"
+ :total="taskHistoryPage.total"></PIMTable>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="taskHistoryVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 宸℃琛ㄥ崟寮圭獥 -->
+ <el-dialog v-model="inspectionDialogVisible"
+ :title="inspectionDialogTitle"
+ width="720px"
+ class="facility-form-dialog"
+ :close-on-click-modal="false">
+ <el-form ref="inspectionFormRef"
+ :model="inspectionForm"
+ :rules="inspectionRules"
+ label-position="top"
+ class="inspection-form">
+ <div v-if="inspectionForm.facilityName || inspectionForm.facilityCode"
+ class="dialog-summary">
+ <div class="summary-item">
+ <span>璁炬柦鍚嶇О</span>
+ <strong>{{ inspectionForm.facilityName || '-' }}</strong>
+ </div>
+ <div class="summary-item">
+ <span>璁炬柦缂栧彿</span>
+ <strong>{{ inspectionForm.facilityCode || '-' }}</strong>
+ </div>
+ </div>
+ <div class="inspection-form-grid">
+ <el-form-item label="宸℃缂栧彿"
+ prop="inspectionCode">
+ <el-input v-model="inspectionForm.inspectionCode"
+ placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
+ :disabled="isInspectionBaseReadonly" />
+ </el-form-item>
+ <el-form-item label="宸℃绫诲瀷"
+ prop="inspectionType">
+ <el-select v-model="inspectionForm.inspectionType"
+ placeholder="璇烽�夋嫨宸℃绫诲瀷"
+ style="width: 100%"
+ :disabled="isInspectionBaseReadonly">
+ <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
+ <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="璁″垝宸℃鏃堕棿"
+ prop="planTime"
+ class="form-grid-full">
+ <el-date-picker v-model="inspectionForm.planTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨璁″垝宸℃鏃堕棿"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%"
+ :disabled="isInspectionBaseReadonly" />
+ </el-form-item>
+ <el-form-item label="宸℃椤圭洰"
+ class="form-grid-full">
+ <el-input v-model="inspectionForm.inspectionProject"
+ type="textarea"
+ :rows="3"
+ disabled />
+ </el-form-item>
+ </div>
+ <template v-if="inspectionDialogType !== 'add'">
<el-form-item label="妫�鏌ョ粨鏋�"
prop="checkResult">
- <el-radio-group v-model="inspectionForm.checkResult">
+ <el-radio-group v-model="inspectionForm.checkResult" :disabled="isInspectionView">
<el-radio label="姝e父">姝e父</el-radio>
<el-radio label="寮傚父">寮傚父</el-radio>
</el-radio-group>
</el-form-item>
- <el-form-item label="妫�鏌ヨ鏄�">
+ <el-form-item label="妫�鏌ヨ鏄�"
+ prop="checkDesc">
<el-input v-model="inspectionForm.checkDesc"
type="textarea"
:rows="3"
- placeholder="璇疯緭鍏ユ鏌ヨ鏄�" />
+ placeholder="璇疯緭鍏ユ鏌ヨ鏄�"
+ :disabled="isInspectionView" />
+ </el-form-item>
+ <el-form-item v-if="inspectionForm.checkResult === '寮傚父'" label="鐜板満鐓х墖">
+ <ImageUpload v-model:file-list="inspectionForm.storageBlobDTOs"
+ :limit="6"
+ button-text="涓婁紶鐓х墖"
+ :disabled="isInspectionView" />
</el-form-item>
</template>
</el-form>
<template #footer>
<span class="dialog-footer">
- <el-button type="primary"
+ <el-button v-if="!isInspectionView"
+ type="primary"
@click="submitInspectionForm">纭畾</el-button>
- <el-button @click="inspectionDialogVisible = false">鍙栨秷</el-button>
+ <el-button @click="inspectionDialogVisible = false">{{ isInspectionView ? '鍏抽棴' : '鍙栨秷' }}</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 宸℃璇︽儏寮圭獥 -->
+ <el-dialog v-model="inspectionDetailVisible"
+ title="宸℃璇︽儏"
+ width="920px"
+ class="detail-dialog">
+ <el-descriptions :column="3" border>
+ <el-descriptions-item label="宸℃缂栧彿">{{ inspectionDetail.inspectionCode || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁炬柦鍚嶇О">{{ inspectionDetail.facilityName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="宸℃浜�">{{ inspectionDetail.inspectorName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁″垝宸℃鏃堕棿">{{ inspectionDetail.planTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹為檯宸℃鏃堕棿">{{ inspectionDetail.actualTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐘舵��">
+ <el-tag :type="inspectionStatusType(inspectionDetail.status)">{{ inspectionDetail.status || '-' }}</el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="妫�鏌ョ粨鏋�">
+ <el-tag :type="inspectionResultType(inspectionDetail.checkResult)">{{ inspectionDetail.checkResult || '鏈~鍐�' }}</el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃椤圭洰" :span="2">{{ inspectionDetail.inspectionProject || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="妫�鏌ヨ鏄�" :span="3">{{ inspectionDetail.checkDesc || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ <div v-if="inspectionDetailImageUrls.length" class="detail-section">
+ <div class="detail-section-title">鐜板満鐓х墖</div>
+ <div class="detail-image-list">
+ <el-image v-for="(url, index) in inspectionDetailImageUrls"
+ :key="`${url}-${index}`"
+ :src="url"
+ :preview-src-list="inspectionDetailImageUrls"
+ :initial-index="index"
+ fit="cover"
+ class="detail-image" />
+ </div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="inspectionDetailVisible = false">鍏抽棴</el-button>
</span>
</template>
</el-dialog>
@@ -327,41 +678,163 @@
:close-on-click-modal="false">
<el-form ref="rectificationFormRef"
:model="rectificationForm"
+ :rules="rectificationRules"
label-width="120px">
- <template v-if="rectificationDialogTitle !== '楠屾敹'">
- <el-form-item label="闂鎻忚堪">
- <el-input v-model="rectificationForm.problemDesc"
- type="textarea"
- :rows="3"
- placeholder="璇疯緭鍏ラ棶棰樻弿杩�" />
- </el-form-item>
- <el-form-item label="闂绛夌骇">
- <el-select v-model="rectificationForm.problemLevel"
- placeholder="璇烽�夋嫨闂绛夌骇"
- style="width: 100%">
- <el-option label="涓�鑸�" value="涓�鑸�" />
- <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
- </el-select>
- </el-form-item>
- </template>
- <el-form-item label="鏁存敼璇存槑" v-if="rectificationDialogTitle === '鏁存敼'">
+ <div v-if="rectificationForm.facilityName || rectificationForm.inspectionCode"
+ class="dialog-summary">
+ <div class="summary-item">
+ <span>璁炬柦鍚嶇О</span>
+ <strong>{{ rectificationForm.facilityName || '-' }}</strong>
+ </div>
+ <div class="summary-item">
+ <span>宸℃缂栧彿</span>
+ <strong>{{ rectificationForm.inspectionCode || '-' }}</strong>
+ </div>
+ </div>
+ <el-form-item label="闂鎻忚堪"
+ :prop="isRectificationCreate ? 'problemDesc' : undefined">
+ <el-input v-model="rectificationForm.problemDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ラ棶棰樻弿杩�"
+ :disabled="!isRectificationCreate" />
+ </el-form-item>
+ <el-form-item v-if="rectificationInspectionImageUrls.length"
+ label="宸℃寮傚父鍥剧墖">
+ <div class="rectification-image-list">
+ <el-image v-for="(url, index) in rectificationInspectionImageUrls"
+ :key="`${url}-${index}`"
+ :src="url"
+ :preview-src-list="rectificationInspectionImageUrls"
+ :initial-index="index"
+ fit="cover"
+ class="rectification-image" />
+ </div>
+ </el-form-item>
+ <el-form-item label="闂绛夌骇"
+ :prop="isRectificationCreate ? 'problemLevel' : undefined">
+ <el-select v-model="rectificationForm.problemLevel"
+ placeholder="璇烽�夋嫨闂绛夌骇"
+ style="width: 100%"
+ :disabled="!isRectificationCreate">
+ <el-option label="涓�鑸�" value="涓�鑸�" />
+ <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="璁″垝鏁存敼鏃堕棿"
+ :prop="isRectificationCreate ? 'planTime' : undefined">
+ <el-date-picker v-model="rectificationForm.planTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨璁″垝鏁存敼鏃堕棿"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%"
+ :disabled="!isRectificationCreate" />
+ </el-form-item>
+ <el-form-item label="鏁存敼璐d换浜�"
+ :prop="isRectificationCreate ? 'rectifyUserId' : undefined">
+ <el-select v-if="isRectificationCreate"
+ v-model="rectificationForm.rectifyUserId"
+ placeholder="璇烽�夋嫨鏁存敼璐d换浜�"
+ filterable
+ clearable
+ style="width: 100%">
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
+ </el-select>
+ <el-input v-else
+ :model-value="rectificationForm.rectifyUserName || getUserName(rectificationForm.rectifyUserId) || '-'"
+ disabled />
+ </el-form-item>
+ <el-form-item v-if="showVerifyUser"
+ label="楠屾敹浜�"
+ :prop="isRectificationFix ? 'verifyUserId' : undefined">
+ <el-select v-if="isRectificationFix"
+ v-model="rectificationForm.verifyUserId"
+ placeholder="璇烽�夋嫨楠屾敹浜�"
+ filterable
+ clearable
+ style="width: 100%">
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
+ </el-select>
+ <el-input v-else
+ :model-value="rectificationForm.verifyUserName || getUserName(rectificationForm.verifyUserId) || '-'"
+ disabled />
+ </el-form-item>
+ <el-form-item v-if="showRectifyDesc"
+ label="鏁存敼璇存槑"
+ :prop="isRectificationFix ? 'rectifyDesc' : undefined">
<el-input v-model="rectificationForm.rectifyDesc"
type="textarea"
:rows="3"
- placeholder="璇疯緭鍏ユ暣鏀硅鏄�" />
+ placeholder="璇疯緭鍏ユ暣鏀硅鏄�"
+ :disabled="!isRectificationFix" />
</el-form-item>
- <el-form-item label="楠屾敹璇存槑" v-if="rectificationDialogTitle === '楠屾敹'">
+ <el-form-item v-if="showVerifyDesc"
+ label="楠屾敹璇存槑"
+ :prop="isRectificationVerify ? 'verifyDesc' : undefined">
<el-input v-model="rectificationForm.verifyDesc"
type="textarea"
:rows="3"
- placeholder="璇疯緭鍏ラ獙鏀惰鏄�" />
+ placeholder="璇疯緭鍏ラ獙鏀惰鏄�"
+ :disabled="!isRectificationVerify" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
- <el-button type="primary"
+ <el-button v-if="!isRectificationView"
+ type="primary"
@click="submitRectificationForm">纭畾</el-button>
- <el-button @click="rectificationDialogVisible = false">鍙栨秷</el-button>
+ <el-button @click="rectificationDialogVisible = false">{{ isRectificationView ? '鍏抽棴' : '鍙栨秷' }}</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏁存敼璇︽儏寮圭獥 -->
+ <el-dialog v-model="rectificationDetailVisible"
+ title="鏁存敼璇︽儏"
+ width="920px"
+ class="detail-dialog">
+ <el-descriptions :column="3" border>
+ <el-descriptions-item label="宸℃缂栧彿">{{ rectificationDetail.inspectionCode || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁炬柦鍚嶇О">{{ rectificationDetail.facilityName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="闂绛夌骇">
+ <el-tag :type="rectificationLevelType(rectificationDetail.problemLevel)">
+ {{ rectificationDetail.problemLevel || '-' }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="鏁存敼璐d换浜�">{{ rectificationDetail.rectifyUserName || getUserName(rectificationDetail.rectifyUserId) || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁″垝鏁存敼鏃堕棿">{{ rectificationDetail.planTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹為檯鏁存敼鏃堕棿">{{ rectificationDetail.actualTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐘舵��">
+ <el-tag :type="rectificationStatusType(rectificationDetail.status)">{{ rectificationDetail.status || '-' }}</el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="楠屾敹浜�">{{ rectificationDetail.verifyUserName || getUserName(rectificationDetail.verifyUserId) || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="楠屾敹鏃堕棿">{{ rectificationDetail.verifyTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="闂鎻忚堪" :span="3">{{ rectificationDetail.problemDesc || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鏁存敼璇存槑" :span="3">{{ rectificationDetail.rectifyDesc || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="楠屾敹璇存槑" :span="3">{{ rectificationDetail.verifyDesc || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ <div v-if="rectificationDetailImageUrls.length" class="detail-section">
+ <div class="detail-section-title">宸℃寮傚父鍥剧墖</div>
+ <div class="detail-image-list">
+ <el-image v-for="(url, index) in rectificationDetailImageUrls"
+ :key="`${url}-${index}`"
+ :src="url"
+ :preview-src-list="rectificationDetailImageUrls"
+ :initial-index="index"
+ fit="cover"
+ class="detail-image" />
+ </div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="rectificationDetailVisible = false">鍏抽棴</el-button>
</span>
</template>
</el-dialog>
@@ -370,22 +843,96 @@
<script setup>
import { Search } from "@element-plus/icons-vue";
-import { onMounted, ref, reactive, toRefs } from "vue";
+import { onMounted, ref, reactive, toRefs, computed, provide } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
+import { userListNoPage } from "@/api/system/user.js";
+import useUserStore from "@/store/modules/user";
import {
getFacilityLedgerList,
addFacilityLedger,
updateFacilityLedger,
deleteFacilityLedger,
+ getFacilityInspectionTaskList,
+ addFacilityInspectionTask,
+ updateFacilityInspectionTask,
+ deleteFacilityInspectionTask,
getFacilityInspectionList,
- addFacilityInspection,
updateFacilityInspection,
deleteFacilityInspection,
getFacilityRectificationList,
addFacilityRectification,
updateFacilityRectification
} from "@/api/safeProduction/safetyFacility";
+
+const userStore = useUserStore();
+const userList = ref([]);
+const currentUserId = computed(() => Number(userStore.id) || null);
+const ENABLED = 1;
+
+const weekOptions = [
+ { label: "鍛ㄤ竴", value: "MON" },
+ { label: "鍛ㄤ簩", value: "TUE" },
+ { label: "鍛ㄤ笁", value: "WED" },
+ { label: "鍛ㄥ洓", value: "THU" },
+ { label: "鍛ㄤ簲", value: "FRI" },
+ { label: "鍛ㄥ叚", value: "SAT" },
+ { label: "鍛ㄦ棩", value: "SUN" }
+];
+
+const dayOptions = Array.from({ length: 31 }, (_, index) => {
+ const value = String(index + 1).padStart(2, "0");
+ return { label: `${index + 1}鏃, value };
+});
+
+const frequencyTypeMap = {
+ DAILY: "姣忔棩",
+ WEEKLY: "姣忓懆",
+ MONTHLY: "姣忔湀"
+};
+
+const weekLabelMap = weekOptions.reduce((map, item) => {
+ map[item.value] = item.label;
+ return map;
+}, {});
+
+const createTaskForm = () => ({
+ id: null,
+ inspectionName: "",
+ facilityId: null,
+ facilityCode: "",
+ facilityName: "",
+ inspectionProject: "",
+ inspectorId: "",
+ frequencyType: "",
+ frequencyDetail: "",
+ week: "",
+ day: "",
+ time: "",
+ isEnabled: ENABLED,
+ remark: ""
+});
+
+const validateFrequencyDetail = (rule, value, callback) => {
+ if (!taskForm.value.frequencyType) {
+ callback(new Error("璇烽�夋嫨浠诲姟棰戠巼"));
+ return;
+ }
+ if (taskForm.value.frequencyType === "DAILY" && !taskForm.value.frequencyDetail) {
+ callback(new Error("璇烽�夋嫨鎵ц鏃堕棿"));
+ return;
+ }
+ if (taskForm.value.frequencyType === "WEEKLY" && (!taskForm.value.week || !taskForm.value.time)) {
+ callback(new Error("璇烽�夋嫨鏄熸湡鍜屾椂闂�"));
+ return;
+ }
+ if (taskForm.value.frequencyType === "MONTHLY" && (!taskForm.value.day || !taskForm.value.time)) {
+ callback(new Error("璇烽�夋嫨鏃ユ湡鍜屾椂闂�"));
+ return;
+ }
+ callback();
+};
// 琛ㄥ崟楠岃瘉瑙勫垯
const ledgerRules = {
@@ -395,8 +942,30 @@
installLocation: [{ required: true, message: "璇疯緭鍏ュ畨瑁呬綅缃�", trigger: "blur" }]
};
+const taskRules = {
+ inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О", trigger: "blur" }],
+ facilityId: [{ required: true, message: "璇烽�夋嫨瀹夊叏璁炬柦", trigger: "change" }],
+ inspectionProject: [{ required: true, message: "璇疯緭鍏ュ贰妫�椤圭洰", trigger: "blur" }],
+ inspectorId: [{ required: true, message: "璇烽�夋嫨宸℃浜�", trigger: "change" }],
+ frequencyType: [{ required: true, message: "璇烽�夋嫨浠诲姟棰戠巼", trigger: "change" }],
+ frequencyDetail: [{ required: true, validator: validateFrequencyDetail, trigger: "change" }]
+};
+
const inspectionRules = {
- inspectionCode: [{ required: true, message: "璇疯緭鍏ュ贰妫�缂栧彿", trigger: "blur" }]
+ inspectionCode: [{ required: true, message: "璇疯緭鍏ュ贰妫�缂栧彿", trigger: "blur" }],
+ inspectionType: [{ required: true, message: "璇烽�夋嫨宸℃绫诲瀷", trigger: "change" }],
+ planTime: [{ required: true, message: "璇烽�夋嫨璁″垝宸℃鏃堕棿", trigger: "change" }],
+ checkResult: [{ required: true, message: "璇烽�夋嫨妫�鏌ョ粨鏋�", trigger: "change" }]
+};
+
+const rectificationRules = {
+ problemDesc: [{ required: true, message: "璇疯緭鍏ラ棶棰樻弿杩�", trigger: "blur" }],
+ problemLevel: [{ required: true, message: "璇烽�夋嫨闂绛夌骇", trigger: "change" }],
+ planTime: [{ required: true, message: "璇烽�夋嫨璁″垝鏁存敼鏃堕棿", trigger: "change" }],
+ rectifyUserId: [{ required: true, message: "璇烽�夋嫨鏁存敼璐d换浜�", trigger: "change" }],
+ verifyUserId: [{ required: true, message: "璇烽�夋嫨楠屾敹浜�", trigger: "change" }],
+ rectifyDesc: [{ required: true, message: "璇疯緭鍏ユ暣鏀硅鏄�", trigger: "blur" }],
+ verifyDesc: [{ required: true, message: "璇疯緭鍏ラ獙鏀惰鏄�", trigger: "blur" }]
};
// 鍝嶅簲寮忔暟鎹�
@@ -410,24 +979,45 @@
ledgerSelectedIds: [],
ledgerForm: {
id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
- installLocation: "", installTime: "", productionDate: "", validPeriod: null,
+ installLocation: "", installTime: "", productionDate: "",
status: "姝e父", remark: ""
},
ledgerDialogVisible: false,
ledgerDialogTitle: "",
ledgerDialogType: "add",
+ ledgerDetailVisible: false,
+ ledgerDetail: {},
+ // 宸℃浠诲姟
+ taskSearchForm: { inspectionName: "", facilityName: "", isEnabled: "" },
+ taskTableLoading: false,
+ taskPage: { current: 1, size: 20, total: 0 },
+ taskTableData: [],
+ taskSelectedIds: [],
+ taskForm: createTaskForm(),
+ taskDialogVisible: false,
+ taskDialogTitle: "鏂板宸℃浠诲姟",
+ taskDetailVisible: false,
+ taskDetail: {},
+ taskHistoryVisible: false,
+ taskHistoryTask: {},
+ taskHistoryTableLoading: false,
+ taskHistoryPage: { current: 1, size: 10, total: 0 },
+ taskHistoryTableData: [],
+ facilityOptions: [],
// 宸℃璁板綍
inspectionSearchForm: { inspectionCode: "", status: "" },
inspectionTableLoading: false,
inspectionPage: { current: 1, size: 20, total: 0 },
inspectionTableData: [],
inspectionForm: {
- id: null, facilityId: null, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
- planTime: "", checkResult: "", checkDesc: ""
+ id: null, scheduleTaskId: null, facilityId: null, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
+ facilityCode: "", facilityName: "", inspectionProject: "", planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: []
},
inspectionDialogVisible: false,
inspectionDialogTitle: "",
- inspectionDialogType: "add",
+ inspectionDialogType: "do",
+ inspectionDetailVisible: false,
+ inspectionDetail: {},
// 鏁存敼璺熻釜
rectificationSearchForm: { status: "" },
rectificationTableLoading: false,
@@ -435,66 +1025,291 @@
rectificationTableData: [],
rectificationForm: {
id: null, inspectionId: null, facilityId: null, problemDesc: "",
- problemLevel: "", rectifyDesc: "", verifyDesc: ""
+ problemLevel: "", rectifyUserId: "", rectifyUserName: "", verifyUserId: "",
+ verifyUserName: "", facilityName: "", facilityCode: "", inspectionCode: "",
+ planTime: "", actualTime: "", rectifyDesc: "", verifyTime: "", verifyDesc: "",
+ status: "", storageBlobVOs: []
},
rectificationDialogVisible: false,
rectificationDialogTitle: "",
- rectificationDialogType: "add"
+ rectificationDialogType: "add",
+ rectificationDetailVisible: false,
+ rectificationDetail: {}
});
const {
activeTab,
ledgerSearchForm, ledgerTableLoading, ledgerPage, ledgerTableData, ledgerSelectedIds,
- ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType,
+ ledgerForm, ledgerDialogVisible, ledgerDialogTitle, ledgerDialogType, ledgerDetailVisible, ledgerDetail,
+ taskSearchForm, taskTableLoading, taskPage, taskTableData, taskSelectedIds,
+ taskForm, taskDialogVisible, taskDialogTitle, taskDetailVisible, taskDetail,
+ taskHistoryVisible, taskHistoryTask, taskHistoryTableLoading, taskHistoryPage, taskHistoryTableData,
+ facilityOptions,
inspectionSearchForm, inspectionTableLoading, inspectionPage, inspectionTableData,
- inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType,
+ inspectionForm, inspectionDialogVisible, inspectionDialogTitle, inspectionDialogType, inspectionDetailVisible, inspectionDetail,
rectificationSearchForm, rectificationTableLoading, rectificationPage, rectificationTableData,
- rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType
+ rectificationForm, rectificationDialogVisible, rectificationDialogTitle, rectificationDialogType,
+ rectificationDetailVisible, rectificationDetail
} = toRefs(data);
// 琛ㄥ崟寮曠敤
const ledgerFormRef = ref();
+const taskFormRef = ref();
const inspectionFormRef = ref();
const rectificationFormRef = ref();
+const isInspectionView = computed(() => inspectionDialogType.value === "view");
+const isInspectionBaseReadonly = computed(() => inspectionDialogType.value !== "add");
+const isRectificationView = computed(() => rectificationDialogType.value === "view");
+const isRectificationCreate = computed(() => rectificationDialogType.value === "add");
+const isRectificationFix = computed(() => rectificationDialogType.value === "do");
+const isRectificationVerify = computed(() => rectificationDialogType.value === "verify");
+const showRectifyDesc = computed(
+ () =>
+ isRectificationFix.value ||
+ isRectificationVerify.value ||
+ (isRectificationView.value && !!rectificationForm.value.rectifyDesc)
+);
+const showVerifyDesc = computed(
+ () =>
+ isRectificationVerify.value ||
+ (isRectificationView.value &&
+ (rectificationForm.value.status === "宸查獙鏀�" || !!rectificationForm.value.verifyDesc))
+);
+const showVerifyUser = computed(
+ () =>
+ isRectificationFix.value ||
+ isRectificationVerify.value ||
+ isRectificationView.value ||
+ !!rectificationForm.value.verifyUserId
+);
+const getAttachmentUrl = item => {
+ if (!item) return "";
+ if (typeof item === "string") return item;
+ return item.url || item.previewURL || item.previewUrl || item.downloadURL || "";
+};
+const rectificationInspectionImageUrls = computed(() => {
+ const list = rectificationForm.value.storageBlobVOs || rectificationForm.value.storageBlobDTOs || [];
+ return list.map(getAttachmentUrl).filter(Boolean);
+});
+const inspectionDetailImageUrls = computed(() => {
+ const list = inspectionDetail.value.storageBlobVOs || inspectionDetail.value.storageBlobDTOs || [];
+ return list.map(getAttachmentUrl).filter(Boolean);
+});
+const rectificationDetailImageUrls = computed(() => {
+ const list = rectificationDetail.value.storageBlobVOs || rectificationDetail.value.storageBlobDTOs || [];
+ return list.map(getAttachmentUrl).filter(Boolean);
+});
+
+const ledgerStatusType = value => {
+ const map = { 姝e父: "success", 寮傚父: "danger", 鎶ュ簾: "info" };
+ return map[value] || "info";
+};
+const inspectionResultType = value => {
+ const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+ return map[value || "鏈~鍐�"] || "info";
+};
+const inspectionStatusType = value => value === "寰呭贰妫�" ? "info" : "success";
+const rectificationLevelType = value => value === "閲嶅ぇ" ? "danger" : "warning";
+const rectificationStatusType = value => {
+ const map = { 寰呮暣鏀�: "danger", 鏁存敼涓�: "warning", 宸叉暣鏀�: "success", 宸查獙鏀�: "info" };
+ return map[value] || "info";
+};
+
+const padTime = value => String(value).padStart(2, "0");
+const formatDateTime = (date = new Date()) => {
+ const target = date instanceof Date ? date : new Date(date);
+ return `${target.getFullYear()}-${padTime(target.getMonth() + 1)}-${padTime(target.getDate())} ${padTime(target.getHours())}:${padTime(target.getMinutes())}:${padTime(target.getSeconds())}`;
+};
+const addDaysDateTime = days => {
+ const target = new Date();
+ target.setDate(target.getDate() + days);
+ target.setHours(18, 0, 0, 0);
+ return formatDateTime(target);
+};
+const getUserName = userId => {
+ const user = userList.value.find(item => Number(item.userId) === Number(userId));
+ return user?.nickName || "";
+};
+const formatFrequencyDetail = value => {
+ if (!value) return "--";
+ if (!value.includes(",")) return value;
+ const [firstPart, timePart] = value.split(",");
+ if (weekLabelMap[firstPart]) {
+ return `${weekLabelMap[firstPart]} ${timePart || ""}`.trim();
+ }
+ if (firstPart) {
+ return `${Number(firstPart)}鏃� ${timePart || ""}`.trim();
+ }
+ return value;
+};
+const isPendingInspection = row => row?.status === "寰呭贰妫�";
+const isCheckedInspection = row => row?.status === "宸插贰妫�";
+const isAbnormalInspection = row => row?.checkResult === "寮傚父";
+const isPendingRectification = row => row?.status === "寰呮暣鏀�" || row?.status === "鏁存敼涓�";
+const isRectified = row => row?.status === "宸叉暣鏀�";
+const isNotAssignedVerifier = row =>
+ row?.verifyUserId && Number(row.verifyUserId) !== Number(currentUserId.value);
+
+provide("parentMethods", {
+ openLedgerDetail: row => openLedgerDetail(row),
+ openTaskDetail: row => openTaskDetail(row),
+ openInspectionDetail: row => openInspectionDetail(row)
+});
// 璁炬柦鍙拌处琛ㄦ牸鍒楅厤缃�
const ledgerTableColumn = ref([
- { label: "璁炬柦缂栧彿", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
- { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
- { label: "璁炬柦绫诲瀷", prop: "facilityType", showOverflowTooltip: true, minWidth: 100 },
- { label: "瑙勬牸鍨嬪彿", prop: "facilitySpec", showOverflowTooltip: true, minWidth: 120 },
- { label: "瀹夎浣嶇疆", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 },
- { label: "瀹夎鏃堕棿", prop: "installTime", minWidth: 120 },
- { label: "涓嬫妫�鏌ユ椂闂�", prop: "nextCheckTime", minWidth: 120 },
{
- label: "鐘舵��", prop: "status", minWidth: 80, dataType: "tag",
+ label: "璁炬柦缂栧彿",
+ prop: "facilityCode",
+ dataType: "link",
+ linkMethod: "openLedgerDetail",
+ showOverflowTooltip: true,
+ minWidth: 120,
+ align: "center",
+ },
+ { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 , align: "center"},
+ { label: "璁炬柦绫诲瀷", prop: "facilityType", showOverflowTooltip: true, minWidth: 120 , align: "center"},
+ { label: "瀹夎浣嶇疆", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 , align: "center"},
+ { label: "瀹夎鏃堕棿", prop: "installTime", minWidth: 120 , align: "center"},
+ {
+ label: "鐘舵��", prop: "status", minWidth: 100, dataType: "tag", align: "center",
formatType: params => {
const map = { 姝e父: "success", 寮傚父: "danger", 鎶ュ簾: "info" };
return map[params] || "info";
}
},
{
- dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+ dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 140,
operation: [
{ name: "缂栬緫", type: "text", clickFun: row => openLedgerForm("edit", row) },
- { name: "鍙戣捣宸℃", type: "text", clickFun: row => openInspectionForm("add", row) },
- { name: "鍒犻櫎", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteLedger(row) }
+ { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteLedger(row) }
]
+ }
+]);
+
+// 宸℃浠诲姟琛ㄦ牸鍒楅厤缃�
+const taskTableColumn = ref([
+ {
+ label: "宸℃浠诲姟鍚嶇О",
+ prop: "inspectionName",
+ dataType: "link",
+ linkMethod: "openTaskDetail",
+ showOverflowTooltip: true,
+ minWidth: 170,
+ align: "left"
+ },
+ { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 155, align: "left" },
+ { label: "宸℃椤圭洰", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 190, align: "left" },
+ { label: "鎵ц宸℃浜�", prop: "inspectorName", minWidth: 120, align: "center" },
+ {
+ label: "鏄惁鍚敤",
+ prop: "isEnabled",
+ minWidth: 90,
+ align: "center",
+ dataType: "tag",
+ formatData: value => value === 1 ? "鏄�" : "鍚�",
+ formatType: value => value === 1 ? "success" : "info"
+ },
+ {
+ label: "棰戞",
+ prop: "frequencyType",
+ minWidth: 90,
+ align: "center",
+ formatData: value => frequencyTypeMap[value] || value || "--"
+ },
+ {
+ label: "鎵ц鏃堕棿",
+ prop: "frequencyDetail",
+ minWidth: 120,
+ align: "center",
+ formatData: value => formatFrequencyDetail(value)
+ },
+ { label: "涓嬫鎵ц鏃堕棿", prop: "nextExecutionTime", minWidth: 170, showOverflowTooltip: true, align: "center" },
+ {
+ dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 220,
+ operation: [
+ { name: "鍘嗗彶宸℃", type: "text", clickFun: row => openTaskHistory(row) },
+ { name: "缂栬緫", type: "text", clickFun: row => openTaskDialog("edit", row) },
+ { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteTask(row) }
+ ]
+ }
+]);
+
+const taskHistoryTableColumn = ref([
+ {
+ label: "宸℃缂栧彿",
+ prop: "inspectionCode",
+ dataType: "link",
+ linkMethod: "openInspectionDetail",
+ showOverflowTooltip: true,
+ minWidth: 180,
+ align: "center"
+ },
+ { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150, align: "left" },
+ { label: "宸℃椤圭洰", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 180, align: "left" },
+ { label: "璁″垝宸℃鏃堕棿", prop: "planTime", minWidth: 170, align: "center" },
+ { label: "宸℃浜�", prop: "inspectorName", minWidth: 110, align: "center" },
+ { label: "瀹為檯宸℃鏃堕棿", prop: "actualTime", minWidth: 170, align: "center" },
+ {
+ label: "妫�鏌ョ粨鏋�", prop: "checkResult", minWidth: 100, align: "center", dataType: "tag",
+ formatData: params => params || "鏈~鍐�",
+ formatType: params => {
+ const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+ return map[params] || "info";
+ }
+ },
+ {
+ label: "鐘舵��", prop: "status", minWidth: 100, align: "center", dataType: "tag",
+ formatType: params => params === "寰呭贰妫�" ? "info" : "success"
}
]);
// 宸℃璁板綍琛ㄦ牸鍒楅厤缃�
const inspectionTableColumn = ref([
- { label: "宸℃缂栧彿", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
- { label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
- { label: "璁炬柦缂栧彿", prop: "facilityCode", showOverflowTooltip: true, minWidth: 120 },
- { label: "宸℃绫诲瀷", prop: "inspectionType", minWidth: 100 },
- { label: "璁″垝宸℃鏃堕棿", prop: "planTime", minWidth: 180 },
- { label: "宸℃浜�", prop: "inspectorName", minWidth: 100 },
- { label: "瀹為檯宸℃鏃堕棿", prop: "actualTime", minWidth: 180 },
+ {
+ label: "宸℃缂栧彿",
+ dataType: "link",
+ linkMethod: "openInspectionDetail",
+ width: 200,
+ align: "center",
+ prop: "inspectionCode",
+ showOverflowTooltip: true,
+ minWidth: 150
+ },
+ {
+ label: "璁炬柦鍚嶇О",
+ prop: "facilityName",
+ showOverflowTooltip: true,
+ minWidth: 150
+ },
+ {
+ label: "宸℃椤圭洰",
+ prop: "inspectionProject",
+ showOverflowTooltip: true,
+ minWidth: 180
+ },
+ {
+ label: "璁″垝宸℃鏃堕棿",
+ prop: "planTime",
+ minWidth: 180
+ },
+ {
+ label: "宸℃浜�",
+ prop: "inspectorName",
+ minWidth: 100
+ },
+ {
+ label: "瀹為檯宸℃鏃堕棿",
+ prop: "actualTime",
+ minWidth: 180
+ },
{
label: "妫�鏌ョ粨鏋�", prop: "checkResult", minWidth: 100, dataType: "tag",
- formatType: params => params === "姝e父" ? "success" : "danger"
+ formatData: params => params || "鏈~鍐�",
+ formatType: params => {
+ const map = { 姝e父: "success", 寮傚父: "danger", 鏈~鍐�: "info" };
+ return map[params] || "info";
+ }
},
{
label: "鐘舵��", prop: "status", minWidth: 100, dataType: "tag",
@@ -506,25 +1321,26 @@
{
name: "宸℃", type: "text",
clickFun: row => openInspectionForm("do", row),
- show: row => row.status === "寰呭贰妫�"
+ show: isPendingInspection
},
{
name: "鏌ョ湅", type: "text",
- clickFun: row => openInspectionForm("view", row),
- show: row => row.status !== "寰呭贰妫�"
+ clickFun: row => openInspectionDetail(row),
+ show: isCheckedInspection
},
{
name: "鏁存敼", type: "text",
- clickFun: row => openRectificationForm("add", row),
- show: row => row.checkResult === "寮傚父"
+ clickFun: row => openRectificationFromInspection(row),
+ show: row => isCheckedInspection(row) && isAbnormalInspection(row)
},
- { name: "鍒犻櫎", type: "text", style: { color: "#F56C6C" }, clickFun: row => handleDeleteInspection(row) }
+ { name: "鍒犻櫎", type: "text", clickFun: row => handleDeleteInspection(row), show: isPendingInspection }
]
}
]);
// 鏁存敼璺熻釜琛ㄦ牸鍒楅厤缃�
const rectificationTableColumn = ref([
+ { label: "宸℃缂栧彿", prop: "inspectionCode", showOverflowTooltip: true, minWidth: 150 },
{ label: "璁炬柦鍚嶇О", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 },
{ label: "闂鎻忚堪", prop: "problemDesc", showOverflowTooltip: true, minWidth: 200 },
{
@@ -540,21 +1356,21 @@
return map[params] || "info";
}
},
- { label: "楠屾敹浜�", prop: "verifyUserName", minWidth: 120 },
{
- dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 200,
+ dataType: "action", label: "鎿嶄綔", align: "center", fixed: "right", width: 180,
operation: [
{
name: "鏁存敼", type: "text",
clickFun: row => openRectificationForm("do", row),
- show: row => row.status === "寰呮暣鏀�" || row.status === "鏁存敼涓�"
+ show: isPendingRectification
},
{
name: "楠屾敹", type: "text",
clickFun: row => openRectificationForm("verify", row),
- show: row => row.status === "宸叉暣鏀�"
+ show: isRectified,
+ disabled: isNotAssignedVerifier
},
- { name: "鏌ョ湅", type: "text", clickFun: row => openRectificationForm("view", row) }
+ { name: "鏌ョ湅", type: "text", clickFun: row => openRectificationDetail(row) }
]
}
]);
@@ -562,13 +1378,31 @@
// 鐢熷懡鍛ㄦ湡
onMounted(() => {
getLedgerList();
+ getTaskList();
+ getInspectionList();
+ getRectificationList();
+ getFacilityOptionList();
+ getUserList();
});
// 鏍囩椤靛垏鎹�
const handleTabClick = () => {
if (activeTab.value === "ledger") getLedgerList();
+ else if (activeTab.value === "task") getTaskList();
else if (activeTab.value === "inspection") getInspectionList();
else if (activeTab.value === "rectification") getRectificationList();
+};
+
+const getUserList = () => {
+ userListNoPage().then(res => {
+ userList.value = res.data || [];
+ });
+};
+
+const getFacilityOptionList = () => {
+ getFacilityLedgerList({ current: 1, size: 1000 }).then(res => {
+ facilityOptions.value = (res.data?.records || []).filter(item => item.status !== "鎶ュ簾");
+ });
};
// ============ 璁炬柦鍙拌处鏂规硶 ============
@@ -578,13 +1412,23 @@
getLedgerList();
};
+const resetLedgerQuery = () => {
+ Object.assign(ledgerSearchForm.value, {
+ facilityCode: "",
+ facilityName: "",
+ facilityType: "",
+ status: ""
+ });
+ handleLedgerQuery();
+};
+
const getLedgerList = () => {
ledgerTableLoading.value = true;
getFacilityLedgerList({ ...ledgerPage.value, ...ledgerSearchForm.value })
.then(res => {
ledgerTableLoading.value = false;
- ledgerTableData.value = res.data.records;
- ledgerPage.value.total = res.data.total;
+ ledgerTableData.value = res.data?.records || [];
+ ledgerPage.value.total = res.data?.total || 0;
})
.catch(() => { ledgerTableLoading.value = false; });
};
@@ -599,13 +1443,18 @@
ledgerSelectedIds.value = selection.map(item => item.id);
};
+const openLedgerDetail = row => {
+ ledgerDetail.value = { ...row };
+ ledgerDetailVisible.value = true;
+};
+
const openLedgerForm = (type, row = null) => {
ledgerDialogType.value = type;
if (type === "add") {
ledgerDialogTitle.value = "鏂板璁炬柦";
Object.assign(ledgerForm.value, {
id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "",
- installLocation: "", installTime: "", productionDate: "", validPeriod: null,
+ installLocation: "", installTime: "", productionDate: "",
status: "姝e父", remark: ""
});
} else {
@@ -624,6 +1473,7 @@
ElMessage.success(ledgerDialogType.value === "add" ? "娣诲姞鎴愬姛" : "鏇存柊鎴愬姛");
ledgerDialogVisible.value = false;
getLedgerList();
+ getFacilityOptionList();
} else {
ElMessage.error(res.msg || "鎿嶄綔澶辫触");
}
@@ -640,8 +1490,242 @@
if (res.code === 200) {
ElMessage.success("鍒犻櫎鎴愬姛");
getLedgerList();
+ getFacilityOptionList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
}
}).catch(() => {});
+};
+
+const handleBatchDeleteLedger = () => {
+ if (ledgerSelectedIds.value.length === 0) {
+ ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑璁炬柦");
+ return;
+ }
+ ElMessageBox.confirm("纭鍒犻櫎閫変腑鐨勮鏂藉悧锛熷凡浜х敓宸℃璁板綍鐨勮鏂戒笉浼氳鍚庣鍏佽鍒犻櫎銆�", "鎵归噺鍒犻櫎", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }).then(async () => {
+ const res = await deleteFacilityLedger(ledgerSelectedIds.value);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ ledgerSelectedIds.value = [];
+ getLedgerList();
+ getFacilityOptionList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+ }).catch(() => {});
+};
+
+// ============ 宸℃浠诲姟鏂规硶 ============
+
+const handleTaskQuery = () => {
+ taskPage.value.current = 1;
+ getTaskList();
+};
+
+const resetTaskQuery = () => {
+ Object.assign(taskSearchForm.value, {
+ inspectionName: "",
+ facilityName: "",
+ isEnabled: ""
+ });
+ handleTaskQuery();
+};
+
+const getTaskList = () => {
+ taskTableLoading.value = true;
+ getFacilityInspectionTaskList({ ...taskPage.value, ...taskSearchForm.value })
+ .then(res => {
+ taskTableLoading.value = false;
+ taskTableData.value = res.data?.records || [];
+ taskPage.value.total = res.data?.total || 0;
+ })
+ .catch(() => { taskTableLoading.value = false; });
+};
+
+const taskPagination = obj => {
+ taskPage.value.current = obj.page;
+ taskPage.value.size = obj.limit;
+ getTaskList();
+};
+
+const handleTaskSelectionChange = selection => {
+ taskSelectedIds.value = selection.map(item => item.id);
+};
+
+const openTaskDetail = row => {
+ taskDetail.value = { ...row };
+ taskDetailVisible.value = true;
+};
+
+const openTaskDialog = (type, row = null) => {
+ resetTaskForm();
+ taskDialogTitle.value = type === "add" ? "鏂板宸℃浠诲姟" : "缂栬緫宸℃浠诲姟";
+ if (type === "edit" && row) {
+ Object.assign(taskForm.value, {
+ id: row.id,
+ inspectionName: row.inspectionName,
+ facilityId: row.facilityId,
+ facilityCode: row.facilityCode,
+ facilityName: row.facilityName,
+ inspectionProject: row.inspectionProject,
+ inspectorId: row.inspectorId,
+ frequencyType: row.frequencyType,
+ frequencyDetail: row.frequencyDetail,
+ isEnabled: row.isEnabled ?? ENABLED,
+ remark: row.remark
+ });
+ parseFrequencyDetail(row.frequencyType, row.frequencyDetail);
+ }
+ taskDialogVisible.value = true;
+};
+
+const resetTaskForm = () => {
+ Object.assign(taskForm.value, createTaskForm());
+ taskFormRef.value?.clearValidate?.();
+};
+
+const handleTaskFacilityChange = facilityId => {
+ const facility = facilityOptions.value.find(item => Number(item.id) === Number(facilityId));
+ taskForm.value.facilityCode = facility?.facilityCode || "";
+ taskForm.value.facilityName = facility?.facilityName || "";
+};
+
+const handleFrequencyTypeChange = () => {
+ Object.assign(taskForm.value, { frequencyDetail: "", week: "", day: "", time: "" });
+ taskFormRef.value?.clearValidate?.("frequencyDetail");
+};
+
+const parseFrequencyDetail = (frequencyType, frequencyDetail) => {
+ if (!frequencyDetail) return;
+ if (frequencyType === "DAILY") {
+ taskForm.value.frequencyDetail = frequencyDetail;
+ return;
+ }
+ const [firstPart, timePart] = frequencyDetail.split(",");
+ taskForm.value.frequencyDetail = "";
+ taskForm.value.time = timePart || "";
+ if (frequencyType === "WEEKLY") {
+ taskForm.value.week = firstPart || "";
+ }
+ if (frequencyType === "MONTHLY") {
+ taskForm.value.day = String(firstPart || "").padStart(2, "0");
+ }
+};
+
+const buildFrequencyDetail = () => {
+ if (taskForm.value.frequencyType === "DAILY") {
+ return taskForm.value.frequencyDetail;
+ }
+ if (taskForm.value.frequencyType === "WEEKLY") {
+ return `${taskForm.value.week},${taskForm.value.time}`;
+ }
+ if (taskForm.value.frequencyType === "MONTHLY") {
+ return `${taskForm.value.day},${taskForm.value.time}`;
+ }
+ return "";
+};
+
+const submitTaskForm = async () => {
+ try {
+ await taskFormRef.value.validate();
+ const payload = {
+ id: taskForm.value.id,
+ inspectionName: taskForm.value.inspectionName,
+ facilityId: taskForm.value.facilityId,
+ facilityCode: taskForm.value.facilityCode,
+ facilityName: taskForm.value.facilityName,
+ inspectionProject: taskForm.value.inspectionProject,
+ inspectorId: taskForm.value.inspectorId,
+ frequencyType: taskForm.value.frequencyType,
+ frequencyDetail: buildFrequencyDetail(),
+ isEnabled: taskForm.value.isEnabled,
+ remark: taskForm.value.remark
+ };
+ const api = payload.id ? updateFacilityInspectionTask : addFacilityInspectionTask;
+ const res = await api(payload);
+ if (res.code === 200) {
+ ElMessage.success(payload.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+ taskDialogVisible.value = false;
+ activeTab.value = "task";
+ getTaskList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("浠诲姟琛ㄥ崟鏍¢獙澶辫触:", error);
+ }
+};
+
+const handleDeleteTask = row => {
+ ElMessageBox.confirm("纭鍒犻櫎璇ュ畾鏃跺贰妫�浠诲姟鍚楋紵", "鍒犻櫎", {
+ confirmButtonText: "纭", cancelButtonText: "鍙栨秷", type: "warning"
+ }).then(async () => {
+ const res = await deleteFacilityInspectionTask([row.id]);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ getTaskList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+ }).catch(() => {});
+};
+
+const handleBatchDeleteTask = () => {
+ if (taskSelectedIds.value.length === 0) {
+ ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑宸℃浠诲姟");
+ return;
+ }
+ ElMessageBox.confirm("纭鍒犻櫎閫変腑鐨勫畾鏃跺贰妫�浠诲姟鍚楋紵", "鎵归噺鍒犻櫎", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }).then(async () => {
+ const res = await deleteFacilityInspectionTask(taskSelectedIds.value);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ taskSelectedIds.value = [];
+ getTaskList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+ }).catch(() => {});
+};
+
+const openTaskHistory = row => {
+ taskHistoryTask.value = { ...row };
+ taskHistoryPage.value.current = 1;
+ taskHistoryVisible.value = true;
+ getTaskHistoryList();
+};
+
+const getTaskHistoryList = () => {
+ if (!taskHistoryTask.value?.id) {
+ taskHistoryTableData.value = [];
+ taskHistoryPage.value.total = 0;
+ return;
+ }
+ taskHistoryTableLoading.value = true;
+ getFacilityInspectionList({
+ current: taskHistoryPage.value.current,
+ size: taskHistoryPage.value.size,
+ scheduleTaskId: taskHistoryTask.value.id
+ })
+ .then(res => {
+ taskHistoryTableLoading.value = false;
+ taskHistoryTableData.value = res.data?.records || [];
+ taskHistoryPage.value.total = res.data?.total || 0;
+ })
+ .catch(() => { taskHistoryTableLoading.value = false; });
+};
+
+const taskHistoryPagination = obj => {
+ taskHistoryPage.value.current = obj.page;
+ taskHistoryPage.value.size = obj.limit;
+ getTaskHistoryList();
};
// ============ 宸℃璁板綍鏂规硶 ============
@@ -651,13 +1735,21 @@
getInspectionList();
};
+const resetInspectionQuery = () => {
+ Object.assign(inspectionSearchForm.value, {
+ inspectionCode: "",
+ status: ""
+ });
+ handleInspectionQuery();
+};
+
const getInspectionList = () => {
inspectionTableLoading.value = true;
getFacilityInspectionList({ ...inspectionPage.value, ...inspectionSearchForm.value })
.then(res => {
inspectionTableLoading.value = false;
- inspectionTableData.value = res.data.records;
- inspectionPage.value.total = res.data.total;
+ inspectionTableData.value = res.data?.records || [];
+ inspectionPage.value.total = res.data?.total || 0;
})
.catch(() => { inspectionTableLoading.value = false; });
};
@@ -668,23 +1760,36 @@
getInspectionList();
};
+const openInspectionDetail = row => {
+ inspectionDetail.value = {
+ ...row,
+ storageBlobDTOs: row.storageBlobVOs || row.storageBlobDTOs || []
+ };
+ inspectionDetailVisible.value = true;
+};
+
const openInspectionForm = (type, row = null) => {
+ if (type === "view") {
+ openInspectionDetail(row);
+ return;
+ }
inspectionDialogType.value = type;
- if (type === "add") {
- inspectionDialogTitle.value = "鍙戣捣宸℃";
- Object.assign(inspectionForm.value, {
- id: null, facilityId: row.id, inspectionCode: "", inspectionType: "瀹氭湡宸℃",
- planTime: "", checkResult: "", checkDesc: ""
- });
- } else if (type === "do") {
+ if (type === "do") {
inspectionDialogTitle.value = "宸℃";
Object.assign(inspectionForm.value, {
- id: row.id, facilityId: row.facilityId, inspectionCode: row.inspectionCode,
- inspectionType: row.inspectionType, planTime: row.planTime, checkResult: "", checkDesc: ""
+ id: row.id,
+ scheduleTaskId: row.scheduleTaskId,
+ facilityId: row.facilityId,
+ facilityCode: row.facilityCode,
+ facilityName: row.facilityName,
+ inspectionCode: row.inspectionCode,
+ inspectionType: row.inspectionType,
+ inspectionProject: row.inspectionProject,
+ planTime: row.planTime,
+ checkResult: "",
+ checkDesc: "",
+ storageBlobDTOs: []
});
- } else {
- inspectionDialogTitle.value = "鏌ョ湅宸℃";
- Object.assign(inspectionForm.value, { ...row });
}
inspectionDialogVisible.value = true;
};
@@ -692,21 +1797,45 @@
const submitInspectionForm = async () => {
try {
await inspectionFormRef.value.validate();
- if (inspectionDialogTitle.value === "宸℃") {
+ if (inspectionDialogType.value === "do") {
+ if (!inspectionForm.value.checkResult) {
+ ElMessage.warning("璇烽�夋嫨妫�鏌ョ粨鏋�");
+ return;
+ }
+ if (inspectionForm.value.checkResult === "寮傚父" && !inspectionForm.value.checkDesc) {
+ ElMessage.warning("妫�鏌ョ粨鏋滃紓甯告椂璇峰~鍐欐鏌ヨ鏄�");
+ return;
+ }
+ if (inspectionForm.value.checkResult === "寮傚父" && !hasAttachments(inspectionForm.value.storageBlobDTOs)) {
+ ElMessage.warning("妫�鏌ョ粨鏋滃紓甯告椂璇蜂笂浼犵幇鍦虹収鐗�");
+ return;
+ }
inspectionForm.value.status = "宸插贰妫�";
- inspectionForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
+ inspectionForm.value.actualTime = formatDateTime();
}
- const api = inspectionForm.value.id ? updateFacilityInspection : addFacilityInspection;
- const res = await api({ ...inspectionForm.value });
+ const res = await updateFacilityInspection({ ...inspectionForm.value });
if (res.code === 200) {
ElMessage.success("鎿嶄綔鎴愬姛");
inspectionDialogVisible.value = false;
getInspectionList();
+ if (inspectionDialogType.value === "do" && inspectionForm.value.checkResult === "寮傚父") {
+ ElMessageBox.confirm("鏈宸℃缁撴灉涓哄紓甯革紝鏄惁绔嬪嵆鍒涘缓鏁存敼璺熻釜锛�", "鍒涘缓鏁存敼", {
+ confirmButtonText: "鍒涘缓鏁存敼",
+ cancelButtonText: "绋嶅悗澶勭悊",
+ type: "warning"
+ }).then(() => {
+ openRectificationFromInspection({ ...inspectionForm.value });
+ }).catch(() => {});
+ }
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
}
} catch (error) {
console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
}
};
+
+const hasAttachments = attachments => Array.isArray(attachments) && attachments.length > 0;
const handleDeleteInspection = row => {
ElMessageBox.confirm("纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵", "鍒犻櫎", {
@@ -716,6 +1845,8 @@
if (res.code === 200) {
ElMessage.success("鍒犻櫎鎴愬姛");
getInspectionList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
}
}).catch(() => {});
};
@@ -727,13 +1858,20 @@
getRectificationList();
};
+const resetRectificationQuery = () => {
+ Object.assign(rectificationSearchForm.value, {
+ status: ""
+ });
+ handleRectificationQuery();
+};
+
const getRectificationList = () => {
rectificationTableLoading.value = true;
getFacilityRectificationList({ ...rectificationPage.value, ...rectificationSearchForm.value })
.then(res => {
rectificationTableLoading.value = false;
- rectificationTableData.value = res.data.records;
- rectificationPage.value.total = res.data.total;
+ rectificationTableData.value = res.data?.records || [];
+ rectificationPage.value.total = res.data?.total || 0;
})
.catch(() => { rectificationTableLoading.value = false; });
};
@@ -744,32 +1882,129 @@
getRectificationList();
};
+const getExistingRectification = async inspectionId => {
+ if (!inspectionId) return null;
+ const res = await getFacilityRectificationList({ current: 1, size: 1, inspectionId });
+ return res.data?.records?.[0] || null;
+};
+
+const getRectificationDialogType = row => {
+ if (isPendingRectification(row)) return "do";
+ if (isRectified(row)) return "verify";
+ return "view";
+};
+
+const openRectificationDetail = row => {
+ rectificationDetail.value = {
+ ...row,
+ storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
+ };
+ rectificationDetailVisible.value = true;
+};
+
+const openRectificationFromInspection = async row => {
+ const existing = await getExistingRectification(row.id);
+ activeTab.value = "rectification";
+ if (existing) {
+ ElMessage.info("璇ュ贰妫�宸插瓨鍦ㄦ暣鏀硅褰曪紝宸蹭负浣犳墦寮�瀵瑰簲澶勭悊绐楀彛");
+ existing.inspectionCode = existing.inspectionCode || row.inspectionCode;
+ existing.facilityCode = existing.facilityCode || row.facilityCode;
+ existing.facilityName = existing.facilityName || row.facilityName;
+ openRectificationForm(getRectificationDialogType(existing), existing);
+ return;
+ }
+ openRectificationForm("add", row);
+};
+
const openRectificationForm = (type, row = null) => {
+ if (type === "view") {
+ openRectificationDetail(row);
+ return;
+ }
rectificationDialogType.value = type;
if (type === "add") {
rectificationDialogTitle.value = "鏂板鏁存敼";
Object.assign(rectificationForm.value, {
- id: null, inspectionId: row.id, facilityId: row.facilityId,
- problemDesc: "", problemLevel: "", rectifyDesc: "", verifyDesc: ""
+ id: null,
+ inspectionId: row.id,
+ facilityId: row.facilityId,
+ facilityName: row.facilityName || "",
+ facilityCode: row.facilityCode || "",
+ inspectionCode: row.inspectionCode || "",
+ problemDesc: row.checkDesc || "",
+ problemLevel: "涓�鑸�",
+ rectifyUserId: currentUserId.value || "",
+ rectifyUserName: getUserName(currentUserId.value),
+ verifyUserId: "",
+ verifyUserName: "",
+ planTime: addDaysDateTime(1),
+ actualTime: "",
+ rectifyDesc: "",
+ verifyTime: "",
+ verifyDesc: "",
+ status: "寰呮暣鏀�",
+ storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
});
} else if (type === "do") {
rectificationDialogTitle.value = "鏁存敼";
Object.assign(rectificationForm.value, {
- id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
- problemDesc: row.problemDesc, problemLevel: row.problemLevel, rectifyDesc: "", verifyDesc: ""
+ ...row,
+ storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
+ rectifyDesc: row.rectifyDesc || "",
+ verifyDesc: row.verifyDesc || ""
});
} else if (type === "verify") {
rectificationDialogTitle.value = "楠屾敹";
Object.assign(rectificationForm.value, {
- id: row.id, inspectionId: row.inspectionId, facilityId: row.facilityId,
- problemDesc: row.problemDesc, problemLevel: row.problemLevel,
- rectifyDesc: row.rectifyDesc, verifyDesc: ""
+ ...row,
+ storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || [],
+ verifyDesc: row.verifyDesc || ""
});
} else {
rectificationDialogTitle.value = "鏌ョ湅鏁存敼";
- Object.assign(rectificationForm.value, { ...row });
+ Object.assign(rectificationForm.value, {
+ ...row,
+ storageBlobVOs: row.storageBlobVOs || row.storageBlobDTOs || []
+ });
}
rectificationDialogVisible.value = true;
+};
+
+const buildRectificationPayload = () => {
+ const {
+ id,
+ inspectionId,
+ facilityId,
+ problemDesc,
+ problemLevel,
+ problemImage,
+ rectifyUserId,
+ planTime,
+ actualTime,
+ rectifyDesc,
+ rectifyImage,
+ status,
+ verifyUserId,
+ verifyTime,
+ verifyDesc
+ } = rectificationForm.value;
+ return {
+ id,
+ inspectionId,
+ facilityId,
+ problemDesc,
+ problemLevel,
+ problemImage,
+ rectifyUserId,
+ planTime,
+ actualTime,
+ rectifyDesc,
+ rectifyImage,
+ status,
+ verifyUserId,
+ verifyTime,
+ verifyDesc
+ };
};
const submitRectificationForm = async () => {
@@ -777,27 +2012,95 @@
rectificationDialogVisible.value = false;
return;
}
- if (rectificationDialogTitle.value === "鏁存敼") {
+ try {
+ await rectificationFormRef.value.validate();
+ } catch (error) {
+ console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+ return;
+ }
+ if (rectificationDialogType.value === "do") {
rectificationForm.value.status = "宸叉暣鏀�";
- rectificationForm.value.actualTime = new Date().toISOString().replace("T", " ").substring(0, 19);
- } else if (rectificationDialogTitle.value === "楠屾敹") {
+ rectificationForm.value.actualTime = formatDateTime();
+ } else if (rectificationDialogType.value === "verify") {
rectificationForm.value.status = "宸查獙鏀�";
- rectificationForm.value.verifyTime = new Date().toISOString().replace("T", " ").substring(0, 19);
+ rectificationForm.value.verifyTime = formatDateTime();
}
const api = rectificationForm.value.id ? updateFacilityRectification : addFacilityRectification;
- const res = await api({ ...rectificationForm.value });
+ const res = await api(buildRectificationPayload());
if (res.code === 200) {
ElMessage.success("鎿嶄綔鎴愬姛");
rectificationDialogVisible.value = false;
getRectificationList();
+ getInspectionList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
}
};
</script>
<style scoped>
+.safety-facility-page {
+ padding-top: 4px;
+}
+
+.facility-tabs {
+ width: 100%;
+}
+
+.facility-tabs :deep(.el-tabs__header) {
+ margin-bottom: 18px;
+}
+
+.facility-tabs :deep(.el-tabs__nav-wrap::after) {
+ height: 1px;
+ background-color: #d8e2ef;
+}
+
+.facility-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 14px 18px;
+ min-height: 44px;
+ margin-bottom: 18px;
+}
+
+.toolbar-filters,
+.toolbar-actions {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 10px 12px;
+}
+
+.toolbar-actions {
+ margin-left: auto;
+}
+
+.table_list {
+ padding-top: 6px;
+}
+
+.history-summary {
+ margin-bottom: 16px;
+}
+
+.table_list :deep(.link) {
+ color: var(--el-color-primary);
+ cursor: pointer;
+ font-weight: 600;
+}
+
+.table_list :deep(.link:hover) {
+ text-decoration: underline;
+}
+
.search_title {
font-size: 14px;
+ font-weight: 600;
color: #606266;
+ white-space: nowrap;
}
.mb20 {
@@ -807,4 +2110,147 @@
.ml10 {
margin-left: 10px;
}
+
+.toolbar-filters .ml10 {
+ margin-left: 0;
+}
+
+.facility-form-dialog :deep(.el-dialog__body) {
+ padding: 24px 32px 10px;
+}
+
+.facility-form-dialog :deep(.el-dialog__footer) {
+ padding: 8px 32px 26px;
+}
+
+.dialog-summary {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 12px;
+ margin-bottom: 20px;
+ padding: 14px 18px;
+ border: 1px solid #e4eaf3;
+ border-radius: 6px;
+ background: #f7faff;
+}
+
+.summary-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ min-width: 0;
+}
+
+.summary-item span {
+ flex: 0 0 auto;
+ color: #7a8599;
+}
+
+.summary-item strong {
+ min-width: 0;
+ overflow: hidden;
+ color: #25324b;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.inspection-form-grid {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr) minmax(220px, 0.8fr);
+ column-gap: 20px;
+}
+
+.inspection-form-grid .form-grid-full {
+ grid-column: 1 / -1;
+}
+
+.inspection-form :deep(.el-form-item) {
+ margin-bottom: 20px;
+}
+
+.inspection-form :deep(.el-form-item__label) {
+ margin-bottom: 8px;
+ padding: 0;
+ font-weight: 600;
+ color: #25324b;
+ line-height: 1.2;
+}
+
+.rectification-image-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.rectification-image {
+ width: 96px;
+ height: 96px;
+ border: 1px solid #dbe4f0;
+ border-radius: 6px;
+ background: #f8fafc;
+}
+
+.detail-dialog :deep(.el-dialog__body) {
+ padding: 24px 32px 8px;
+}
+
+.detail-dialog :deep(.el-descriptions__label) {
+ width: 130px;
+ color: #4d5b73;
+ font-weight: 600;
+ background: #f4f7fb;
+}
+
+.detail-dialog :deep(.el-descriptions__content) {
+ color: #25324b;
+ word-break: break-word;
+}
+
+.detail-section {
+ margin-top: 18px;
+}
+
+.detail-section-title {
+ margin-bottom: 10px;
+ color: #25324b;
+ font-weight: 600;
+}
+
+.detail-image-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.detail-image {
+ width: 96px;
+ height: 96px;
+ border: 1px solid #dbe4f0;
+ border-radius: 6px;
+ background: #f8fafc;
+}
+
+.frequency-row {
+ display: flex;
+ width: 100%;
+ align-items: center;
+ gap: 12px;
+}
+
+.frequency-time-picker {
+ min-width: 0;
+ flex: 1;
+}
+
+.frequency-day-select {
+ flex: 0 0 132px;
+ width: 132px;
+}
+
+@media (max-width: 900px) {
+ .inspection-form-grid,
+ .dialog-summary {
+ grid-template-columns: 1fr;
+ }
+}
</style>
--
Gitblit v1.9.3