1.首先是商品详情页

通过查看页面购物车地址为:
<a href="javascript:details.addGoodsCar();" class="pr6" id="add_goods_car"><input type="button" value="加入购物车" class="btn btn_redbd plr10" ></a>
这里触发了一个函数,经查看发现为:
addGoodsCar:function(){
//判断是否登陆
if(!loginmall.islogin()){
if($("#login_div").length==0){
$(".content").append(loginmall.nologinPage());
//延迟1毫秒显示
setTimeout('details.loginShow()', 100);
}else{
details.loginShow();
}
return;
}
details.modalShow();
buyType="0";
}
这里又出发了一个modalShow函数,主要是弹出模态框:
modalShow:function(){
var wh = $(window).height();
$(".pop_mask").show();
$(".pop_item").animate({height:wh},300);
$(".pop_item .pop_con").show().animate({height:"80%"},300);
},
pop.mask:
<div class="pop_mask"></div>
pop_item:
<div class="pop_item">
<div class="pop_con" style="display:none;">
<div class="item_info">
<span class="iconfont t_gray s_18 close js-close" onclick="details.modalHide()">�</span>
<ul class="list_ul ul_28 bg_white clearfix mb15 ed_b">
<li class="plr10 pb20 clearfix">
<div class="w_inner p_relative clearfix">
<a href="javascript:;" class="fl tc l_2 wp20 db">
<span href="javascript:;" class="t-cell-css">
<img id="cellImage" src="${nginxPath }${goods.showImg}" alt="" class="">
</span>
</a>
<div class="r_8 wp80 pl10 fl clearfix">
<a href="javascript:;" class="name lh120">${goods.goodsName}</a>
<input type="hidden" id="goodsPrice" value="${goods.price}">
<input type="hidden" id="sellerGoodsStoreNum" value="${sellerGoods.storeNum}">
<p class="wp100 t_orange"><span id="modal_price"><#if products?exists>¥#{products.sellPrice;m2M2}<#else>${goods.price}</#if></span><span class="t_gray s_08 inline_block ml8">(库存<span id="modal_store_num"><#if sellerProducts?exists>${sellerProducts.storeNum}<#else>${sellerGoods.storeNum}</#if></span>件)</span></p>
<p class="t_gray s_08" id="modal_spec_select">
<#if productsSpecVoList?exists>
已选:<#list productsSpecVoList as spec ><#if spec.type=='words'>${spec.value}<#else><img style=" 30px;height: 30px;" src='${nginxPath }${spec.value}' /></#if> </#list>
<#else>
<#if goodsSpecVoList?exists>
请选择:<#list goodsSpecVoList as spec >${spec.name} </#list>
</#if>
</#if>
</p>
<p class="t_gray s_08" id="wenxin_tishi">
</p>
</div>
</div>
</li>
</ul>
<#if goodsSpecVoList?exists>
<div id="modal_spec_list">
<#list goodsSpecVoList as spec >
<div class="bg_white ed_tb mb15 spec" specName="${spec.name}" specType="${spec.type}">
<div class="p10 ed_b bg_f8">${spec.name}</div>
<div class="tags color_tags plr10 pt10 clearfix">
<#if spec.type=='words'>
<#list spec.valueList as specValueVo >
<label><span specValue="${specValueVo.value}" data-imgUrl="${specValueVo.value}" onclick="details.combinationPro(this);productImg(this)" <#if specValueVo.selected=='YES'>class='on'</#if>>${specValueVo.value}</span></label>
</#list>
<#else>
<#list spec.valueList as specValueVo >
<label><span class="pro_img <#if specValueVo.selected=='YES'>on</#if>" data-imgUrl="${specValueVo.value}" specValue="${specValueVo.value}" onclick="details.combinationPro(this);productImg(this)"><img src='${nginxPath }${specValueVo.value}' style=' 30px;height: 30px;'></span></label>
</#list>
</#if>
</div>
</div>
</#list>
</#if>
<script>
function productImg(obj){
var imgUrl = $(obj).attr("data-imgUrl");
$(".t-cell-css img").attr("src",imgUrl)
}
</script>
<div class="mb60">
<div class="bg_white ed_tb clearfix">
<div class="p10 ed_b bg_f8">数量</div>
<div class="fl p10">
<p class="sub_add clearfix">
<input type="button" class="subtract t_gray" value="-" onclick="details.subtract();">
<input type="text" class="value tc" value="1" placeholder="1" id="productNum" onkeyup="details.checkGoodsNum(this);">
<input type="button" class="addition t_gray" value="+" onclick="details.add();">
</p>
</div>
</div>
</div>
<div class="btn-sure">
<input type="button" class="btn btn_orange btn wp100 b_radius0" value="确定" onclick="details.confirm();">
</div>
</div>
</div>
显示结果为下:

