《仿盒马》app开发技术分享-- 购物车业务逻辑完善(端云一体)

article/2025/7/4 4:52:40

开发准备

之前我们已经实现了购物车相关的内容,实现了购物车数据列表的展示,但是我们结算订单之后我们的购物车列表并没有刷新,而且底部的状态栏并没有明显的数据展示来提醒用户,而且当我们在商品详情页添加新商品,底部也没有同步更新,这一节我们要解决的问题就是这些

功能分析

1.新增商品
新增商品时我们需要在底部展示一个当前商品数量的标记展示在购物车图标的右上角
2.提交购物车商品列表
当我们提交购物车商品列表时,我们需要同步刷新购物车右上角数量展示,以及购物车列表页面的数据更新
3.购物车商品删除
当购物车商品滑动删除时,刷新列表页面的列表,以及更新底部状态栏的商品数量展示

代码实现

首先在底部购物车图标右上角新增Badge组件

 @Builder tabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {Column() {if (targetIndex==2){Badge({count: this.badgeCount,style: { badgeSize: 14, badgeColor: '#FA2A2D'},position: BadgePosition.RightTop,}){Image(this.currentIndex === targetIndex ? selectedImg : normalImg).width(30).height(30)}}else {Image(this.currentIndex === targetIndex ? selectedImg : normalImg).width(this.isCheck_Index_One&&targetIndex===0?50:25).height(this.isCheck_Index_One&&targetIndex===0?50:25).borderRadius(this.isCheck_Index_One&&targetIndex===0?25:0)}Text(title).fontSize(14).margin({top:5}).fontWeight(this.currentIndex === targetIndex ?FontWeight.Bold:FontWeight.Normal).fontColor(this.currentIndex === targetIndex ? '#fff65753' : '#6B6B6B')}.width('100%').height(50).justifyContent(FlexAlign.Center)}

然后我们在购物车组件内新增一个控制刷新的变量,并监听变量是否修改,修改后我们执行云数据库的查询方法,查询当前登录用户的购物车列表,当提交完订单之后,我们在订单提交页通过emitter传递状态

订单提交

        Text("提交订单").fontColor(Color.White).padding(10).borderRadius(10).backgroundColor("#d81e06").fontSize(14).onClick(async ()=>{if (this.addressInfo!=null) {let databaseZone = cloudDatabase.zone('default');try {for (let i = 0; i < this.productList.length; i++) {let productPush = new order_product_list();productPush.id=this.codeId+iproductPush.order_product_id=this.codeIdproductPush.img=this.productList[i].productImgAddressproductPush.price=this.productList[i].productPriceproductPush.name=this.productList[i].productNameproductPush.originalPrice=this.productList[i].productOriginalPriceproductPush.spec=this.productList[i].productSpecNameproductPush.buyAmount=this.productList[i].buyAmountlet num = await databaseZone.upsert(productPush);hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`);}}catch (e) {hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${e}`);}let orderPush = new order_list();orderPush.id=Math.floor(Math.random() * 1000000)orderPush.user_id=this.user!.user_idorderPush.order_product_id=String(this.codeId)orderPush.order_code=this.generateOrderNo(10)orderPush.order_status=0if (this.remark!='') {orderPush.order_remark=this.remark}orderPush.address=this.addressInfo.addressorderPush.nickname=this.addressInfo.nikeNameorderPush.phone=this.addressInfo.phoneorderPush.order_create_time=this.formatCurrentDate()orderPush.order_pay_time=this.formatCurrentDate()let num = await databaseZone.upsert(orderPush);hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`);if (num>0) {for (let i = 0; i < this.productList.length; i++) {if (this.productList[i].isNeedPay) {let item = new cart_product_list();item.id=this.productList[i].idlet listData = await databaseZone.delete(item);hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${listData}`);}}let eventData: emitter.EventData = {data: {}};let innerEvent: emitter.InnerEvent = {eventId: 1012,priority: emitter.EventPriority.HIGH};emitter.emit(innerEvent, eventData);router.replaceUrl({url:'pages/view/OrderSuccessPage',params:orderPush})}} else {showToast("请先选择地址")}})

