目录
一、自定义的参数解析器
在使用自定义的参数解析器之前的做法:
使用自定义的参数解析器之后的做法:
二、购物车后台
1.定义购物车对象ShopCar
2.web层定义ShopCarController.java
三、商品详情页面实现
四、购物车查询以及新增的前台
五、购物车删除功能和修改功能
删除
修改
上节内容完成了首页以及登录的功能,登录之后弹出“OK”提示,忘记实现自动跳页面了,这里先继续简单完善一下,比较简单:
login.js:
再次去登录成功之后就会自动跳转回主页并且绑定了用户名:
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时间字段代码生成问题
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;
改完之后将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);
}
}
测试:
然后去进行登录之后,再点击去购物车:
目前是404,因为queryShopCar页面还没有编写:
但是此时redis已经存在用户的值了(如下图):
经过测试,我们会发现,凡是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;
}
}
测试查看商品详情页面:
——————————————————————————————————————————
查看商品详情功能已完成呢
四、购物车查询以及新增的前台
修改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>
测试 加入购物车:
如果再加一个商品:
加入多个商品:
那么加入购物车就成功啦~
五、购物车删除功能和修改功能
删除
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');
}
})
测试单个删除:
删除单个成功:
测试全选删除:
全选删除成功:
修改
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');
}
})
测试:
今日内容就到这啦,下次再会!如果本文对您有帮助的话,点个赞支持一下叭~