wlzboy
2026-02-05 57e98ac3f59e9ca12d3fdbc6f89c9c0b1f86be4d
app/pagesTask/detail.vue
@@ -237,7 +237,17 @@
      
      <!-- 转运 - 费用信息 -->
      <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo">
        <view class="section-title">费用信息</view>
        <view class="section-title">
          费用信息
          <!-- 已完成且未申请发票时显示申请发票按钮 -->
          <button
            v-if="canApplyInvoice"
            class="apply-invoice-btn"
            @click="handleApplyInvoice"
          >
            <text class="cuIcon-form"></text> 申请发票
          </button>
        </view>
        <view class="info-item" v-if="taskDetail.emergencyInfo.transferDistance">
          <view class="label">转运公里数</view>
          <view class="value">{{ taskDetail.emergencyInfo.transferDistance }}公里</view>
@@ -479,7 +489,7 @@
        </button>
      </template>
      
      <!-- 出发中状态: 显示已到达、强制结束 -->
      <!-- 出发中状态: 显示已到达、强制结束、强制完成 -->
      <template v-else-if="taskDetail.taskStatus === 'DEPARTING'">
        <template v-if="canOperateTask()">
          <button 
@@ -493,6 +503,13 @@
            @click="handleTaskAction('forceCancel')"
          >
            强制结束
          </button>
          <button
            v-if="showForceCompleteFeature()"
            class="action-btn force-complete"
            @click="showForceCompleteTimeDialog()"
          >
            强制完成
          </button>
        </template>
      </template>
@@ -559,6 +576,7 @@
  import { checkVehicleActiveTasks } from '@/api/task'
  import { getPaymentInfo } from '@/api/payment'
  import { getDicts } from '@/api/dict'
  import { checkTaskInvoice } from '@/api/invoice'
  import { formatDateTime } from '@/utils/common'
  import { validateTaskForDepart, validateTaskForSettlement, getTaskVehicleId, checkTaskCanDepart } from '@/utils/taskValidator'
  import AttachmentUpload from './components/AttachmentUpload.vue'
@@ -580,7 +598,9 @@
        forceCompleteForm: {
          actualStartTime: '',
          actualEndTime: ''
        }
        },
        hasInvoiceApplied: false, // 是否已申请发票
        invoiceStatus: null // 发票状态:0-待审核, 1-已通过, 2-已驳回
      }
    },
    computed: {
@@ -590,6 +610,16 @@
          return false
        }
        return ['COMPLETED', 'CANCELLED'].includes(this.taskDetail.taskStatus)
      },
      // 是否可以申请发票
      canApplyInvoice() {
        // 仅急救转运任务
        if (this.taskDetail?.taskType !== 'EMERGENCY_TRANSFER') return false
        // 任务必须已完成
        if (this.taskDetail?.taskStatus !== 'COMPLETED') return false
        // 未申请过发票,或曾被驳回
        return !this.hasInvoiceApplied || this.invoiceStatus === 2
      },
      
      // 生成执行人员角色标签的类名
@@ -692,6 +722,8 @@
      this.taskId = options.id
      this.loadTaskDetail()
      this.loadCancelReasonDict() // 加载取消原因字典
      // 检查发票申请状态
      this.checkInvoiceStatus()
    },
    onShow() {
      // 每次页面显示时重新加载数据,确保从编辑页面返回后能看到最新数据
@@ -1051,6 +1083,45 @@
        }
        
        return null;
      },
      // 检查发票申请状态
      checkInvoiceStatus() {
        if (!this.taskId) return;
        // 调用后端接口检查该任务是否已申请发票
        checkTaskInvoice(this.taskId).then(response => {
          if (response.code === 200 && response.data) {
            this.hasInvoiceApplied = true;
            this.invoiceStatus = response.data.status;
          }
        }).catch(error => {
          console.error('检查发票申请状态失败:', error);
          // 忽略错误,默认未申请
        });
      },
      // 申请发票
      handleApplyInvoice() {
        // 准备任务信息
        const taskInfo = {
          taskId: this.taskDetail.taskId,
          taskCode: this.taskDetail.showTaskCode || this.taskDetail.taskCode,
          legacyServiceOrderId: this.taskDetail.emergencyInfo?.legacyServiceOrdId,
          serviceCode: this.taskDetail.emergencyInfo?.serviceCode,
          departure: this.taskDetail.departureAddress,
          destination: this.taskDetail.destinationAddress,
          completionTime: this.formatTime(this.taskDetail.actualEndTime),
          transferPrice: this.paymentInfo?.transferPrice || this.paymentInfo?.totalAmount
        };
        // 将任务信息序列化为 URL 参数
        const taskInfoParam = encodeURIComponent(JSON.stringify(taskInfo));
        // 跳转到发票申请页面,传递任务信息
        uni.navigateTo({
          url: `/pages/mine/invoice/apply?taskInfo=${taskInfoParam}`
        });
      },
      
      // 更新任务状态
@@ -2234,10 +2305,13 @@
        flex: 1;
        height: 80rpx;
        border-radius: 10rpx;
        font-size: 30rpx;
        font-size: 28rpx;
        margin: 0 10rpx;
        background-color: #f0f0f0;
        color: #333;
        white-space: nowrap;
        padding: 0 10rpx;
        min-width: 0;
        
        &.edit {
          background-color: #ff9500;
@@ -2251,6 +2325,11 @@
        
        &.cancel {
          background-color: #ff3b30;
          color: white;
        }
        &.force-end {
          background-color: #ff6b22;
          color: white;
        }
        
@@ -2295,6 +2374,20 @@
      margin-left: 10rpx;
      vertical-align: middle;
    }
    .apply-invoice-btn {
      padding: 8rpx 16rpx;
      font-size: 24rpx;
      color: #fff;
      background-color: #34C759;
      border: none;
      border-radius: 6rpx;
      margin-left: 20rpx;
    }
    .apply-invoice-btn::after {
      border: none;
    }
    
    // 取消原因对话框样式
    .cancel-dialog {