目录

一、自定义的参数解析器

在使用自定义的参数解析器之前的做法:

使用自定义的参数解析器之后的做法:

二、购物车后台

1.定义购物车对象ShopCar

 2.web层定义ShopCarController.java

三、商品详情页面实现

四、购物车查询以及新增的前台

五、购物车删除功能和修改功能

删除

修改


上节内容完成了首页以及登录的功能,登录之后弹出“OK”提示,忘记实现自动跳页面了,这里先继续简单完善一下,比较简单:

 login.js:

springBoot将购物车数据添加入redis springboot购物车功能_mybatis

 再次去登录成功之后就会自动跳转回主页并且绑定了用户名:

springBoot将购物车数据添加入redis springboot购物车功能_User_02

OK,进入今日主题:

一、自定义的参数解析器

在使用自定义的参数解析器之前的做法:

shopCarController :

package com.ycx.spbootpro.controller;

import com.ycx.spbootpro.exception.BusinessException;
import com.ycx.spbootpro.model.User;
import com.ycx.spbootpro.service.IRedisService;
import com.ycx.spbootpro.utils.JsonResponseBody;
import com.ycx.spbootpro.utils.JsonResponseStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 杨总
 * @create 2022-11-07 18:28
 */
@RestController
@RequestMapping("/shopCar")
public class shopCarController {
    @Autowired
    private IRedisService redisService;

    /**
     * 使用参数解析器之前的做法 弊端:
     * 在每一个需要登录之后才能操作的功能,都需要做用户登录验证,即以下代码都需要再写一遍
     * @param token
     * @return
     */
    @RequestMapping("/check")
    public JsonResponseBody check(@CookieValue("token") String token){
       if(token==null)
           throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
            User user=redisService.getUserByToken(token);
       if(user==null)
           throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
            return new JsonResponseBody();
    }

}

 弊端:
     在每一个需要登录之后才能操作的功能,都需要做用户登录验证,即以下代码都需要再写一遍

运行时,点击加入购物车

会出现关于Mybatis-plus时间字段代码生成问题

springBoot将购物车数据添加入redis springboot购物车功能_java_03

 org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])"{"@class":"com.zking.testspbootpro.model.User","nickname":"小胖","password":"6502cbf0ac7d357831536b119ff26d28","salt":"7ceff545c6944e5cb7da355ae6243939","registerDate":{"month":"DECEMBER","year":2021,"dayOfMonth":11,"hour":2,"minute":36,"monthValue":12,"nano":0,"second":56,"dayOfWeek":"SATURDAY","dayOfYear":345,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}},"lastLoginDate":null,"loginCount":0}"; line: 1, column: 172] (through reference chain: com.zking.testspbootpro.model.User["registerDate"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])"{"@class":"com.zking.testspbootpro.model.User","nickname":"小胖","password":"6502cbf0ac7d357831536b119ff26d28","salt":"7ceff545c6944e5cb7da355ae6243939","registerDate":{"month":"DECEMBER","year":2021,"dayOfMonth":11,"hour":2,"minute":36,"monthValue":12,"nano":0,"second":56,"dayOfWeek":"SATURDAY","dayOfYear":345,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}},"lastLoginDate":null,"loginCount":0}"; line: 1, column: 172] (through reference chain: com.zking.testspbootpro.model.User["registerDate"])

 出现上述错误,原因是使用了lastLoginDate,去User.java类,将其改成java.util.Date;

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_04

改完之后将redis中的数据以及cookie中的数据清空,再次登录测试;

 此外我们还要在User类里面添加一个id属性,因为后面有需要涉及到:

package com.ycx.spbootpro.model;

import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.Date;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * <p>
 * 用户信息表
 * </p>
 *
 * @author yangzong
 * @since 2022-11-05
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
public class User implements Serializable {

    private Long id;

    /**
     * 昵称
     */
    private String nickname;

    /**
     * MD5(MD5(pass明文+固定salt)+salt)
     */
    private String password;

    /**
     * 随机salt
     */
    private String salt;

    /**
     * 注册时间
     */
    private Date registerDate;

    /**
     * 最后一次登录时间
     */
    private Date lastLoginDate;

    /**
     * 登录次数
     */
    private Integer loginCount;


}

 使用自定义的参数解析器之后的做法:

shopCarController更改之后 :

package com.ycx.spbootpro.controller;

import com.ycx.spbootpro.exception.BusinessException;
import com.ycx.spbootpro.model.User;
import com.ycx.spbootpro.service.IRedisService;
import com.ycx.spbootpro.utils.JsonResponseBody;
import com.ycx.spbootpro.utils.JsonResponseStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 杨总
 * @create 2022-11-07 18:28
 */
@RestController
@RequestMapping("/shopCar")
public class shopCarController {
    @Autowired
    private IRedisService redisService;


    @RequestMapping("/check")
    public JsonResponseBody check(User user){
        return new JsonResponseBody();
    }
}

UserArgumentResovler : 

package com.ycx.spbootpro.config;

import com.ycx.spbootpro.exception.BusinessException;
import com.ycx.spbootpro.model.User;
import com.ycx.spbootpro.service.IRedisService;
import com.ycx.spbootpro.utils.CookieUtils;
import com.ycx.spbootpro.utils.JsonResponseStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 杨总
 * @create 2022-11-07 19:14
 *
 * 凡是实现HandlerMethodArgumentResolver接口的类都是参数解析器类
 */


