wlzboy
2025-12-24 b30c1ebb0e46e734e70f8731484764f449f48818
app/pages/index.vue
@@ -101,7 +101,8 @@
            <view class="task-header">
              <view class="task-title">
                {{ getTaskTypeText(task.type) }} - {{ task.vehicle }}
                <text v-if="task.isHeadPush === '1'" class="head-push-tag">总</text>
                <text v-if="task.emergencyInfo && task.emergencyInfo.serviceOrdVip === '1'" class="vip-tag">VIP</text>
                <text v-if="task.emergencyInfo && task.emergencyInfo.fromHq2Is === '1'" class="hq-tag">广总</text>
              </view>
              <view
                class="task-status"
@@ -127,9 +128,10 @@
              </view>
            </view>
            <!-- 任务编号单独一行 -->
            <!-- 任务编号和开始时间在同一行显示,但分开一些 -->
            <view class="task-code-row">
              <text class="task-code">{{ task.showTaskCode }}</text>
              <text class="task-time">{{ task.startTime }}</text>
            </view>
            <!-- 任务详细信息 -->
@@ -137,18 +139,18 @@
              <view class="info-row">
                <view class="info-item">
                  <view class="label">出发地:</view>
                  <view class="value">{{ task.startLocation }}</view>
                  <view class="value">{{ getStartLocationDisplay(task) }}</view>
                </view>
                <view class="info-item">
                  <view class="label">目的地:</view>
                  <view class="value">{{ task.endLocation }}</view>
                </view>
              </view>
              <view class="info-row">
                <view class="info-item">
                  <view class="label">出发时间:</view>
                  <view class="value">{{ task.startTime }}</view>
                  <view class="label">目的地:</view>
                  <view class="value">{{ getEndLocationDisplay(task) }}</view>
                </view>
              </view>
              <view class="info-row">
                <view class="info-item">
                  <view class="label">执行人员:</view>
                  <view class="value">{{ task.assignee }}</view>
@@ -235,12 +237,13 @@
<script>
import { mapState } from "vuex";
import { getMyTasks, changeTaskStatus } from "@/api/task";
import { getMyTasks, changeTaskStatus, checkTaskConsentAttachment } from "@/api/task";
import { getUserProfile } from "@/api/system/user";
import { getUserBoundVehicle } from "@/api/vehicle";
import { getUnreadCount } from "@/api/message";
import { formatDateTime } from "@/utils/common";
import subscribeManager from "@/utils/subscribe";
import { checkTaskCanDepart } from "@/utils/taskValidator";
export default {
  data() {
@@ -505,14 +508,12 @@
                type: task.taskType,
                vehicle: vehicleInfo,
                vehicleList: task.assignedVehicles || [],
                startLocation: this.formatAddress(
                  task.departureAddress || task.startLocation || "未设置"
                ),
                endLocation: this.formatAddress(
                  task.destinationAddress || task.endLocation || "未设置"
                ),
                startLocation: task.departureAddress || task.startLocation || "未设置",
                endLocation: task.destinationAddress || task.endLocation || "未设置",
                startTime: task.plannedStartTime
                  ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                  ? (task.plannedStartTime.startsWith('1900') || task.plannedStartTime.startsWith('1970')
                    ? '未分配时间'
                    : formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm"))
                  : "未设置",
                assignee: task.assigneeName || "未分配",
                taskNo: task.taskCode || "未知编号",
@@ -555,6 +556,33 @@
      return address;
    },
    // 获取出发地显示内容(转运任务显示转出医院名称)
    getStartLocationDisplay(task) {
      // 如果是转运任务且有emergencyInfo信息
      if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo && task.emergencyInfo.hospitalOutName) {
        return task.emergencyInfo.hospitalOutName;
      }
      // 其他情况使用原来的startLocation
      return this.formatAddress(task.startLocation || "未设置");
    },
    // 获取目的地显示内容(转运任务显示转入医院名称或详细地址)
    getEndLocationDisplay(task) {
      // 如果是转运任务且有emergencyInfo信息
      if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo) {
        // 优先显示转入医院名称
        if (task.emergencyInfo.hospitalInName) {
          if(task.emergencyInfo.hospitalInName.includes("家中")){
            return task.emergencyInfo.destinationAddress;
          }
          return task.emergencyInfo.hospitalInName;
        }
      }
      // 其他情况使用原来的endLocation
      return this.formatAddress(task.endLocation || "未设置");
    },
    // 转换状态格式(将数据库状态转换为UI使用的状态)
    convertStatus(dbStatus) {
      const statusMap = {
@@ -586,16 +614,96 @@
    },
    // 处理任务操作
    handleTaskAction(task, action) {
    async handleTaskAction(task, action) {
      switch (action) {
        case "depart":
          // 出发 -> 状态变为出发中
          this.$modal
            .confirm("确定要出发吗?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
            })
            .catch(() => {});
          // 显示加载提示
          uni.showLoading({
            title: "检查任务状态...",
          });
          try {
            // 调用工具类检查任务是否可以出发(包含基本校验和冲突检查)
            const checkResult = await checkTaskCanDepart(task);
            uni.hideLoading();
            console.log("出发检查结果:", checkResult);
            console.log("valid:", checkResult.valid);
            console.log("conflicts:", checkResult.conflicts);
            if (!checkResult.valid) {
              // 校验失败,显示提示信息并提供跳转选项
              const conflicts = checkResult.conflicts || [];
              const conflictInfo = conflicts.length > 0 ? conflicts[0] : null;
              console.log("冲突信息:", conflictInfo);
              // 如果有冲突任务信息,提供跳转按钮
              if (conflictInfo && conflictInfo.taskId) {
                console.log(
                  "显示带跳转按钮的弹窗,任务ID:",
                  conflictInfo.taskId
                );
                const conflictTaskId = conflictInfo.taskId;
                const message =
                  checkResult.message || conflictInfo.message || "存在冲突任务";
                uni.showModal({
                  title: "提示",
                  content: message,
                  confirmText: "去处理",
                  cancelText: "知道了",
                  success: function (res) {
                    console.log("弹窗点击结果:", res);
                    if (res.confirm) {
                      // 用户点击"现在去处理",跳转到冲突任务详情页
                      console.log("准备跳转到任务详情页:", conflictTaskId);
                      uni.navigateTo({
                        url: `/pagesTask/detail?id=${conflictTaskId}`,
                      });
                    }
                  },
                  fail: function (err) {
                    console.error("显示弹窗失败:", err);
                  },
                });
              } else {
                // 没有冲突任务ID,只显示提示
                console.log("显示普通提示弹窗");
                uni.showModal({
                  title: "提示",
                  content: checkResult.message || "任务校验失败",
                  showCancel: false,
                  confirmText: "知道了",
                  fail: function (err) {
                    console.error("显示弹窗失败:", err);
                  },
                });
              }
              return;
            }
            // 所有检查通过,可以出发
            this.$modal
              .confirm("确定要出发吗?")
              .then(() => {
                this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
              })
              .catch(() => {});
          } catch (error) {
            uni.hideLoading();
            console.error("检查任务状态失败:", error);
            // 检查失败时,仍然允许出发
            this.$modal
              .confirm("检查任务状态失败,是否继续出发?")
              .then(() => {
                this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
              })
              .catch(() => {});
          }
          break;
        case "cancel":
@@ -640,12 +748,8 @@
        case "complete":
          // 已完成 -> 状态变为已完成
          this.$modal
            .confirm("确认任务已完成?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "COMPLETED", "任务已完成");
            })
            .catch(() => {});
          // 需要检查是否上传了知情同意书
          this.checkConsentAttachmentAndThen(task.taskId, "COMPLETED", "任务已完成");
          break;
      }
    },
