- 一、商品详情页与购物车对接:
- 二、订单管理功能实现:
- 2.1 新建两个模块zyg-order-interface与zyg-order-service:
- 2.2 在zyg-cart-web工程中引入zyg-order-interface:
- 2.3 在nginx中添加cart相关的模块:
- 2.4 在zyg-cart-web中的/resources/templates中添加如下文件:
- 2.5 在zyg-cart-web中的/resources/tempaltes中的getOrderInfo.html
- 2.6 在zyg-cart-web中的orderController中添加方法:
- 2.7 在zyg-order-service中添加如下方法:
- 2.8 程序运行效果如下:
一、商品详情页与购物车对接:
1.1 新建zyg-page-web工程:
在resources/templates/item.html文件中添加如下代码:
<div class="summary-wrap">
<div class="fl title">
<div class="control-group">
<div class="controls">
<input autocomplete="off" type="text" value="1" id="num" minnum="1" class="itxt" />
<a href="javascript:void(0)" class="increment plus">+</a>
<a href="javascript:void(0)" class="increment mins">-</a>
</div>
</div>
</div>
<div class="fl">
<ul class="btn-choose unstyled">
<li>
<a href="javascript:;" target="_blank"
class="sui-btn btn-danger addshopcar"
onclick="addCart()"
>加入购物车</a>
</li>
</ul>
</div>
</div>
//添加到购物车
function addCart(){
let itemId = sku.id + "";
let num = $("#num").val();
location.href = "http://cart.zeyigou.com/cart/addCart?itemId=1420726543731773441&num="+num;
}
注意:因为我们使用了nginx处理了跨域请求,所以,这里遇不到跨域问题,后面项目中再来处理!
二、订单管理功能实现:
2.1 新建两个模块zyg-order-interface与zyg-order-service:
2.2 在zyg-cart-web工程中引入zyg-order-interface:
<dependency>
<groupId>com.zelin</groupId>
<artifactId>zyg-order-interface</artifactId>
<version>2.0</version>
</dependency>
2.3 在nginx中添加cart相关的模块:
2.3.1 在/mydata/nginx/html/static/下新建order目录,复制相关的资源:
2.3.2 在/mydata/nginx/conf/conf.d/zeyigou.conf下添加配置:
server {
listen 80;
server_name order.zeyigou.com;
location / {
proxy_pass http://order;
proxy_set_header Host $host:$server_port;
}
include /etc/nginx/static.conf;
}
2.3.3 在/mydata/nginx/conf/nginx.conf下添加配置:
upstream order{
server 192.168.56.1:9008;
}
2.4 在zyg-cart-web中的/resources/templates中添加如下文件:
2.5 在zyg-cart-web中的/resources/tempaltes中的getOrderInfo.html
【 前端提交数据方式一: 采用地址栏传参方式 】
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>结算页</title>
<link rel="stylesheet" type="text/css" href="/static/order/css/webbase.css" />
<link rel="stylesheet" type="text/css" href="/static/order/css/pages-getOrderInfo.css" />
<script th:inline="javascript">
//0. 得到所有地址列表
let addressList = [[${addressList}]];
let addrs = addressList.filter(f=>f.isDefault=='1');
let url = "/order/add";
//定义方法调用的变量
let flag = false;
window.onload=function(){
setAddr(addrs[0]);
}
//1. 设置地址的勾选样式
function setStyle(address){
//1.1 取消addr-item下所有div的selected样式
$(".addr-item div").removeClass("selected");
setAddr(address)
}
function setAddr(address) {
url = "/order/add";
//1.1 在最下面的地址栏显示地址信息
let addr = "寄送至:" + address.address + " 收货人:" + address.contact + " " + address.mobile;
$("#address").html(addr);
//1.2 为url连接字符串
url += "?receiverAreaName="+address.address;
url += "&receiverMobile="+address.mobile;
url += "&receiver="+address.contact;
//1.3 如果setPaymentType()方法未调用,我们调用一次
if(!flag){
setPaymentType(1);
}
}
//设置paymentType的值
function setPaymentType(type){
if(url.indexOf("paymentType") == -1){
url += "&paymentType=" + type;
}
flag = true;
}
//提交订单
function submitOrder(){
let ser = $("#form1").serialize();
console.log("ser:",ser)
console.log("url:",url);
//1. 提交表单
location.href = url;
}
</script>
</head>
<body>
<!--head-->
<div class="top">
<div class="py-container">
<div class="shortcut">
<ul class="fl">
<li class="f-item">泽易购欢迎您!</li>
<li class="f-item">请登录 <span><a href="#">免费注册</a></span></li>
</ul>
<ul class="fr">
<li class="f-item">我的订单</li>
<li class="f-item space"></li>
<li class="f-item">我的泽易购</li>
<li class="f-item space"></li>
<li class="f-item">泽易购会员</li>
<li class="f-item space"></li>
<li class="f-item">企业采购</li>
<li class="f-item space"></li>
<li class="f-item">关注泽易购</li>
<li class="f-item space"></li>
<li class="f-item">客户服务</li>
<li class="f-item space"></li>
<li class="f-item">网站导航</li>
</ul>
</div>
</div>
</div>
<div class="cart py-container">
<!--logoArea-->
<div class="logoArea">
<div class="fl logo"><span class="title">结算页</span></div>
<div class="fr search">
<form class="sui-form form-inline">
<div class="input-append">
<input type="text" class="input-error input-xxlarge" placeholder="泽易购自营" />
<button class="sui-btn btn-xlarge btn-danger" type="button">搜索</button>
</div>
</form>
</div>
</div>
<!--主内容-->
<div class="checkout py-container">
<div class="checkout-tit">
<h4 class="tit-txt">填写并核对订单信息</h4>
</div>
<div class="checkout-steps">
<!--收件人信息-->
<div class="step-tit">
<h5>收件人信息<span><a data-toggle="modal" data-target=".edit" data-keyboard="false" class="newadd">新增收货地址</a></span></h5>
</div>
<div class="step-cont">
<div class="addressInfo">
<ul class="addr-detail">
<li class="addr-item">
<div th:each="address : ${addressList}">
<div th:class=" ${address.isDefault=='1'}?'con name selected':'con name'">
<a href="javascript:;" th:onclick="setStyle([[${address}]])">[[${address.contact}]]<span title="点击取消选择"> </a></div>
<div class="con address">[[${address.contact}]] [[${address.address}]] <span>[[${address.mobile}]]</span>
<span class="base" th:if="${address.isDefault=='1'}">默认地址</span>
<span class="edittext"><a data-toggle="modal" data-target=".edit" data-keyboard="false" >编辑</a> <a href="/static/order/javascript:;">删除</a></span>
</div>
<div class="clearfix"></div>
</div>
</li>
</ul>
<!--添加地址-->
<div tabindex="-1" role="dialog" data-hasfoot="false" class="sui-modal hide fade edit">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" data-dismiss="modal" aria-hidden="true" class="sui-close">×</button>
<h4 id="myModalLabel" class="modal-title">添加收货地址</h4>
</div>
<div class="modal-body">
<form action="" class="sui-form form-horizontal">
<div class="control-group">
<label class="control-label">收货人:</label>
<div class="controls">
<input type="text" class="input-medium">
</div>
</div>
<div class="control-group">
<label class="control-label">详细地址:</label>
<div class="controls">
<input type="text" class="input-large">
</div>
</div>
<div class="control-group">
<label class="control-label">联系电话:</label>
<div class="controls">
<input type="text" class="input-medium">
</div>
</div>
<div class="control-group">
<label class="control-label">邮箱:</label>
<div class="controls">
<input type="text" class="input-medium">
</div>
</div>
<div class="control-group">
<label class="control-label">地址别名:</label>
<div class="controls">
<input type="text" class="input-medium">
</div>
<div class="othername">
建议填写常用地址:<a href="#" class="sui-btn btn-default">家里</a> <a href="#" class="sui-btn btn-default">父母家</a> <a href="#" class="sui-btn btn-default">公司</a>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" data-ok="modal" class="sui-btn btn-primary btn-large">确定</button>
<button type="button" data-dismiss="modal" class="sui-btn btn-default btn-large">取消</button>
</div>
</div>
</div>
</div>
<!--确认地址-->
</div>
<div class="hr"></div>
</div>
<div class="hr"></div>
<!--支付和送货-->
<div class="payshipInfo">
<div class="step-tit">
<h5>支付方式</h5>
</div>
<div class="step-cont">
<ul class="payType">
<li class="selected" onclick="setPaymentType(1)">微信付款<span title="点击取消选择"></span></li>
<li onclick="setPaymentType(2)">货到付款<span title="点击取消选择"></span></li>
</ul>
</div>
<div class="hr"></div>
<div class="step-tit">
<h5>送货清单</h5>
</div>
<div class="step-cont">
<ul class="send-detail">
<li th:each="cart : ${cartList}">
<div class="sendGoods">
<span th:text="${cart.sellerName}" style="padding:5px 10px;background-color: red;color:white"></span>
<ul class="yui3-g" th:each="item : ${cart.orderItemList}">
<li class="yui3-u-1-6">
<span><img th:src="${item.picPath}"/></span>
</li>
<li class="yui3-u-7-12">
<div class="desc" th:text="${item.title}"></div>
<div class="seven">7天无理由退货</div>
</li>
<li class="yui3-u-1-12">
<div class="price" th:text="${item.price}">¥5399.00</div>
</li>
<li class="yui3-u-1-12">
<div class="num">X[[${item.num}]]</div>
</li>
<li class="yui3-u-1-12">
<div class="exit">有货</div>
</li>
</ul>
</div>
</li>
<li>aa</li>
<li>bb</li>
</ul>
</div>
<div class="hr"></div>
</div>
<div class="linkInfo">
<div class="step-tit">
<h5>发票信息</h5>
</div>
<div class="step-cont">
<span>普通发票(电子)</span>
<span>个人</span>
<span>明细</span>
</div>
</div>
<div class="cardInfo">
<div class="step-tit">
<h5>使用优惠/抵用</h5>
</div>
</div>
</div>
</div>
<div class="order-summary">
<div class="static fr">
<div class="list">
<span><i class="number">1</i>件商品,总商品金额</span>
<em class="allprice">¥5399.00</em>
</div>
<div class="list">
<span>返现:</span>
<em class="money">0.00</em>
</div>
<div class="list">
<span>运费:</span>
<em class="transport">0.00</em>
</div>
</div>
</div>
<div class="clearfix trade">
<div class="fc-price">应付金额: <span class="price">¥5399.00</span></div>
<div class="fc-receiverInfo" id="address">寄送至:</div>
</div>
<div class="submit">
<a class="sui-btn btn-danger btn-xlarge" href="javascript:void(0)" onclick="submitOrder()">提交订单</a>
</div>
</div>
<!-- 底部栏位 -->
...
【 前端提交数据方式二: 采用表单隐藏域方式 】
<script th:inline="javascript">
//0. 得到所有地址列表
let addressList = [[${addressList}]];
let addrs = addressList.filter(f=>f.isDefault=='1');
let url = "/order/add";
//定义方法调用的变量
let flag = false;
window.onload=function(){
setAddr2(addrs[0])
}
//1. 设置地址的勾选样式
function setStyle(address){
//1.1 取消addr-item下所有div的selected样式
$(".addr-item div").removeClass("selected");
setAddr2(address)
}
//设置提交数据方式二:直接为表单隐藏域赋值
function setAddr2(address){
//2.1 在最下面的地址栏显示地址信息
let addr = "寄送至:" + address.address + " 收货人:" + address.contact + " " + address.mobile;
$("#address").html(addr);
//2.2 为表单隐藏域赋值
$("#receiverAreaName").val(address.address);
$("#receiverMobile").val(address.mobile);
$("#receiver").val(address.contact);
}
//设置paymentType的值
function setPaymentType(type){
$("#paymentType").val(type);
}
//提交订单
function submitOrder(){
let ser = $("#form1").serialize();
console.log("ser:",ser)
console.log("url:",url);
//1. 提交表单
location.href = url;
}
</script>
<form action="/order/add" th:action="@{/order/add}" method="post" id="form1">
<input type="hidden" name="receiverAreaName" id="receiverAreaName">
<input type="hidden" name="receiverMobile" id="receiverMobile">
<input type="hidden" name="receiver" id="receiver">
<input type="hidden" name="paymentType" id="paymentType" value="1">
</form>
<div class="step-cont">
<ul class="payType">
<li class="selected" onclick="setPaymentType2(1)">微信付款<span title="点击取消选择"></span></li>
<li onclick="setPaymentType2(2)">货到付款<span title="点击取消选择"></span></li>
</ul>
</div>
注意:这里表单 的action一定要用th:action的形式,否则,报错,原因是: CsrfFilter与Rest服务Post方式的矛盾: 只有GET|HEAD|TRACE|OPTIONS这4类方法会被放行,其它Method的http请求,都要验证_csrf的token是否正确,而通常post方式调用rest服务时,又没有_csrf的token,所以校验失败。 具体解决方案,参考:https://blog.csdn.net/wangmate/article/details/106198947
2.6 在zyg-cart-web中的orderController中添加方法:
/**
* 功能: 提交订单
* 参数:
* 返回值: java.lang.String
* 时间: 2021/8/14 16:44
*/
@Transactional
@RequestMapping("/add")
public String add(OrderEntity order){
System.out.println("order = " + order);
//1.1 得到订单址列表
//① 获取登录名
String name = SecurityContextHolder.getContext().getAuthentication().getName();
//② 为订单对象设置属性
order.setSourceType("2");
order.setUserId(name);
orderService.add(order);
return "pay";
}
2.7 在zyg-order-service中添加如下方法:
/**
* 功能: 提交订单
* 参数:
* 返回值: void
* 时间: 2021/8/14 16:44
*/
@Override
public void add(OrderEntity order) {
//1. 得到购物车列表的字符串
String cartStr = redisTemplate.opsForValue().get(order.getUserId());
//2. 转换为List<Cart>对象并返回
List<Cart> cartList = null;
if(StringUtils.isNotBlank(cartStr)){
cartList = JSON.parseArray(cartStr,Cart.class);
}
//3. 添加订单(一个购物车对应一个订单)
for (Cart cart : cartList) {
//3.1 定义订单对象
OrderEntity orderEntity = new OrderEntity();
//3.2 生成订单id主键
long id = idWorker.nextId();
orderEntity.setOrderId(id);
//3.3 设置订单的其它相关属性
orderEntity.setCreateTime(new Date());
orderEntity.setPaymentType(order.getPaymentType());
orderEntity.setReceiver(order.getReceiver());
orderEntity.setReceiverAreaName(order.getReceiverAreaName());
orderEntity.setReceiverMobile(order.getReceiverMobile());
orderEntity.setSellerId(cart.getSellerId());
orderEntity.setUserId(order.getUserId());
orderEntity.setSourceType(order.getSourceType());
orderEntity.setStatus("1"); //未支付
double sum = 0; //定义订单的总金额
//3.4 得到购物车的购物项数据,向订单项表中添加此数据
for (OrderItemEntity item : cart.getOrderItemList()) {
//3.4.1 计算小计
BigDecimal totalFee = new BigDecimal(item.getNum() * item.getPrice().doubleValue());
item.setTotalFee(totalFee);
//3.4.2 累加总金额
sum += totalFee.doubleValue();
//3.4.3 设置订单的id
item.setOrderId(id);
//3.4.4 设置订单项的id
item.setId(idWorker.nextId());
//3.4.5 添加订单项到tb_ordeItem表
orderItemDao.insert(item);
}
//3.5 计算此订单的总金额
orderEntity.setPayment(new BigDecimal(sum));
//3.6 添加订单
this.save(orderEntity);
}
//4. 清空redis中的购物车
//todo...
}