大型电商项目订单功能实现

大型电商项目订单功能实现_第1张图片

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 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
 * 

Title: OrderController

*

Description:

*

Company: www.itcast.cn

* @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 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中配置拦截器。



	
		
		
	

2.1.4. 实现sso系统的回调

@RequestMapping("/page/login")
public String showLogin(String redirectUrl,Model model) {
	model.addAttribute("redirect",redirectUrl);
	return "login";
}
	


项目展示:

大型电商项目订单功能实现_第2张图片

大型电商项目订单功能实现_第3张图片

大型电商项目订单功能实现_第4张图片



一个问题:订单编号怎么生成

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
大型电商项目订单功能实现_第5张图片



你可能感兴趣的:(后端编程)