尚品汇-结算页数据接口封装实现(三十九)

2024-08-25 12:04

本文主要是介绍尚品汇-结算页数据接口封装实现(三十九),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录:

(1)业务介绍

(2)结算页

(3) 在 service-user模块获取地址列表

(4)在service-user-client暴露远程接口

(5)在service-cart模块获取选中商品数据

(6)创建service-cart-client模块

(7)搭建service-order模块

(1)业务介绍

订单业务在整个电商平台中处于核心位置,也是比较复杂的一块业务。是把“物”变为“钱”的一个中转站。

      整个订单模块一共分四部分组成:

  1. 结算
  2. 下单
  3. 对接支付服务
  4. 对接库存管理系统

(2)结算页

 入口:购物车点击计算按钮 ,结算必须要登录!

分析页面需要的数据:

  1. 需要用户地址信息
  2. 购物车中选择的商品列表
  3. 用户地址信息在service-user模块,购物车信息在service-cart模块,所以我们要在相应模块提供api接口,通过feign client调用获取数据

点击结算到结算页的流程:

 

(3) 在 service-user模块获取地址列表

 

添加mapper

package com.atguigu.gmall.user.mapper;@Mapper
public interface UserAddressMapper extends BaseMapper<UserAddress> {
}

编写接口

package com.atguigu.gmall.user.service;public interface UserAddressService {/*** 根据用户Id 查询用户的收货地址列表!* @param userId* @return*/List<UserAddress> findUserAddressListByUserId(String userId);
}

实现类

package com.atguigu.gmall.user.service.impl;@Service
public class UserAddressServiceImpl implements UserAddressService {@Autowiredprivate UserAddressMapper userAddressMapper;@Overridepublic List<UserAddress> findUserAddressListByUserId(String userId) {// 操作哪个数据库表,则就使用哪个表对应的mapper!// new Example() ; 你操作的哪个表,则对应的传入表的实体类!// select * from userAddress where userId = ?;QueryWrapper<UserAddress> queryWrapper = new QueryWrapper<>();queryWrapper.eq("user_id", userId);List<UserAddress> userAddressList = userAddressMapper.selectList(queryWrapper);return userAddressList;}
}

用户地址实体类:UserAddress      

package com.atguigu.gmall.model.user;import com.atguigu.gmall.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "用户地址")
@TableName("user_address")
public class UserAddress extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "用户地址")@TableField("user_address")private String userAddress;@ApiModelProperty(value = "用户id")@TableField("user_id")private Long userId;@ApiModelProperty(value = "收件人")@TableField("consignee")private String consignee;@ApiModelProperty(value = "联系方式")@TableField("phone_num")private String phoneNum;@ApiModelProperty(value = "是否是默认")@TableField("is_default")private String isDefault;}

 

创建控制器

package com.atguigu.gmall.user.controller;@RestController
@RequestMapping("/api/user")
public class UserApiController {@Autowiredprivate UserAddressService userAddressService;/*** 获取用户地址* @param userId* @return*/@GetMapping("inner/findUserAddressListByUserId/{userId}")public List<UserAddress> findUserAddressListByUserId(@PathVariable("userId") String userId){return userAddressService.findUserAddressListByUserId(userId);}}

 

(4)在service-user-client暴露远程接口

 

接口类

package com.atguigu.gmall.user.client;@FeignClient(value = "service-user", fallback = UserDegradeFeignClient.class)
public interface UserFeignClient {@GetMapping("/api/user/inner/findUserAddressListByUserId/{userId}")List<UserAddress> findUserAddressListByUserId(@PathVariable(value = "userId") String userId);
}
package com.atguigu.gmall.user.client.impl;@Component
public class UserDegradeFeignClient implements UserFeignClient {@Overridepublic List<UserAddress> findUserAddressListByUserId(String userId) {return null;}
}

(5)在service-cart模块获取选中商品数据

添加接口:CartService 接口

/*** 根据用户Id 查询购物车列表** @param userId* @return*/
List<CartInfo> getCartCheckedList(String userId);

实现类

@Override
public List<CartInfo> getCartCheckedList(String userId) {//  获取的选中的购物车列表!String cartKey = this.getCartKey(userId);//  获取到购物车集合数据:List<CartInfo>  cartInfoList = this.redisTemplate.opsForHash().values(cartKey);List<CartInfo> cartInfos = cartInfoList.stream().filter(cartInfo -> {//  再次确认一下最新价格cartInfo.setSkuPrice(productFeignClient.getSkuPrice(cartInfo.getSkuId()));//判断是否选中,返回选中的 true返回 filter过滤出来选中的  return cartInfo.getIsChecked().intValue() == 1;}).collect(Collectors.toList());//  返回数据return cartInfos;
}

 

