尚品汇-订单接口实现(四十)

目录:

(1)搭建service-order-client模块

(2)微服务之间用户信息传递

(3)在web-all模块中添加接口

(4)下订单

(1)搭建service-order-client模块

搭建过程同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>

   <version>1.0</version>
   <artifactId>service-order-client</artifactId>
   <packaging>jar</packaging>
   <name>service-order-client</name>
   <description>service-order-client</description>

</project>

在service-order-client暴露接口

复制代码
package com.atguigu.gmall.order.client;


@FeignClient(value = "service-order", fallback = OrderDegradeFeignClient.class)
public interface OrderFeignClient {
    @GetMapping("/api/order/auth/trade")
    Result<Map<String, Object>> trade();
}

package com.atguigu.gmall.order.client.impl;


@Component
public class OrderDegradeFeignClient implements OrderFeignClient {

    @Override
    public Result<Map<String, Object>> trade() {
        return Result.fail();
    }
}

(2)微服务之间用户信息传递

如上图:因为微服务之间并没有传递头文件 ,所以我们可以定义一个拦截器,每次微服务调用之前都先检查下头文件,将请求的头文件中的用户信息再放入到header中,再调用其他微服务即可。

在web-util中添加拦截器

复制代码
package com.atguigu.gmall.common.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Component
public class FeignInterceptor implements RequestInterceptor {

    public void apply(RequestTemplate requestTemplate){
            //  微服务远程调用使用feign ,feign 传递数据的时候,没有。
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //  添加header 数据
            requestTemplate.header("userTempId", request.getHeader("userTempId"));
            requestTemplate.header("userId", request.getHeader("userId"));

    }

}

配置网关

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| - id : web-order uri : lb://web-all predicates : - Host=order.gmall.com - id : service-order uri : lb://service-order predicates : - Path=/*/order/** |

(3)在web-all模块中添加接口

<dependency >

<groupId >com.atguigu.gmall</groupId >

<artifactId >service-order-client</artifactId >

<version >1.0</version >

</dependency >

在web-all中添加控制器

复制代码
package com.atguigu.gmall.all.controller;


@Controller
public class OrderController {

    @Autowired
    private OrderFeignClient orderFeignClient;

    /**
     * 确认订单
     * @param model
     * @return
     */
    @GetMapping("trade.html")
    public String trade(Model model) {
        Result<Map<String, Object>> result = orderFeignClient.trade();

        //addAllAttributes会把里面的map拆分成一个个键值对传过去
        model.addAllAttributes(result.getData());
        return "order/trade";
    }
}

跳转到结算页:

(4)下订单

下单功能分析:

  1. 保存单据前要做记录:验库存,验价格
  2. 保存单据: orderInfo orderDetail。
  3. 保存以后把购物车中的商品删除。{演示不删!}
  4. 重定向到支付页面。

实体类:OrderInfo

复制代码
package com.atguigu.gmall.model.order;

