基于HarmonyOS的情侣美食管理应用开发实战(十一)- 主厨订单处理功能
📖 系列文章目录
- (一)项目设计与角色管理
- (二)菜谱管理与订单系统
- (三)美食相册与设置功能
- (四)数据库优化与问题解决
- (五)数据持久化问题修复
- (六)图片显示问题修复
- (七)菜谱详情页面开发
- (八)收藏功能实现
- (九)食客菜谱浏览功能
- (十)点餐清单与提交订单
- (十一)主厨订单处理功能(本文)
- (十二)双向订单记录查询
一、功能概述
1.1 需求分析
主厨需要能够查看食客提交的订单,并进行相应的处理操作。本章节将实现主厨的订单管理功能,包括:
- 订单列表展示:展示所有订单,按时间倒序排列
- 待处理提醒:待处理订单显示红点提示
- 订单状态管理:接受、开始制作、完成、取消订单
- 订单详情查看:查看订单的完整信息
1.2 功能特点
✅ 实时更新:订单状态变更实时反映
✅ 提醒明显:待处理订单红点提示
✅ 操作便捷:一键处理订单
✅ 状态清晰:不同状态使用不同颜色标识
二、订单状态流转
2.1 状态流转图
**
**
待处理 ──接受──> 已接受 ──开始──> 制作中 ──完成──> 已完成
│ │
└──取消──> 已取消 <──取消──┘
2.2 状态操作权限
| 当前状态 | 可执行操作 | 操作角色 |
|---|---|---|
| 待处理 | 接受、取消 | 主厨 |
| 已接受 | 开始制作、取消 | 主厨 |
| 制作中 | 完成制作 | 主厨 |
| 已完成 | 无 | - |
| 已取消 | 无 | - |
三、订单列表展示
3.1 数据库查询方法
在RdbUtil中添加查询所有订单的方法:
static async queryAllOrders(): Promise<Order[]> {
try {
const predicates = new relationalStore.RdbPredicates('order')
predicates.orderByDesc('order_time') // 按下单时间倒序
const resultSet = await this.rdbStore.query(predicates)
const orders: Order[] = []
while (resultSet.goToNextRow()) {
const order = Order.fromJson({
id: resultSet.getLong(resultSet.getColumnIndex('id')),
recipe_id: resultSet.getLong(resultSet.getColumnIndex('recipe_id')),
recipe_name: resultSet.getString(resultSet.getColumnIndex('recipe_name')),
recipe_image: resultSet.getString(resultSet.getColumnIndex('recipe_image')),
status: resultSet.getLong(resultSet.getColumnIndex('status')),
remark: resultSet.getString(resultSet.getColumnIndex('remark')),
order_time: resultSet.getLong(resultSet.getColumnIndex('order_time')),
accept_time: resultSet.getLong(resultSet.getColumnIndex('accept_time')),
complete_time: resultSet.getLong(resultSet.getColumnIndex('complete_time')),
create_time: resultSet.getLong(resultSet.getColumnIndex('create_time')),
update_time: resultSet.getLong(resultSet.getColumnIndex('update_time'))
})
orders.push(order)
}
resultSet.close()
return orders
} catch (err) {
LogUtil.error('RdbUtil', `查询所有订单失败: ${err}`)
return []
}
}
3.2 订单列表UI
**
**
@Builder
OrderList() {
if (this.orders.length === 0) {
// 空状态
Column() {
Text('🕐')
.fontSize(60)
.fontColor(CommonStyle.TEXT_COLOR_HINT)
Text('暂无订单')
.fontSize(16)
.fontColor(CommonStyle.TEXT_COLOR_HINT)
.margin({ top: 16 })
}
.width('100%')
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
} else {
// 订单列表
List({ space: 12 }) {
ForEach(this.orders, (order: Order) => {
ListItem() {
this.OrderCard(order)
}
}, (order: Order) => order.id.toString())
}
.width('100%')
.layoutWeight(1)
.padding({ left: 16, right: 16 })
}
}
四、订单卡片设计
4.1 卡片UI实现
**
**
@Builder
OrderCard(order: Order) {
Column() {
// 订单头部
Row() {
Text(order.recipeName)
.fontSize(16)
.fontColor(CommonStyle.TEXT_COLOR_PRIMARY)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
Text(this.getOrderStatusText(order.status))
.fontSize(12)
.fontColor(CommonStyle.TEXT_COLOR_WHITE)
.backgroundColor(this.getOrderStatusColor(order.status))
.borderRadius(CommonStyle.BORDER_RADIUS_ROUND)
.padding({ left: 12, right: 12, top: 4, bottom: 4 })
}
.width('100%')
// 订单信息
Row() {
if (order.recipeImage) {
Image(order.recipeImage)
.width(60)
.height(60)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.objectFit(ImageFit.Cover)
} else {
Column() {
Text('🍳')
.fontSize(30)
}
.width(60)
.height(60)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.backgroundColor(CommonStyle.BG_COLOR_GRAY)
.justifyContent(FlexAlign.Center)
}
Column() {
Text(`下单时间: ${this.formatTime(order.orderTime)}`)
.fontSize(12)
.fontColor(CommonStyle.TEXT_COLOR_SECONDARY)
if (order.remark) {
Text(`备注: ${order.remark}`)
.fontSize(12)
.fontColor(CommonStyle.TEXT_COLOR_SECONDARY)
.margin({ top: 4 })
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
.padding({ left: 12 })
}
.width('100%')
.margin({ top: 12 })
// 操作按钮
this.OrderActions(order)
}
.width('100%')
.padding(16)
.backgroundColor(CommonStyle.BG_COLOR_WHITE)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
}
4.2 状态颜色映射
getOrderStatusText(status: number): string {
switch (status) {
case CommonConstant.ORDER_STATUS_PENDING: return '待处理'
case CommonConstant.ORDER_STATUS_ACCEPTED: return '已接受'
case CommonConstant.ORDER_STATUS_COOKING: return '制作中'
case CommonConstant.ORDER_STATUS_COMPLETED: return '已完成'
case CommonConstant.ORDER_STATUS_CANCELLED: return '已取消'
default: return '未知'
}
}
getOrderStatusColor(status: number): string {
switch (status) {
case CommonConstant.ORDER_STATUS_PENDING: return '#FF9500' // 橙色
case CommonConstant.ORDER_STATUS_ACCEPTED: return '#34C759' // 绿色
case CommonConstant.ORDER_STATUS_COOKING: return '#007AFF' // 蓝色
case CommonConstant.ORDER_STATUS_COMPLETED: return '#8E8E93' // 灰色
case CommonConstant.ORDER_STATUS_CANCELLED: return '#FF3B30' // 红色
default: return '#8E8E93'
}
}
五、订单操作功能
5.1 操作按钮UI
**
**
@Builder
OrderActions(order: Order) {
if (order.status !== CommonConstant.ORDER_STATUS_COMPLETED &&
order.status !== CommonConstant.ORDER_STATUS_CANCELLED) {
Row() {
if (order.status === CommonConstant.ORDER_STATUS_PENDING) {
// 待处理状态:接受/取消
Button('接受')
.fontSize(14)
.fontColor(CommonStyle.TEXT_COLOR_WHITE)
.backgroundColor(RoleStyle.CHEF_COLOR)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.layoutWeight(1)
.height(36)
.onClick(() => {
this.acceptOrder(order)
})
Button('取消')
.fontSize(14)
.fontColor(CommonStyle.TEXT_COLOR_SECONDARY)
.backgroundColor(CommonStyle.BG_COLOR_GRAY)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.layoutWeight(1)
.height(36)
.margin({ left: 12 })
.onClick(() => {
this.cancelOrder(order)
})
} else if (order.status === CommonConstant.ORDER_STATUS_ACCEPTED) {
// 已接受状态:开始制作/取消
Button('开始制作')
.fontSize(14)
.fontColor(CommonStyle.TEXT_COLOR_WHITE)
.backgroundColor(RoleStyle.CHEF_COLOR)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.layoutWeight(1)
.height(36)
.onClick(() => {
this.startCooking(order)
})
Button('取消')
.fontSize(14)
.fontColor(CommonStyle.TEXT_COLOR_SECONDARY)
.backgroundColor(CommonStyle.BG_COLOR_GRAY)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.layoutWeight(1)
.height(36)
.margin({ left: 12 })
.onClick(() => {
this.cancelOrder(order)
})
} else if (order.status === CommonConstant.ORDER_STATUS_COOKING) {
// 制作中状态:完成制作
Button('完成制作')
.fontSize(14)
.fontColor(CommonStyle.TEXT_COLOR_WHITE)
.backgroundColor(RoleStyle.CHEF_COLOR)
.borderRadius(CommonStyle.BORDER_RADIUS_MD)
.width('100%')
.height(36)
.onClick(() => {
this.completeOrder(order)
})
}
}
.width('100%')
.margin({ top: 12 })
}
}
5.2 订单更新方法
在RdbUtil中添加更新订单的方法:
static async updateOrder(order: Order): Promise<boolean> {
try {
const valueBucket: relationalStore.ValuesBucket = {
'status': order.status,
'accept_time': order.acceptTime,
'complete_time': order.completeTime,
'update_time': Date.now()
}
const predicates = new relationalStore.RdbPredicates('order')
predicates.equalTo('id', order.id)
const changedRows = await this.rdbStore.update(valueBucket, predicates)
return changedRows > 0
} catch (err) {
LogUtil.error('RdbUtil', `更新订单失败: ${err}`)
return false
}
}
5.3 操作逻辑实现
// 接受订单
async acceptOrder(order: Order) {
order.status = CommonConstant.ORDER_STATUS_ACCEPTED
order.acceptTime = Date.now()
const success = await RdbUtil.updateOrder(order)
if (success) {
promptAction.showToast({ message: '已接受订单', duration: 2000 })
this.loadOrders() // 刷新列表
}
}
// 开始制作
async startCooking(order: Order) {
order.status = CommonConstant.ORDER_STATUS_COOKING
const success = await RdbUtil.updateOrder(order)
if (success) {
promptAction.showToast({ message: '开始制作', duration: 2000 })
this.loadOrders()
}
}
// 完成制作
async completeOrder(order: Order) {
order.status = CommonConstant.ORDER_STATUS_COMPLETED
order.completeTime = Date.now()
const success = await RdbUtil.updateOrder(order)
if (success) {
promptAction.showToast({ message: '制作完成', duration: 2000 })
this.loadOrders()
}
}
// 取消订单
async cancelOrder(order: Order) {
order.status = CommonConstant.ORDER_STATUS_CANCELLED
const success = await RdbUtil.updateOrder(order)
if (success) {
promptAction.showToast({ message: '订单已取消', duration: 2000 })
this.loadOrders()
}
}
六、待处理订单提醒
6.1 红点提示实现
@Builder
OrderTabTitle() {
Row() {
Text('订单')
.fontSize(16)
.fontColor(this.currentTab === 1 ?
RoleStyle.CHEF_COLOR : CommonStyle.TEXT_COLOR_SECONDARY)
.fontWeight(this.currentTab === 1 ? FontWeight.Bold : FontWeight.Normal)
// 待处理订单红点
if (this.pendingOrderCount > 0) {
Badge({
count: this.pendingOrderCount,
position: BadgePosition.RightTop,
style: { badgeSize: 16, badgeColor: '#FF3B30' }
}) {
Text('')
.width(1)
.height(1)
}
}
}
}
6.2 待处理订单计数
async loadPendingOrderCount() {
try {
const pendingOrders = await RdbUtil.queryOrdersByStatus(
CommonConstant.ORDER_STATUS_PENDING
)
this.pendingOrderCount = pendingOrders.length
} catch (err) {
LogUtil.error('ChefHomePage', `加载待处理订单数量失败: ${err}`)
}
}
七、技术要点总结
7.1 状态驱动UI
// 根据订单状态显示不同的操作按钮
if (order.status === CommonConstant.ORDER_STATUS_PENDING) {
// 显示接受/取消按钮
} else if (order.status === CommonConstant.ORDER_STATUS_ACCEPTED) {
// 显示开始制作/取消按钮
} else if (order.status === CommonConstant.ORDER_STATUS_COOKING) {
// 显示完成制作按钮
}
7.2 时间戳处理
formatTime(timestamp: number): string {
if (!timestamp) {
return ''
}
const date = new Date(timestamp)
const month = (date.getMonth() + 1).toString().padStart(2, '0')
const day = date.getDate().toString().padStart(2, '0')
const hour = date.getHours().toString().padStart(2, '0')
const minute = date.getMinutes().toString().padStart(2, '0')
return `${month}-${day} ${hour}:${minute}`
}
7.3 数据刷新机制
// 操作完成后刷新列表
async acceptOrder(order: Order) {
// ... 更新订单状态
const success = await RdbUtil.updateOrder(order)
if (success) {
this.loadOrders() // 重新加载订单列表
}
}
八、总结
通过本篇文章,我们完成了主厨订单处理功能的开发:
✅ 订单列表展示:按时间倒序展示所有订单
✅ 状态管理完整:支持接受、制作、完成、取消操作
✅ 提醒机制明显:待处理订单红点提示
✅ 交互体验友好:操作按钮清晰,状态标识明确
下一篇文章将介绍双向订单记录查询功能的实现,敬请期待!