From 6735ee5fec84b96a2484a784e37d4cefb4f7c34c Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 14 八月 2026 10:32:56 +0800
Subject: [PATCH] fix: 去除小数限制
---
src/views/safeProduction/lineInspection/index.vue | 2660 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 2,337 insertions(+), 323 deletions(-)
diff --git a/src/views/safeProduction/lineInspection/index.vue b/src/views/safeProduction/lineInspection/index.vue
index 45358e9..e758125 100644
--- a/src/views/safeProduction/lineInspection/index.vue
+++ b/src/views/safeProduction/lineInspection/index.vue
@@ -1,127 +1,1046 @@
<template>
- <div class="line-inspection">
- <!-- 鎼滅储鍖哄煙 -->
- <div class="search-area">
- <el-form :inline="true" :model="searchForm">
- <el-form-item label="浠诲姟鍚嶇О">
- <el-input v-model="searchForm.taskName" placeholder="璇疯緭鍏ヤ换鍔″悕绉�" clearable />
- </el-form-item>
- <el-form-item label="绾胯矾鍚嶇О">
- <el-input v-model="searchForm.routeName" placeholder="璇疯緭鍏ョ嚎璺悕绉�" clearable />
- </el-form-item>
- <el-form-item label="宸℃浜�">
- <el-input v-model="searchForm.inspector" placeholder="璇疯緭鍏ュ贰妫�浜�" clearable />
- </el-form-item>
- <el-form-item label="鐘舵��">
- <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" clearable>
- <el-option label="寰呭贰妫�" value="寰呭贰妫�" />
- <el-option label="杩涜涓�" value="杩涜涓�" />
- <el-option label="宸插畬鎴�" value="宸插畬鎴�" />
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
- <el-button @click="resetSearch">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
+ <div class="app-container line-inspection-page">
+ <div class="module-tabs">
+ <button
+ v-for="tab in moduleTabs"
+ :key="tab.value"
+ class="module-tab"
+ :class="{ active: activeTab === tab.value }"
+ type="button"
+ @click="handleModuleTabChange(tab.value)"
+ >
+ {{ tab.label }}
+ </button>
</div>
- <!-- 鎿嶄綔鎸夐挳 -->
- <div class="actions">
- <el-button type="primary" @click="handleAdd">鏂板宸℃</el-button>
- <el-button type="success" @click="handleExport">瀵煎嚭</el-button>
- </div>
-
- <!-- 宸℃鍒楄〃 -->
- <el-table :data="inspectionList" style="width: 100%; margin-top: 10px;" border>
- <el-table-column prop="taskName" label="浠诲姟鍚嶇О" width="180" />
- <el-table-column prop="routeName" label="绾胯矾鍚嶇О" width="180" />
- <el-table-column prop="deviceName" label="鍏宠仈璁惧" width="150" />
- <el-table-column prop="inspector" label="宸℃浜�" width="120" />
- <el-table-column prop="inspectionTime" label="宸℃鏃堕棿" width="180" />
- <el-table-column prop="inspectionResult" label="宸℃缁撴灉" width="120">
- <template #default="{ row }">
- <el-tag :type="row.inspectionResult === '姝e父' ? 'success' : 'danger'">
- {{ row.inspectionResult || '鏈贰妫�' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="status" label="鐘舵��" width="120">
- <template #default="{ row }">
- <el-tag :type="getStatusType(row.status)">
- {{ row.status }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鎿嶄綔" width="200" fixed="right">
- <template #default="{ row }">
- <el-button type="primary" link @click="handleEdit(row)">缂栬緫</el-button>
- <el-button type="danger" link @click="handleDelete(row)">鍒犻櫎</el-button>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 鍒嗛〉 -->
- <div class="pagination">
- <el-pagination
- v-model:current-page="pagination.currentPage"
- v-model:page-size="pagination.pageSize"
- :page-sizes="[10, 20, 50, 100]"
- :total="pagination.total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
-
- <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
- <el-dialog :title="dialogTitle" v-model="showDialog" width="600px">
- <el-form :model="form" :rules="formRules" ref="formRef" label-width="100px">
- <el-form-item label="浠诲姟鍚嶇О" prop="taskName">
- <el-input v-model="form.taskName" placeholder="璇疯緭鍏ヤ换鍔″悕绉�" />
- </el-form-item>
- <el-form-item label="绾胯矾鍚嶇О" prop="routeName">
- <el-input v-model="form.routeName" placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
- </el-form-item>
- <el-form-item label="鍏宠仈璁惧">
- <el-select v-model="form.deviceId" placeholder="璇烽�夋嫨璁惧" clearable>
- <el-option
- v-for="item in deviceOptions"
- :key="item.id"
- :label="item.deviceName"
- :value="item.id"
+ <div class="search_form line-search-panel mb20">
+ <div class="search-left">
+ <template v-if="activeTab === 'task'">
+ <div class="filter-item">
+ <span class="search_title">宸℃浠诲姟鍚嶇О锛�</span>
+ <el-input
+ v-model="taskSearchForm.inspectionName"
+ class="filter-control is-wide"
+ placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
/>
- </el-select>
- </el-form-item>
- <el-form-item label="宸℃浜�" prop="inspector">
- <el-input v-model="form.inspector" placeholder="璇疯緭鍏ュ贰妫�浜�" />
- </el-form-item>
- <el-form-item label="宸℃鏃堕棿">
- <el-date-picker
- v-model="form.inspectionTime"
- type="datetime"
- placeholder="璇烽�夋嫨宸℃鏃堕棿"
- format="YYYY-MM-DD HH:mm:ss"
- value-format="YYYY-MM-DD HH:mm:ss"
+ </div>
+ <div class="filter-item">
+ <span class="search_title">绾胯矾鍚嶇О锛�</span>
+ <el-input
+ v-model="taskSearchForm.lineName"
+ class="filter-control"
+ placeholder="璇疯緭鍏ョ嚎璺悕绉�"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
+ />
+ </div>
+ <div class="filter-item">
+ <span class="search_title">鏄惁鍚敤锛�</span>
+ <el-select
+ v-model="taskSearchForm.isEnabled"
+ class="filter-control is-short"
+ clearable
+ placeholder="璇烽�夋嫨"
+ @change="handleQuery"
+ >
+ <el-option label="鏄�" :value="1" />
+ <el-option label="鍚�" :value="0" />
+ </el-select>
+ </div>
+ </template>
+ <template v-else-if="activeTab === 'record'">
+ <div class="filter-item">
+ <span class="search_title">宸℃缂栧彿锛�</span>
+ <el-input
+ v-model="recordSearchForm.inspectionCode"
+ class="filter-control"
+ placeholder="璇疯緭鍏ュ贰妫�缂栧彿"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
+ />
+ </div>
+ <div class="filter-item">
+ <span class="search_title">宸℃鍚嶇О锛�</span>
+ <el-input
+ v-model="recordSearchForm.inspectionName"
+ class="filter-control"
+ placeholder="璇疯緭鍏ュ贰妫�鍚嶇О"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
+ />
+ </div>
+ <div class="filter-item">
+ <span class="search_title">绾胯矾鍚嶇О锛�</span>
+ <el-input
+ v-model="recordSearchForm.lineName"
+ class="filter-control"
+ placeholder="璇疯緭鍏ョ嚎璺悕绉�"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
+ />
+ </div>
+ </template>
+ <template v-else>
+ <div class="filter-item">
+ <span class="search_title">闅愭偅缂栧彿锛�</span>
+ <el-input
+ v-model="rectifySearchForm.hazardCode"
+ class="filter-control"
+ placeholder="璇疯緭鍏ラ殣鎮g紪鍙�"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
+ />
+ </div>
+ <div class="filter-item">
+ <span class="search_title">闅愭偅鎻忚堪锛�</span>
+ <el-input
+ v-model="rectifySearchForm.hazardDesc"
+ class="filter-control"
+ placeholder="璇疯緭鍏ラ殣鎮f弿杩�"
+ clearable
+ :prefix-icon="Search"
+ @change="handleQuery"
+ />
+ </div>
+ <div class="filter-item">
+ <span class="search_title">鏁存敼鐘舵�侊細</span>
+ <el-select
+ v-model="rectifySearchForm.status"
+ class="filter-control is-short"
+ clearable
+ placeholder="璇烽�夋嫨"
+ @change="handleQuery"
+ >
+ <el-option label="寰呮暣鏀�" value="寰呮暣鏀�" />
+ <el-option label="鏁存敼涓�" value="鏁存敼涓�" />
+ <el-option label="宸叉暣鏀�" value="宸叉暣鏀�" />
+ </el-select>
+ </div>
+ </template>
+ <div class="filter-buttons">
+ <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+ <el-button @click="resetQuery">閲嶇疆</el-button>
+ </div>
+ </div>
+ </div>
+
+ <div class="table_list">
+ <div class="table-toolbar" v-if="activeTab === 'task'">
+ <div></div>
+ <div class="toolbar-actions">
+ <el-button type="primary" :icon="Plus" @click="openTaskDialog('add')">鏂板宸℃浠诲姟</el-button>
+ <el-button type="danger" :icon="Delete" :disabled="selectedIds.length === 0" @click="handleBatchDeleteTask">鍒犻櫎</el-button>
+ </div>
+ </div>
+ <PIMTable
+ rowKey="id"
+ :column="tableColumns"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ :tableLoading="tableLoading"
+ :total="page.total"
+ :height="'calc(100vh - 25em)'"
+ :table-style="{ width: '100%' }"
+ @selection-change="handleSelectionChange"
+ @pagination="pagination"
+ >
+ <template #taskName="{ row }">
+ <el-button class="task-name-link" type="primary" link @click="openTaskDetail(row)">
+ {{ row.inspectionName || "--" }}
+ </el-button>
+ </template>
+ <template #inspectionCode="{ row }">
+ <el-button class="code-link" type="primary" link @click="openInspectionDetailEntry(row)">
+ {{ row.inspectionCode || "--" }}
+ </el-button>
+ </template>
+ <template #inspectionResult="{ row }">
+ <el-tag :type="getInspectionResultType(row.inspectionResult)" size="small">
+ {{ row.inspectionResult || "鏈贰妫�" }}
+ </el-tag>
+ </template>
+ <template #inspectorName="{ row }">
+ <div class="person-tags">
+ <template v-if="getInspectorNames(row).length">
+ <el-tag
+ v-for="name in getInspectorNames(row)"
+ :key="name"
+ size="small"
+ type="primary"
+ class="person-tag"
+ >
+ {{ name }}
+ </el-tag>
+ </template>
+ <span v-else class="no-data">--</span>
+ </div>
+ </template>
+ <template #isEnabled="{ row }">
+ <el-tag :type="row.isEnabled === 1 ? 'success' : 'info'" size="small">
+ {{ row.isEnabled === 1 ? "鏄�" : "鍚�" }}
+ </el-tag>
+ </template>
+ <template #status="{ row }">
+ <el-tag :type="getInspectionStatusType(row.status)" size="small">
+ {{ row.status || "--" }}
+ </el-tag>
+ </template>
+ <template #hazardLevel="{ row }">
+ <el-tag :type="getRiskLevelType(row.hazardLevel)" size="small">
+ {{ row.hazardLevel || "--" }}
+ </el-tag>
+ </template>
+ <template #hazardStatus="{ row }">
+ <el-tag :type="getHazardStatusType(row.status)" size="small">
+ {{ row.status || "--" }}
+ </el-tag>
+ </template>
+ <template #rectifyPhotos="{ row }">
+ <el-tag :type="hasAttachments(getAttachments(row)) ? 'success' : 'info'" size="small">
+ {{ hasAttachments(getAttachments(row)) ? "宸蹭笂浼�" : "鏈笂浼�" }}
+ </el-tag>
+ </template>
+ </PIMTable>
+ </div>
+
+ <el-dialog
+ v-model="taskDetailVisible"
+ title="宸℃浠诲姟璇︽儏"
+ width="780px"
+ :close-on-click-modal="false"
+ >
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="宸℃浠诲姟鍚嶇О">
+ {{ taskDetail.inspectionName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="绾胯矾鍚嶇О">
+ {{ taskDetail.lineName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鎵ц宸℃浜�">
+ {{ getInspectorNames(taskDetail).join("銆�") || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鏄惁鍚敤">
+ <el-tag :type="taskDetail.isEnabled === 1 ? 'success' : 'info'" size="small">
+ {{ taskDetail.isEnabled === 1 ? "鏄�" : "鍚�" }}
+ </el-tag>
+ </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="鏈�鍚庢墽琛屾椂闂�">
+ {{ taskDetail.lastExecutionTime || "--" }}
+ </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="1280px"
+ :close-on-click-modal="false"
+ >
+ <el-descriptions class="history-summary" :column="3" border>
+ <el-descriptions-item label="宸℃浠诲姟鍚嶇О">
+ {{ taskHistoryTask.inspectionName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="绾胯矾鍚嶇О">
+ {{ taskHistoryTask.lineName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="棰戞">
+ {{ frequencyTypeMap[taskHistoryTask.frequencyType] || taskHistoryTask.frequencyType || "--" }}
+ </el-descriptions-item>
+ </el-descriptions>
+ <PIMTable
+ rowKey="id"
+ :column="taskHistoryColumns"
+ :tableData="taskHistoryData"
+ :page="taskHistoryPage"
+ :tableLoading="taskHistoryLoading"
+ :total="taskHistoryPage.total"
+ :height="420"
+ :table-style="{ width: '100%' }"
+ @pagination="taskHistoryPagination"
+ >
+ <template #inspectionCode="{ row }">
+ <el-button class="code-link" type="primary" link @click="openInspectionDetail(row)">
+ {{ row.inspectionCode || "--" }}
+ </el-button>
+ </template>
+ <template #inspectionResult="{ row }">
+ <el-tag :type="getInspectionResultType(row.inspectionResult)" size="small">
+ {{ row.inspectionResult || "鏈贰妫�" }}
+ </el-tag>
+ </template>
+ <template #inspectorName="{ row }">
+ <div class="person-tags">
+ <template v-if="getInspectorNames(row).length">
+ <el-tag
+ v-for="name in getInspectorNames(row)"
+ :key="name"
+ size="small"
+ type="primary"
+ class="person-tag"
+ >
+ {{ name }}
+ </el-tag>
+ </template>
+ <span v-else class="no-data">--</span>
+ </div>
+ </template>
+ <template #status="{ row }">
+ <el-tag :type="getInspectionStatusType(row.status)" size="small">
+ {{ row.status || "--" }}
+ </el-tag>
+ </template>
+ </PIMTable>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="taskHistoryVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <el-dialog
+ v-model="inspectionDetailVisible"
+ title="宸℃璇︽儏"
+ width="960px"
+ :close-on-click-modal="false"
+ >
+ <el-descriptions :column="3" border>
+ <el-descriptions-item label="宸℃缂栧彿">
+ {{ inspectionDetail.inspectionCode || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃鍚嶇О">
+ {{ inspectionDetail.inspectionName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="绾胯矾鍚嶇О">
+ {{ inspectionDetail.lineName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="璁″垝宸℃鏃堕棿">
+ {{ inspectionDetail.planTime || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="瀹為檯宸℃鏃堕棿">
+ {{ inspectionDetail.actualInspectionTime || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃缁撴灉">
+ <el-tag :type="getInspectionResultType(inspectionDetail.inspectionResult)" size="small">
+ {{ inspectionDetail.inspectionResult || "鏈贰妫�" }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃浜�">
+ {{ getInspectorNames(inspectionDetail).join("銆�") || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鐘舵��">
+ <el-tag :type="getInspectionStatusType(inspectionDetail.status)" size="small">
+ {{ inspectionDetail.status || "--" }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃绫诲瀷">
+ {{ inspectionDetail.inspectionType || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃椤圭洰" :span="3">
+ {{ inspectionDetail.inspectionProject || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="澶囨敞" :span="3">
+ {{ inspectionDetail.remark || "--" }}
+ </el-descriptions-item>
+ </el-descriptions>
+
+ <div class="detail-section-title">宸℃鎵ц璁板綍</div>
+ <el-table v-loading="inspectionDetailLoading" :data="inspectionDetailRecords" border>
+ <el-table-column prop="checkResult" label="缁撴灉" width="90" align="center">
+ <template #default="{ row }">
+ <el-tag :type="row.checkResult === '姝e父' ? 'success' : 'danger'" size="small">
+ {{ row.checkResult || "--" }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="checkContent" label="宸℃椤圭洰" min-width="180" show-overflow-tooltip />
+ <el-table-column prop="checkDesc" label="宸℃璇存槑" min-width="180" show-overflow-tooltip />
+ <el-table-column prop="checkTime" label="宸℃鏃堕棿" width="170" align="center" />
+ <el-table-column label="鐜板満鐓х墖" min-width="180" align="center">
+ <template #default="{ row }">
+ <div v-if="getAttachments(row).length" class="photo-list">
+ <el-image
+ v-for="(item, index) in getAttachments(row)"
+ :key="item.storageAttachmentId || item.id || index"
+ class="record-photo"
+ :src="getAttachmentPreviewUrl(item)"
+ :preview-src-list="getAttachmentPreviewUrls(row)"
+ fit="cover"
+ preview-teleported
+ />
+ </div>
+ <span v-else class="no-data">--</span>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <div class="detail-section-title">鏁存敼璺熻釜</div>
+ <el-table v-loading="inspectionDetailLoading" :data="inspectionDetailHazards" border>
+ <el-table-column prop="hazardCode" label="闅愭偅缂栧彿" width="145" align="center" show-overflow-tooltip />
+ <el-table-column prop="hazardDesc" label="寮傚父鎻忚堪" min-width="170" show-overflow-tooltip />
+ <el-table-column prop="hazardLocation" label="寮傚父浣嶇疆" min-width="130" show-overflow-tooltip />
+ <el-table-column prop="hazardLevel" label="椋庨櫓绛夌骇" width="105" align="center">
+ <template #default="{ row }">
+ <el-tag :type="getRiskLevelType(row.hazardLevel)" size="small">
+ {{ row.hazardLevel || "--" }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="rectifyUserName" label="鏁存敼璐d换浜�" width="120" align="center" show-overflow-tooltip />
+ <el-table-column prop="rectifyDeadline" label="鏁存敼鏈熼檺" width="120" align="center" />
+ <el-table-column prop="rectifyDesc" label="鏁存敼璇存槑" min-width="170" show-overflow-tooltip>
+ <template #default="{ row }">
+ {{ row.rectifyDesc || "--" }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="rectifyTime" label="鏁存敼鏃堕棿" width="165" align="center">
+ <template #default="{ row }">
+ {{ row.rectifyTime || "--" }}
+ </template>
+ </el-table-column>
+ <el-table-column label="鏁存敼鐓х墖" min-width="150" align="center">
+ <template #default="{ row }">
+ <div v-if="getAttachments(row).length" class="photo-list">
+ <el-image
+ v-for="(item, index) in getAttachments(row)"
+ :key="item.storageAttachmentId || item.id || index"
+ class="record-photo"
+ :src="getAttachmentPreviewUrl(item)"
+ :preview-src-list="getAttachmentPreviewUrls(row)"
+ fit="cover"
+ preview-teleported
+ />
+ </div>
+ <span v-else class="no-data">--</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="status" label="鏁存敼鐘舵��" width="100" align="center">
+ <template #default="{ row }">
+ <el-tag :type="getHazardStatusType(row.status)" size="small">
+ {{ row.status || "--" }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="inspectionDetailVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <el-dialog
+ v-model="executeDialogVisible"
+ title="鎵ц宸℃"
+ width="820px"
+ :close-on-click-modal="false"
+ @closed="resetExecuteForm"
+ >
+ <el-descriptions :column="2" border class="execute-summary">
+ <el-descriptions-item label="宸℃缂栧彿">
+ {{ currentInspection.inspectionCode || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃鍚嶇О">
+ {{ currentInspection.inspectionName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="绾胯矾鍚嶇О">
+ {{ currentInspection.lineName || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="璁″垝鏃堕棿">
+ {{ currentInspection.planTime || "--" }}
+ </el-descriptions-item>
+ <el-descriptions-item label="宸℃椤圭洰" :span="2">
+ {{ currentInspection.inspectionProject || "--" }}
+ </el-descriptions-item>
+ </el-descriptions>
+
+ <el-form ref="executeFormRef" :model="executeForm" :rules="executeRules" label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃缁撴灉" prop="checkResult">
+ <el-radio-group v-model="executeForm.checkResult" @change="handleExecuteResultChange">
+ <el-radio label="姝e父">姝e父</el-radio>
+ <el-radio label="寮傚父">寮傚父</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃鏃堕棿" prop="checkTime">
+ <el-date-picker
+ v-model="executeForm.checkTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨宸℃鏃堕棿"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item v-if="executeForm.checkResult === '姝e父'" label="宸℃璇存槑" prop="checkDesc">
+ <el-input
+ v-model="executeForm.checkDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ユ甯稿贰妫�鎯呭喌璇存槑"
/>
</el-form-item>
- <el-form-item label="宸℃缁撴灉">
- <el-radio-group v-model="form.inspectionResult">
- <el-radio label="姝e父">姝e父</el-radio>
- <el-radio label="寮傚父">寮傚父</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="闅愭偅鎻忚堪" v-if="form.inspectionResult === '寮傚父'">
- <el-input type="textarea" v-model="form.hazardDescription" placeholder="璇疯緭鍏ラ殣鎮f弿杩�" />
+
+ <template v-if="executeForm.checkResult === '寮傚父'">
+ <el-form-item label="寮傚父鐓х墖" prop="storageBlobDTOs">
+ <ImageUpload v-model:file-list="executeForm.storageBlobDTOs" :limit="6" button-text="涓婁紶鐓х墖" />
+ </el-form-item>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="闅愭偅绫诲瀷" prop="hiddenType">
+ <el-select v-model="executeForm.hiddenType" placeholder="璇烽�夋嫨闅愭偅绫诲瀷" clearable style="width: 100%">
+ <el-option
+ v-for="item in hiddenTypeOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="椋庨櫓绛夌骇" prop="riskLevel">
+ <el-select v-model="executeForm.riskLevel" placeholder="璇烽�夋嫨椋庨櫓绛夌骇" clearable style="width: 100%">
+ <el-option v-for="item in riskLevelList" :key="item.value" :label="item.label" :value="item.value" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="闅愭偅浣嶇疆" prop="hazardLocation">
+ <el-input v-model="executeForm.hazardLocation" placeholder="璇疯緭鍏ラ殣鎮d綅缃�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏁存敼璐d换浜�" prop="rectifyUserId">
+ <el-select
+ v-model="executeForm.rectifyUserId"
+ placeholder="璇烽�夋嫨鏁存敼璐d换浜�"
+ filterable
+ clearable
+ style="width: 100%"
+ @change="handleRectifyUserChange"
+ >
+ <el-option
+ v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鏁存敼鏈熼檺" prop="rectifyTime">
+ <el-date-picker
+ v-model="executeForm.rectifyTime"
+ type="date"
+ placeholder="璇烽�夋嫨鏁存敼鏈熼檺"
+ format="YYYY-MM-DD"
+ value-format="YYYY-MM-DD"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="寮傚父鎻忚堪/鏁存敼瑕佹眰" prop="hazardDesc">
+ <el-input
+ v-model="executeForm.hazardDesc"
+ type="textarea"
+ :rows="3"
+ placeholder="璇锋弿杩板紓甯告儏鍐靛拰鏁存敼瑕佹眰"
+ />
+ </el-form-item>
+ </template>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitExecuteForm">鎻愪氦</el-button>
+ <el-button @click="executeDialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <el-dialog
+ v-model="taskDialogVisible"
+ :title="taskDialogTitle"
+ width="960px"
+ :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="lineName">
+ <el-input v-model="taskForm.lineName" placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃浜�" prop="inspectorIds">
+ <el-select
+ v-model="taskForm.inspectorIds"
+ placeholder="璇烽�夋嫨宸℃浜�"
+ filterable
+ multiple
+ collapse-tags
+ collapse-tags-tooltip
+ clearable
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-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="inspectionDialogVisible"
+ title="缂栬緫宸℃璁板綍"
+ width="800px"
+ :close-on-click-modal="false"
+ @closed="resetInspectionForm"
+ >
+ <el-form ref="inspectionFormRef" :model="inspectionForm" :rules="inspectionRules" label-width="120px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="宸℃缂栧彿" prop="inspectionCode">
+ <el-input v-model="inspectionForm.inspectionCode" placeholder="璇疯緭鍏ュ贰妫�缂栧彿" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃鍚嶇О" prop="inspectionName">
+ <el-input v-model="inspectionForm.inspectionName" placeholder="璇疯緭鍏ュ贰妫�鍚嶇О" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="绾胯矾鍚嶇О" prop="lineName">
+ <el-input v-model="inspectionForm.lineName" placeholder="璇疯緭鍏ョ嚎璺悕绉�" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃绫诲瀷" prop="inspectionType">
+ <el-select v-model="inspectionForm.inspectionType" placeholder="璇烽�夋嫨宸℃绫诲瀷" style="width: 100%">
+ <el-option label="瀹氭湡宸℃" value="瀹氭湡宸℃" />
+ <el-option label="涓存椂宸℃" value="涓存椂宸℃" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <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>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="宸℃浜�" prop="inspectorIds">
+ <el-select
+ v-model="inspectionForm.inspectorIds"
+ placeholder="璇烽�夋嫨宸℃浜�"
+ filterable
+ multiple
+ collapse-tags
+ collapse-tags-tooltip
+ clearable
+ style="width: 100%"
+ >
+ <el-option
+ v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="宸℃椤圭洰">
+ <el-input
+ v-model="inspectionForm.inspectionProject"
+ type="textarea"
+ :rows="3"
+ placeholder="璇疯緭鍏ュ贰妫�椤圭洰"
+ />
</el-form-item>
<el-form-item label="澶囨敞">
- <el-input type="textarea" v-model="form.remarks" placeholder="璇疯緭鍏ュ娉�" />
+ <el-input v-model="inspectionForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭畾</el-button>
- <el-button @click="showDialog = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="submitInspectionForm">纭畾</el-button>
+ <el-button @click="inspectionDialogVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <el-dialog
+ ref="recordDialogRef"
+ v-model="recordDialogVisible"
+ title="宸℃璁板綍"
+ width="70vw"
+ :close-on-click-modal="false"
+ @open="onRecordDialogOpen"
+ >
+ <div class="mb10">
+ <el-button
+ type="primary"
+ size="small"
+ :disabled="currentInspectionStatus === '宸插畬鎴�'"
+ @click="openRecordForm"
+ >
+ 鏂板璁板綍
+ </el-button>
+ </div>
+ <div class="dialog-table-wrapper">
+ <el-table :data="recordList" border style="width: 100%">
+ <el-table-column prop="checkPoint" label="妫�鏌ョ偣" min-width="140" show-overflow-tooltip />
+ <el-table-column prop="checkContent" label="妫�鏌ュ唴瀹�" min-width="200" show-overflow-tooltip />
+ <el-table-column prop="checkResult" label="妫�鏌ョ粨鏋�" width="100">
+ <template #default="{ row }">
+ <el-tag :type="row.checkResult === '姝e父' ? 'success' : 'danger'">
+ {{ row.checkResult }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="checkDesc" label="妫�鏌ヨ鏄�" min-width="180" show-overflow-tooltip />
+ <el-table-column label="鐜板満鐓х墖" width="100">
+ <template #default="{ row }">
+ <el-tag :type="hasAttachments(row.storageBlobVOs) ? 'success' : 'info'">
+ {{ hasAttachments(row.storageBlobVOs) ? "宸蹭笂浼�" : "鏈笂浼�" }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="checkTime" label="妫�鏌ユ椂闂�" width="180" />
+ <el-table-column label="鎿嶄綔" width="130" fixed="right">
+ <template #default="{ row }">
+ <el-button type="primary" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="openEditRecordForm(row)">缂栬緫</el-button>
+ <el-button type="danger" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="handleDeleteRecord(row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <el-dialog
+ v-model="recordFormVisible"
+ :title="recordForm.id ? '缂栬緫宸℃璁板綍' : '鏂板宸℃璁板綍'"
+ width="600px"
+ append-to-body
+ :close-on-click-modal="false"
+ >
+ <el-form ref="recordFormRef" :model="recordForm" :rules="recordRules" label-width="100px">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="妫�鏌ョ偣" prop="checkPoint">
+ <el-input v-model="recordForm.checkPoint" placeholder="璇疯緭鍏ユ鏌ョ偣" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="妫�鏌ョ粨鏋�" prop="checkResult">
+ <el-radio-group v-model="recordForm.checkResult">
+ <el-radio label="姝e父">姝e父</el-radio>
+ <el-radio label="寮傚父">寮傚父</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="妫�鏌ュ唴瀹�" prop="checkContent">
+ <el-input v-model="recordForm.checkContent" type="textarea" :rows="3" placeholder="璇疯緭鍏ユ鏌ュ唴瀹�" />
+ </el-form-item>
+ <el-form-item label="妫�鏌ヨ鏄�">
+ <el-input v-model="recordForm.checkDesc" type="textarea" :rows="2" placeholder="璇疯緭鍏ユ鏌ヨ鏄�" />
+ </el-form-item>
+ <el-form-item v-if="recordForm.checkResult === '寮傚父'" label="鐜板満鐓х墖">
+ <ImageUpload v-model:file-list="recordForm.storageBlobDTOs" :limit="6" button-text="涓婁紶鐓х墖" />
+ </el-form-item>
+ <el-form-item label="妫�鏌ユ椂闂�">
+ <el-date-picker
+ v-model="recordForm.checkTime"
+ type="datetime"
+ placeholder="璇烽�夋嫨妫�鏌ユ椂闂�"
+ format="YYYY-MM-DD HH:mm:ss"
+ value-format="YYYY-MM-DD HH:mm:ss"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitRecordForm">纭畾</el-button>
+ <el-button @click="recordFormVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </el-dialog>
+
+ <el-dialog
+ ref="hazardDialogRef"
+ v-model="hazardDialogVisible"
+ title="闅愭偅绠$悊"
+ width="75vw"
+ :close-on-click-modal="false"
+ @open="onHazardDialogOpen"
+ >
+ <div class="mb10">
+ <el-button
+ type="primary"
+ size="small"
+ :disabled="currentInspectionStatus === '宸插畬鎴�'"
+ @click="openHazardForm('add')"
+ >
+ 涓婃姤闅愭偅
+ </el-button>
+ </div>
+ <div class="dialog-table-wrapper">
+ <el-table :data="hazardList" border style="width: 100%">
+ <el-table-column prop="hazardCode" label="闅愭偅缂栧彿" min-width="120" show-overflow-tooltip />
+ <el-table-column prop="hazardDesc" label="闅愭偅鎻忚堪" min-width="200" show-overflow-tooltip />
+ <el-table-column prop="hazardLevel" label="闅愭偅绛夌骇" width="100">
+ <template #default="{ row }">
+ <el-tag :type="row.hazardLevel === '閲嶅ぇ' ? 'danger' : 'warning'">
+ {{ row.hazardLevel }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="hazardLocation" label="闅愭偅浣嶇疆" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="status" label="鐘舵��" width="100">
+ <template #default="{ row }">
+ <el-tag :type="getHazardStatusType(row.status)">
+ {{ row.status }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="rectifyUserName" label="鏁存敼璐d换浜�" min-width="120" />
+ <el-table-column label="鎿嶄綔" width="150" fixed="right">
+ <template #default="{ row }">
+ <el-button type="primary" link :disabled="currentInspectionStatus === '宸插畬鎴�'" @click="openHazardForm('edit', row)">缂栬緫</el-button>
+ <el-button
+ v-if="row.status !== '宸叉暣鏀�'"
+ type="success"
+ link
+ :disabled="currentInspectionStatus === '宸插畬鎴�'"
+ @click="handleRectify(row)"
+ >
+ 鏁存敼
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+
+ <el-dialog
+ v-model="hazardFormVisible"
+ :title="hazardDialogTitle"
+ width="600px"
+ append-to-body
+ :close-on-click-modal="false"
+ >
+ <el-form ref="hazardFormRef" :model="hazardForm" :rules="hazardRules" label-width="100px">
+ <el-form-item label="闅愭偅鎻忚堪" prop="hazardDesc">
+ <el-input v-model="hazardForm.hazardDesc" type="textarea" :rows="3" placeholder="璇疯緭鍏ラ殣鎮f弿杩�" />
+ </el-form-item>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="闅愭偅绛夌骇" prop="hazardLevel">
+ <el-select v-model="hazardForm.hazardLevel" placeholder="璇烽�夋嫨闅愭偅绛夌骇" style="width: 100%">
+ <el-option label="涓�鑸�" value="涓�鑸�" />
+ <el-option label="閲嶅ぇ" value="閲嶅ぇ" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="闅愭偅浣嶇疆" prop="hazardLocation">
+ <el-input v-model="hazardForm.hazardLocation" placeholder="璇疯緭鍏ラ殣鎮d綅缃�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitHazardForm">纭畾</el-button>
+ <el-button @click="hazardFormVisible = false">鍙栨秷</el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ </el-dialog>
+
+ <el-dialog
+ v-model="rectifyFormVisible"
+ title="鏁存敼"
+ width="620px"
+ append-to-body
+ :close-on-click-modal="false"
+ @closed="resetRectifyForm"
+ >
+ <el-form ref="rectifyFormRef" :model="rectifyForm" :rules="rectifyRules" label-width="100px">
+ <el-form-item label="鏁存敼璇存槑" prop="rectifyDesc">
+ <el-input v-model="rectifyForm.rectifyDesc" type="textarea" :rows="4" placeholder="璇疯緭鍏ユ暣鏀硅鏄�" />
+ </el-form-item>
+ <el-form-item label="鏁存敼鍚庣収鐗�" prop="storageBlobDTOs">
+ <ImageUpload v-model:file-list="rectifyForm.storageBlobDTOs" :limit="6" button-text="涓婁紶鐓х墖" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="submitRectifyForm">纭畾</el-button>
+ <el-button @click="rectifyFormVisible = false">鍙栨秷</el-button>
</span>
</template>
</el-dialog>
@@ -129,246 +1048,1341 @@
</template>
<script setup>
-import { ref, reactive, onMounted } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
+import { computed, getCurrentInstance, onMounted, reactive, ref } from "vue";
+import { Delete, Plus, Search } from "@element-plus/icons-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 {
+ getLineInspectionTaskList,
+ addLineInspectionTask,
+ updateLineInspectionTask,
+ deleteLineInspectionTask,
getLineInspectionList,
- addOrEditLineInspection,
+ getLineInspectionById,
+ updateLineInspection,
deleteLineInspection,
- exportLineInspection
-} from '@/api/safeProduction/lineInspection'
-import { getDeviceLedger } from '@/api/equipmentManagement/ledger'
+ executeLineInspection,
+ getInspectionRecords,
+ addInspectionRecord,
+ updateInspectionRecord,
+ deleteInspectionRecord,
+ getInspectionHazards,
+ getHazardsByInspectionId,
+ addInspectionHazard,
+ updateInspectionHazard
+} from "@/api/safeProduction/lineInspection";
-// 鎼滅储琛ㄥ崟
-const searchForm = reactive({
- taskName: '',
- routeName: '',
- inspector: '',
- status: ''
-})
+const ENABLED = 1;
+const { proxy } = getCurrentInstance();
+const { hidden_danger_type } = proxy.useDict("hidden_danger_type");
+const userStore = useUserStore();
+const currentUserId = computed(() => Number(userStore.id));
-// 鍒嗛〉鏁版嵁
-const pagination = reactive({
- currentPage: 1,
- pageSize: 10,
- total: 0
-})
+const activeTab = ref("task");
+const tableLoading = ref(false);
+const tableData = ref([]);
+const selectedIds = ref([]);
+const userList = ref([]);
+const taskDialogVisible = ref(false);
+const taskDetailVisible = ref(false);
+const taskHistoryVisible = ref(false);
+const taskHistoryLoading = ref(false);
+const inspectionDetailVisible = ref(false);
+const inspectionDetailLoading = ref(false);
+const executeDialogVisible = ref(false);
+const inspectionDialogVisible = ref(false);
+const recordDialogVisible = ref(false);
+const recordFormVisible = ref(false);
+const hazardDialogVisible = ref(false);
+const hazardFormVisible = ref(false);
+const rectifyFormVisible = ref(false);
+const taskDialogTitle = ref("鏂板宸℃浠诲姟");
+const hazardDialogTitle = ref("涓婃姤闅愭偅");
+const currentInspectionId = ref(null);
+const currentInspectionStatus = ref("");
+const currentInspection = ref({});
+const inspectionDetail = ref({});
+const taskHistoryTask = ref({});
+const taskHistoryData = ref([]);
+const inspectionDetailRecords = ref([]);
+const inspectionDetailHazards = ref([]);
+const recordList = ref([]);
+const hazardList = ref([]);
-// 鍒楄〃鏁版嵁
-const inspectionList = ref([])
+const taskFormRef = ref();
+const inspectionFormRef = ref();
+const recordFormRef = ref();
+const hazardFormRef = ref();
+const executeFormRef = ref();
+const rectifyFormRef = ref();
-// 璁惧閫夐」
-const deviceOptions = ref([])
+const moduleTabs = [
+ { label: "宸℃浠诲姟", value: "task" },
+ { label: "宸℃璁板綍", value: "record" },
+ { label: "鏁存敼璺熻釜", value: "rectify" }
+];
-// 瀵硅瘽妗嗙姸鎬�
-const showDialog = ref(false)
-const dialogTitle = ref('鏂板宸℃')
+const page = reactive({
+ current: 1,
+ size: 20,
+ total: 0,
+ layout: "total, sizes, prev, pager, next, jumper"
+});
-// 琛ㄥ崟鏁版嵁
-const form = reactive({
+const taskHistoryPage = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+ layout: "total, sizes, prev, pager, next, jumper"
+});
+
+const taskSearchForm = reactive({
+ inspectionName: "",
+ lineName: "",
+ isEnabled: ""
+});
+
+const recordSearchForm = reactive({
+ inspectionCode: "",
+ inspectionName: "",
+ lineName: ""
+});
+
+const rectifySearchForm = reactive({
+ hazardCode: "",
+ hazardDesc: "",
+ status: ""
+});
+
+const createTaskForm = () => ({
id: null,
- taskName: '',
- routeName: '',
- deviceId: null,
- inspector: '',
- inspectionTime: '',
- inspectionResult: '',
- hazardDescription: '',
- remarks: ''
-})
+ inspectionName: "",
+ lineName: "",
+ inspectionProject: "",
+ inspectorId: "",
+ inspectorIds: [],
+ frequencyType: "",
+ frequencyDetail: "",
+ week: "",
+ day: "",
+ time: "",
+ isEnabled: ENABLED,
+ remark: ""
+});
-// 琛ㄥ崟楠岃瘉瑙勫垯
-const formRules = reactive({
- taskName: [{ required: true, message: '璇疯緭鍏ヤ换鍔″悕绉�', trigger: 'blur' }],
- routeName: [{ required: true, message: '璇疯緭鍏ョ嚎璺悕绉�', trigger: 'blur' }],
- inspector: [{ required: true, message: '璇疯緭鍏ュ贰妫�浜�', trigger: 'blur' }]
-})
+const createInspectionForm = () => ({
+ id: null,
+ scheduleTaskId: null,
+ inspectionCode: "",
+ inspectionName: "",
+ lineName: "",
+ inspectionType: "瀹氭湡宸℃",
+ inspectionProject: "",
+ planTime: "",
+ inspectorId: "",
+ inspectorIds: [],
+ status: "",
+ remark: ""
+});
-const formRef = ref(null)
+const taskForm = reactive(createTaskForm());
+const taskDetail = ref({});
+const inspectionForm = reactive(createInspectionForm());
-// 鑾峰彇鐘舵�佹爣绛剧被鍨�
-const getStatusType = (status) => {
- const map = {
- '寰呭贰妫�': 'info',
- '杩涜涓�': 'warning',
- '宸插畬鎴�': 'success'
+const recordForm = reactive({
+ id: null,
+ inspectionId: null,
+ checkPoint: "",
+ checkContent: "",
+ checkResult: "姝e父",
+ checkDesc: "",
+ checkTime: "",
+ storageBlobDTOs: []
+});
+
+const hazardForm = reactive({
+ id: null,
+ inspectionId: null,
+ hazardDesc: "",
+ hazardLevel: "",
+ hazardLocation: ""
+});
+
+const rectifyForm = reactive({
+ id: null,
+ rectifyDesc: "",
+ storageBlobDTOs: []
+});
+
+const createExecuteForm = () => ({
+ inspectionId: null,
+ checkResult: "姝e父",
+ checkDesc: "",
+ checkTime: "",
+ storageBlobDTOs: [],
+ hiddenType: "",
+ riskLevel: "",
+ hazardLocation: "",
+ hazardDesc: "",
+ rectifyUserId: "",
+ rectifyUserMobile: "",
+ rectifyTime: ""
+});
+
+const executeForm = reactive(createExecuteForm());
+
+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 validateFrequencyDetail = (rule, value, callback) => {
+ if (!taskForm.frequencyType) {
+ callback(new Error("璇烽�夋嫨浠诲姟棰戠巼"));
+ return;
}
- return map[status] || 'info'
-}
-
-// 鑾峰彇宸℃鍒楄〃
-const fetchList = async () => {
- try {
- const params = {
- ...searchForm,
- current: pagination.currentPage,
- size: pagination.pageSize
- }
- const res = await getLineInspectionList(params)
- if (res.code === 200) {
- inspectionList.value = res.data.records || []
- pagination.total = res.data.total || 0
- } else {
- ElMessage.error(res.message || '鑾峰彇鍒楄〃澶辫触')
- }
- } catch (error) {
- ElMessage.error('鑾峰彇鍒楄〃澶辫触')
+ if (taskForm.frequencyType === "DAILY" && !taskForm.frequencyDetail) {
+ callback(new Error("璇烽�夋嫨鏃堕棿"));
+ return;
}
-}
-
-// 鑾峰彇璁惧鍒楄〃
-const fetchDeviceOptions = async () => {
- try {
- const res = await getDeviceLedger()
- if (res.code === 200) {
- deviceOptions.value = res.data || []
- }
- } catch (error) {
- console.error('鑾峰彇璁惧鍒楄〃澶辫触')
+ if (taskForm.frequencyType === "WEEKLY" && (!taskForm.week || !taskForm.time)) {
+ callback(new Error("璇烽�夋嫨鏄熸湡鍜屾椂闂�"));
+ return;
}
-}
-
-// 鎼滅储
-const handleSearch = () => {
- pagination.currentPage = 1
- fetchList()
-}
-
-// 閲嶇疆鎼滅储
-const resetSearch = () => {
- Object.assign(searchForm, {
- taskName: '',
- routeName: '',
- inspector: '',
- status: ''
- })
- handleSearch()
-}
-
-// 鏂板
-const handleAdd = () => {
- dialogTitle.value = '鏂板宸℃'
- Object.assign(form, {
- id: null,
- taskName: '',
- routeName: '',
- deviceId: null,
- inspector: '',
- inspectionTime: '',
- inspectionResult: '',
- hazardDescription: '',
- remarks: ''
- })
- showDialog.value = true
-}
-
-// 缂栬緫
-const handleEdit = (row) => {
- dialogTitle.value = '缂栬緫宸℃'
- Object.assign(form, {
- id: row.id,
- taskName: row.taskName,
- routeName: row.routeName,
- deviceId: row.deviceId,
- inspector: row.inspector,
- inspectionTime: row.inspectionTime,
- inspectionResult: row.inspectionResult,
- hazardDescription: row.hazardDescription,
- remarks: row.remarks
- })
- showDialog.value = true
-}
-
-// 鍒犻櫎
-const handleDelete = async (row) => {
- try {
- await ElMessageBox.confirm('纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵', '鎻愮ず', {
- type: 'warning'
- })
- const res = await deleteLineInspection([row.id])
- if (res.code === 200) {
- ElMessage.success('鍒犻櫎鎴愬姛')
- fetchList()
- } else {
- ElMessage.error(res.message || '鍒犻櫎澶辫触')
- }
- } catch (error) {
- // 鍙栨秷鍒犻櫎
+ if (taskForm.frequencyType === "MONTHLY" && (!taskForm.day || !taskForm.time)) {
+ callback(new Error("璇烽�夋嫨鏃ユ湡鍜屾椂闂�"));
+ return;
}
-}
+ callback();
+};
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
- if (!formRef.value) return
- try {
- await formRef.value.validate()
- const res = await addOrEditLineInspection(form)
- if (res.code === 200) {
- ElMessage.success('鎿嶄綔鎴愬姛')
- showDialog.value = false
- fetchList()
- } else {
- ElMessage.error(res.message || '鎿嶄綔澶辫触')
- }
- } catch (error) {
- ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�')
+const taskRules = {
+ inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О", trigger: "blur" }],
+ lineName: [{ required: true, message: "璇疯緭鍏ョ嚎璺悕绉�", trigger: "blur" }],
+ inspectionProject: [{ required: true, message: "璇疯緭鍏ュ贰妫�椤圭洰", trigger: "blur" }],
+ inspectorIds: [{ type: "array", 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" }],
+ inspectionName: [{ required: true, message: "璇疯緭鍏ュ贰妫�鍚嶇О", trigger: "blur" }],
+ lineName: [{ required: true, message: "璇疯緭鍏ョ嚎璺悕绉�", trigger: "blur" }],
+ inspectorIds: [{ type: "array", required: true, message: "璇烽�夋嫨宸℃浜�", trigger: "change" }]
+};
+
+const recordRules = {
+ checkPoint: [{ required: true, message: "璇疯緭鍏ユ鏌ョ偣", trigger: "blur" }],
+ checkContent: [{ required: true, message: "璇疯緭鍏ユ鏌ュ唴瀹�", trigger: "blur" }],
+ checkResult: [{ required: true, message: "璇烽�夋嫨妫�鏌ョ粨鏋�", trigger: "change" }]
+};
+
+const hazardRules = {
+ hazardDesc: [{ required: true, message: "璇疯緭鍏ラ殣鎮f弿杩�", trigger: "blur" }],
+ hazardLevel: [{ required: true, message: "璇烽�夋嫨闅愭偅绛夌骇", trigger: "change" }],
+ hazardLocation: [{ required: true, message: "璇疯緭鍏ラ殣鎮d綅缃�", trigger: "blur" }]
+};
+
+const rectifyRules = {
+ rectifyDesc: [{ required: true, message: "璇疯緭鍏ユ暣鏀硅鏄�", trigger: "blur" }],
+ storageBlobDTOs: [{ required: true, message: "璇蜂笂浼犳暣鏀瑰悗鐓х墖", trigger: "change" }]
+};
+
+const riskLevelList = [
+ { value: "閲嶅ぇ椋庨櫓", label: "閲嶅ぇ椋庨櫓" },
+ { value: "杈冨ぇ椋庨櫓", label: "杈冨ぇ椋庨櫓" },
+ { value: "涓�鑸闄�", label: "涓�鑸闄�" },
+ { value: "浣庨闄�", label: "浣庨闄�" }
+];
+
+const hiddenTypeOptions = computed(() => {
+ const list = hidden_danger_type?.value || [];
+ return list.length ? list : [{ label: "绾胯矾宸℃", value: "绾胯矾宸℃" }];
+});
+
+const validateAbnormalRequired = message => (rule, value, callback) => {
+ if (executeForm.checkResult !== "寮傚父") {
+ callback();
+ return;
}
-}
-
-// 瀵煎嚭
-const handleExport = async () => {
- try {
- const res = await exportLineInspection(searchForm)
- const blob = new Blob([res])
- const url = window.URL.createObjectURL(blob)
- const link = document.createElement('a')
- link.href = url
- link.download = '绾胯矾宸℃璁板綍.xlsx'
- link.click()
- window.URL.revokeObjectURL(url)
- ElMessage.success('瀵煎嚭鎴愬姛')
- } catch (error) {
- ElMessage.error('瀵煎嚭澶辫触')
+ if (Array.isArray(value) ? value.length === 0 : value === "" || value === null || value === undefined) {
+ callback(new Error(message));
+ return;
}
-}
+ callback();
+};
-// 鍒嗛〉澶у皬鏀瑰彉
-const handleSizeChange = (val) => {
- pagination.pageSize = val
- fetchList()
-}
+const executeRules = {
+ checkResult: [{ required: true, message: "璇烽�夋嫨宸℃缁撴灉", trigger: "change" }],
+ checkTime: [{ required: true, message: "璇烽�夋嫨宸℃鏃堕棿", trigger: "change" }],
+ storageBlobDTOs: [{ validator: validateAbnormalRequired("宸℃寮傚父鏃惰涓婁紶寮傚父鐓х墖"), trigger: "change" }],
+ hiddenType: [{ validator: validateAbnormalRequired("璇烽�夋嫨闅愭偅绫诲瀷"), trigger: "change" }],
+ riskLevel: [{ validator: validateAbnormalRequired("璇烽�夋嫨椋庨櫓绛夌骇"), trigger: "change" }],
+ hazardLocation: [{ validator: validateAbnormalRequired("璇疯緭鍏ラ殣鎮d綅缃�"), trigger: "blur" }],
+ hazardDesc: [{ validator: validateAbnormalRequired("璇疯緭鍏ュ紓甯告弿杩�/鏁存敼瑕佹眰"), trigger: "blur" }],
+ rectifyUserId: [{ validator: validateAbnormalRequired("璇烽�夋嫨鏁存敼璐d换浜�"), trigger: "change" }],
+ rectifyTime: [{ validator: validateAbnormalRequired("璇烽�夋嫨鏁存敼鏈熼檺"), trigger: "change" }]
+};
-// 褰撳墠椤垫敼鍙�
-const handleCurrentChange = (val) => {
- pagination.currentPage = val
- fetchList()
-}
+const taskColumns = [
+ { label: "宸℃浠诲姟鍚嶇О", prop: "inspectionName", minWidth: 165, dataType: "slot", slot: "taskName", align: "left" },
+ { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 150, showOverflowTooltip: true, align: "left" },
+ { label: "宸℃椤圭洰", prop: "inspectionProject", minWidth: 175, showOverflowTooltip: true, align: "left" },
+ { label: "鎵ц宸℃浜�", prop: "inspectorName", minWidth: 145, dataType: "slot", slot: "inspectorName", align: "center" },
+ { label: "鏄惁鍚敤", prop: "isEnabled", minWidth: 90, dataType: "slot", slot: "isEnabled", align: "center" },
+ {
+ label: "棰戞",
+ prop: "frequencyType",
+ minWidth: 85,
+ align: "center",
+ formatData: value => frequencyTypeMap[value] || value || "--"
+ },
+ {
+ label: "寮�濮嬫棩鏈熶笌鏃堕棿",
+ prop: "frequencyDetail",
+ minWidth: 150,
+ 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",
+ style: { color: "#F56C6C" },
+ clickFun: row => handleDeleteTask(row)
+ }
+ ]
+ }
+];
+
+const taskHistoryColumns = [
+ { label: "宸℃缂栧彿", prop: "inspectionCode", width: 190, dataType: "slot", slot: "inspectionCode", align: "center" },
+ { label: "宸℃鍚嶇О", prop: "inspectionName", minWidth: 135, showOverflowTooltip: true, align: "left" },
+ { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 130, showOverflowTooltip: true, align: "left" },
+ { label: "宸℃椤圭洰", prop: "inspectionProject", minWidth: 150, showOverflowTooltip: true, align: "left" },
+ { label: "璁″垝宸℃鏃堕棿", prop: "planTime", width: 165, showOverflowTooltip: true, align: "center" },
+ { label: "宸℃缁撴灉", prop: "inspectionResult", width: 90, dataType: "slot", slot: "inspectionResult", align: "center" },
+ { label: "瀹為檯宸℃鏃堕棿", prop: "actualInspectionTime", width: 165, showOverflowTooltip: true, align: "center" },
+ { label: "宸℃浜�", prop: "inspectorName", minWidth: 105, dataType: "slot", slot: "inspectorName", align: "center" },
+ { label: "鐘舵��", prop: "status", width: 90, dataType: "slot", slot: "status", align: "center" }
+];
+
+const recordColumns = [
+ { label: "宸℃缂栧彿", prop: "inspectionCode", width: 190, dataType: "slot", slot: "inspectionCode", align: "center" },
+ { label: "宸℃鍚嶇О", prop: "inspectionName", minWidth: 135, showOverflowTooltip: true, align: "left" },
+ { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 130, showOverflowTooltip: true, align: "left" },
+ { label: "宸℃椤圭洰", prop: "inspectionProject", minWidth: 145, showOverflowTooltip: true, align: "left" },
+ { label: "璁″垝宸℃鏃堕棿", prop: "planTime", width: 165, showOverflowTooltip: true, align: "center" },
+ { label: "宸℃缁撴灉", prop: "inspectionResult", width: 90, dataType: "slot", slot: "inspectionResult", align: "center" },
+ { label: "瀹為檯宸℃鏃堕棿", prop: "actualInspectionTime", width: 165, showOverflowTooltip: true, align: "center" },
+ { label: "宸℃浜�", prop: "inspectorName", minWidth: 105, dataType: "slot", slot: "inspectorName", align: "center" },
+ { label: "鐘舵��", prop: "status", width: 90, dataType: "slot", slot: "status", align: "center" },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 125,
+ operation: [
+ {
+ name: "鎵ц宸℃",
+ type: "text",
+ clickFun: row => openExecuteDialog(row),
+ show: row => row.status !== "宸插畬鎴�" && row.status !== "寰呮暣鏀�"
+ },
+ {
+ name: "鍒犻櫎",
+ type: "text",
+ style: { color: "#F56C6C" },
+ clickFun: row => handleDeleteInspection(row),
+ disabled: row => row.status !== "寰呭贰妫�"
+ }
+ ]
+ }
+];
+
+const rectifyColumns = [
+ { label: "闅愭偅缂栧彿", prop: "hazardCode", width: 135, showOverflowTooltip: true, align: "center" },
+ { label: "宸℃缂栧彿", prop: "inspectionCode", width: 190, dataType: "slot", slot: "inspectionCode", align: "center" },
+ { label: "宸℃鍚嶇О", prop: "inspectionName", minWidth: 120, showOverflowTooltip: true, align: "left" },
+ { label: "绾胯矾鍚嶇О", prop: "lineName", minWidth: 120, showOverflowTooltip: true, align: "left" },
+ { label: "寮傚父鎻忚堪", prop: "hazardDesc", minWidth: 160, showOverflowTooltip: true, align: "left" },
+ { label: "寮傚父浣嶇疆", prop: "hazardLocation", minWidth: 130, showOverflowTooltip: true, align: "left" },
+ { label: "椋庨櫓绛夌骇", prop: "hazardLevel", width: 95, dataType: "slot", slot: "hazardLevel", align: "center" },
+ { label: "鏁存敼璐d换浜�", prop: "rectifyUserName", minWidth: 110, showOverflowTooltip: true, align: "center" },
+ { label: "鏁存敼鏈熼檺", prop: "rectifyDeadline", width: 110, showOverflowTooltip: true, align: "center" },
+ { label: "鏁存敼鐘舵��", prop: "status", width: 95, dataType: "slot", slot: "hazardStatus", align: "center" },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ fixed: "right",
+ width: 85,
+ operation: [
+ {
+ name: "鏁存敼",
+ type: "text",
+ color: "#67C23A",
+ clickFun: row => handleRectify(row),
+ show: row => row.status !== "宸叉暣鏀�" && canRectify(row)
+ }
+ ]
+ }
+];
+
+const tableColumns = computed(() => {
+ if (activeTab.value === "task") {
+ return taskColumns;
+ }
+ if (activeTab.value === "record") {
+ return recordColumns;
+ }
+ return rectifyColumns;
+});
onMounted(() => {
- fetchList()
- fetchDeviceOptions()
-})
+ getList();
+ userListNoPage().then(res => {
+ userList.value = res.data || [];
+ });
+});
+
+const getList = async () => {
+ tableLoading.value = true;
+ try {
+ const params = cleanParams({
+ current: page.current,
+ size: page.size,
+ ...getActiveSearchForm()
+ });
+ const api = getActiveListApi();
+ const res = await api(params);
+ tableData.value = res.data?.records || [];
+ page.total = res.data?.total || 0;
+ } finally {
+ tableLoading.value = false;
+ }
+};
+
+const getActiveSearchForm = () => {
+ if (activeTab.value === "task") {
+ return taskSearchForm;
+ }
+ if (activeTab.value === "record") {
+ return recordSearchForm;
+ }
+ return rectifySearchForm;
+};
+
+const getActiveListApi = () => {
+ if (activeTab.value === "task") {
+ return getLineInspectionTaskList;
+ }
+ if (activeTab.value === "record") {
+ return getLineInspectionList;
+ }
+ return getInspectionHazards;
+};
+
+const handleQuery = () => {
+ page.current = 1;
+ getList();
+};
+
+const resetQuery = () => {
+ page.current = 1;
+ if (activeTab.value === "task") {
+ Object.assign(taskSearchForm, { inspectionName: "", lineName: "", isEnabled: "" });
+ } else if (activeTab.value === "record") {
+ Object.assign(recordSearchForm, { inspectionCode: "", inspectionName: "", lineName: "" });
+ } else {
+ Object.assign(rectifySearchForm, { hazardCode: "", hazardDesc: "", status: "" });
+ }
+ getList();
+};
+
+const handleTabChange = () => {
+ selectedIds.value = [];
+ page.current = 1;
+ getList();
+};
+
+const handleModuleTabChange = tab => {
+ if (activeTab.value === tab) {
+ return;
+ }
+ activeTab.value = tab;
+ handleTabChange();
+};
+
+const pagination = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+};
+
+const handleSelectionChange = selection => {
+ selectedIds.value = selection.map(item => item.id);
+};
+
+const openTaskDetail = row => {
+ taskDetail.value = { ...row };
+ taskDetailVisible.value = true;
+};
+
+const openTaskHistory = row => {
+ taskHistoryTask.value = { ...row };
+ taskHistoryPage.current = 1;
+ taskHistoryVisible.value = true;
+ fetchTaskHistory();
+};
+
+const fetchTaskHistory = async () => {
+ if (!taskHistoryTask.value?.id) {
+ taskHistoryData.value = [];
+ taskHistoryPage.total = 0;
+ return;
+ }
+ taskHistoryLoading.value = true;
+ try {
+ const res = await getLineInspectionList(
+ cleanParams({
+ current: taskHistoryPage.current,
+ size: taskHistoryPage.size,
+ scheduleTaskId: taskHistoryTask.value.id
+ })
+ );
+ taskHistoryData.value = res.data?.records || [];
+ taskHistoryPage.total = res.data?.total || 0;
+ } finally {
+ taskHistoryLoading.value = false;
+ }
+};
+
+const taskHistoryPagination = obj => {
+ taskHistoryPage.current = obj.page;
+ taskHistoryPage.size = obj.limit;
+ fetchTaskHistory();
+};
+
+const openInspectionDetailEntry = row => {
+ if (activeTab.value === "rectify") {
+ openInspectionDetailById(row.inspectionId, row);
+ return;
+ }
+ openInspectionDetail(row);
+};
+
+const openInspectionDetailById = async (inspectionId, fallback = {}) => {
+ let row = {
+ id: inspectionId,
+ inspectionCode: fallback.inspectionCode,
+ inspectionName: fallback.inspectionName,
+ lineName: fallback.lineName
+ };
+ if (inspectionId) {
+ const res = await getLineInspectionById(inspectionId);
+ if (res.code === 200 && res.data) {
+ row = { ...row, ...res.data };
+ }
+ }
+ openInspectionDetail(row);
+};
+
+const openInspectionDetail = async row => {
+ if (!row?.id) {
+ ElMessage.warning("宸℃璁板綍涓嶅瓨鍦�");
+ return;
+ }
+ inspectionDetail.value = { ...row };
+ inspectionDetailVisible.value = true;
+ inspectionDetailLoading.value = true;
+ try {
+ const [recordsRes, hazardsRes] = await Promise.all([
+ getInspectionRecords(row.id),
+ getHazardsByInspectionId(row.id)
+ ]);
+ inspectionDetailRecords.value = recordsRes.code === 200 ? recordsRes.data || [] : [];
+ inspectionDetailHazards.value = hazardsRes.code === 200 ? hazardsRes.data || [] : [];
+ } finally {
+ inspectionDetailLoading.value = false;
+ }
+};
+
+const openExecuteDialog = row => {
+ currentInspection.value = { ...row };
+ Object.assign(executeForm, createExecuteForm(), {
+ inspectionId: row.id,
+ checkTime: formatDateTime(new Date()),
+ hazardLocation: row.lineName || ""
+ });
+ executeDialogVisible.value = true;
+};
+
+const resetExecuteForm = () => {
+ Object.assign(executeForm, createExecuteForm());
+ currentInspection.value = {};
+ executeFormRef.value?.clearValidate?.();
+};
+
+const handleExecuteResultChange = () => {
+ if (executeForm.checkResult === "寮傚父") {
+ executeForm.hazardLocation = executeForm.hazardLocation || currentInspection.value.lineName || "";
+ executeForm.checkDesc = "";
+ }
+ executeFormRef.value?.clearValidate?.();
+};
+
+const handleRectifyUserChange = userId => {
+ const selectedUser = userList.value.find(user => Number(user.userId) === Number(userId));
+ executeForm.rectifyUserMobile = selectedUser?.phonenumber || "";
+};
+
+const submitExecuteForm = async () => {
+ try {
+ await executeFormRef.value.validate();
+ const payload = { ...executeForm };
+ if (payload.checkResult === "姝e父") {
+ Object.assign(payload, {
+ storageBlobDTOs: [],
+ hiddenType: "",
+ riskLevel: "",
+ hazardLocation: "",
+ hazardDesc: "",
+ rectifyUserId: "",
+ rectifyUserMobile: "",
+ rectifyTime: ""
+ });
+ } else {
+ payload.checkDesc = "";
+ }
+ const res = await executeLineInspection(payload);
+ if (res.code === 200) {
+ ElMessage.success(payload.checkResult === "寮傚父" ? "寮傚父宸蹭笂鎶ユ暣鏀�" : "宸℃宸插畬鎴�");
+ executeDialogVisible.value = false;
+ getList();
+ } else {
+ ElMessage.error(res.msg || "宸℃鎻愪氦澶辫触");
+ }
+ } catch (error) {
+ console.error("鎵ц宸℃琛ㄥ崟鏍¢獙澶辫触:", error);
+ }
+};
+
+const openTaskDialog = (type, row = null) => {
+ resetTaskForm();
+ taskDialogTitle.value = type === "add" ? "鏂板宸℃浠诲姟" : "缂栬緫宸℃浠诲姟";
+ if (type === "edit" && row) {
+ Object.assign(taskForm, {
+ id: row.id,
+ inspectionName: row.inspectionName,
+ lineName: row.lineName,
+ inspectionProject: row.inspectionProject,
+ inspectorId: row.inspectorId,
+ inspectorIds: parseInspectorIds(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, createTaskForm());
+ taskFormRef.value?.clearValidate?.();
+};
+
+const handleFrequencyTypeChange = () => {
+ Object.assign(taskForm, { frequencyDetail: "", week: "", day: "", time: "" });
+ taskFormRef.value?.clearValidate?.("frequencyDetail");
+};
+
+const parseFrequencyDetail = (frequencyType, frequencyDetail) => {
+ if (!frequencyDetail) {
+ return;
+ }
+ if (frequencyType === "DAILY") {
+ taskForm.frequencyDetail = frequencyDetail;
+ return;
+ }
+ const [firstPart, timePart] = frequencyDetail.split(",");
+ taskForm.frequencyDetail = "";
+ taskForm.time = timePart || "";
+ if (frequencyType === "WEEKLY") {
+ taskForm.week = firstPart || "";
+ }
+ if (frequencyType === "MONTHLY") {
+ taskForm.day = String(firstPart || "").padStart(2, "0");
+ }
+};
+
+const submitTaskForm = async () => {
+ try {
+ await taskFormRef.value.validate();
+ const payload = {
+ id: taskForm.id,
+ inspectionName: taskForm.inspectionName,
+ lineName: taskForm.lineName,
+ inspectionProject: taskForm.inspectionProject,
+ inspectorId: taskForm.inspectorIds.join(","),
+ frequencyType: taskForm.frequencyType,
+ frequencyDetail: buildFrequencyDetail(),
+ isEnabled: taskForm.isEnabled,
+ remark: taskForm.remark
+ };
+ const api = taskForm.id ? updateLineInspectionTask : addLineInspectionTask;
+ const res = await api(payload);
+ if (res.code === 200) {
+ ElMessage.success(taskForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+ taskDialogVisible.value = false;
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("浠诲姟琛ㄥ崟鏍¢獙澶辫触:", error);
+ }
+};
+
+const buildFrequencyDetail = () => {
+ if (taskForm.frequencyType === "DAILY") {
+ return taskForm.frequencyDetail;
+ }
+ if (taskForm.frequencyType === "WEEKLY") {
+ return `${taskForm.week},${taskForm.time}`;
+ }
+ if (taskForm.frequencyType === "MONTHLY") {
+ return `${taskForm.day},${taskForm.time}`;
+ }
+ return "";
+};
+
+const handleDeleteTask = row => {
+ confirmDelete("纭鍒犻櫎璇ュ畾鏃跺贰妫�浠诲姟鍚楋紵", async () => {
+ const res = await deleteLineInspectionTask([row.id]);
+ handleDeleteResult(res);
+ });
+};
+
+const handleBatchDeleteTask = () => {
+ if (selectedIds.value.length === 0) {
+ ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑宸℃浠诲姟");
+ return;
+ }
+ confirmDelete("纭鍒犻櫎閫変腑鐨勫畾鏃跺贰妫�浠诲姟鍚楋紵", async () => {
+ const res = await deleteLineInspectionTask(selectedIds.value);
+ handleDeleteResult(res);
+ });
+};
+
+const openInspectionDialog = row => {
+ resetInspectionForm();
+ Object.assign(inspectionForm, {
+ id: row.id,
+ scheduleTaskId: row.scheduleTaskId,
+ inspectionCode: row.inspectionCode,
+ inspectionName: row.inspectionName,
+ lineName: row.lineName,
+ inspectionType: row.inspectionType,
+ inspectionProject: row.inspectionProject,
+ planTime: row.planTime,
+ inspectorId: row.inspectorId,
+ inspectorIds: parseInspectorIds(row.inspectorId),
+ status: row.status,
+ remark: row.remark
+ });
+ inspectionDialogVisible.value = true;
+};
+
+const resetInspectionForm = () => {
+ Object.assign(inspectionForm, createInspectionForm());
+ inspectionFormRef.value?.clearValidate?.();
+};
+
+const submitInspectionForm = async () => {
+ try {
+ await inspectionFormRef.value.validate();
+ const payload = {
+ ...inspectionForm,
+ inspectorId: inspectionForm.inspectorIds.join(",")
+ };
+ delete payload.inspectorIds;
+ const res = await updateLineInspection(payload);
+ if (res.code === 200) {
+ ElMessage.success("淇敼鎴愬姛");
+ inspectionDialogVisible.value = false;
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("宸℃璁板綍琛ㄥ崟鏍¢獙澶辫触:", error);
+ }
+};
+
+const handleDeleteInspection = row => {
+ confirmDelete("纭鍒犻櫎璇ュ贰妫�璁板綍鍚楋紵", async () => {
+ const res = await deleteLineInspection([row.id]);
+ handleDeleteResult(res);
+ });
+};
+
+const openRecordDialog = row => {
+ currentInspectionId.value = row.id;
+ currentInspectionStatus.value = row.status;
+ fetchRecords(row.id);
+ recordDialogVisible.value = true;
+};
+
+const fetchRecords = async inspectionId => {
+ const res = await getInspectionRecords(inspectionId);
+ if (res.code === 200) {
+ recordList.value = res.data || [];
+ }
+};
+
+const openRecordForm = () => {
+ Object.assign(recordForm, {
+ id: null,
+ inspectionId: currentInspectionId.value,
+ checkPoint: "",
+ checkContent: "",
+ checkResult: "姝e父",
+ checkDesc: "",
+ checkTime: "",
+ storageBlobDTOs: []
+ });
+ recordFormVisible.value = true;
+};
+
+const openEditRecordForm = row => {
+ Object.assign(recordForm, {
+ id: row.id,
+ inspectionId: row.inspectionId,
+ checkPoint: row.checkPoint,
+ checkContent: row.checkContent,
+ checkResult: row.checkResult,
+ checkDesc: row.checkDesc,
+ checkTime: row.checkTime,
+ storageBlobDTOs: getAttachments(row)
+ });
+ recordFormVisible.value = true;
+};
+
+const handleDeleteRecord = row => {
+ confirmDelete("纭鍒犻櫎璇ュ贰妫�璁板綍鏄庣粏鍚楋紵", async () => {
+ const res = await deleteInspectionRecord([row.id]);
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ fetchRecords(currentInspectionId.value);
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+ });
+};
+
+const submitRecordForm = async () => {
+ try {
+ await recordFormRef.value.validate();
+ if (recordForm.checkResult === "寮傚父" && !hasAttachments(recordForm.storageBlobDTOs)) {
+ ElMessage.warning("宸℃缁撴灉寮傚父鏃惰涓婁紶鐜板満鐓х墖");
+ return;
+ }
+ const api = recordForm.id ? updateInspectionRecord : addInspectionRecord;
+ const res = await api({ ...recordForm });
+ if (res.code === 200) {
+ ElMessage.success(recordForm.id ? "淇敼鎴愬姛" : "娣诲姞鎴愬姛");
+ recordFormVisible.value = false;
+ fetchRecords(currentInspectionId.value);
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("宸℃璁板綍鏄庣粏琛ㄥ崟鏍¢獙澶辫触:", error);
+ }
+};
+
+const openHazardDialog = row => {
+ currentInspectionId.value = row.id;
+ currentInspectionStatus.value = row.status;
+ fetchHazards(row.id);
+ hazardDialogVisible.value = true;
+};
+
+const fetchHazards = async inspectionId => {
+ const res = await getHazardsByInspectionId(inspectionId);
+ if (res.code === 200) {
+ hazardList.value = res.data || [];
+ }
+};
+
+const openHazardForm = (type, row = null) => {
+ if (type === "add") {
+ hazardDialogTitle.value = "涓婃姤闅愭偅";
+ Object.assign(hazardForm, {
+ id: null,
+ inspectionId: currentInspectionId.value,
+ hazardDesc: "",
+ hazardLevel: "",
+ hazardLocation: ""
+ });
+ } else {
+ hazardDialogTitle.value = "缂栬緫闅愭偅";
+ Object.assign(hazardForm, {
+ id: row.id,
+ inspectionId: row.inspectionId,
+ hazardDesc: row.hazardDesc,
+ hazardLevel: row.hazardLevel,
+ hazardLocation: row.hazardLocation
+ });
+ }
+ hazardFormVisible.value = true;
+};
+
+const submitHazardForm = async () => {
+ try {
+ await hazardFormRef.value.validate();
+ const api = hazardForm.id ? updateInspectionHazard : addInspectionHazard;
+ const res = await api({ ...hazardForm });
+ if (res.code === 200) {
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ hazardFormVisible.value = false;
+ fetchHazards(currentInspectionId.value);
+ } else {
+ ElMessage.error(res.msg || "鎿嶄綔澶辫触");
+ }
+ } catch (error) {
+ console.error("闅愭偅琛ㄥ崟鏍¢獙澶辫触:", error);
+ }
+};
+
+const handleRectify = row => {
+ if (!canRectify(row)) {
+ ElMessage.warning("鍙湁鏁存敼璐d换浜哄彲浠ヨ繘琛屾暣鏀�");
+ return;
+ }
+ currentInspectionId.value = row.inspectionId || currentInspectionId.value;
+ Object.assign(rectifyForm, {
+ id: row.id,
+ rectifyDesc: "",
+ storageBlobDTOs: []
+ });
+ rectifyFormVisible.value = true;
+};
+
+const resetRectifyForm = () => {
+ Object.assign(rectifyForm, {
+ id: null,
+ rectifyDesc: "",
+ storageBlobDTOs: []
+ });
+ rectifyFormRef.value?.clearValidate?.();
+};
+
+const submitRectifyForm = async () => {
+ await rectifyFormRef.value.validate();
+ if (!hasAttachments(rectifyForm.storageBlobDTOs)) {
+ ElMessage.warning("璇蜂笂浼犳暣鏀瑰悗鐓х墖");
+ return;
+ }
+ const res = await updateInspectionHazard({
+ id: rectifyForm.id,
+ status: "宸叉暣鏀�",
+ rectifyDesc: rectifyForm.rectifyDesc,
+ storageBlobDTOs: rectifyForm.storageBlobDTOs
+ });
+ if (res.code === 200) {
+ ElMessage.success("鏁存敼鎴愬姛");
+ rectifyFormVisible.value = false;
+ if (currentInspectionId.value) {
+ fetchHazards(currentInspectionId.value);
+ }
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鏁存敼澶辫触");
+ }
+};
+
+const canRectify = row => {
+ return Number(row?.rectifyUserId) === currentUserId.value;
+};
+
+const confirmDelete = (message, onConfirm) => {
+ ElMessageBox.confirm(message, "鍒犻櫎", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ })
+ .then(onConfirm)
+ .catch(() => {});
+};
+
+const handleDeleteResult = res => {
+ if (res.code === 200) {
+ ElMessage.success("鍒犻櫎鎴愬姛");
+ selectedIds.value = [];
+ getList();
+ } else {
+ ElMessage.error(res.msg || "鍒犻櫎澶辫触");
+ }
+};
+
+const cleanParams = params => {
+ return Object.fromEntries(
+ Object.entries(params).filter(([, value]) => value !== "" && value !== null && value !== undefined)
+ );
+};
+
+const getInspectionStatusType = status => {
+ const map = {
+ 寰呭贰妫�: "info",
+ 宸℃涓�: "warning",
+ 寰呮暣鏀�: "danger",
+ 宸插畬鎴�: "success"
+ };
+ return map[status] || "info";
+};
+
+const getInspectionResultType = result => {
+ const map = {
+ 姝e父: "success",
+ 寮傚父: "danger"
+ };
+ return map[result] || "info";
+};
+
+const getHazardStatusType = status => {
+ const map = {
+ 寰呮暣鏀�: "danger",
+ 鏁存敼涓�: "warning",
+ 宸叉暣鏀�: "success"
+ };
+ return map[status] || "info";
+};
+
+const getRiskLevelType = level => {
+ const map = {
+ 閲嶅ぇ椋庨櫓: "danger",
+ 杈冨ぇ椋庨櫓: "warning",
+ 涓�鑸闄�: "primary",
+ 浣庨闄�: "info",
+ 閲嶅ぇ: "danger",
+ 涓�鑸�: "warning"
+ };
+ return map[level] || "info";
+};
+
+const getInspectorNames = row => {
+ if (Array.isArray(row.inspector)) {
+ return row.inspector.filter(Boolean);
+ }
+ if (!row.inspectorName && row.inspectorId) {
+ return parseInspectorIds(row.inspectorId)
+ .map(id => userList.value.find(user => Number(user.userId) === Number(id))?.nickName)
+ .filter(Boolean);
+ }
+ return String(row.inspectorName || "")
+ .split(",")
+ .map(item => item.trim())
+ .filter(Boolean);
+};
+
+const parseInspectorIds = inspectorId => {
+ return String(inspectorId || "")
+ .split(",")
+ .map(item => Number(item.trim()))
+ .filter(item => !Number.isNaN(item));
+};
+
+const formatFrequencyDetail = value => {
+ if (!value) {
+ return "--";
+ }
+ return String(value).replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => weekLabelMap[match] || match);
+};
+
+const getAttachments = row => row?.storageBlobDTOs || row?.storageBlobVOs || [];
+const hasAttachments = attachments => Array.isArray(attachments) && attachments.length > 0;
+const getAttachmentPreviewUrl = row => row?.previewURL || row?.previewUrl || row?.url || row?.downloadURL || row?.downloadUrl || "";
+const getAttachmentPreviewUrls = row => getAttachments(row).map(getAttachmentPreviewUrl).filter(Boolean);
+
+const formatDateTime = date => {
+ const pad = value => String(value).padStart(2, "0");
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
+};
+
+const setDialogFixedHeight = () => {
+ setTimeout(() => {
+ const dialogs = document.body.querySelectorAll(".el-dialog");
+ const dialog = dialogs[dialogs.length - 1];
+ if (!dialog) return;
+ Object.assign(dialog.style, {
+ height: "70vh",
+ maxHeight: "70vh",
+ overflow: "hidden",
+ display: "flex",
+ flexDirection: "column"
+ });
+ const body = dialog.querySelector(".el-dialog__body");
+ if (body) {
+ Object.assign(body.style, { flex: "1", overflow: "hidden" });
+ }
+ const wrapper = dialog.querySelector(".dialog-table-wrapper");
+ if (wrapper) {
+ Object.assign(wrapper.style, { flex: "1", overflowY: "auto" });
+ }
+ }, 100);
+};
+
+const onRecordDialogOpen = () => setDialogFixedHeight();
+const onHazardDialogOpen = () => setDialogFixedHeight();
</script>
<style scoped>
-.line-inspection {
- padding: 20px;
+.line-inspection-page :deep(.table_list) {
+ width: 100%;
}
-.search-area {
- background: #f5f7fa;
- padding: 20px;
- border-radius: 4px;
- margin-bottom: 15px;
-}
-
-.actions {
- margin-bottom: 15px;
-}
-
-.pagination {
- margin-top: 20px;
+.module-tabs {
display: flex;
- justify-content: flex-end;
+ align-items: center;
+ gap: 42px;
+ min-height: 58px;
+ margin-bottom: 16px;
+ padding: 0 28px;
+ border-bottom: 1px solid #d7e2f1;
+}
+
+.module-tab {
+ position: relative;
+ border: 0;
+ background: transparent;
+ color: #1f2d3d;
+ font-size: 16px;
+ line-height: 58px;
+ cursor: pointer;
+ padding: 0;
+}
+
+.module-tab.active {
+ color: #003bb3;
+ font-weight: 600;
+}
+
+.module-tab.active::after {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 2px;
+ background: #003bb3;
+ content: "";
+}
+
+.line-search-panel {
+ justify-content: flex-start;
+ align-items: center;
+ gap: 16px;
+ min-height: 44px;
+ overflow: hidden;
+}
+
+.search-left {
+ display: flex;
+ flex: 1 1 auto;
+ flex-wrap: nowrap;
+ align-items: center;
+ gap: 14px;
+ min-width: 0;
+ padding-right: 12px;
+}
+
+.filter-item,
+.filter-buttons,
+.toolbar-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ flex: 0 0 auto;
+}
+
+.filter-control {
+ width: 210px;
+}
+
+.filter-control.is-wide {
+ width: 240px;
+}
+
+.filter-control.is-short {
+ width: 150px;
+}
+
+.table-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+ margin-bottom: 12px;
+ min-height: 40px;
+}
+
+.search_title {
+ font-size: 14px;
+ color: #606266;
+ white-space: nowrap;
+}
+
+.person-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ align-items: center;
+ justify-content: center;
+}
+
+.person-tag {
+ margin: 0;
+}
+
+.task-name-link {
+ max-width: 100%;
+ padding: 0;
+ font-weight: 600;
+ vertical-align: middle;
+}
+
+.task-name-link :deep(span),
+.code-link :deep(span) {
+ display: inline-block;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.code-link {
+ max-width: 100%;
+ padding: 0;
+ font-weight: 600;
+ vertical-align: middle;
+}
+
+.detail-section-title {
+ margin: 18px 0 10px;
+ color: #1f2d3d;
+ font-size: 15px;
+ font-weight: 600;
+}
+
+.history-summary {
+ margin-bottom: 14px;
+}
+
+.execute-summary {
+ margin-bottom: 18px;
+}
+
+.photo-list {
+ display: flex;
+ justify-content: center;
+ gap: 6px;
+ flex-wrap: wrap;
+}
+
+.record-photo {
+ width: 46px;
+ height: 46px;
+ border-radius: 4px;
+ border: 1px solid #dcdfe6;
+}
+
+.frequency-row {
+ display: grid;
+ grid-template-columns: 132px minmax(170px, 1fr);
+ gap: 10px;
+ width: 100%;
+}
+
+.frequency-day-select,
+.frequency-time-picker {
+ width: 100%;
+}
+
+:deep(.frequency-detail-item .el-form-item__label) {
+ width: 72px !important;
+ flex: 0 0 72px;
+}
+
+.no-data {
+ color: #909399;
+}
+
+.mb10 {
+ margin-bottom: 10px;
+}
+
+.mb20 {
+ margin-bottom: 20px;
+}
+
+.ml10 {
+ margin-left: 10px;
+}
+
+@media (max-width: 1500px) {
+ .line-search-panel {
+ align-items: flex-start;
+ }
+
+ .search-left {
+ flex-wrap: wrap;
+ }
}
</style>
--
Gitblit v1.9.3