import com.atguigu.gmall.model.activity.ActivityRule;
import com.atguigu.gmall.model.activity.CouponInfo;
import com.atguigu.gmall.model.base.BaseEntity;
import com.atguigu.gmall.model.enums.ActivityType;
import com.atguigu.gmall.model.enums.CouponType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@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;

    @ApiModelProperty(value = "地区")
    @TableField("province_id")
    private Long provinceId;

    @ApiModelProperty(value = "促销金额")
    @TableField("activity_reduce_amount")
    private BigDecimal activityReduceAmount;

    @ApiModelProperty(value = "优惠券")
    @TableField("coupon_amount")
    private BigDecimal couponAmount;

    @ApiModelProperty(value = "原价金额")
    @TableField("original_total_amount")
    private BigDecimal originalTotalAmount;

    @ApiModelProperty(value = "可退款日期(签收后30天)")
    @TableField("refundable_time")
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
    private Date refundableTime;

    @ApiModelProperty(value = "运费")
    @TableField("feight_fee")
    private BigDecimal feightFee;

    @ApiModelProperty(value = "操作时间")
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
    @TableField("operate_time")
    private Date operateTime;

    //  计算活动或者优惠劵的金额
    @TableField(exist = false)
    private List<OrderDetailVo> orderDetailVoList;

    @TableField(exist = false)
    private String orderStatusName;

    @TableField(exist = false)
    private CouponInfo couponInfo;

    // 计算总价格
    public void sumTotalAmount(){
        BigDecimal totalAmount = new BigDecimal("0");
        BigDecimal originalTotalAmount = new BigDecimal("0");
        BigDecimal couponAmount = new BigDecimal("0");
        //  减去优惠劵
        if(null != couponInfo) {
            couponAmount = couponAmount.add(couponInfo.getReduceAmount());
            totalAmount = totalAmount.subtract(couponInfo.getReduceAmount());
        }
        //  减去活动
        if(null != this.getActivityReduceAmount()) {
            totalAmount = totalAmount.subtract(this.getActivityReduceAmount());
        }
        //  计算最后
        for (OrderDetail orderDetail : orderDetailList) {
            BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
            originalTotalAmount = originalTotalAmount.add(skuTotalAmount);
            totalAmount = totalAmount.add(skuTotalAmount);
        }
        this.setTotalAmount(totalAmount);
        this.setOriginalTotalAmount(originalTotalAmount);
        this.setCouponAmount(couponAmount);
    }

    /**
     * 获取促销优惠总金额
     * @param orderInfo
     * @return
     */
    public BigDecimal getActivityReduceAmount(OrderInfo orderInfo) {
        //促销优惠金额
        BigDecimal activityReduceAmount = new BigDecimal("0");
        List<OrderDetailVo> orderDetailVoList = orderInfo.getOrderDetailVoList();
        if(!CollectionUtils.isEmpty(orderDetailVoList)) {
            for(OrderDetailVo orderDetailVo : orderDetailVoList) {
                ActivityRule activityRule = orderDetailVo.getActivityRule();
                if(null != activityRule) {
                    activityReduceAmount = activityReduceAmount.add(activityRule.getReduceAmount());
                }
            }
        }
        return activityReduceAmount;
    }
    /**
     * 计算购物项分摊的优惠减少金额
     * 打折:按折扣分担
     * 现金:按比例分摊
     * @param orderInfo
     * @return
     */
    public Map<String, BigDecimal> computeOrderDetailPayAmount(OrderInfo orderInfo) {
        Map<String, BigDecimal> skuIdToReduceAmountMap = new HashMap<>();
        //  获取到订单明细
        List<OrderDetailVo> orderDetailVoList = orderInfo.getOrderDetailVoList();
        if (!CollectionUtils.isEmpty(orderDetailVoList)) {
            for (OrderDetailVo orderDetailVo : orderDetailVoList) {
                //  获取到活动的规则
                ActivityRule activityRule = orderDetailVo.getActivityRule();
                List<OrderDetail> orderDetailList = orderDetailVo.getOrderDetailList();
                if (null != activityRule) {
                    //  key = activity:skuId
                    //优惠金额, 按比例分摊
                    BigDecimal reduceAmount = activityRule.getReduceAmount();
                    if (orderDetailList.size() == 1) {
                        //  记录活动的减少的金额
                        skuIdToReduceAmountMap.put("activity:" + orderDetailList.get(0).getSkuId(), reduceAmount);
                    } else {
                        // 总金额
                        BigDecimal originalTotalAmount = new BigDecimal(0);
                        for (OrderDetail orderDetail : orderDetailList) {
                            BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
                            originalTotalAmount = originalTotalAmount.add(skuTotalAmount);
                        }
                        //  记录除最后一项是所有分摊金额, 最后一项 = 总的 - skuPartReduceAmount
                        //  三项  100 一项 33.33 二项 33.33 第三项 100-66.66 = 33.34
                        BigDecimal skuPartReduceAmount = new BigDecimal(0);
                        //  促销活动对应的是满减!
                        if (activityRule.getActivityType().equals(ActivityType.FULL_REDUCTION.name())) {
                            for (int i = 0, len = orderDetailList.size(); i < len; i++) {
                                OrderDetail orderDetail = orderDetailList.get(i);
                                //  最后一项前面一项应该如何做
                                if (i < len - 1) {
                                    BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
                                    //sku分摊金额  skuTotalAmount/originalTotalAmount * 优惠的金额
                                    BigDecimal skuReduceAmount = skuTotalAmount.divide(originalTotalAmount, 2, RoundingMode.HALF_UP).multiply(reduceAmount);
                                    skuIdToReduceAmountMap.put("activity:" + orderDetail.getSkuId(), skuReduceAmount);

                                    skuPartReduceAmount = skuPartReduceAmount.add(skuReduceAmount);
                                } else {
                                    //  最后一项
                                    BigDecimal skuReduceAmount = reduceAmount.subtract(skuPartReduceAmount);
                                    skuIdToReduceAmountMap.put("activity:" + orderDetail.getSkuId(), skuReduceAmount);
                                }
                            }
                        } else {
                            //  满量打折
                            for (int i = 0, len = orderDetailList.size(); i < len; i++) {
                                OrderDetail orderDetail = orderDetailList.get(i);
                                if (i < len - 1) {
                                    BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
                                    //sku分摊金额
                                    BigDecimal skuDiscountTotalAmount = skuTotalAmount.multiply(activityRule.getBenefitDiscount().divide(new BigDecimal("10")));
                                    BigDecimal skuReduceAmount = skuTotalAmount.subtract(skuDiscountTotalAmount);
                                    skuIdToReduceAmountMap.put("activity:" + orderDetail.getSkuId(), skuReduceAmount);

                                    skuPartReduceAmount = skuPartReduceAmount.add(skuReduceAmount);
                                } else {
                                    BigDecimal skuReduceAmount = reduceAmount.subtract(skuPartReduceAmount);
                                    skuIdToReduceAmountMap.put("activity:" + orderDetail.getSkuId(), skuReduceAmount);
                                }
                            }
                        }
                    }
                }
            }
        }
        //  计算优惠券
        CouponInfo couponInfo = orderInfo.getCouponInfo();
        if (null != couponInfo) {
            //sku对应的订单明细
            Map<Long, OrderDetail> skuIdToOrderDetailMap = new HashMap<>();
            for (OrderDetail orderDetail : orderInfo.getOrderDetailList()) {
                skuIdToOrderDetailMap.put(orderDetail.getSkuId(), orderDetail);
            }
            // 优惠券对应的skuId列表
            List<Long> skuIdList = couponInfo.getSkuIdList();
            // 优惠券优惠总金额
            BigDecimal reduceAmount = couponInfo.getReduceAmount();
            if (skuIdList.size() == 1) {
                // sku总的优惠金额 = 优惠券 key = "coupon:skuId"
                skuIdToReduceAmountMap.put("coupon:" + skuIdToOrderDetailMap.get(skuIdList.get(0)).getSkuId(), reduceAmount);
            } else {
                //总金额
                BigDecimal originalTotalAmount = new BigDecimal(0);
                for (Long skuId : skuIdList) {
                    OrderDetail orderDetail = skuIdToOrderDetailMap.get(skuId);
                    BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
                    originalTotalAmount = originalTotalAmount.add(skuTotalAmount);
                }
                // 记录除最后一项是所有分摊金额, 最后一项 = 总的 - skuPartReduceAmount
                BigDecimal skuPartReduceAmount = new BigDecimal(0);
                // 购物券类型 1 现金券 2 折扣券 3 满减券 4 满件打折券
                if (couponInfo.getCouponType().equals(CouponType.CASH.name()) || couponInfo.getCouponType().equals(CouponType.FULL_REDUCTION.name())) {
                    for (int i = 0, len = skuIdList.size(); i < len; i++) {
                        OrderDetail orderDetail = skuIdToOrderDetailMap.get(skuIdList.get(i));
                        if (i < len - 1) {
                            BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
                            //sku分摊金额
                            BigDecimal skuReduceAmount = skuTotalAmount.divide(originalTotalAmount, 2, RoundingMode.HALF_UP).multiply(reduceAmount);
                            skuIdToReduceAmountMap.put("coupon:" + orderDetail.getSkuId(), skuReduceAmount);

                            skuPartReduceAmount = skuPartReduceAmount.add(skuReduceAmount);
                        } else {
                            BigDecimal skuReduceAmount = reduceAmount.subtract(skuPartReduceAmount);
                            skuIdToReduceAmountMap.put("coupon:" + orderDetail.getSkuId(), skuReduceAmount);
                        }
                    }
                } else {
                    //  对应的2,4
                    for (int i = 0, len = skuIdList.size(); i < len; i++) {
                        OrderDetail orderDetail = skuIdToOrderDetailMap.get(skuIdList.get(i));
                        if (i < len - 1) {
                            BigDecimal skuTotalAmount = orderDetail.getOrderPrice().multiply(new BigDecimal(orderDetail.getSkuNum()));
                            BigDecimal skuDiscountTotalAmount = skuTotalAmount.multiply(couponInfo.getBenefitDiscount().divide(new BigDecimal("10")));
                            BigDecimal skuReduceAmount = skuTotalAmount.subtract(skuDiscountTotalAmount);
                            //sku分摊金额
                            skuIdToReduceAmountMap.put("coupon:" + orderDetail.getSkuId(), skuReduceAmount);

                            skuPartReduceAmount = skuPartReduceAmount.add(skuReduceAmount);
                        } else {
                            BigDecimal skuReduceAmount = reduceAmount.subtract(skuPartReduceAmount);
                            skuIdToReduceAmountMap.put("coupon:" + orderDetail.getSkuId(), skuReduceAmount);
                        }
                    }
                }
            }
        }
        return skuIdToReduceAmountMap;
    }
}

