1.展示订单确认页面
1.1.1. 功能分析
-
1、在购物车页面点击“去结算”按钮跳转到订单确认页面。
-
-
2、请求的url:/order/order-cart
-
-
3、参数:没有参数。
-
-
4、购物车商品数据从cookie中取出来的。可以在订单系统中取到cookie中的购物车数据。
-
-
5、配送地址列表,需要用户登录。需要根据用户id查询收货地址列表。静态数据。
-
-
6、支付方式。静态数据。
-
-
6、返回值:逻辑视图String,展示订单确认页面。
1.1.2. Interface层
-
package cn.e3mall.order.service;
-
-
import cn.e3mall.common.utils.E3Result;
-
import cn.e3mall.order.pojo.OrderInfo;
-
-
public
interface OrderService {
-
//创建订单
-
E3Result createOrder(OrderInfo orderInfo);
-
}
1.1.3. Service层
-
package cn.e3mall.order.service.impl;
-
-
import java.util.Date;
-
import java.util.List;
-
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.beans.factory.annotation.Value;
-
import org.springframework.stereotype.Service;
-
-
import cn.e3mall.common.jedis.JedisClient;
-
import cn.e3mall.common.utils.E3Result;
-
import cn.e3mall.mapper.TbOrderItemMapper;
-
import cn.e3mall.mapper.TbOrderMapper;
-
import cn.e3mall.mapper.TbOrderShippingMapper;
-
import cn.e3mall.order.pojo.OrderInfo;
-
import cn.e3mall.order.service.OrderService;
-
import cn.e3mall.pojo.TbOrderItem;
-
import cn.e3mall.pojo.TbOrderShipping;
-
/**
-
* 订单处理服务
-
* @author cxx
-
*
-
*/
-
@Service
-
public
class OrderServiceImpl implements OrderService {
-
-
@Autowired
-
private TbOrderMapper orderMapper;
-
@Autowired
-
private TbOrderItemMapper orderItemMapper;
-
@Autowired
-
private TbOrderShippingMapper orderShippingMapper;
-
@Autowired
-
private JedisClient jedisClient;
-
-
@Value(
"${ORDER_ID_GEN_KEY}")
-
private String ORDER_ID_GEN_KEY;
-
@Value(
"${ORDER_ID_START}")
-
private String ORDER_ID_START;
-
@Value(
"${ORDER_DETAIL_ID_GEN_KEY}")
-
private String ORDER_DETAIL_ID_GEN_KEY;
-
-
@Override
-
public E3Result createOrder(OrderInfo orderInfo) {
-
//生成订单号。使用redis的incr生成。
-
if (!jedisClient.exists(ORDER_ID_GEN_KEY)) {
-
jedisClient.set(ORDER_ID_GEN_KEY, ORDER_ID_START);
-
}
-
String orderId = jedisClient.incr(ORDER_ID_GEN_KEY).toString();
-
//补全orderInfo的属性
-
orderInfo.setOrderId(orderId);
-
//1、未付款,2、已付款,3、未发货,4、已发货,5、交易成功,6、交易关闭
-
orderInfo.setStatus(
1);
-
orderInfo.setCreateTime(
new Date());
-
orderInfo.setUpdateTime(
new Date());
-
//插入订单表
-
orderMapper.insert(orderInfo);
-
//向订单明细表插入数据。
-
List<TbOrderItem> orderItems = orderInfo.getOrderItems();
-
for (TbOrderItem tbOrderItem : orderItems) {
-
//生成明细id
-
String odId = jedisClient.incr(ORDER_DETAIL_ID_GEN_KEY).toString();
-
//补全pojo的属性
-
tbOrderItem.setId(odId);
-
tbOrderItem.setOrderId(orderId);
-
//向明细表插入数据
-
orderItemMapper.insert(tbOrderItem);
-
}
-
//向订单物流表插入数据
-
TbOrderShipping orderShipping = orderInfo.getOrderShipping();
-
orderShipping.setOrderId(orderId);
-
orderShipping.setCreated(
new Date());
-
orderShipping.setUpdated(
new Date());
-
orderShippingMapper.insert(orderShipping);
-
//返回E3Result,包含订单号
-
return E3Result.ok(orderId);
-
}
-
-
}
1.1.4.表现层
-
package cn.e3mall.order.controller;
-
-
import java.util.List;
-
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.ui.Model;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestMethod;
-
-
import cn.e3mall.cart.service.CartService;
-
import cn.e3mall.common.utils.E3Result;
-
import cn.e3mall.order.pojo.OrderInfo;
-
import cn.e3mall.order.service.OrderService;
-
import cn.e3mall.pojo.TbItem;
-
import cn.e3mall.pojo.TbUser;
-
-
/**
-
* 订单管理Controller
-
* <p>Title: OrderController</p>
-
* <p>Description: </p>
-
* <p>Company: www.itcast.cn</p>
-
* @version 1.0
-
*/
-
@Controller
-
public
class OrderController {
-
-
@Autowired
-
private CartService cartService;
-
@Autowired
-
private OrderService orderService;
-
-
@RequestMapping(
"/order/order-cart")
-
public String showOrderCart(HttpServletRequest request) {
-
//取用户id
-
TbUser user= (TbUser) request.getAttribute(
"user");
-
//根据用户id取收货地址列表
-
//使用静态数据。。。
-
//取支付方式列表
-
//静态数据
-
//根据用户id取购物车列表
-
List<TbItem> cartList = cartService.getCartList(user.getId());
-
//把购物车列表传递给jsp
-
request.setAttribute(
"cartList", cartList);
-
//返回页面
-
return
"order-cart";
-
}
-
-
@RequestMapping(value=
"/order/create", method=RequestMethod.POST)
-
public String createOrder(OrderInfo orderInfo, HttpServletRequest request) {
-
//取用户信息
-
TbUser user = (TbUser) request.getAttribute(
"user");
-
//把用户信息添加到orderInfo中。
-
orderInfo.setUserId(user.getId());
-
orderInfo.setBuyerNick(user.getUsername());
-
//调用服务生成订单
-
E3Result e3Result = orderService.createOrder(orderInfo);
-
//如果订单生成成功,需要删除购物车
-
if (e3Result.getStatus() ==
200) {
-
//清空购物车
-
cartService.clearCartItem(user.getId());
-
}
-
//把订单号传递给页面
-
request.setAttribute(
"orderId", e3Result.getData());
-
request.setAttribute(
"payment", orderInfo.getPayment());
-
//返回逻辑视图
-
return
"success";
-
}
-
}
2.用户身份认证
在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。
2.1.1. 功能分析
1、使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。
2、业务逻辑
a) 从cookie中取token。 b) 没有token,需要跳转到登录页面。 c) 有token。调用sso系统的服务,根据token查询用户信息。 d) 如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。 e) 查询到用户信息。放行。
3、在springmvc.xml中配置拦截器。
**在展示订单页面前,我们Redis有用户原理购物车数据,需要将Cookie数据与它进行合并2.1.2. 拦截器实现
-
package cn.e3mall.order.interceptor;
-
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
-
import org.apache.commons.lang3.StringUtils;
-
import org.springframework.beans.factory.annotation.Autowired;
-
import org.springframework.beans.factory.annotation.Value;
-
import org.springframework.web.servlet.HandlerInterceptor;
-
import org.springframework.web.servlet.ModelAndView;
-
-
import cn.e3mall.cart.service.CartService;
-
import cn.e3mall.common.utils.CookieUtils;
-
import cn.e3mall.common.utils.E3Result;
-
import cn.e3mall.common.utils.JsonUtils;
-
import cn.e3mall.pojo.TbItem;
-
import cn.e3mall.pojo.TbUser;
-
import cn.e3mall.sso.service.TokenService;
-
-
/**
-
* 用户登录拦截器
-
* @author cxx
-
*
-
*/
-
public
class LoginInterceptor implements HandlerInterceptor{
-
-
@Value(
"${SSO_URL}")
-
private String SSO_URL;
-
@Autowired
-
private TokenService tokenService;
-
@Autowired
-
private CartService cartService;
-
-
@Override
-
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
-
throws Exception {
-
//从cookie中获取token
-
String token = CookieUtils.getCookieValue(request,
"token");
-
//判断token是否存在
-
if(StringUtils.isBlank(token)) {
-
//跳到登录页面,登录成功后跳到该页面
-
response.sendRedirect(SSO_URL+
"/page/login?redirect="+request.getRequestURI());
-
return
false;
-
}
-
E3Result e3Result = tokenService.getUserByToken(token);
-
//判断用户是否身份过期
-
if(e3Result.getStatus() !=
200) {
-
//如果token不存在,未登录状态,跳转到sso系统的登录页面。用户登录成功后,跳转到当前请求的url
-
response.sendRedirect(SSO_URL +
"/page/login?redirect=" + request.getRequestURL());
-
//拦截
-
return
false;
-
}
-
//把用户信息放入到request中
-
TbUser user = (TbUser)e3Result.getData();
-
request.setAttribute(
"user",user);
-
//判断cookie中是否有数据,合并到服务器
-
String jsonCartList = CookieUtils.getCookieValue(request,
"cart",
true);
-
if(StringUtils.isNoneBlank(jsonCartList)) {
-
//合并购物车
-
cartService.mergeCart(user.getId(), JsonUtils.jsonToList(jsonCartList, TbItem.class));
-
}
-
//放行
-
return
true;
-
}
-
-
@Override
-
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
-
ModelAndView modelAndView)
throws Exception {
-
// TODO Auto-generated method stub
-
-
}
-
-
@Override
-
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
-
throws Exception {
-
// TODO Auto-generated method stub
-
-
}
-
-
-
}
2.1.3. 配置拦截器
springmvc.xml中配置拦截器。
-
<!-- 拦截器配置 -->
-
<mvc:interceptors>
-
<mvc:interceptor>
-
<mvc:mapping path=
"/**"/>
-
<bean
class=
"cn.e3mall.order.interceptor.LoginInterceptor"/>
-
</mvc:interceptor>
-
</mvc:interceptors>
2.1.4. 实现sso系统的回调
-
@RequestMapping(
"/page/login")
-
public String showLogin(String redirectUrl,Model model) {
-
model.addAttribute(
"redirect",redirectUrl);
-
return
"login";
-
}
项目展示:
一个问题:订单编号怎么生成
Redis Incr 命令将 key 中储存的数字值增一。
-
#订单号生成key
-
ORDER_ID_GEN_KEY=ORDER_ID_GEN
-
#订单号初始值
-
ORDER_ID_START=
100544
-
#订单明细id生成key
-
ORDER_DETAIL_ID_GEN_KEY=ORDER_DETAIL_ID_GEN
![](https://i-blog.csdnimg.cn/blog_migrate/00722bf82bf7832ecb068a3d0dc6be8b.png)