| | |
| | | </view> |
| | | |
| | | <!-- 正在运行的任务列表 --> |
| | | <scroll-view class="running-tasks-section" scroll-y="true"> |
| | | <scroll-view |
| | | class="running-tasks-section" |
| | | scroll-y="true" |
| | | @scrolltolower="onScrollToLower" |
| | | > |
| | | <view class="task-list"> |
| | | <view class="task-item" v-for="task in runningTasks" :key="task.id"> |
| | | <view class="task-main" @click="viewTaskDetail(task)"> |
| | | <!-- 任务头部:标题和状态标签 --> |
| | | <view class="task-header"> |
| | | <view class="task-title" |
| | | >{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view |
| | | > |
| | | <view class="task-title"> |
| | | {{ getTaskTypeText(task.type) }} - {{ task.vehicle }} |
| | | <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" |
| | | :class=" |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 任务编号单独一行 --> |
| | | <!-- 任务编号和开始时间在同一行显示,但分开一些 --> |
| | | <view class="task-code-row"> |
| | | <text class="task-code">{{ task.taskNo }}</text> |
| | | <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> |
| | |
| | | <uni-icons type="info" size="40" color="#ccc"></uni-icons> |
| | | <text>暂无正在运行的任务</text> |
| | | </view> |
| | | |
| | | <!-- 加载更多提示 --> |
| | | <view class="load-more" v-if="runningTasks.length > 0 && hasMore && loading"> |
| | | <uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons> |
| | | <text>正在加载更多数据...</text> |
| | | </view> |
| | | <view class="load-more no-more" v-else-if="runningTasks.length > 0 && !hasMore"> |
| | | <text>没有更多数据了</text> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | |
| | | unreadMessageCount: 0, |
| | | |
| | | // 正在运行的任务列表 |
| | | taskList: [], |
| | | allTaskList: [], // 存储所有任务数据 |
| | | displayedTaskList: [], // 存储当前显示的任务数据 |
| | | loading: false, |
| | | |
| | | // 订阅状态 |
| | | hasSubscribed: false, |
| | | |
| | | // 前端分页相关 |
| | | currentPage: 1, |
| | | pageSize: 10, |
| | | hasMore: true, |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | |
| | | // 正在运行的任务(待处理和各种处理中的任务) |
| | | runningTasks() { |
| | | return this.taskList.filter((task) => { |
| | | return this.displayedTaskList.filter((task) => { |
| | | // 包含待处理、出发中、已到达、返程中等所有未完成的状态 |
| | | return [ |
| | | "PENDING", |
| | |
| | | } |
| | | |
| | | // 检查订阅状态(先检查本地,后面会检查微信官方状态) |
| | | this.hasSubscribed = subscribeManager.checkLocalSubscribeStatus(); |
| | | this.hasSubscribed = true;//subscribeManager.checkLocalSubscribeStatus(); |
| | | |
| | | // 自动订阅(如果未订阅则显示确认弹窗) |
| | | this.autoSubscribeOnLaunch(); |
| | | // this.autoSubscribeOnLaunch(); |
| | | |
| | | // 加载用户绑定车辆信息 |
| | | this.loadUserVehicle(); |
| | |
| | | |
| | | // 每次显示页面时刷新任务列表、绑定车辆和消息数量 |
| | | this.loadUserVehicle(); |
| | | // 重新加载任务列表时重置分页 |
| | | this.currentPage = 1; |
| | | this.hasMore = true; |
| | | this.loadRunningTasks(); |
| | | this.loadUnreadMessageCount(); |
| | | }, |
| | | onPullDownRefresh() { |
| | | // 下拉刷新时重置分页参数 |
| | | this.currentPage = 1; |
| | | this.hasMore = true; |
| | | // 下拉刷新 |
| | | this.loadRunningTasks(); |
| | | setTimeout(() => { |
| | |
| | | }, 1000); |
| | | }, |
| | | methods: { |
| | | // 滚动到底部时加载更多 |
| | | onScrollToLower() { |
| | | if (this.hasMore && !this.loading) { |
| | | this.loadMoreTasks(); |
| | | } |
| | | }, |
| | | |
| | | // 自动订阅(小程序启动时调用) |
| | | autoSubscribeOnLaunch() { |
| | | subscribeManager.autoSubscribe() |
| | |
| | | this.loading = false; |
| | | // 根据后端返回的数据结构进行解析 |
| | | const data = response.data || response.rows || response || []; |
| | | // 过滤出未完成的任务 |
| | | const allTasks = Array.isArray(data) ? data : []; |
| | | this.taskList = allTasks |
| | | |
| | | // 如果是第一页,直接替换数据;否则追加数据 |
| | | if (this.currentPage === 1) { |
| | | this.allTaskList = data; |
| | | } else { |
| | | this.allTaskList = [...this.allTaskList, ...data]; |
| | | } |
| | | |
| | | // 格式化任务数据 |
| | | this.allTaskList = this.allTaskList |
| | | .filter((task) => { |
| | | // 只显示未完成和未取消的任务 |
| | | return ( |
| | |
| | | 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") |
| | | : "未设置", |
| | |
| | | status: this.convertStatus(task.taskStatus), // 转换状态格式以兼容旧UI |
| | | }; |
| | | }); |
| | | |
| | | // 更新显示的任务列表 |
| | | this.updateDisplayedTaskList(); |
| | | }) |
| | | .catch((error) => { |
| | | this.loading = false; |
| | | console.error("加载任务列表失败:", error); |
| | | }); |
| | | }, |
| | | |
| | | // 更新显示的任务列表(前端分页) |
| | | updateDisplayedTaskList() { |
| | | const start = 0; |
| | | const end = this.currentPage * this.pageSize; |
| | | this.displayedTaskList = this.allTaskList.slice(start, end); |
| | | this.hasMore = end < this.allTaskList.length; |
| | | }, |
| | | |
| | | // 加载更多任务(前端分页) |
| | | loadMoreTasks() { |
| | | if (!this.hasMore || this.loading) return; |
| | | |
| | | this.currentPage++; |
| | | this.updateDisplayedTaskList(); |
| | | }, |
| | | |
| | | // 格式化地址 - 只显示-前面的部分 |
| | |
| | | return address.substring(0, dashIndex); |
| | | } |
| | | 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使用的状态) |
| | |
| | | height: 0 !important; |
| | | background: transparent; |
| | | } |
| | | |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | |
| | | } |
| | | } |
| | | |
| | | // 任务编号单独一行 |
| | | // 任务编号和时间在同一行显示 |
| | | .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; |
| | |
| | | margin-top: 20rpx; |
| | | } |
| | | } |
| | | |
| | | .load-more { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | padding: 20rpx 0; |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | |
| | | &.no-more { |
| | | 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> |