这里触发了一个js函数:details.confirm()
confirm:function(){
var noSelectSpec="";
$("#modal_spec_list").find(".spec").each(function(){
if($(this).find(".on").length<1){
noSelectSpec+=$(this).attr("specName")+" ";
}
});
//判断是否有没被选中的规格
if(noSelectSpec !=""){
resetJstip("请选择:"+noSelectSpec);
return false;
}
//判断是否选中到货品
if(productsId=="" || sellerProductsId==""){
resetJstip("请选择:"+noSelectSpec);
return false;
}
//判断当前购买量是否大于库存
var productNum=parseInt($("#productNum").val());
var storeNum=parseInt(details.replaceAll($("#modal_store_num").html(), ",", ''));
if(productNum>storeNum){
resetJstip("数量超出范围~");
return false;
}
if(buyType=="0"){
//加入购物车
var amount=parseInt($("#productNum").val());
$.ajax({
type : "POST",
url : ctx+"/shop/m/goods/ajaxAddToGoodsCar",
data :{"sellerGoodsId":sellerGoodsId,"goodsId":goodsId,"sellerProductsId":sellerProductsId,"productsId":productsId,"amount":amount,"sharePersonId":sharePersonId},
dataType : "json",
async : false,
success : function(data) {
if(data.type==1){
//加入购物车成功,关闭模态框
details.modalHide();
}
resetJstip(data.msg);
}
});
}else{
//立即购买,跳转到确认订单页面
$("#productsForm").html("");
$("#productsForm").append("<input name="orderGoods[0].goodsId" value=""+goodsId+"" type="hidden">");
$("#productsForm").append("<input name="orderGoods[0].productId" value=""+productsId+"" type="hidden">");
$("#productsForm").append("<input name="orderGoods[0].sellerGoodsId" value=""+sellerGoodsId+"" type="hidden">");
$("#productsForm").append("<input name="orderGoods[0].sellerProductId" value=""+sellerProductsId+"" type="hidden">");
$("#productsForm").append("<input name="orderGoods[0].goodsNums" value=""+$("#productNum").val()+"" type="hidden">");
$("#productsForm").append("<input name="orderGoods[0].shareUserId" value=""+sharePersonId+"" type="hidden">");
$("#productsForm").append("<input name="fuGoodsLevel" value=""+fuGoodsLevel+"" type="hidden">");
$("#productsForm").submit();
}
},
经过一系列的参数判断,将一些参数通过ajax传到后台,我们来到后台:
@RequestMapping(value = "/ajaxAddToGoodsCar")
@ResponseBody
public AjaxMessage ajaxAddToGoodsCar(GoodsCar goodsCar) {
try {
String userId = ShiroUserUtil.getShiroUserId();
String productSerialNumber = ShiroUserUtil.getProductSerialNumber();
// 自己分享的商品 不能享受分享收益
if (!EmptyUtil.isNullOrEmpty(goodsCar.getSharePersonId())) {
String[] sharePersonIds = goodsCar.getSharePersonId().split("~");
for (int i = 0; i < sharePersonIds.length; i++) {
if (userId.equals(sharePersonIds[i])) {
goodsCar.setSharePersonId(null);
break;
}
}
}
goodsCarService.addToGoodsCar(productSerialNumber, userId, goodsCar);
return AjaxMessage.getInstance(AjaxMessage.INFO, "添加成功,在购物车等亲~");
} catch (Exception e) {
e.printStackTrace();
return AjaxMessage.getInstance(AjaxMessage.ERROR, "加入购物车失败");
}
}
这个控制层访问了一个服务层:
@Override
public void addToGoodsCar(String productSerialNumber, String userId, GoodsCar goodsCar) {
// 验证当前登录人的购物车中是否存在此货品
String hql = " from GoodsCar where productSerialNumber=:productSerialNumber and userId=:userId and productsId=:productsId and sellerProductsId=:sellerProductsId ";
Map<String, Object> params = new HashMap<String, Object>();
params.put("productSerialNumber", productSerialNumber);
params.put("userId", userId);
params.put("productsId", goodsCar.getProductsId());
params.put("sellerProductsId", goodsCar.getSellerProductsId());
GoodsCar car = goodsCarDao.findUnique(hql, params);
if (!EmptyUtil.isNullOrEmpty(car)) {
// 购物车中存在此货品,更新数量
car.setAmount(car.getAmount() + goodsCar.getAmount());
if (!EmptyUtil.isNullOrEmpty(goodsCar.getSharePersonId())) {
car.setSharePersonId(goodsCar.getSharePersonId());
}
goodsCarDao.save(car);
} else {
// 购物车种不存在此货品,保存记录
goodsCar.setProductSerialNumber(productSerialNumber);
goodsCar.setUserId(userId);
goodsCarDao.save(goodsCar);
}
}
可以看出这个购物车的实现依旧是存储在数据库的
简单的归纳如下:
点击添加到购物车->触发模态框->触发库存与购买的判断->触发后台->后台判断当前要添加的购物车的商品在购物车中是否存在则更新数量,若不存在则添加到购物车。
下面是购物车的实体:
@Entity
@Table(name = "PT_GOODS_CAR")
public class GoodsCar extends IdEntity {
/** serialVersionUID */
private static final long serialVersionUID = 3486623718188862844L;
/** 产品序列号 */
private java.lang.String productSerialNumber;
/** 用户ID */
private java.lang.String userId;
/** 商品ID */
private java.lang.String goodsId;
/** 货品ID */
private java.lang.String productsId;
/** 卖家商品ID*/
private java.lang.String sellerGoodsId;
/** 卖家货品ID*/
private java.lang.String sellerProductsId;
/** 创建时间 */
private java.util.Date createTime;
/** 商品或者货品的数量 */
private java.lang.Long amount;
/** 分享人id */
private java.lang.String sharePersonId;
}
setter和getter方法略