HarmonyOS 鸿蒙Next《仿盒马》app开发技术分享之回收订单详情页

HarmonyOS 鸿蒙Next《仿盒马》app开发技术分享之 回收订单详情页

技术栈

Appgallery connect

开发准备

上一节我们实现了订单列表的所有功能,展示了待取件、已取消、运输中、已完成等订单列表的数据展示,并且在对应的订单中点击功能按钮实现了订单的状态切换,这一节我们就要通过点击对应列表内的订单进入相应的订单详情页,展示当前订单的状态和对应的信息,当进入的是已完成订单时展示当前订单的收益,分别显示收入多少金额和对应的积分

功能分析

要实现订单详情查看的功能,首先需要在对应的item添加点击事件,传递当前的订单id过去详情页面,在详情页面接收对应的id,根据id查询当前对应的订单,展示到对应的组件内,然后根据订单内的weightid查询出当前订单的重量,件数,金额收益,积分收益,展示到已完成订单的详情内

代码实现

首先我们先吧对应的实体添加一下

//订单
class RecycleInfo {
    id: number;
    user_id: number = 0;
    nike_name: string;
    phone: string;
    address: string;
    day: string;
    start_time: string;
    end_time: string;
    msg: string;
    weight_id: string;
    create_time: string;
    express_code: string;
    express_people: string;
    express_company: string;
    order_type: number;
    logistics_id: number;
    constructor() {}

    setId(id: number): void {
        this.id = id;
    }

    getId(): number {
        return this.id;
    }

    setUser_id(user_id: number): void {
        this.user_id = user_id;
    }

    getUser_id(): number {
        return this.user_id;
    }

    setNike_name(nike_name: string): void {
        this.nike_name = nike_name;
    }

    getNike_name(): string {
        return this.nike_name;
    }

    setPhone(phone: string): void {
        this.phone = phone;
    }

    getPhone(): string {
        return this.phone;
    }

    setAddress(address: string): void {
        this.address = address;
    }

    getAddress(): string {
        return this.address;
    }

    setDay(day: string): void {
        this.day = day;
    }

    getDay(): string {
        return this.day;
    }

    setStart_time(start_time: string): void {
        this.start_time = start_time;
    }

    getStart_time(): string {
        return this.start_time;
    }

    setEnd_time(end_time: string): void {
        this.end_time = end_time;
    }

    getEnd_time(): string {
        return this.end_time;
    }

    setMsg(msg: string): void {
        this.msg = msg;
    }

    getMsg(): string {
        return this.msg;
    }

    setWeight_id(weight_id: string): void {
        this.weight_id = weight_id;
    }

    getWeight_id(): string {
        return this.weight_id;
    }

    setCreate_time(create_time: string): void {
        this.create_time = create_time;
    }

    getCreate_time(): string {
        return this.create_time;
    }

    setExpress_code(express_code: string): void {
        this.express_code = express_code;
    }

    getExpress_code(): string {
        return this.express_code;
    }

    setExpress_people(express_people: string): void {
        this.express_people = express_people;
    }

    getExpress_people(): string {
        return this.express_people;
    }

    setExpress_company(express_company: string): void {
        this.express_company = express_company;
    }

    getExpress_company(): string {
        return this.express_company;
    }

    setOrder_type(order_type: number): void {
        this.order_type = order_type;
    }

    getOrder_type(): number {
        return this.order_type;
    }

    setLogistics_id(logistics_id: number): void {
        this.logistics_id = logistics_id;
    }

    getLogistics_id(): number {
        return this.logistics_id;
    }

