购物车问题总结

9 篇文章 0 订阅
8 篇文章 0 订阅

一,数据库表的设计

-- 购物车表
-- 每个用户都有一个购物车
drop table if exists t_shopcar;
create table t_shopcar(
uid int,
bid int,
num int,-- 同种商品的数量
`status` tinyint(4) default 1,-- 1:正常,0:禁用,-1:删除
create_time timestamp default current_timestamp,-- 记录创建时间,时间戳,在创建新纪录时吧这个字段值设置为当前时间,但以后修改时不再更新它
update_time timestamp on update current_timestamp,-- 记录更新时间,时间戳,在创建新纪录时吧这个字段值设为0,但以后修改的时候更新为当前的时间戳
-- foreign key(uid) references t_user(id),
foreign key (uid) references t_user(id)  on update cascade on delete cascade,
foreign key(bid) references t_book(id)
);
mysql> desc t_shopcar;
+-------------+------------+------+-----+---------------------+-----------------------------+
| Field       | Type       | Null | Key | Default             | Extra                       |
+-------------+------------+------+-----+---------------------+-----------------------------+
| uid         | int(11)    | YES  | MUL | NULL                |                             |
| bid         | int(11)    | YES  | MUL | NULL                |                             |
| num         | int(11)    | YES  |     | NULL                |                             |
| status      | tinyint(4) | YES  |     | 1                   |                             |
| create_time | timestamp  | NO   |     | CURRENT_TIMESTAMP   |                             |
| update_time | timestamp  | NO   |     | 0000-00-00 00:00:00 | on update CURRENT_TIMESTAMP |
+-------------+------------+------+-----+---------------------+-----------------------------+

这里的create_time和update_time不用插入,会自动将当前时间插入

select * from t_shopcar order by update_time desc;
+------+------+------+--------+---------------------+---------------------+
| uid  | bid  | num  | status | create_time         | update_time         |
+------+------+------+--------+---------------------+---------------------+
|    9 |    8 |    9 |   NULL | 2019-02-13 15:21:42 | 2019-02-13 22:45:50 |
|    9 |   16 |   13 |   NULL | 2019-02-12 19:07:50 | 2019-02-13 22:30:33 |
|    9 |   18 |    5 |   NULL | 2019-02-13 17:07:11 | 2019-02-13 22:14:16 |
|    9 |   15 |    2 |   NULL | 2019-02-13 14:46:33 | 2019-02-13 14:49:31 |
|    9 |    3 |    1 |      1 | 2019-02-12 13:56:06 | 2019-02-12 13:56:06 |
+------+------+------+--------+---------------------+---------------------+

二,加入购物车

1. sql查询的问题

在加入购物车时需要先查询购物车之前是否已存在这种商品。如果以存在就在之前的基础上更新它的num值。
不存在的话就直接插入。
在查询购物车中的商品时,需要根据uid进行查询,再根据bid(商品id)进行分组,统计同种商品的件数,也就是统计组内的数量,最后再根据update_time进行降序排列。
(其实这点是之前没有想好,如果在加入购物车之前已经查询是否存在这种商品那么uid和bid就是唯一的了,就不存在重复的情况了,也就不用再根据bid进行分组统计同种商品的件数了。算是又练习了一下sql。)

mysql> select T.uid,T.bid,sum(T.num) as bid_count,T.status,T.update_time,T.create_time from    (select uid,bid,num,status,update_time,create_time from t_shopcar where uid=9) as T group by bid order by update_time desc;
+------+------+-----------+--------+---------------------+---------------------+
| uid  | bid  | bid_count | status | update_time         | create_time         |
+------+------+-----------+--------+---------------------+---------------------+
|    9 |    8 |         9 |   NULL | 2019-02-13 22:45:50 | 2019-02-13 15:21:42 |
|    9 |   16 |        13 |   NULL | 2019-02-13 22:30:33 | 2019-02-12 19:07:50 |
|    9 |   18 |         5 |   NULL | 2019-02-13 22:14:16 | 2019-02-13 17:07:11 |
|    9 |   15 |         3 |   NULL | 2019-02-13 14:49:31 | 2019-02-13 14:46:33 |
|    9 |    3 |         1 |      1 | 2019-02-12 13:56:06 | 2019-02-12 13:56:06 |
|    9 |    2 |         2 |      1 | 0000-00-00 00:00:00 | 2019-02-12 15:00:34 |
+------+------+-----------+--------+---------------------+---------------------+

