目录
一、用户登录跳转界面
js
$(function () { alert(233); // 给登录按钮添加事件 $("#login").click(function () { let mobile = $("#mobile").val(); let password = $("#password").val(); console.log("mobile=%s,password=%s",mobile,password); //1.密码加密 //1) 定义固定盐 let salt='f1g2h3j4'; //2) 固定盐混淆 let temp=salt.charAt(1)+""+salt.charAt(5)+password+salt.charAt(0)+""+salt.charAt(3); //3) 使用MD5完成前端第一次加密 let pwd=md5(temp); //2.向后台发起登录ajax请求 $.post('/user/toLogin',{ mobile:mobile, password:pwd },function(rs){ if(rs.code!=200){//登录失败 alert(rs.msg); }else //alert(rs.msg); location.href="/";//登录成功跳转index.html },'json'); }); });
user.java
package com.zking.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 zking
* @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 LocalDateTime lastLoginDate;
/**
* 登录次数
*/
private Integer loginCount;
}
二、参数解析器以及购物车后台
代码
<!--返回顶部--> <div class="gotop"> <a href="javascript:void(0)" οnclick="check()"> <dl> <dt><img src="img/gt1.png"/></dt> <dd>去购<br />物车</dd> </dl> </a> <a href="#" class="dh"> <dl> <dt><img src="img/gt2.png"/></dt> <dd>联系<br />客服</dd> </dl> </a> <a href="${ctx}/page/mygxin.html"> <dl> <dt><img src="img/gt3.png"/></dt> <dd>个人<br />中心</dd> </dl> </a> <a href="#" class="toptop" style="display: none"> <dl> <dt><img src="img/gt4.png"/></dt> <dd>返回<br />顶部</dd> </dl> </a> <p>400-800-8200</p> </div> <!-------------------login--------------------------> <!--footer--> <div class="footer"> <div class="top"> <div class="wrapper"> <div class="clearfix"> <a href="#2" class="fl"><img src="img/foot1.png"/></a> <span class="fl">7天无理由退货</span> </div> <div class="clearfix"> <a href="#2" class="fl"><img src="img/foot2.png"/></a> <span class="fl">15天免费换货</span> </div> <div class="clearfix"> <a href="#2" class="fl"><img src="img/foot3.png"/></a> <span class="fl">满599包邮</span> </div> <div class="clearfix"> <a href="#2" class="fl"><img src="img/foot4.png"/></a> <span class="fl">手机特色服务</span> </div> </div> </div> <p class="dibu">最家家居©2013-2017公司版权所有 京ICP备080100-44备0000111000号<br /> 违法和不良信息举报电话:400-800-8200,本网站所列数据,除特殊说明,所有数据均出自我司实验室测试</p> </div> <script src="js/jquery-1.12.4.min.js" type="text/javascript" charset="utf-8"></script> <script> function check() { $.get('/shopCar/check',{},function(rs){ if(rs.code!=200){ alert('请先登录后再购买商品!'); }else location.href='/shopCar/queryShopCar'; },'json'); } </script>
UserArgumentResovler 参数解析器
package com.zking.spbootpro.config;
import com.zking.spbootpro.exception.BusinessException;
import com.zking.spbootpro.model.User;
import com.zking.spbootpro.service.IredisService;
import com.zking.spbootpro.utils.CookieUtils;
import com.zking.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 org.springframework.web.servlet.HandlerExceptionResolver;
import javax.servlet.http.HttpServletRequest;
/**
* 参数解析器
* @author 锦鲤
* @site www.lucy.com
* @company xxx公司
* @create 2022-11-07 18:25
*/
@Component
public class UserArgumentResovler implements HandlerMethodArgumentResolver {
@Autowired
private IredisService iredisService;
/**
* 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= iredisService.getUserToRedis(token);
if(user ==null){
throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
}
return user;
}
}
WebConfig
package com.zking.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 锦鲤
* @site www.lucy.com
* @company xxx公司
* @create 2022-11-07 18:42
*
*/
@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);
}
}
购物车后台搭建
实体类ShopCar 、ShopCarItem
package com.zking.spbootpro.model.vo;
import java.util.*;
/**
* @author 锦鲤
* @company xxx公司
* @create 2022-11-07 10:36
* <p>
* view object
* 购物车对象
*/
public class ShopCar {
private List<ShopCarItem> items= new ArrayList<ShopCarItem>();
public List<ShopCarItem> getItems() {
return items;
}
public void setItems(List<ShopCarItem> items) {
this.items = items;
}
// 增加
public void add(ShopCarItem shopCarItem) {
// 1.当购物车存在该商品时
for (ShopCarItem item : items) {
if (Objects.equals(shopCarItem.getGid(), item.getGid())) {
item.setQuantity(item.getQuantity() + 1);
return;
}
}
// 2.当购物车不存在该商品时
items.add(shopCarItem);
}
// 删除 1,2,3
public void delete(String gids) {
List<String> gidList = Arrays.asList(gids.split(","));
Iterator<ShopCarItem> it = items.iterator();
while (it.hasNext()) {
ShopCarItem next = it.next();
if (gidList.contains(next.getGid()+"")) {
it.remove();
}
}
}
// 修改
public void update(ShopCarItem shopCarItem) {
for (ShopCarItem item : items) {
if (Objects.equals(shopCarItem.getGid(), item.getGid())) {
item.setQuantity(shopCarItem.getQuantity());
}
}
}
// 查询
// 小计
}
package com.zking.spbootpro.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @author 锦鲤
* @site www.lucy.com
* @company xxx公司
* @create 2022-11-07 19:16
* 购物车明细
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ShopCarItem {
// 商品id、商品名称、商品单价、商品数量、图片
private long gid;
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);
}
}
ShopCarController
package com.zking.spbootpro.Controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zking.spbootpro.model.Goods;
import com.zking.spbootpro.model.User;
import com.zking.spbootpro.model.vo.ShopCar;
import com.zking.spbootpro.model.vo.ShopCarItem;
import com.zking.spbootpro.service.IGoodsService;
import com.zking.spbootpro.service.IredisService;
import com.zking.spbootpro.utils.JsonResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @author 锦鲤
*
*/
@Controller
@RequestMapping("/shopCar")
public class ShopCarController {
@Autowired
private IredisService redisService;
/**
* 使用参数解析器之前的做法弊端:
* 在每一个需要登录之后才能操作的功能,都需要做用户登录验证,即以下代码都需要写一遍
*
* @param
* @return
*/
// @RequestMapping("/check")
// public JsonResponseBody check(@CookieValue("token") String token){
// if (token == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
// User user = redisService.getUserToRedis(token);
// if (user == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
// return new JsonResponseBody();
// }
@ResponseBody
@RequestMapping("/check")
public JsonResponseBody check(User user) {
// if (token == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
// User user = redisService.getUserToRedis(token);
// if (user == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
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;
// 增加
@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);
// request.setAttribute("shopCar",shopCar);
return new JsonResponseBody();
}
// 修改
@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();
}
// 删除
@ResponseBody
@RequestMapping("/delete")
public JsonResponseBody delete(User user,
HttpServletRequest request,
HttpServletResponse resp,
String gids) {
ModelAndView mv = new ModelAndView();
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> <body> <!------------------------------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> <#list gt01?keys as key> <div class="flower clearfix tran"> <#list gt01[key] as g> <a href="${ctx}/page/proDetail.html" 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="proDetail.html"> <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>
商品详情
四、购物车查询以及新增的前台
GoodsController
package com.zking.spbootpro.Controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zking.spbootpro.model.Goods; import com.zking.spbootpro.service.IGoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; 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 zking * @since 2022-11-05 */ @Controller @RequestMapping("/goods") public class GoodsController { @Autowired private IGoodsService iGoodsService; @RequestMapping("/detail/{gid}") public ModelAndView detail(@PathVariable("gid") long gid){ Goods goods = iGoodsService.getOne(new QueryWrapper<Goods>().eq("gid", gid)); ModelAndView mv = new ModelAndView(); mv.addObject("goods",goods); mv.setViewName("proDetail.html"); return mv; } }
ShopCarController
package com.zking.spbootpro.Controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zking.spbootpro.model.Goods;
import com.zking.spbootpro.model.User;
import com.zking.spbootpro.model.vo.ShopCar;
import com.zking.spbootpro.model.vo.ShopCarItem;
import com.zking.spbootpro.service.IGoodsService;
import com.zking.spbootpro.service.IredisService;
import com.zking.spbootpro.utils.JsonResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @author 锦鲤
*
*/
@Controller
@RequestMapping("/shopCar")
public class ShopCarController {
@Autowired
private IredisService redisService;
/**
* 使用参数解析器之前的做法弊端:
* 在每一个需要登录之后才能操作的功能,都需要做用户登录验证,即以下代码都需要写一遍
*
* @param
* @return
*/
// @RequestMapping("/check")
// public JsonResponseBody check(@CookieValue("token") String token){
// if (token == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
// User user = redisService.getUserToRedis(token);
// if (user == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
// return new JsonResponseBody();
// }
@ResponseBody
@RequestMapping("/check")
public JsonResponseBody check(User user) {
// if (token == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
// User user = redisService.getUserToRedis(token);
// if (user == null)
// throw new BusinessException(JsonResponseStatus.TOKEN_EEROR);
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;
// 增加
@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);
// request.setAttribute("shopCar",shopCar);
return new JsonResponseBody();
}
// 修改
@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();
}
// 删除
@ResponseBody
@RequestMapping("/delete")
public JsonResponseBody delete(User user,
HttpServletRequest request,
HttpServletResponse resp,
String gids) {
ModelAndView mv = new ModelAndView();
ShopCar shopCar = getShopCar(user, request);
shopCar.delete(gids);
return new JsonResponseBody();
}
}
详情界面
<!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">
<#-- 360 -->
<img class="det" src="${goods.goodsImg}" />
</div>
<div class="fr intro">
<div class="title">
<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支快乐花" data-src="img/temp/proBig01.jpg"></p>
<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" data-src="img/temp/proBig02.jpg"></p>
<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" data-src="img/temp/proBig03.jpg"></p>
<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" data-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>
购物车界面数据绑定
<!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" data-src="img/temp/proDet01_big.jpg">
<img src="img/temp/proDet02.jpg" data-src="img/temp/proDet02_big.jpg">
<img src="img/temp/proDet03.jpg" data-src="img/temp/proDet03_big.jpg">
<img src="img/temp/proDet04.jpg" data-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支快乐花" data-src="img/temp/proBig01.jpg"></p>
<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" data-src="img/temp/proBig02.jpg"></p>
<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" data-src="img/temp/proBig03.jpg"></p>
<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" data-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>
五、购物车删除及修改功能
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 1,2,3,4,5,6
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();// {1,2,3,4,5,6}
$(".th input[type='checkbox']:checked").each(function(j){
gidarr.push($(".th").eq(index).find('div:eq(0) input[type=hidden]').val());
// gids += $(".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();
})
//改变商品规格
// $(".pro dd").hover(function(){
// var html='';
// html='<span class="edit">修改</span>';
// $(this).addClass("on").append(html).parents(".th").siblings(".th").find(".pro dd").removeClass("on").find('.edit').remove();
// $(".edit").each(function(i){
// $(this).attr("id",'edit'+i);
// $("#edit"+i).click(function(){
// $(".proDets").show();
// $(".mask").show();
// $(".changeBtn .buy").attr("data-id",i);
// })
// })
// },function(){
// $(this).removeClass("on");
// })
// $(".changeBtn .buy").click(function(){
// var index = $(this).attr("data-id");
// var result = $(".smallImg .on").find("img").attr("alt");
// $("#edit"+index).prev().text(result);
// $(".proDets").hide();
// $(".mask").hide();
// $("#edit"+index).parent("dd").removeClass("on").find(".edit").remove();
// });
// $(".changeBtn .cart").click(function(){
// $(".proDets").hide();
// $(".mask").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'); }
数量增减