@@ -654,6 +758,43 @@
    updateTaskStatus(taskId, status, remark) {
      // 获取GPS位置信息
      this.getLocationAndUpdateStatus(taskId, status, remark);
    },
    // 检查知情同意书附件并更新状态
    async checkConsentAttachmentAndThen(taskId, status, remark) {
      try {
        uni.showLoading({
          title: '检查附件...'
        });
        const response = await checkTaskConsentAttachment(taskId);
        uni.hideLoading();
        if (response.code === 200) {
          // 已上传知情同意书,继续更新状态
          this.$modal
            .confirm("确认任务已完成?")
            .then(() => {
              this.updateTaskStatus(taskId, status, remark);
            })
            .catch(() => {});
        } else {
          // 未上传知情同意书,显示提示
          this.$modal.confirm('任务未上传知情同意书,无法完成任务。是否现在去上传?').then(() => {
            // 跳转到任务详情页上传附件
            this.$tab.navigateTo(`/pagesTask/detail?id=${taskId}`);
          }).catch(() => {});
        }
      } catch (error) {
        uni.hideLoading();
        console.error('检查附件失败:', error);
        // 如果检查失败,询问用户是否继续
        this.$modal.confirm('检查附件状态失败,是否继续完成任务?').then(() => {
          this.updateTaskStatus(taskId, status, remark);
        }).catch(() => {});
      }
    },
    // 获取位置信息并更新状态
@@ -824,17 +965,6 @@
  * {
    -ms-overflow-style: none; /* IE 10+ */
  }
}
// 总部推送标记样式
.head-push-tag {
  color: #ff0000;
  font-size: 24rpx;
  font-weight: bold;
  margin-left: 10rpx;
  padding: 2rpx 8rpx;
  border: 1rpx solid #ff0000;
  border-radius: 4rpx;
}
// 用户信息区域
@@ -1115,13 +1245,22 @@
          }
        }
        // 任务编号单独一行
        // 任务编号和时间在同一行显示
        .task-code-row {
          margin-bottom: 15rpx;
          padding: 10rpx 0;
          border-bottom: 1rpx dashed #e0e0e0;
          display: flex;
          justify-content: space-between;
          .task-code {
            font-size: 28rpx;
            color: #333;
            font-weight: 500;
            font-family: monospace;
          }
          .task-time {
            font-size: 28rpx;
            color: #333;
            font-weight: 500;
@@ -1220,6 +1359,28 @@
        color: #666;
      }
    }
    .vip-tag {
      display: inline-block;
      padding: 2rpx 8rpx;
      font-size: 20rpx;
      color: #fff;
      background-color: #ff0000;
      border-radius: 4rpx;
      margin-left: 10rpx;
      vertical-align: middle;
    }
    .hq-tag {
      display: inline-block;
      padding: 2rpx 8rpx;
      font-size: 20rpx;
      color: #fff;
      background-color: #5856d6;
      border-radius: 4rpx;
      margin-left: 10rpx;
      vertical-align: middle;
    }
  }
}
</style>