添加mapper

复制代码
package com.atguigu.gmall.order.mapper;


@Mapper
public interface OrderInfoMapper extends BaseMapper<OrderInfo> {

}

package com.atguigu.gmall.order.mapper;


@Mapper
public interface OrderDetailMapper extends BaseMapper<OrderDetail> {
}

添加接口OrderService :

复制代码
package com.atguigu.gmall.order.service;

public interface OrderService extends IService<OrderInfo> {

    /**
     * 保存订单
     * @param orderInfo
     * @return
     */
    Long saveOrderInfo(OrderInfo orderInfo);
}

实现类:

复制代码
package com.atguigu.gmall.order.service.impl;


@Service
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

@Override
@Transactional
public Long saveOrderInfo(OrderInfo orderInfo) {
    //调用里面的方法获取总金额
    orderInfo.sumTotalAmount();
    //订单状态
    orderInfo.setOrderStatus(OrderStatus.UNPAID.name());

    //付款方式  在线支付写死了
     orderInfo.setPaymentWay(PaymentWay.ONLINE.name());
    
    String outTradeNo = "ATGUIGU" + System.currentTimeMillis() + "" + new Random().nextInt(1000);
    //订单交易号
    orderInfo.setOutTradeNo(outTradeNo);
    //创建时间,不写也没事数据库自动添加
    orderInfo.setCreateTime(new Date());
    // 失效时间,定义为1天
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE, 1);
    orderInfo.setExpireTime(calendar.getTime());

   //进度状态
    orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
       
    //订单描述   
     // 获取订单明细
       List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
    StringBuffer tradeBody = new StringBuffer();
    for (OrderDetail orderDetail : orderDetailList) {
        tradeBody.append(orderDetail.getSkuName()+" ");
    }
    //如果订单描述长度大于100进行截取
    if (tradeBody.toString().length()>100){
        orderInfo.setTradeBody(tradeBody.toString().substring(0,100));
    }else {
        orderInfo.setTradeBody(tradeBody.toString());
    }

    //保存订单
    orderInfoMapper.insert(orderInfo);

    for (OrderDetail orderDetail : orderDetailList) {
        //设置订单id
        orderDetail.setOrderId(orderInfo.getId());
        //保存订单明细
        orderDetailMapper.insert(orderDetail);  
    }
    return orderInfo.getId();
  }
}

