易课寄在线购课系统开发笔记(三十四)–完成订单系统的开发
订单系统
功能分析
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 :
/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>