MyBatis插入时间为0000-00-00 00:00:00这种情况时会出现异常需要在jdbc.url上加入zeroDateTimeBehavior=convertToNull

jdbc.url=jdbc:mysql://localhost:3306/book_ssm_db?characterEncoding=UTF8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull

2. 点击加入购物车时的页面跳转问题。

<br/>数量:<input type="button" value="-" onclick="subShop()"/>
            <input type="text" id="shopCount" size="2" value="1"/>
            <input type="button" value="+" onclick="addShop()"/>
................................................................

  <input type="hidden" value="${book.id}" id="bid"/>
            <input type="hidden" value="${user.id}" id="uid">

在点击加入购物车时需要将bid和text框中的商品数量shopCount添加到购物车中,
shopCount的值需要在text框中获取,所以需要通过js的方式在点击添加到购物车这个按钮时时触发js函数得到shopCount的值,然后在js函数中通过ajax将shopCount的值作为num,还要把bid(图书id)传给后台的action。

addLabel.js

function addShop(){
	var count=$("#shopCount").val();
	$("#shopCount").html($("#shopCount").val(++count));
}

function subShop(){
	var count=$("#shopCount").val();
	if (count>1){
        $("#shopCount").html($("#shopCount").val(--count));
	}
}

但是如果用户在未登录的情况下将商品(图书)加入到购物车时addToCar就会被未登录的拦截器拦截,ajax请求无法完成,拦截器拦截了请求却跳不过去,无法跳转到登录页面,被僵在这里了。
(如果不用ajax请求,拦截器的跳转是正常的)
所以暂时想到的就是将跳转到登录页面这个请求放到js里面去做。

addLabel.js



function addToCar(){
    var count=$("#shopCount").val();
    var bid=$("#bid").val();
    var uid=$("#uid").val();

    if (uid==null||uid==""){
        //在原有窗口打开
        window.location.href = "toLogin";
        // window.open("toLogin");在新窗口中打开
	}
	else {
        $.ajax({
            type : "post",
            url : "addToCar",// 后台的action
            data : {
                num : count,
                bid : bid,
                uid : uid
            },
            dataType : "json",
            success : success_function
        });
	}

}
function success_function(data){
	//这里的data是服务器从后端返回的结果
    alert(typeof(data.res));
	alert("data"+data.res);
	// var sta=data.res.substring(0,data.res.lastIndexOf("="));
	// var end=data.res.substring(data.res.indexOf("="),data.res.length);
	// alert("sta"+sta.toString()+"end"+end.toString());
    window.location.href=data.res+data.bid;
	// alert(${pageContext.request.contextPath}+"/WEB-INF/content/"+data.toString()+".jsp");
    // var localObj = window.location; //这个的意思是获取当前页面的地址
    // var protocol = location.protocol ;//获取http或https
    // var host = localObj.host;// 获取JSP地址栏IP和端口号 //localhost:8080
    // var contextPath = localObj.pathname.split("/")[1]; //获取项目名
    // var basePath = protocol +"//"+host+"/"+contextPath;
    //http://localhost:8081/bookDetail/WEB-INF/content/car/addSuccess.jsp
    // window.location.href=basePath.toString()+"/WEB-INF/content/"+data.toString()+".jsp";
    return true;
}

但是添加到购物车之后,由于是ajax请求所以后台的action返回的逻辑地址无法正常跳转。本来想在js中的ajax回调函数中用