@Component
public class UserArgumentResovler implements HandlerMethodArgumentResolver {
        @Autowired
        private IRedisService redisService;
    /**
     * supportsParameter方法的返回值,
     * true:则会调用下面resolveArgument
     * false:则不调用
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType() == User.class;
    }


    /**
     * resolveArgument:具体的业务代码处理
     * @param methodParameter
     * @param modelAndViewContainer
     * @param nativeWebRequest
     * @param webDataBinderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request =(HttpServletRequest) nativeWebRequest.getNativeRequest();
        String token = CookieUtils.getCookieValue(request, "token");
        if(token==null)
            throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
        User user=redisService.getUserByToken(token);
        if(user==null)
            throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
        return user;
    }
}

WebConfig :

package com.ycx.spbootpro.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * @author 杨总
 * @create 2022-11-07 19:37
 *
 * WebMvcConfigurer添加之后,会覆盖application.yml中静态资源映射
 * mvc:
 *         static-path-pattern: /static/**
 */

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private UserArgumentResovler userArgumentResovler;

    /**
     * 将对应的解析器添加到配置中
     * 配置静态资源访问映射,使用了WebMvcConfigurer会覆盖原有的application.yml文件中的静态资源配置
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }

    /**
     * 添加自定义的参数解析器
     * @param resolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(userArgumentResovler);
    }
}

测试:

springBoot将购物车数据添加入redis springboot购物车功能_User_05

 

springBoot将购物车数据添加入redis springboot购物车功能_java_06

 然后去进行登录之后,再点击去购物车:

目前是404,因为queryShopCar页面还没有编写

springBoot将购物车数据添加入redis springboot购物车功能_java_07

 但是此时redis已经存在用户的值了(如下图):

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_08

经过测试,我们会发现,凡是controller中的方法中包含参数User,都会进参数解析器UserArgumentResovler中的resolveArgument方法;这样一定程度下可以减少用户信息登录检验;

当然,我们也可以通过拦截器、过滤器、aop等方式,来解决这一类问题。

二、购物车后台

购物车明细

 ShopCarItem :

package com.ycx.spbootpro.model.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 杨总
 * @create 2022-11-07 22:01
 *
 * 购物车明细
 */

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ShopCarItem {

    private Long gid;//商品id
    private String goodsName;//名称
    private String goodsImg;//图片
    private BigDecimal goodsPrice;//价格
    private Integer quantity;//数量

    /**
     * 这是个虚拟方法,用于计算商品的小计
     * 公式:商品的单价*数量=小计
     * @return
     */
    public BigDecimal smalltotal(){
        BigDecimal num=new BigDecimal(quantity);
        return goodsPrice.multiply(num);
    }
}

1.定义购物车对象ShopCar

1.1购物车中商品集合
定义购物车商品详情对象ShopCarItem
商品ID/商品名称/商品单价/商品图片/商品数量/小计计算方法
1.2加入购物车
1.3删除购物车中指定商品
1.4更新购物车中商品数量
1.5清空购物车
1.6总价计算

package com.ycx.spbootpro.model.vo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;

/**
 * @author 杨总
 * @create 2022-11-07 22:00
 *
 * vo:view object
 *
 * 购物车对象
 */
public class ShopCar {
    //    1.1购物车中商品集合
    private List<ShopCarItem> items=new ArrayList<>();

    public List<ShopCarItem> getItems() {
        return items;
    }

    public void setItems(List<ShopCarItem> items) {
        this.items = items;
    }

    //    1.2加入购物车(增加)
    public void add(ShopCarItem shopCarItem) {
        //循环遍历购物车集合
        for (ShopCarItem item : items) {
            //判断加入购物车中的商品ID与购物车中的商品ID是否一致
            if (item.getGid().equals(shopCarItem.getGid()+"")) {
                //获取购物车中原有商品的数量,再进行+1
                Integer num = item.getQuantity();
                item.setQuantity(num + 1);
//              item.setQuantity(item.getQuantity()+1);
                return;
            }
        }
        //加入购物车
        items.add(shopCarItem);
    }

    //    1.3删除购物车中指定商品(删除)
    public void delete(String gids) {
        //将gids分割后转换成List集合
        List<String> ids = Arrays.asList(gids.split(","));
        //获取商品集合迭代器对象
        ListIterator<ShopCarItem> it = items.listIterator();
        //循环遍历迭代器
        while (it.hasNext()) {
            //获取迭代器元素并移动下标
            ShopCarItem shopCarItem = it.next();
            //判断购物车中的商品ID是否在被删除商品的ID集合中
            if (ids.contains(shopCarItem.getGid() + "")) {
                //删除商品
                it.remove();
            }
        }
    }

    //    1.4更新购物车中商品数量(修改)
    public void update(ShopCarItem shopCarItem) {
        //循环遍历购物车集合
        for (ShopCarItem item : items) {
            //判断加入购物车中的商品ID与购物车中的商品ID是否一致
            if (item.getGid().equals(shopCarItem.getGid())) {
                //将更新的商品数量覆盖购物车中对应商品的数量
                item.setQuantity(shopCarItem.getQuantity());
                break;
            }
        }
    }

    //    1.5清空购物车
    public void clear() {
        items.clear();
    }

    //    1.6总价计算
    public BigDecimal total() {
        BigDecimal total = new BigDecimal(0);
        for (ShopCarItem item : items) {
            total = total.add(item.smalltotal());
        }
        return total;
    }

}

  2.web层定义ShopCarController.java

1) 从session中获取购物车对象ShopCar
注:根据当前登陆用户ID绑定购物车,确保一人一车
2) 加入购物车方法
3) 查询购物车商品方法
4) 删除购物车指定商品方法
5) 更新购物车商品数量方法

