| | |
| | | <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" |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 任务编号单独一行 --> |
| | | <!-- 任务编号和开始时间在同一行显示,但分开一些 --> |
| | | <view class="task-code-row"> |
| | | <text class="task-code">{{ task.showTaskCode }}</text> |
| | | <text class="task-time">{{ task.startTime }}</text> |
| | | </view> |
| | | |
| | | <!-- 任务详细信息 --> |
| | |
| | | <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> |
| | |
| | | |
| | | <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() { |
| | |
| | | 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 || "未知编号", |
| | |
| | | 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 = { |
| | |
| | | }, |
| | | |
| | | // 处理任务操作 |
| | | 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": |
| | |
| | | |
| | | case "complete": |
| | | // 已完成 -> 状态变为已完成 |
| | | this.$modal |
| | | .confirm("确认任务已完成?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "COMPLETED", "任务已完成"); |
| | | }) |
| | | .catch(() => {}); |
| | | // 需要检查是否上传了知情同意书 |
| | | this.checkConsentAttachmentAndThen(task.taskId, "COMPLETED", "任务已完成"); |
| | | break; |
| | | } |
| | | }, |
| | |
| | | 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(() => {}); |
| | | } |
| | | }, |
| | | |
| | | // 获取位置信息并更新状态 |
| | |
| | | * { |
| | | -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; |
| | | } |
| | | |
| | | // 用户信息区域 |
| | |
| | | } |
| | | } |
| | | |
| | | // 任务编号单独一行 |
| | | // 任务编号和时间在同一行显示 |
| | | .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; |
| | |
| | | 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> |