大型电商项目订单功能实现
1.展示订单确认页面
1.1.1. 功能分析
1、在购物车页面点击“去结算”按钮跳转到订单确认页面。2、请求的url:/order/order-cart3、参数:没有参数。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 * */@Servicepublic 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 */@Controllerpublic 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 中储存的数字值增一。
#订单号生成keyORDER_ID_GEN_KEY=ORDER_ID_GEN#订单号初始值ORDER_ID_START=100544#订单明细id生成keyORDER_DETAIL_ID_GEN_KEY=ORDER_DETAIL_ID_GEN
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.****.net/jiangjunshow