| | |
| | | </div> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 安全设施巡检 --> |
| | | <el-tab-pane label="安全设施巡检" name="inspection"> |
| | | <!-- 巡检任务 --> |
| | | <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-form ref="ledgerFormRef" |
| | | :model="ledgerForm" |
| | | :rules="ledgerRules" |
| | | label-width="120px" |
| | | :disabled="isLedgerView"> |
| | | label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="设施编号" |
| | |
| | | </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="下次检查时间"> |
| | | <el-input :value="computedNextCheckTime" disabled placeholder="根据安装时间+有效期自动计算" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="状态" |
| | | prop="status"> |
| | | <el-select v-model="ledgerForm.status" |
| | |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button v-if="!isLedgerView" |
| | | type="primary" |
| | | <el-button type="primary" |
| | | @click="submitLedgerForm">确定</el-button> |
| | | <el-button @click="ledgerDialogVisible = false">{{ isLedgerView ? '关闭' : '取消' }}</el-button> |
| | | <el-button @click="ledgerDialogVisible = false">取消</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 设施台账详情弹窗 --> |
| | | <el-dialog v-model="ledgerDetailVisible" |
| | | title="设施详情" |
| | | width="760px" |
| | | class="detail-dialog"> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="设施编号">{{ ledgerDetail.facilityCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="设施名称">{{ ledgerDetail.facilityName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="设施类型">{{ ledgerDetail.facilityType || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="规格型号">{{ ledgerDetail.facilitySpec || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="安装位置">{{ ledgerDetail.installLocation || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="安装时间">{{ ledgerDetail.installTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="生产日期">{{ ledgerDetail.productionDate || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="状态"> |
| | | <el-tag :type="ledgerStatusType(ledgerDetail.status)">{{ ledgerDetail.status || '-' }}</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="备注" :span="2">{{ ledgerDetail.remark || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" @click="ledgerDetailVisible = false">关闭</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 巡检任务表单弹窗 --> |
| | | <el-dialog v-model="taskDialogVisible" |
| | | :title="taskDialogTitle" |
| | | width="920px" |
| | | :close-on-click-modal="false" |
| | | @closed="resetTaskForm"> |
| | | <el-form ref="taskFormRef" |
| | | :model="taskForm" |
| | | :rules="taskRules" |
| | | label-width="120px"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="巡检任务名称" |
| | | prop="inspectionName"> |
| | | <el-input v-model="taskForm.inspectionName" |
| | | placeholder="请输入巡检任务名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="安全设施" |
| | | prop="facilityId"> |
| | | <el-select v-model="taskForm.facilityId" |
| | | placeholder="请选择安全设施" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleTaskFacilityChange"> |
| | | <el-option v-for="item in facilityOptions" |
| | | :key="item.id" |
| | | :label="`${item.facilityName}(${item.facilityCode || '-'})`" |
| | | :value="item.id" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="巡检人" |
| | | prop="inspectorId"> |
| | | <el-select v-model="taskForm.inspectorId" |
| | | placeholder="请选择巡检人" |
| | | filterable |
| | | clearable |
| | | style="width: 100%"> |
| | | <el-option v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="是否启用" |
| | | prop="isEnabled"> |
| | | <el-radio-group v-model="taskForm.isEnabled"> |
| | | <el-radio :label="1">是</el-radio> |
| | | <el-radio :label="0">否</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="巡检项目" |
| | | prop="inspectionProject"> |
| | | <el-input v-model="taskForm.inspectionProject" |
| | | type="textarea" |
| | | :autosize="{ minRows: 3, maxRows: 6 }" |
| | | placeholder="请输入巡检项目" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="备注"> |
| | | <el-input v-model="taskForm.remark" |
| | | type="textarea" |
| | | :autosize="{ minRows: 3, maxRows: 6 }" |
| | | placeholder="请输入备注" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务频率" |
| | | prop="frequencyType"> |
| | | <el-select v-model="taskForm.frequencyType" |
| | | placeholder="请选择" |
| | | clearable |
| | | style="width: 100%" |
| | | @change="handleFrequencyTypeChange"> |
| | | <el-option label="每日" value="DAILY" /> |
| | | <el-option label="每周" value="WEEKLY" /> |
| | | <el-option label="每月" value="MONTHLY" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col v-if="taskForm.frequencyType === 'DAILY'" :span="12"> |
| | | <el-form-item class="frequency-detail-item" |
| | | label="执行时间" |
| | | prop="frequencyDetail"> |
| | | <el-time-picker v-model="taskForm.frequencyDetail" |
| | | placeholder="选择时间" |
| | | format="HH:mm" |
| | | value-format="HH:mm" |
| | | style="width: 100%" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col v-if="taskForm.frequencyType === 'WEEKLY'" :span="12"> |
| | | <el-form-item class="frequency-detail-item" |
| | | label="执行时间" |
| | | prop="frequencyDetail"> |
| | | <div class="frequency-row"> |
| | | <el-select v-model="taskForm.week" |
| | | class="frequency-day-select" |
| | | placeholder="请选择星期" |
| | | clearable> |
| | | <el-option v-for="item in weekOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | <el-time-picker v-model="taskForm.time" |
| | | class="frequency-time-picker" |
| | | placeholder="选择时间" |
| | | format="HH:mm" |
| | | value-format="HH:mm" /> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col v-if="taskForm.frequencyType === 'MONTHLY'" :span="12"> |
| | | <el-form-item class="frequency-detail-item" |
| | | label="执行时间" |
| | | prop="frequencyDetail"> |
| | | <div class="frequency-row"> |
| | | <el-select v-model="taskForm.day" |
| | | class="frequency-day-select" |
| | | placeholder="请选择日期" |
| | | clearable> |
| | | <el-option v-for="item in dayOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | <el-time-picker v-model="taskForm.time" |
| | | class="frequency-time-picker" |
| | | placeholder="选择时间" |
| | | format="HH:mm" |
| | | value-format="HH:mm" /> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" |
| | | @click="submitTaskForm">保存</el-button> |
| | | <el-button @click="taskDialogVisible = false">取消</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 巡检任务详情 --> |
| | | <el-dialog v-model="taskDetailVisible" |
| | | title="巡检任务详情" |
| | | width="860px"> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="巡检任务名称">{{ taskDetail.inspectionName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="安全设施">{{ taskDetail.facilityName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="设施编号">{{ taskDetail.facilityCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="巡检人">{{ taskDetail.inspectorName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="是否启用">{{ taskDetail.isEnabled === 1 ? '是' : '否' }}</el-descriptions-item> |
| | | <el-descriptions-item label="频次">{{ frequencyTypeMap[taskDetail.frequencyType] || taskDetail.frequencyType || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="执行时间">{{ formatFrequencyDetail(taskDetail.frequencyDetail) }}</el-descriptions-item> |
| | | <el-descriptions-item label="下次执行时间">{{ taskDetail.nextExecutionTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="巡检项目" :span="2">{{ taskDetail.inspectionProject || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="备注" :span="2">{{ taskDetail.remark || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" @click="taskDetailVisible = false">关闭</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 历史巡检记录 --> |
| | | <el-dialog v-model="taskHistoryVisible" |
| | | title="历史巡检记录" |
| | | width="1100px"> |
| | | <el-descriptions class="history-summary" :column="3" border> |
| | | <el-descriptions-item label="巡检任务名称">{{ taskHistoryTask.inspectionName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="安全设施">{{ taskHistoryTask.facilityName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="频次">{{ frequencyTypeMap[taskHistoryTask.frequencyType] || taskHistoryTask.frequencyType || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <PIMTable rowKey="id" |
| | | :column="taskHistoryTableColumn" |
| | | :tableData="taskHistoryTableData" |
| | | :page="taskHistoryPage" |
| | | :isSelection="false" |
| | | :tableLoading="taskHistoryTableLoading" |
| | | @pagination="taskHistoryPagination" |
| | | :total="taskHistoryPage.total"></PIMTable> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" @click="taskHistoryVisible = false">关闭</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | 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="检查结果" |
| | |
| | | type="primary" |
| | | @click="submitInspectionForm">确定</el-button> |
| | | <el-button @click="inspectionDialogVisible = false">{{ isInspectionView ? '关闭' : '取消' }}</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 巡检详情弹窗 --> |
| | | <el-dialog v-model="inspectionDetailVisible" |
| | | title="巡检详情" |
| | | width="920px" |
| | | class="detail-dialog"> |
| | | <el-descriptions :column="3" border> |
| | | <el-descriptions-item label="巡检编号">{{ inspectionDetail.inspectionCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="设施名称">{{ inspectionDetail.facilityName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="巡检人">{{ inspectionDetail.inspectorName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="计划巡检时间">{{ inspectionDetail.planTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="实际巡检时间">{{ inspectionDetail.actualTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="状态"> |
| | | <el-tag :type="inspectionStatusType(inspectionDetail.status)">{{ inspectionDetail.status || '-' }}</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="检查结果"> |
| | | <el-tag :type="inspectionResultType(inspectionDetail.checkResult)">{{ inspectionDetail.checkResult || '未填写' }}</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="巡检项目" :span="2">{{ inspectionDetail.inspectionProject || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="检查说明" :span="3">{{ inspectionDetail.checkDesc || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <div v-if="inspectionDetailImageUrls.length" class="detail-section"> |
| | | <div class="detail-section-title">现场照片</div> |
| | | <div class="detail-image-list"> |
| | | <el-image v-for="(url, index) in inspectionDetailImageUrls" |
| | | :key="`${url}-${index}`" |
| | | :src="url" |
| | | :preview-src-list="inspectionDetailImageUrls" |
| | | :initial-index="index" |
| | | fit="cover" |
| | | class="detail-image" /> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" @click="inspectionDetailVisible = false">关闭</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 整改详情弹窗 --> |
| | | <el-dialog v-model="rectificationDetailVisible" |
| | | title="整改详情" |
| | | width="920px" |
| | | class="detail-dialog"> |
| | | <el-descriptions :column="3" border> |
| | | <el-descriptions-item label="巡检编号">{{ rectificationDetail.inspectionCode || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="设施名称">{{ rectificationDetail.facilityName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="问题等级"> |
| | | <el-tag :type="rectificationLevelType(rectificationDetail.problemLevel)"> |
| | | {{ rectificationDetail.problemLevel || '-' }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="整改责任人">{{ rectificationDetail.rectifyUserName || getUserName(rectificationDetail.rectifyUserId) || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="计划整改时间">{{ rectificationDetail.planTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="实际整改时间">{{ rectificationDetail.actualTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="状态"> |
| | | <el-tag :type="rectificationStatusType(rectificationDetail.status)">{{ rectificationDetail.status || '-' }}</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="验收人">{{ rectificationDetail.verifyUserName || getUserName(rectificationDetail.verifyUserId) || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="验收时间">{{ rectificationDetail.verifyTime || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="问题描述" :span="3">{{ rectificationDetail.problemDesc || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="整改说明" :span="3">{{ rectificationDetail.rectifyDesc || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="验收说明" :span="3">{{ rectificationDetail.verifyDesc || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <div v-if="rectificationDetailImageUrls.length" class="detail-section"> |
| | | <div class="detail-section-title">巡检异常图片</div> |
| | | <div class="detail-image-list"> |
| | | <el-image v-for="(url, index) in rectificationDetailImageUrls" |
| | | :key="`${url}-${index}`" |
| | | :src="url" |
| | | :preview-src-list="rectificationDetailImageUrls" |
| | | :initial-index="index" |
| | | fit="cover" |
| | | class="detail-image" /> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" @click="rectificationDetailVisible = false">关闭</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | addFacilityLedger, |
| | | updateFacilityLedger, |
| | | deleteFacilityLedger, |
| | | getFacilityInspectionTaskList, |
| | | addFacilityInspectionTask, |
| | | updateFacilityInspectionTask, |
| | | deleteFacilityInspectionTask, |
| | | getFacilityInspectionList, |
| | | addFacilityInspection, |
| | | updateFacilityInspection, |
| | | deleteFacilityInspection, |
| | | getFacilityRectificationList, |
| | |
| | | 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 = { |
| | |
| | | facilityName: [{ required: true, message: "请输入设施名称", trigger: "blur" }], |
| | | facilityType: [{ required: true, message: "请选择设施类型", trigger: "change" }], |
| | | installLocation: [{ required: true, message: "请输入安装位置", trigger: "blur" }] |
| | | }; |
| | | |
| | | const taskRules = { |
| | | inspectionName: [{ required: true, message: "请输入巡检任务名称", trigger: "blur" }], |
| | | facilityId: [{ required: true, message: "请选择安全设施", trigger: "change" }], |
| | | inspectionProject: [{ required: true, message: "请输入巡检项目", trigger: "blur" }], |
| | | inspectorId: [{ required: true, message: "请选择巡检人", trigger: "change" }], |
| | | frequencyType: [{ required: true, message: "请选择任务频率", trigger: "change" }], |
| | | frequencyDetail: [{ required: true, validator: validateFrequencyDetail, trigger: "change" }] |
| | | }; |
| | | |
| | | const inspectionRules = { |
| | |
| | | ledgerSelectedIds: [], |
| | | ledgerForm: { |
| | | id: null, facilityCode: "", facilityName: "", facilityType: "", facilitySpec: "", |
| | | installLocation: "", installTime: "", productionDate: "", validPeriod: null, |
| | | installLocation: "", installTime: "", productionDate: "", |
| | | status: "正常", remark: "" |
| | | }, |
| | | ledgerDialogVisible: false, |
| | | ledgerDialogTitle: "", |
| | | ledgerDialogType: "add", |
| | | ledgerDetailVisible: false, |
| | | ledgerDetail: {}, |
| | | // 巡检任务 |
| | | taskSearchForm: { inspectionName: "", facilityName: "", isEnabled: "" }, |
| | | taskTableLoading: false, |
| | | taskPage: { current: 1, size: 20, total: 0 }, |
| | | taskTableData: [], |
| | | taskSelectedIds: [], |
| | | taskForm: createTaskForm(), |
| | | taskDialogVisible: false, |
| | | taskDialogTitle: "新增巡检任务", |
| | | taskDetailVisible: false, |
| | | taskDetail: {}, |
| | | taskHistoryVisible: false, |
| | | taskHistoryTask: {}, |
| | | taskHistoryTableLoading: false, |
| | | taskHistoryPage: { current: 1, size: 10, total: 0 }, |
| | | taskHistoryTableData: [], |
| | | facilityOptions: [], |
| | | // 巡检记录 |
| | | inspectionSearchForm: { inspectionCode: "", status: "" }, |
| | | inspectionTableLoading: false, |
| | | inspectionPage: { current: 1, size: 20, total: 0 }, |
| | | inspectionTableData: [], |
| | | inspectionForm: { |
| | | id: null, facilityId: null, inspectionCode: "", inspectionType: "定期巡检", |
| | | facilityCode: "", facilityName: "", planTime: "", checkResult: "", checkDesc: "", storageBlobDTOs: [] |
| | | 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, |
| | |
| | | }, |
| | | 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 isLedgerView = computed(() => ledgerDialogType.value === "view"); |
| | | const isInspectionView = computed(() => inspectionDialogType.value === "view"); |
| | | const isInspectionBaseReadonly = computed(() => inspectionDialogType.value !== "add"); |
| | | const isRectificationView = computed(() => rectificationDialogType.value === "view"); |
| | |
| | | const list = rectificationForm.value.storageBlobVOs || rectificationForm.value.storageBlobDTOs || []; |
| | | return list.map(getAttachmentUrl).filter(Boolean); |
| | | }); |
| | | |
| | | // 自动计算下次检查时间 |
| | | const computedNextCheckTime = computed(() => { |
| | | const { installTime, validPeriod } = ledgerForm.value; |
| | | if (!installTime || !validPeriod) return ""; |
| | | const date = new Date(installTime); |
| | | date.setDate(date.getDate() + validPeriod); |
| | | return date.toISOString().split("T")[0]; |
| | | const inspectionDetailImageUrls = computed(() => { |
| | | const list = inspectionDetail.value.storageBlobVOs || inspectionDetail.value.storageBlobDTOs || []; |
| | | return list.map(getAttachmentUrl).filter(Boolean); |
| | | }); |
| | | const rectificationDetailImageUrls = computed(() => { |
| | | const list = rectificationDetail.value.storageBlobVOs || rectificationDetail.value.storageBlobDTOs || []; |
| | | return list.map(getAttachmentUrl).filter(Boolean); |
| | | }); |
| | | |
| | | const ledgerStatusType = value => { |
| | | const map = { 正常: "success", 异常: "danger", 报废: "info" }; |
| | | return map[value] || "info"; |
| | | }; |
| | | const inspectionResultType = value => { |
| | | const map = { 正常: "success", 异常: "danger", 未填写: "info" }; |
| | | return map[value || "未填写"] || "info"; |
| | | }; |
| | | const inspectionStatusType = value => value === "待巡检" ? "info" : "success"; |
| | | const rectificationLevelType = value => value === "重大" ? "danger" : "warning"; |
| | | const rectificationStatusType = value => { |
| | | const map = { 待整改: "danger", 整改中: "warning", 已整改: "success", 已验收: "info" }; |
| | | return map[value] || "info"; |
| | | }; |
| | | |
| | | const padTime = value => String(value).padStart(2, "0"); |
| | | const formatDateTime = (date = new Date()) => { |
| | | const target = date instanceof Date ? date : new Date(date); |
| | | return `${target.getFullYear()}-${padTime(target.getMonth() + 1)}-${padTime(target.getDate())} ${padTime(target.getHours())}:${padTime(target.getMinutes())}:${padTime(target.getSeconds())}`; |
| | | }; |
| | | const formatCompactDateTime = (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())}`; |
| | | }; |
| | | const addDaysDateTime = days => { |
| | | const target = new Date(); |
| | |
| | | target.setHours(18, 0, 0, 0); |
| | | return formatDateTime(target); |
| | | }; |
| | | const getDefaultPlanTime = row => { |
| | | if (row?.nextCheckTime) return `${row.nextCheckTime} 09:00:00`; |
| | | return formatDateTime(); |
| | | }; |
| | | const buildInspectionCode = row => { |
| | | const code = row?.facilityCode || "FAC"; |
| | | return `XJ-${code}-${formatCompactDateTime()}`; |
| | | }; |
| | | const getUserName = userId => { |
| | | const user = userList.value.find(item => Number(item.userId) === Number(userId)); |
| | | return user?.nickName || ""; |
| | | }; |
| | | const isScrappedFacility = row => row?.status === "报废"; |
| | | 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 === "异常"; |
| | |
| | | row?.verifyUserId && Number(row.verifyUserId) !== Number(currentUserId.value); |
| | | |
| | | provide("parentMethods", { |
| | | openLedgerDetail: row => openLedgerForm("view", row) |
| | | openLedgerDetail: row => openLedgerDetail(row), |
| | | openTaskDetail: row => openTaskDetail(row), |
| | | openInspectionDetail: row => openInspectionDetail(row) |
| | | }); |
| | | |
| | | // 设施台账表格列配置 |
| | |
| | | }, |
| | | { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150 , align: "center"}, |
| | | { label: "设施类型", prop: "facilityType", showOverflowTooltip: true, minWidth: 120 , align: "center"}, |
| | | { label: "规格型号", prop: "facilitySpec", showOverflowTooltip: true, minWidth: 120 , align: "center"}, |
| | | { label: "安装位置", prop: "installLocation", showOverflowTooltip: true, minWidth: 150 , align: "center"}, |
| | | { label: "安装时间", prop: "installTime", minWidth: 120 , align: "center"}, |
| | | { label: "下次检查时间", prop: "nextCheckTime", minWidth: 120 , align: "center"}, |
| | | { |
| | | label: "状态", prop: "status", minWidth: 100, dataType: "tag", align: "center", |
| | | formatType: params => { |
| | |
| | | } |
| | | }, |
| | | { |
| | | dataType: "action", label: "操作", align: "center", fixed: "right", width: 190, |
| | | dataType: "action", label: "操作", align: "center", fixed: "right", width: 140, |
| | | operation: [ |
| | | { name: "编辑", type: "text", clickFun: row => openLedgerForm("edit", row) }, |
| | | { |
| | | name: "发起巡检", |
| | | type: "text", |
| | | show: row => !isScrappedFacility(row), |
| | | clickFun: row => openInspectionForm("add", row) |
| | | }, |
| | | { name: "删除", type: "text", clickFun: row => handleDeleteLedger(row) } |
| | | ] |
| | | } |
| | | ]); |
| | | |
| | | // 巡检任务表格列配置 |
| | | const taskTableColumn = ref([ |
| | | { |
| | | label: "巡检任务名称", |
| | | prop: "inspectionName", |
| | | dataType: "link", |
| | | linkMethod: "openTaskDetail", |
| | | showOverflowTooltip: true, |
| | | minWidth: 170, |
| | | align: "left" |
| | | }, |
| | | { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 155, align: "left" }, |
| | | { label: "巡检项目", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 190, align: "left" }, |
| | | { label: "执行巡检人", prop: "inspectorName", minWidth: 120, align: "center" }, |
| | | { |
| | | label: "是否启用", |
| | | prop: "isEnabled", |
| | | minWidth: 90, |
| | | align: "center", |
| | | dataType: "tag", |
| | | formatData: value => value === 1 ? "是" : "否", |
| | | formatType: value => value === 1 ? "success" : "info" |
| | | }, |
| | | { |
| | | label: "频次", |
| | | prop: "frequencyType", |
| | | minWidth: 90, |
| | | align: "center", |
| | | formatData: value => frequencyTypeMap[value] || value || "--" |
| | | }, |
| | | { |
| | | label: "执行时间", |
| | | prop: "frequencyDetail", |
| | | minWidth: 120, |
| | | align: "center", |
| | | formatData: value => formatFrequencyDetail(value) |
| | | }, |
| | | { label: "下次执行时间", prop: "nextExecutionTime", minWidth: 170, showOverflowTooltip: true, align: "center" }, |
| | | { |
| | | dataType: "action", label: "操作", align: "center", fixed: "right", width: 220, |
| | | operation: [ |
| | | { name: "历史巡检", type: "text", clickFun: row => openTaskHistory(row) }, |
| | | { name: "编辑", type: "text", clickFun: row => openTaskDialog("edit", row) }, |
| | | { name: "删除", type: "text", clickFun: row => handleDeleteTask(row) } |
| | | ] |
| | | } |
| | | ]); |
| | | |
| | | const taskHistoryTableColumn = ref([ |
| | | { |
| | | label: "巡检编号", |
| | | prop: "inspectionCode", |
| | | dataType: "link", |
| | | linkMethod: "openInspectionDetail", |
| | | showOverflowTooltip: true, |
| | | minWidth: 180, |
| | | align: "center" |
| | | }, |
| | | { label: "设施名称", prop: "facilityName", showOverflowTooltip: true, minWidth: 150, align: "left" }, |
| | | { label: "巡检项目", prop: "inspectionProject", showOverflowTooltip: true, minWidth: 180, align: "left" }, |
| | | { label: "计划巡检时间", prop: "planTime", minWidth: 170, align: "center" }, |
| | | { label: "巡检人", prop: "inspectorName", minWidth: 110, align: "center" }, |
| | | { label: "实际巡检时间", prop: "actualTime", minWidth: 170, align: "center" }, |
| | | { |
| | | label: "检查结果", prop: "checkResult", minWidth: 100, align: "center", dataType: "tag", |
| | | formatData: params => params || "未填写", |
| | | formatType: params => { |
| | | const map = { 正常: "success", 异常: "danger", 未填写: "info" }; |
| | | return map[params] || "info"; |
| | | } |
| | | }, |
| | | { |
| | | label: "状态", prop: "status", minWidth: 100, align: "center", dataType: "tag", |
| | | formatType: params => params === "待巡检" ? "info" : "success" |
| | | } |
| | | ]); |
| | | |
| | |
| | | const inspectionTableColumn = ref([ |
| | | { |
| | | label: "巡检编号", |
| | | dataType: "link", |
| | | linkMethod: "openInspectionDetail", |
| | | width: 200, |
| | | align: "center", |
| | | prop: "inspectionCode", |
| | |
| | | minWidth: 150 |
| | | }, |
| | | { |
| | | label: "设施编号", |
| | | prop: "facilityCode", |
| | | label: "巡检项目", |
| | | prop: "inspectionProject", |
| | | showOverflowTooltip: true, |
| | | minWidth: 120 |
| | | }, |
| | | { |
| | | label: "巡检类型", |
| | | prop: "inspectionType", |
| | | minWidth: 100 |
| | | minWidth: 180 |
| | | }, |
| | | { |
| | | label: "计划巡检时间", |
| | |
| | | }, |
| | | { |
| | | name: "查看", type: "text", |
| | | clickFun: row => openInspectionForm("view", row), |
| | | clickFun: row => openInspectionDetail(row), |
| | | show: isCheckedInspection |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { label: "整改责任人", prop: "rectifyUserName", minWidth: 120 }, |
| | | { label: "计划整改时间", prop: "planTime", minWidth: 180 }, |
| | | { label: "实际整改时间", prop: "actualTime", minWidth: 180 }, |
| | | { |
| | | label: "状态", prop: "status", minWidth: 100, dataType: "tag", |
| | | formatType: params => { |
| | |
| | | return map[params] || "info"; |
| | | } |
| | | }, |
| | | { label: "验收人", prop: "verifyUserName", minWidth: 120 }, |
| | | { label: "验收时间", prop: "verifyTime", minWidth: 180 }, |
| | | { |
| | | dataType: "action", label: "操作", align: "center", fixed: "right", width: 180, |
| | | operation: [ |
| | |
| | | show: isRectified, |
| | | disabled: isNotAssignedVerifier |
| | | }, |
| | | { name: "查看", type: "text", clickFun: row => openRectificationForm("view", row) } |
| | | { name: "查看", type: "text", clickFun: row => openRectificationDetail(row) } |
| | | ] |
| | | } |
| | | ]); |
| | |
| | | // 生命周期 |
| | | onMounted(() => { |
| | | getLedgerList(); |
| | | getTaskList(); |
| | | getInspectionList(); |
| | | getRectificationList(); |
| | | getFacilityOptionList(); |
| | | getUserList(); |
| | | }); |
| | | |
| | | // 标签页切换 |
| | | const handleTabClick = () => { |
| | | if (activeTab.value === "ledger") getLedgerList(); |
| | | else if (activeTab.value === "task") getTaskList(); |
| | | else if (activeTab.value === "inspection") getInspectionList(); |
| | | else if (activeTab.value === "rectification") getRectificationList(); |
| | | }; |
| | |
| | | const getUserList = () => { |
| | | userListNoPage().then(res => { |
| | | userList.value = res.data || []; |
| | | }); |
| | | }; |
| | | |
| | | const getFacilityOptionList = () => { |
| | | getFacilityLedgerList({ current: 1, size: 1000 }).then(res => { |
| | | facilityOptions.value = (res.data?.records || []).filter(item => item.status !== "报废"); |
| | | }); |
| | | }; |
| | | |
| | |
| | | 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: "正常", remark: "" |
| | | }); |
| | | } else if (type === "view") { |
| | | ledgerDialogTitle.value = "设施详情"; |
| | | Object.assign(ledgerForm.value, { ...row }); |
| | | } else { |
| | | ledgerDialogTitle.value = "编辑设施"; |
| | | Object.assign(ledgerForm.value, { ...row }); |
| | |
| | | const submitLedgerForm = async () => { |
| | | try { |
| | | await ledgerFormRef.value.validate(); |
| | | // 自动计算下次检查时间 |
| | | ledgerForm.value.nextCheckTime = computedNextCheckTime.value || null; |
| | | const api = ledgerDialogType.value === "add" ? addFacilityLedger : updateFacilityLedger; |
| | | const res = await api({ ...ledgerForm.value }); |
| | | if (res.code === 200) { |
| | | ElMessage.success(ledgerDialogType.value === "add" ? "添加成功" : "更新成功"); |
| | | ledgerDialogVisible.value = false; |
| | | getLedgerList(); |
| | | getFacilityOptionList(); |
| | | } else { |
| | | ElMessage.error(res.msg || "操作失败"); |
| | | } |
| | |
| | | if (res.code === 200) { |
| | | ElMessage.success("删除成功"); |
| | | getLedgerList(); |
| | | getFacilityOptionList(); |
| | | } else { |
| | | ElMessage.error(res.msg || "删除失败"); |
| | | } |
| | |
| | | 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(); |
| | | }; |
| | | |
| | | // ============ 巡检记录方法 ============ |
| | |
| | | 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, |
| | | facilityCode: row.facilityCode, |
| | | facilityName: row.facilityName, |
| | | inspectionCode: buildInspectionCode(row), |
| | | inspectionType: "定期巡检", |
| | | planTime: getDefaultPlanTime(row), |
| | | checkResult: "", |
| | | checkDesc: "", |
| | | storageBlobDTOs: [] |
| | | }); |
| | | } else if (type === "do") { |
| | | if (type === "do") { |
| | | inspectionDialogTitle.value = "巡检"; |
| | | Object.assign(inspectionForm.value, { |
| | | id: row.id, |
| | | scheduleTaskId: row.scheduleTaskId, |
| | | facilityId: row.facilityId, |
| | | facilityCode: row.facilityCode, |
| | | facilityName: row.facilityName, |
| | | inspectionCode: row.inspectionCode, |
| | | inspectionType: row.inspectionType, |
| | | inspectionProject: row.inspectionProject, |
| | | planTime: row.planTime, |
| | | checkResult: "", |
| | | checkDesc: "", |
| | | storageBlobDTOs: [] |
| | | }); |
| | | } else { |
| | | inspectionDialogTitle.value = "查看巡检"; |
| | | Object.assign(inspectionForm.value, { ...row, storageBlobDTOs: row.storageBlobVOs || row.storageBlobDTOs || [] }); |
| | | } |
| | | inspectionDialogVisible.value = true; |
| | | }; |
| | |
| | | inspectionForm.value.status = "已巡检"; |
| | | 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; |
| | | if (inspectionDialogType.value === "add") { |
| | | activeTab.value = "inspection"; |
| | | } |
| | | getInspectionList(); |
| | | if (inspectionDialogType.value === "do" && inspectionForm.value.checkResult === "异常") { |
| | | ElMessageBox.confirm("本次巡检结果为异常,是否立即创建整改跟踪?", "创建整改", { |
| | |
| | | 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"; |
| | |
| | | }; |
| | | |
| | | const openRectificationForm = (type, row = null) => { |
| | | if (type === "view") { |
| | | openRectificationDetail(row); |
| | | return; |
| | | } |
| | | rectificationDialogType.value = type; |
| | | if (type === "add") { |
| | | rectificationDialogTitle.value = "新增整改"; |
| | |
| | | padding-top: 6px; |
| | | } |
| | | |
| | | .history-summary { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .table_list :deep(.link) { |
| | | color: var(--el-color-primary); |
| | | cursor: pointer; |
| | |
| | | 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 { |