✅ 阶段 4 – 订单列表 & 状态
目标
- 展示用户「我的订单」列表
- 支持状态筛选(全部 / 待处理 / 已完成)
- 支持分页加载和实时刷新
- 使用原生组件编写
✅ 1. 页面结构:文件结构
pages/orders/├─ index.json├─ index.wxml├─ index.js└─ index.wxss
✅ 2. 页面配置 index.json
{"navigationBarTitleText": "我的订单"
}
✅ 3. 页面模板 index.wxml
<view class="tabs"><text class="tab {{activeTab==0 ? 'active' : ''}}" data-index="0" bindtap="onTabChange">全部</text><text class="tab {{activeTab==1 ? 'active' : ''}}" data-index="1" bindtap="onTabChange">待处理</text><text class="tab {{activeTab==2 ? 'active' : ''}}" data-index="2" bindtap="onTabChange">已完成</text>
</view><view wx:if="{{orders.length}}"><block wx:for="{{orders}}" wx:key="orderNo"><view class="order-card"><view class="order-header"><text>订单号:{{item.orderNo}}</text><text class="status {{item.status}}">{{item.status == 'PENDING' ? '待处理' : '已完成'}}</text></view><view class="order-body"><text>共 {{item.totalCount}} 件商品</text><text>合计:¥{{item.totalPrice}}</text></view><view class="order-time">{{item.timeStr}}</view></view></block>
</view><view wx:else class="empty"><text>暂无订单</text>
</view>
✅ 4. 样式 index.wxss
.tabs {display: flex;border-bottom: 1px solid #eee;background: #f8f8f8;
}
.tab {flex: 1;text-align: center;padding: 20rpx 0;font-size: 30rpx;color: #888;
}
.tab.active {color: #333;border-bottom: 4rpx solid #07c160;font-weight: bold;
}.order-card {background: #fff;margin: 20rpx;padding: 20rpx;border-radius: 12rpx;box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.04);
}
.order-header {display: flex;justify-content: space-between;font-weight: bold;
}
.status {font-size: 28rpx;
}
.status.PENDING {color: #ff9900;
}
.status.DONE {color: #07c160;
}
.order-body {margin-top: 10rpx;font-size: 28rpx;display: flex;justify-content: space-between;
}
.order-time {font-size: 24rpx;color: #999;margin-top: 10rpx;text-align: right;
}
.empty {text-align: center;color: #999;font-size: 28rpx;padding: 100rpx 0;
}
✅ 5. 页面逻辑 index.js
const db = wx.cloud.database()
const PAGE_SIZE = 10Page({data: {activeTab: 0,orders: [],page: 0,finished: false},onShow() {this.resetAndLoad()this.timer = setInterval(() => this.refresh(), 5000)},onHide() {clearInterval(this.timer)},onUnload() {clearInterval(this.timer)},onTabChange(e) {this.setData({ activeTab: Number(e.currentTarget.dataset.index) })this.resetAndLoad()},resetAndLoad() {this.setData({ orders: [], page: 0, finished: false })this.loadPage()},async loadPage(isRefresh = false) {if (this.data.finished) returnconst statusMap = ['', 'PENDING', 'DONE']const filter = statusMap[this.data.activeTab]let query = db.collection('orders')if (filter) {query = query.where({ status: filter })}const res = await query.orderBy('createdAt', 'desc').skip(this.data.page * PAGE_SIZE).limit(PAGE_SIZE).get()const list = res.data.map(o => ({...o,totalCount: o.items.reduce((sum, i) => sum + i.count, 0),timeStr: this.formatTime(o.createdAt)}))this.setData({orders: isRefresh ? list : this.data.orders.concat(list),page: this.data.page + 1,finished: list.length < PAGE_SIZE})},refresh() {this.setData({ page: 0, finished: false })this.loadPage(true)},formatTime(ts) {const date = new Date(ts)return `${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`}
})
✅ 6. 自测 Checklist
- 能切换订单状态:全部 / 待处理 / 已完成
- 正确显示订单号、商品数量、金额
- 页面卡片样式清晰
- 页面首次进入加载数据
- 每 5 秒自动刷新状态(模拟店员更新)
- 无订单时显示「暂无订单」