user_id = session('user_id'); $this->cartName .= $this->user_id; $default_data = Cache::get($this->cartName)['goods_list']??[];//缓存数据索引:goods_list if (!$default_data){ $_where[] = ['user_id',"=",$this->user_id]; $_where[] = ['type',"=",''];//type为空:自营;否则如 hy:华源(目前统一标记为extend) //购物车数据--shopping_cart表 $cart_data = ShoppingCartModel::field("batch_id as id,goods_number as num, unit_price as price")->where($_where)->select()->toArray(); if ($cart_data){ $init_flag = true;//true:shopping_cart表存在该用户的数据 foreach ($cart_data as $item){ $this->add($item, true);//添加到购物车数据缓存,返回值(类型:布尔)未处理 } } } if (!$init_flag){ $this->setGoods($default_data);//缓存数据存在时,$this->goods = 缓存数据; } } public function getGoods() { return $this->goods; } public function setGoods($goods) { $this->goods = $goods; } /** * @todo 现有业务逻辑待厘清 * 添加购物车 同时更新model * @access public * @param array $data * $data为数组包含以下几个值 * $Data= [ * "id"=>1, //批次ID * "num"=>2, //商品数量 * "options"=>array() //其他参数,如价格、颜色可以是数组或字符串|可以不添加 * ] * * @throws \Exception * @return void */ public function add($data,$init_flag = false) { if (!is_array($data) || !isset($data['id']) || !isset($data['num']) || !isset($data['price']) || ($data['price'] <0)) { throw new \Exception('购物车ADD方法参数设置错误');//抛出异常,keys:捕获异常--异常处理 } //添加商品支持多商品添加 //$options = isset($data['options']) ? $data['options'] : ''; //$sid = md5($data['id']); $sid = $data['id'];//batch_id $_where[] = ['user_id',"=",$this->user_id]; $_where[] = ["batch_id","=",$sid]; //生成唯一ID用于处理相同商品有不同属性时 if (isset($this->goods[$sid])) {//缓存已存在? //如果数量为0删除商品 if ($data['num'] == 0) { unset($this->goods[$sid]); if (!$init_flag){//缓存发起删除shopping_cart记录? //user_id+batch_id校验足矣? ShoppingCartModel::where($_where)->delete();//模型delete?模型对象or数据表?软删除? } } else {//不为0 增加 //已经存在相同商品时增加商品数量 $this->goods[$sid]['num'] = $this->goods[$sid]['num'] + $data['num']; $this->goods[$sid]['total'] = $this->goods[$sid]['num'] * $this->goods[$sid]['price'];//两次添加,销售价格不一样未处理 if (!$init_flag){ if ($this->goods[$sid]['num'] > 0){ $update_data['goods_number'] = $this->goods[$sid]['num']; $update_data['unit_price'] = $this->goods[$sid]['price']; ShoppingCartModel::where($_where)->update($update_data); }else{ ShoppingCartModel::where($_where)->delete(); } } } } else {//不存在 写入 if ($data['num'] > 0) { $this->goods[$sid] = $data;//batch_id索引对应商品数据 $this->goods[$sid]['total'] = $data['num'] * $data['price'];//金额 if (!$init_flag) { $add_data['user_id'] = $this->user_id; $add_data['batch_id'] = $sid; $add_data['unit_price'] = $data['price']; $add_data['goods_number'] = $data['num']; ShoppingCartModel::create($add_data); } } } //存在问题:每add一条数据即缓存一次。 //修改方案:放到__construct方法内,所有数据add之后(foreach结束后)设置一次缓存 return $this->store(); } /** * 保存到缓存 * * 缓存数据结构 * $cart = * [ * 'goods_list'=>[ * 'batch_id'=>['batch_id'=>$batch_id,'goods_num'=>$num,'price'=>$price],//新增shopping_cart_id 用于匹配shopping_cart表记录 * 'batch_id'=>['batch_id'=>$batch_id,'goods_num'=>$num,'price'=>$price], * ], * 'total_num' =>$num,//batch_id数量,相同batch_id合并处理 * 'total_price'=>$total_price,//总金额 * ] * * 重点 : $goods 赋值逻辑! */ private function store() { $cart = [ 'goods_list' => $this->goods, 'total_num' => $this->getTotalNums(), 'total_price' => $this->getTotalPrice(), ]; return Cache::set($this->cartName,$cart,config('SYSTEM_CONSTANT')['USER_INFO_CACHE_TIME']); } /** * 统计购物车中商品分类数量 */ public function getTotalNums() { $rows = 0; foreach ($this->goods as $v) { //$rows += $v['num']; $rows ++; } return $rows; } /** * 获得商品汇总价格 */ public function getTotalPrice() { $total = 0; foreach ($this->goods as $v) { $total += $v['price'] * $v['num']; } return $total; } /** * 更新购物车数量(update+delete操作) * 适用场景: * 1.删除购物车数据,传值goods_number=0 * 2.更新shopping_cart表中价格和数量信息 * * @param $data * $data=[ * "sid"=>'', //商品的唯一SID * "num"=>2, //商品数量 * ] * @return bool * @throws \Exception */ public function update($data) { if ( ! isset($data['sid']) || ! isset($data['num'])) { throw new \Exception('购物车update方法参数错误,缺少sid或num值'); } $sid = $data['sid']; $_where[] = ['user_id',"=",$this->user_id]; $_where[] = ["batch_id","=",$sid]; if (isset($this->goods[$sid])) { if ($data['num'] == 0) { unset($this->goods[$sid]); ShoppingCartModel::where($_where)->delete(); } else { $this->goods[$sid]['num'] = $data['num']; if (isset($data['price']) && is_numeric($data['price']) && $data['price'] > 0){ $this->goods[$sid]['price'] = $data['price']; } $this->goods[$sid]['total'] = $data['num'] * $this->goods[$sid]['price']; $update_data['goods_number'] = $this->goods[$sid]['num']; $update_data['unit_price'] = $this->goods[$sid]['price']; ShoppingCartModel::where($_where)->update($update_data); } return $this->store(); } return false; } /** * 获得购物车中的所有数据(缓存中取出,初始状态为空) * @return mixed */ public function getAllData() { $this->store();//缓存数据,此处已有返回值,下一行冗余,直接return 本行,方法体改为: return $this->store(); return Cache::get($this->cartName);//cartName格式:前缀+user_id缓存值(session) } /** * 获取购物车内所有商品的ID信息(batch_id) * @return array */ public function getAllId() { $id_arr = []; foreach ($this->goods as $k => $item) { $id_arr[] = $k; } return $id_arr; } /** * 删除购物车,同步删除数据库表记录 * @param $sid 商品SID编号 * @return bool * @throws \Exception */ public function del($sid) { if (isset($this->goods[$sid])) { unset($this->goods[$sid]); $_where[] = ['user_id',"=",$this->user_id]; $_where[] = ["batch_id","=",$sid]; ShoppingCartModel::where($_where)->delete(); $this->store(); return true; } return false; } /** * 删除所有商品 * @return bool * @throws \Exception */ public function flush() { ShoppingCartModel::where("user_id",$this->user_id)->delete(); $this->setGoods([]); $this->store(); return true; } }