package com.ycx.spbootpro.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycx.spbootpro.exception.BusinessException;
import com.ycx.spbootpro.model.Goods;
import com.ycx.spbootpro.model.User;
import com.ycx.spbootpro.model.vo.ShopCar;
import com.ycx.spbootpro.model.vo.ShopCarItem;
import com.ycx.spbootpro.service.IGoodsService;
import com.ycx.spbootpro.service.IRedisService;
import com.ycx.spbootpro.utils.JsonResponseBody;
import com.ycx.spbootpro.utils.JsonResponseStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author 杨总
 * @create 2022-11-07 18:28
 */
@Controller
@RequestMapping("/shopCar")
public class shopCarController {
    @Autowired
    private IRedisService redisService;

    @ResponseBody
    @RequestMapping("/check")
    public JsonResponseBody check(User user) {
        return new JsonResponseBody();
    }

    //    从session中获取购物车对象
    private ShopCar getShopCar(User user, HttpServletRequest request) {
        HttpSession session = request.getSession();
        ShopCar shopCar = (ShopCar) session.getAttribute(user.getId() + "_shopCar");
        if (shopCar == null) {
            shopCar = new ShopCar();
            session.setAttribute(user.getId() + "_shopCar", shopCar);
        }
        return shopCar;
    }

    //    查询
    @RequestMapping("/queryShopCar")
    public ModelAndView queryShopCar(User user,
                                     HttpServletRequest request,
                                     HttpServletResponse resp) {
        ModelAndView mv = new ModelAndView();
        ShopCar shopCar = getShopCar(user, request);
        mv.addObject("shopCar", shopCar);
        mv.setViewName("cart.html");
        return mv;
    }


    @Autowired
    private IGoodsService goodsService;

    /**
     * 增加
     * @param user
     * @param request
     * @param resp
     * @param gid
     * @return
     */
    @ResponseBody
    @RequestMapping("/add")
    public JsonResponseBody add(User user,
                                HttpServletRequest request,
                                HttpServletResponse resp,
                                Long gid) {

        ModelAndView mv = new ModelAndView();
        ShopCar shopCar = getShopCar(user, request);
        Goods goods = goodsService.getOne(new QueryWrapper<Goods>().eq("gid", gid));
//       初始化商品详情ShopCarItem
        ShopCarItem item = new ShopCarItem();
        item.setQuantity(1);
        item.setGid(goods.getGid());
        item.setGoodsImg(goods.getGoodsImg());
        item.setGoodsName(goods.getGoodsName());
        item.setGoodsPrice(goods.getGoodsPrice());
        //加入购物车
        shopCar.add(item);
       
        return new JsonResponseBody<>();
    }

    /**
     * 修改
     * @param user
     * @param request
     * @param resp
     * @param shopCarItem
     * @return
     */
    @ResponseBody
    @RequestMapping("/update")
    public JsonResponseBody update(User user,
                                HttpServletRequest request,
                                HttpServletResponse resp,
                               ShopCarItem shopCarItem) {

        ModelAndView mv = new ModelAndView();
        ShopCar shopCar = getShopCar(user, request);
        //加入购物车
        shopCar.update(shopCarItem);
        return new JsonResponseBody<>();
    }


    /**
     * 删除购物车中指定的商品
     * @param user 用户对象
     * @param gids 商品ID
     * @param request
     * @return
     */
    @RequestMapping("/delete")
    @ResponseBody
    public JsonResponseBody<?> delete(User user,
                                      HttpServletRequest request,
                                      HttpServletResponse resp,
                                      String gids){
        ModelAndView mv = new ModelAndView();
        //从session中获取购物车对象
        ShopCar shopCar = getShopCar(user, request);
        //更新商品数量
        shopCar.delete(gids);
        return new JsonResponseBody<>();
    }

}

三、商品详情页面实现

index.html修改如下:

<!DOCTYPE html>
<html>
	<head lang="en">
		<#include "common/head.html" />
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/index.css" />
	</head>
	<div>
		<!------------------------------head------------------------------>
		<#include "common/top.html" />

		<!-------------------------banner--------------------------->
		<div class="block_home_slider">
			<div id="home_slider" class="flexslider">
				<ul class="slides">
					<li>
						<div class="slide">
							<img src="img/banner2.jpg"/>
						</div>
					</li>
					<li>
						<div class="slide">
							<img src="img/banner1.jpg"/>
						</div>
					</li>
				</ul>
			</div>
		</div>
		
		<!------------------------------thImg------------------------------>
		<div class="thImg">
			<div class="clearfix">
				<a href="${ctx}/page/vase_proList.html"><img src="img/i1.jpg"/></a>
				<a href="${ctx}/page/proList.html"><img src="img/i2.jpg"/></a>
				<a href="#2"><img src="img/i3.jpg"/></a>
			</div>
		</div>
		
		<!------------------------------news------------------------------>
		<div class="news">
			<div class="wrapper">
				<h2><img src="img/ih1.jpg"/></h2>
				<div class="top clearfix">
					<a href="${ctx}/page/proDetail.html"><img src="img/n1.jpg"/><p></p></a>
					<a href="${ctx}/page/proDetail.html"><img src="img/n2.jpg"/><p></p></a>
					<a href="${ctx}/page/proDetail.html"><img src="img/n3.jpg"/><p></p></a>
				</div>
				<div class="bott clearfix">
					<a href="${ctx}/page/proDetail.html"><img src="img/n4.jpg"/><p></p></a>
					<a href="${ctx}/page/proDetail.html"><img src="img/n5.jpg"/><p></p></a>
					<a href="${ctx}/page/proDetail.html"><img src="img/n6.jpg"/><p></p></a>
				</div>
				<h2><img src="img/ih2.jpg"/></h2>
				<#if gt01?? && gt01?size gt 0>
				<!--遍历gt01中所有的key,是为了该key中的对象-->
					<#list gt01?keys as key>
						<div class="flower clearfix tran">
						<#list gt01[key] as g>
							<a href="${ctx}/goods/detail/${g.gid}" class="clearfix">
								<dl>
									<dt>
										<span class="abl"></span>
										<img src="${g.goodsImg}"/>
										<span class="abr"></span>
									</dt>
									<dd>${g.goodsName}</dd>
									<dd><span>¥ ${g.goodsPrice}</span></dd>
								</dl>
							</a>
						</#list>
						</div>
					</#list>
				</#if>


			</div>
		</div>

		<!------------------------------ad------------------------------>
		<a href="#" class="ad"><img src="img/ib1.jpg"/></a>
		
		<!------------------------------people------------------------------>
		<div class="people">
			<div class="wrapper">
				<h2><img src="img/ih3.jpg"/></h2>
				<#if gt07?? && gt07?size gt 0>
				<#list gt07?keys as key>
				<div class="pList clearfix tran">
					<#list gt07[key] as g>
					<a href="${ctx}/goods/detail/${g.gid}">
						<dl>
							<dt>
								<span class="abl"></span>
								<img src="${g.goodsImg}"/>
								<span class="abr"></span>
							</dt>
							<dd>${g.goodsName}</dd>
							<dd><span>¥ ${g.goodsPrice}</span></dd>
						</dl>
					</a>
					</#list>
				</div>
				</#list>
				</#if>>

			</div>
		</div>

		<#include "common/footer.html"/>

		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/nav.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/jquery.flexslider-min.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			$(function() {
				$('#home_slider').flexslider({
					animation: 'slide',
					controlNav: true,
					directionNav: true,
					animationLoop: true,
					slideshow: true,
					slideshowSpeed:2000,
					useCSS: false
				});

			});
		</script>
	</body>
