本篇为实战系列第四篇,为大家带来购物车和订单界面
实现购物车功能,在点击书籍列表右侧的加入购物车后加入到购物车
这里购物车是用Session实现的,当点击加入购物车时,将书籍添加到Cookies中
将该书籍对应的主键添加到为”ZouCart”的Cookies中,如果在Cookies中已经有该书籍则将其对应的数量+1。
/**
* 添加购物车商品
*
* @param itemId
* @param request
* @param response
* @return
*/
@Override
public Msg addCartItem(long itemId, HttpServletRequest request, HttpServletResponse response) {
//取商品信息
CartItem cartItem = null;
//收取购物车商品列表
List<CartItem> itemList = getCartItemList(request);
//判断购物车商品列表是否存在此商品
for (CartItem item : itemList) {
//如果存在此商品
if (item.getId() == itemId) {
//增加商品数量
item.setQuantity(item.getQuantity() + 1);
cartItem = item;
break;
}
}
if (cartItem == null) {
cartItem = new CartItem();
Msg msg = bookService.getBookByPrimary(itemId);
if (msg.getCode() == 100) {
Book book = (Book) msg.getExtend().get("book");
cartItem.setQuantity(1);
cartItem.setId(book.getbId());
cartItem.setAuthor(book.getAuthor());
cartItem.setBook_image(book.getBookImage());
cartItem.setBook_name(book.getBookName());
cartItem.setPrice(book.getPrice());
cartItem.setPubilshing(book.getPubilshing());
}
//添加到购物车列表
itemList.add(cartItem);
}
CookieUtil.setCookie(request, response, "ZouCart", JsonUtils.objectToJson(itemList), true);
return Msg.success();
}
/**
* 获取购物车信息
*
* @param request
* @param response
* @return
*/
@Override
public List<CartItem> getCartItemList(HttpServletRequest request, HttpServletResponse response) {
//从cookies中取得商品列表
String cartJson = CookieUtil.getCookieValue(request, "ZouCart", true);
if (cartJson == null) {
return new ArrayList<>();
}
//把json转换成商品列表
try {
List<CartItem> list = JsonUtils.jsonToList(cartJson, CartItem.class);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
Controller:
@RequestMapping("/add/{itemId}")
public String addCartItem(@PathVariable Long itemId, HttpServletRequest request, HttpServletResponse response) {
cartService.addCartItem(itemId, request, response);
return "cart/success";
}
@RequestMapping("/cart")
public String toCart(HttpServletRequest request, HttpServletResponse response, Model model) {
List<CartItem> list = cartService.getCartItemList(request, response);
model.addAttribute("cartList", list);
return "cart/cartList";
}
Html:
<div class="box box-info">
<div class="box-body" style="display: block;">
<div class="table-responsive">
<div>
<h3>商品已成功加入购物车!</h3>
<span id="flashBuy" style="display: none">商品数量有限,请您尽快下单并付款!</span>
<h3>
<a class="btn-1" href="/cart/cart" id="GotoShoppingCart">去购物车结算</a>
</h3>
</div>
<h3>
<span class="ml10">您还可以 <a
class="ftx-05" href="javascript:history.back();">继续购物</a></span>
</h3>
</span>
</div>
</div>
</div>
当跳转到购物车界面时,可以任意修改商品的数量或删除某一商品,自动计算购物车内商品的总价
Service:
/**
* 删除购物车商品
*
* @param itemId
* @param request
* @param response
* @return
*/
@Override
public Msg deleteCartItem(long itemId, HttpServletRequest request, HttpServletResponse response) {
//从cookies中获取购物车列表
List<CartItem> itemList = getCartItemList(request);
//从列表中找到此商品
for (CartItem cartItem : itemList) {
if (cartItem.getId() == itemId) {
itemList.remove(cartItem);
break;
}
}
//把购物车列表重新写入cookies
CookieUtil.setCookie(request, response, "ZouCart", JsonUtils.objectToJson(itemList), true);
return Msg.success();
}
/**
* 更新购物车数据
*
* @param itemId
* @param quantity
* @param request
* @param response
* @return
*/
@Override
public Msg updateItem(long itemId, int quantity, HttpServletRequest request, HttpServletResponse response) {
List<CartItem> itemList = getCartItemList(request);
for (CartItem cartItem : itemList) {
if (cartItem.getId() == itemId) {
cartItem.setQuantity(quantity);
break;
}
}
CookieUtil.setCookie(request, response, "ZouCart", JsonUtils.objectToJson(itemList), true);
return Msg.success();
}
Controller:
@RequestMapping("/delete/{itemId}")
public String deleteCartItem(@PathVariable Long itemId, HttpServletRequest request, HttpServletResponse response) {
cartService.deleteCartItem(itemId, request, response);
return "redirect:/cart/cart";
}
@RequestMapping("/updateQuantity/{itemId}/{itemQuantity}")
public String updateQuantity(@PathVariable("itemId") Long itemId, @PathVariable("itemQuantity") Integer quantity,
HttpServletRequest request, HttpServletResponse response) {
cartService.updateItem(itemId, quantity, request, response);
return "redirect:/cart/cart";
}
Html:
<div class="box box-info">
<div class="box-body" style="display: block;">
<div class="table-responsive">
<table class="table no-margin">
<thead>
<tr>
<th>书本作者</th>
<th>封面</th>
<th>书名</th>
<th>价格</th>
<th>购买数量</th>
<th>出版社</th>
<th>商品总价</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:set var="totalPrice" value="0"></c:set>
<c:forEach var="cart" items="${cartList}">
<c:set var="totalPrice" value="${ totalPrice + (cart.price * cart.quantity)}"/>
<tr>
<td>${cart.author}</td>
<td><img src="<%=request.getContextPath()%>/${cart.book_image}"
style="width: 45px;height: 80px;"
onclick='showimage("<%=request.getContextPath()%>/${cart.book_image}")'/>
</td>
<td>${cart.book_name}</td>
<td>${cart.price}</td>
<td>
<input type="text"
itemPrice="${cart.price}"
itemId="${cart.id}" value="${cart.quantity}"
class="quantity">
</td>
<td>${cart.pubilshing}</td>
<td>${cart.price*cart.quantity}</td>
<td>
<a type="button" class="btn btn-danger"
href="<%=request.getContextPath()%>/cart/delete/${cart.id}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div>
<h2>总价:¥<fmt:formatNumber value="${totalPrice}" maxFractionDigits="2" minFractionDigits="2"
groupingUsed="true"/></h2>
<a type="button" class="btn btn-danger"
href="<%=request.getContextPath()%>/order/toindex">去结算</a>
</div>
</div>
</div>
进入购物车界面后,可以选择提交订单,这里我们提交订单前必须要求登录过,我们将用Shiro来实现,下一篇将介绍登录功能,这里我们直接讲订单是如何实现的
Dao:
//插入订单
int insert(Order order);
//插入订单细节
int insertDetail(Detail detail);
<insert id="insert" parameterType="Order">
insert into `order`
(o_id,order_status,target_address,telephone,price,description,u_id,username)
values
(#{oId},#{orderStatus},#{targetAddress},#{telephone},#{price},#{description},#{uId},#{username})
</insert>
<insert id="insertDetail" parameterType="Detail">
insert into order_detail (book_num,bookName,book_price,o_id)
values (#{bookNum},#{bookName},#{bookPrice},#{oId})
</insert>
Service:
public String create(Order order,List<Detail> details) {
//调用创建订单服务前补全用户信息
//从cookie中取得购物车的内容,然后获取用户信息
String orderId= new Date().getTime()+UUID.randomUUID().toString().substring(0,5);
order.setoId(orderId);
orderMapper.insert(order);
for (Detail detail : details) {
//补全订单明细信息并存储
detail.setoId(orderId);
orderMapper.insertDetail(detail);
}
return orderId;
}
Controller:
@RequestMapping("/toindex")
public String showOrderCart(HttpServletRequest request, HttpServletResponse response, Model model) {
//去购物车商品列表
List<CartItem> list = cartService.getCartItemList(request, response);
//传递给页面
model.addAttribute("cartList", list);
return "order/order-cart";
}
@RequestMapping(value = "/createOrder", method = RequestMethod.POST)
public String createOrder(Order order, DetailList detailList, Model model, HttpServletRequest request, HttpServletResponse response) {
try {
//从session中取得用户信息
User user = (User) request.getSession().getAttribute("user");
//在order对象中补全用户信息
order.setuId(user.getuId());
order.setOrderStatus(1);
order.setUsername(user.getUsername());
//调用服务
String orderId = orderService.create(order, detailList.getDetails());
CookieUtil.deleteCookie(request, response, "ZouCart");
model.addAttribute("orderId", orderId);
model.addAttribute("data", new DateTime().plusDays(3).toString("yyyy-MM-dd"));
return "redirect:/book/toindex";
} catch (Exception e) {
e.printStackTrace();
model.addAttribute("message", "创建订单出错。请稍后重试!");
model.addAttribute("data", new DateTime().plusDays(3).toString("yyyy-MM-dd"));
return "commons/error";
}
}
首页中我的订单和我的购物车按钮,点击可查看我的订单和我的购物车,我的订单可以查看详情。我的购物车只需直接调用进入购物车的方法即可不再赘述
Dao:
//查询订单该用户所属订单
List<Order> getAllOrderByUser(Long id);
//查询该订单所属细节
List<Detail> getAllDetailByOrder(String id);
<select id="getAllOrderByUser" parameterType="java.lang.Long" resultType="Order">
select * from `order` where u_id=#{id}
</select>
<select id="getAllDetailByOrder" parameterType="java.lang.String" resultType="Detail">
select * from `order_detail` where o_id=#{id}
</select>
Service:
public List<Order> getAllOrderByUser(Long id) {
return orderMapper.getAllOrderByUser(id);
}
public List<Detail> getAllDetailByOrder(String id) {
return orderMapper.getAllDetailByOrder(id);
}
Controller:
@RequestMapping(value = "/myOrder/{uId}", method = RequestMethod.GET)
public String myOrder(@PathVariable("uId") Long uId, Model model) {
List<Order> orders = orderService.getAllOrderByUser(uId);
model.addAttribute("orders", orders);
return "order/order";
}
@RequestMapping(value = "/getAllDetailByOrder/{oId}", method = RequestMethod.GET)
public String getAllDetailByOrder(@PathVariable("oId") String oId, Model model) {
List<Detail> details = orderService.getAllDetailByOrder(oId);
model.addAttribute("details", details);
return "order/orderDetail";
}
Html:Order
<table class="table no-margin">
<thead>
<tr>
<th>订单目标地址</th>
<th>快递员电话</th>
<th>订单情况:"0"未交费,“1"交费</th>
<th>订单下定用户姓名</th>
<th>总价</th>
<th>订单描述</th>
<th>下单时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="order" items="${orders}">
<tr>
<td>${order.targetAddress}</td>
<td>${order.telephone}</td>
<td>${order.orderStatus}</td>
<td>${order.username}</td>
<td>${order.price}</td>
<td>${order.description}</td>
<td>${order.uptime}</td>
<td>
<a type="button" class="btn btn-danger"
href="<%=request.getContextPath()%>/order/getAllDetailByOrder/${order.oId}">查看该订单细节</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
Html:Order-Detail
<table class="table no-margin">
<thead>
<tr>
<th>所属订单编号</th>
<th>书本数量</th>
<th>书本名字</th>
<th>书本单价</th>
</tr>
</thead>
<tbody>
<c:forEach var="detail" items="${details}">
<tr>
<td>${detail.odId}</td>
<td>${detail.bookNum}</td>
<td>${detail.bookName}</td>
<td>${detail.bookPrice}</td>
</tr>
</c:forEach>
</tbody>
</table>
测试:当我们选择购买书籍为
地址:
数据库中将会出现相应数据:
用户如果登录过后,头像旁边会有我的订单和我的购物车按钮,点击可查看我的订单和我的购物车,我的订单可以查看详情。