继续编写控制器:在OrderApiController:

复制代码
@Autowired
private OrderService orderService;
/**
     * 提交订单
     * @param orderInfo
     * @param request
     * @return
     */
    @PostMapping("auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {
        // 获取到用户Id
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));

        // 验证通过,保存订单!
        Long orderId = orderService.saveOrderInfo(orderInfo);
        return Result.ok(orderId);
    }

订单表多了一条数据:

相关推荐
小新同学^O^7 分钟前
简单学习 --> TCP协议
java·网络·tcp
月落归舟20 分钟前
深入理解Java适配器模式,彻底搞懂设计思想
java·开发语言·适配器模式
Mr_pyx20 分钟前
【LeetHOT100】二叉树的中序遍历——Java多解法详解
java·开发语言·深度优先
jay神31 分钟前
基于SpringBoot的宠物生命周期信息管理系统
java·数据库·spring boot·后端·web开发·宠物·管理系统
万亿少女的梦1681 小时前
基于SpringBoot的在线考试管理系统设计与实现
java·spring boot·后端
一勺菠萝丶1 小时前
如何在 Linux 服务器上使用 Speedtest 官方 CLI 测试带宽(小白教程)
java·服务器·前端
范什么特西1 小时前
第一个Mybatis
java·开发语言·mybatis
下次再写1 小时前
【Redis实战】深入理解Redis缓存策略:从原理到Spring Boot实践
java·spring boot·redis·缓存穿透·缓存击穿·分布式缓存·缓存策略
超梦dasgg2 小时前
智慧充电系统计费定价服务Java 实现
java·开发语言·spring·微服务
敲敲千反田2 小时前
ThreadLocal和CompletableFuture
java·网络·jvm