e3mall商城总结13之订单确认(有BUG)
说在前面的话
上一节说了购物车的生成,本节主要说了在购物车的列表上去结算,从而生成一个未支付的订单,生成的订单默认状态为1,
题目说的BUG是因为所有数据都是通过前端向后端生成的,包括订单的金额。因此是可以通过F12工具进行修改金额。所以说这个商城的订单生成金额是有BUG存在的。所以我们应该在后台通过商品id、数量进行生成金额,不应该在取前端的金额。
购物车的数据都是从redis中取出来的。
service层:
OrderServiceImpl .java
package cn.tsu.order.e3mall.service.impl;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.tsu.e3mall.dao.TbOrderItemMapper;
import cn.tsu.e3mall.dao.TbOrderMapper;
import cn.tsu.e3mall.dao.TbOrderShippingMapper;
import cn.tsu.e3mall.jedis.JedisClient;
import cn.tsu.e3mall.pojo.TbItem;
import cn.tsu.e3mall.pojo.TbOrderItem;
import cn.tsu.e3mall.pojo.TbOrderShipping;
import cn.tsu.e3mall.utils.E3Result;
import cn.tsu.order.e3mall.pojo.OrderInfo;
import cn.tsu.order.e3mall.service.OrderService;
import cn.tsu.order.e3mall.service.config.OrderConfig;
import cn.tsu.order.e3mall.service.config.UUIDUtils;
/**
* 订单列表的service
* @author xiaofeng
*
*/
@Service
public class OrderServiceImpl implements OrderService{
@Autowired
private JedisClient jedisClient;//redis
@Autowired
private TbOrderMapper orderMapper;//订单
@Autowired
private TbOrderShippingMapper orderShippingMapper;//收件人
@Autowired
private TbOrderItemMapper orderItemMapper;//订单中的商品列表
//创建订单
@Override
public E3Result CreateOrder(OrderInfo orderInfo) {
// 订单生成
//1.查询redis中是否含有初始值,通过redis生成商品id
//2.若不含,则创建一个初始值
if (!jedisClient.exists(OrderConfig.ORDER_ID_KEY_REDIS)) {
jedisClient.set(OrderConfig.ORDER_ID_KEY_REDIS, OrderConfig.ORDER_ID_REDIS);
}
//3.若含有,则初始值加1当做orderId
String orderId = jedisClient.incr(OrderConfig.ORDER_ID_KEY_REDIS).toString();
//4.把orderId加入到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 orderItem : orderItems) {
orderItem.setId(UUIDUtils.date());
orderItem.setOrderId(orderId);
orderItemMapper.insert(orderItem);
}
//收件人生成
TbOrderShipping orderShipping = orderInfo.getOrderShipping();
orderShipping.setOrderId(orderId);
orderShipping.setCreated(new Date());
orderShipping.setUpdated(new Date());
//清除购物车
jedisClient.del(OrderConfig.CART_REDIS_PRE+orderInfo.getUserId());
return E3Result.ok(orderId);
}
}
controller层:
OrderController.java
package cn.tsu.order.e3mall.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.tsu.cart.e3mall.service.CartService;
import cn.tsu.e3mall.pojo.TbItem;
import cn.tsu.e3mall.pojo.TbUser;
import cn.tsu.e3mall.utils.E3Result;
import cn.tsu.order.e3mall.pojo.OrderInfo;
import cn.tsu.order.e3mall.service.OrderService;
/**
* 支付的逻辑controller
* @author xiaofeng
*
*/
@Controller
public class OrderController {
@Autowired
private CartService cartService;
@Autowired
private OrderService orderService;
@RequestMapping("order/order-cart")
public String showOrder(HttpServletRequest request) {
//通过拦截器set的tbuser获取用户
TbUser tbUser = (TbUser) request.getAttribute("tbUser");
//获取购物车里的商品
List<TbItem> cartList = cartService.getCart(tbUser.getId());
request.setAttribute("cartList", cartList);
return "order-cart";
}
//订单生成
@RequestMapping("/order/create")
public String orderCreate(OrderInfo orderInfo ,HttpServletRequest request) {
TbUser tbUser = (TbUser) request.getAttribute("tbUser");
orderInfo.setUserId(tbUser.getId());
orderInfo.setBuyerNick(tbUser.getUsername());
E3Result e3Result = orderService.CreateOrder(orderInfo);
request.setAttribute("payment", orderInfo.getPayment());
request.setAttribute("orderId", e3Result.getData());
return "success";
}
}
拦截器LoginInterceptor:
LoginInterceptor.java
package cn.tsu.order.e3mall.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.jboss.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import cn.tsu.cart.e3mall.config.OrderConfig;
import cn.tsu.e3mall.pojo.TbUser;
import cn.tsu.e3mall.utils.CookieUtils;
import cn.tsu.e3mall.utils.E3Result;
import cn.tsu.sso.e3mall.service.UserService;
/**
*登录拦截器
* @author xiaofeng
*
*/
public class LoginInterceptor implements HandlerInterceptor{
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String url = request.getRequestURL().toString();
System.out.println(url);
//从用户浏览器中获取cookies
String token = CookieUtils.getCookieValue(request, OrderConfig.USER_LOGIN_TOKEN);
//若获取不到,则代表没登录,跳转到登录页面,拦截
if (StringUtils.isBlank(token)) {
response.sendRedirect(OrderConfig.LOGIN_HEAD+"/page/login?redirect="+url);
return false;
}
//获取到后到redis中查找user信息
E3Result e3Result = userService.getToken(token);
//若查不到信息,则代表没登录,跳转到登录页面,拦截
if (e3Result.getStatus() != 200) {
response.sendRedirect(OrderConfig.LOGIN_HEAD+"/page/login?redirect="+url);
return false;
}
//若查找到,把user放到request域中
TbUser tbUser = (TbUser) e3Result.getData();
request.setAttribute("tbUser", tbUser);
//放行
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
}
}
数据库的读写分离(mycat)
Mysql提供的解决方案:使用binlog进行数据库同步。需要配置mysql。
代码中实现读写分类:
1、可以使用aop实现一个切面。动态切换数据源。需要编程实现。
2、使用数据库中间件实现读写分类,分库分表。
分库分表:
当数据库的表中数据非常大的时候例如上千万条数据。查询性能非常低。可以把一张表保存到不同的数中。
可以使用一个数据库中间件mycat。国产开源项目,前身是cobar项目。
完!!!!
你可以让我入坑,但是总不能让我陷进去吧!