    static parseFrom(inputObject: any): RecycleInfo {
        let result = new RecycleInfo();
        if (!inputObject) {
            return result;
        }
        if (inputObject.id) {
            result.id = inputObject.id;
        }
        if (inputObject.user_id) {
            result.user_id = inputObject.user_id;
        }
        if (inputObject.nike_name) {
            result.nike_name = inputObject.nike_name;
        }
        if (inputObject.phone) {
            result.phone = inputObject.phone;
        }
        if (inputObject.address) {
            result.address = inputObject.address;
        }
        if (inputObject.day) {
            result.day = inputObject.day;
        }
        if (inputObject.start_time) {
            result.start_time = inputObject.start_time;
        }
        if (inputObject.end_time) {
            result.end_time = inputObject.end_time;
        }
        if (inputObject.msg) {
            result.msg = inputObject.msg;
        }
        if (inputObject.weight_id) {
            result.weight_id = inputObject.weight_id;
        }
        if (inputObject.create_time) {
            result.create_time = inputObject.create_time;
        }
        if (inputObject.express_code) {
            result.express_code = inputObject.express_code;
        }
        if (inputObject.express_people) {
            result.express_people = inputObject.express_people;
        }
        if (inputObject.express_company) {
            result.express_company = inputObject.express_company;
        }
        if (inputObject.order_type) {
            result.order_type = inputObject.order_type;
        }
        if (inputObject.logistics_id) {
            result.logistics_id = inputObject.logistics_id;
        }
        return result;
    }
}

export { RecycleInfo };
//规格
class WeightInfo {
    id: number;
    weight_id: number;
    weight: string;
    txt: string;
    integral: number;
    money: number;
    constructor() {}

    setId(id: number): void {
        this.id = id;
    }

    getId(): number {
        return this.id;
    }

    setWeight_id(weight_id: number): void {
        this.weight_id = weight_id;
    }

    getWeight_id(): number {
        return this.weight_id;
    }

    setWeight(weight: string): void {
        this.weight = weight;
    }

    getWeight(): string {
        return this.weight;
    }

    setTxt(txt: string): void {
        this.txt = txt;
    }

    getTxt(): string {
        return this.txt;
    }

    setIntegral(integral: number): void {
        this.integral = integral;
    }

    getIntegral(): number {
        return this.integral;
    }

    setMoney(money: number): void {
        this.money = money;
    }

    getMoney(): number {
        return this.money;
    }
}

export { WeightInfo };

首先添加对应的点击事件,在所有的列表都要添加上

.onClick(() => {
    router.pushUrl({ url: "pages/recycle/order/RecycleOrderDetailsPage", params: { code: item.id }})
})

然后在订单详情页面接收对应的id

let params = (this.getUIContext().getRouter().getParams() as Record<string, string>)['code']
if (params != undefined && params != '') {
    this.orderCode = params
}

根据id查询出对应的订单详情

let databaseZone = cloudDatabase.zone('default');
let condition = new cloudDatabase.DatabaseQuery(recycle_info);
condition.equalTo("id", this.orderCode!)
let listData = await databaseZone.query(condition);
let json = JSON.stringify(listData)
let data1: RecycleInfo[] = JSON.parse(json)
this.orderInfo = data1[0]

拿到id对应的订单之后,我们根据当前订单的weightid查询出对应的重量、收益、积分等信息

let condition1 = new cloudDatabase.DatabaseQuery(weight_info);
condition1.equalTo("weight_id", data1[0].weight_id)
let listData1 = await databaseZone.query(condition1);
let json1 = JSON.stringify(listData1)
let data: WeightInfo[] = JSON.parse(json1)
this.weightInfo = data[0]

然后我们把对应的信息填充到组件上

import { hilog } from '@kit.PerformanceAnalysisKit';
import { cloudDatabase } from '@kit.CloudFoundationKit';
import { CommonTopBar } from '../../widget/CommonTopBar';
import { recycle_info } from '../../clouddb/recycle_info';
import { RecycleInfo } from '../../entity/RecycleInfo';
import { weight_info } from '../../clouddb/weight_info';
import { WeightInfo } from '../../entity/WeightInfo';

@Entry
@Component
struct OrderDetailsPage {
    @State orderInfo: RecycleInfo | null = null
    @State orderCode: string = ''
    @State flag: boolean = false
    @State titleStr: string = ''
    @State msgStr: string = ''
    @State weightInfo: WeightInfo | null = null

