小程序开发日记②:订单列表、详情与支付状态

1150 字
6 分钟
小程序开发日记②:订单列表、详情与支付状态

用户下单后最关心三件事:现在是什么状态、下一步要做什么、什么时候能送到。订单模块就围绕这三件事组织,而不是简单照搬管理端字段。

1. 列表状态分组#

订单页提供“全部、待支付、待调度、配送中、已完成”五个标签。接口返回的后台状态比标签更多,因此需要状态映射,而不能直接用标签文本请求。

const tabStatusMap = {
0: null,
1: ['UNPAID'],
2: ['PENDING_AUDIT', 'WAIT_DISPATCH'],
3: ['DELIVERING'],
4: ['COMPLETED', 'CANCELED', 'REJECTED', 'DELIVERY_FAILED']
}

页面请求时增加版本号,用户快速切换标签后,只接收最后一次查询结果,避免慢请求把新标签的数据覆盖掉。

let queryVersion = 0
async function loadOrders() {
const requestId = ++queryVersion
const response = await OrderApi.getOrderList(params.value)
if (requestId !== queryVersion) return
orders.value = response.rows || []
}

2. 订单卡片是视图模型#

OrderStatusCard 统一处理状态颜色、右上角状态形状、价格、摘要和按钮。卡片不直接决定业务,只接收已经转换好的展示属性。

为了让背景图片覆盖整个盒子,图片层使用绝对定位,内容层单独抬高层级:

.order-card { position: relative; overflow: hidden; }
.order-card__background {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.order-card__content { position: relative; z-index: 1; }

右上角状态区域单独绘制与主题相近、但有区分度的色块,解决背景图边缘在圆角裁剪时露白的问题。

3. 详情页聚合数据#

pages/order/detail.vue 同时读取订单详情、进度记录和凭证图片。详情加载成功后,再根据状态构建页面头部、时间线和操作按钮。

async function loadDetail(showPageLoading = true) {
if (!orderId.value || refreshing.value) return
refreshing.value = true
try {
const [detailResult, progressResult] = await Promise.all([
OrderApi.getOrderDetail(orderId.value),
OrderApi.getOrderProgress(orderId.value)
])
detail.value = detailResult.data || {}
progressRecords.value = progressResult.rows || []
await loadProofImages()
} finally {
refreshing.value = false
}
}

页面支持下拉刷新,并在可变状态下每 30 秒轻量刷新一次。离开页面必须清除计时器,避免隐藏页面继续请求。

4. 支付倒计时#

待支付订单根据创建或更新时间计算剩余时间:

const baseTime = Number.isNaN(updateTime) ? createTime : updateTime
const remain = PAYMENT_TIMEOUT - (Date.now() - baseTime)

倒计时归零后页面主动刷新详情,由服务端确认订单最终状态。前端不能擅自把订单改为取消,因为支付回调可能正在路上。

5. 支付与取消#

支付按钮设置 paying 防重复触发,调用支付接口后根据结果更新页面。取消操作先弹确认框,用户确认后调用 cancelOrder,成功再刷新详情。

点击取消
↓
确认风险与结果
↓
调用取消接口
↓
重新读取订单详情

对于已驳回订单,详情页提供“重新提交”,跳回对应类型表单并携带 orderId 与 resubmit=1。表单回显原数据,用户修改后走专门的重提接口。

6. 进度时间线#

时间线不是根据当前状态虚构节点,而是优先使用真实 process logs。只有后端暂未返回记录时才使用基础状态生成占位。审核、调度、起飞、签收都显示真实操作时间,用户才能知道订单究竟停在哪里。

7. 本篇小结#

前后台状态的解释差异#

管理端关心“待审核”和“待调度”的操作区别,用户端更关心“平台正在确认”和“等待安排配送”。页面没有修改原始枚举,而是通过视图函数提供用户文案。这样接口与排查日志仍使用统一状态,界面表达则更自然。

轮询的边界#

只有 UNPAID、PENDING_AUDIT、WAIT_DISPATCH、DELIVERING 等可变状态需要轮询。订单进入完成、取消、驳回等终态后停止计时器。页面隐藏时也停止,重新显示再立即拉取一次,避免小程序在后台持续耗电和请求。

详情中的价格、来源订单号、MMSI 和流程时间都通过统一格式化函数处理。缺失值显示 --,金额固定两位小数,订单号始终使用业务 orderNo。这些规则看起来零碎,但正是用户判断“是不是我的那张订单”的依据。

订单模块让我意识到,“状态”不是卡片右上角的四个字,而是接口、按钮、倒计时、时间线和跳转共同遵守的规则。只改颜色不改行为,就像给红灯刷成绿色,路还是会堵。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
小程序开发日记②:订单列表、详情与支付状态
https://firefly.cuteleaf.cn/posts/mmp-dev-diary-2/
作者
Yore
发布于
2026-08-09
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Yore
Hello, I'm Yore.
公告
欢迎来到Yore的博客!本站基于原创作者夏叶的博客网站模版创作。
分类
标签
最新动态
站点统计
文章
51
分类
2
标签
124
总字数
94,115
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.15.0
文章许可
CC BY-NC-SA 4.0