| | |
| | | <avue-crud v-model="tableData" :option="option" :data="tableData" v-model:page="page" |
| | | @size-change="sizeChange" @current-change="handleCurrentChange" :table-loading="loading"> |
| | | <template #menu-left> |
| | | <el-button type="primary" icon="el-icon-plus" @click="handleAdd">新建工单</el-button> |
| | | <el-button |
| | | v-if="activeTab === 'all' || activeTab === 'myTickets'" |
| | | type="primary" |
| | | icon="el-icon-plus" |
| | | @click="handleAdd" |
| | | >新建工单</el-button> |
| | | <el-button type="success" plain icon="el-icon-download" @click="exportData">导出</el-button> |
| | | </template> |
| | | <template #menu="{ row }"> |
| | |
| | | 发起任务 |
| | | </div> |
| | | <div |
| | | v-for="(status, index) in fixedStatuses" |
| | | v-for="(status, index) in dynamicFixedStatuses" |
| | | :key="index" |
| | | :class="{ active: Number(currentDetail.status) >= Number(status) }" |
| | | class="step-title" |
| | |
| | | </div> |
| | | </template> |
| | | </el-step> |
| | | <el-step v-for="(status, index) in fixedStatuses" :key="index"> |
| | | <el-step v-for="(status, index) in dynamicFixedStatuses" :key="index"> |
| | | <template #description> |
| | | <span class="step-description"> |
| | | {{ getStepHandler(status) }} |
| | |
| | | width: 100px; |
| | | margin-left: 4px; |
| | | color: #666; |
| | | font-size: 12px;">耗时{{ getStepTime(status) }}</span> |
| | | font-size: 12px;">耗时:{{ getStepTime(status) }}</span> |
| | | </div> |
| | | <div class="step-description" > |
| | | {{ getStepCreateTime(status) }} |
| | |
| | | stepInfos: [], // 新增:存储步骤信息 |
| | | fixedStatuses: ["2", "0", "3", "4", "5"], // 固定的五个状态 |
| | | userNameToIdMap: {}, // 新增用户名到ID的映射 |
| | | workType: 0, // 新增:当前工单work_type |
| | | }; |
| | | }, |
| | | created() { |
| | |
| | | } |
| | | return formattedFields; |
| | | }, |
| | | dynamicFixedStatuses() { |
| | | // 根据当前工单work_type动态返回流程 |
| | | if (this.workType === 1) { |
| | | return ["3", "4", "5"]; // 人工工单:处理中-已完成-已完结 |
| | | } |
| | | return this.fixedStatuses; // 默认流程 |
| | | }, |
| | | ...mapGetters(['userInfo']), |
| | | }, |
| | | methods: { |
| | |
| | | |
| | | // 直接从返回对象中获取正确的路径 |
| | | const center = adcodeObj?.payload?.objects?.collection?.geometries?.[0]?.properties?.center; |
| | | |
| | | console.log('获取到的中心点:', center); |
| | | |
| | | if (Array.isArray(center) && center.length === 2) { |
| | | this.mapParams.center = center; |
| | | console.log('成功设置地图中心点:', center); |
| | | } else { |
| | | // 如果找不到中心点,尝试使用 bbox 的中心点 |
| | | const bbox = adcodeObj?.payload?.bbox; |
| | |
| | | const centerX = (bbox[0] + bbox[2]) / 2; |
| | | const centerY = (bbox[1] + bbox[3]) / 2; |
| | | this.mapParams.center = [centerX, centerY]; |
| | | console.log('使用 bbox 计算的中心点:', this.mapParams.center); |
| | | } else { |
| | | console.warn('无法获取有效的中心点坐标,使用默认值'); |
| | | this.mapParams.center = [115.861365, 28.621311]; |
| | | } |
| | | } |
| | | |
| | | this.mapLoaded = true; |
| | | } catch (error) { |
| | | console.error('地图脚本加载失败:', error); |
| | | this.$message.error('地图加载失败,请检查网络或API Key配置'); |
| | | } |
| | | }, |
| | |
| | | this.userNameToIdMap[user.name] = user.id; |
| | | }); |
| | | }); |
| | | |
| | | console.log('用户名到ID的映射:', this.userNameToIdMap); |
| | | } catch (error) { |
| | | console.error('获取下拉框数据失败:', error); |
| | | this.$message.error('加载下拉框数据失败'); |
| | | } |
| | | }, |
| | |
| | | video_url: item.video_url || '', // 保存原始 video_url |
| | | location: (!isNaN(longitude) && !isNaN(latitude)) ? [longitude, latitude] : null, |
| | | processing_details: item.processing_details || '', // 添加处理详情字段 |
| | | video_url: item.video_url || '', // 保存原始 video_url |
| | | location: (!isNaN(longitude) && !isNaN(latitude)) ? [longitude, latitude] : null, |
| | | processing_details: item.processing_details || '', // 添加处理详情字段 |
| | | update_photo_url: item.update_photo_url || '', // 添加处理图片字段 |
| | | |
| | | work_type: item.work_type !== undefined ? Number(item.work_type) : 0, // 保留work_type字段并转为数字 |
| | | }; |
| | | }); |
| | | |
| | |
| | | |
| | | await this.fetchTabCounts(); |
| | | } catch (error) { |
| | | console.error("获取数据失败:", error); |
| | | this.$message.error(error.message || "获取数据失败"); |
| | | this.tableData = []; |
| | | this.page.total = 0; |
| | |
| | | throw new Error(response.data.msg || '创建失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('提交失败:', error); |
| | | if (error.message.includes('验证未通过')) { |
| | | this.$message.warning('请填写完整的工单信息'); |
| | | } else { |
| | |
| | | throw new Error(response.data.msg || '保存失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('保存草稿失败:', error); |
| | | this.$message.error(error.message || '保存草稿失败,请稍后重试'); |
| | | } |
| | | }, |
| | | |
| | | async handleLocationChange(val) { |
| | | console.log('地图选址返回值:', val); |
| | | |
| | | |
| | | // 处理 Proxy 对象的值 |
| | | let locationValue = val.value; |
| | |
| | | // 确保我们获取到实际的数组值 |
| | | this.form.location = [locationValue[0], locationValue[1]]; |
| | | this.form.address = locationValue[2] || ''; |
| | | |
| | | console.log('解析后的位置信息:', { |
| | | 经度: this.form.location[0], |
| | | 纬度: this.form.location[1], |
| | | 地址: this.form.address |
| | | }); |
| | | } else { |
| | | console.warn('无效的位置数据'); |
| | | this.form.location = []; |
| | | this.form.address = ''; |
| | | } |
| | |
| | | try { |
| | | const response = await getstatusCount(); |
| | | const { statusCount, totalCount, userCount } = response.data.data; |
| | | |
| | | console.log('接口返回的状态统计数据:', { statusCount, totalCount, userCount }); |
| | | |
| | | this.tabs.forEach(tab => { |
| | | if (tab.name === 'all') { |
| | | tab.count = totalCount || 0; // 总工单数 |
| | |
| | | tab.count = statusCount[String(tab.value)] || 0; // 根据状态值映射 |
| | | } |
| | | }); |
| | | |
| | | console.log('更新后的 tabs 数据:', this.tabs); |
| | | } catch (error) { |
| | | console.error('获取 tab 数据失败:', error); |
| | | this.$message.error('获取 tab 数据失败'); |
| | | } |
| | | }, |
| | |
| | | }, |
| | | |
| | | async handleCurrentChange(val) { |
| | | console.log('当前页变更:', val); |
| | | // 先更新页码 |
| | | this.page.currentPage = val; |
| | | // 等待 DOM 更新后再请求数据 |
| | |
| | | }, |
| | | |
| | | async sizeChange(val) { |
| | | console.log('每页条数变更:', val); |
| | | this.page.pageSize = val; |
| | | this.page.currentPage = 1; // 重置到第一页 |
| | | await this.$nextTick(); |
| | |
| | | }, |
| | | |
| | | async handleViewDetail(row) { |
| | | console.log('查看详情数据:', row); |
| | | // 先设置workType,直接从row读取 |
| | | this.workType = row.work_type !== undefined ? Number(row.work_type) : 0; |
| | | |
| | | // 重置上传组件的文件列表 |
| | | this.$nextTick(() => { |
| | | this.$refs.MapContainer.initAddEntity('point',this.currentDetail.location); |
| | | if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) { |
| | | this.$refs.MapContainer.initAddEntity('point', this.currentDetail.location); |
| | | } |
| | | }); |
| | | |
| | | const detailData = { |
| | |
| | | |
| | | try { |
| | | const stepResponse = await getStepInfo(row.orderNumber); |
| | | console.log('接口返回的步骤信息:', stepResponse.data.data); |
| | | // 不再从stepResponse获取work_type |
| | | |
| | | const steps = stepResponse.data.data || []; |
| | | // 兼容原有步骤数据 |
| | | const steps = Array.isArray(stepResponse.data.data) |
| | | ? stepResponse.data.data |
| | | : stepResponse.data.data?.steps || []; |
| | | |
| | | // 根据接口返回的步骤信息补充处理人和时间 |
| | | this.stepInfos = this.fixedStatuses.map(status => { |
| | | // 根据流程类型动态生成步骤 |
| | | const statusArr = this.workType === 1 ? ["3", "4", "5"] : this.fixedStatuses; |
| | | this.stepInfos = statusArr.map(status => { |
| | | const step = steps.find(s => String(s.status) === String(status)); |
| | | return { |
| | | status, |
| | |
| | | }; |
| | | }); |
| | | |
| | | console.log('处理后的步骤信息:', this.stepInfos); |
| | | |
| | | this.currentDetail.status = row.status; // 使用行数据中的状态 |
| | | } catch (error) { |
| | | console.error('获取步骤信息失败:', error); |
| | | // 如果接口调用失败,使用默认的固定状态 |
| | | this.stepInfos = this.fixedStatuses.map(status => ({ |
| | | const statusArr = this.workType === 1 ? ["3", "4", "5"] : this.fixedStatuses; |
| | | this.stepInfos = statusArr.map(status => ({ |
| | | status, |
| | | name: status === row.status ? row.handler || '未分配' : '未处理', |
| | | time: status === row.status ? row.startTime || '未知时间' : null, |
| | |
| | | } |
| | | |
| | | this.currentDetail = detailData; |
| | | console.log('当前详情数据:', this.currentDetail); |
| | | this.detailVisible = true; |
| | | this.$nextTick(() => { |
| | | this.$refs.MapContainer.initAddEntity('point', this.currentDetail.location) |
| | | }) |
| | | if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) { |
| | | this.$refs.MapContainer.initAddEntity('point', this.currentDetail.location); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | getStepHandler(status) { |
| | |
| | | }, |
| | | getStepCreateTime(status) { |
| | | const step = this.stepInfos.find(step => step.status === status); |
| | | console.log('getStepCreateTime:', step); |
| | | return step ? step.create_time : null; |
| | | }, |
| | | getActiveStep() { |
| | | // 由于新增了发起任务步骤,需要调整步骤索引 |
| | | const index = this.fixedStatuses.indexOf(String(this.currentDetail.status)); |
| | | return index !== -1 ? index + 1 : 1; // 加1是因为多了发起任务这一步 |
| | | // 动态流程下,步骤索引需适配 |
| | | const arr = this.dynamicFixedStatuses; |
| | | const index = arr.indexOf(String(this.currentDetail.status)); |
| | | return index !== -1 ? index + 1 : 1; |
| | | }, |
| | | |
| | | openMap() { |
| | | const areaCode = this.userInfo.detail.areaCode; |
| | | const subAreaCode = areaCode ? areaCode.substring(0, 6) : ''; |
| | | const adcodeObj = getAdcodeObj(geoJson, 'adcode', subAreaCode); |
| | | |
| | | console.log('区域代码:', subAreaCode); |
| | | console.log('getAdcodeObj返回值:', { |
| | | 完整对象: adcodeObj, |
| | | 级别: adcodeObj?.level, |
| | | 名称: adcodeObj?.name, |
| | | 代码: adcodeObj?.adcode, |
| | | 中心点: adcodeObj?.center, |
| | | 边界: adcodeObj?.polyline, |
| | | }); |
| | | |
| | | getAdcodeObj(geoJson, 'adcode', subAreaCode); |
| | | this.$message.info("地图选址功能暂未实现"); |
| | | }, |
| | | |
| | |
| | | export_json_to_excel(headers, exportData, '工单数据'); |
| | | this.$message.success('数据导出成功'); |
| | | } catch (error) { |
| | | console.error('导出失败:', error); |
| | | this.$message.error(error.message || '导出失败,请稍后重试'); |
| | | } finally { |
| | | this.loading = false; |
| | |
| | | throw new Error(response.data.msg || '操作失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('通过操作失败:', error); |
| | | this.$message.error(error.message || '操作失败,请稍后重试'); |
| | | } |
| | | }, |
| | |
| | | throw new Error(response.data.msg || '操作失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('不通过操作失败:', error); |
| | | this.$message.error(error.message || '操作失败,请稍后重试'); |
| | | } |
| | | }, |
| | |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | </style> |
| | | ``` |