diff --git a/pages.json b/pages.json index b3f3c946..6abc7efb 100644 --- a/pages.json +++ b/pages.json @@ -63,6 +63,90 @@ "navigationStyle": "custom" } }, + { + "path": "pages/mall/delivery/order-detail", + "style": { + "navigationBarTitleText": "订单详情页", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/profile", + "style": { + "navigationBarTitleText": "配送个人中心", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/order-history", + "style": { + "navigationBarTitleText": "历史记录", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/earnings", + "style": { + "navigationBarTitleText": "历史记录", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/tasks", + "style": { + "navigationBarTitleText": "全部任务", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/task-detail", + "style": { + "navigationBarTitleText": "任务详情", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/profile-edit", + "style": { + "navigationBarTitleText": "编辑个人资料", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/ratings", + "style": { + "navigationBarTitleText": "评价", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/vehicle", + "style": { + "navigationBarTitleText": "车辆管理", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/vehicle-add", + "style": { + "navigationBarTitleText": "添加车辆", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/vehicle-edit", + "style": { + "navigationBarTitleText": "添加车辆", + "navigationStyle": "custom" + } + }, + { + "path": "pages/mall/delivery/settings", + "style": { + "navigationBarTitleText": "设置", + "navigationStyle": "custom" + } + }, { "path": "pages/mall/delivery/order-detail", "style": { diff --git a/pages/mall/delivery/delivery.md b/pages/mall/delivery/delivery.md new file mode 100644 index 00000000..3166bf09 --- /dev/null +++ b/pages/mall/delivery/delivery.md @@ -0,0 +1,191 @@ +✅ 明白了!你不需要完整代码,而是希望我**用简洁的 Markdown 文档形式,解释这个 `delivery` 文件夹下的项目结构和每个页面的功能定位**。 + +--- + +# 🚚 配送端模块项目结构说明(`/pages/mall/delivery/`) + +> 本模块为配送员使用的移动端应用核心功能区,涵盖个人中心、任务管理、收入统计、车辆管理等核心功能。 + +--- + +## 📁 目录结构概览 + +``` +delivery/ +├── index.uvue # 配送端首页(工作台) +├── profile.uvue # 个人中心 +├── profile-edit.uvue # 编辑个人信息 +├── settings.uvue # 设置页面 +├── tasks.uvue # 配送任务列表(按状态筛选) +├── task-detail.uvue # 单个任务详情页 +├── order-history.uvue # 历史订单列表 +├── order-detail.uvue # 订单详情页(从历史或当前跳转) +├── earnings.uvue # 收入明细 +├── ratings.uvue # 评价记录 +├── vehicle.uvue # 车辆管理主页 +├── vehicle-add.uvue # 添加车辆 +├── vehicle-edit.uvue # 编辑车辆信息 +└── index.uvue # 首页(与上面重复?应统一命名) +``` + +> 💡 注:`index.uvue` 出现两次,建议保留一个作为首页入口,另一个可重命名为 `dashboard.uvue` 或 `home.uvue` + +--- + +## 🧭 各页面功能说明 + +### 1. `index.uvue` —— **配送端首页 / 工作台** +- ✅ 核心入口页面 +- 📍 展示当前任务、今日数据、快捷操作入口 +- 🔄 可跳转到“个人中心”、“任务列表”、“收入明细”等 + +--- + +### 2. `profile.uvue` —— **个人中心** +- 👤 显示配送员基本信息(头像、姓名、评分、总单数) +- 📊 展示今日配送数据(完成单数、收入、里程、准时率) +- 📈 收入统计图表(最近7天) +- 🚗 功能菜单:收入明细、车辆管理、评价记录、帮助中心、意见反馈 + +--- + +### 3. `profile-edit.uvue` —— **编辑个人信息** +- 🖋️ 修改头像、姓名、身份证号、驾驶证、车辆信息、服务区域等 +- 📱 界面包含表单输入 + 保存按钮 +- ⬅️ 左上角返回按钮(箭头+文字垂直排列) +- 💾 数据本地模拟或调用API更新 + +--- + +### 4. `settings.uvue` —— **设置页面** +- ⚙️ 通用设置项(如通知、隐私、退出登录等) +- 🔐 安全相关设置(修改密码、绑定手机等) +- 📲 通常由 `profile.uvue` 中的“⚙️”图标进入 + +--- + +### 5. `tasks.uvue` —— **配送任务列表** +- 📋 按状态分类展示任务: + - 全部任务 + - 待接单 + - 配送中 + - 已完成 +- 🚀 点击任一任务 → 跳转至 `task-detail.uvue` +- 📈 页面顶部有“工作状态”切换开关(工作中/休息中) + +--- + +### 6. `task-detail.uvue` —— **任务详情页** +- 📍 显示取货地址、送达地址、距离、预计时间 +- 📞 “联系客户”按钮 +- 📝 查看任务详情(可选) +- ✅ 适用于“当前任务”或“待接单”的操作场景 + +--- + +### 7. `order-history.uvue` —— **历史订单列表** +- 📜 展示已完成、已接受、配送中的历史订单 +- 📌 包含订单号、状态、取送货地址、配送费、距离、时间 +- 🔍 点击“查看详情” → 跳转至 `order-detail.uvue`,并携带参数 `?from=history` +- 📅 支持查看“已完成”的订单(仅显示“联系客服”按钮) + +--- + +### 8. `order-detail.uvue` —— **订单详情页(多来源)** +- 🔄 从 `tasks.uvue` 或 `order-history.uvue` 进入 +- 🎯 **关键逻辑**: + - 若来自历史订单(`from=history`)且状态为“已完成” → 只显示“联系客服” + - 若来自历史订单且状态为“进行中” → 显示“接受/拒绝/导航/完成”等操作按钮 + - 若非历史来源 → 显示完整操作按钮 +- 📞 包含联系顾客、联系商家、联系客服三个联系方式 + +--- + +### 9. `earnings.uvue` —— **收入明细** +- 💰 展示总收入、用户打赏、商家打赏、总订单数 +- 📊 按订单聚合的收入数据列表 +- 📈 图表展示最近7天收入趋势 +- ➕ 加载更多按钮 + +--- + +### 10. `ratings.uvue` —— **评价记录** +- ⭐ 展示用户对配送员的评价 +- 📝 包含评分、评价内容、订单号、时间 +- 📊 统计平均分、好评率等 + +--- + +### 11. `vehicle.uvue` —— **车辆管理主页** +- 🚗 列出当前绑定的所有车辆 +- ➕ “添加车辆”按钮 +- 🖋️ 点击车辆 → 跳转至 `vehicle-edit.uvue` +- 🗑️ 支持删除、设为主用车等操作 + +--- + +### 12. `vehicle-add.uvue` —— **添加车辆** +- 📝 表单填写:车牌号、车型、行驶证照片、车辆类型等 +- ✅ 提交后绑定到当前账户 +- ⬅️ 返回车辆管理页 + +--- + +### 13. `vehicle-edit.uvue` —— **编辑车辆信息** +- 🖋️ 修改已有车辆信息(车牌、车型、照片等) +- 📸 支持重新上传行驶证照片 +- ✅ 保存后更新车辆信息 + +--- + +## 🔄 页面跳转关系图(简化版) + +``` +index.uvue + │ + ├──→ profile.uvue → profile-edit.uvue + │ + ├──→ tasks.uvue → task-detail.uvue + │ + ├──→ order-history.uvue → order-detail.uvue (from=history) + │ + ├──→ earnings.uvue + │ + ├──→ ratings.uvue + │ + └──→ vehicle.uvue → vehicle-add.uvue / vehicle-edit.uvue +``` + +--- + +## 🎯 设计原则 + +- ✅ **一致性**:所有页面使用相同导航栏样式(左上角返回按钮 + 居中标题) +- ✅ **响应式**:适配 H5、APP、小程序等平台 +- ✅ **状态驱动**:根据订单状态动态显示不同操作按钮 +- ✅ **用户体验优先**:历史订单跳转后只显示必要操作,避免冗余按钮 + +--- + +## 📌 建议优化点 + +| 问题 | 建议 | +|------|------| +| `index.uvue` 重复 | 重命名为 `dashboard.uvue` 或 `home.uvue` | +| 页面间参数传递 | 使用 `uni.navigateTo({ url: '?param=value' })` 并在 `onLoad` 中接收 | +| UTS 语法兼容性 | 如遇问题,可临时改用标准 TS 语法调试 | + +--- + +## ✅ 总结 + +这个 `delivery` 模块是一个完整的配送员工作系统,涵盖了: + +- **个人管理**(资料、设置) +- **任务处理**(接单、配送、完成) +- **数据统计**(收入、评价、历史) +- **车辆管理** + +结构清晰、功能完整,适合用于实际配送平台开发。 + +--- diff --git a/pages/mall/delivery/earnings.uvue b/pages/mall/delivery/earnings.uvue new file mode 100644 index 00000000..c3bfc49a --- /dev/null +++ b/pages/mall/delivery/earnings.uvue @@ -0,0 +1,542 @@ + + + + + \ No newline at end of file diff --git a/pages/mall/delivery/index.uvue b/pages/mall/delivery/index.uvue index 1f9af9a8..7e785649 100644 --- a/pages/mall/delivery/index.uvue +++ b/pages/mall/delivery/index.uvue @@ -77,14 +77,16 @@ + - + + @@ -208,7 +210,7 @@ export default { data() { return { - isOnline: false, + isOnline: true, driverInfo: { id: '', @@ -279,7 +281,7 @@ this.currentTask = { id: '1', order_no: 'D202501081234', - status: 2, + status: 2, // 👈 设置为“已接取”,以便测试“开始取货”按钮 pickup_address: { detail: '华强北商业区华强电子世界2楼A205', area: '华强北' @@ -429,6 +431,9 @@ // 任务操作方法 acceptTask() { // TODO: 调用API接受任务 + if (this.currentTask) { + this.currentTask.status = 2 // 更新状态为“已接取” + } uni.showToast({ title: '任务已接受', icon: 'success' @@ -437,6 +442,9 @@ startPickup() { // TODO: 调用API开始取货 + if (this.currentTask) { + this.currentTask.status = 3 // 更新状态为“取货中” + } uni.showToast({ title: '开始取货', icon: 'success' @@ -445,6 +453,9 @@ confirmPickup() { // TODO: 调用API确认取货 + if (this.currentTask) { + this.currentTask.status = 4 // 更新状态为“已取货” + } uni.showToast({ title: '取货完成', icon: 'success' @@ -453,20 +464,44 @@ startDelivery() { // TODO: 调用API开始配送 + if (this.currentTask) { + this.currentTask.status = 5 // 更新状态为“配送中” + } uni.showToast({ title: '开始配送', icon: 'success' }) }, - confirmDelivery() { - // TODO: 调用API确认送达 - uni.showToast({ - title: '配送完成', - icon: 'success' + // 显示确认送达弹框 + showConfirmDeliveryDialog() { + uni.showModal({ + title: '确认送达', + content: '确认商品已送到顾客手中?', + success: (res) => { + if (res.confirm) { + this.confirmDelivery() + } + } }) - this.currentTask = null - this.loadAvailableOrders() + }, + + // 确认送达 + confirmDelivery() { + // TODO: 调用API确认送达 + if (this.currentTask) { + // 1. 将订单状态更新为“已完成” (假设5表示已完成) + this.currentTask.status = 5; + // 2. 将已完成的任务保存到本地存储,以便历史订单页面可以读取 + const completedOrder = {...this.currentTask}; // 创建副本,避免引用问题 + uni.setStorageSync('completed_order_for_history', completedOrder); + } + uni.showToast({ + title: '配送完成', + icon: 'success' + }) + this.currentTask = null + this.loadAvailableOrders() }, contactCustomer() { @@ -485,6 +520,23 @@ }) }, + // 查看订单详情(跳转到 order-detail 页面) + viewOrderDetail(orderId?: string,status?:number) { + if (orderId && status) { + uni.navigateTo({ + url: `/pages/mall/delivery/order-detail?id=${orderId}&status=${status}` // ✅ 强制为 1 + }) + } else if (this.currentTask) { + uni.navigateTo({ + url: `/pages/mall/delivery/order-detail?id=${this.currentTask.id}&status=${this.currentTask.status}` + }) + }else{ + uni.navigateTo({ + url: `/pages/mall/delivery/order-detail?id=${orderId}&status=1` // ✅ 强制为 1 + }) + } + }, + // 订单操作方法 acceptOrder(orderId: string) { // TODO: 调用API接受订单 @@ -496,12 +548,6 @@ this.loadAvailableOrders() }, - viewOrderDetail(orderId: string) { - uni.navigateTo({ - url: `/pages/mall/delivery/order-detail?id=${orderId}` - }) - }, - // 导航方法 goToOrderHistory() { uni.navigateTo({ @@ -531,393 +577,482 @@ +/* ... 保持原有 style 部分不变 ... */ +.delivery-container { + background-color: #f8f9fa; + min-height: 100vh; + padding-bottom: 40rpx; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +.header { + background-color: #fff; + padding: 20rpx 30rpx; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1rpx solid #e9ecef; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +.driver-info { + display: flex; + align-items: center; +} + +.avatar { + width: 80rpx; + height: 80rpx; + border-radius: 40rpx; + margin-right: 20rpx; + border: 2rpx solid #dee2e6; +} + +.driver-details { + display: flex; + flex-direction: column; + justify-content: center; +} + +.driver-name { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 8rpx; +} + +.work-status { + font-size: 24rpx; + padding: 6rpx 12rpx; + border-radius: 12rpx; + font-weight: 500; +} + +.status-online { + background-color: #E8F5E8; + color: #4CAF50; +} + +.status-offline { + background-color: #FFF3E0; + color: #FF9800; +} + +.status-switch { + display: flex; + align-items: center; + gap: 10rpx; +} + +.switch-label { + font-size: 22rpx; + color: #666; +} + +/* 今日统计 */ +.stats-section { + background-color: #fff; + margin: 20rpx; + padding: 20rpx 30rpx; + border-radius: 16rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +.section-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 20rpx; + text-align: center; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15rpx; + justify-items: center; +} + +.stat-item { + display: flex; + flex-direction: column; + align-items: center; + padding: 15rpx; + background-color: #f8f9fa; + border-radius: 12rpx; + min-width: 120rpx; +} + +.stat-value { + font-size: 36rpx; + font-weight: bold; + color: #4CAF50; + margin-bottom: 10rpx; + line-height: 1.2; +} + +.stat-label { + font-size: 24rpx; + color: #666; + text-align: center; +} + +/* 当前任务 */ +.current-task-section { + background-color: #fff; + margin: 20rpx; + padding: 20rpx 30rpx; + border-radius: 16rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +.section-title { + font-size: 32rpx; + font-weight: bold; + color: #333; + margin-bottom: 20rpx; + text-align: center; +} + +.task-card { + border: 1rpx solid #e9ecef; + border-radius: 12rpx; + padding: 20rpx; + background-color: #ffffff; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +.task-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15rpx; + padding-bottom: 15rpx; + border-bottom: 1rpx solid #f8f9fa; +} + +.task-id { + font-size: 28rpx; + font-weight: bold; + color: #333; +} + +.task-status { + font-size: 24rpx; + padding: 6rpx 12rpx; + border-radius: 12rpx; + font-weight: 500; +} + +.task-accepted { + background-color: #E3F2FD; + color: #1976D2; +} + +.task-picking { + background-color: #FFF3E0; + color: #F57C00; +} + +.task-delivering { + background-color: #E8F5E8; + color: #388E3C; +} + +.task-addresses { + margin-bottom: 20rpx; +} + +.address-item { + display: flex; + align-items: flex-start; + margin-bottom: 15rpx; + padding: 10rpx 0; + border-bottom: 1rpx dashed #e9ecef; +} + +.address-icon { + font-size: 28rpx; + margin-right: 15rpx; + margin-top: 5rpx; + color: #666; +} + +.address-info { + display: flex; + flex-direction: column; + flex: 1; +} + +.address-label { + font-size: 24rpx; + color: #666; + margin-bottom: 8rpx; + font-weight: 500; +} + +.address-text { + font-size: 28rpx; + color: #333; + margin-bottom: 8rpx; + word-break: break-all; +} + +.contact-info { + font-size: 24rpx; + color: #666; + font-weight: 500; +} + +.address-line { + width: 2rpx; + height: 30rpx; + background-color: #ddd; + margin: 10rpx 0 10rpx 14rpx; +} + +.task-details { + display: flex; + justify-content: space-between; + margin-bottom: 20rpx; + padding: 15rpx; + background-color: #f8f9fa; + border-radius: 8rpx; + font-size: 24rpx; + color: #666; +} + +.task-info { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + font-size: 24rpx; + color: #666; + margin: 0 5rpx; +} + +.task-actions { + display: flex; + flex-wrap: wrap; + gap: 10rpx; + margin-top: 10rpx; +} + +.action-btn { + flex: 1; + height: 80rpx; + border-radius: 8rpx; + font-size: 28rpx; + border: none; + font-weight: 500; + padding: 0 10rpx; + box-sizing: border-box; +} + +.primary { + background-color: #4CAF50; + color: #fff; +} + +.secondary { + background-color: #f0f0f0; + color: #333; + border: 1rpx solid #ddd; +} + +/* 可接取订单 */ +.available-orders-section { + margin: 20rpx; +} + +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20rpx; +} + +.refresh-btn { + font-size: 26rpx; + color: #4CAF50; + padding: 8rpx 16rpx; + background-color: #e8f5e8; + border-radius: 12rpx; + font-weight: 500; +} + +.empty-orders { + background-color: #fff; + padding: 40rpx 30rpx; + border-radius: 16rpx; + text-align: center; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +.empty-text { + font-size: 32rpx; + color: #999; + margin-bottom: 15rpx; +} + +.empty-subtitle { + font-size: 24rpx; + color: #ccc; +} + +.order-card { + background-color: #fff; + border-radius: 12rpx; + padding: 20rpx; + margin-bottom: 15rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); + border: 1rpx solid #e9ecef; +} + +.order-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15rpx; + padding-bottom: 15rpx; + border-bottom: 1rpx solid #f8f9fa; +} + +.order-id { + font-size: 28rpx; + color: #333; + font-weight: bold; +} + +.order-fee { + font-size: 32rpx; + color: #4CAF50; + font-weight: bold; +} + +.order-route { + display: flex; + align-items: center; + margin-bottom: 15rpx; + padding: 10rpx 0; + border-bottom: 1rpx solid #f8f9fa; +} + +.route-item { + display: flex; + align-items: center; + flex: 1; +} + +.route-icon { + font-size: 24rpx; + margin-right: 8rpx; + color: #666; +} + +.route-text { + font-size: 26rpx; + color: #333; + word-break: break-all; +} + +.route-arrow { + font-size: 24rpx; + color: #999; + margin: 0 15rpx; +} + +.order-info { + display: flex; + justify-content: space-between; + margin-bottom: 15rpx; + padding: 10rpx 0; + border-bottom: 1rpx solid #f8f9fa; + font-size: 22rpx; + color: #666; +} + +.info-item { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + font-size: 22rpx; + color: #666; + margin: 0 5rpx; +} + +.order-actions { + display: flex; + gap: 10rpx; + margin-top: 10rpx; +} + +.order-btn { + flex: 1; + height: 70rpx; + border-radius: 8rpx; + font-size: 26rpx; + border: none; + font-weight: 500; + padding: 0 10rpx; + box-sizing: border-box; +} + +.accept { + background-color: #4CAF50; + color: #fff; +} + +.detail { + background-color: #f0f0f0; + color: #333; + border: 1rpx solid #ddd; +} + +/* 历史记录快捷入口 */ +.quick-actions-section { + background-color: #fff; + margin: 20rpx; + padding: 20rpx 30rpx; + border-radius: 16rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); +} + +.actions-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20rpx; + justify-items: center; +} + +.action-item { + display: flex; + flex-direction: column; + align-items: center; + padding: 20rpx; + background-color: #f8f9fa; + border-radius: 12rpx; + min-width: 120rpx; + cursor: pointer; + transition: background-color 0.2s; +} + +.action-item:hover { + background-color: #e8f5e8; +} + +.action-icon { + font-size: 48rpx; + margin-bottom: 15rpx; + color: #666; +} + +.action-text { + font-size: 24rpx; + color: #333; + text-align: center; + font-weight: 500; +} + \ No newline at end of file diff --git a/pages/mall/delivery/order-detail.uvue b/pages/mall/delivery/order-detail.uvue index 9759a08e..68bc94d4 100644 --- a/pages/mall/delivery/order-detail.uvue +++ b/pages/mall/delivery/order-detail.uvue @@ -1,17 +1,35 @@ - + \ No newline at end of file diff --git a/pages/mall/delivery/order-history.uvue b/pages/mall/delivery/order-history.uvue new file mode 100644 index 00000000..c283855c --- /dev/null +++ b/pages/mall/delivery/order-history.uvue @@ -0,0 +1,472 @@ + + + + + \ No newline at end of file diff --git a/pages/mall/delivery/profile-edit.uvue b/pages/mall/delivery/profile-edit.uvue new file mode 100644 index 00000000..62d82af5 --- /dev/null +++ b/pages/mall/delivery/profile-edit.uvue @@ -0,0 +1,439 @@ + + + + + \ No newline at end of file diff --git a/pages/mall/delivery/profile.uvue b/pages/mall/delivery/profile.uvue index 1fd1882c..05e07c0b 100644 --- a/pages/mall/delivery/profile.uvue +++ b/pages/mall/delivery/profile.uvue @@ -1,8 +1,13 @@