From c803a77c8fc16e7b18100a46a24bc4947c86843d Mon Sep 17 00:00:00 2001 From: not-like-juvenile <16056107+not-like-juvenile@user.noreply.gitee.com> Date: Tue, 3 Feb 2026 12:01:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B5=E9=9D=A2=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages.json | 7 + pages/mall/delivery/all.uvue | 360 ++++++++++++++++++ .../{doc => db}/db-data-generation.md | 0 pages/mall/delivery/doc/all.md | 51 +++ pages/mall/delivery/doc/earnings.md | 3 + pages/mall/delivery/doc/index.md | 10 + pages/mall/delivery/doc/order-detail.md | 42 +- pages/mall/delivery/doc/order-history.md | 75 ++++ pages/mall/delivery/index.uvue | 172 +++++++-- pages/mall/delivery/order-detail.uvue | 178 +++++++-- pages/mall/delivery/order-history.uvue | 182 +++++---- pages/mall/delivery/profile.uvue | 5 + 12 files changed, 904 insertions(+), 181 deletions(-) create mode 100644 pages/mall/delivery/all.uvue rename pages/mall/delivery/{doc => db}/db-data-generation.md (100%) create mode 100644 pages/mall/delivery/doc/all.md diff --git a/pages.json b/pages.json index 6261795f..813e91fe 100644 --- a/pages.json +++ b/pages.json @@ -268,6 +268,13 @@ "navigationStyle": "custom" } }, + { + "path": "all", + "style": { + "navigationBarTitleText": "待接取任务", + "navigationStyle": "custom" + } + }, { "path": "earnings", "style": { diff --git a/pages/mall/delivery/all.uvue b/pages/mall/delivery/all.uvue new file mode 100644 index 00000000..bbdb9b58 --- /dev/null +++ b/pages/mall/delivery/all.uvue @@ -0,0 +1,360 @@ + + + + + diff --git a/pages/mall/delivery/doc/db-data-generation.md b/pages/mall/delivery/db/db-data-generation.md similarity index 100% rename from pages/mall/delivery/doc/db-data-generation.md rename to pages/mall/delivery/db/db-data-generation.md diff --git a/pages/mall/delivery/doc/all.md b/pages/mall/delivery/doc/all.md new file mode 100644 index 00000000..fcf50ed0 --- /dev/null +++ b/pages/mall/delivery/doc/all.md @@ -0,0 +1,51 @@ + +## 1. 功能概述 +`all.uvue` 是为配送端设计的全量订单抓取页面。当首页待接订单超过 5 个时,用户可通过此页面查看并抢单。 + +## 2. 核心设计说明 +根据最新 UI 指标,该页面采用了**现代垂直流布局**: +- **中心费用展示**:订单金额在卡片顶部居中加粗显示,强化利益点。 +- **垂直路径流**:采用垂直排布的取货(📍)与送达(🏠)地址,中间以箭头连接,更符合手机屏阅读习惯。 +- **全宽操作按钮**:底部采用 100% 宽度的按钮,提高抢单操作的触达率。 +- **实时空态处理**:当订单被他人抢先接走时,列表会自动更新。 + +## 3. 技术实现要点 + +### 3.1 数据安全与并发控制 +在执行 `acceptOrder`(抢单)时,通过数据库约束确保操作的原子性: +```uts +// 增加 driver_id 为空的前提条件,防止已被他人接单 +const res = await supa.from('ml_delivery_tasks') + .update({ + driver_id: driverId, + status: 2, + accepted_at: new Date().toISOString() + }) + .eq('id', taskId) + .is('driver_id', 'null') // 关键:确保单子还没被接 + .execute(); +``` + +### 3.2 数据结构转换 (`_transformTask`) +为了兼容数据库存储的 JSON 字符串格式与 UI 组件所需的 Object 格式,页面内置了转换逻辑: +- 自动解析 `pickup_address` 和 `delivery_address` JSON 字符串。 +- 格式化 `delivery_fee` 为保留两位小数。 +- 映射状态码到对应的 UI 标签。 + +### 3.3 路由与交互 +- **路由路径**:`pages/mall/delivery/all` +- **导航栏**:配置了 `navigationBarTitleText: "待接订单"`,并开启了原生的回退功能。 +- **动态跳转**:支持从详情页返回后自动刷新列表(通过 `onShow` 触发)。 + +## 4. 样式规范 +- 布局:Flexbox (Column) +- 配色: + - 取货点:Pink (`#ff4d94`) + - 送达点:Blue (`#2196F3`) + - 主按钮:Green (`#4CAF50`) +- 间距:标准 30rpx 外边距,卡片内 40rpx 内边距。 + +## 5. 开发历史 +- **2026-02-03**: 页面初版创建。 +- **2026-02-03**: 完成从水平卡片到垂直流卡片的 UI 重构。 +- **2026-02-03**: 接入 Supabase 实现秒级抢单逻辑与状态同步。 diff --git a/pages/mall/delivery/doc/earnings.md b/pages/mall/delivery/doc/earnings.md index c8b8a825..147f2b3b 100644 --- a/pages/mall/delivery/doc/earnings.md +++ b/pages/mall/delivery/doc/earnings.md @@ -58,6 +58,8 @@ const result = Array.from(orderMap.values()) ## 数据源更新:包含已接订单(Accepted) - 需求说明:为了与“历史订单”页面保持一致,收入统计应包含配送员已接取(accepted/assigned)的订单,不仅限于已完成订单。也就是说,只要 `ml_delivery_tasks` 中 `driver_id` = 当前司机且 `status >= 2`(已接取或进行中),其对应的订单都应计入收入统计范围。 +- 需求说明(已采纳):收入统计以 `ml_delivery_tasks` 为数据源之一:只要任务记录显示 `driver_id` = 当前司机且 `status >= 2`(已接取或进行中),其对应订单即应计入统计范围。注意:部分 `ml_delivery_tasks` 可能没有可匹配的 `ml_orders`(`order_id` 为空或在 `ml_orders` 中找不到),页面/后端应对缺失 `order_no` 做回退显示并记录供核查。 + - 推荐 Supabase 查询示例(后端或前端按需实现): ``` @@ -78,6 +80,7 @@ LIMIT :size OFFSET :offset; ```js const taskRes = await supa.from('ml_delivery_tasks').select('order_id').eq('driver_id', uid).gte('status', 2).execute() const orderIds = taskRes.data.map(r => r.order_id) +// 对于 order_id 为空或找不到的情况,server 端应记录这些 id 以便排查 const ordersRes = await supa.from('ml_orders').select('*,ml_delivery_tips(*)').in('id', orderIds).order('created_at',{ascending:false}).limit(size).execute() ``` diff --git a/pages/mall/delivery/doc/index.md b/pages/mall/delivery/doc/index.md index dbea39f3..b3ef5702 100644 --- a/pages/mall/delivery/doc/index.md +++ b/pages/mall/delivery/doc/index.md @@ -46,6 +46,16 @@ await supa.from('ml_delivery_tasks') - `toggleWorkStatus()`:切换 `isOnline` 并调用 `startWork()` / `stopWork()`。上线时会刷新可接订单列表。 - 接单/开始取货/确认取货/开始配送/确认送达等均通过对 `ml_delivery_tasks` 的 `update` 操作变更 `status`,并在成功后更新本地 `currentTask`。 +## UI 行为变动(已生效) +- 当页面检测到存在 `currentTask`(来自 `ml_delivery_tasks`)时,页面不会再弹出“附近可接订单”列表。即:配送端以 `ml_delivery_tasks` 为状态真源,主页面的订单展示不再依赖或回退展示 `ml_orders.order_status`,以避免两表不同步导致的显示冲突。 +- 为了减少页面闪烁与重复刷新,`enableAutoRefresh` 在默认实现中已可被关闭(`false`),且 `loadAvailableOrders()` 在检测到 `currentTask` 时会跳过可接订单的渲染。 + +## 会话与加载保护 +- `supaReady` 的会话恢复在某些环境中会较慢,页面中已对其使用 `Promise.race(..., 1500)` 超时包装:超时后页面会打警告并继续渲染以避免长时间阻塞用户界面。依赖用户 id 的查询在超时情况下可能为空,请参照 `order-history.md` 的“已实现的防护”部分进行排查。 + +## 前端同步尝试(临时) +- 在接单/确认送达流程中前端会尝试向 `ml_orders` 发送更新(将 `order_status` 同步到任务的状态)并记录返回结果用于诊断。但该同步并不保证在所有权限或网络错误下成功,因此更稳妥的方案仍是后端触发器同步或可信服务端接口。 + ## 注意事项 - 高并发接单场景需后端保证原子性(乐观锁或 DB 事务)以防止竞单冲突。 - `loadAvailableOrders()` 最好按司机服务区域与距离筛选,并使用分页/实时推送代替频繁轮询。 diff --git a/pages/mall/delivery/doc/order-detail.md b/pages/mall/delivery/doc/order-detail.md index 31408d88..6b683279 100644 --- a/pages/mall/delivery/doc/order-detail.md +++ b/pages/mall/delivery/doc/order-detail.md @@ -22,30 +22,26 @@ - 解析 `options.id` 与 `options.status`,调用 `loadOrderDetail(id)`。 - `loadOrderDetail(id)` - - 判断 ID 类型(UUID / 数字 / 非数字)以决定查询字段(`id`、`cid`、`order_no`)。 - - 并行查询 `ml_orders`, `ml_order_items`, `ml_shops`, `ml_delivery_tasks` 并合并到页面状态。 + - **加载保护**:对 `supaReady` 采用 1.5s 超时策略包装,防止会话刷新阻塞页面加载。 + - **智能 ID 回查**:优先从 `ml_orders` (UUID/cid/order_no) 查找。若未找到,则尝试从未分配任务表 `ml_delivery_tasks` 中根据 ID 查找,再反查关联订单。 + - **降级机制(Fallback)**:当 `ml_orders` 行缺失时,自动回退到从 `ml_delivery_tasks` 提取地址、手机号、配送费及距离等基础信息进行展示,并在 UI 上显示回退加载提示。 + - **清理加载状态**:在 `finally` 块中统一切除加载动画 (`uni.hideLoading`),防止界面挂起。 -- `acceptOrder()` / `rejectOrder(reason)` - - accept: 尝试对 `ml_delivery_tasks` 执行 `update driver_id` 操作并设置 `status=2`(处理中),需要后端并发保护。 - - reject: 增加拒单原因到 `ml_delivery_tasks` 或 `order_notes` 并回滚本地 UI 状态。 +## 交互与样式优化(2026-02-03 更新) +- **联系人信息解析**:地址栏(取货/送货)现在仅在“联系人姓名”存在时显示分隔点 `·`。若无姓名,则仅显示手机号,避免显示为 `. 手机号`。 +- **联系方式布局优化**:为了防止手机号在不同屏幕宽度下被图标遮挡,联系人区域采用**垂直居中布局**(图标在上,姓名电话在下),显著拉高了边框高度 (`min-height: 180rpx`) 并增加了垂直间距。 +- **文本显示优化**: + - 商品区域的“**订单号**”增加了加粗显示 (`bold`),提升核对便利性。 + - 展示给配送员的联系手机号调大了字号并加粗,确保清晰可见。 + - 修复了在 Uni-app x 下由于类型推断导致的手机号无法通过点语法访问的问题(改用索引访问)。 -- `confirmPickup()` / `confirmDelivery()` - - 根据 `task.id` 更新相应时间戳字段(`picked_at`/`delivered_at`)并设置状态(例如 `status=3/4`)。 - -## 示例:按 id 类型查询(伪代码) -``` -let q = supa.from('ml_orders').select('*') -if (isUUID(id)) q = q.eq('id', id) -else if (isNumeric(id)) q = q.eq('cid', id) -else q = q.eq('order_no', id) -const { data: order } = await q.limit(1).execute() +## 示例:地址兼容解析逻辑 +```typescript +// 兼容 JSON 字符串及对象格式的地址字段 +let shipping = {} +if (typeof raw == 'string') { + try { shipping = JSON.parse(raw) } catch (e) { shipping = { detail: raw } } +} else { shipping = raw || {} } +// 访问方式:(address as UTSJSONObject)['phone'] ``` -## 事务与并发注意 -- 接单场景应使用后端原子性检查(数据库事务或行级乐观锁)以避免多司机同时接单。 -- 前端接单流程:先尝试 update(带 where driver_id IS NULL),若返回 0 row affected 则提示已被接单。 - -## 错误处理与回退 -- 捕获所有 supa 调用错误并将友好错误展示给用户(例如:'网络错误,请稍后重试')。 -- 对可能缺失的字段(地址为字符串或对象)使用 `_transformAddress()` 做兼容处理。 - diff --git a/pages/mall/delivery/doc/order-history.md b/pages/mall/delivery/doc/order-history.md index b46ea431..9095fd79 100644 --- a/pages/mall/delivery/doc/order-history.md +++ b/pages/mall/delivery/doc/order-history.md @@ -1,3 +1,78 @@ +# 历史订单 页面说明(order-history.uvue) + +## 概要 +`order-history.uvue` 用于配送员查看历史订单与近期任务。页面会展示: +- 以 `ml_delivery_tasks` 为配送端“状态真源”的任务记录(只要 `driver_id = 当前司机` 且 `status >= 2`,均会包含在统计/列表中); +- 页面会批量回填对应 `ml_orders.order_no` 以补全显示(若 `order_no` 缺失会显示回退文本),避免直接以 `ml_orders.order_status` 作为展示依据而导致与配送端不一致。 + +页面关键点: +- 首次加载时通过 `loadOrderHistory()` 拉取数据;页面每次显示时会检查本地存储 `completed_order_for_history`,并把刚完成订单插入列表表头。 +- 使用 Supabase 客户端 `supa` 读取 `ml_delivery_tasks` 与 `ml_orders` 表,并通过 `getCurrentUser()` / `getCurrentUserId()` 获取当前用户/司机 id。 + +## 行为细节 +- 当前实现优先以 `ml_delivery_tasks`(status >= 2)作为数据源,页面会: + - 查询 `ml_delivery_tasks` 中与 `driver_id` 相关的任务,按时间排序并映射为页面项; + - 对获取到的 `order_id` 列表做一次批量查询 `ml_orders` 以回填 `order_no` 和订单详情; + - 对没有匹配到 `ml_orders` 的 `order_id`,页面会用短 id 回退显示并在控制台打印缺失 id 列表,便于后台核查数据不一致的原因。 +- 为避免重复展示,页面在将“当前任务对应订单”插入顶部时,会先检查 `orderList` 是否已有相同 `id`。 + +## 依赖 & 相关文件 +- 页面文件:`pages/mall/delivery/order-history.uvue`(当前) +- Supabase 实例:`components/supadb/aksupainstance.uts`(导出 `supa` 与 `supaReady`) +- 用户/会话工具:`utils/store.uts`(`getCurrentUser()`、`getCurrentUserId()`) +- 相关文档: + - `pages/mall/delivery/doc/earnings.md`(收入聚合与 DB 建议) + - `pages/mall/delivery/doc/test-user-1_at_123.com.md`(测试用户与 SQL 示例) + +## 已实现的防护与诊断信息 +- `supaReady` 在会话恢复时可能会进行网络刷新(refreshSession),该步骤可能较慢。为避免页面长时间阻塞,页面中对 `supaReady` 使用了 `Promise.race` 的 1.5s 超时包装:如果超时会打印警告并继续执行(某些依赖用户 id 的查询可能因此为空)。 +- 如果 `getCurrentUserId()` 返回空,页面会尝试从 `supa.getSession()` 获取 auth id 并在 `ak_users` 表中查找对应的 `ak_users.id` 作为回退,这能修复 `driver_id` 在数据库中为 `ak_users.id` 的常见映射问题。 + +## 常见不一致现象说明 +- 我们观察到的常见情况:`ml_delivery_tasks` 中的任务显示为“已完成”(配送端),但对应 `ml_orders.order_status` 仍为“已取消”或其它状态,导致不同页面显示冲突。原因通常为: + - `ml_delivery_tasks.order_id` 为空或格式不一致(UUID vs string); + - `ml_orders` 没有相应行(数据尚未同步或被删除); + - RLS/权限导致前端不能读取或更新 `ml_orders`。 + +建议排查 SQL(例): +``` +SELECT t.id AS task_id, t.order_id, t.status AS task_status, o.order_status +FROM public.ml_delivery_tasks t +LEFT JOIN public.ml_orders o ON o.id = t.order_id +WHERE t.status >= 2 +ORDER BY t.created_at DESC +LIMIT 200; +``` + +如需我为你生成触发器或前端重试队列示例,我可以继续实现。 + +## 常见问题与排查步骤 +1. 问题:页面没有显示当前已接订单(即使首页显示有当前任务)。 + - 检查控制台日志:页面会打印 `loadOrderHistory: currentUserId=`、`loadOrderHistory: session id fallback=`、`loadOrderHistory: delivery_tasks dtRes=`、`loadOrderHistory: ordersRes=`。把这些日志逐项核对: + - `currentUserId` 应为 `ak_users.id`(或系统实际使用的 driver id)。 + - `dtRes`(delivery_tasks 查询)应包含对象数组,且数组项含 `order_id`。 + - `ordersRes` 应包含对应的 `ml_orders` 行。 + - 若 `dtRes` 为空且 `session id fallback` 有值,说明 `ak_users` 表中可能没有把 auth id 映射到 `ak_users.id`,需要把 `ak_users.auth_id` 填入或同步。 + - 若 `ordersRes` 为空,但 `dtRes` 非空,请检查 `ml_orders.id` 与 `ml_delivery_tasks.order_id` 的数据类型(例如 UUID vs string)以及 RLS 策略。 + +2. 问题:页面加载慢或时不时刷新。 + - 原因:多个页面在 `onShow`/`onLoad` 时发起多次 supa 查询,且 `supaReady` 恢复会话有时较慢,导致累积延迟。已在 `index.uvue` 增加了防抖与 `enableAutoRefresh` 开关来禁止自动刷新。 + - 排查:查看控制台是否有 `supaReady timeout/failed` 警告(若有,则说明会话恢复慢或失败)。 + +## 性能与安全建议 +- 若数据量大,请在后端做分页与聚合(只返回必要字段);避免一次性查询大量 `ml_orders` 字段。参见 `earnings.md` 中的后端接口建议。 +- 长期建议:修改 `components/supadb/aksupainstance.uts` 中会话恢复逻辑,让刷新在后台异步进行或提供可配置的超时策略,避免阻塞页面加载。 + +## 测试步骤(快速) +1. 使用测试用户(参见 `test-user-1_at_123.com.md`)创建一个 `ml_delivery_tasks` 记录,`driver_id` 对应当前司机,且 `status >= 2`。 +2. 在首页确认当前任务显示;然后打开“历史订单”页面,观察顶部是否显示该订单。若未显示,贴上控制台中 `loadOrderHistory:` 的相关日志给开发者排查。 + +## 变更历史 +- 2026-02-02:添加回退 mapping(session -> ak_users.id)、supaReady 超时保护的说明、调试日志建议及性能建议。 + +--- + +如需我把文档翻译为英文或生成 README 风格的一页说明,我可以继续补充。 # order-history.uvue — 历史订单 ## 概要 diff --git a/pages/mall/delivery/index.uvue b/pages/mall/delivery/index.uvue index cd916250..de149c9b 100644 --- a/pages/mall/delivery/index.uvue +++ b/pages/mall/delivery/index.uvue @@ -97,8 +97,6 @@ 附近订单 🔄 刷新 - - 更多 ➜ @@ -107,34 +105,41 @@ 请保持在线状态,有新订单会自动推送 - - - {{ order.order_no }} - ¥{{ order.delivery_fee }} - - - - - 📍 - {{ order.pickup_address.area }} + + + + {{ order.order_no }} + ¥{{ order.delivery_fee }} - - - 🏠 - {{ order.delivery_address.area }} + + + + 📍 + {{ order.pickup_address.area || order.pickup_address.detail }} + + + + 🏠 + {{ order.delivery_address.area || order.delivery_address.detail }} + + + + + 距离: {{ order.distance }}km + 预计: {{ order.estimated_time }}分钟 + 下单: {{ formatTime(order.created_at) }} + + + + + - - - 距离: {{ order.distance }}km - 预计: {{ order.estimated_time }}分钟 - 下单: {{ formatTime(order.created_at) }} - - - - - - + + + + + 查看全部订单 (共 {{ availableOrders.length }} 个待接订单) ➜ @@ -308,7 +313,10 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' } } if (res && (res.data instanceof Array) && res.data.length > 0) { - this.driverInfo = Object.assign(this.driverInfo, res.data[0]) + const data = res.data[0] as DeliveryDriverType + this.driverInfo = Object.assign(this.driverInfo, data) + // 同步工作状态到本地变量 + this.isOnline = (this.driverInfo.work_status === 1) } } catch (e) { console.error('loadDriverInfo error', e) @@ -434,6 +442,7 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' return { id: task.id, + order_id: task.order_id || task.orderId || task.orderId || '', order_no: task.order_no || task.orderNo || task.trade_no || '', status: Number(task.status) || 1, pickup_address: parseAddress(task.pickup_address), @@ -465,8 +474,34 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' // 切换工作状态 toggleWorkStatus(event: UniSwitchChangeEvent) { - this.isOnline = event.detail.value + const targetStatus = event.detail.value + // 检查是否有当前任务,不允许离线 + if (!targetStatus && this.currentTask != null) { + // 1. 先同步 UI 状态为 false (由于用户已经拨动了开关) + this.isOnline = false + + // 2. 弹出警告 + uni.showModal({ + title: '无法下线', + content: '您当前有正在进行的任务,请完成后再下线。', + showCancel: false, + success: (_) => { + // 3. 用户点击确定后或立即强制回弹开关为 true + this.$nextTick(() => { + this.isOnline = true + }) + } + }) + + // 4. 冗余保障:如果 Modal 没及时回弹,延时强制重置 + setTimeout(() => { + this.isOnline = true + }, 300) + return + } + + this.isOnline = targetStatus if (this.isOnline) { this.startWork() } else { @@ -475,8 +510,15 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' }, // 开始工作 - startWork() { - // TODO: 调用API开始工作,上传位置 + async startWork() { + const driverId = this.driverInfo.id + if (driverId != '') { + try { + await supa.from('ml_delivery_drivers').update({ work_status: 1 } as any).eq('id', driverId).execute() + } catch (e) { + console.error('startWork update failed', e) + } + } this.loadAvailableOrders() uni.showToast({ title: '已上线接单', @@ -485,8 +527,15 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' }, // 停止工作 - stopWork() { - // TODO: 调用API停止工作 + async stopWork() { + const driverId = this.driverInfo.id + if (driverId != '') { + try { + await supa.from('ml_delivery_drivers').update({ work_status: 0 } as any).eq('id', driverId).execute() + } catch (e) { + console.error('stopWork update failed', e) + } + } this.availableOrders = [] uni.showToast({ title: '已下线休息', @@ -631,6 +680,29 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' if (res && !res.error) { const completedOrder = { ...this.currentTask } uni.setStorageSync('completed_order_for_history', completedOrder) + // 同步更新 ml_orders 的状态,确保两个表状态一致 + try { + // 尝试使用 currentTask.order_id(由 _transformTask 提供) + const orderId = (this.currentTask as any).order_id || '' + if (orderId) { + const upRes: any = await supa.from('ml_orders').update({ order_status: 5 }).eq('id', orderId).execute() + console.log('confirmDelivery: ml_orders update res=', upRes) + if (!upRes || upRes.error) console.warn('confirmDelivery: ml_orders update failed', upRes) + } else { + // 如无 order_id,回退读取任务行以查找 order_id + const tRes: any = await supa.from('ml_delivery_tasks').select('order_id').eq('id', this.currentTask.id).limit(1).execute() + if (tRes && Array.isArray(tRes.data) && tRes.data.length > 0) { + const oid = tRes.data[0].order_id + if (oid) { + const upRes2: any = await supa.from('ml_orders').update({ order_status: 5 }).eq('id', oid).execute() + console.log('confirmDelivery: ml_orders update (fallback) res=', upRes2) + if (!upRes2 || upRes2.error) console.warn('confirmDelivery: ml_orders update (fallback) failed', upRes2) + } + } + } + } catch (syncErr) { + console.warn('confirmDelivery: failed to sync ml_orders status', syncErr) + } uni.showToast({ title: '配送完成', icon: 'success' }) this.currentTask = null this.loadAvailableOrders() @@ -684,6 +756,21 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' const res = await supa.from('ml_delivery_tasks').update({ driver_id: driverId, status: 2 }).eq('id', orderId).execute() if (res && !res.error) { uni.showToast({ title: '订单已接受', icon: 'success' }) + // 同步更新 ml_orders 状态为已接取(2) + try { + // orderId 这里是 ml_delivery_tasks.id(task id),需要先获取 order_id + const tRes: any = await supa.from('ml_delivery_tasks').select('order_id').eq('id', orderId).limit(1).execute() + if (tRes && Array.isArray(tRes.data) && tRes.data.length > 0) { + const oid = tRes.data[0].order_id + if (oid) { + const upRes: any = await supa.from('ml_orders').update({ order_status: 2 }).eq('id', oid).execute() + console.log('acceptOrder: ml_orders update res=', upRes) + if (!upRes || upRes.error) console.warn('acceptOrder: ml_orders update failed', upRes) + } + } + } catch (syncErr) { + console.warn('acceptOrder: failed to sync ml_orders status', syncErr) + } await this.loadCurrentTask() await this.loadAvailableOrders() } @@ -1174,6 +1261,25 @@ import { getCurrentUserId, getCurrentUser } from '@/utils/store.uts' border: 1rpx solid #ddd; } +/* 加载更多订单入口样式 */ +.view-all-footer { + background-color: #ffffff; + padding: 24rpx; + border-radius: 12rpx; + margin: 10rpx 0 30rpx; + display: flex; + justify-content: center; + align-items: center; + border: 1rpx dashed #4CAF50; + box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.1); +} + +.view-all-text { + font-size: 26rpx; + color: #4CAF50; + font-weight: bold; +} + /* 历史记录快捷入口 */ .quick-actions-section { background-color: #fff; diff --git a/pages/mall/delivery/order-detail.uvue b/pages/mall/delivery/order-detail.uvue index d58fb0e4..d516ccd1 100644 --- a/pages/mall/delivery/order-detail.uvue +++ b/pages/mall/delivery/order-detail.uvue @@ -1,5 +1,6 @@