</html>

cart.html修改如下:

<!DOCTYPE html>
<html>
	<head lang="en">
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css" />
	</head>
	<body>
		<!--------------------------------------cart--------------------->
		<div class="head ding">
			<div class="wrapper clearfix">
				<div class="clearfix" id="top">
					<h1 class="fl"><a href="${ctx}/"><img src="img/logo.png"/></a></h1>
					<div class="fr clearfix" id="top1">
						<form action="#" method="get" class="fl">
							<input type="text" placeholder="搜索" />
							<input type="button" />
						</form>
					</div>
				</div>
			</div>
		</div>
		<div class="cart mt">
			<!-----------------logo------------------->
			<!--<div class="logo">
				<h1 class="wrapper clearfix">
					<a href="${ctx}/"><img class="fl" src="img/temp/logo.png"></a>
					<img class="top" src="img/temp/cartTop01.png">
				</h1>
			</div>-->
			<!-----------------site------------------->
			<div class="site">
				<p class=" wrapper clearfix">
					<span class="fl">购物车</span>
					<img class="top" src="img/temp/cartTop01.png">
					<a href="${ctx}/" class="fr">继续购物></a>
				</p>
			</div>
			<!-----------------table------------------->
			<div class="table wrapper">
				<div class="tr">
					<div>商品</div>
					<div>单价</div>
					<div>数量</div>
					<div>小计</div>
					<div>操作</div>
				</div>
				<#if shopCar??>
				<#list shopCar.items as g>
				<div class="th">
					<div class="pro clearfix">
						<label class="fl">
							<input type="hidden" value="${g.gid!}"/>
							<input type="checkbox"/>
							<span></span>
						</label>
						<a class="fl" href="#">
							<dl class="clearfix">
								<dt class="fl"><img style="width: 120px;height: 120px;" src="${g.goodsImg}"></dt>
								<dd class="fl">
									<p>${g.goodsName}</p>
									<p>颜色分类:</p>
									<p>白色瓷瓶+白色串枚</p>
								</dd>
							</dl>
						</a>
					</div>
					<div class="price">¥${g.goodsPrice}</div>
					<div class="number">
						<p class="num clearfix">
							<img class="fl sub" src="img/temp/sub.jpg">
							<span class="fl">${g.quantity}</span>
							<img class="fl add" src="img/temp/add.jpg">
						</p>
					</div>
					<div class="price sAll">¥${g.smalltotal()}</div>
					<div class="price"><a class="del" href="javascript:void(0)">删除</a></div>
				</div>
			    </#list>
		        </#if>

				<div class="goOn">空空如也~<a href="${ctx}/">去逛逛</a></div>
				<div class="tr clearfix">
					<label class="fl">
						<input class="checkAll" type="checkbox"/>
						<span></span>
					</label>
					<p class="fl">
						<a href="javascript:void(0);">全选</a>
						<a href="javascript:void(0);" class="del">删除</a>
					</p>
					<p class="fr">
						<span>共<small id="sl">0</small>件商品</span>
						<span>合计: <small id="all">¥0.00</small></span>
						<a class="count">结算</a>
					</p>
				</div>
			</div>
		</div>
		<div class="mask"></div>
		<div class="tipDel">
			<p>确定要删除该商品吗?</p>
			<p class="clearfix">
				<a class="fl cer" href="javascript:void(0);">确定</a>
				<a class="fr cancel" href="javascript:void(0);">取消</a>
			</p>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<!----------------mask------------------->
		<div class="mask"></div>
		<!-------------------mask内容------------------->
		<div class="proDets">
			<img class="off" src="img/temp/off.jpg" />
			<div class="proCon clearfix">
				<div class="proImg fr">
					<img class="list" src="img/temp/proDet.jpg"  />
					<div class="smallImg clearfix">
						<img src="img/temp/proDet01.jpg" src="img/temp/proDet01_big.jpg">
						<img src="img/temp/proDet02.jpg" src="img/temp/proDet02_big.jpg">
						<img src="img/temp/proDet03.jpg" src="img/temp/proDet03_big.jpg">
						<img src="img/temp/proDet04.jpg" src="img/temp/proDet04_big.jpg">
					</div>
				</div>
				<div class="fl">
					<div class="proIntro change">
						<p>颜色分类</p>
						<div class="smallImg clearfix">
							<p class="fl on"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" src="img/temp/proBig01.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" src="img/temp/proBig02.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" src="img/temp/proBig03.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" src="img/temp/proBig04.jpg"></p>
						</div>
					</div>
					<div class="changeBtn clearfix">
						<a href="#2" class="fl"><p class="buy">确认</p></a>
						<a href="#2" class="fr"><p class="cart">取消</p></a>
					</div>
				</div>
			</div>
		</div>
		<div class="pleaseC">
			<p>请选择宝贝</p>
			<img class="off" src="img/temp/off.jpg" />
		</div>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
	</body>