    async aboutToAppear(): Promise<void> {
        let params = (this.getUIContext().getRouter().getParams() as Record<string, string>)['code']
        if (params != undefined && params != '') {
            this.orderCode = params
        }
        let databaseZone = cloudDatabase.zone('default');
        let condition = new cloudDatabase.DatabaseQuery(recycle_info);
        condition.equalTo("id", this.orderCode!)
        let listData = await databaseZone.query(condition);
        let json = JSON.stringify(listData)
        let data1: RecycleInfo[] = JSON.parse(json)
        this.orderInfo = data1[0]

        let condition1 = new cloudDatabase.DatabaseQuery(weight_info);
        condition1.equalTo("weight_id", data1[0].weight_id)
        let listData1 = await databaseZone.query(condition1);
        let json1 = JSON.stringify(listData1)
        let data: WeightInfo[] = JSON.parse(json1)
        this.weightInfo = data[0]
        hilog.info(0x0000, 'testTag', `Succeeded in querying data, result: ${JSON.parse(json)}`);
        if (this.orderInfo?.order_type == 0) {
            this.titleStr = "待取件"
            this.msgStr = '已通知快递小哥按时上门取件,请耐心等候'
        }
        if (this.orderInfo?.order_type == 1) {
            this.titleStr = "已取消"
            this.msgStr = '订单已取消,感谢您的使用'
        }
        if (this.orderInfo?.order_type == 2) {
            this.titleStr = "运输中"
            this.msgStr = '包裹已寄出,将会根据订单发放奖励'
        }
        if (this.orderInfo?.order_type == 3) {
            this.titleStr = "已完成"
            this.msgStr = '奖励已发放'
        }
        this.flag = true
    }

