天猫整站(简易版)SSM(十四)需要登录才能使用的功能
一、购物车页面操作
购物车页面和服务端的交互主要是三个
1. 增加、减少某种产品的数量
2. 删除某种产品
3. 选中产品后,提交到结算页面
1.1 调整订单数量
点击增加或者减少按钮后,根据cartPage.jsp 中的js代码,会通过Ajax访问/forechangeOrderItem路径
导致ForeController.changeOrderItem()方法被调用
1. 判断用户是否登录
2. 获取pid和number
3. 遍历出用户当前所有的未生成订单的OrderItem
4. 根据pid找到匹配的OrderItem,并修改数量后更新到数据库
5. 返回字符串"success"
@RequestMapping("forechangeOrderItem")
@ResponseBody
public String changeOrderItem(@RequestParam("pid") int pid,@RequestParam("number") int number,Model model,HttpSession session){
User user = (User) session.getAttribute("user");
if (user == null){
return "fail";
}else {
List<OrderItem> orderItems = orderItemService.listByUser(user.getId());
for (OrderItem orderItem : orderItems){
if (orderItem.getPid() == pid){
orderItem.setNumber(number);
orderItemService.update(orderItem);
break;
}
}
return "success";
}
}
1.2 删除订单项
点击删除按钮后,根据 cartPage.jsp中的js代码,会通过Ajax访问/foredeleteOrderItem路径
导致ForeController.deleteOrderItem方法被调用
1. 判断用户是否登录
2. 获取oiid
3. 删除oiid对应的OrderItem数据
4. 返回字符串"success"
@RequestMapping("foredeleteOrderItem")
@ResponseBody
public String deleteOrderItem(@RequestParam("oiid") int oiid,Model model,HttpSession session){
User user = (User)session.getAttribute("user");
if (user != null){
orderItemService.delete(oiid);
return "success";
}else {
return "fail";
}
}
1.3 提交到结算页面
在选中了购物车中的任意商品之后,结算按钮呈现可点击状态。
点击之后,提交到结算页面,并带上(多个)被选中的OrderItem对象的id
http://localhost:8080/tmall_ssm/forebuy?oiid=8&oiid=9
二、订单状态图
1. 首先是创建订单,刚创建好之后,订单处于waitPay 待付款状态
2. 接着是付款,付款后,订单处于waitDelivery 待发货状态
3. 前两步都是前台用户操作导致的,接下来需要到后台做发货操作,发货后,订单处于waitConfirm 待确认收货状态
4. 接着又是前台用户进行确认收货操作,操作之后,订单处于waitReview 待评价状态
5. 最后进行评价,评价之后,订单处于finish 完成状态
以上状态都是一个接一个的,不能跳状态进行。
比较特殊的是,无论当前订单处于哪个状态,都可以进行删除操作。 像订单这样极其重要的业务数据,实际上是不允许真正从数据库中删除掉的,而是把状态标记为删除,以表示其被删掉了,所以在删除之后,订单处于 delete 已删除状态
三、生成订单
3.1 结算页操作
通过立即购买或者购物车中点击结算进入结算页面,然后提交订单
3.2 事务管理
在applicationContext.xml中配置事务管理
因为增加订单行为需要同时修改两个表
1. 为Order表新增数据
2. 修改OrderItem表
所以需要进行事务管理,否则当新增了Order表的数据,还没有来得及修改OrderItem的时候出问题,比如突然断电,那么OrderItem的数据就会是脏数据了(没有指向正确的Order表数据)。
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
3.3 ForeController.createOrder
提交订单访问路径 /forecreateOrder, 导致ForeController.createOrder 方法被调用
1. 从session中获取user对象
2. 通过参数Order接受地址,邮编,收货人,用户留言等信息
3. 根据当前时间加上一个4位随机数生成订单号
4. 根据上述参数,创建订单对象
5. 把订单状态设置为等待支付
6. 从session中获取订单项集合 ( 在结算功能中的ForeController.buy()方法中,订单项集合被放到了session中 )
7. 把订单加入到数据库,并且遍历订单项集合,设置每个订单项的order,更新到数据库
8. 统计本次订单的总金额
9. 客户端跳转到确认支付页forealipay,并带上订单id和总金额
@RequestMapping("forecreateOrder")
public String createOrder(Order order,HttpSession session){
User user = (User) session.getAttribute("user");
//根据时间加上一个随机的四位数生成订单编号
String orderCode = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())+ RandomUtils.nextInt(10000);
order.setOrderCode(orderCode);
order.setCreateDate(new Date());
order.setUid(user.getId());
order.setStatus(OrderService.WAIT_PAY);
List<OrderItem> orderItems = (List<OrderItem>) session.getAttribute("ois");
float total = orderService.getTotal(order,orderItems);
return "redirect:forealipay?oid="+order.getId() +"&total="+total;
}
3.4 确认支付
1. 在上一步客户端跳转到路径/forealipay方法,导致PageController.alipay()方法被调用。 alipay()没做什么事情,就是服务端跳转到了alipay.jsp页面。
2. alipay.jsp :
中间是确认支付业务页面 alipayPage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@include file="../include/fore/header.jsp"%>
<%@include file="../include/fore/top.jsp"%>
<%@include file="../include/fore/cart/alipayPage.jsp"%>
<%@include file="../include/fore/footer.jsp"%>
3. alipayPage.jsp:
显示总金额,并且让确认支付按钮跳转到页面 /forepayed页面,并带上oid和金额
<%--
Created by IntelliJ IDEA.
User:
Date: 2018/10/2
Time: 10:21
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<div class="aliPayPageDiv">
<div class="aliPayPageLogo">
<img class="pull-left" src="${pageContext.request.contextPath}/img/site/simpleLogo.png">
<div style="clear:both"></div>
</div>
<div>
<span class="confirmMoneyText">扫一扫付款(元)</span>
<span class="confirmMoney">
¥<fmt:formatNumber type="number" value="${param.total}" minFractionDigits="2"/></span>
</div>
<div>
<img class="aliPayImg" src="${pageContext.request.contextPath}/img/site/alipay2wei.png">
</div>
<div>
<a href="forepayed?oid=${param.oid}&total=${param.total}"><button class="confirmPay">确认支付</button></a>
</div>
</div>
3.5 支付成功
1. 在上一步确认访问按钮提交数据到/forepayed,导致ForeController.payed方法被调用
1.1 获取参数oid
1.2 根据oid获取到订单对象order
1.3 修改订单对象的状态和支付时间
1.4 更新这个订单对象到数据库
1.5 把这个订单对象放在model的属性"o"上
1.6 服务端跳转到payed.jsp
@RequestMapping("forepayed")
public String payed(@RequestParam("oid") int oid,@RequestParam("total") float total,Model model){
Order order = orderService.get(oid);
order.setStatus(OrderService.WAIT_DELIVERY);
order.setPayDate(new Date());
orderService.update(order);
model.addAttribute("o",order);
return "fore/payed";
}
2. payed.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@include file="../include/fore/header.jsp"%>
<%@include file="../include/fore/top.jsp"%>
<%@include file="../include/fore/simpleSearch.jsp"%>
<%@include file="../include/fore/cart/payedPage.jsp"%>
<%@include file="../include/fore/footer.jsp"%>
中间是支付成功业务页面 payedPage.jsp
3. payedPage.jsp
显示订单中的地址,邮编,收货人,手机号码等等
<%--
Created by IntelliJ IDEA.
User:
Date: 2018/10/2
Time: 10:29
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<div class="payedDiv">
<div class="payedTextDiv">
<img src="${pageContext.request.contextPath}/img/site/paySuccess.png">
<span>您已成功付款</span>
</div>
<div class="payedAddressInfo">
<ul>
<li>收货地址:${o.address} ${o.receiver} ${o.mobile }</li>
<li>实付款:<span class="payedInfoPrice">
¥<fmt:formatNumber type="number" value="${param.total}" minFractionDigits="2"/>
</li>
<li>预计10月18日送达 </li>
</ul>
<div class="paedCheckLinkDiv">
您可以
<a class="payedCheckLink" href="forebought">查看已买到的宝贝</a>
<a class="payedCheckLink" href="forebought">查看交易详情 </a>
</div>
</div>
<div class="payedSeperateLine">
</div>
<div class="warningDiv">
<img src="${pageContext.request.contextPath}/img/site/warning.png">
<b>安全提醒:</b>下单后,<span class="redColor boldWord">用QQ给您发送链接办理退款的都是骗子!</span>天猫不存在系统升级,订单异常等问题,谨防假冒客服电话诈骗!
</div>
</div>