</html>

proDetail.html修改如下:

<!DOCTYPE html>
<html>
	<head>
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css"/>
	</head>
	<body>
		<!------------------------------head------------------------------>
		<#include "common/top.html">
		<!-----------------address------------------------------->
		<div class="address">
			<div class="wrapper clearfix">
				<a href="${ctx}/">首页</a>
				<span>/</span>
				<a href="${ctx}/page/flowerDer.html">装饰摆件</a>
				<span>/</span>
				<a href="${ctx}/page/proList.html">干花花艺</a>
				<span>/</span>
				<#--
				注意:
				1)${goods.goodsTitle!}:只能判断goodsTitle属性是否为空,不能判断goods对象是否为空
				2)${(goods.goodsTitle)!}:既可以判断goods对象是否为空,也可以判断goodsTitle属性是否为空
				-->
				<a href="#" class="on">【最家】非洲菊仿真花干花</a>
			</div>
		</div>
		<!-----------------------Detail------------------------------>
		<div class="detCon">
			<div class="proDet wrapper">
				<div class="proCon clearfix">
					<div class="proImg fl">
						<img class="det" src="${goods.goodsImg}" />
					</div>
					<div class="fr intro">
						<div class="title">
							<h4>【最家】${goods.goodsName}</h4>
							<p>${goods.goodsDetail}</p>
							<span>¥ ${goods.goodsPrice}</span>
						</div>
						<div class="proIntro">
							<p>颜色分类</p>
							<div class="smallImg clearfix categ">
								<p class="fl"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" src="img/temp/proBig01.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" src="img/temp/proBig02.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" src="img/temp/proBig03.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" src="img/temp/proBig04.jpg"></p>
							</div>
							<p>数量  库存<span>${goods.goodsStock}</span>件</p>
							<div class="num clearfix">
								<img class="fl sub" src="img/temp/sub.jpg">
								<span class="fl" contentEditable="true">1</span>
								<img class="fl add" src="img/temp/add.jpg">
								<p class="please fl">请选择商品属性!</p>
							</div>
						</div>
						<div class="btns clearfix">
							<a href="#2"><p class="buy fl">立即购买</p></a>
							<a href="javascript:void(0);"><p class="cart fr">加入购物车</p></a>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="introMsg wrapper clearfix">
			<div class="msgL fl">
				<div class="msgTit clearfix">
					<a class="on">商品详情</a>
					<a>所有评价</a>
				</div>
				<div class="msgAll">
					<div class="msgImgs">
						<img src="img/temp/det01.jpg">
						<img src="img/temp/det02.jpg">
						<img src="img/temp/det03.jpg">
						<img src="img/temp/det04.jpg">
						<img src="img/temp/det05.jpg">
						<img src="img/temp/det06.jpg">
						<img src="img/temp/det07.jpg">
					</div>
					<div class="eva">
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="msgR fr">
				<h4>为你推荐</h4>
				<div class="seeList">
					<a href="#">
						<dl>
							<dt><img src="img/temp/see01.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see02.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see03.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see04.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
				</div>
				
			</div>
		</div>
		<div class="like">
			<h4>猜你喜欢</h4>
			<div class="bottom">
				<div class="hd">
					<span class="prev"><img src="img/temp/prev.png"></span>
					<span class="next"><img src="img/temp/next.png"></span>
				</div>
				<div class="imgCon bd">
					<div class="likeList clearfix">
						<div>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like01.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like02.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like03.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like04.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html" class="last">
								<dl>
									<dt><img src="img/temp/like05.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
						</div>
						<div>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like01.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like02.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like03.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like04.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html" class="last">
								<dl>
									<dt><img src="img/temp/like05.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
						</div>
					</div>
				</div>
			</div>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<script src="js/jquery.SuperSlide.2.1.1.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/nav.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			jQuery(".bottom").slide({titCell:".hd ul",mainCell:".bd .likeList",autoPage:true,autoPlay:false,effect:"leftLoop",autoPlay:true,vis:1});
		</script>
	</body>
</html>

GoodsController :

package com.ycx.spbootpro.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ycx.spbootpro.model.Goods;
import com.ycx.spbootpro.service.IGoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

/**
 * <p>
 * 商品信息表 前端控制器
 * </p>
 *
 * @author yangzong
 * @since 2022-11-05
 */
@Controller
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private IGoodsService goodsService;

    /**
     * 根据商品ID查询商品详情信息
     * @param gid
     * @return
     */
    @RequestMapping("/detail/{gid}")
    public ModelAndView detail(@PathVariable("gid") Long gid){
        ModelAndView mv=new ModelAndView();
        //根据商品ID查询单个商品信息
        Goods goods = goodsService.getOne(new QueryWrapper<Goods>().eq("gid", gid));
        //将商品存入model带入前端展示
        mv.addObject("goods",goods);
        //设置跳转页面,商品详情页
        mv.setViewName("proDetail.html");
        return mv;
    }

}

