| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="附件图片" prop="photos" required class="upload-wrapper"> |
| | | <el-upload ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card" |
| | | :on-change="handleFileChange" :on-remove="handleUploadRemove" :before-upload="beforeUpload" |
| | | :file-list="form.photos" :limit="1" accept="image/*" class="uploader"> |
| | | <span |
| | | style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span> |
| | | <el-upload ref="upload" |
| | | :action="'#'" |
| | | :auto-upload="false" |
| | | list-type="picture-card" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleUploadRemove" |
| | | :before-upload="beforeUpload" |
| | | :file-list="form.photos" |
| | | :limit="1" |
| | | accept="image/*" |
| | | class="create-upload"> |
| | | <template v-if="form.photos.length < 1"> |
| | | <i class="el-icon-plus">+</i> |
| | | </template> |
| | | </el-upload> |
| | | <div class="upload-tip">支持jpg/png格式图片,单张不超过5MB</div> |
| | | <div class="upload-tip">需上传含有地址信息的照片(jpg、jpeg、png),且不超过5M</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | |
| | | <!-- 基本信息表格 --> |
| | | <el-table :show-header="false" :data="formattedDetailFields" border style="width: 100%; margin-bottom: 20px;"> |
| | | <el-table-column prop="label1" label="基本信息" width="150" /> |
| | | <el-table-column prop="label1" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | <span v-if="currentDetail.status === 0 && row.label1 === '工单名称'" class="required-label"> |
| | | <span class="required-star">*</span>{{ row.label1 }} |
| | | </span> |
| | | <span v-else>{{ row.label1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修复工单名称可编辑 --> |
| | | <template v-if="currentDetail.status === 0 && row.label1 === '工单名称' && hasProcessingBtnPermission()"> |
| | | <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" /> |
| | | </template> |
| | | <!-- 修复任务接收单位为下拉框 --> |
| | | <template v-else-if="currentDetail.status === 0 && row.label1 === '发起单位'"> |
| | | <el-select v-model="currentDetail.department" placeholder="请选择任务接收单位" @change="handleDepartmentChange"> |
| | | <el-option v-for="item in departments" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" class="required-input" /> |
| | | </template> |
| | | <template v-else>{{ row.value1 }}</template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="label2" label="基本信息" width="150" /> |
| | | <el-table-column prop="label2" label="基本信息" width="150"> |
| | | <template #default="{ row }"> |
| | | <!-- 添加必填星号的标签 --> |
| | | <span v-if="currentDetail.status === 0 && (row.label2 === '工单类型' || row.label2 === '工单内容')" class="required-label"> |
| | | <span class="required-star">*</span>{{ row.label2 }} |
| | | </span> |
| | | <span v-else>{{ row.label2 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修复工单内容可编辑 --> |
| | | <template v-if="currentDetail.status === 0 && row.label2 === '工单内容' && hasProcessingBtnPermission()"> |
| | | <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" /> |
| | | </template> |
| | | <!-- 修复工单类型为下拉框 --> |
| | | <template v-else-if="currentDetail.status === 0 && row.label2 === '工单类型' && hasProcessingBtnPermission()"> |
| | | <el-select v-model="currentDetail.type" placeholder="请选择工单类型"> |
| | | <!-- 修改工单类型和工单内容的显示 --> |
| | | <template v-if="currentDetail.status === 0 && row.label2 === '工单类型' && hasProcessingBtnPermission()"> |
| | | <el-select v-model="currentDetail.type" placeholder="请选择工单类型" class="required-input"> |
| | | <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </template> |
| | | <!-- 修复任务处理人为下拉框 --> |
| | | <template v-else-if="currentDetail.status === 0 && row.label2 === '任务处理人'"> |
| | | <el-select v-model="currentDetail.handler" placeholder="请选择任务处理人" @change="handleHandlerChange"> |
| | | <el-option v-for="user in departmentUsers[currentDetail.department] || []" :key="user.id" |
| | | :label="user.name" :value="user.id" /> |
| | | </el-select> |
| | | <template v-else-if="currentDetail.status === 0 && row.label2 === '工单内容' && hasProcessingBtnPermission()"> |
| | | <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" class="required-input" /> |
| | | </template> |
| | | <template v-else>{{ row.value2 }}</template> |
| | | </template> |
| | |
| | | |
| | | <!-- 事件处理详情 --> |
| | | <div v-if="[3, 4, 5].includes(currentDetail.status)" class="form-section"> |
| | | <div class="section-title">事件处理详情</div> |
| | | <div class="section-title"> |
| | | <!-- 处理中状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 3"> |
| | | <span class="required-label"> |
| | | <span class="required-star">*</span>事件处理详情 |
| | | </span> |
| | | </template> |
| | | <template v-else> |
| | | 事件处理详情 |
| | | </template> |
| | | </div> |
| | | <!-- 处理中状态显示输入框 --> |
| | | <template v-if="currentDetail.status === 3 && hasProcessedAndOverBtnPermission()"> |
| | | <el-input type="textarea" v-model="currentDetail.processingDetail" placeholder="请输入事件处理详情" :rows="4" |
| | |
| | | |
| | | <!-- 上传图片 --> |
| | | <div v-if="[3, 4].includes(currentDetail.status)" class="form-section" style="margin-bottom: 32px;"> |
| | | <div class="section-title" v-if="hasProcessedAndOverBtnPermission()">上传图片</div> |
| | | <el-upload v-if="hasProcessedAndOverBtnPermission()" ref="upload" :action="'#'" :auto-upload="false" |
| | | list-type="picture-card" :on-change="handleFileChange" :on-remove="handleUploadRemove" |
| | | :before-upload="beforeUpload" :file-list="[]" :limit="1" accept="image/*"> |
| | | <span |
| | | style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span> |
| | | <div class="section-title" v-if="hasProcessedAndOverBtnPermission()"> |
| | | <!-- 已完成状态显示必填星号 --> |
| | | <template v-if="currentDetail.status === 4"> |
| | | <span class="required-label"> |
| | | <span class="required-star">*</span>上传图片 |
| | | </span> |
| | | </template> |
| | | <template v-else> |
| | | 上传图片 |
| | | </template> |
| | | </div> |
| | | <el-upload v-if="hasProcessedAndOverBtnPermission()" |
| | | ref="upload" |
| | | :action="'#'" |
| | | :auto-upload="false" |
| | | list-type="picture-card" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleUploadRemove" |
| | | :before-upload="beforeUpload" |
| | | :file-list="currentDetail.photos || []" |
| | | :limit="1" |
| | | accept="image/*" |
| | | class="detail-upload"> |
| | | <template v-if="!currentDetail.photos || currentDetail.photos.length < 1"> |
| | | <i class="el-icon-plus">+</i> |
| | | </template> |
| | | </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-section"> |
| | | <el-row :gutter="20"> |
| | |
| | | <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="contain" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]" fit="contain" |
| | | style="width: 700px; height: 520px; cursor: pointer;"> |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | |
| | | <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="fill" |
| | | :preview-src-list="[getPreviewUrl(currentDetail.updatePhotoUrl)]" fit="fill" |
| | | style="width: 700px; height: 520px; cursor: pointer;"> |
| | | <template #placeholder> |
| | | <div class="image-placeholder"> |
| | |
| | | column: [ |
| | | // { label: "序号", prop: "id", width: 70 }, |
| | | { label: "工单编号", prop: "orderNumber", width: 150 }, |
| | | { label: "工单名称", prop: "orderName", width: 150 }, |
| | | { label: "工单名称", prop: "orderName", width: 170, overHidden: true, tooltip: true }, |
| | | { label: "所属单位", prop: "department", width: 100 }, |
| | | { label: "发起时间", prop: "startTime", width: 160 }, |
| | | { label: "关联算法", prop: "aiType", width: 160 }, |
| | |
| | | const fields = [ |
| | | { label: "工单名称", value: this.currentDetail.orderName }, |
| | | { label: "工单类型", value: this.currentDetail.type }, |
| | | { label: "关联任务", value: this.currentDetail.job_name || '暂无关联航线' }, |
| | | { label: "关联任务", value: this.currentDetail.job_name || '/' }, |
| | | { label: "任务发起人", value: this.currentDetail.creator }, |
| | | { label: "当前状态", value: this.mapStatus(this.currentDetail.status) }, |
| | | { label: "事件地址", value: this.currentDetail.address }, // 包含经纬度信息 |
| | |
| | | isPass: 0, |
| | | eventNum: currentItem.orderNumber, |
| | | eventName: currentItem.orderName, |
| | | eventType: currentItem.type, |
| | | }; |
| | | |
| | | const response = await flowEvent(data); |
| | |
| | | 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 |
| | |
| | | }, |
| | | async approveAndDispatch() { |
| | | if (this.dispatchLoading) return; |
| | | // this.dispatchLoading = true; |
| | | this.dispatchDialogVisible = true; // 打开派发对话框 |
| | | |
| | | // 添加必填项检查 |
| | | if (!this.currentDetail.orderName || !this.currentDetail.orderName.trim()) { |
| | | this.$message.warning('请填写工单名称'); |
| | | return; |
| | | } |
| | | if (!this.currentDetail.type) { |
| | | this.$message.warning('请选择工单类型'); |
| | | return; |
| | | } |
| | | if (!this.currentDetail.content || !this.currentDetail.content.trim()) { |
| | | this.$message.warning('请填写工单内容'); |
| | | return; |
| | | } |
| | | |
| | | // 通过验证后,打开派发对话框 |
| | | this.dispatchDialogVisible = true; |
| | | }, |
| | | hasProcessingBtnPermission() { |
| | | // undefined 或 false 都返回 false,只有 true 返回 true |
| | |
| | | status: currentItem.status, |
| | | isPass: 0, |
| | | eventNum: currentItem.orderNumber, |
| | | eventName: currentItem.orderName, |
| | | }; |
| | | console.log('删除前:', this.selections) |
| | | const response = await flowEvent(data); |
| | |
| | | // 获取所有图片列表用于预览 |
| | | getImageList() { |
| | | return this.selections |
| | | .map(item => item.photo_url) |
| | | .map(item => this.getPreviewUrl(item.photo_url)) |
| | | .filter(url => url); // 过滤掉空值 |
| | | }, |
| | | |
| | |
| | | const lastDot = url.lastIndexOf('.'); |
| | | if (lastDot === -1) return url; |
| | | return url.slice(0, lastDot) + '_small' + url.slice(lastDot); |
| | | }, |
| | | |
| | | // 添加新方法:获取预览图地址 |
| | | getPreviewUrl(url) { |
| | | if (!url) return ''; |
| | | const lastDot = url.lastIndexOf('.'); |
| | | if (lastDot === -1) return url; |
| | | return url.slice(0, lastDot) + '_show' + url.slice(lastDot); |
| | | }, |
| | | }, |
| | | }; |
| | |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .no-media { |
| | | border: 1px dashed #d9d9d9; |
| | | } |
| | | |
| | | .info-table { |
| | | margin-bottom: 20px; |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 新建工单和处理工单的上传组件样式 */ |
| | | .create-upload, |
| | | .detail-upload { |
| | | :deep(.el-upload--picture-card) { |
| | | width: 120px; |
| | | height: 100px; |
| | | line-height: 100px; |
| | | } |
| | | |
| | | /* 隐藏额外的上传按钮 */ |
| | | :deep(.el-upload.el-upload--picture-card) { |
| | | display: none; |
| | | } |
| | | |
| | | /* 当没有图片时显示上传按钮 */ |
| | | :deep(.el-upload.el-upload--picture-card:first-child) { |
| | | display: flex; |
| | | } |
| | | |
| | | /* 上传组件的预览图片样式 */ |
| | | :deep(.el-upload-list--picture-card .el-upload-list__item) { |
| | | width: 120px; |
| | | height: 100px; |
| | | } |
| | | } |
| | | |
| | | /* 事件图片和处理图片的预览样式 */ |
| | | .media-content { |
| | | :deep(.el-image) { |
| | | width: 700px !important; |
| | | height: 520px !important; |
| | | |
| | | .el-image__inner { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: contain; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 原有图片预览的样式 */ |
| | | .el-image-viewer__wrapper { |
| | | :deep(.el-image-viewer__img) { |
| | | max-width: 100%; |
| | | max-height: 100%; |
| | | object-fit: contain; |
| | | } |
| | | } |
| | | |
| | | /* 必填项样式 */ |
| | | .required-label { |
| | | position: relative; |
| | | display: inline-block; |
| | | |
| | | .required-star { |
| | | color: #F56C6C; |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | |
| | | /* 必填输入框样式 */ |
| | | .required-input { |
| | | width: 100%; |
| | | |
| | | :deep(.el-input__inner), |
| | | :deep(.el-textarea__inner) { |
| | | &:focus { |
| | | border-color: #409EFF; |
| | | } |
| | | } |
| | | } |
| | | </style> |