购物车主要实现了添加商品至购物车、购物车列表、编辑购物车等三个功能,本文主要讲述了新峰商城购物车工作原理及添加商品至购物车功能的实现方法。
一、购物车模块简介
线下超市或商场的购物流程如下:
(1)进入商场
(2)获取购物车或者购物蓝
(3)在商场中四处逛
(4)在不同的区域选择不同的商品
(5)将想购买的商品放入购物车
(6)某些商品需要称重或者其它处理
(7)到收银台清点商品并计算价格
(8)结账
(9)离开商场并回家
新峰商城的购物车是将线下购物车进行抽象而开发一个功能,与线下实体的购物车不同,线上购物车模块的作用是存放商城用户挑选的商品数据。
二、购物车表结构设计
user_id 用户的ID,根据这个字段确定用户购物车中的数据
goods_id 关联的商品ID,根据这个字段查询对应的商品信息并显示到页面上
goods_count 购物车中某件商品的数量
create_time 商品添加到购物车中的时间
三、商品加入购物车功能的实现
数据层
(1)实体类
NewBeeMallShoppingCartItem实体类如下所示:
java
public class NewBeeMallShoppingCartItem{
private Long cartItemId;
private Long userId;
private Long goodsId;
private Integer goodsCount;
private Byte isDeleted;
private Date createTime;
private Date updateTime;
}
(2)Mapper接口
NewBeeMallShoppingCartItemMapper接口代码如下所示:
java
public interface NewBeeMallShoppingCartItemMapper{
//保存一条新记录
int insertSelective(NewBeeMallShoppingCartItem record);
//根据userId和goodsId查询记录
NewBeeMallShoppingCartItem selectByUserIdAndGoodsId(@Param("newBeeMallUserId") Long
newBeeMallUserId,@Param("goodsId") Long goodsId);
//根据userId查询当前用户已添加了多少条记录
int selectCountByUserId(Long newBeeMallUserId);
}
(3)Mapper映射文件
NewBeeMallShoppingCartItemMapper接口映射文件如下所示:
XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="ltd.newbee.mall.dao.NewBeeMallShoppingCartItemMapper">
<resultMap id="BaseResultMap" type="ltd.newbee.mall.entity.NewBeeMallShoppingCartItem">
<id column="cart_item_id" jdbcType="BIGINT" property="cartItemId"/>
<result column="user_id" jdbcType="BIGINT" property="userId"/>
<result column="goods_id" jdbcType="BIGINT" property="goodsId"/>
<result column="goods_count" jdbcType="INTEGER" property="goodsCount"/>
<result column="is_deleted" jdbcType="TINYINT" property="isDeleted"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>
<sql id="Base_Column_List">
cart_item_id, user_id, goods_id, goods_count, is_deleted, create_time, update_time
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from tb_newbee_mall_shopping_cart_item
where cart_item_id = #{cartItemId,jdbcType=BIGINT} and is_deleted = 0
</select>
<select id="selectByUserIdAndGoodsId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from tb_newbee_mall_shopping_cart_item
where user_id = #{newBeeMallUserId,jdbcType=BIGINT} and goods_id=#{goodsId,jdbcType=BIGINT} and is_deleted = 0
limit 1
</select>
<select id="selectByUserId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from tb_newbee_mall_shopping_cart_item
where user_id = #{newBeeMallUserId,jdbcType=BIGINT} and is_deleted = 0
limit #{number}
</select>
<select id="selectCountByUserId" resultType="int">
select
count(*)
from tb_newbee_mall_shopping_cart_item
where user_id = #{newBeeMallUserId,jdbcType=BIGINT} and is_deleted = 0
</select>
<update id="deleteByPrimaryKey" parameterType="java.lang.Long">
update tb_newbee_mall_shopping_cart_item set is_deleted = 1
where cart_item_id = #{cartItemId,jdbcType=BIGINT} and is_deleted = 0
</update>
<update id="deleteBatch">
update tb_newbee_mall_shopping_cart_item
set is_deleted=1 where cart_item_id in
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<insert id="insert" parameterType="ltd.newbee.mall.entity.NewBeeMallShoppingCartItem">
insert into tb_newbee_mall_shopping_cart_item (cart_item_id, user_id, goods_id,
goods_count, is_deleted, create_time,
update_time)
values (#{cartItemId,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{goodsId,jdbcType=BIGINT},
#{goodsCount,jdbcType=INTEGER}, #{isDeleted,jdbcType=TINYINT}, #{createTime,jdbcType=TIMESTAMP},
#{updateTime,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="ltd.newbee.mall.entity.NewBeeMallShoppingCartItem">
insert into tb_newbee_mall_shopping_cart_item
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="cartItemId != null">
cart_item_id,
</if>
<if test="userId != null">
user_id,
</if>
<if test="goodsId != null">
goods_id,
</if>
<if test="goodsCount != null">
goods_count,
</if>
<if test="isDeleted != null">
is_deleted,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="updateTime != null">
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="cartItemId != null">
#{cartItemId,jdbcType=BIGINT},
</if>
<if test="userId != null">
#{userId,jdbcType=BIGINT},
</if>
<if test="goodsId != null">
#{goodsId,jdbcType=BIGINT},
</if>
<if test="goodsCount != null">
#{goodsCount,jdbcType=INTEGER},
</if>
<if test="isDeleted != null">
#{isDeleted,jdbcType=TINYINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
#{updateTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<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="updateByPrimaryKey" parameterType="ltd.newbee.mall.entity.NewBeeMallShoppingCartItem">
update tb_newbee_mall_shopping_cart_item
set user_id = #{userId,jdbcType=BIGINT},
goods_id = #{goodsId,jdbcType=BIGINT},
goods_count = #{goodsCount,jdbcType=INTEGER},
is_deleted = #{isDeleted,jdbcType=TINYINT},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where cart_item_id = #{cartItemId,jdbcType=BIGINT}
</update>
</mapper>
业务层
(1)接口
NewBeeMallShoppingCartService接口主要代码如下所示:
java
public interface NewBeeMallShoppingCartService{
//保存商品至购物车中
String saveNewBeeMallCartItem(NewBeeMallShoppingCartItem newBeeMall);
}
(2)实现
NewBeeMallShoppingCartService实现主要代码如下所示:
java
@Service
public class NewBeeMallShoppingCartServiceImpl implements NewBeeMallShoppingCartService{
@Autowired
private NewBeeMallShoppingCartItemMapper newBeeMallShoppingCartItemMapper;
@Autowired
private NewBeeMallGoodsMapper newBeeMallGoodsMapper;
@Override
public String saveNewBeeMallCartItem(NewBeeMallShoppingCartItem newBeeMallShoppingCartItem){
NewBeeMallShoppingCartItem temp=NewBeeMallShoppingCartItemMapper.selectByUserIdAndGoodsId(newBeeMallShoppingCartItem.getId(),newBeeMallShoppingCartItem.getGoodsId());
if(temp!=null){
return "购物车中已存在";
}
NewBeeMallGoods newBeeMallGoods=newBeeMallGoodsMapper.selectByPrimaryKey(newBeeMallShoppingCartItem.getGoodsId());
//商品为空
if(newBeeMallGoods==null){
return ServiceResultEnum.GOODS_NOT_EXIST.getResult();
}
int totalItem=newBeeMallShoppingCartItemMapper.selectCountByUserId(NewBeeMallShoppingCartItem.getUserId())+1;
//超出单个商品的最大数量
if(NewBeeMallShoppingCartItem.getGoodsCount()>Constants.SHOPPING_CART_ITEM_LIMIT_NUMBER) {return ServiceResultEnum.SHOPPING_CART_ITEM_LIMIT_NUMBER_ERROR.getResult(); }
//超出最大数量
if(totalItem>Constants.SHOPPING_CART_ITEM_TOTAL_NUMBER){
return ServiceResultEnum.SHOPPING_CART_ITEM_TOTAL_ERROR_NUMBER.getResult(); }
//保存记录
if(newBeeMallShoppingCartItemMapper.insertSelective(newBeeMallShoppingCartItem)>0){
return ServiceResultEnum.SUCCESS.getResult();
}
return ServiceResultEnum.DB_ERROR.getResult();
}
}
代码先对参数进行校验,校验步骤如下所示:
(1)根据用户信息和商品信息查询购物项表中是否已存在相同的记录,如存在则修改,不存在则进行后续操作。
(2)判断商品数据是否正确
(3)判断用户的购物车中的商吕数量是否已超出最大限制
在校验通过后再进行新增操作,将此记录保存到数据库中。
控制层
java
@Controller
public class ShoppingCartController {
@Resource
private NewBeeMallShoppingCartService newBeeMallShoppingCartService;
@PostMapping("/shop-cart")
@ResponseBody
public Result saveNewBeeMallShoppingCartItem(@RequestBody NewBeeMallShoppingCartItem newBeeMallShoppingCartItem,
HttpSession httpSession) {
NewBeeMallUserVO user = (NewBeeMallUserVO) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
newBeeMallShoppingCartItem.setUserId(user.getUserId());
String saveResult = newBeeMallShoppingCartService.saveNewBeeMallCartItem(newBeeMallShoppingCartItem);
//添加成功
if (ServiceResultEnum.SUCCESS.getResult().equals(saveResult)) {
return ResultGenerator.genSuccessResult();
}
//添加失败
return ResultGenerator.genFailResult(saveResult);
}
}
前端
添加商品到购物车功能交互是在商品详情页中实现,在此页面中有"加入购物车"的按钮,单击此按钮执行saveToCart()方法,详情页detail.html模板文件中按钮代码如下所示:
html
<input class="car" type="button" th:onclick="'saveToCart('+${goodsDetail.goodsId}+')'" value="加入购物车"/>
saveToCart() 代码如下所示:
javascript
<script type="text/javascript">
/**
* 添加到购物车
*/
function saveToCart(id) {
var goodsCount = 1;
var data = {
"goodsId": id,
"goodsCount": goodsCount
};
$.ajax({
type: 'POST',
url: '/shop-cart',
contentType: 'application/json',
data: JSON.stringify(data),
success: function (result) {
if (result.resultCode == 200) {
Swal.fire({
title: "确认框",
text: "添加成功",
icon: "success",iconColor:"#1d953f",
showCancelButton: true,
confirmButtonText: '确认',
cancelButtonText: '取消'
}).then((flag) => {
if (flag.value) {
window.location.reload();
}
}
);
} else {
Swal.fire({
text: result.message,
icon: "error",iconColor:"#f05b72",
});
}
},
error: function () {
Swal.fire({
text: "操作失败",
icon: "error",iconColor:"#f05b72",
});
}
});
}
</script>
代码执行逻辑如下所示:
(1)封闭参数,主要是商品id和商品数量,商品数量默认为1
(2)向后端添加购物车接口发送请求
(3)根据返回数据弹出提示信息