购物车实体类:CartInfo

package com.atguigu.gmall.model.cart;import com.atguigu.gmall.model.activity.CouponInfo;
import com.atguigu.gmall.model.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;@Data
@ApiModel(description = "购物车")
@TableName("cart_info")
public class CartInfo extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "用户id")private String userId;@ApiModelProperty(value = "skuid")private Long skuId;@ApiModelProperty(value = "放入购物车时价格")private BigDecimal cartPrice;@ApiModelProperty(value = "数量")private Integer skuNum;@ApiModelProperty(value = "图片文件")private String imgUrl;@ApiModelProperty(value = "sku名称 (冗余)")private String skuName;@ApiModelProperty(value = "isChecked")private Integer isChecked = 1;// 实时价格 skuInfo.priceBigDecimal skuPrice;//  优惠券信息列表@ApiModelProperty(value = "购物项对应的优惠券信息")@TableField(exist = false)private List<CouponInfo> couponInfoList;}

 

继续在ApiCartController中编写控制器

/*** 根据用户Id 查询购物车列表** @param userId* @return*/
@GetMapping("getCartCheckedList/{userId}")
public List<CartInfo> getCartCheckedList(@PathVariable(value = "userId") String userId) {return cartService.getCartCheckedList(userId);
}

 

 

(6)创建service-cart-client模块

 

修改配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.atguigu.gmall</groupId><artifactId>service-client</artifactId><version>1.0</version></parent><artifactId>service-cart-client</artifactId><version>1.0</version><packaging>jar</packaging><name>service-cart-client</name><description>service-cart-client</description></project>
package com.atguigu.gmall.cart.client;@FeignClient(value = "service-cart",fallback = CartDegradeFeignClient.class)
public interface CartFeignClient {//  获取选中购物车列表!@GetMapping("/api/cart/getCartCheckedList/{userId}")public List<CartInfo> getCartCheckedList(@PathVariable String userId);
}

package com.atguigu.gmall.cart.client.impl;
@Component
public class CartDegradeFeignClient implements CartFeignClient {@Overridepublic List<CartInfo> getCartCheckedList(String userId) {return null;}
}

(7)搭建service-order模块

 

搭建方式如service-cart

修改pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.atguigu.gmall</groupId><artifactId>service</artifactId><version>1.0</version></parent><version>1.0</version><artifactId>service-order</artifactId><packaging>jar</packaging><name>service-order</name><description>service-order</description><dependencies><dependency><groupId>com.atguigu.gmall</groupId><artifactId>service-product-client</artifactId><version>1.0</version></dependency><dependency><groupId>com.atguigu.gmall</groupId><artifactId>service-cart-client</artifactId><version>1.0</version></dependency><dependency><groupId>com.atguigu.gmall</groupId><artifactId>service-user-client</artifactId><version>1.0</version></dependency></dependencies><build><finalName>service-order</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

添加配置

bootstrap.properties:

spring.application.name=service-order
spring.profiles.active=dev
spring.cloud.nacos.discovery.server-addr=192.168.200.129:8848
spring.cloud.nacos.config.server-addr=192.168.200.129:8848
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=yaml
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml

Nacos配置:

 

启动类

package com.atguigu.gmall.order;
@SpringBootApplication
@ComponentScan(basePackages = "com.atguigu.gmall")
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.atguigu.gmall")
public class ServiceOrderApplication {public static void main(String[] args) {SpringApplication.run(ServiceOrderApplication.class,args);}
}

 

订单表: 

id

主键。自动生成

consignee

收货人名称。页面获取

consignee_tel

收货人电话。页面获取

deliveryAddress

收货地址。页面获取

total_amount

总金额。计算

order_status

订单状态,用于显示给用户查看。设定初始值。

userId

用户Id。从拦截器已放到请求属性中。

payment_way

支付方式(网上支付、货到付款)。页面获取

orderComment

订单状态。页面获取

out_trade_no

第三方支付编号。按规则生成

create_time

创建时间。设当前时间             

expire_time

失效时间,默认当前时间+1天

process_status

订单进度状态,程序控制、 后台管理查看。设定初始值,

tracking_no

物流编号,初始为空,发货后补充

parent_order_id

拆单时产生,默认为空

 

 

 

 

订单详情表:

id

主键,自动生成

order_id

订单编号,主表保存后给从表

sku_id

商品id 页面传递

sku_name

商品名称,后台添加

img_url

图片路径,后台添加

order_price

购买价格(下单时的sku价格) 商品单价,从页面中获取,并验价。

sku_num

商品个数,从页面中获取

 

添加实体

 

