1. 持久層
1.1 規劃sql語句
- 執行更新t_cart表記錄的num值
- 根據cid查詢購物車的數據是否存在
select * from t_cart where cid=#{cid}
1.2 接口和抽象方法
/*** 獲取購物車中商品的數據總數* @return 購物車中商品的數據總數*/Cart findByCid(Integer cid);
1.3 xml文件中sql映射
<select id="findByCid" resultMap="CartEntityMap">select * from t_cart where cid=#{cid}</select>
1.4 測試類中進行測試
@Testpublic void findByCid() {Integer cid = 1;Cart cart = cartMapper.findByCid(cid);System.out.println(cart);}
2. 業務層
2.1 規劃異常
-
更新時產生的更新異常
-
查詢時數據是否有訪問的權限
-
要查詢的數據不存在,CartNotFoundException異常
package com.cy.store.service.ex;public class CartNotFoundException extends ServiceException{public CartNotFoundException() {super();}public CartNotFoundException(String message) {super(message);}public CartNotFoundException(String message, Throwable cause) {super(message, cause);}public CartNotFoundException(Throwable cause) {super(cause);}protected CartNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}
2.2 接口和抽象方法
/*** 添加購物車數量* @param cid 購物車數據id* @param uid 用戶id* @param username 用戶名* @return 修改后的購物車商品數量*/Integer addNum(Integer cid, Integer uid, String username);/*** 減少購物車數量* @param cid 購物車數據id* @param uid 用戶id* @param username 用戶名* @return 修改后的購物車商品數量*/Integer cutNum(Integer cid, Integer uid, String username);
2.3 實現類實現接口,重寫抽象方法
/*** 修改購物車商品的數量* @param cid 購物車id* @param uid 用戶id* @param username 用戶名* @return 修改后的商品數量*/@Overridepublic Integer addNum(Integer cid, Integer uid, String username) {
// 判斷數據庫中是否有購物車數據Cart cart = cartMapper.findByCid(cid);if (cart==null){throw new CartNotFoundException("購物車數據不存在");}if (cart.getUid()!=uid){throw new AccessDeniedException("非法訪問");}
// 進行數量+1操作Integer newNum = cart.getNum()+1;Integer rows = cartMapper.updateNumByCid(cid,newNum,username,new Date());
// 如果返回影響行數不為1,則拋出更新數據產生未知的異常if (rows!=1){throw new UpdateException("更新數據時產生未知的異常");}// 返回數據庫中商品的數量return newNum;}/*** 減少購物車商品的數量* @param cid 購物車id* @param uid 用戶id* @param username 用戶名* @return 修改后的商品數量*/@Overridepublic Integer cutNum(Integer cid, Integer uid, String username) {
// 判斷數據庫中是否有購物車數據Cart cart = cartMapper.findByCid(cid);if (cart==null){throw new CartNotFoundException("購物車數據不存在");}if (cart.getUid()!=uid){throw new AccessDeniedException("非法訪問");}Integer newNum = null;if (cart.getNum()!=0){// 進行數量-1操作newNum = cart.getNum()-1;Integer rows = cartMapper.updateNumByCid(cid,newNum,username,new Date());// 如果返回影響行數不為1,則拋出更新數據產生未知的異常if (rows!=1){throw new UpdateException("更新數據時產生未知的異常");}}else {throw new CartNotFoundException("無法減少商品了");}// 返回數據庫中商品的數量return newNum;}
}
3. 控制層
3.1 規劃異常的處理
? ? ? ? 在BaseController中捕獲CartNotFoundException異常
/*** 控制層基類*/
public class BaseController {//操作成功的狀態碼public static final int OK = 200;/*** 全局異常處理器,用于捕獲并處理業務層拋出的異常。** @param e 捕獲的異常對象* @return 返回封裝后的 JsonResult 對象,包含狀態碼和錯誤信息*/
// 該項目中產生了異常,會被統一攔截到此方法中,這個方法此時就充當了請求處理方法,方法的返回值直接給前端瀏覽器,返回給前端的數據中,狀態碼,狀態碼對應信息,數據@ExceptionHandler({ServiceException.class, FileUploadException.class})public JsonResult<Void> handleException(Throwable e) {// 創建一個 JsonResult 實例,并初始化異常消息JsonResult<Void> result = new JsonResult<>(e);// 判斷異常類型,設置對應的狀態碼和提示信息if (e instanceof UsernameDuplicatedException){// 用戶名被占用時返回 400 狀態碼和相應提示result.setState(4000);result.setMessage("用戶名被占用");} else if (e instanceof InsertException){// 插入數據失敗時返回 500 狀態碼和相應提示result.setState(4000);result.setMessage("注冊時產生未知的異常");}else if (e instanceof UsernameNotFoundException){result.setState(4001);result.setMessage("用戶數據不存在");}else if (e instanceof PasswordNotMatchException){result.setState(4002);result.setMessage("用戶密碼錯誤");}else if (e instanceof AddressCountLimitException){result.setState(4003);result.setMessage("收貨地址超出上限");}else if (e instanceof CartNotFoundException){result.setState(4007);result.setMessage("購物車數據不存在");}else if (e instanceof AccessDeniedException){result.setState(4004);result.setMessage("收貨地址數據非法訪問");}else if (e instanceof AddressNotFoundException){result.setState(4005);result.setMessage("收貨地址數據不存在");}else if (e instanceof ProductNotFoundException){result.setState(4006);result.setMessage("商品數據不存在");}else if (e instanceof DeleteException){result.setState(5002);result.setMessage("刪除數據時產生未知的異常");}else if (e instanceof UpdateException){result.setState(5003);result.setMessage("更新數據時產生未知的異常");} else if (e instanceof FileEmptyException) {result.setState(6000);} else if (e instanceof FileSizeException) {result.setState(6001);} else if (e instanceof FileTypeException) {result.setState(6002);} else if (e instanceof FileStateException) {result.setState(6003);} else if (e instanceof FileUploadIOException) {result.setState(6004);}// 返回最終的響應結果return result;}/*** 從Session中獲取當前登錄用戶的uid* * @param session HttpSession對象,用于獲取會話中的用戶ID* @return 當前登錄用戶的uid* * `protected` 表示該方法只能被同一個包內的類或子類訪問。* `final` 表示該方法不能被子類重寫。*/protected final Integer getUidFromSession(HttpSession session) {// 從Session中獲取uid// 從會話中獲取uid屬性并轉換為整數類型返回return Integer.valueOf(session.getAttribute("uid").toString());}/*** 從Session中獲取當前登錄用戶的用戶名* @param session HttpSession對象,用于獲取會話中的用戶名* @return 當前登錄用戶的用戶名*/protected final String getUsernameFromSession(HttpSession session) {// 從Session中獲取當前登錄的用戶名return session.getAttribute("username").toString();}}
?3.2 規劃并實現請求
/*** 增加購物車商品數量* @param cid 購物車id* @param session 登錄用戶* @return 修改數量*/@RequestMapping("/num/add/{cid}")public JsonResult<Integer> addNum(@PathVariable("cid") Integer cid, HttpSession session) {Integer uid = getUidFromSession(session);String username = getUsernameFromSession(session);Integer data = cartService.addNum(cid, uid, username);return new JsonResult<>(OK, data);}/*** 減少購物車商品數量* @param cid 購物車id* @param session 登錄用戶* @return 修改數量*/@RequestMapping("/num/cut/{cid}")public JsonResult<Integer> cutNum(@PathVariable("cid") Integer cid, HttpSession session) {Integer uid = getUidFromSession(session);String username = getUsernameFromSession(session);Integer data = cartService.cutNum(cid, uid, username);return new JsonResult<>(OK, data);}
3.3 測試
? ? ? ? 啟動項目,先登錄,再通過訪問url地址進行測試
4. 前端代碼
? ? ? ? 增加減少購物車商品數量的邏輯基本上是一樣的
<script type="text/javascript">
<!-- 當頁面加載時發送獲取購物車列表的請求 -->$(document).ready(function() {showCartList();});//展示購物車列表數據function showCartList() {// 清空數據區$("#cart-list").empty();$.ajax({url: "/carts",type: "GET",dataType: "JSON",success: function(json) {var list = json.data;// 遍歷后端響應過來的數據for (var i = 0; i < list.length; i++) {// 給數據進行占位var tr = '<tr>\n' +'<td>\n' +'<input name="cids" value="#{cid}" type="checkbox" class="ckitem" />\n' +'</td>\n' +'<td><img src="..#{image}collect.png" class="img-responsive" /></td>\n' +'<td>#{title}#{msg}</td>\n' +'<td>¥<span id="goodsPrice#{cid}">#{singlePrice}</span></td>\n' +'<td>\n' +'<input type="button" value="-" class="num-btn" onclick="reduceNum(#{cid})" />\n' +'<input id="goodsCount#{cid}" type="text" size="2" readonly="readonly" class="num-text" value="#{num}">\n' +'<input class="num-btn" type="button" value="+" onclick="addNum(#{cid})" />\n' +'</td>\n' +'<td><span id="goodsCast#{cid}">#{totalPrice}</span></td>\n' +'<td>\n' +'<input type="button" onclick="delCartItem(this)" class="cart-del btn btn-default btn-xs" value="刪除" />\n' +'</td>\n' +'</tr>';// 賦值tr = tr.replaceAll(/#{cid}/g, list[i].cid);tr = tr.replaceAll(/#{image}/g, list[i].image);tr = tr.replaceAll(/#{title}/g, list[i].title);tr = tr.replaceAll(/#{singlePrice}/g, list[i].realPrice);tr = tr.replaceAll(/#{num}/g, list[i].num);tr = tr.replaceAll(/#{totalPrice}/g, list[i].realPrice * list[i].num);if (list[i].realPrice < list[i].price) {tr = tr.replace(/#{msg}/g, "比加入時降價" + (list[i].price - list[i].realPrice) + "元");} else {tr = tr.replace(/#{msg}/g, "");}// 每次遍歷完數據,就往頁面中添加一行數據$("#cart-list").append(tr);}},error: function (xhr) {alert("加載購物車列表數據時產生未知的異常"+xhr.status);}});}function addNum(cid) {$.ajax({url: "/carts/num/add/"+cid,type: "POST",dataType: "JSON",success: function (json) {if (json.state == 200) {$("#goodsCount"+cid).val(json.data);// .html() 修改某個標簽的內容var price = $("#goodsPrice"+cid).html();var totalPrice = price * json.data;//將商品總價更新到標簽中$("#goodsCast"+cid).html(totalPrice);} else {alert("增加購物車商品數量失敗"+json.message);}},error: function (xhr) {alert("增加購物車商品數量時產生未知的異常!"+xhr.message);}});}// 減少購物車商品數量function reduceNum(cid) {$.ajax({url: "/carts/num/cut/"+cid,type: "POST",dataType: "JSON",success: function (json) {if (json.state == 200) {$("#goodsCount"+cid).val(json.data);// .html() 修改某個標簽的內容var price = $("#goodsPrice"+cid).html();var totalPrice = price * json.data;//將商品總價更新到標簽中$("#goodsCast"+cid).html(totalPrice);} else {alert("增加購物車商品數量失敗"+json.message);}},error: function (xhr) {alert("增加購物車商品數量時產生未知的異常!"+xhr.message);}});}// $(function() {// //返回鏈接// $(".link-account").click(function() {// location.href = "orderConfirm.html";// })// })</script>