    build() {
        if (this.flag) {
            Column() {
                CommonTopBar({ title: "订单详情", alpha: 0, titleAlignment: TextAlign.Center, backButton: true })
                Scroll() {
                    Column() {
                        Column({ space: 15 }) {
                            Text(this.titleStr)
                                .fontSize(20)
                                .width('100%')
                                .textAlign(TextAlign.Center)
                                .fontColor(Color.Black)
                                .fontWeight(FontWeight.Bold)
                            Text(this.msgStr)
                                .fontSize(16)
                                .fontColor(Color.Black)
                                .width('100%')
                                .textAlign(TextAlign.Center)
                        }
                        .width('100%')
                        .padding(15)
                        .backgroundColor("#fff3574a")
                        .alignItems(HorizontalAlign.Start)
                        Divider()
                            .width('100%')
                            .height(5)
                            .color("#e6e6e6")
                        Column() {
                            Row({ space: 20 }) {
                                Image($r('app.media.order_location'))
                                    .height(20)
                                    .width(20)
                                Column() {
                                    Row() {
                                        Text(this.orderInfo?.nike_name)
                                            .fontColor(Color.Black)
                                            .fontSize(16)
                                            .fontWeight(FontWeight.Bold)
                                        Text(this.orderInfo?.phone)
                                            .fontColor(Color.Black)
                                            .fontSize(16)
                                            .fontWeight(FontWeight.Bold)
                                            .margin({ left: 20 })
                                    }
                                    Text(this.orderInfo?.address)
                                        .fontColor(Color.Black)
                                        .fontSize(16)
                                        .margin({ top: 10 })
                                }
                                .padding(10)
                                .alignItems(HorizontalAlign.Start)
                                .width('100%')
                            }
                        }
                        .padding(10)
                        .alignItems(HorizontalAlign.Start)
                        .width('100%')
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Column() {
                            Row() {
                                Row({ space: 10 }) {
                                    Image($r('app.media.background'))
                                        .height(70)
                                        .width(70)
                                        .margin({ left: 10 })
                                        .borderRadius(10)
                                    Column({ space: 5 }) {
                                        Text("衣帽鞋包")
                                            .fontColor(Color.Black)
                                            .fontSize(14)
                                        Text("回收重量:" + this.weightInfo?.weight)
                                            .fontColor(Color.Grey)
                                            .fontSize(14)
                                    }
                                    .alignItems(HorizontalAlign.Start)
                                }
                                .justifyContent(FlexAlign.Start)
                                .alignItems(VerticalAlign.Top)
                            }
                            .padding(10)
                            .width('100%')
                            .alignItems(VerticalAlign.Top)
                            .justifyContent(FlexAlign.SpaceBetween)
                            Divider()
                                .width('100%')
                                .height(1)
                                .backgroundColor("#f7f7f7")
                            if (this.orderInfo?.order_type == 3) {
                                Row() {
                                    Text()
                                    Blank()
                                    Text() {
                                        Span("订单奖励:")
                                            .fontSize(16)
                                            .fontColor(Color.Black)
                                        Span("¥" + String(this.weightInfo?.money))
                                            .fontSize(12)
                                            .fontColor(Color.Red)
                                        Span("积分:" + String(this.weightInfo?.integral))
                                            .fontSize(12)
                                            .fontColor(Color.Red)
                                    }
                                }
                                .padding(10)
                                .width('100%')
                                .justifyContent(FlexAlign.SpaceBetween)
                            }
                        }
                        .width('100%')
                        Divider()
                            .width('100%')
                            .height(5)
                            .color("#e6e6e6")
                        Text("快递信息")
                            .fontSize(18)
                            .fontColor(Color.Black)
                            .fontWeight(FontWeight.Bold)
                            .margin({ left: 15 })
                        Divider()
                            .width('100%')
                            .height(5)
                            .color("#e6e6e6")
                        Row() {
                            Text("运单编号:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo?.express_code)
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Row() {
                            Text("快递公司:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo?.express_company)
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Row() {
                            Text("快递员:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo?.express_people)
                                .fontSize(16)
                                .fontColor(Color.Black)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(5)
                            .color("#e6e6e6")
                        Text("下单信息")
                            .fontSize(18)
                            .fontColor(Color.Black)
                            .fontWeight(FontWeight.Bold)
                            .margin({ left: 15 })
                        Divider()
                            .width('100%')
                            .height(5)
                            .color("#e6e6e6")
                        Row() {
                            Text("联系人:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo?.nike_name + " " + this.orderInfo?.phone)
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Row() {
                            Text("取件地址:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo?.address)
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Row() {
                            Text("预约时间:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo!.day + this.orderInfo?.start_time + "--" + this.orderInfo?.end_time)
                                .fontSize(16)
                                .fontColor(Color.Black)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Row() {
                            Text("备注:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo?.msg != '' ? this.orderInfo?.msg : "无")
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Divider()
                            .width('100%')
                            .height(0.8)
                            .color("#e6e6e6")
                        Row() {
                            Text("订单编号:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(String(this.orderInfo?.id))
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                        Row() {
                            Text("创建时间:")
                                .fontSize(16)
                                .fontColor(Color.Black)
                            Blank()
                            Text(this.orderInfo!.day + this.orderInfo?.start_time)
                                .fontColor(Color.Black)
                                .fontSize(14)
                        }
                        .justifyContent(FlexAlign.SpaceBetween)
                        .width('100%')
                        .padding(10)
                    }
                }
                .height('100%')
                .margin({ bottom: 50 })
                .backgroundColor(Color.White)
                .alignItems(HorizontalAlign.Start)
            }
            .height('100%')
            .width('100%')
        }
    }
}

更多关于HarmonyOS 鸿蒙Next《仿盒马》app开发技术分享之回收订单详情页的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

鸿蒙Next开发仿盒马App的回收订单详情页,主要涉及以下技术点:

  1. 使用ArkUI框架构建页面布局
  2. 声明式UI开发方式
  3. 自定义组件实现订单卡片
  4. 数据绑定展示订单详情
  5. 路由导航管理页面跳转

关键实现:

  • 通过Column/Row/Flex等布局组件构建页面结构
  • 使用ForEach渲染订单商品列表
  • @State/@Prop管理组件状态
  • 自定义Dialog组件处理操作确认

性能优化:

  • 列表项使用复用机制
  • 合理使用组件生命周期,

更多关于HarmonyOS 鸿蒙Next《仿盒马》app开发技术分享之回收订单详情页的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


从技术实现来看,这个订单详情页的开发思路清晰合理,主要实现了以下核心功能:

  1. 数据传递与接收:
  • 通过router.pushUrl传递订单ID参数
  • 使用getRouter().getParams()接收参数
  1. 数据查询:
  • 使用CloudDB的DatabaseQuery进行订单数据查询
  • 通过equalTo条件精确查询特定订单
  • 二次查询关联的重量规格信息
  1. 状态管理:
  • 使用@State管理组件状态
  • 根据order_type动态显示不同状态文本
  1. UI展示:
  • 采用Scroll+Column实现可滚动布局
  • 使用Divider进行内容分隔
  • 对已完成订单特殊显示收益信息

代码结构规范,查询逻辑完整,建议可以:

  1. 添加加载状态提示
  2. 增加错误处理机制
  3. 考虑使用缓存优化查询性能

整体实现符合HarmonyOS应用开发规范,是一个典型的数据详情页实现方案。

回到顶部