電腦商城--購物車

加入購物車

1 購物車-創建數據表

1.使用use命令先選中store數據庫。

USE store;

2.在store數據庫中創建t_cart用戶數據表。

CREATE TABLE t_cart (cid INT AUTO_INCREMENT COMMENT '購物車數據id',uid INT NOT NULL COMMENT '用戶id',pid INT NOT NULL COMMENT '商品id',price BIGINT COMMENT '加入時商品單價',num INT COMMENT '商品數量',created_user VARCHAR(20) COMMENT '創建人',created_time DATETIME COMMENT '創建時間',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改時間',PRIMARY KEY (cid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2 購物車-創建實體類

????????在com.cy.store.entity包下創建購物車的Cart實體類。

package com.cy.store.entity;
import java.io.Serializable;
?
/** 購物車數據的實體類 */
public class Cart extends BaseEntity implements Serializable {private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;
?// Generate: Getter and Setter、Generate hashCode() and equals()、toString()
}

3 購物車-添加購物車-持久層

3.1 規劃需要執行的SQL語句

????????向購物車表中插入商品數據的SQL語句大致是:

insert into t_cart (除了cid以外的字段列表) values (匹配的值列表);

????????如果用戶曾經將某個商品加入到購物車過,則點擊“加入購物車”按鈕只會對購物車中相同商品數量做遞增操作。

update t_cart set num=? where cid=?

????????關于判斷“到底應該插入數據,還是修改數量”,可以通過“查詢某用戶是否已經添加某商品到購物車”來完成。如果查詢到某結果,就表示該用戶已經將該商品加入到購物車了,如果查詢結果為null,則表示該用戶沒有添加過該商品。

select * from t_cart where uid=? and pid=?

3.2 接口與抽象方法

????????在com.cy.store.mapper包下創建CartMapper接口,并添加抽象相關的方法。

package com.cy.store.mapper;
import com.cy.store.entity.Cart;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
?
/** 處理購物車數據的持久層接口 */
public interface CartMapper {/*** 插入購物車數據* @param cart 購物車數據* @return 受影響的行數*/Integer insert(Cart cart);
?/*** 修改購物車數據中商品的數量* @param cid 購物車數據的id* @param num 新的數量* @param modifiedUser 修改執行人* @param modifiedTime 修改時間* @return 受影響的行數*/Integer updateNumByCid(@Param("cid") Integer cid,@Param("num") Integer num,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);
?/*** 根據用戶id和商品id查詢購物車中的數據* @param uid 用戶id* @param pid 商品id* @return 匹配的購物車數據,如果該用戶的購物車中并沒有該商品,則返回null*/Cart findByUidAndPid(@Param("uid") Integer uid,@Param("pid") Integer pid);
}
3.3 配置SQL映射

1.在resources.mapper文件夾下創建CartMapper.xml文件,并在文件中配置以上三個方法的映射。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.mapper.CartMapper"><resultMap id="CartEntityMap" type="com.cy.store.entity.Cart"><id column="cid" property="cid"/><result column="created_user" property="createdUser"/><result column="created_time" property="createdTime"/><result column="modified_user" property="modifiedUser"/><result column="modified_time" property="modifiedTime"/></resultMap>
?<!-- 插入購物車數據:Integer insert(Cart cart) --><insert id="insert" useGeneratedKeys="true" keyProperty="cid">INSERT INTO t_cart (uid, pid, price, num, created_user, created_time, modified_user, modified_time)VALUES (#{uid}, #{pid}, #{price}, #{num}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})</insert>
?<!-- 修改購物車數據中商品的數量:Integer updateNumByCid(@Param("cid") Integer cid,@Param("num") Integer num,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime) --><update id="updateNumByCid">UPDATEt_cartSETnum=#{num},modified_user=#{modifiedUser},modified_time=#{modifiedTime}WHEREcid=#{cid}</update>
?<!-- 根據用戶id和商品id查詢購物車中的數據:Cart findByUidAndPid(@Param("uid") Integer uid,@Param("pid") Integer pid) --><select id="findByUidAndPid" resultMap="CartEntityMap">SELECT*FROMt_cartWHEREuid=#{uid} AND pid=#{pid}</select>
</mapper>

2.在com.cy.store.mapper包下創建CartMapperTests測試類,并添加測試方法。

package com.cy.store.mapper;
import com.cy.store.entity.Cart;
import com.cy.store.entity.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
import java.util.List;@RunWith(SpringRunner.class)
@SpringBootTest
public class CartMapperTests {@Autowiredprivate CartMapper cartMapper;@Testpublic void insert() {Cart cart = new Cart();cart.setUid(1);cart.setPid(2);cart.setNum(3);cart.setPrice(4L);Integer rows = cartMapper.insert(cart);System.out.println("rows=" + rows);}@Testpublic void updateNumByCid() {Integer cid = 1;Integer num = 10;String modifiedUser = "購物車管理員";Date modifiedTime = new Date();Integer rows = cartMapper.updateNumByCid(cid, num, modifiedUser, modifiedTime);System.out.println("rows=" + rows);}@Testpublic void findByUidAndPid() {Integer uid = 1;Integer pid = 2;Cart result = cartMapper.findByUidAndPid(uid, pid);System.out.println(result);}
}

4 購物車-添加購物車-業務層

4.1 規劃異常

????????在插入數據時,可能拋出InsertException異常;在修改數據時,可能拋出UpdateException異常。如果不限制購物車中的記錄的數量,則沒有其它異常。

4.2 接口與抽象方法

????????在com.cy.store.service包下創建ICartService接口,并添加抽象方法。

package com.cy.store.service;/** 處理商品數據的業務層接口 */
public interface ICartService {/*** 將商品添加到購物車* @param uid 當前登錄用戶的id* @param pid 商品的id* @param amount 增加的數量* @param username 當前登錄的用戶名*/void addToCart(Integer uid, Integer pid, Integer amount, String username);
}
4.3 實現抽象方法

1.創建com.cy.store.service.impl.CartServiceImpl類,并實現ICartService接口,并在類的定義前添加@Service注解。在類中聲明CartMapper持久層對象和IProductService處理商品數據的業務對象,并都添加@Autowired注修飾。

package com.cy.store.service.impl;
import com.cy.store.entity.Cart;
import com.cy.store.entity.Product;
import com.cy.store.mapper.CartMapper;
import com.cy.store.service.ICartService;
import com.cy.store.service.IProductService;
import com.cy.store.service.ex.InsertException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;/** 處理購物車數據的業務層實現類 */
@Service
public class CartServiceImpl implements ICartService {@Autowiredprivate CartMapper cartMapper;@Autowiredprivate IProductService productService;
}

2.在CartServiceImpl類中實現業務層ICartService接口中定義的抽象方法。

@Override
public void addToCart(Integer uid, Integer pid, Integer amount, String username) {// 根據參數pid和uid查詢購物車中的數據// 判斷查詢結果是否為null// 是:表示該用戶并未將該商品添加到購物車// -- 創建Cart對象// -- 封裝數據:uid,pid,amount// -- 調用productService.findById(pid)查詢商品數據,得到商品價格// -- 封裝數據:price// -- 封裝數據:4個日志// -- 調用insert(cart)執行將數據插入到數據表中// 否:表示該用戶的購物車中已有該商品// -- 從查詢結果中獲取購物車數據的id// -- 從查詢結果中取出原數量,與參數amount相加,得到新的數量// -- 執行更新數量
}

3.addToCart(Integer uid, Integer pid, Integer amount, String username)方法的代碼具體實現。

@Override
public void addToCart(Integer uid, Integer pid, Integer amount, String username) {// 根據參數pid和uid查詢購物車中的數據Cart result = cartMapper.findByUidAndPid(uid, pid);Integer cid = result.getCid();Date now = new Date();// 判斷查詢結果是否為nullif (result == null) {// 是:表示該用戶并未將該商品添加到購物車// 創建Cart對象Cart cart = new Cart();// 封裝數據:uid,pid,amountcart.setUid(uid);cart.setPid(pid);cart.setNum(amount);// 調用productService.findById(pid)查詢商品數據,得到商品價格Product product = productService.findById(pid);// 封裝數據:pricecart.setPrice(product.getPrice());// 封裝數據:4個日志cart.setCreatedUser(username);cart.setCreatedTime(now);cart.setModifiedUser(username);cart.setModifiedTime(now);// 調用insert(cart)執行將數據插入到數據表中Integer rows = cartMapper.insert(cart);if (rows != 1) {throw new InsertException("插入商品數據時出現未知錯誤,請聯系系統管理員");}} else {// 否:表示該用戶的購物車中已有該商品// 從查詢結果中獲取購物車數據的idInteger cid = result.getCid();// 從查詢結果中取出原數量,與參數amount相加,得到新的數量Integer num = result.getNum() + amount;// 執行更新數量Integer rows = cartMapper.updateNumByCid(cid, num, username, now);if (rows != 1) {throw new InsertException("修改商品數量時出現未知錯誤,請聯系系統管理員");}}
}

4.在com.cy.store.service包下創建測試類CartServiceTests類,并編寫測試方法。

package com.cy.store.service;
import com.cy.store.entity.Product;
import com.cy.store.service.ex.ServiceException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;@RunWith(SpringRunner.class)
@SpringBootTest
public class CartServiceTests {@Autowiredprivate ICartService cartService;@Testpublic void addToCart() {try {Integer uid = 2;Integer pid = 10000007;Integer amount = 1;String username = "Tom";cartService.addToCart(uid, pid, amount, username);System.out.println("OK.");} catch (ServiceException e) {System.out.println(e.getClass().getSimpleName());System.out.println(e.getMessage());}}
}

5 購物車-添加購物車-控制器

5.1 處理異常

說明:無異常。

5.2 設計請求

????????設計用戶提交的請求,并設計響應的方式。

請求路徑:/carts/add_to_cart

請求參數:Integer pid, Integer amount, HttpSession session

請求類型:POST

響應結果:JsonResult<Void>

5.3 處理請求

1.在com.cy.store.controller包下創建CartController類并繼承自BaseController類,添加@RequestMapping("carts")和@RestController注解;在類中聲明ICartService業務對象,并使用@Autowired注解修飾。

package com.cy.store.controller;
import com.cy.store.service.ICartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("carts")
public class CartController extends BaseController {@Autowiredprivate ICartService cartService;}

2.在CartController類中添加處理請求的addToCart()方法。

@RequestMapping("add_to_cart")
public JsonResult<Void> addToCart(Integer pid, Integer amount, HttpSession session) {// 從Session中獲取uid和usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 調用業務對象執行添加到購物車cartService.addToCart(uid, pid, amount, username);// 返回成功return new JsonResult<Void>(OK);
}

3.完成后啟動項目,先登錄再訪問http://localhost:8080/carts/add_to_cart?pid=10000017&amount=3進行測試。

6 購物車-添加購物車-前端頁面

1.在product.html頁面中的body標簽內的script標簽里為“加入購物車”按鈕添加點擊事件。

$("#btn-add-to-cart").click(function() {$.ajax({url: "/carts/add_to_cart",type: "POST",data: {"pid": id,"amount": $("#num").val()},dataType: "JSON",success: function(json) {if (json.state == 200) {alert("增加成功!");} else {alert("增加失敗!" + json.message);}},error: function(xhr) {alert("您的登錄信息已經過期,請重新登錄!HTTP響應碼:" + xhr.status);location.href = "login.html";}});
});

????????$.ajax函數中參數data提交請參數的方式:

// 1.適用于參數較多,且都在同一個表單中
data: $("#form表單id屬性值").serialize()
// 2.僅適用于上傳文件
data: new FormData($("##form表單id屬性值")[0])
// 3.參數拼接形式提交
data: "pid=10000005&amount=3"
// 4.使用JSON格式提交參數
data: {"pid": 10000005,"amount": 3
}

2.完成后啟動項目,先登錄再訪問http://localhost:8080/web/index.html頁面進行測試。


?顯示購物車列表

1 購物車-顯示列表-持久層

1.1 規劃需要執行的SQL語句

????????顯示某用戶的購物車列表數據的SQL語句大致是。

SELECTcid,uid,pid,t_cart.price,t_cart.num,t_product.title,t_product.price AS realPrice,t_product.image
FROMt_cartLEFT JOIN t_product ON t_cart.pid = t_product.id 
WHEREuid = #{uid}
ORDER BYt_cart.created_time DESC
1.2 接口與抽象方法

1.由于涉及多表關聯查詢,必然沒有哪個實體類可以封裝此次的查詢結果,因此需要創建VO類。創建com.cy.store.vo.CartVO類。

package com.cy.store.vo;
import java.io.Serializable;/** 購物車數據的Value Object類 */
public class CartVO implements Serializable {private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;private String title;private Long realPrice;private String image;// Generate: Getter and Setter、Generate hashCode() and equals()、toString()
}

2.在CartMapper接口中添加抽象方法。

/*** 查詢某用戶的購物車數據* @param uid 用戶id* @return 該用戶的購物車數據的列表*/
List<CartVO> findVOByUid(Integer uid);
1.3 配置SQL映射

1.在CartMapper.xml文件中添加findVOByUid()方法的映射。

<!-- 查詢某用戶的購物車數據:List<CartVO> findVOByUid(Integer uid) -->
<select id="findVOByUid" resultType="com.cy.store.vo.CartVO">SELECTcid,uid,pid,t_cart.price,t_cart.num,t_product.title,t_product.price AS realPrice,t_product.imageFROMt_cartLEFT JOIN t_product ON t_cart.pid = t_product.id WHEREuid = #{uid}ORDER BYt_cart.created_time DESC
</select>

2.在CartMapperTests測試類中添加findVOByUid()方法的測試。

@Test
public void findVOByUid() {List<CartVO> list = cartMapper.findVOByUid(31);System.out.println(list);
}

2 購物車-顯示列表-業務層

2.1 規劃異常

說明:無異常。

2.2 接口與抽象方法

????????在ICartService接口中添加findVOByUid()抽象方法。

/*** 查詢某用戶的購物車數據* @param uid 用戶id* @return 該用戶的購物車數據的列表*/
List<CartVO> getVOByUid(Integer uid);
2.3 實現抽象方法

1.在CartServiceImpl類中重寫業務接口中的抽象方法。

@Override
public List<CartVO> getVOByUid(Integer uid) {return cartMapper.findVOByUid(uid);
}

2.在CartServiceTests測試類中添加getVOByUid()測試方法。

@Test
public void getVOByUid() {List<CartVO> list = cartService.getVOByUid(31);System.out.println("count=" + list.size());for (CartVO item : list) {System.out.println(item);}
}

3 購物車-顯示列表-控制器

3.1 處理異常

說明:無異常。

3.2 設計請求

????????設計用戶提交的請求,并設計響應的方式。

請求路徑:/carts/

請求參數:HttpSession session

請求類型:GET

響應結果:JsonResult<List<CartVO>>

3.3 處理請求

1.在CartController類中編寫處理請求的代碼。

@GetMapping({"", "/"})
public JsonResult<List<CartVO>> getVOByUid(HttpSession session) {// 從Session中獲取uidInteger uid = getUidFromSession(session);// 調用業務對象執行查詢數據List<CartVO> data = cartService.getVOByUid(uid);// 返回成功與數據return new JsonResult<List<CartVO>>(OK, data);
}

2.完成后啟動項目,先登錄再訪問http://localhost:8080/carts請求進行測試。

4 購物車-顯示列表-前端頁面

1.將cart.html頁面的head頭標簽內引入的cart.js文件注釋掉。

<!-- <script src="../js/cart.js" type="text/javascript" charset="utf-8"></script> -->

2.給form標簽添加action="orderConfirm.html"屬性、tbody標簽添加id="cart-list"屬性、結算按鈕的類型改為type="button"值。如果以上屬性值已經添加過無需重復添加。

3.在cart.html頁面body標簽內的script標簽中編寫展示購物車列表的代碼。

$(document).ready(function() {showCartList();
});function showCartList() {$("#cart-list").empty();$.ajax({url: "/carts",type: "GET",dataType: "JSON",success: function(json) {let list = json.data;for (let i = 0; i < list.length; i++) {let tr = '<tr>'+ '<td>'+ 	'<input name="cids" value="#{cid}" type="checkbox" class="ckitem" />'+ '</td>'+ '<td><img src="..#{image}collect.png" class="img-responsive" /></td>'+ '<td>#{title}#{msg}</td>'+ '<td>¥<span id="price-#{cid}">#{realPrice}</span></td>'+ '<td>'+ 	'<input type="button" value="-" class="num-btn" onclick="reduceNum(1)" />'+ 	'<input id="num-#{cid}" type="text" size="2" readonly="readonly" class="num-text" value="#{num}">'+ 	'<input class="num-btn" type="button" value="+" onclick="addNum(#{cid})" />'+ '</td>'+ '<td>¥<span id="total-price-#{cid}">#{totalPrice}</span></td>'+ '<td>'+ 	'<input type="button" onclick="delCartItem(this)" class="cart-del btn btn-default btn-xs" value="刪除" />'+ '</td>'+ '</tr>';tr = tr.replace(/#{cid}/g, list[i].cid);tr = tr.replace(/#{title}/g, list[i].title);tr = tr.replace(/#{image}/g, list[i].image);tr = tr.replace(/#{realPrice}/g, list[i].realPrice);tr = tr.replace(/#{num}/g, list[i].num);tr = tr.replace(/#{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);}}});
}

4.完成后啟動項目,先登錄再訪問http://localhost:8080/web/cart.html頁面進行測試。


增加商品數量

1 購物車-增加商品數量-持久層

1.1 規劃需要執行的SQL語句

1.首先進行查詢需要操作的購物車數據信息。

SELECT * FROM t_cart WHERE cid=?

2.然后計算出新的商品數量值,如果滿足更新條件則執行更新操作。此SQL語句無需重復開發。

UPDATE t_cart SET num=?, modified_user=?, modified_time=? WHERE cid=?

1.2 接口與抽象方法

在CartMapper接口中添加抽象方法。

/*** 根據購物車數據id查詢購物車數據詳情* @param cid 購物車數據id* @return 匹配的購物車數據詳情,如果沒有匹配的數據則返回null*/
Cart findByCid(Integer cid);
1.3 配置SQL映射

1.在CartMapper文件中添加findByCid(Integer cid)方法的映射。

<!-- 根據購物車數據id查詢購物車數據詳情:Cart findByCid(Integer cid) -->
<select id="findByCid" resultMap="CartEntityMap">SELECT*FROMt_cartWHEREcid = #{cid}
</select>

2.在CartMapperTests測試類中添加findByCid()測試方法。

@Test
public void findByCid() {Integer cid = 6;Cart result = cartMapper.findByCid(cid);System.out.println(result);
}

2 購物車-增加商品數量-業務層

2.1 規劃異常

1.如果嘗試訪問的購物車數據不存在,則拋出CartNotFoundException異常。創建com.cy.store.service.ex.CartNotFoundException類。

/** 購物車數據不存在的異常 */
public class CartNotFoundException extends ServiceException {// Override Methods...
}

2.如果嘗試訪問的數據并不是當前登錄用戶的數據,則拋出AccessDeniedException異常。此異常類無需再次創建。

3.最終執行更新操作時,可能會拋出UpdateException異常。此異常類無需再次創建。

2.2 接口與抽象方法

在業務層ICartService接口中添加addNum()抽象方法。

/*** 將購物車中某商品的數量加1* @param cid 購物車數量的id* @param uid 當前登錄的用戶的id* @param username 當前登錄的用戶名* @return 增加成功后新的數量*/
Integer addNum(Integer cid, Integer uid, String username);
2.3 實現抽象方法

1.在CartServiceImpl類中,實現接口中的抽象方法并規劃業務邏輯。

public Integer addNum(Integer cid, Integer uid, String username) {// 調用findByCid(cid)根據參數cid查詢購物車數據// 判斷查詢結果是否為null// 是:拋出CartNotFoundException// 判斷查詢結果中的uid與參數uid是否不一致// 是:拋出AccessDeniedException// 可選:檢查商品的數量是否大于多少(適用于增加數量)或小于多少(適用于減少數量)// 根據查詢結果中的原數量增加1得到新的數量num// 創建當前時間對象,作為modifiedTime// 調用updateNumByCid(cid, num, modifiedUser, modifiedTime)執行修改數量
}

2.實現addNum()方法中的業務邏輯代碼。

@Override
public Integer addNum(Integer cid, Integer uid, String username) {// 調用findByCid(cid)根據參數cid查詢購物車數據Cart result = cartMapper.findByCid(cid);// 判斷查詢結果是否為nullif (result == null) {// 是:拋出CartNotFoundExceptionthrow new CartNotFoundException("嘗試訪問的購物車數據不存在");}// 判斷查詢結果中的uid與參數uid是否不一致if (!result.getUid().equals(uid)) {// 是:拋出AccessDeniedExceptionthrow new AccessDeniedException("非法訪問");}// 可選:檢查商品的數量是否大于多少(適用于增加數量)或小于多少(適用于減少數量)// 根據查詢結果中的原數量增加1得到新的數量numInteger num = result.getNum() + 1;// 創建當前時間對象,作為modifiedTimeDate now = new Date();// 調用updateNumByCid(cid, num, modifiedUser, modifiedTime)執行修改數量Integer rows = cartMapper.updateNumByCid(cid, num, username, now);if (rows != 1) {throw new InsertException("修改商品數量時出現未知錯誤,請聯系系統管理員");}// 返回新的數量return num;
}

3.在CartServiceTests測試類中添加addNum()測試方法。

@Test
public void addNum() {try {Integer cid = 6;Integer uid = 31;String username = "管理員";Integer num = cartService.addNum(cid, uid, username);System.out.println("OK. New num=" + num);} catch (ServiceException e) {System.out.println(e.getClass().getSimpleName());System.out.println(e.getMessage());}
}

3 購物車-增加商品數量-控制器

3.1 處理異常

在BaseController類中添加CartNotFoundException異常類的統一管理。

// ...
else if (e instanceof CartNotFoundException) {result.setState(4007);
}
// ...
3.2 設計請求

設計用戶提交的請求,并設計響應的方式。

請求路徑:/carts/{cid}/num/add

請求參數:@PathVariable("cid") Integer cid, HttpSession session

請求類型:POST

響應結果:JsonResult<Integer>

3.3 處理請求

1.在CartController類中添加處理請求的addNum()方法。

@RequestMapping("{cid}/num/add")
public JsonResult<Integer> addNum(@PathVariable("cid") Integer cid, HttpSession session) {// 從Session中獲取uid和usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 調用業務對象執行增加數量Integer data = cartService.addNum(cid, uid, username);// 返回成功return new JsonResult<Integer>(OK, data);
}

2.完成后啟動項目,先登錄再訪問http://localhost:8080/carts/6/num/add頁面進行測試。

4 購物車-增加商品數量-前端頁面

1.首先確定在showCartList()函數中動態拼接的增加購物車按鈕是綁定了addNum()事件,如果已經添加無需重復添加。

<input class="num-btn" type="button" value="+" onclick="addNum(#{cid})" />

2.在script標簽中定義addNum()函數并編寫增加購物車數量的邏輯代碼。

function addNum(cid) {$.ajax({url: "/carts/" + cid + "/num/add",type: "POST",dataType: "JSON",success: function(json) {if (json.state == 200) {// showCartList();$("#num-" + cid).val(json.data);let price = $("#price-" + cid).html();let totalPrice = price * json.data;$("#total-price-" + cid).html(totalPrice);} else {alert("增加商品數量失敗!" + json.message);}},error: function(xhr) {alert("您的登錄信息已經過期,請重新登錄!HTTP響應碼:" + xhr.status);location.href = "login.html";}});
}

3.完成后啟動項目,先登錄再訪問http://localhost:8080/web/cart.html頁面點擊“+”按鈕進行測試。


顯示勾選的購物車數據

1 顯示確認訂單頁-顯示勾選的購物車數據-持久層

1.1 規劃需要執行的SQL語句

????????在“確認訂單頁”顯示的商品信息,應來自前序頁面(購物車列表)中勾選的數據,所以顯示的信息其實是購物車中的數據。到底需要顯示哪些取決于用戶的勾選操作,當用戶勾選了若干條購物車數據后,這些數據的id應傳遞到當前“確認訂單頁”中,該頁面根據這些id獲取需要顯示的數據列表。

????????所以在持久層需要完成“根據若干個不確定的id值,查詢購物車數據表,顯示購物車中的數據信息”。則需要執行的SQL語句大致是。

SELECTcid,uid,pid,t_cart.price,t_cart.num,t_product.title,t_product.price AS realPrice,t_product.image
FROMt_cartLEFT JOIN t_product ON t_cart.pid = t_product.id 
WHEREcid IN (?, ?, ?)
ORDER BYt_cart.created_time DESC	
1.2 接口與抽象方法

????????在CartMapper接口中添加findVOByCids(Integer[] cids)方法。

/*** 根據若干個購物車數據id查詢詳情的列表* @param cids 若干個購物車數據id* @return 匹配的購物車數據詳情的列表*/
List<CartVO> findVOByCids(Integer[] cids);
1.3 配置SQL映射

1.在CartMapper.xml文件中添加SQL語句的映射配置。

<!-- 根據若干個購物車數據id查詢詳情的列表:List<CartVO> findVOByCids(Integer[] cids) -->
<select id="findVOByCids" resultType="com.cy.store.vo.CartVO">SELECTcid,uid,pid,t_cart.price,t_cart.num,t_product.title,t_product.price AS realPrice,t_product.imageFROMt_cartLEFT JOIN t_product ON t_cart.pid = t_product.idWHEREcid IN (<foreach collection="array" item="cid" separator=",">#{cid}</foreach>)ORDER BYt_cart.created_time DESC
</select>

2.在CartMapperTests測試類中添加findVOByCids()測試方法。

@Test
public void findVOByCids() {Integer[] cids = {1, 2, 6, 7, 8, 9, 10};List<CartVO> list = cartMapper.findVOByCids(cids);System.out.println("count=" + list.size());for (CartVO item : list) {System.out.println(item);}
}

2 顯示確認訂單頁-顯示勾選的購物車數據-業務層

2.1 規劃異常

說明:無異常。

2.2 接口與抽象方法

在ICartService接口中添加getVOByCids()抽象方法。

/*** 根據若干個購物車數據id查詢詳情的列表* @param uid 當前登錄的用戶的id* @param cids 若干個購物車數據id* @return 匹配的購物車數據詳情的列表*/
List<CartVO> getVOByCids(Integer uid, Integer[] cids);
2.3 實現抽象方法

1.在CartServiceImpl類中重寫業務接口中的抽象方法。

@Override
public List<CartVO> getVOByCids(Integer uid, Integer[] cids) {List<CartVO> list = cartMapper.findVOByCids(cids);/**for (CartVO cart : list) {if (!cart.getUid().equals(uid)) {list.remove(cart);}}*/Iterator<CartVO> it = list.iterator();while (it.hasNext()) {CartVO cart = it.next();if (!cart.getUid().equals(uid)) {it.remove();}}return list;
}

2.在CartServiceTests測試類中添加getVOByCids()測試方法。

@Test
public void getVOByCids() {Integer[] cids = {1, 2, 6, 7, 8, 9, 10};Integer uid = 31;List<CartVO> list = cartService.getVOByCids(uid, cids);System.out.println("count=" + list.size());for (CartVO item : list) {System.out.println(item);}
}

3 顯示確認訂單頁-顯示勾選的購物車數據-控制器

3.1 處理異常

說明:無異常。

3.2 設計請求

????????設計用戶提交的請求,并設計響應的方式。

請求路徑:/carts/list

請求參數:Integer[] cids, HttpSession session

請求類型:GET

響應結果:JsonResult<List<CartVO>>

3.3 處理請求

1.在CartController類中添加處理請求的getVOByCids()方法。

@GetMapping("list")
public JsonResult<List<CartVO>> getVOByCids(Integer[] cids, HttpSession session) {// 從Session中獲取uidInteger uid = getUidFromSession(session);// 調用業務對象執行查詢數據List<CartVO> data = cartService.getVOByCids(uid, cids);// 返回成功與數據return new JsonResult<>(OK, data);
}

2.完成后啟動項目,先登錄再訪問http://localhost:8080/carts/list?cids=7&cids=8&cids=13&cids=14&cids=17地址進行測試。

4 顯示確認訂單頁-前端頁面

4.1 顯示勾選的購物車數據-前端頁面

1.在orderConfirm.html頁面的head標簽里注釋掉引入外部的orderConfirm.js文件。

<!-- <script src="../js/orderConfirm.js" type="text/javascript" charset="utf-8"></script> -->

2.在orderConfirm.html頁面中檢查必要控件的屬性是否添加,如果已添加無需重復添加。

3.在orderConfirm.html頁面中的body標簽內的最后添加srcipt標簽并在標簽內部添加處理購物車“訂單商品信息”列表展示的代碼。

<script type="text/javascript">
$(document).ready(function() {// showAddressList();showCartList();
});function showCartList() {$("#cart-list").empty();$.ajax({url: "/carts/list",data: location.search.substr(1),type: "GET",dataType: "JSON",success: function(json) {let list = json.data;console.log("count=" + list.length);let allCount = 0;let allPrice = 0;for (let i = 0; i < list.length; i++) {console.log(list[i].title);let tr = '<tr>'+ '<td><img src="..#{image}collect.png" class="img-responsive" /></td>'+ '<td><input type="hidden" name="cids" value="#{cid}" />#{title}</td>'+ '<td>¥<span>#{realPrice}</span></td>'+ '<td>#{num}</td>'+ '<td>¥<span>#{totalPrice}</span></td>'+ '</tr>';tr = tr.replace(/#{cid}/g, list[i].cid);tr = tr.replace(/#{image}/g, list[i].image);tr = tr.replace(/#{title}/g, list[i].title);tr = tr.replace(/#{realPrice}/g, list[i].realPrice);tr = tr.replace(/#{num}/g, list[i].num);tr = tr.replace(/#{totalPrice}/g, list[i].realPrice * list[i].num);$("#cart-list").append(tr);allCount += list[i].num;allPrice += list[i].realPrice * list[i].num;}$("#all-count").html(allCount);$("#all-price").html(allPrice);}});
}
</script>

4.完成后啟動項目,先登錄再訪問http://localhost:8080/web/cart.html頁面,勾選商品再點擊“結算”按鈕進行測試。

4.2 顯示選擇收貨地址-前端頁面

1.在orderConfirm.html頁面中的body標簽內的srcipt標簽中添加獲取收貨地址列表方法的定義。

function showAddressList() {$("#address-list").empty();$.ajax({url: "/addresses",type: "GET",dataType: "JSON",success: function(json) {let list = json.data;console.log("count=" + list.length);for (let i = 0; i < list.length; i++) {console.log(list[i].name);let opt = '<option value="#{aid}">#{name} | #{tag} | #{province}#{city}#{area}#{address} | #{phone}</option>';opt = opt.replace(/#{aid}/g, list[i].aid);opt = opt.replace(/#{tag}/g, list[i].tag);opt = opt.replace("#{name}", list[i].name);opt = opt.replace("#{province}", list[i].provinceName);opt = opt.replace("#{city}", list[i].cityName);opt = opt.replace("#{area}", list[i].areaName);opt = opt.replace("#{address}", list[i].address);opt = opt.replace("#{phone}", list[i].phone);$("#address-list").append(opt);}}});
}

2.在orderConfirm.html頁面中的body標簽內的srcipt標簽中添加展示收貨地址列表方法的調用。

<script type="text/javascript">$(document).ready(function() {showAddressList();showCartList();});
</script>

3.完成后啟動項目,先登錄再訪問http://localhost:8080/web/orderConfirm.html頁面進行測試。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84710.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84710.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84710.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024-2025學年度下期《網頁設計》期末模擬測試

一、 單選題 1. HTML文檔的根標簽是( ) A. <html> B. <head> C. <body> D. <!DOCTYPE> 2. 用于定義段落內容的標簽是&#xff1a;( ) A. <div> B. <p> C. <span> D. <br> 3. 網以下哪個屬性用于定義CSS內聯樣式…

搭建加解密網站遇到的問

本機向云服務器傳輸文件 用winscp 服務器在安裝 SSH 服務時自動生成密鑰對&#xff08;公鑰私鑰&#xff09; 為什么要有指紋驗證&#xff1f; 防止中間人攻擊&#xff08;Man-in-the-Middle&#xff09; 指紋驗證打破這個攻擊鏈&#xff1a; 小問題 安裝python時 ./confi…

CSS 制作學成在線網頁

1 項目結構 1.1 總結 2 網頁制作思路 3 header 區域 - 布局 3.1 通欄 3.2 logo 3.3 導航 3.4 搜索區域 3.5 用戶區域 4 banner 區域 4.1 左側側導航 4.2 右側課程表 5 精品推薦 6 推薦課程區域 參考鏈接&#xff1a; 82-準備工作-項目目錄與版心_嗶哩嗶哩_bilibili

圖靈完備之路(數電學習三分鐘)----門的多路化

上一章中我們學習了如何用與非門實現其他邏輯門&#xff0c;但上節中的輸入信號始終為2&#xff0c;但在現實中&#xff0c;輸入的信號數量是不確定的&#xff0c;所以我們需要設計多輸入的門&#xff1a; 1.三路與非門&#xff08;卡諾圖法&#xff09; 我們還是從與非門開始…

【前端】二進制文件流下載(get、post)再談一次

最近二進制文件流下載可謂是又出幺蛾子&#xff0c;翻閱以前的文章也找不到解決方案&#xff0c;感覺還是沒用完全理解&#xff0c;這次再整理一遍。 先說一個通用場景&#xff0c;就是無論get還是post在接口請求的時候設定好 headers: { Content-Type: application/json;cha…

uv功能介紹和完整使用示例總結

以下是關于 UV 工具的完整使用示例總結,結合其核心功能與典型場景,幫助用戶快速上手并高效管理 Python 項目: 一、安裝與配置 快速安裝 macOS/Linux:curl -LsSf https://astral.sh/uv/install.sh | shWindows:powershell -ExecutionPolicy ByPass -c "irm https://as…

MySQL啟動報錯“mysqld_safe Directory ‘/var/lib/mysql‘ don‘t exists“終極解決方案!從入門到高階全攻略

在MySQL的使用過程中&#xff0c;啟動報錯mysqld_safe Directory /var/lib/mysql dont exists是開發者經常遇到的問題。這個錯誤看似簡單&#xff0c;實則可能涉及目錄權限、系統配置、文件系統等多個方面。本文將結合官方文檔與實際經驗&#xff0c;從基礎到高級&#xff0c;為…

python 常見數學公式函數使用詳解

Python 數學公式與函數大全 Python 提供了豐富的數學計算支持&#xff0c;包括內置函數、標準庫&#xff08;math、cmath、numpy&#xff09;和第三方庫&#xff08;sympy、scipy&#xff09;。以下是常用數學公式和函數的分類整理&#xff1a; 1. 基本數學運算 1.1 算術運算…

阿里云服務器+寶塔面板發布網站

一、租用服務器 &#xff08;1&#xff09;、進入官網 阿里云-計算&#xff0c;為了無法計算的價值阿里云——阿里巴巴集團旗下公司&#xff0c;是全球領先的云計算及人工智能科技公司之一。提供免費試用、云服務器、云數據庫、云安全、云企業應用等云計算服務&#xff0c;以…

langchain框架中各種Agent(LLMSingleAgent ReactAgent Plan-and-Execute Agent)原理方式對比

在LangChain框架中&#xff0c;LLMSingleActionAgent與ReAct Agent及其他Agent類型在內部原理上存在顯著差異&#xff0c;主要體現在推理機制、行動策略、動態性等方面。以下結合實例進行詳細說明&#xff1a; 1. LLMSingleActionAgent的內部原理 LLMSingleActionAgent是LangC…

AI+預測3D新模型百十個定位預測+膽碼預測+去和尾2025年6月22日第116彈

從今天開始&#xff0c;咱們還是暫時基于舊的模型進行預測&#xff0c;好了&#xff0c;廢話不多說&#xff0c;按照老辦法&#xff0c;重點8-9碼定位&#xff0c;配合三膽下1或下2&#xff0c;殺1-2個和尾&#xff0c;再殺4-5個和值&#xff0c;可以做到100-300注左右。 (1)定…

電池模塊仿真 - 線性時不變降階模型

電池模塊熱設計挑戰 針對使用周期設計電池模塊存在幾個獨特的熱工程挑戰。 使用循環&#xff08;例如駕駛循環&#xff09;涉及可變的負載、速度和環境條件&#xff0c;要求電池在動態壓力下提供一致的性能。管理熱行為至關重要&#xff0c;因為波動的電流會產生熱量&#xf…

408第二季 - 組成原理 - IO方式II

繼續中斷 中斷優先級包括響應優先級和處理優先級 注意下面的&#xff0c;很多都是之前說的 這里的中斷向量的地址&#xff0c;就是下面的很粗的箭頭 一個很復雜的圖 然后記一下很復雜的東西 關中斷&#xff0c;保存斷點和中斷服務程序尋址都是之前講過的 繼續推進&#xff01;…

Spring AOP:橫切關注點的優雅解決方案

目錄 概要 和面向對象編程的區別 優點 AOP的底層原理 JDK動態代理技術 AOP七大術語 切點表達式 AOP實現方式 Spring對AOP的實現包括以下3種方式&#xff1a; 在本篇文章中&#xff0c;我們主要講解前兩種方式。 基于AspectJ的AOP注解式開發 定義目標類以及目標方法…

開源 Arkts 鴻蒙應用 開發(三)Arkts語言的介紹

文章的目的為了記錄使用Arkts 進行Harmony app 開發學習的經歷。本職為嵌入式軟件開發&#xff0c;公司安排開發app&#xff0c;臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 Arkts …

hot100 -- 16.多維動態規劃

1.不同路徑 問題&#xff1a; 一個機器人位于一個 m x n 網格的左上角 &#xff08;起始點在下圖中標記為 “Start” &#xff09;。 機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角&#xff08;在下圖中標記為 “Finish” &#xff09;。 問總共有多少條…

優先級繼承和優先級天花板(pthread_mutexattr_setprotocol)

優先級繼承和優先級天花板&#xff0c;均可以解決優先級翻轉問題。 優先級翻轉&#xff1a; 實例觀察優先級翻轉和優先級繼承現象-CSDN博客 如果有兩個線程A和B&#xff0c;A的優先級大于B的優先級。在B獲取鎖之后&#xff0c;釋放鎖之前&#xff0c;A想要獲取鎖&#xff0c…

Spark on Hive表結構變更

Spark on Hive表結構變更 1、表結構變更概述1、表結構變更概述 在Spark on Hive架構中,表結構(Schema)變更是一個常見且重要的操作。理解其背景、使用場景以及具體方式對于大數據平臺管理至關重要 1.1、Spark on Hive元數據管理 Hive Metastore(HMS): 核心組件。它是一個…

NotePad++ 怎么沒有找到插件管理?

今天想使用NotePad閱讀markdown文檔&#xff0c;卻發現未安裝插件&#xff0c;本想通過插件管理安裝一下&#xff0c;結果沒有插件管理&#xff01;&#xff01;&#xff01;&#xff01; 我發現幫助菜單里面有一個入口 可惜的是網頁無法打開。。。 只能自己下載插件了。 將插件…

內容搜索軟件AnyTXT.Searcher忘記文件名也能搜,全文檢索 1 秒定位文件

各位文件搜索小能手們&#xff01;你們有沒有過這種糟心事兒&#xff0c;想找個文件&#xff0c;死活想不起文件名&#xff0c;在電腦里一頓亂翻&#xff0c;眼睛都找瞎了也沒找到。今天我就給你們介紹一款神器——AnyTXT.Searcher&#xff0c;它可是免費的全文檢索工具&#x…