package com.atguigu.gmall.model.order;@Data
@ApiModel(description = "订单信息")
@TableName("order_info")
public class OrderInfo extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "收货人")@TableField("consignee")private String consignee;@ApiModelProperty(value = "收件人电话")@TableField("consignee_tel")private String consigneeTel;@ApiModelProperty(value = "总金额")@TableField("total_amount")private BigDecimal totalAmount;@ApiModelProperty(value = "订单状态")@TableField("order_status")private String orderStatus;@ApiModelProperty(value = "用户id")@TableField("user_id")private Long userId;@ApiModelProperty(value = "付款方式")@TableField("payment_way")private String paymentWay;@ApiModelProperty(value = "送货地址")@TableField("delivery_address")private String deliveryAddress;@ApiModelProperty(value = "订单备注")@TableField("order_comment")private String orderComment;@ApiModelProperty(value = "订单交易编号(第三方支付用)")@TableField("out_trade_no")private String outTradeNo;@ApiModelProperty(value = "订单描述(第三方支付用)")@TableField("trade_body")private String tradeBody;@ApiModelProperty(value = "创建时间")@TableField("create_time")
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")private Date createTime;@ApiModelProperty(value = "失效时间")@TableField("expire_time")
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")private Date expireTime;@ApiModelProperty(value = "进度状态")@TableField("process_status")private String processStatus;@ApiModelProperty(value = "物流单编号")@TableField("tracking_no")private String trackingNo;@ApiModelProperty(value = "父订单编号")@TableField("parent_order_id")private Long parentOrderId;@ApiModelProperty(value = "图片路径")@TableField("img_url")private String imgUrl;@TableField(exist = false)private List<OrderDetail> orderDetailList;@TableField(exist = false)private String wareId;// 计算总价格public void sumTotalAmount(){BigDecimal totalAmount=new BigDecimal("0");for (OrderDetail orderDetail : orderDetailList) {totalAmount= totalAmount.add(orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum())));}this.totalAmount=  totalAmount;}}
package com.atguigu.gmall.model.order;@Data
@ApiModel(description = "订单明细")
@TableName("order_detail")
public class OrderDetail extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "订单编号")@TableField("order_id")private Long orderId;@ApiModelProperty(value = "sku_id")@TableField("sku_id")private Long skuId;@ApiModelProperty(value = "sku名称(冗余)")@TableField("sku_name")private String skuName;@ApiModelProperty(value = "图片名称(冗余)")@TableField("img_url")private String imgUrl;@ApiModelProperty(value = "购买价格(下单时sku价格)")@TableField("order_price")private BigDecimal orderPrice;@ApiModelProperty(value = "购买个数")@TableField("sku_num")private Integer skuNum;// 是否有足够的库存!@TableField(exist = false)private String hasStock;}

其中hasStock是一个非持久化属性,用户传递【是否还有库存】的标志。

如果商品在库存中有足够数据,suceess = “1”,fail=“0”

接口封装:

package com.atguigu.gmall.order.controller;
@RestController
@RequestMapping("api/order")
public class OrderApiController {@Autowiredprivate UserFeignClient userFeignClient;@Autowiredprivate CartFeignClient cartFeignClient;/*** 确认订单* @param request* @return*/@GetMapping("auth/trade")public Result<Map<String, Object>> trade(HttpServletRequest request) {// 获取到用户IdString userId = AuthContextHolder.getUserId(request);//获取用户地址List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(userId);// 渲染送货清单// 先得到用户想要购买的商品!List<CartInfo> cartInfoList = cartFeignClient.getCartCheckedList(userId);// 声明一个集合来存储订单明细ArrayList<OrderDetail> detailArrayList = new ArrayList<>();for (CartInfo cartInfo : cartInfoList) {OrderDetail orderDetail = new OrderDetail();orderDetail.setSkuId(cartInfo.getSkuId());orderDetail.setSkuName(cartInfo.getSkuName());orderDetail.setImgUrl(cartInfo.getImgUrl());orderDetail.setSkuNum(cartInfo.getSkuNum());orderDetail.setOrderPrice(cartInfo.getSkuPrice());// 添加到集合detailArrayList.add(orderDetail);}// 计算总金额OrderInfo orderInfo = new OrderInfo();orderInfo.setOrderDetailList(detailArrayList);//调用对象里面的封装好的方法获总金额orderInfo.sumTotalAmount();Map<String, Object> result = new HashMap<>();result.put("userAddressList", userAddressList);result.put("detailArrayList", detailArrayList);// 保存总金额result.put("totalNum", detailArrayList.size());result.put("totalAmount", orderInfo.getTotalAmount());return Result.ok(result);}
}

 

 

 

说明:接口已经封装,接下来暴露接口,提供给web-all模块前端展示数据

 

 

 

这篇关于尚品汇-结算页数据接口封装实现(三十九)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1105507

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time