测试查看商品详情页面:

 

springBoot将购物车数据添加入redis springboot购物车功能_spring boot_09

 

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_10

 ——————————————————————————————————————————

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_11

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_12

查看商品详情功能已完成呢

四、购物车查询以及新增的前台

修改proDetail.html:

<!DOCTYPE html>
<html>
	<head>
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css"/>
	</head>
	<body>
		<!------------------------------head------------------------------>
		<#include "common/top.html">
		<!-----------------address------------------------------->
		<div class="address">
			<div class="wrapper clearfix">
				<a href="${ctx}/">首页</a>
				<span>/</span>
				<a href="${ctx}/page/flowerDer.html">装饰摆件</a>
				<span>/</span>
				<a href="${ctx}/page/proList.html">干花花艺</a>
				<span>/</span>
				<#--
				注意:
				1)${goods.goodsTitle!}:只能判断goodsTitle属性是否为空,不能判断goods对象是否为空
				2)${(goods.goodsTitle)!}:既可以判断goods对象是否为空,也可以判断goodsTitle属性是否为空
				-->
				<a href="#" class="on">【最家】非洲菊仿真花干花</a>
			</div>
		</div>
		<!-----------------------Detail------------------------------>
		<div class="detCon">
			<div class="proDet wrapper">
				<div class="proCon clearfix">
					<div class="proImg fl">
						<img class="det" src="${goods.goodsImg}" />
					</div>
					<div class="fr intro">
						<div class="title">
							<!--设置id隐藏域-->
							<input type="hidden" id="gids" value="${goods.gid}">
							<h4>【最家】${goods.goodsName}</h4>
							<p>${goods.goodsDetail}</p>
							<span>¥ ${goods.goodsPrice}</span>
						</div>
						<div class="proIntro">
							<p>颜色分类</p>
							<div class="smallImg clearfix categ">
								<p class="fl"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" src="img/temp/proBig01.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" src="img/temp/proBig02.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" src="img/temp/proBig03.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" src="img/temp/proBig04.jpg"></p>
							</div>
							<p>数量  库存<span>${goods.goodsStock}</span>件</p>
							<div class="num clearfix">
								<img class="fl sub" src="img/temp/sub.jpg">
								<span class="fl" contentEditable="true">1</span>
								<img class="fl add" src="img/temp/add.jpg">
								<p class="please fl">请选择商品属性!</p>
							</div>
						</div>
						<div class="btns clearfix">
							<a href="#2"><p class="buy fl">立即购买</p></a>
							<a href="javascript:void(0);"><p class="cart fr">加入购物车</p></a>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="introMsg wrapper clearfix">
			<div class="msgL fl">
				<div class="msgTit clearfix">
					<a class="on">商品详情</a>
					<a>所有评价</a>
				</div>
				<div class="msgAll">
					<div class="msgImgs">
						<img src="img/temp/det01.jpg">
						<img src="img/temp/det02.jpg">
						<img src="img/temp/det03.jpg">
						<img src="img/temp/det04.jpg">
						<img src="img/temp/det05.jpg">
						<img src="img/temp/det06.jpg">
						<img src="img/temp/det07.jpg">
					</div>
					<div class="eva">
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="msgR fr">
				<h4>为你推荐</h4>
				<div class="seeList">
					<a href="#">
						<dl>
							<dt><img src="img/temp/see01.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see02.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see03.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see04.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
				</div>
				
			</div>
		</div>
		<div class="like">
			<h4>猜你喜欢</h4>
			<div class="bottom">
				<div class="hd">
					<span class="prev"><img src="img/temp/prev.png"></span>
					<span class="next"><img src="img/temp/next.png"></span>
				</div>
				<div class="imgCon bd">
					<div class="likeList clearfix">
						<div>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like01.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like02.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like03.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like04.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html" class="last">
								<dl>
									<dt><img src="img/temp/like05.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
						</div>
						<div>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like01.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like02.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like03.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like04.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html" class="last">
								<dl>
									<dt><img src="img/temp/like05.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
						</div>
					</div>
				</div>
			</div>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<script src="js/jquery.SuperSlide.2.1.1.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/nav.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			jQuery(".bottom").slide({titCell:".hd ul",mainCell:".bd .likeList",autoPage:true,autoPlay:false,effect:"leftLoop",autoPlay:true,vis:1});
			$(function () {
				$(".cart").click(function () {
					$.get('/shopCar/add',{gid:$("#gids").val()},function(rs){
						if(rs.code!=200){
							alert('请先登录后再购买商品!');
						}else
							location.href='/shopCar/queryShopCar';
					},'json');
				});
			})
		</script>
	</body>
</html>

测试 加入购物车:

springBoot将购物车数据添加入redis springboot购物车功能_spring boot_13

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_14

 如果再加一个商品:

springBoot将购物车数据添加入redis springboot购物车功能_spring_15

 

springBoot将购物车数据添加入redis springboot购物车功能_java_16

加入多个商品:

springBoot将购物车数据添加入redis springboot购物车功能_spring boot_17

那么加入购物车就成功啦~

五、购物车删除功能和修改功能

删除

cart.js:

