request->post(); $res = \Yii::$app->services->validate->validate($params, [ [['goods_id', 'attr_id', 'num'], 'required'], ]); if ($res === false) return $this->error(\Yii::$app->services->validate->getErrorMessage()); $goods = Goods::findOne(['id' => $params['goods_id'], 'status' => StatusEnum::ENABLED, 'is_on_sale' => 1]); if (empty($goods)) return $this->error("商品不存在"); if(isset($goods->is_pay_limit)&& $goods->is_pay_limit) { return $this->error("该商品限制支付,不允许加入购物车"); } // 处方药不能加入购物车 if ($goods->goods_subtype == GoodsTypeEnum::GOODS_SUBTYPE_PRESCRIPTION) { return $this->error("处方药商品不允许加入购物车"); } $member_buy_limit_setting = json_decode($goods->extra['member_buy_limit_setting'], true); $params['buy_limit_nums'] = $member_buy_limit_setting['nums'] ?? 0; $params['buy_limit_total_num'] = $member_buy_limit_setting['total_num'] ?? 0; // 没有规格id则查找默认规格【寻找价格最低的规格】 $where = ['goods_id' => $params['goods_id'], 'status' => StatusEnum::ENABLED]; !empty($params['attr_id']) && $where['id'] = $params['attr_id']; $goods_attr = GoodsAttr::find()->where($where)->orderBy('price asc')->one(); if ($goods_attr->goods_id != $params['goods_id']) return $this->error("goods_id与attr_id不配对"); if (empty($goods->is_attr)) { if (empty($goods->stock)) return $this->error('库存不足'); } else { //多规格 if (empty($goods_attr)) return $this->error("所选的规格不存在"); if (empty($goods_attr->stock)) return $this->error("所选的规格库存不足"); } // 公共调用 $res = GlobalInvoke::exec(GlobalInvoke::CART_ADD, $this->mall_id, [ 'goods' => $goods, 'mall_id' => $this->mall_id, ]); if (!empty($res) && $res['cart'] == false) { return $this->error($res['message']); } $params['mch_id'] = $goods->mch_id; $params['mall_id'] = $this->mall_id; $params['user_id'] = $this->user_id; Cart::addCart($params); $event = new EditCartEvent($this->mall_id); $data = ['num' => $params['num'], 'goods_id' => $params['goods_id'], 'mall_id' => $this->mall_id]; \Yii::$app->services->events->dispatch($event, $data, $event->listeners); return $this->success('加入购物车成功', []); } catch (\Exception $e) { return $this->error($e->getMessage(), []); } } /** * 删除购物车 * @return mixed|void */ public function actionDel() { $params = \Yii::$app->request->post(); $res = \Yii::$app->services->validate->validate($params, [ [['list'], 'required'], ]); if ($res === false) return $this->error(\Yii::$app->services->validate->getErrorMessage()); $params['mall_id'] = $this->mall_id; $params['user_id'] = $this->user_id; Cart::delCart($params); return $this->success('操作成功', []); } /** * 购物车列表 * @return mixed|void */ public function actionIndex() { $get = \Yii::$app->request->get(); if (empty($this->user_id)) return $this->success('请登录'); $res = \Yii::$app->services->validate->validate($get, [ [['location_style'], 'safe'], ]); if ($res === false) return $this->error(\Yii::$app->services->validate->getErrorMessage()); $list = Cart::getCartList($this->user_id); $attr_ids = $this->attrIdsByDesc($list); $data = []; if (!empty($list)) { $attr_id_arr = []; $num_arr = []; foreach ($list as $v) { $row = json_decode($v, true); if (is_array($row)) { $attr_id_arr[] = $row['attr_id']; $num_arr[$row['attr_id']] = $row['num']; } } $params['where'] = [['id' => $attr_id_arr]]; $params['with'] = ['goods' => function ($query) { $query->select('id,goods_name,mch_id,is_on_sale,cover_pic,is_attr,goods_source,status')->with(['extra']); }]; $params['select'] = 'id,sign_id,goods_id,pic_url,price,name'; $list = GoodsAttr::lists($params); // 按顺序重组 $list = $this->listSortByAttrIds($list, $attr_ids); $rows = []; $user = $this->user; $user_level = UserLevel::findOne(['mall_id' => $this->mall_id, 'level' => $user['level'], 'status' => StatusEnum::ENABLED]); $discount = 10; if (isset($user_level)) $discount = $user_level['discount']; $goods_deduct_arr = []; if(MallAddons::isInstall($this->mall_id,AddonsEnum::ADDONS_NAME_AGENT)){ $setting = \Yii::$app->services->setting->addons->get($this->mall_id, AddonsEnum::ADDONS_NAME_AGENT, 'basic'); if (!empty($setting['is_self_buy']) && !empty($setting['enable_goods_deduct'])) { $goods_deduct_arr = \common\logic\order\marketing\AgentMarketing::getDeductMoney($this->mall_id,$this->user_id,$num_arr); } } if (!empty($list)) { foreach ($list as $v) { $member_price_setting = Json::decode($v['goods']['extra']['member_price_setting']); $v['member_price'] = Goods::computeMemberPrice($v['price'],$v['sign_id'],$user['level'],$v['goods']['is_attr'], $v['goods']['extra']['is_member_price'],$member_price_setting,$discount); if (!empty($v['goods']['extra']['is_member_price']) && !empty($v['extra']['member_price_setting'])) { $member_price_setting = $v['extra']['member_price_setting']; if ($v['goods']['is_attr']) { if (!empty($member_price_setting['level' . $user['level']][$v['sign_id']])) $v['price'] = $member_price_setting['level' . $user['level']][$v['sign_id']]; } else { if (!empty($member_price_setting[$user['level']])) $v['price'] = $member_price_setting[$user['level']]; } } // 最低起购 $member_buy_limit_setting = isset($v['goods']['extra']['member_buy_limit_setting']) ? json_decode($v['goods']['extra']['member_buy_limit_setting'], true) : []; $member_buy_limit_num = $member_buy_limit_setting['nums'] ?? 0; $member_price = $v['member_price']; // 渠道分红内购会员价特殊计算方式 if (isset($goods_deduct_arr[$v['id']]) && $goods_deduct_arr[$v['id']]) { // 如果内购返回价格,并且价格不为0,则取内购价格 $member_price = bcdiv($goods_deduct_arr[$v['id']], $num_arr[$v['id']], 2); } elseif (isset($goods_deduct_arr[$v['id']]) && ($goods_deduct_arr[$v['id']] == 0)) { // 或者内购返回价格等于0,则取商品价格 $agent_item = AgentCommissionItemSetting::find() ->select('item_id, is_participate, is_self_buy_alone, is_self_buy, enable_goods_deduct') ->where(['item_id' => $v['goods_id'], 'status' => StatusEnum::ENABLED]) ->asArray() ->one(); $member_price = $v['price']; if (!empty($agent_item) && empty($agent_item['is_participate'])) { $member_price = $v['member_price']; } if (!empty($agent_item['is_self_buy_alone'])) { if (empty($agent_item['is_self_buy']) || empty($agent_item['enable_goods_deduct'])) { $member_price = $v['member_price']; } } } $rows[$v['goods']['mch_id']][] = [ 'goods_id' => $v['goods_id'], 'num' => $num_arr[$v['id']], 'attr_id' => $v['id'], 'price' => $v['price'], 'member_price' => $member_price, 'cover_pic' => $v['goods']['cover_pic']??'', 'attr' => $v['name'], 'goods_name' => $v['goods']['goods_name'], 'is_on_sale' => $v['goods']['status'] < StatusEnum::ENABLED ? StatusEnum::DISABLED : $v['goods']['is_on_sale'], 'goods_source' => $v['goods']['goods_source'], 'member_buy_limit_num' => $member_buy_limit_num, ]; } } $mall_name = \Yii::$app->services->setting->mall->get($this->mall_id, 'basic.name'); $mall_logo = \Yii::$app->services->setting->mall->get($this->mall_id, 'basic.logo'); $mch_arr = [ ['id' => 0, 'mch_pic' => $mall_logo, 'mch_name' => $mall_name, 'list' => []] ]; //多商户 if (MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_MCH)) { $mch_ids = []; foreach ($list as $item) { if($item['goods']['mch_id'])$mch_ids[] = $item['goods']['mch_id']; } if(!empty($mch_ids)){ $mch_list = Mch::lists(['where' => [['id' => $mch_ids]], 'select' => 'id,logo_img as mch_pic,store_name as mch_name'], true); if($mch_list)$mch_arr = array_merge($mch_arr, $mch_list); } } $data = []; foreach ($mch_arr as $key => $val) { if (isset($rows[$val['id']])) { $data[]=[ 'id'=>$val['id'], 'mch_name'=>$val['mch_name'], 'mch_pic'=>$val['mch_pic'], 'list'=>$rows[$val['id']], ]; } else { unset($mch_arr[$key]); } } $new_data = GlobalInvoke::exec(GlobalInvoke::CART_LIST_APPEND_FILEDS, $this->mall_id, ['mall_id' => $this->mall_id, 'location_style'=> $get['location_style'] ?? 1, 'user_id' => $this->user_id, 'data' => $data]); $data = $new_data ? $new_data : $data; } return $this->success('操作成功', $data); } public function actionUpdateCart() { try { $params = \Yii::$app->request->post(); $res = \Yii::$app->services->validate->validate($params, [ [['goods_id', 'num'], 'required'], [['attr_id'], 'safe'], ]); if ($res === false) return $this->error(\Yii::$app->services->validate->getErrorMessage()); $goods = Goods::findOne(['id' => $params['goods_id'], 'status' => StatusEnum::ENABLED, 'is_on_sale' => 1]); if (empty($goods)) return $this->error("商品不存在"); $member_buy_limit_setting = json_decode($goods->extra['member_buy_limit_setting'], true); $params['buy_limit_nums'] = $member_buy_limit_setting['nums'] ?? 0; $params['buy_limit_total_num'] = $member_buy_limit_setting['total_num'] ?? 0; // 最低购买 if ($params['num'] < $params['buy_limit_nums']) { return $this->error(sprintf('该商品最低购买数量为%s', $params['buy_limit_nums'])); } // 没有规格id则查找默认规格【寻找价格最低的规格】 $where = ['goods_id' => $params['goods_id'], 'status' => StatusEnum::ENABLED]; !empty($params['attr_id']) && $where['id'] = $params['attr_id']; $goods_attr = GoodsAttr::find()->where($where)->orderBy('price asc')->one(); if ($goods_attr->goods_id != $params['goods_id']) return $this->error("goods_id与attr_id不配对"); if (empty($goods->is_attr)) { if (empty($goods->stock)) return $this->error('库存不足'); } else { //多规格 if (empty($goods_attr)) return $this->error("所选的规格不存在"); if (empty($goods_attr->stock)) return $this->error("所选的规格库存不足"); } // 公共调用 $res = GlobalInvoke::exec(GlobalInvoke::CART_ADD, $this->mall_id, [ 'goods' => $goods, 'mall_id' => $this->mall_id, ]); if (!empty($res) && $res['cart'] == false) { return $this->error($res['message']); } $params['mch_id'] = $goods->mch_id; $params['mall_id'] = $this->mall_id; $params['user_id'] = $this->user_id; Cart::updateCart($params); $event = new EditCartEvent($this->mall_id); $data = ['num' => $params['num'], 'goods_id' => $params['goods_id'], 'mall_id' => $this->mall_id]; \Yii::$app->services->events->dispatch($event, $data, $event->listeners); return $this->success('更新购物车成功', []); } catch (\Exception $e) { return $this->error($e->getMessage(), []); } } /** * 获取排序后的规格ID * * @param array $list * @return array */ protected function attrIdsByDesc($list) { $attr_id = []; if (empty($list)) return $attr_id; // 转义JSON字符串 $list = array_filter(array_map(function ($item) { $arr = Json::decode($item); // 兼容旧程序没有microtime if (is_array($arr) && empty($arr['microtime'])) { $arr['microtime'] = 0; } return $arr; }, $list), function ($item) { return is_array($item); }); // 按时间排序 array_multisort(array_column($list, 'microtime'), SORT_DESC, $list); // 获取attr_id return array_column($list, 'attr_id'); } /** * 通过AttrIds重新排序 * * @param array $list * @param array $attr_ids * @return array */ protected function listSortByAttrIds($list, $attr_ids) { $new_list = []; if (empty($list)) return $new_list; // 获取已经排序的规格ID foreach ($attr_ids as $attr_id) { foreach ($list as $item) { if ($item['id'] == $attr_id) { $new_list[] = $item; } } } return $new_list; } //获取要展示的商品购物车类型列表 public function actionGetCartTypeList() { if (\Yii::$app->request->isGET) { // $get = \Yii::$app->request->get(); $config = \Yii::$app->services->setting->mall->get($this->mall_id, 'cart'); if (!empty($config['cart_type'])) { $config['cart_type'] = json_decode($config['cart_type'],true); } else { if (!isset($config['cart_type'])) { $config['cart_type'][] = CartEnum::MALL_CART; } } if (!empty($config['cart_name'])) { $config['cart_name'] = json_decode($config['cart_name'],true); } if (!MallAddons::isInstall($this->mall_id, AddonsEnum::ADDONS_NAME_STORE)) { foreach ($config['cart_type'] as $key => $value) { if ($value == CartEnum::STORE_MALL_CART) { unset($config['cart_type'][$key]); } } } sort($config['cart_type']); //整理顺序 $cart_num = []; $cart_type = CartEnum::getMap(); foreach ($config['cart_type'] as $k => $val) { switch ($val) { case 1: $list = Cart::getCartList($this->user_id); break; case 2: $list = StoreCart::getCartList($this->user_id); break; } if (!empty($config['cart_name']) && $config['cart_name'][$val]['is_show'] == 1) { $cart_type[$val] = $config['cart_name'][$val]['name']; } $ids = $this->attrIdsByDesc($list); $cart_num[$val] = count($ids); } $this->success('获取成功',['list' => $config['cart_type'], 'cart_num' => $cart_num, 'type' => $cart_type]); } } }