| | |
| | | <view class="user-info-content"> |
| | | <view class="user-details"> |
| | | <view class="user-info-row"> |
| | | <text class="user-name">{{ userName || '未登录' }}</text> |
| | | <text class="separator" v-if="currentUser.branchCompanyName">|</text> |
| | | <text class="user-name">{{ userName || "未登录" }}</text> |
| | | <text class="separator" v-if="currentUser.branchCompanyName" |
| | | >|</text |
| | | > |
| | | <view class="branch-company" v-if="currentUser.branchCompanyName"> |
| | | <uni-icons type="location" size="16" color="#666" style="margin-right: 4rpx;"></uni-icons> |
| | | <uni-icons |
| | | type="location" |
| | | size="16" |
| | | color="#666" |
| | | style="margin-right: 4rpx" |
| | | ></uni-icons> |
| | | <text>{{ currentUser.branchCompanyName }}</text> |
| | | </view> |
| | | <text class="separator" v-if="boundVehicle">|</text> |
| | | <view class="vehicle-info" @click.stop="goToBindVehicle" v-if="boundVehicle"> |
| | | <view |
| | | class="vehicle-info" |
| | | @click.stop="goToBindVehicle" |
| | | v-if="boundVehicle" |
| | | > |
| | | <text>{{ boundVehicle }}</text> |
| | | <uni-icons |
| | | type="loop" |
| | | size="16" |
| | | <uni-icons |
| | | type="loop" |
| | | size="16" |
| | | color="#007AFF" |
| | | style="margin-left: 4rpx;" |
| | | style="margin-left: 4rpx" |
| | | ></uni-icons> |
| | | </view> |
| | | </view> |
| | | <view class="bind-vehicle-btn" v-if="!boundVehicle" @click="goToBindVehicle"> |
| | | <uni-icons type="plus-filled" size="16" color="#007AFF" style="margin-right: 4rpx;"></uni-icons> |
| | | <view |
| | | class="bind-vehicle-btn" |
| | | v-if="!boundVehicle" |
| | | @click="goToBindVehicle" |
| | | > |
| | | <uni-icons |
| | | type="plus-filled" |
| | | size="16" |
| | | color="#007AFF" |
| | | style="margin-right: 4rpx" |
| | | ></uni-icons> |
| | | <text>绑定车牌</text> |
| | | </view> |
| | | </view> |
| | |
| | | <uni-icons type="chat" size="24" color="#007AFF"></uni-icons> |
| | | </view> |
| | | <view class="message-text">消息中心</view> |
| | | <view class="unread-dot" v-if="unreadMessageCount > 0">{{ unreadMessageCount }}</view> |
| | | <view class="unread-dot" v-if="unreadMessageCount > 0">{{ |
| | | unreadMessageCount |
| | | }}</view> |
| | | <view class="arrow"> |
| | | <uni-icons type="arrowright" size="16" color="#999"></uni-icons> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 订阅通知提示卡片(未订阅时显示) --> |
| | | <view |
| | | class="subscribe-banner" |
| | | v-if="!hasSubscribed" |
| | | @click="clickConfirmsubscribeTaskNotify" |
| | | > |
| | | <view class="banner-icon"> |
| | | <uni-icons type="bell" size="28" color="#ff9500"></uni-icons> |
| | | </view> |
| | | <view class="banner-content"> |
| | | <view class="banner-title">开启任务通知</view> |
| | | <view class="banner-desc">及时接收任务分配和状态更新提醒</view> |
| | | </view> |
| | | <view class="banner-action"> |
| | | <text>立即开启</text> |
| | | <uni-icons type="arrowright" size="16" color="#007AFF"></uni-icons> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <view class="task-main" @click="viewTaskDetail(task)"> |
| | | <!-- 任务头部:标题和状态标签 --> |
| | | <view class="task-header"> |
| | | <view class="task-title">{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view> |
| | | <view class="task-status" :class="task.taskStatus === 'PENDING' ? 'status-pending' : task.taskStatus === 'DEPARTING' ? 'status-departing' : task.taskStatus === 'ARRIVED' ? 'status-arrived' : task.taskStatus === 'RETURNING' ? 'status-returning' : task.taskStatus === 'COMPLETED' ? 'status-completed' : task.taskStatus === 'CANCELLED' ? 'status-cancelled' : task.taskStatus === 'IN_PROGRESS' ? 'status-in-progress' : 'status-default'"> |
| | | <view class="task-title" |
| | | >{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view |
| | | > |
| | | <view |
| | | class="task-status" |
| | | :class=" |
| | | task.taskStatus === 'PENDING' |
| | | ? 'status-pending' |
| | | : task.taskStatus === 'DEPARTING' |
| | | ? 'status-departing' |
| | | : task.taskStatus === 'ARRIVED' |
| | | ? 'status-arrived' |
| | | : task.taskStatus === 'RETURNING' |
| | | ? 'status-returning' |
| | | : task.taskStatus === 'COMPLETED' |
| | | ? 'status-completed' |
| | | : task.taskStatus === 'CANCELLED' |
| | | ? 'status-cancelled' |
| | | : task.taskStatus === 'IN_PROGRESS' |
| | | ? 'status-in-progress' |
| | | : 'status-default' |
| | | " |
| | | > |
| | | {{ getStatusText(task.status) }} |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 任务编号单独一行 --> |
| | | <view class="task-code-row"> |
| | | <text class="task-code">{{ task.taskNo }}</text> |
| | | <text class="task-code">{{ task.showTaskCode }}</text> |
| | | </view> |
| | | |
| | | |
| | | <!-- 任务详细信息 --> |
| | | <view class="task-info"> |
| | | <view class="info-row"> |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 操作按钮 --> |
| | | <view class="task-actions"> |
| | | <!-- 待处理状态: 显示出发、取消 --> |
| | | <template v-if="task.taskStatus === 'PENDING'"> |
| | | <button |
| | | class="action-btn primary" |
| | | <button |
| | | class="action-btn primary" |
| | | @click="handleTaskAction(task, 'depart')" |
| | | > |
| | | 出发 |
| | | </button> |
| | | <button |
| | | class="action-btn cancel" |
| | | <button |
| | | class="action-btn cancel" |
| | | @click="handleTaskAction(task, 'cancel')" |
| | | > |
| | | 取消 |
| | | </button> |
| | | </template> |
| | | |
| | | |
| | | <!-- 出发中状态: 显示已到达、强制结束 --> |
| | | <template v-else-if="task.taskStatus === 'DEPARTING'"> |
| | | <button |
| | | class="action-btn primary" |
| | | <button |
| | | class="action-btn primary" |
| | | @click="handleTaskAction(task, 'arrive')" |
| | | > |
| | | 已到达 |
| | | </button> |
| | | <button |
| | | class="action-btn cancel" |
| | | <button |
| | | class="action-btn cancel" |
| | | @click="handleTaskAction(task, 'forceCancel')" |
| | | > |
| | | 强制结束 |
| | | </button> |
| | | </template> |
| | | |
| | | |
| | | <!-- 已到达状态: 显示已返程 --> |
| | | <template v-else-if="task.taskStatus === 'ARRIVED'"> |
| | | <button |
| | | class="action-btn primary" |
| | | <button |
| | | class="action-btn primary" |
| | | @click="handleTaskAction(task, 'return')" |
| | | > |
| | | 已返程 |
| | | </button> |
| | | </template> |
| | | |
| | | |
| | | <!-- 返程中状态: 显示已完成 --> |
| | | <template v-else-if="task.taskStatus === 'RETURNING'"> |
| | | <button |
| | | class="action-btn primary" |
| | | <button |
| | | class="action-btn primary" |
| | | @click="handleTaskAction(task, 'complete')" |
| | | > |
| | | 已完成 |
| | | </button> |
| | | </template> |
| | | |
| | | |
| | | <!-- 已完成/已取消: 不显示按钮 --> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <view class="no-data" v-if="runningTasks.length === 0"> |
| | | <uni-icons type="info" size="40" color="#ccc"></uni-icons> |
| | | <text>暂无正在运行的任务</text> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | import { getMyTasks, changeTaskStatus } from '@/api/task' |
| | | import { getUserProfile } from '@/api/system/user' |
| | | import { getUserBoundVehicle } from '@/api/vehicle' |
| | | import { getUnreadCount } from '@/api/message' |
| | | import { formatDateTime } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | // 用户绑定的车辆信息 |
| | | boundVehicle: '', |
| | | boundVehicleId: null, |
| | | |
| | | // 消息数据 |
| | | messages: [], |
| | | unreadMessageCount: 0, |
| | | |
| | | // 正在运行的任务列表 |
| | | taskList: [], |
| | | loading: false |
| | | } |
| | | import { mapState } from "vuex"; |
| | | import { getMyTasks, changeTaskStatus } 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"; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | // 用户绑定的车辆信息 |
| | | boundVehicle: "", |
| | | boundVehicleId: null, |
| | | |
| | | // 消息数据 |
| | | messages: [], |
| | | unreadMessageCount: 0, |
| | | |
| | | // 正在运行的任务列表 |
| | | taskList: [], |
| | | loading: false, |
| | | |
| | | // 订阅状态 |
| | | hasSubscribed: false, |
| | | }; |
| | | }, |
| | | computed: { |
| | | ...mapState({ |
| | | userName: (state) => state.user.nickName, |
| | | currentUser: (state) => state.user, |
| | | }), |
| | | |
| | | // 正在运行的任务(待处理和各种处理中的任务) |
| | | runningTasks() { |
| | | return this.taskList.filter((task) => { |
| | | // 包含待处理、出发中、已到达、返程中等所有未完成的状态 |
| | | return [ |
| | | "PENDING", |
| | | "DEPARTING", |
| | | "ARRIVED", |
| | | "RETURNING", |
| | | "IN_PROGRESS", |
| | | ].includes(task.taskStatus); |
| | | }); |
| | | }, |
| | | computed: { |
| | | ...mapState({ |
| | | userName: state => state.user.nickName, |
| | | currentUser: state => state.user |
| | | }), |
| | | |
| | | // 正在运行的任务(待处理和各种处理中的任务) |
| | | runningTasks() { |
| | | return this.taskList.filter(task => { |
| | | // 包含待处理、出发中、已到达、返程中等所有未完成的状态 |
| | | return ['PENDING', 'DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(task.taskStatus) |
| | | }, |
| | | onLoad() { |
| | | // 检查用户是否已登录 |
| | | const userId = this.currentUser.userId; |
| | | if (!userId) { |
| | | console.log("用户未登录,跳过加载数据"); |
| | | return; |
| | | } |
| | | |
| | | // 检查订阅状态(先检查本地,后面会检查微信官方状态) |
| | | this.hasSubscribed = true;//subscribeManager.checkLocalSubscribeStatus(); |
| | | |
| | | // 自动订阅(如果未订阅则显示确认弹窗) |
| | | this.autoSubscribeOnLaunch(); |
| | | |
| | | // 加载用户绑定车辆信息 |
| | | this.loadUserVehicle(); |
| | | // 加载正在运行的任务 |
| | | this.loadRunningTasks(); |
| | | // 加载未读消息数量 |
| | | this.loadUnreadMessageCount(); |
| | | }, |
| | | onShow() { |
| | | // 检查用户是否已登录 |
| | | const userId = this.currentUser.userId; |
| | | if (!userId) { |
| | | console.log("用户未登录,跳过加载数据"); |
| | | return; |
| | | } |
| | | |
| | | // 每次显示页面时刷新任务列表、绑定车辆和消息数量 |
| | | this.loadUserVehicle(); |
| | | this.loadRunningTasks(); |
| | | this.loadUnreadMessageCount(); |
| | | }, |
| | | onPullDownRefresh() { |
| | | // 下拉刷新 |
| | | this.loadRunningTasks(); |
| | | setTimeout(() => { |
| | | uni.stopPullDownRefresh(); |
| | | }, 1000); |
| | | }, |
| | | methods: { |
| | | // 自动订阅(小程序启动时调用) |
| | | autoSubscribeOnLaunch() { |
| | | subscribeManager.autoSubscribe() |
| | | .then((result) => { |
| | | if (result.skipped) { |
| | | console.log('用户已订阅,无需重复订阅'); |
| | | this.hasSubscribed = true; |
| | | } else if (result.success) { |
| | | this.hasSubscribed = true; |
| | | console.log('自动订阅成功'); |
| | | } else { |
| | | // 订阅失败或被拒绝,更新状态 |
| | | this.hasSubscribed = false; |
| | | } |
| | | |
| | | // 如果返回了状态信息,输出详细状态 |
| | | if (result.status) { |
| | | console.log('详细订阅状态:', result.status); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.log('自动订阅取消或失败:', error); |
| | | this.hasSubscribed = false; |
| | | }); |
| | | }, |
| | | |
| | | // 加载用户绑定的车辆信息 |
| | | loadUserVehicle() { |
| | | const userId = this.currentUser.userId; |
| | | if (!userId) { |
| | | console.error("用户未登录,无法获取绑定车辆信息"); |
| | | this.boundVehicle = ""; |
| | | this.boundVehicleId = null; |
| | | return; |
| | | } |
| | | |
| | | getUserBoundVehicle(userId) |
| | | .then((response) => { |
| | | if (response.code === 200 && response.data) { |
| | | const vehicle = response.data; |
| | | this.boundVehicle = vehicle.vehicleNumber || "未知车牌"; |
| | | this.boundVehicleId = vehicle.vehicleId; |
| | | console.log("用户绑定车辆:", this.boundVehicle); |
| | | } else { |
| | | this.boundVehicle = ""; |
| | | this.boundVehicleId = null; |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.error("获取绑定车辆信息失败:", error); |
| | | this.boundVehicle = ""; |
| | | this.boundVehicleId = null; |
| | | }); |
| | | }, |
| | | |
| | | // 加载未读消息数量 |
| | | loadUnreadMessageCount() { |
| | | // 检查用户是否已登录 |
| | | const userId = this.currentUser.userId; |
| | | if (!userId) { |
| | | console.log("用户未登录,跳过获取未读消息数量"); |
| | | return; |
| | | } |
| | | |
| | | getUnreadCount() |
| | | .then((response) => { |
| | | if (response.code === 200) { |
| | | this.unreadMessageCount = response.data || 0; |
| | | // 更新TabBar徽标 |
| | | this.updateTabBarBadge(this.unreadMessageCount); |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.error("获取未读消息数量失败:", error); |
| | | }); |
| | | }, |
| | | |
| | | // 更新TabBar徽标 |
| | | updateTabBarBadge(count) { |
| | | if (count > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, // 消息页面在tabBar中的索引 |
| | | text: count > 99 ? "99+" : count.toString(), |
| | | }); |
| | | } else { |
| | | uni.removeTabBarBadge({ |
| | | index: 3, |
| | | }); |
| | | } |
| | | }, |
| | | onLoad() { |
| | | // 检查用户是否已登录 |
| | | const userId = this.currentUser.userId |
| | | |
| | | // 加载用户信息(保留以兼容之前的代码) |
| | | loadUserProfile() { |
| | | const userId = this.currentUser.userId; |
| | | if (!userId) { |
| | | console.log('用户未登录,跳过加载数据') |
| | | return |
| | | console.error("用户未登录,无法获取用户信息"); |
| | | return; |
| | | } |
| | | |
| | | // 加载用户绑定车辆信息 |
| | | this.loadUserVehicle() |
| | | // 加载正在运行的任务 |
| | | this.loadRunningTasks() |
| | | // 加载未读消息数量 |
| | | this.loadUnreadMessageCount() |
| | | }, |
| | | onShow() { |
| | | // 检查用户是否已登录 |
| | | const userId = this.currentUser.userId |
| | | if (!userId) { |
| | | console.log('用户未登录,跳过加载数据') |
| | | return |
| | | } |
| | | |
| | | // 每次显示页面时刷新任务列表、绑定车辆和消息数量 |
| | | this.loadUserVehicle() |
| | | this.loadRunningTasks() |
| | | this.loadUnreadMessageCount() |
| | | }, |
| | | onPullDownRefresh() { |
| | | // 下拉刷新 |
| | | this.loadRunningTasks() |
| | | setTimeout(() => { |
| | | uni.stopPullDownRefresh() |
| | | }, 1000) |
| | | }, |
| | | methods: { |
| | | // 加载用户绑定的车辆信息 |
| | | loadUserVehicle() { |
| | | const userId = this.currentUser.userId |
| | | if (!userId) { |
| | | console.error('用户未登录,无法获取绑定车辆信息') |
| | | this.boundVehicle = '' |
| | | this.boundVehicleId = null |
| | | return |
| | | } |
| | | |
| | | getUserBoundVehicle(userId).then(response => { |
| | | if (response.code === 200 && response.data) { |
| | | const vehicle = response.data |
| | | this.boundVehicle = vehicle.vehicleNumber || '未知车牌' |
| | | this.boundVehicleId = vehicle.vehicleId |
| | | console.log('用户绑定车辆:', this.boundVehicle) |
| | | } else { |
| | | this.boundVehicle = '' |
| | | this.boundVehicleId = null |
| | | } |
| | | }).catch(error => { |
| | | console.error('获取绑定车辆信息失败:', error) |
| | | this.boundVehicle = '' |
| | | this.boundVehicleId = null |
| | | }) |
| | | }, |
| | | |
| | | // 加载未读消息数量 |
| | | loadUnreadMessageCount() { |
| | | // 检查用户是否已登录 |
| | | const userId = this.currentUser.userId |
| | | if (!userId) { |
| | | console.log('用户未登录,跳过获取未读消息数量') |
| | | return |
| | | } |
| | | |
| | | getUnreadCount().then(response => { |
| | | if (response.code === 200) { |
| | | this.unreadMessageCount = response.data || 0 |
| | | // 更新TabBar徽标 |
| | | this.updateTabBarBadge(this.unreadMessageCount) |
| | | } |
| | | }).catch(error => { |
| | | console.error('获取未读消息数量失败:', error) |
| | | }) |
| | | }, |
| | | |
| | | // 更新TabBar徽标 |
| | | updateTabBarBadge(count) { |
| | | if (count > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, // 消息页面在tabBar中的索引 |
| | | text: count > 99 ? '99+' : count.toString() |
| | | }) |
| | | } else { |
| | | uni.removeTabBarBadge({ |
| | | index: 3 |
| | | }) |
| | | } |
| | | }, |
| | | |
| | | // 加载用户信息(保留以兼容之前的代码) |
| | | loadUserProfile() { |
| | | const userId = this.currentUser.userId |
| | | if (!userId) { |
| | | console.error('用户未登录,无法获取用户信息') |
| | | return |
| | | } |
| | | |
| | | getUserProfile().then(response => { |
| | | const userInfo = response.data || response |
| | | |
| | | getUserProfile() |
| | | .then((response) => { |
| | | const userInfo = response.data || response; |
| | | // 获取用户绑定的车辆信息 |
| | | if (userInfo.boundVehicle) { |
| | | this.boundVehicle = userInfo.boundVehicle.vehicleNumber |
| | | this.boundVehicleId = userInfo.boundVehicle.vehicleId |
| | | this.boundVehicle = userInfo.boundVehicle.vehicleNumber; |
| | | this.boundVehicleId = userInfo.boundVehicle.vehicleId; |
| | | } |
| | | }).catch(error => { |
| | | console.error('获取用户信息失败:', error) |
| | | }) |
| | | }, |
| | | |
| | | // 加载正在运行的任务 |
| | | loadRunningTasks() { |
| | | const userId = this.currentUser.userId |
| | | if (!userId) { |
| | | console.error('用户未登录,无法加载任务列表') |
| | | return |
| | | } |
| | | |
| | | this.loading = true |
| | | // 使用 /task/my 接口获取当前用户相关的所有任务(用户创建、分配给用户、执行人是用户) |
| | | getMyTasks().then(response => { |
| | | this.loading = false |
| | | .catch((error) => { |
| | | console.error("获取用户信息失败:", error); |
| | | }); |
| | | }, |
| | | |
| | | // 加载正在运行的任务 |
| | | loadRunningTasks() { |
| | | const userId = this.currentUser.userId; |
| | | if (!userId) { |
| | | console.error("用户未登录,无法加载任务列表"); |
| | | return; |
| | | } |
| | | |
| | | this.loading = true; |
| | | // 使用 /task/my 接口获取当前用户相关的所有任务(用户创建、分配给用户、执行人是用户) |
| | | getMyTasks() |
| | | .then((response) => { |
| | | this.loading = false; |
| | | // 根据后端返回的数据结构进行解析 |
| | | const data = response.data || response.rows || response || [] |
| | | const data = response.data || response.rows || response || []; |
| | | // 过滤出未完成的任务 |
| | | const allTasks = Array.isArray(data) ? data : [] |
| | | const allTasks = Array.isArray(data) ? data : []; |
| | | this.taskList = allTasks |
| | | .filter(task => { |
| | | .filter((task) => { |
| | | // 只显示未完成和未取消的任务 |
| | | return task.taskStatus !== 'COMPLETED' && task.taskStatus !== 'CANCELLED' |
| | | return ( |
| | | task.taskStatus !== "COMPLETED" && |
| | | task.taskStatus !== "CANCELLED" |
| | | ); |
| | | }) |
| | | .map(task => { |
| | | .map((task) => { |
| | | // 从assignedVehicles数组中获取车辆信息 |
| | | let vehicleInfo = '未分配车辆' |
| | | let vehicleInfo = "未分配车辆"; |
| | | if (task.assignedVehicles && task.assignedVehicles.length > 0) { |
| | | const firstVehicle = task.assignedVehicles[0] |
| | | vehicleInfo = firstVehicle.vehicleNo || '未知车牌' |
| | | const firstVehicle = task.assignedVehicles[0]; |
| | | vehicleInfo = firstVehicle.vehicleNo || "未知车牌"; |
| | | if (task.assignedVehicles.length > 1) { |
| | | vehicleInfo += ` 等${task.assignedVehicles.length}辆` |
| | | vehicleInfo += ` 等${task.assignedVehicles.length}辆`; |
| | | } |
| | | } |
| | | |
| | | |
| | | return { |
| | | ...task, |
| | | // 格式化显示字段 |
| | |
| | | type: task.taskType, |
| | | vehicle: vehicleInfo, |
| | | vehicleList: task.assignedVehicles || [], |
| | | startLocation: this.formatAddress(task.departureAddress || task.startLocation || '未设置'), |
| | | endLocation: this.formatAddress(task.destinationAddress || task.endLocation || '未设置'), |
| | | startTime: task.plannedStartTime ? formatDateTime(task.plannedStartTime, 'YYYY-MM-DD HH:mm') : '未设置', |
| | | assignee: task.assigneeName || '未分配', |
| | | taskNo: task.taskCode || '未知编号', |
| | | status: this.convertStatus(task.taskStatus) // 转换状态格式以兼容旧UI |
| | | } |
| | | }) |
| | | }).catch(error => { |
| | | this.loading = false |
| | | console.error('加载任务列表失败:', error) |
| | | startLocation: this.formatAddress( |
| | | task.departureAddress || task.startLocation || "未设置" |
| | | ), |
| | | endLocation: this.formatAddress( |
| | | task.destinationAddress || task.endLocation || "未设置" |
| | | ), |
| | | startTime: task.plannedStartTime |
| | | ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm") |
| | | : "未设置", |
| | | assignee: task.assigneeName || "未分配", |
| | | taskNo: task.taskCode || "未知编号", |
| | | status: this.convertStatus(task.taskStatus), // 转换状态格式以兼容旧UI |
| | | }; |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 格式化地址 - 只显示-前面的部分 |
| | | formatAddress(address) { |
| | | if (!address) return '未设置' |
| | | const dashIndex = address.indexOf('-') |
| | | if (dashIndex > 0) { |
| | | return address.substring(0, dashIndex) |
| | | } |
| | | return address |
| | | }, |
| | | |
| | | // 转换状态格式(将数据库状态转换为UI使用的状态) |
| | | convertStatus(dbStatus) { |
| | | const statusMap = { |
| | | 'PENDING': 'pending', |
| | | 'DEPARTING': 'processing', |
| | | 'ARRIVED': 'processing', |
| | | 'RETURNING': 'processing', |
| | | 'IN_PROGRESS': 'processing', |
| | | 'COMPLETED': 'completed', |
| | | 'CANCELLED': 'cancelled' |
| | | } |
| | | return statusMap[dbStatus] || 'pending' |
| | | }, |
| | | // 跳转到绑定车辆页面 |
| | | goToBindVehicle() { |
| | | // 跳转到绑定车辆的页面 |
| | | this.$tab.navigateTo('/pages/bind-vehicle'); |
| | | }, |
| | | |
| | | // 跳转到消息页面 |
| | | goToMessages() { |
| | | this.$tab.switchTab('/pages/message/index'); |
| | | }, |
| | | |
| | | // 查看任务详情 |
| | | viewTaskDetail(task) { |
| | | // 跳转到任务详情页面 - 使用taskId |
| | | this.$tab.navigateTo(`/pages/task/detail?id=${task.taskId || task.id}`); |
| | | }, |
| | | |
| | | // 处理任务操作 |
| | | handleTaskAction(task, action) { |
| | | switch (action) { |
| | | case 'depart': |
| | | // 出发 -> 状态变为出发中 |
| | | this.$modal.confirm('确定要出发吗?').then(() => { |
| | | this.updateTaskStatus(task.taskId, 'DEPARTING', '任务已出发') |
| | | }).catch(() => {}); |
| | | break; |
| | | |
| | | case 'cancel': |
| | | // 取消 -> 二次确认后状态变为已取消 |
| | | this.$modal.confirm('确定要取消此任务吗?').then(() => { |
| | | this.updateTaskStatus(task.taskId, 'CANCELLED', '任务已取消') |
| | | }).catch(() => {}); |
| | | break; |
| | | |
| | | case 'arrive': |
| | | // 已到达 -> 状态变为已到达 |
| | | this.$modal.confirm('确认已到达目的地?').then(() => { |
| | | this.updateTaskStatus(task.taskId, 'ARRIVED', '已到达目的地') |
| | | }).catch(() => {}); |
| | | break; |
| | | |
| | | case 'forceCancel': |
| | | // 强制结束 -> 状态变为已取消 |
| | | this.$modal.confirm('确定要强制结束此任务吗?').then(() => { |
| | | this.updateTaskStatus(task.taskId, 'CANCELLED', '任务已强制结束') |
| | | }).catch(() => {}); |
| | | break; |
| | | |
| | | case 'return': |
| | | // 已返程 -> 状态变为返程中 |
| | | this.$modal.confirm('确认开始返程?').then(() => { |
| | | this.updateTaskStatus(task.taskId, 'RETURNING', '已开始返程') |
| | | }).catch(() => {}); |
| | | break; |
| | | |
| | | case 'complete': |
| | | // 已完成 -> 状态变为已完成 |
| | | this.$modal.confirm('确认任务已完成?').then(() => { |
| | | this.updateTaskStatus(task.taskId, 'COMPLETED', '任务已完成') |
| | | }).catch(() => {}); |
| | | break; |
| | | } |
| | | }, |
| | | |
| | | // 更新任务状态 |
| | | updateTaskStatus(taskId, status, remark) { |
| | | // 获取GPS位置信息 |
| | | this.getLocationAndUpdateStatus(taskId, status, remark) |
| | | }, |
| | | |
| | | // 获取位置信息并更新状态 |
| | | getLocationAndUpdateStatus(taskId, status, remark) { |
| | | const that = this |
| | | |
| | | // 使用uni.getLocation获取GPS位置 |
| | | uni.getLocation({ |
| | | type: 'gcj02', |
| | | geocode: true, |
| | | altitude: true, |
| | | success: function(res) { |
| | | console.log('GPS定位成功:', res) |
| | | |
| | | const statusData = { |
| | | taskStatus: status, |
| | | remark: remark, |
| | | latitude: res.latitude, |
| | | longitude: res.longitude, |
| | | locationAddress: res.address ? res.address.street || res.address.poiName || '' : '', |
| | | locationProvince: res.address ? res.address.province || '' : '', |
| | | locationCity: res.address ? res.address.city || '' : '', |
| | | locationDistrict: res.address ? res.address.district || '' : '', |
| | | gpsAccuracy: res.accuracy, |
| | | altitude: res.altitude, |
| | | speed: res.speed, |
| | | heading: res.direction || res.heading |
| | | } |
| | | |
| | | changeTaskStatus(taskId, statusData).then(response => { |
| | | that.$modal.showToast('状态更新成功') |
| | | that.loadRunningTasks() |
| | | }).catch(error => { |
| | | console.error('更新任务状态失败:', error) |
| | | that.$modal.showToast('状态更新失败,请重试') |
| | | .catch((error) => { |
| | | this.loading = false; |
| | | console.error("加载任务列表失败:", error); |
| | | }); |
| | | }, |
| | | |
| | | // 格式化地址 - 只显示-前面的部分 |
| | | formatAddress(address) { |
| | | if (!address) return "未设置"; |
| | | const dashIndex = address.indexOf("-"); |
| | | if (dashIndex > 0) { |
| | | return address.substring(0, dashIndex); |
| | | } |
| | | return address; |
| | | }, |
| | | |
| | | // 转换状态格式(将数据库状态转换为UI使用的状态) |
| | | convertStatus(dbStatus) { |
| | | const statusMap = { |
| | | PENDING: "pending", |
| | | DEPARTING: "processing", |
| | | ARRIVED: "processing", |
| | | RETURNING: "processing", |
| | | IN_PROGRESS: "processing", |
| | | COMPLETED: "completed", |
| | | CANCELLED: "cancelled", |
| | | }; |
| | | return statusMap[dbStatus] || "pending"; |
| | | }, |
| | | // 跳转到绑定车辆页面 |
| | | goToBindVehicle() { |
| | | // 跳转到绑定车辆的页面 |
| | | this.$tab.navigateTo("/pages/bind-vehicle"); |
| | | }, |
| | | |
| | | // 跳转到消息页面 |
| | | goToMessages() { |
| | | this.$tab.switchTab("/pages/message/index"); |
| | | }, |
| | | |
| | | // 查看任务详情 |
| | | viewTaskDetail(task) { |
| | | // 跳转到任务详情页面 - 使用taskId |
| | | this.$tab.navigateTo(`/pagesTask/detail?id=${task.taskId || task.id}`); |
| | | }, |
| | | |
| | | // 处理任务操作 |
| | | handleTaskAction(task, action) { |
| | | switch (action) { |
| | | case "depart": |
| | | // 出发 -> 状态变为出发中 |
| | | this.$modal |
| | | .confirm("确定要出发吗?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发"); |
| | | }) |
| | | }, |
| | | fail: function(err) { |
| | | console.error('GPS定位失败:', err) |
| | | |
| | | that.$modal.confirm('GPS定位失败,是否继续更新状态?').then(() => { |
| | | .catch(() => {}); |
| | | break; |
| | | |
| | | case "cancel": |
| | | // 取消 -> 二次确认后状态变为已取消 |
| | | this.$modal |
| | | .confirm("确定要取消此任务吗?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "CANCELLED", "任务已取消"); |
| | | }) |
| | | .catch(() => {}); |
| | | break; |
| | | |
| | | case "arrive": |
| | | // 已到达 -> 状态变为已到达 |
| | | this.$modal |
| | | .confirm("确认已到达目的地?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "ARRIVED", "已到达目的地"); |
| | | }) |
| | | .catch(() => {}); |
| | | break; |
| | | |
| | | case "forceCancel": |
| | | // 强制结束 -> 状态变为已取消 |
| | | this.$modal |
| | | .confirm("确定要强制结束此任务吗?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "CANCELLED", "任务已强制结束"); |
| | | }) |
| | | .catch(() => {}); |
| | | break; |
| | | |
| | | case "return": |
| | | // 已返程 -> 状态变为返程中 |
| | | this.$modal |
| | | .confirm("确认开始返程?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "RETURNING", "已开始返程"); |
| | | }) |
| | | .catch(() => {}); |
| | | break; |
| | | |
| | | case "complete": |
| | | // 已完成 -> 状态变为已完成 |
| | | this.$modal |
| | | .confirm("确认任务已完成?") |
| | | .then(() => { |
| | | this.updateTaskStatus(task.taskId, "COMPLETED", "任务已完成"); |
| | | }) |
| | | .catch(() => {}); |
| | | break; |
| | | } |
| | | }, |
| | | |
| | | // 更新任务状态 |
| | | updateTaskStatus(taskId, status, remark) { |
| | | // 获取GPS位置信息 |
| | | this.getLocationAndUpdateStatus(taskId, status, remark); |
| | | }, |
| | | |
| | | // 获取位置信息并更新状态 |
| | | getLocationAndUpdateStatus(taskId, status, remark) { |
| | | const that = this; |
| | | |
| | | // 使用uni.getLocation获取GPS位置 |
| | | uni.getLocation({ |
| | | type: "gcj02", |
| | | geocode: true, |
| | | altitude: true, |
| | | success: function (res) { |
| | | console.log("GPS定位成功:", res); |
| | | |
| | | const statusData = { |
| | | taskStatus: status, |
| | | remark: remark, |
| | | latitude: res.latitude, |
| | | longitude: res.longitude, |
| | | locationAddress: res.address |
| | | ? res.address.street || res.address.poiName || "" |
| | | : "", |
| | | locationProvince: res.address ? res.address.province || "" : "", |
| | | locationCity: res.address ? res.address.city || "" : "", |
| | | locationDistrict: res.address ? res.address.district || "" : "", |
| | | gpsAccuracy: res.accuracy, |
| | | altitude: res.altitude, |
| | | speed: res.speed, |
| | | heading: res.direction || res.heading, |
| | | }; |
| | | |
| | | changeTaskStatus(taskId, statusData) |
| | | .then((response) => { |
| | | that.$modal.showToast("状态更新成功"); |
| | | that.loadRunningTasks(); |
| | | }) |
| | | .catch((error) => { |
| | | console.error("更新任务状态失败:", error); |
| | | that.$modal.showToast("状态更新失败,请重试"); |
| | | }); |
| | | }, |
| | | fail: function (err) { |
| | | console.error("GPS定位失败:", err); |
| | | |
| | | that.$modal |
| | | .confirm("GPS定位失败,是否继续更新状态?") |
| | | .then(() => { |
| | | const statusData = { |
| | | taskStatus: status, |
| | | remark: remark |
| | | } |
| | | |
| | | changeTaskStatus(taskId, statusData).then(response => { |
| | | that.$modal.showToast('状态更新成功') |
| | | that.loadRunningTasks() |
| | | }).catch(error => { |
| | | console.error('更新任务状态失败:', error) |
| | | that.$modal.showToast('状态更新失败,请重试') |
| | | }) |
| | | }).catch(() => {}) |
| | | remark: remark, |
| | | }; |
| | | |
| | | changeTaskStatus(taskId, statusData) |
| | | .then((response) => { |
| | | that.$modal.showToast("状态更新成功"); |
| | | that.loadRunningTasks(); |
| | | }) |
| | | .catch((error) => { |
| | | console.error("更新任务状态失败:", error); |
| | | that.$modal.showToast("状态更新失败,请重试"); |
| | | }); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | }); |
| | | }, |
| | | |
| | | // 获取状态样式类 |
| | | getStatusClass(status) { |
| | | const statusClassMap = { |
| | | PENDING: "status-pending", |
| | | DEPARTING: "status-departing", |
| | | ARRIVED: "status-arrived", |
| | | RETURNING: "status-returning", |
| | | COMPLETED: "status-completed", |
| | | CANCELLED: "status-cancelled", |
| | | IN_PROGRESS: "status-in-progress", |
| | | }; |
| | | return statusClassMap[status] || "status-default"; |
| | | }, |
| | | |
| | | getStatusText(status) { |
| | | // 支持新旧两种状态格式 |
| | | const statusMap = { |
| | | // 新格式(数据库状态) |
| | | PENDING: "待处理", |
| | | DEPARTING: "出发中", |
| | | ARRIVED: "已到达", |
| | | RETURNING: "返程中", |
| | | COMPLETED: "已完成", |
| | | CANCELLED: "已取消", |
| | | IN_PROGRESS: "处理中", |
| | | // 旧格式(UI状态) |
| | | pending: "待处理", |
| | | processing: "处理中", |
| | | completed: "已完成", |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }, |
| | | |
| | | getTaskTypeText(type) { |
| | | const typeMap = { |
| | | // 新格式(数据库类型) |
| | | MAINTENANCE: "维修保养", |
| | | FUEL: "加油", |
| | | OTHER: "其他", |
| | | EMERGENCY_TRANSFER: "转运任务", |
| | | WELFARE: "福祉车", |
| | | // 旧格式(UI类型) |
| | | maintenance: "维修保养", |
| | | refuel: "加油", |
| | | inspection: "巡检", |
| | | emergency: "转运任务", |
| | | welfare: "福祉车", |
| | | }; |
| | | return typeMap[type] || "未知类型"; |
| | | }, |
| | | |
| | | clickConfirmsubscribeTaskNotify() { |
| | | subscribeManager.subscribeWithConfirm() |
| | | .then((result) => { |
| | | if (result.success) { |
| | | this.hasSubscribed = true; |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 获取状态样式类 |
| | | getStatusClass(status) { |
| | | const statusClassMap = { |
| | | 'PENDING': 'status-pending', |
| | | 'DEPARTING': 'status-departing', |
| | | 'ARRIVED': 'status-arrived', |
| | | 'RETURNING': 'status-returning', |
| | | 'COMPLETED': 'status-completed', |
| | | 'CANCELLED': 'status-cancelled', |
| | | 'IN_PROGRESS': 'status-in-progress' |
| | | } |
| | | return statusClassMap[status] || 'status-default' |
| | | }, |
| | | |
| | | getStatusText(status) { |
| | | // 支持新旧两种状态格式 |
| | | const statusMap = { |
| | | // 新格式(数据库状态) |
| | | 'PENDING': '待处理', |
| | | 'DEPARTING': '出发中', |
| | | 'ARRIVED': '已到达', |
| | | 'RETURNING': '返程中', |
| | | 'COMPLETED': '已完成', |
| | | 'CANCELLED': '已取消', |
| | | 'IN_PROGRESS': '处理中', |
| | | // 旧格式(UI状态) |
| | | 'pending': '待处理', |
| | | 'processing': '处理中', |
| | | 'completed': '已完成' |
| | | } |
| | | return statusMap[status] || '未知' |
| | | }, |
| | | |
| | | getTaskTypeText(type) { |
| | | const typeMap = { |
| | | // 新格式(数据库类型) |
| | | 'MAINTENANCE': '维修保养', |
| | | 'FUEL': '加油', |
| | | 'OTHER': '其他', |
| | | 'EMERGENCY_TRANSFER': '转运任务', |
| | | 'WELFARE': '福祉车', |
| | | // 旧格式(UI类型) |
| | | 'maintenance': '维修保养', |
| | | 'refuel': '加油', |
| | | 'inspection': '巡检', |
| | | 'emergency': '转运任务', |
| | | 'welfare': '福祉车' |
| | | } |
| | | return typeMap[type] || '未知类型' |
| | | } |
| | | } |
| | | } |
| | | .catch((error) => { |
| | | console.log('订阅取消或失败:', error); |
| | | }); |
| | | }, |
| | | |
| | | // 订阅任务通知(直接调用,不显示确认弹窗) |
| | | subscribeTaskNotify() { |
| | | subscribeManager.subscribeDirect() |
| | | .then((result) => { |
| | | if (result.success) { |
| | | this.hasSubscribed = true; |
| | | } |
| | | }) |
| | | .catch((error) => { |
| | | console.log('订阅失败:', error); |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .home-container { |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | | height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | // 隐藏滚动条但保持滚动功能 |
| | | ::-webkit-scrollbar { |
| | | display: none; |
| | | width: 0 !important; |
| | | height: 0 !important; |
| | | background: transparent; |
| | | } |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | .home-container { |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | | height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | // 隐藏滚动条但保持滚动功能 |
| | | ::-webkit-scrollbar { |
| | | display: none; |
| | | width: 0 !important; |
| | | height: 0 !important; |
| | | background: transparent; |
| | | } |
| | | |
| | | // 用户信息区域 |
| | | .user-info-section { |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | flex-shrink: 0; // 防止收缩 |
| | | |
| | | .user-info-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .user-details { |
| | | flex: 1; |
| | | |
| | | .user-info-row { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | margin-bottom: 12rpx; |
| | | |
| | | .user-name { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | |
| | | .separator { |
| | | margin: 0 12rpx; |
| | | color: #ddd; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .branch-company { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .vehicle-info { |
| | | font-size: 26rpx; |
| | | color: #007AFF; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | } |
| | | |
| | | // 用户信息区域 |
| | | .user-info-section { |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | flex-shrink: 0; // 防止收缩 |
| | | |
| | | .user-info-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .user-details { |
| | | flex: 1; |
| | | |
| | | .user-info-row { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | margin-bottom: 12rpx; |
| | | |
| | | .user-name { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | |
| | | .bind-vehicle-btn { |
| | | |
| | | .separator { |
| | | margin: 0 12rpx; |
| | | color: #ddd; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .branch-company { |
| | | font-size: 26rpx; |
| | | color: #007AFF; |
| | | color: #666; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | &:active { |
| | | opacity: 0.7; |
| | | } |
| | | } |
| | | |
| | | .vehicle-info { |
| | | font-size: 26rpx; |
| | | color: #007aff; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | .bind-vehicle-btn { |
| | | font-size: 26rpx; |
| | | color: #007aff; |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | &:active { |
| | | opacity: 0.7; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 消息入口 |
| | | .message-entry { |
| | | } |
| | | |
| | | // 消息入口 |
| | | .message-entry { |
| | | display: flex; |
| | | align-items: center; |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | position: relative; |
| | | |
| | | .message-icon { |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .message-text { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .unread-dot { |
| | | position: absolute; |
| | | top: 15rpx; |
| | | right: 60rpx; |
| | | background-color: #ff4d4f; |
| | | color: white; |
| | | border-radius: 50%; |
| | | width: 32rpx; |
| | | height: 32rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | position: relative; |
| | | |
| | | .message-icon { |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .message-text { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .unread-dot { |
| | | position: absolute; |
| | | top: 15rpx; |
| | | right: 60rpx; |
| | | background-color: #ff4d4f; |
| | | color: white; |
| | | border-radius: 50%; |
| | | width: 32rpx; |
| | | height: 32rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 20rpx; |
| | | } |
| | | |
| | | .arrow { |
| | | margin-left: 20rpx; |
| | | } |
| | | justify-content: center; |
| | | font-size: 20rpx; |
| | | } |
| | | |
| | | // 正在运行的任务标题 |
| | | .running-tasks-header { |
| | | margin-bottom: 20rpx; |
| | | flex-shrink: 0; // 防止收缩 |
| | | |
| | | .header-title { |
| | | font-size: 36rpx; |
| | | |
| | | .arrow { |
| | | margin-left: 20rpx; |
| | | } |
| | | } |
| | | |
| | | // 订阅通知横幅 |
| | | .subscribe-banner { |
| | | display: flex; |
| | | align-items: center; |
| | | background: linear-gradient(135deg, #fff9e6 0%, #fff3e0 100%); |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(255, 149, 0, 0.1); |
| | | border: 1rpx solid #ffe0b2; |
| | | |
| | | .banner-icon { |
| | | margin-right: 20rpx; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .banner-content { |
| | | flex: 1; |
| | | |
| | | .banner-title { |
| | | font-size: 30rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | margin-bottom: 8rpx; |
| | | } |
| | | |
| | | .banner-desc { |
| | | font-size: 24rpx; |
| | | color: #666; |
| | | line-height: 1.4; |
| | | } |
| | | } |
| | | |
| | | // 正在运行的任务列表 |
| | | .running-tasks-section { |
| | | flex: 1; |
| | | |
| | | .banner-action { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 12rpx 24rpx; |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | // 隐藏滚动条但保持滚动功能 |
| | | ::-webkit-scrollbar { |
| | | display: none; |
| | | width: 0 !important; |
| | | height: 0 !important; |
| | | background: transparent; |
| | | border-radius: 30rpx; |
| | | flex-shrink: 0; |
| | | |
| | | text { |
| | | font-size: 26rpx; |
| | | color: #007aff; |
| | | margin-right: 4rpx; |
| | | } |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | |
| | | .task-list { |
| | | .task-item { |
| | | background-color: #fafafa; |
| | | border-radius: 15rpx; |
| | | margin-bottom: 30rpx; |
| | | overflow: hidden; |
| | | |
| | | .task-main { |
| | | padding: 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | |
| | | // 任务头部:标题和状态 |
| | | .task-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | margin-bottom: 15rpx; |
| | | |
| | | .task-title { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | padding-right: 20rpx; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | .task-status { |
| | | padding: 8rpx 20rpx; |
| | | border-radius: 30rpx; |
| | | font-size: 24rpx; |
| | | white-space: nowrap; |
| | | flex-shrink: 0; |
| | | |
| | | // 待处理 - 橙色 |
| | | &.status-pending { |
| | | background-color: #fff3e0; |
| | | color: #ff9500; |
| | | } |
| | | |
| | | // 出发中 - 蓝色 |
| | | &.status-departing { |
| | | background-color: #e3f2fd; |
| | | color: #007AFF; |
| | | } |
| | | |
| | | // 已到达 - 紫色 |
| | | &.status-arrived { |
| | | background-color: #f3e5f5; |
| | | color: #9c27b0; |
| | | } |
| | | |
| | | // 返程中 - 青色 |
| | | &.status-returning { |
| | | background-color: #e0f2f1; |
| | | color: #009688; |
| | | } |
| | | |
| | | // 已完成 - 绿色 |
| | | &.status-completed { |
| | | background-color: #e8f5e9; |
| | | color: #34C759; |
| | | } |
| | | |
| | | // 已取消 - 灰色 |
| | | &.status-cancelled { |
| | | background-color: #f5f5f5; |
| | | color: #999; |
| | | } |
| | | |
| | | // 处理中 (兼容旧数据) - 蓝色 |
| | | &.status-in-progress { |
| | | background-color: #e3f2fd; |
| | | color: #007AFF; |
| | | } |
| | | |
| | | // 默认样式 |
| | | &.status-default { |
| | | background-color: #f5f5f5; |
| | | color: #666; |
| | | } |
| | | } |
| | | } |
| | | |
| | | &:active { |
| | | opacity: 0.9; |
| | | } |
| | | } |
| | | |
| | | // 正在运行的任务标题 |
| | | .running-tasks-header { |
| | | margin-bottom: 20rpx; |
| | | flex-shrink: 0; // 防止收缩 |
| | | |
| | | .header-title { |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | } |
| | | |
| | | // 正在运行的任务列表 |
| | | .running-tasks-section { |
| | | flex: 1; |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | // 隐藏滚动条但保持滚动功能 |
| | | ::-webkit-scrollbar { |
| | | display: none; |
| | | width: 0 !important; |
| | | height: 0 !important; |
| | | background: transparent; |
| | | } |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | |
| | | .task-list { |
| | | .task-item { |
| | | background-color: #fafafa; |
| | | border-radius: 15rpx; |
| | | margin-bottom: 30rpx; |
| | | overflow: hidden; |
| | | |
| | | .task-main { |
| | | padding: 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | |
| | | // 任务头部:标题和状态 |
| | | .task-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: flex-start; |
| | | margin-bottom: 15rpx; |
| | | |
| | | .task-title { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | padding-right: 20rpx; |
| | | line-height: 1.4; |
| | | } |
| | | |
| | | // 任务编号单独一行 |
| | | .task-code-row { |
| | | margin-bottom: 15rpx; |
| | | padding: 10rpx 0; |
| | | border-bottom: 1rpx dashed #e0e0e0; |
| | | |
| | | .task-code { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | font-weight: 500; |
| | | font-family: monospace; |
| | | |
| | | .task-status { |
| | | padding: 8rpx 20rpx; |
| | | border-radius: 30rpx; |
| | | font-size: 24rpx; |
| | | white-space: nowrap; |
| | | flex-shrink: 0; |
| | | |
| | | // 待处理 - 橙色 |
| | | &.status-pending { |
| | | background-color: #fff3e0; |
| | | color: #ff9500; |
| | | } |
| | | } |
| | | |
| | | .task-info { |
| | | .info-row { |
| | | display: flex; |
| | | margin-bottom: 15rpx; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .info-item { |
| | | flex: 1; |
| | | display: flex; |
| | | |
| | | .label { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-right: 10rpx; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .value { |
| | | font-size: 26rpx; |
| | | flex: 1; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | |
| | | // 出发中 - 蓝色 |
| | | &.status-departing { |
| | | background-color: #e3f2fd; |
| | | color: #007aff; |
| | | } |
| | | |
| | | // 已到达 - 紫色 |
| | | &.status-arrived { |
| | | background-color: #f3e5f5; |
| | | color: #9c27b0; |
| | | } |
| | | |
| | | // 返程中 - 青色 |
| | | &.status-returning { |
| | | background-color: #e0f2f1; |
| | | color: #009688; |
| | | } |
| | | |
| | | // 已完成 - 绿色 |
| | | &.status-completed { |
| | | background-color: #e8f5e9; |
| | | color: #34c759; |
| | | } |
| | | |
| | | // 已取消 - 灰色 |
| | | &.status-cancelled { |
| | | background-color: #f5f5f5; |
| | | color: #999; |
| | | } |
| | | |
| | | // 处理中 (兼容旧数据) - 蓝色 |
| | | &.status-in-progress { |
| | | background-color: #e3f2fd; |
| | | color: #007aff; |
| | | } |
| | | |
| | | // 默认样式 |
| | | &.status-default { |
| | | background-color: #f5f5f5; |
| | | color: #666; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .task-actions { |
| | | display: flex; |
| | | padding: 20rpx; |
| | | |
| | | .action-btn { |
| | | flex: 1; |
| | | height: 70rpx; |
| | | border-radius: 10rpx; |
| | | font-size: 26rpx; |
| | | margin: 0 5rpx; |
| | | background-color: #f0f0f0; |
| | | |
| | | // 任务编号单独一行 |
| | | .task-code-row { |
| | | margin-bottom: 15rpx; |
| | | padding: 10rpx 0; |
| | | border-bottom: 1rpx dashed #e0e0e0; |
| | | |
| | | .task-code { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | |
| | | &.primary { |
| | | background-color: #007AFF; |
| | | color: white; |
| | | } |
| | | |
| | | &.cancel { |
| | | background-color: #ff3b30; |
| | | color: white; |
| | | } |
| | | |
| | | &.disabled { |
| | | opacity: 0.5; |
| | | } |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | font-weight: 500; |
| | | font-family: monospace; |
| | | } |
| | | } |
| | | |
| | | .task-info { |
| | | .info-row { |
| | | display: flex; |
| | | margin-bottom: 15rpx; |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .info-item { |
| | | flex: 1; |
| | | display: flex; |
| | | |
| | | .label { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-right: 10rpx; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .value { |
| | | font-size: 26rpx; |
| | | flex: 1; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .no-data { |
| | | text-align: center; |
| | | padding: 100rpx 0; |
| | | color: #999; |
| | | |
| | | text { |
| | | display: block; |
| | | margin-top: 20rpx; |
| | | |
| | | .task-actions { |
| | | display: flex; |
| | | padding: 20rpx; |
| | | |
| | | .action-btn { |
| | | flex: 1; |
| | | height: 70rpx; |
| | | border-radius: 10rpx; |
| | | font-size: 26rpx; |
| | | margin: 0 5rpx; |
| | | background-color: #f0f0f0; |
| | | color: #333; |
| | | |
| | | &.primary { |
| | | background-color: #007aff; |
| | | color: white; |
| | | } |
| | | |
| | | &.cancel { |
| | | background-color: #ff3b30; |
| | | color: white; |
| | | } |
| | | |
| | | &.disabled { |
| | | opacity: 0.5; |
| | | } |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .no-data { |
| | | text-align: center; |
| | | padding: 100rpx 0; |
| | | color: #999; |
| | | |
| | | text { |
| | | display: block; |
| | | margin-top: 20rpx; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |