<template>
|
<view class="home-container">
|
<!-- 顶部用户信息区域 -->
|
<view class="user-info-section">
|
<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
|
>
|
<view class="branch-company" v-if="currentUser.branchCompanyName">
|
<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"
|
>
|
<text>{{ boundVehicle }}</text>
|
<uni-icons
|
type="loop"
|
size="16"
|
color="#007AFF"
|
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>
|
<text>绑定车牌</text>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- 消息入口 -->
|
<view class="message-entry" @click="goToMessages">
|
<view class="message-icon">
|
<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="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="running-tasks-header">
|
<text class="header-title">正在运行的任务</text>
|
</view>
|
|
<!-- 正在运行的任务列表 -->
|
<scroll-view class="running-tasks-section" scroll-y="true">
|
<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-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>
|
</view>
|
|
<!-- 任务详细信息 -->
|
<view class="task-info">
|
<view class="info-row">
|
<view class="info-item">
|
<view class="label">出发地:</view>
|
<view class="value">{{ task.startLocation }}</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>
|
<view class="info-item">
|
<view class="label">执行人员:</view>
|
<view class="value">{{ task.assignee }}</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- 操作按钮 -->
|
<view class="task-actions">
|
<!-- 待处理状态: 显示出发、取消 -->
|
<template v-if="task.taskStatus === 'PENDING'">
|
<button
|
class="action-btn primary"
|
@click="handleTaskAction(task, 'depart')"
|
>
|
出发
|
</button>
|
<button
|
class="action-btn cancel"
|
@click="handleTaskAction(task, 'cancel')"
|
>
|
取消
|
</button>
|
</template>
|
|
<!-- 出发中状态: 显示已到达、强制结束 -->
|
<template v-else-if="task.taskStatus === 'DEPARTING'">
|
<button
|
class="action-btn primary"
|
@click="handleTaskAction(task, 'arrive')"
|
>
|
已到达
|
</button>
|
<button
|
class="action-btn cancel"
|
@click="handleTaskAction(task, 'forceCancel')"
|
>
|
强制结束
|
</button>
|
</template>
|
|
<!-- 已到达状态: 显示已返程 -->
|
<template v-else-if="task.taskStatus === 'ARRIVED'">
|
<button
|
class="action-btn primary"
|
@click="handleTaskAction(task, 'return')"
|
>
|
已返程
|
</button>
|
</template>
|
|
<!-- 返程中状态: 显示已完成 -->
|
<template v-else-if="task.taskStatus === 'RETURNING'">
|
<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>
|
</view>
|
</view>
|
</scroll-view>
|
</view>
|
</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";
|
import subscribeManager from "@/utils/subscribe";
|
|
export default {
|
data() {
|
return {
|
// 用户绑定的车辆信息
|
boundVehicle: "",
|
boundVehicleId: null,
|
|
// 消息数据
|
messages: [],
|
unreadMessageCount: 0,
|
|
// 正在运行的任务列表
|
taskList: [],
|
loading: false,
|
|
// 订阅状态
|
hasSubscribed: true,
|
};
|
},
|
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 = 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,
|
});
|
}
|
},
|
|
// 加载用户信息(保留以兼容之前的代码)
|
loadUserProfile() {
|
const userId = this.currentUser.userId;
|
if (!userId) {
|
console.error("用户未登录,无法获取用户信息");
|
return;
|
}
|
|
getUserProfile()
|
.then((response) => {
|
const userInfo = response.data || response;
|
// 获取用户绑定的车辆信息
|
if (userInfo.boundVehicle) {
|
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;
|
// 根据后端返回的数据结构进行解析
|
const data = response.data || response.rows || response || [];
|
// 过滤出未完成的任务
|
const allTasks = Array.isArray(data) ? data : [];
|
this.taskList = allTasks
|
.filter((task) => {
|
// 只显示未完成和未取消的任务
|
return (
|
task.taskStatus !== "COMPLETED" &&
|
task.taskStatus !== "CANCELLED"
|
);
|
})
|
.map((task) => {
|
// 从assignedVehicles数组中获取车辆信息
|
let vehicleInfo = "未分配车辆";
|
if (task.assignedVehicles && task.assignedVehicles.length > 0) {
|
const firstVehicle = task.assignedVehicles[0];
|
vehicleInfo = firstVehicle.vehicleNo || "未知车牌";
|
if (task.assignedVehicles.length > 1) {
|
vehicleInfo += ` 等${task.assignedVehicles.length}辆`;
|
}
|
}
|
|
return {
|
...task,
|
// 格式化显示字段
|
id: task.taskId,
|
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);
|
});
|
},
|
|
// 格式化地址 - 只显示-前面的部分
|
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", "任务已出发");
|
})
|
.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(() => {});
|
},
|
});
|
},
|
|
// 获取状态样式类
|
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;
|
}
|
})
|
.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+ */
|
}
|
}
|
|
// 用户信息区域
|
.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;
|
}
|
}
|
|
.bind-vehicle-btn {
|
font-size: 26rpx;
|
color: #007aff;
|
display: flex;
|
align-items: center;
|
|
&:active {
|
opacity: 0.7;
|
}
|
}
|
}
|
}
|
}
|
|
// 消息入口
|
.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;
|
justify-content: center;
|
font-size: 20rpx;
|
}
|
|
.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;
|
}
|
}
|
|
.banner-action {
|
display: flex;
|
align-items: center;
|
padding: 12rpx 24rpx;
|
background-color: white;
|
border-radius: 30rpx;
|
flex-shrink: 0;
|
|
text {
|
font-size: 26rpx;
|
color: #007aff;
|
margin-right: 4rpx;
|
}
|
}
|
|
&: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-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;
|
}
|
}
|
}
|
|
// 任务编号单独一行
|
.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-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;
|
}
|
}
|
}
|
}
|
}
|
|
.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>
|