购物车页

@Link @Watch("onListRefresh") listRefresh:booleanasync onListRefresh(){const  userInfo= await StorageUtils.getAll('user')if (userInfo!=null) {this.user=JSON.parse(userInfo)}if (this.currentIndexCheck==this.currentIndex) {let condition = new cloudDatabase.DatabaseQuery(cart_product_list);condition.equalTo("user_id",this.user?.user_id)let listData = await databaseZone.query(condition);let json = JSON.stringify(listData)this.productList= JSON.parse(json)hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${listData}`);this.getCountPrice()this.flag=true}}

首页接收

@State listRefresh:boolean=falselet innerEvent1: emitter.InnerEvent = {eventId: 1012};let callback1: Callback<emitter.EventData> = async (eventData: emitter.EventData) => {this.listRefresh=truelet databaseZone = cloudDatabase.zone('default');let condition = new cloudDatabase.DatabaseQuery(cart_product_list);condition.equalTo("user_id",this.user?.user_id)let listData = await databaseZone.query(condition);this.badgeCount=listData.length}emitter.on(innerEvent1, callback1);

新增商品

 Row(){Text("加入购物车").width('70%').borderRadius(30).textAlign(TextAlign.Center).fontColor(Color.Black).margin({top:70}).height(40).fontSize(18).fontWeight(FontWeight.Bold).backgroundColor("#FCDB29").onClick(async ()=>{try {let databaseZone = cloudDatabase.zone('default');let condition = new cloudDatabase.DatabaseQuery(cart_product_list);condition.equalTo("productId",this.product?.id).and().equalTo("productSpecId",this.specList[this.checkIndex].id)let listData = await databaseZone.query(condition);let json = JSON.stringify(listData)hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${json}`);let request:CartProductList[]=JSON.parse(json)let cartPush = new cart_product_list();if (request.length>0) {let data:CartProductList=request[0]cartPush.id=data.id;cartPush.productId=data.productId//商品idcartPush.productSpecId=data.productSpecId//规格idcartPush.productName=data.productName//商品名称cartPush.productSpecName=data.productSpecNamecartPush.productImgAddress=data.productImgAddresscartPush.buyAmount=this.addNumber+data.buyAmount//商品数量cartPush.isNeedPay=data.isNeedPay//是否选中 默认为truecartPush.activityType=data.activityType//活动类型 暂无cartPush.productPrice=data.productPrice//价格cartPush.productOriginalPrice=data.productOriginalPrice//划线价cartPush.couponPrice=data.couponPrice}else {cartPush.id=Math.floor(Math.random() * 1000000);cartPush.productId=this.product!.id//商品idcartPush.productSpecId=this.specList[this.checkIndex].id//规格idcartPush.productName=this.product!.name//商品名称cartPush.productSpecName=this.specList[this.checkIndex].namecartPush.productImgAddress=this.product!.url//图片地址cartPush.buyAmount=this.addNumber//商品数量cartPush.isNeedPay=true//是否选中 默认为truecartPush.activityType="1"//活动类型 暂无cartPush.productPrice=this.product!.price//价格cartPush.productOriginalPrice=this.product!.original_price//划线价cartPush.couponPrice=0cartPush.user_id=this.user!.user_id}let num = await databaseZone.upsert(cartPush);hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${num}`);if (num>0) {showToast("添加商品成功")}let eventData: emitter.EventData = {data: {}};let innerEvent: emitter.InnerEvent = {eventId: 1011,priority: emitter.EventPriority.HIGH};emitter.emit(innerEvent, eventData);this.controller.close()}catch (err) {hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${err}`);}})}.width('100%').justifyContent(FlexAlign.Center)

我们执行代码看看效果
在这里插入图片描述
可以看到我们的效果已经成功展示出来了


http://www.hkcw.cn/article/brqFKvecil.shtml

相关文章

谷歌CEO皮查伊眼中的“下一代平台“与未来图景

目录 前言 一、从"能力秀"到"平台重构"&#xff1a;AI的"第二乐章" 二、"万物皆可创"&#xff1a;AI如何引爆每个人的创造力&#xff1f; 三、AI走出屏幕&#xff1a;XR眼镜与机器人的未来交响曲 四、Web不死&#xff0c;只是换了…

DDC Learning Record(2)

这些是 “UV 生成策略”&#xff0c;决定了 Houdini 如何分析模型空间&#xff0c;并分配 UV 坐标。它们只影响 UV 坐标的生成方式&#xff0c;不影响后续贴图的读取行为。 face得到的结果是&#xff1a; 每个面都被映射到了整张贴图&#xff08;[0,1]&#xff09;&#xff0c;…

MySQL数据库从0到1

目录 数据库概述 基本命令 查询命令 函数 表的操作 增删改数据和表结构 约束 事务 索引 视图 触发器 存储过程和函数 三范式 数据库概述 SQL语句的分类&#xff1a; DQL&#xff1a;查询语句&#xff0c;凡是select语句都是DQL。 DML&#xff1a;insert,delete,up…

STM32CubeDAC及DMA配置

STM32CubeDAC及DMA配置 一&#xff0c;问题1二&#xff0c;解决11&#xff0c;宏观思路CubeMX配置2&#xff0c;HAL_TIM_Base_Start(&htim6) 的作用1&#xff0c;作用1&#xff1a;使能TIM6的时钟并让它开始计数2&#xff0c;作用2&#xff1a;当 TIM6 溢出时&#xff0c;会…

c++ 赋值函数和拷贝构造函数的调用时机

测试代码&#xff1a; void testcopyAndFuzhi() {class Dog {private:string name;public:Dog(string myname) : name(myname) {}Dog(Dog& otherDog) {std::cout << "调用拷贝构造函数." << endl;this->name otherDog.name;}Dog& operator …

Python列表、字典、元组、集合

列表 list 基本格式&#xff1a;列表名 [元素1,元素2,元素3] 所有元素放在[ ]之中&#xff0c;元素之间用逗号","隔开&#xff0c;元素可以是不同的类型 列表的类型也是列表 li [1,"hello",2] print(type(li)) 列表是可迭代对象&#xff0c;可以用fo…

sctpscan:用于发现 SCTP 网络扫描器!全参数详细教程!Kali Linux教程!

简介 用于发现和安全的 SCTP 网络扫描器 sctpscan 是一款 SCTP 协议端口扫描工具&#xff0c;主要用于识别目标主机上开放的 SCTP&#xff08;Stream Control Transmission Protocol&#xff09;服务端口。 sctpscan 的主要功能是&#xff1a; 探测目标主机 SCTP 协议是否开…

力扣题解654:最大二叉树

一、题目内容 题目要求根据一个不重复的整数数组 nums 构建最大二叉树。最大二叉树的构建规则如下&#xff1a; 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值左边的子数组前缀上构建左子树。递归地在最大值右边的子数组后缀上构建右子树。返回由 nums 构…

车载诊断架构 --- DTC消抖参数(Trip Counter DTCConfirmLimit )

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

75.解决当编辑完用户消息,确认重新生成AI回答时,已有的AI回答还是存在,并且新生成的回答并没有显示到气泡里bug

在上一个bug解决完后&#xff0c;又出来一个bug&#xff0c;我真是服了哈哈哈 新的bug是&#xff1a; 当编辑完用户消息&#xff0c;确认重新生成AI回答时&#xff0c;已有的AI回答还是存在&#xff0c;并且新生成的回答并没有显示到气泡里 出现这个bug的原因还是出现在rege…

C# 用户控件(User Control)详解:创建、使用与最佳实践

在C#应用程序开发中&#xff0c;用户控件&#xff08;User Control&#xff09;是一种强大的工具&#xff0c;它允许开发者将多个标准控件组合成一个可复用的自定义组件。无论是Windows Forms还是WPF&#xff0c;用户控件都能显著提高UI开发的效率&#xff0c;减少重复代码&…

SpringBoot-配置Spring MVC

一、Spring MVC回顾 Spring MVC是一种常用的Java Web框架&#xff0c;它提供了一种基于MVC模式的开发方式&#xff0c;可以方便地实现Web应用程序。在Spring MVC中&#xff0c;WebMvcConfigurer是一种常用的配置方式&#xff0c;可以允许我们自定义Spring MVC的行为&#xff0c…

Python训练营打卡 Day26

知识点回顾&#xff1a; 函数的定义变量作用域&#xff1a;局部变量和全局变量函数的参数类型&#xff1a;位置参数、默认参数、不定参数传递参数的手段&#xff1a;关键词参数传递参数的顺序&#xff1a;同时出现三种参数类型时 ——————————————————————…

【Delphi】接收windows文件夹中文件拖拽

本文根据EmailX45的视频文件&#xff0c;进行了优化改进&#xff0c;原文参见&#xff1a;Delphi: Drag and Drop Files from Explorer into TPanel / TMemo - YouTube 在Windows中&#xff0c;如果将选择的文件拖动到Delphi程序的控件上&#xff0c;有很多实现方法&#xff0c…

电脑的ip地址会自动变怎么办?原因解析和解决方法

在当今互联网时代&#xff0c;IP地址是每台联网设备的"身份证"&#xff0c;但很多用户都遇到过IP地址自动变化的情况。这种现象既可能发生在内网&#xff08;局域网&#xff09;环境中&#xff0c;也可能出现在外网&#xff08;公网&#xff09;连接中。要理解IP地址…

CppCon 2014 学习: C++11 in the Wild

介绍了三个现代 C 的实用工具或功能。下面是对每部分的解释和总结&#xff1a; 1. Auto() 宏 用途&#xff1a;在作用域结束时自动执行清理代码&#xff0c;类似于 RAII 的机制。功能&#xff1a;你可以定义一段代码&#xff0c;在作用域结束时自动执行&#xff08;不需要手动…

三大模块曝光:分钟级搭建专属平台,解锁算力灵活操控新体验,重新定义智能开发效率天花板

一. 蓝耘元生代 MaaS介绍及简单使用 背景介绍 创新产品定位&#xff1a; 蓝耘元生代 MaaS 平台于 2024 年 11 月 28 日推出&#xff0c;非传统智算平台&#xff0c;以资源聚合能力整合上下游资源&#xff0c;为用户提供优质全面服务。 核心模块功能&#xff1a; 集成智算算…

乾坤qiankun的使用

vue2 为主应用 react 为子应用 在项目中安装乾坤 yarn add qiankun # 或者 npm i qiankun -Svue主应用 在main.js中新增 &#xff08;需要注意的是路由模型为history模式&#xff09; registerMicroApps([{name: reactApp,entry: //localhost:3011,container: #container,/…

FreeRTOS实时操作系统学习笔记

一 RTOS入门 1.1 裸机与RTOS介绍&#xff08;了解&#xff09; 裸机编程是指在嵌入式系统中&#xff0c;直接在硬件上运行代码&#xff0c;没有操作系统的支持。这种方式下&#xff0c;开发者需要完全掌握硬件资源&#xff0c;包括时钟、中断、外设等。任务调度和资源管理都由…

MCP还是A2A?AI未来技术选型深度对比分析报告

引言 MCP&#xff08;Multi-Core Processor&#xff09;与A2A&#xff08;Asynchronous to Asynchronous&#xff09;分别代表了计算架构发展中的两种重要范式。前者延续传统冯诺依曼体系的并行优化路径&#xff0c;后者则试图突破同步时钟的物理限制。理解二者的本质差异&…