$(function(){
	/**************数量加减***************/
	$(".num .sub").click(function(){
		var num = parseInt($(this).siblings("span").text());
		if(num<=1){
			$(this).attr("disabled","disabled");
		}else{
			num--;
			$(this).siblings("span").text(num);
			//获取除了货币符号以外的数字
			var price = $(this).parents(".number").prev().text().substring(1);
			//单价和数量相乘并保留两位小数
			$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));
			jisuan();
			zg();
		}
	});
	$(".num .add").click(function(){
		var num = parseInt($(this).siblings("span").text());
		if(num>=5){
			confirm("限购5件");
		}else{
			num++;
			$(this).siblings("span").text(num);
			var price = $(this).parents(".number").prev().text().substring(1);
			$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));
			jisuan();
			zg();
		}
	});
	//计算总价
	function jisuan(){
		var all=0;
		var len =$(".th input[type='checkbox']:checked").length;
		if(len==0){
			 $("#all").text('¥'+parseFloat(0).toFixed(2));
		}else{
			 $(".th input[type='checkbox']:checked").each(function(){
			 	//获取小计里的数值
	        	var sAll = $(this).parents(".pro").siblings('.sAll').text().substring(1);
	        	//累加
	        	all+=parseFloat(sAll);
	        	//赋值
	        	$("#all").text('¥'+all.toFixed(2));
	        })
		}
		
	}
	//计算总共几件商品
	function zg(){
		var zsl = 0;
		var index = $(".th input[type='checkbox']:checked").parents(".th").find(".num span");
		var len =index.length;
		if(len==0){
			$("#sl").text(0);
		}else{
			index.each(function(){
				zsl+=parseInt($(this).text());
				$("#sl").text(zsl);
			})
		}
		if($("#sl").text()>0){
			$(".count").css("background","#c10000");
		}else{
			$(".count").css("background","#8e8e8e");
		}
	}
	/*****************商品全选***********************/
	$("input[type='checkbox']").on('click',function(){
		var sf = $(this).is(":checked");
		var sc= $(this).hasClass("checkAll");
		if(sf){
			if(sc){
				 $("input[type='checkbox']").each(function(){  
	                this.checked=true;  
	           }); 
				zg();
	           	jisuan();
			}else{
				$(this).checked=true; 
	            var len = $("input[type='checkbox']:checked").length;
	            var len1 = $("input").length-1;
				if(len==len1){
					 $("input[type='checkbox']").each(function(){  
		                this.checked=true;  
		            }); 
				}
				zg();
				jisuan();
			}
		}else{
			if(sc){
				 $("input[type='checkbox']").each(function(){  
	                this.checked=false;  
	           }); 
				zg();
				jisuan();
			}else{
				$(this).checked=false;
				var len = $(".th input[type='checkbox']:checked").length;
	            var len1 = $("input").length-1;
				if(len<len1){
					$('.checkAll').attr("checked",false);
				}
				zg();
				jisuan();
			}
		}
		
	});
	/****************************proDetail 加入购物车*******************************/
	$(".btns .cart").click(function(){
		if($(".categ p").hasClass("on")){
			var num = parseInt($(".num span").text());
			var num1 = parseInt($(".goCart span").text());
			$(".goCart span").text(num+num1);
		}
	});
	
	//删除购物车商品
	$('.del').click(function(){
		//定义商品id
		let gids="";
		//单个删除
		if($(this).parent().parent().hasClass("th")){
			$(".mask").show();
			$(".tipDel").show();
			index = $(this).parents(".th").index()-1;

			//TODO 获取当前的checkbox中设置的隐藏域(包含了商品ID)
			gids=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();

			$('.cer').click(function(){
				$(".mask").hide();
				$(".tipDel").hide();
				$(".th").eq(index).remove();
				$('.cer').off('click');
				if($(".th").length==0){
					$(".table .goOn").show();
				}
				del(gids);
			})
		}else{
			//选中多个一起删除
			if($(".th input[type='checkbox']:checked").length==0){
				$(".mask").show();
				$(".pleaseC").show();
			}
			else{
				$(".mask").show();
				$(".tipDel").show();

				let gidarr=new Array();
				$(".th input[type='checkbox']:checked").each(function(j){
					gidarr.push($(".th").eq(index).find('div:eq(0) input[type=hidden]').val());
				});
				gids=gidarr.join(",")

				$('.cer').click(function(){
					$(".th input[type='checkbox']:checked").each(function(j){
						index = $(this).parents('.th').index()-1;
						$(".th").eq(index).remove();
						if($(".th").length==0){
							$(".table .goOn").show();
						}
					})
					$(".mask").hide();
					$(".tipDel").hide();
					zg();
					jisuan();

					del(gids);
				})
			}
		}
	})
	$('.cancel').click(function(){
		$(".mask").hide();
		$(".tipDel").hide();
	})

	//在页面初始化事件外添加删除方法
//删除商品
	function del(gids){
		$.post('/shopCar/delete',{
			'gids':gids
		},function(rs){
			if(rs.code!=200)
				alert(rs.msg);
			else
				location.href='/shopCar/queryShopCar';
		},'json');
	}
	
})

测试单个删除:

springBoot将购物车数据添加入redis springboot购物车功能_java_18

springBoot将购物车数据添加入redis springboot购物车功能_java_19

删除单个成功:

springBoot将购物车数据添加入redis springboot购物车功能_spring_20

测试全选删除:

springBoot将购物车数据添加入redis springboot购物车功能_spring_21

 全选删除成功:

springBoot将购物车数据添加入redis springboot购物车功能_mybatis_22

修改

cart.js进行整改:

