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

目录:

(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 {

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Override
    public 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 {

    @Autowired
    private 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 {


    @Override
    public 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.price
    BigDecimal 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 {

    @Override
    public 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”

接口封装:

获取用户id:

package com.atguigu.gmall.order.controller;
@RestController
@RequestMapping("api/order")
public class OrderApiController {

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private CartFeignClient cartFeignClient;


    /**
     * 确认订单
     * @param request
     * @return
     */
    @GetMapping("auth/trade")
    public Result<Map<String, Object>> trade(HttpServletRequest request) {
        // 获取到用户Id
        String 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模块前端展示数据

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵俺第一专栏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值