window.location.href=${pageContext.request.contextPath}+"/WEB-INF/content/"+data.toString()+".jsp";
但是报错,{用不了,js中没法用${}

又改成

// var localObj = window.location; //这个的意思是获取当前页面的地址
    // var protocol = location.protocol ;//获取http或https
    // var host = localObj.host;// 获取JSP地址栏IP和端口号 //localhost:8080
    // var contextPath = localObj.pathname.split("/")[1]; //获取项目名
    // var basePath = protocol +"//"+host+"/"+contextPath;
    //http://localhost:8081/bookDetail/WEB-INF/content/car/addSuccess.jsp
    // window.location.href=basePath.toString()+"/WEB-INF/content/"+data.toString()+".jsp";

地址试了好多遍还是不对。
想在后台的action中直接用请求转发跳转的,这样还是同一个request要传递的数据也不会丢,但是地址还是不对。。。
这种方式放弃了。

然后又改,将要跳转的地址和参数都放到map中在回调函数中取出来。

 map.put("res","addSuccess?bid="+tShopCar.getBid());
 window.location.href=data.res

之前res写的是result,结果在Js中data.result的时候type还有值都是undefined,和js中的函数冲突了。
但是改了之后浏览器里面控制台还是500
百度,再百度
结果是 window.location.href传参的问题
不能写成
window.location.href=“addSuccess?bid=5” 这种
一定要把地址和参数分开写
window.location.href=“addSuccess?bid=”+“5”

然后又改
把data.res的地址和参数分割开。

// var sta=data.res.substring(0,data.res.lastIndexOf("="));
	// var end=data.res.substring(data.res.indexOf("="),data.res.length);
	// alert("sta"+sta.toString()+"end"+end.toString());
    window.location.href=sta+end;

但是sta和end的值莫名其妙,是数字。

算了,还是改后台的action吧。

   map.put("bid",tShopcar.getBid().toString());
      map.put("res","carbookDetail?bid=");
 map.put("res","addSuccess?bid="+tShopCar.getBid());

这下终于成功了,改了一天再不成功我怕是真的要被气晕过去了。

@Controller
public class CarController {
    @Autowired
    private ICarService carService;
    @Autowired
    private IBookService bookService;

    //Ajax方式请求后台时,未登录访问购物车被拦截,ajax请求失败,但是一直在请求?所以被拦截之后拦截器无法跳转到登录页面
    @ResponseBody//将函数返回值作为请求返回值,没有这个注解的话,请求的响应应该是一个页面,不需要页面的话应该加上这个注解。
    @RequestMapping(value = "addToCar",method = RequestMethod.POST)
    public Map<String,String> addToCar(TShopcar tShopcar, Model model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("-----addToCar-----"+tShopcar);
        Map<String,String> map=new HashMap<String,String>();
        map.put("bid",tShopcar.getBid().toString());
        if(carService.addBook(tShopcar.getUid(),tShopcar.getBid(),tShopcar.getNum())){
        //网站端跳转到添加成功的页面,如果是手机端不用跳转
//            request.getRequestDispatcher(request.getContextPath()+"/WEB-INF/content/car/addSuccess.jsp").forward(request, response);
            map.put("res","addSuccess?bid=");
//            return "addSuccess";
        }
        else {
            //添加失败,购物车已满!
//            request.getRequestDispatcher(request.getContextPath()+"/WEB-INF/content/book/bookDetail.jsp").forward(request, response);
//            return "bookDetail";
            map.put("res","carbookDetail?bid=");
        }
        System.out.println("carController addToCar map===>"+map.get("res"));
        return map;
    }

    @RequestMapping(value = "addSuccess",method=RequestMethod.GET)
    public  String addSuccess(int bid,Model model){
        TBook book=bookService.selectBookById(bid);
        model.addAttribute("book",book);

//        List<TShopcar> bookList=carService.QueryCar(tShopcar.getUid());
//        model.addAttribute("shopCount",bookList.size());
        return "car/addSuccess";
    }

    @RequestMapping(value = "carbookDetail",method=RequestMethod.GET)
    public  String addFail(int bid,Model model){
        TBook book=bookService.selectBookById(bid);
        model.addAttribute("book",book);
        return "book/bookDetail";
    }

    @RequestMapping(value = "queryCar",method = RequestMethod.GET)
    public String queryCar(int uid,Model model){
        List<TShopcar> bookInCar=carService.QueryCar(uid);
        //查出TShopcar需要用到的属性有num即商品的件数,还有bid,需要根据bid去查找出对应的book
        //<书,书的件数>
         Map shopCarList=new HashMap<TBook,Integer>();
         for (TShopcar shopcar:bookInCar){
             shopCarList.put(bookService.selectBookById(shopcar.getBid()),shopcar.getNum());
         }
        model.addAttribute("shopcarList",shopCarList);
        return "car/shopcarList";
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值