| | |
| | | <el-dialog v-model="detailVisible" title="工单详情" width="80%" append-to-body> |
| | | <div class="detail-container"> |
| | | <div class="event-title-center">{{ currentDetail.orderName || '事件名称' }}</div> |
| | | <div v-if="totalTime" class="event-total-time" |
| | | style="text-align:center;color:#666;font-size:15px;margin-bottom:12px;"> |
| | | 总耗时:{{ totalTime }} |
| | | </div> |
| | | <!-- 工单状态流程 --> |
| | | <div class="custom-steps-container"> |
| | | <!-- 标题行 --> |
| | |
| | | style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span> |
| | | </el-upload> |
| | | <div class="el-upload__tip" style="margin-top: 12px;" v-if="hasProcessedAndOverBtnPermission()"> |
| | | 支持 jpg/png 格式图片,单张不超过 5MB |
| | | (上传照片即可完结工单,只能上传jpg、jpeg、png照片,且不超过5M) |
| | | </div> |
| | | </div> |
| | | <!-- 图片和地图部分 --> |
| | |
| | | <div class="media-box"> |
| | | <div class="media-title">事件图片</div> |
| | | <div class="media-content"> |
| | | <el-image |
| | | v-if="currentDetail.mediaUrl" |
| | | :src="getThumbUrl(currentDetail.mediaUrl)" |
| | | :preview-src-list="[currentDetail.mediaUrl]" |
| | | fit="cover" |
| | | style="width: 100%; height: 300px; cursor: pointer;" |
| | | > |
| | | <el-image v-if="currentDetail.mediaUrl" :src="getThumbUrl(currentDetail.mediaUrl)" |
| | | :preview-src-list="[currentDetail.mediaUrl]" fit="contain" |
| | | style="width: 700px; height: 520px; cursor: pointer;"> |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | | <i class="el-icon-picture-outline"></i> |
| | |
| | | <template v-if="currentDetail.status === 5"> |
| | | <div class="media-title">工单处理图片</div> |
| | | <div class="media-content"> |
| | | <el-image |
| | | v-if="currentDetail.updatePhotoUrl" |
| | | :src="getThumbUrl(currentDetail.updatePhotoUrl)" |
| | | :preview-src-list="[currentDetail.updatePhotoUrl]" |
| | | fit="cover" |
| | | style="width: 100%; height: 300px; cursor: pointer;" |
| | | > |
| | | <el-image v-if="currentDetail.updatePhotoUrl" :src="getThumbUrl(currentDetail.updatePhotoUrl)" |
| | | :preview-src-list="[currentDetail.updatePhotoUrl]" fit="fill" |
| | | style="width: 700px; height: 520px; cursor: pointer;"> |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | | <i class="el-icon-picture-outline"></i> |
| | |
| | | <template v-else> |
| | | <div class="media-title">地图标记事件点</div> |
| | | <div class="media-content"> |
| | | <div id="map-container" style="width: 100%; height: 300px; background: #f5f5f5;"> |
| | | <div id="map-container" style="width: 700px; height: 520px; background: #f5f5f5;"> |
| | | <map-container v-if='detailVisible' ref="MapContainer"></map-container> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="dialog-footer"> |
| | | <template v-if="currentDetail.status === 2"> |
| | | <!-- 待审核 --> |
| | | <el-button v-if="hasReviewBtnPermission()" type="primary" :loading="approveLoading" @click="approveTicket">通过</el-button> |
| | | <el-button v-if="hasReviewBtnPermission()" type="danger" :loading="rejectLoading" @click="rejectTicket">不通过</el-button> |
| | | <el-button v-if="hasReviewBtnPermission()" type="primary" :loading="approveLoading" |
| | | @click="approveTicket">通过</el-button> |
| | | <el-button v-if="hasReviewBtnPermission()" type="danger" :loading="rejectLoading" |
| | | @click="rejectTicket">不通过</el-button> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 0"> |
| | | <el-button v-if="hasProcessingBtnPermission()" type="primary" :loading="dispatchLoading" @click="approveAndDispatch">通过并派发</el-button> |
| | | <el-button v-if="hasProcessingBtnPermission()" type="danger" :loading="rejectLoading" @click="rejectTicket">不通过</el-button> |
| | | <el-button v-if="hasProcessingBtnPermission()" type="primary" :loading="dispatchLoading" |
| | | @click="approveAndDispatch">通过并派发</el-button> |
| | | <el-button v-if="hasProcessingBtnPermission()" type="danger" :loading="rejectLoading" |
| | | @click="rejectTicket">不通过</el-button> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <!-- 处理中 --> |
| | | <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="completeLoading" @click="completeTicket">完成工单</el-button> |
| | | <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="completeLoading" |
| | | @click="completeTicket">完成工单</el-button> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 4"> |
| | | <!-- 已完成 --> |
| | | <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="finalizeLoading" @click="finalizeTicket">完结工单</el-button> |
| | | <el-button v-if="hasProcessedAndOverBtnPermission()" type="primary" :loading="finalizeLoading" |
| | | @click="finalizeTicket">完结工单</el-button> |
| | | <el-button @click="detailVisible = false">取消</el-button> |
| | | </template> |
| | | <template v-else-if="currentDetail.status === 5"> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- 添加在其他 dialog 组件之后 --> |
| | | <el-dialog v-model="reviewDialogVisible" title="批量审核" width="70%" append-to-body custom-class="review-dialog"> |
| | | <el-dialog v-model="reviewDialogVisible" title="批量审核" width="70%" append-to-body custom-class="review-dialog" @close="cancleBatchReject"> |
| | | <div class="review-container"> |
| | | <div class="review-image-wrapper"> |
| | | <!-- 修改左右箭头的显示条件 --> |
| | |
| | | </div> |
| | | |
| | | <div class="review-image-container"> |
| | | <el-image |
| | | v-if="currentReviewImage" |
| | | :src="getThumbUrl(currentReviewImage)" |
| | | fit="cover" |
| | | :preview-src-list="getImageList()" |
| | | :initial-index="currentImageIndex - 1" |
| | | class="preview-image" |
| | | style="cursor: pointer;" |
| | | > |
| | | <el-image v-if="currentReviewImage" :src="getThumbUrl(currentReviewImage)" fit="fill" |
| | | :preview-src-list="getImageList()" :initial-index="currentImageIndex - 1" class="preview-image" |
| | | style="cursor: pointer;"> |
| | | <template #error> |
| | | <div class="image-error"> |
| | | <i class="el-icon-picture-outline"></i> |
| | |
| | | selection: true, // 添加多选功能 |
| | | index: true, // 保留序号功能 |
| | | indexLabel: '序号', |
| | | indexWidth: 60, |
| | | indexWidth: 60, |
| | | menuWidth: 150, |
| | | searchMenuSpan: 6, |
| | | viewBtn: false, |
| | |
| | | reviewDialogVisible: false, // 新增:审核对话框可见性 |
| | | currentReviewImage: '', // 新增:当前审核图片 |
| | | currentImageIndex: 1, // 新增:当前图片索引 |
| | | totalTime: '', |
| | | isShowInfo: false, |
| | | }; |
| | | }, |
| | |
| | | isPass: 0, |
| | | eventNum: currentItem.orderNumber, |
| | | eventName: currentItem.orderName, |
| | | eventType: currentItem.type, |
| | | }; |
| | | |
| | | const response = await flowEvent(data); |
| | |
| | | }, |
| | | |
| | | async fetchTabCounts() { |
| | | try { |
| | | // 判断是否有部门筛选 |
| | | let params = {}; |
| | | if (this.filters.department) { |
| | | params.deptId = this.filters.department; |
| | | } |
| | | const response = await getstatusCount(params); |
| | | const { statusCount, totalCount, userCount } = response.data.data; |
| | | this.tabs.forEach(tab => { |
| | | if (tab.name === 'all') { |
| | | tab.count = totalCount || 0; // 总工单数 |
| | | } else if (tab.name === 'myTickets') { |
| | | tab.count = userCount || 0; // 我发起的工单数 |
| | | } else { |
| | | tab.count = statusCount[String(tab.value)] || 0; // 根据状态值映射 |
| | | try { |
| | | // 判断是否有部门筛选 |
| | | let params = {}; |
| | | if (this.filters.department) { |
| | | params.deptId = this.filters.department; |
| | | } |
| | | const response = await getstatusCount(params); |
| | | const { statusCount, totalCount, userCount } = response.data.data; |
| | | this.tabs.forEach(tab => { |
| | | if (tab.name === 'all') { |
| | | tab.count = totalCount || 0; // 总工单数 |
| | | } else if (tab.name === 'myTickets') { |
| | | tab.count = userCount || 0; // 我发起的工单数 |
| | | } else { |
| | | tab.count = statusCount[String(tab.value)] || 0; // 根据状态值映射 |
| | | } |
| | | }); |
| | | } catch (error) { |
| | | this.$message.error('获取 tab 数据失败'); |
| | | } |
| | | }); |
| | | } catch (error) { |
| | | this.$message.error('获取 tab 数据失败'); |
| | | } |
| | | }, |
| | | }, |
| | | |
| | | handleTabChange(tab) { |
| | | this.activeTab = tab.props?.name || tab.name; |
| | |
| | | const steps = Array.isArray(stepResponse.data.data) |
| | | ? stepResponse.data.data |
| | | : stepResponse.data.data?.steps || []; |
| | | const finishedStep = steps.find(s => String(s.status) === '5'); |
| | | this.totalTime = finishedStep && finishedStep.total_time ? finishedStep.total_time : ''; |
| | | if (this.activeTab !== 'myTickets') { |
| | | this.stepInfos = steps.map(step => ({ |
| | | status: String(step.status), |
| | |
| | | status: this.currentDetail.status, |
| | | isPass: 0, // 0 表示通过 |
| | | eventNum: this.currentDetail.orderNumber, |
| | | eventName: this.currentDetail.orderName, // 工单名称 |
| | | eventType: this.currentDetail.type, // 工单类型 |
| | | departmentId: this.dispatchForm.department, // 派发部门 ID |
| | | handlerId: this.dispatchForm.handler, // 处理人 ID |
| | | }; |
| | | |
| | | const file = this.currentDetail.file || null; // 如果没有文件,则为 null |
| | |
| | | try { |
| | | // 检查是否上传了图片 |
| | | if (!this.currentDetail.photos || !this.currentDetail.photos.length) { |
| | | this.$message.warning('请上传处理图片'); |
| | | this.$message.warning('请上传事件处理照片,或飞行任务结束核验工单是否完结'); |
| | | return; |
| | | } |
| | | |
| | |
| | | status: currentItem.status, |
| | | isPass: 0, |
| | | eventNum: currentItem.orderNumber, |
| | | eventName: currentItem.orderName, |
| | | eventType: currentItem.type, |
| | | }; |
| | | console.log('删除前:', this.selections) |
| | | const response = await flowEvent(data); |
| | |
| | | }, |
| | | |
| | | cancleBatchReject() { |
| | | reviewDialogVisible = false; |
| | | this.fetchTableData(); |
| | | this.reviewDialogVisible = false; |
| | | this.selections = []; |
| | | this.currentImageIndex = 1; |
| | | this.currentReviewImage = ''; |
| | | this.fetchTableData(); |
| | | }, |
| | | // 批量审核不通过 |
| | | async handleBatchReject() { |
| | |
| | | return; |
| | | } |
| | | |
| | | await this.$confirm('确认驳回当前工单?', '提示', { |
| | | await this.$confirm('确认该工单审核不通过?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | |
| | | isPass: 1, |
| | | eventNum: currentItem.orderNumber, |
| | | eventName: currentItem.orderName, |
| | | eventType: currentItem.type, |
| | | }; |
| | | |
| | | const response = await flowEvent(data); |
| | |
| | | } |
| | | |
| | | .dialog-footer { |
| | | text-align: right; |
| | | text-align: center; |
| | | padding-top: 16px; |
| | | border-top: 1px solid #ebeef5; |
| | | |
| | |
| | | |
| | | .media-content { |
| | | position: relative; |
| | | height: 300px; |
| | | // height: 300px; |
| | | } |
| | | |
| | | .image-placeholder, |