Design and Implementation of an Online Course Purchase System(34)

Complete the development of the order system

Posted by Chen Xingxu on June 3, 2020

易课寄在线购课系统开发笔记(三十四)–完成订单系统的开发

订单系统

功能分析

1、在购物车页面点击 “去结算” 按钮跳转到订单确认页面;

a) 展示课程列表;

b) 配送地址列表;

c) 选择支付方式。

2、展示订单确认页面之前,应该确认用户身份;

a) 使用拦截器实现;

b) Cookie 中取 token;

c) 取不到 token 跳转到登录页面;

d) 取到 token ,根据 token 查询用户信息;

e) 如果没有用户信息,登录过期跳转到登录页面;

f) 取到用户信息,放行。

3、提交订单;

a) 生成订单;

b) 展示订单提交成功页面。

订单系统系统:订单确认页面、订单提交成功页面。

订单服务系统

工程搭建

创建一个订单服务系统:

  • ecourses-parent:父工程,打包方式 pom,管理 jar 包的版本号。
    • ecourses-common:通用的工具类及通用的 pojo。打包方式 jar
    • ecourses-order-web(war)
    • ecourses-order(聚合工程pom)
      • ecourses-order-interface(jar)
      • ecourses-order-service(war)

可以参考

易课寄在线购课系统开发笔记(七)–后台管理系统工程搭建分析

ecourses-bms 工程。

表现层工程:

ecourses-order-web 打包方式 war。

展示订单确认页面

功能分析

1、在购物车页面点击 “去结算” 按钮跳转到订单确认页面;

2、请求的 url :

12-04

/order/order-cart

1、参数:没有参数;

2、购物车课程数据从 Cookie 中取出来的。可以在订单系统中取到 Cookie 中的购物车数据;

3、配送地址列表,需要用户登录。需要根据用户 id 查询收货地址列表。静态数据;

4、支付方式。静态数据;

5、返回值:逻辑视图String,展示订单确认页面。

Dao 层、Service 层(没有)

需要根据用户 id 查询收货地址列表。没有此功能。

表现层

请求的 url :/order/order-cart

参数:无

业务逻辑:

从 Cookie 中取课程列表展示到页面。

返回值:逻辑视图。

package cn.ecourses.order.controller;
//订单管理Controller
@Controller
public class OrderController {
	
	@Autowired
	private CartService cartService;
	@Autowired
	private OrderService orderService;

	@RequestMapping("/order/order-cart")
	public String showOrderCart(HttpServletRequest request) {
		//取用户id
		EcoursesUser user= (EcoursesUser) request.getAttribute("user");
		//根据用户id取收货地址列表
		//使用静态数据。。。
		//取支付方式列表
		//静态数据
		//根据用户id取购物车列表
		List<EcoursesItem> 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) {
		//取用户信息
		EcoursesUser user = (EcoursesUser) request.getAttribute("user");
		//把用户信息添加到orderInfo中。
		orderInfo.setUserId(user.getId());
		orderInfo.setBuyerNick(user.getUsername());
		//调用服务生成订单
		ECoursesResult ecoursesResult = orderService.createOrder(orderInfo);
		//如果订单生成成功,需要删除购物车
		if (ecoursesResult.getStatus() == 200) {
			//清空购物车
			cartService.clearCartItem(user.getId());
		}
		//把订单号传递给页面
		request.setAttribute("orderId", ecoursesResult.getData());
		request.setAttribute("payment", orderInfo.getPayment());
		//返回逻辑视图
		return "success";
	}
}

用户身份认证

在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。

功能分析

1、使用 SpringMVC 的拦截器实现,需要实现一个接口 HandlerInterceptor 接口;

2、业务逻辑;

a) 从 Cookie 中取 token;

b) 没有 token ,需要跳转到登录页面;

c) 有 token 。调用 SSO 系统的服务,根据 token 查询用户信息;

d) 如果查不到用户信息。用户登录已经过期。需要跳转到登录页面;

e) 查询到用户信息。放行;

3、在 springmvc.xml 中配置拦截器。

拦截器实现

package cn.ecourses.order.interceptor;
//用户登录拦截器
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)) {
			//如果token不存在,未登录状态,跳转到sso系统的登录页面。用户登录成功后,跳转到当前请求的url
			response.sendRedirect(SSO_URL + "/page/login?redirect=" + request.getRequestURL());
			//拦截
			return false;
		}
		//如果token存在,需要调用sso系统的服务,根据token取用户信息
		ECoursesResult ecoursesResult = tokenService.getUserByToken(token);
		//如果取不到,用户登录已经过期,需要登录。
		if (ecoursesResult.getStatus() != 200) {
			//如果token不存在,未登录状态,跳转到sso系统的登录页面。用户登录成功后,跳转到当前请求的url
			response.sendRedirect(SSO_URL + "/page/login?redirect=" + request.getRequestURL());
			//拦截
			return false;
		}
		//如果取到用户信息,是登录状态,需要把用户信息写入request。
		EcoursesUser user = (EcoursesUser) ecoursesResult.getData();
		request.setAttribute("user", user);
		//判断cookie中是否有购物车数据,如果有就合并到服务端。
		String jsonCartList = CookieUtils.getCookieValue(request, "cart", true);
		if (StringUtils.isNoneBlank(jsonCartList)) {
			//合并购物车
			cartService.mergeCart(user.getId(), JsonUtils.jsonToList(jsonCartList, EcoursesItem.class));
		}
		//放行
		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {

	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {

	}
}

配置拦截器

中 springmvc.xml 中配置拦截器。

<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.ecourses.order.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

实现 SSO 系统的回调

12-05