| | |
| | | <div class="custom-steps-container"> |
| | | <!-- 标题行 --> |
| | | <div class="steps-titles"> |
| | | <div class="step-title" :class="{ active: true }"> |
| | | 发起任务 |
| | | <div class="step-title active"> |
| | | {{ workType === 1 ? '发起工单' : '发起任务' }} |
| | | </div> |
| | | <div v-for="(status, index) in dynamicFixedStatuses" :key="index" |
| | | :class="{ active: Number(currentDetail.status) >= Number(status) }" class="step-title"> |
| | | <div v-for="(status, index) in stepStatusList" :key="index" :class="{ |
| | | 'step-title': true, |
| | | 'active': index <= stepStatusList.indexOf(String(currentDetail.status)) |
| | | }"> |
| | | {{ mapStatus(status) }} |
| | | </div> |
| | | </div> |
| | |
| | | {{ currentDetail.creator || '未知' }} |
| | | </span> |
| | | <div class="step-description"> |
| | | {{ currentDetail.startTime || '未知时间' }} |
| | | <template v-if="workType === 0"> |
| | | {{ currentDetail.job_create_time || currentDetail.startTime || '未知时间' }} |
| | | </template> |
| | | <template v-else> |
| | | {{ currentDetail.startTime || '未知时间' }} |
| | | </template> |
| | | </div> |
| | | </template> |
| | | </el-step> |
| | | <el-step v-for="(status, index) in dynamicFixedStatuses" :key="index"> |
| | | <el-step v-for="(status, index) in stepStatusList" :key="index"> |
| | | <template #description> |
| | | <span class="step-description"> |
| | | {{ getStepHandler(status) }} |
| | | </span> |
| | | <div class="step-description" v-if="getStepTime(status)"> |
| | | <span style=" position: absolute; |
| | | right: 80%; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 100px; |
| | | margin-left: 4px; |
| | | color: #666; |
| | | font-size: 12px;">耗时:{{ getStepTime(status) }}</span> |
| | | <span |
| | | style="position: absolute; right: 80%; top: 50%; transform: translateY(-50%); width: 100px; margin-left: 4px; color: #666; font-size: 12px;"> |
| | | 耗时:{{ getStepTime(status) }} |
| | | </span> |
| | | </div> |
| | | <div class="step-description"> |
| | | {{ getStepCreateTime(status) }} |
| | |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修复工单名称可编辑 --> |
| | | <template v-if="currentDetail.status === 0 && row.label1 === '工单名称'&&hasProcessingBtnPermission()"> |
| | | <template v-if="currentDetail.status === 0 && row.label1 === '工单名称' && hasProcessingBtnPermission()"> |
| | | <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" /> |
| | | </template> |
| | | <!-- 修复任务接收单位为下拉框 --> |
| | |
| | | <el-table-column> |
| | | <template #default="{ row }"> |
| | | <!-- 修复工单内容可编辑 --> |
| | | <template v-if="currentDetail.status === 0 && row.label2 === '工单内容'&&hasProcessingBtnPermission()"> |
| | | <template v-if="currentDetail.status === 0 && row.label2 === '工单内容' && hasProcessingBtnPermission()"> |
| | | <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" /> |
| | | </template> |
| | | <!-- 修复工单类型为下拉框 --> |
| | |
| | | return formattedFields; |
| | | }, |
| | | dynamicFixedStatuses() { |
| | | // 根据当前工单work_type动态返回流程 |
| | | if (this.workType === 1) { |
| | | return ["3", "4", "5"]; // 人工工单:处理中-已完成-已完结 |
| | | } |
| | | return this.fixedStatuses; // 默认流程 |
| | | // 直接使用接口返回的 stepInfos |
| | | return this.stepInfos.map(step => String(step.status)); |
| | | }, |
| | | ...mapGetters(['userInfo', 'permission']), |
| | | // 动态过滤tabs,保证isShow为true/false |
| | |
| | | exportBtn: this.validData(this.permission.tickets_export, false,), |
| | | reviewBtn: this.validData(this.permission.tickets_review, false), |
| | | }; |
| | | }, |
| | | stepStatusList() { |
| | | // “我发起的工单”tab用默认流程,其它tab用接口返回的stepInfos |
| | | if (this.activeTab === 'myTickets') { |
| | | if (this.workType === 1) { |
| | | return ["3", "4", "5"]; |
| | | } |
| | | return this.fixedStatuses; |
| | | } |
| | | // 其它tab直接用接口返回的stepInfos |
| | | return this.stepInfos.map(step => String(step.status)); |
| | | }, |
| | | }, |
| | | methods: { |
| | |
| | | ai_type: this.filters.algorithm || undefined, // 添加算法参数 |
| | | // 添加 is_draft 参数,仅在"我发起的"标签页时设置为1 |
| | | is_draft: currentTab?.name === 'myTickets' ? 1 : undefined, |
| | | |
| | | user_id: currentTab?.name === 'myTickets' ? this.userInfo.user_id : undefined, |
| | | }; |
| | | |
| | |
| | | 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字段并转为数字 |
| | | job_name: item.job_name || '', |
| | | job_name: item.job_name || '', |
| | | job_create_time: item.job_create_time || '', |
| | | }; |
| | | }); |
| | | |
| | |
| | | job_name: row.job_name || '', // 新增 |
| | | }; |
| | | |
| | | let stepArr = []; |
| | | try { |
| | | const stepResponse = await getStepInfo(row.orderNumber); |
| | | // 不再从stepResponse获取work_type |
| | | |
| | | // 兼容原有步骤数据 |
| | | const steps = Array.isArray(stepResponse.data.data) |
| | | ? stepResponse.data.data |
| | | : stepResponse.data.data?.steps || []; |
| | | |
| | | // 根据流程类型动态生成步骤 |
| | | 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, |
| | | name: step ? step.name : '', |
| | | time: step ? step.time : null, |
| | | create_time: step ? step.create_time : null, |
| | | }; |
| | | }); |
| | | |
| | | this.currentDetail.status = row.status; // 使用行数据中的状态 |
| | | if (this.activeTab !== 'myTickets') { |
| | | this.stepInfos = steps.map(step => ({ |
| | | status: String(step.status), |
| | | name: step.name, |
| | | time: step.time, |
| | | create_time: step.create_time, |
| | | })); |
| | | } else { |
| | | 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, |
| | | name: step ? step.name : '', |
| | | time: step ? step.time : null, |
| | | create_time: step ? step.create_time : null, |
| | | }; |
| | | }); |
| | | } |
| | | this.currentDetail.status = row.status; |
| | | } catch (error) { |
| | | 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, |
| | | })); |
| | | if (this.activeTab === 'myTickets') { |
| | | 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, |
| | | })); |
| | | } else { |
| | | this.stepInfos = []; |
| | | } |
| | | } |
| | | |
| | | this.currentDetail = detailData; |
| | |
| | | return step ? step.create_time : null; |
| | | }, |
| | | getActiveStep() { |
| | | // 动态流程下,步骤索引需适配 |
| | | const arr = this.dynamicFixedStatuses; |
| | | // 步骤索引适配 |
| | | const arr = this.stepStatusList; |
| | | const index = arr.indexOf(String(this.currentDetail.status)); |
| | | return index !== -1 ? index + 1 : 1; |
| | | return index !== -1 ? index + 2 : 1; |
| | | }, |
| | | |
| | | openMap() { |
| | |
| | | color: #409eff; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .event-title-center { |
| | | text-align: center; |
| | | font-size: 20px; |
| | |
| | | margin-bottom: 12px; |
| | | color: #333; |
| | | } |
| | | |
| | | .custom-steps { |
| | | margin-top: -20px; |
| | | |