$(function(){
	/**************数量加减***************/
	$(".num .sub").click(function(){
		var num = parseInt($(this).siblings("span").text());
		if(num<=1){
			$(this).attr("disabled","disabled");
		}else{
			num--;
			$(this).siblings("span").text(num);
			//获取除了货币符号以外的数字
			var price = $(this).parents(".number").prev().text().substring(1);
			//单价和数量相乘并保留两位小数
			$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));
			jisuan();
			zg();
			//TODO 获取当前行的行索引
			let index = $(this).parents(".th").index()-1;
			//获取当前的checkbox中设置的隐藏域(包含了商品ID)
			let gid=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();
			update(num,gid);
		}
	});
	$(".num .add").click(function(){
		var num = parseInt($(this).siblings("span").text());
		if(num>=5){
			confirm("限购5件");
		}else{
			num++;
			$(this).siblings("span").text(num);
			var price = $(this).parents(".number").prev().text().substring(1);
			$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));
			jisuan();
			zg();
			//TODO 获取当前行的行索引
			let index = $(this).parents(".th").index()-1;
			//获取当前的checkbox中设置的隐藏域(包含了商品ID)
			let gid=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();
			update(num,gid);

		}
	});
	//计算总价
	function jisuan(){
		var all=0;
		var len =$(".th input[type='checkbox']:checked").length;
		if(len==0){
			 $("#all").text('¥'+parseFloat(0).toFixed(2));
		}else{
			 $(".th input[type='checkbox']:checked").each(function(){
			 	//获取小计里的数值
	        	var sAll = $(this).parents(".pro").siblings('.sAll').text().substring(1);
	        	//累加
	        	all+=parseFloat(sAll);
	        	//赋值
	        	$("#all").text('¥'+all.toFixed(2));
	        })
		}
		
	}
	//计算总共几件商品
	function zg(){
		var zsl = 0;
		var index = $(".th input[type='checkbox']:checked").parents(".th").find(".num span");
		var len =index.length;
		if(len==0){
			$("#sl").text(0);
		}else{
			index.each(function(){
				zsl+=parseInt($(this).text());
				$("#sl").text(zsl);
			})
		}
		if($("#sl").text()>0){
			$(".count").css("background","#c10000");
		}else{
			$(".count").css("background","#8e8e8e");
		}
	}
	/*****************商品全选***********************/
	$("input[type='checkbox']").on('click',function(){
		var sf = $(this).is(":checked");
		var sc= $(this).hasClass("checkAll");
		if(sf){
			if(sc){
				 $("input[type='checkbox']").each(function(){  
	                this.checked=true;  
	           }); 
				zg();
	           	jisuan();
			}else{
				$(this).checked=true; 
	            var len = $("input[type='checkbox']:checked").length;
	            var len1 = $("input").length-1;
				if(len==len1){
					 $("input[type='checkbox']").each(function(){  
		                this.checked=true;  
		            }); 
				}
				zg();
				jisuan();
			}
		}else{
			if(sc){
				 $("input[type='checkbox']").each(function(){  
	                this.checked=false;  
	           }); 
				zg();
				jisuan();
			}else{
				$(this).checked=false;
				var len = $(".th input[type='checkbox']:checked").length;
	            var len1 = $("input").length-1;
				if(len<len1){
					$('.checkAll').attr("checked",false);
				}
				zg();
				jisuan();
			}
		}
		
	});
	/****************************proDetail 加入购物车*******************************/
	$(".btns .cart").click(function(){
		if($(".categ p").hasClass("on")){
			var num = parseInt($(".num span").text());
			var num1 = parseInt($(".goCart span").text());
			$(".goCart span").text(num+num1);
		}
	});
	
	//删除购物车商品
	$('.del').click(function(){
		//定义商品id
		let gids="";
		//单个删除
		if($(this).parent().parent().hasClass("th")){
			$(".mask").show();
			$(".tipDel").show();
			index = $(this).parents(".th").index()-1;

			//TODO 获取当前的checkbox中设置的隐藏域(包含了商品ID)
			gids=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();

			$('.cer').click(function(){
				$(".mask").hide();
				$(".tipDel").hide();
				$(".th").eq(index).remove();
				$('.cer').off('click');
				if($(".th").length==0){
					$(".table .goOn").show();
				}
				del(gids);
			})
		}else{
			//选中多个一起删除
			if($(".th input[type='checkbox']:checked").length==0){
				$(".mask").show();
				$(".pleaseC").show();
			}
			else{
				$(".mask").show();
				$(".tipDel").show();

				let gidarr=new Array();
				$(".th input[type='checkbox']:checked").each(function(j){
					gidarr.push($(".th").eq(index).find('div:eq(0) input[type=hidden]').val());
				});
				gids=gidarr.join(",")

				$('.cer').click(function(){
					$(".th input[type='checkbox']:checked").each(function(j){
						index = $(this).parents('.th').index()-1;
						$(".th").eq(index).remove();
						if($(".th").length==0){
							$(".table .goOn").show();
						}
					})
					$(".mask").hide();
					$(".tipDel").hide();
					zg();
					jisuan();

					del(gids);
				})
			}
		}
	})
	$('.cancel').click(function(){
		$(".mask").hide();
		$(".tipDel").hide();
	})

	//在页面初始化事件外添加删除方法
//删除商品
	function del(gids){
		$.post('/shopCar/delete',{
			'gids':gids
		},function(rs){
			if(rs.code!=200)
				alert(rs.msg);
			else
				location.href='/shopCar/queryShopCar';
		},'json');
	}

	//在页面初始化事件外添加修改方法
//更新商品数量
	function update(num,gid){
		$.post('/shopCar/update',{
			'gid':gid,
			'quantity':num
		},function(rs){
			if(rs.code!=200)
				alert(rs.msg);
			else
				location.href='/shopCar/queryShopCar';
		},'json');
	}

})

测试:

springBoot将购物车数据添加入redis springboot购物车功能_spring_23

今日内容就到这啦,下次再会!如果本文对您有帮助的话,点个赞支持一下叭~