新峰商城之购物车(三)
在购物车列表中可以编辑需要购买的商品数量,也可以将商品从购物车中删除,本文将简述以上两个功能的实现过程和代码。
一、数据层
在Mapper接口的NewBeeMallShoppingCartItemMapprer.java增加方法如下:
//根据主键查询记录
NewBeeMallShoppingCartItem selectByPrimaryKey(Long cartItemId);
//修改记录
int updateByPrimaryKeySelective(NewBeeMallShoppingCartItem record);
//删除记录
int deleteByPrimaryKey(Long cartItemId);
在映射文件NewBeeMallShoppingCartItemMapprer.xml中增加代码如下:
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">select<include refid="Base_Column_List"/>from tb_newbee_mall_shopping_cart_itemwhere cart_item_id = #{cartItemId,jdbcType=BIGINT} and is_deleted = 0
</select><update id="updateByPrimaryKeySelective" parameterType="ltd.newbee.mall.entity.NewBeeMallShoppingCartItem">update tb_newbee_mall_shopping_cart_item<set><if test="userId != null">user_id = #{userId,jdbcType=BIGINT},</if><if test="goodsId != null">goods_id = #{goodsId,jdbcType=BIGINT},</if><if test="goodsCount != null">goods_count = #{goodsCount,jdbcType=INTEGER},</if><if test="isDeleted != null">is_deleted = #{isDeleted,jdbcType=TINYINT},</if><if test="createTime != null">create_time = #{createTime,jdbcType=TIMESTAMP},</if><if test="updateTime != null">update_time = #{updateTime,jdbcType=TIMESTAMP},</if></set>where cart_item_id = #{cartItemId,jdbcType=BIGINT}
</update><update id="deleteByPrimaryKey" parameterType="java.lang.Long">update tb_newbee_mall_shopping_cart_item set is_deleted = 1where cart_item_id = #{cartItemId,jdbcType=BIGINT} and is_deleted = 0
</update>
二、业务层
在业务类NewBeeMallShoppingCartService中增加如下方法:
/*** 修改购物车中的属性** @param newBeeMallShoppingCartItem* @return*/
String updateNewBeeMallCartItem(NewBeeMallShoppingCartItem newBeeMallShoppingCartItem);/*** 删除购物车中的商品*** @param shoppingCartItemId* @param userId* @return*/
Boolean deleteById(Long shoppingCartItemId, Long userId);
在业务实现类NewBeeMallShoppingCartServiceImpl中增加如下方法:
@Override
public String updateNewBeeMallCartItem(NewBeeMallShoppingCartItem newBeeMallShoppingCartItem) {NewBeeMallShoppingCartItem newBeeMallShoppingCartItemUpdate = newBeeMallShoppingCartItemMapper.selectByPrimaryKey(newBeeMallShoppingCartItem.getCartItemId());if (newBeeMallShoppingCartItemUpdate == null) {return ServiceResultEnum.DATA_NOT_EXIST.getResult();}//超出单个商品的最大数量if (newBeeMallShoppingCartItem.getGoodsCount() > Constants.SHOPPING_CART_ITEM_LIMIT_NUMBER) {return ServiceResultEnum.SHOPPING_CART_ITEM_LIMIT_NUMBER_ERROR.getResult();}//当前登录账号的userId与待修改的cartItem中userId不同,返回错误if (!newBeeMallShoppingCartItemUpdate.getUserId().equals(newBeeMallShoppingCartItem.getUserId())) {return ServiceResultEnum.NO_PERMISSION_ERROR.getResult();}//数值相同,则不执行数据操作if (newBeeMallShoppingCartItem.getGoodsCount().equals(newBeeMallShoppingCartItemUpdate.getGoodsCount())) {return ServiceResultEnum.SUCCESS.getResult();}newBeeMallShoppingCartItemUpdate.setGoodsCount(newBeeMallShoppingCartItem.getGoodsCount());newBeeMallShoppingCartItemUpdate.setUpdateTime(new Date());//修改记录if (newBeeMallShoppingCartItemMapper.updateByPrimaryKeySelective(newBeeMallShoppingCartItemUpdate) > 0) {return ServiceResultEnum.SUCCESS.getResult();}return ServiceResultEnum.DB_ERROR.getResult();}@Override
public Boolean deleteById(Long shoppingCartItemId, Long userId) {NewBeeMallShoppingCartItem newBeeMallShoppingCartItem = newBeeMallShoppingCartItemMapper.selectByPrimaryKey(shoppingCartItemId);if (newBeeMallShoppingCartItem == null) {return false;}//userId不同不能删除if (!userId.equals(newBeeMallShoppingCartItem.getUserId())) {return false;}return newBeeMallShoppingCartItemMapper.deleteByPrimaryKey(shoppingCartItemId) > 0;}
updateNewMallCartItem()方法,首先对参数进行校验,校验步骤如下所示:
(1)首先根据前端传参的购物项主键id查询购物项表中是否存在记录,若不存在则返回错误信息,若存在则继续操作。
(2)判断用户购物车中的商品数量是否已超出最大限制
在校验通过后再进行修改操作,将此购物项的数量和时间进行修改。
deleteById()方法将此购物项的is_deleted字段修改为1,并非物理删除,而是逻辑删除。
三、控制层
在ShoppingCartController中增加修改购物项和删除购物项两个方法,代码如下所示:
//修改购物项@PutMapping("/shop-cart")@ResponseBodypublic Result updateNewBeeMallShoppingCartItem(@RequestBody NewBeeMallShoppingCartItem newBeeMallShoppingCartItem,HttpSession httpSession) {NewBeeMallUserVO user = (NewBeeMallUserVO) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);newBeeMallShoppingCartItem.setUserId(user.getUserId());String updateResult = newBeeMallShoppingCartService.updateNewBeeMallCartItem(newBeeMallShoppingCartItem);//修改成功if (ServiceResultEnum.SUCCESS.getResult().equals(updateResult)) {return ResultGenerator.genSuccessResult();}//修改失败return ResultGenerator.genFailResult(updateResult);}//删除购物项@DeleteMapping("/shop-cart/{newBeeMallShoppingCartItemId}")@ResponseBodypublic Result updateNewBeeMallShoppingCartItem(@PathVariable("newBeeMallShoppingCartItemId") Long newBeeMallShoppingCartItemId,HttpSession httpSession) {NewBeeMallUserVO user = (NewBeeMallUserVO) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);Boolean deleteResult = newBeeMallShoppingCartService.deleteById(newBeeMallShoppingCartItemId,user.getUserId());//删除成功if (deleteResult) {return ResultGenerator.genSuccessResult();}//删除失败return ResultGenerator.genFailResult(ServiceResultEnum.OPERATE_ERROR.getResult());}
在此Controller类中有几个方法的路径都是/shop-cart,不同的请求方法就是接口的区分方式,POST方法是新增接口,GET方法是购物车列表项页面显示,PUT方法是修改接口,DELETE是购物项删除接口。
编辑功能主要是修改购物项的数量,后端编辑接口负责接收前端传入的cartItemId和goodsCount参数,根据这两个参数修改购物项的数量值。
删除功能主要是进行购物项的逻辑删除,后端删除接口负责接收cartItemId 参数,根据此参数修改购物项的is_deleted的值为1。
四、前端
修改数量按钮的实现逻辑通过列表中商品数量 input框的onblur()事件类实现,首先给商品数量输入框绑定onblur事件,代码如下:
<input class="goods_count" th:id="${'goodsCount'+item.cartItemId}"type="number" th:onblur="'updateItem('+${item.cartItemId}+')'"th:value="${item.goodsCount}" step="1" max="5">
当用户鼠标焦点离开input输入框时就会触发updateItem()方法,此方法会向后端发送修改购物数量的请求,在cart.html模板文件中新增代码如下所示:
/***更新购物项*/function updateItem(id) {var domId = 'goodsCount' + id;var goodsCount = $("#" + domId).val();if (goodsCount > 5) {Swal.fire({text: "单个商品最多可购买5个",icon: "error",iconColor:"#f05b72",});return;}if (goodsCount < 1) {Swal.fire({text: "数量异常",icon: "error",iconColor:"#f05b72",});return;}var data = {"cartItemId": id,"goodsCount": goodsCount};$.ajax({type: 'PUT',url: '/shop-cart',contentType: 'application/json',data: JSON.stringify(data),success: function (result) {if (result.resultCode == 200) {window.location.reload();} else {Swal.fire({text: "操作失败",icon: "error",iconColor:"#f05b72",});}},error: function () {Swal.fire({text: "操作失败",icon: "error",iconColor:"#f05b72",});}});}
此方法具体执行步骤如下所示:
(1)获取购物项主键id和修改后的数量
(2)进行基本的正则验证,修改数量不能大于5且不小于1
(3)向后端购物项修改接口发送请求
(4)根据接口回调进行后续操作
每个购物项的显示区都有一个删除按钮,删除按钮也绑定触发事件,绑定的方法是delteItem(),在cart.html模板文件中的购物项列表区域增加代码如下所示:
<div class="sub_content fl"><a href="##" th:onclick="'deleteItem('+${item.cartItemId}+')'">×</a>
deleteItem()方法的代码如下所示:
/*** * 删除购物项* @param id*/function deleteItem(id) {Swal.fire({title: "确认弹框",text: "确认要删除数据吗?",icon: "warning",iconColor:"#dea32c",showCancelButton: true,confirmButtonText: '确认',cancelButtonText: '取消'}).then((flag) => {if (flag.value) {$.ajax({type: 'DELETE',url: '/shop-cart/' + id,success: function (result) {if (result.resultCode == 200) {window.location.reload();} else {Swal.fire({text: "操作失败",icon: "error",iconColor:"#f05b72",});}},error: function () {Swal.fire({text: "操作失败",icon: "error",iconColor:"#f05b72",});}});}});
}
此方法在让用户确认后,获取需要删除的购物项id并向后端发送删除请求,后端执行逻辑删除操作,传送操作信息至前端,失败则返回错误信息,成功则刷新页面,完成删除操作。