✅P276_商城业务-订单服务-订单确认页完成

gong_yz大约 2 分钟谷粒商城

下单执行流程

订单服务的执行流程如下图所示


创建防重令牌

编写防重令牌前缀常量

cfmall-order/src/main/java/com/gyz/cfmall/order/constant/OrderConstant.java

public class OrderConstant {
    public static final String USER_ORDER_TOKEN_PREFIX = "order:token:";
}

存储防重令牌:4.1 redis存储、4.2 返回页面

com.gyz.cfmall.order.service.impl.OrderServiceImpl#confirmOrder

@Override
public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {
    //构建OrderConfirmVo
    OrderConfirmVo confirmVo = new OrderConfirmVo();
    //获取当前用户登录的信息
    MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();

    //获取当前线程请求头信息(解决Feign异步调用丢失请求头问题)
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    //开启第一个异步任务
    CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
        //每一个线程都来共享之前的请求数据
        RequestContextHolder.setRequestAttributes(requestAttributes);
        //1、远程查询所有的收获地址列表
        List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
        confirmVo.setMemberAddressVos(address);
    }, threadPoolExecutor);

    //开启第二个异步任务
    CompletableFuture<Void> cartInfoFuture = CompletableFuture.runAsync(() -> {
        //每一个线程都来共享之前的请求数据
        RequestContextHolder.setRequestAttributes(requestAttributes);
        //2、远程查询购物车所有选中的购物项
        List<OrderItemVo> currentCartItems = cartFeignService.getCurrentCartItems();
        confirmVo.setItems(currentCartItems);
        //feign在远程调用之前要构造请求,调用很多的拦截器
    }, threadPoolExecutor).thenRunAsync(() -> {
        List<OrderItemVo> items = confirmVo.getItems();
        List<Long> skuIds = items.stream().map(item -> {
            return item.getSkuId();
        }).collect(Collectors.toList());

        R r = wmsFeignService.getSkuHasStock(skuIds);
        List<SkuStockVo> data = r.getData(new TypeReference<List<SkuStockVo>>() {
        });
        Map<Long, Boolean> collect = data.stream().collect(Collectors.toMap(SkuStockVo::getSkuId, SkuStockVo::getHasStock));
        confirmVo.setStocks(collect);
    }, threadPoolExecutor);
    //3、查询用户积分
    Integer integration = memberResponseVo.getIntegration();
    confirmVo.setIntegration(integration);

    CompletableFuture.allOf(addressFuture, cartInfoFuture).get();

    //4、生成防重令牌
    String token = UUID.randomUUID().toString().replace("-", "");
    //4.1 redis存储
    redisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId().toString(), token, 30, TimeUnit.MINUTES);
    //4.2 返回页面
    confirmVo.setOrderToken(token);
    return confirmVo;
}

订单提交数据

京东的结算页中的商品信息是实时获取的,结算的时候会去购物车中再去获取一遍,因此,提交页面的数据Vo没必要提交商品信息

封装订单提交VO

cfmall-order/src/main/java/com/gyz/cfmall/order/vo/OrderSubmitVo.java

package com.gyz.cfmall.order.vo;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class OrderSubmitVo {
    /**
     * 收获地址的id
     */
    private Long addrId;

    /**
     * 支付方式
     */
    private Integer payType;

    /**
     * 防重令牌
     **/
    private String orderToken;

    /**
     * 应付价格
     */
    private BigDecimal payPrice;

    /**
     * 订单备注
     */
    private String remarks;

}

前端页面

cfmall-order/src/main/resources/templates/confirm.html

提交表单编写

<form action="http://order.cfmall.com/submitOrder" method="post">
	<input id="addrInput" type="hidden" name="addrId" />
	<input id="payPriceInput" type="hidden" name="payPrice">
	<input name="orderToken" th:value="${confirmOrderData.orderToken}" type="hidden"/>
	<button class="tijiao" type="submit">提交订单</button>
</form>

输入框绑定数据

function getFare(addrId) {
	$("#addrInput").val(addrId);
	$.get("http://cfmall.com/api/ware/wareinfo/fare?addrId=" + addrId, function (resp) {
		console.log(resp);
		$("#fareEle").text(resp.data.fare);
		var total = [[${confirmOrderData.getTotal()}]];
		//设置运费
		var payPrice = total * 1 + resp.data.fare * 1;
		$("#payPriceEle").text(payPrice);
		$("#payPriceInput").val(payPrice);
		//设置收获地址人信息
		$("#recieveAddr").text(resp.data.address.province + " " + resp.data.address.city + " " + " " + resp.data.address.region + resp.data.address.detailAddress);
		$("#reciever").text(resp.data.address.name);
	})
};

订单提交接口

cfmall-order/src/main/java/com/gyz/cfmall/order/web/OrderWebController.java

@PostMapping("/submitOrder")
public String submitOrder(OrderSubmitVo orderSubmitVo) {

    return null;
}