model = new \app\api\model\app\vip\CardPrivilege; $this->cardModel = new \app\api\model\app\vip\Card; } /** * 获取特权商品列表 * @return void */ public function getGoodsList(){ $limit = input('limit',10); $page = input('page',1); $type = input('type',''); $name = input('name',''); $sort = input('sort','time'); $order = input('order','desc'); $privilegeType = input('privilege_type','free'); $cardId = input('card_id'); $where = []; if($type){ $where['course.type'] = $type; } if($name){ $where['course.name'] = ['like',"%{$name}%"]; } $where['card_privilege.type'] = $privilegeType; $where['card_privilege.card_id'] = $cardId; $where['course.uniacid'] = UNIACID; switch ($sort){ case 'time': $sort = 'course.createtime'; break; case 'price': $sort = 'course.price'; break; default: $sort = 'course.createtime'; break; } $cardInfo = $this->cardModel->where([ 'id'=>$cardId, 'status'=>1 ])->find(); if(!$cardInfo){ $this->error('获取失败'); } $list = $this->model ->setUniacid(false) ->with(['course']) ->where($where) ->limit($limit) ->page($page) ->order($sort,$order) ->select(); //获取card详情 $data = []; if($list){ foreach ($list as &$row) { $row->course->visible(['name','cover','price','price_marking','pay_type','type','id','is_vip_goods']); $cardInfo['privilege_discount_val'] = $privilegeType == 'free' ? 0 : $cardInfo['privilege_discount_val']; $discountPrice = \app\api\model\app\vip\CardPrivilege::getDiscountPrice($row->course->price,$cardInfo['privilege_discount_val']); $row->course['price'] = $discountPrice['price']; $row->course['price_marking'] = $discountPrice['price_marking']; $row->course->is_vip_goods = true; $data[] = $row->course; } } $this->success('获取成功', $data); } /** * 获取商品对应会员卡优惠 * 优先级: * 1. 用户当前已开通会员卡 * 2. 指定课程作用域下绑定该商品的会员卡 * 3. 全部课程作用域且课程类型受作用 (article/video/audio/live/column) 的会员卡 * @return void */ public function getGoodsPrivilege(){ if(!$this->auth->isLogin()){ $this->success('获取成功', ['goodsVipInfo'=>null,'isNowGoodsVip'=>false]); } $goodsId = input('id'); $config = \app\common\model\app\Config::getConfig('vip'); if($config['status'] != 1 || $config['entrance'] != 1){ $this->success('入口关闭'); } $isNowGoodsVip = true; //如果用户开通了会员 那么先获取用户开通的会员有没有指定商品的优惠 $userVipInfo = \app\common\model\app\vip\CardUser::getUserVipInfo($this->auth->id); $cardInfo = false; if($userVipInfo){ //先尝试匹配 指定课程 $cardInfo = $this->model->with(['card'])->where([ 'goods_id'=>$goodsId, 'card.status'=>1, 'card_id'=>$userVipInfo['card']['id'] ])->order('card_privilege.type','desc')->find(); //再尝试匹配 当前已开通卡的「全部课程」作用域权益 if (!$cardInfo) { $cardInfo = $this->buildScopeAllCardPrivilege($userVipInfo['card'], $goodsId); } } //没有开通会员 或 没有已开通会员的优惠 if(!$cardInfo){ //先尝试匹配 指定课程绑定的会员卡 $cardInfo = $this->model->with(['card'])->where([ 'goods_id'=>$goodsId, 'card.status'=>1 ])->order('card_privilege.type','desc')->find(); $isNowGoodsVip = false; //再尝试匹配 启用「全部课程」作用域的会员卡 if (!$cardInfo) { $cardInfo = $this->findScopeAllCardForGoods($goodsId); } } if($cardInfo){ $cardInfo->getRelation('card')->visible(['title','privilege_discount_val']); $cardInfo->visible(['type','card']); } $this->success('获取成功', ['goodsVipInfo'=>$cardInfo,'isNowGoodsVip'=>$isNowGoodsVip]); } /** * 当用户已开通会员卡,构造「全部课程」作用域下的权益伪记录 * @param array $card 已开通的会员卡 * @param int $goodsId * @return false|\app\api\model\app\vip\CardPrivilege */ protected function buildScopeAllCardPrivilege($card, $goodsId) { if (!$card) { return false; } if (!\app\common\model\app\vip\CardPrivilege::isCourseInScopeAll($goodsId)) { return false; } //优先 free 权益(与现有 order desc 一致) if ($card['privilege_free'] == 1 && ($card['privilege_free_scope'] ?? 'specify') == 'all') { return $this->makeVirtualPrivilege($card, 'free'); } if ($card['privilege_discount'] == 1 && ($card['privilege_discount_scope'] ?? 'specify') == 'all') { return $this->makeVirtualPrivilege($card, 'discount'); } return false; } /** * 全平台范围内查找:开启了「全部课程」作用域且作用于当前课程的会员卡 * @param int $goodsId * @return false|\app\api\model\app\vip\CardPrivilege */ protected function findScopeAllCardForGoods($goodsId) { if (!\app\common\model\app\vip\CardPrivilege::isCourseInScopeAll($goodsId)) { return false; } $cardModel = new \app\api\model\app\vip\Card(); //优先 free 权益 $card = $cardModel->where([ 'status' => 1, 'uniacid' => UNIACID, 'privilege_free' => 1, 'privilege_free_scope' => 'all' ])->find(); if ($card) { return $this->makeVirtualPrivilege($card, 'free'); } //其次 discount 权益 $card = $cardModel->where([ 'status' => 1, 'uniacid' => UNIACID, 'privilege_discount' => 1, 'privilege_discount_scope' => 'all' ])->find(); if ($card) { return $this->makeVirtualPrivilege($card, 'discount'); } return false; } /** * 构造一条虚拟的 CardPrivilege 模型实例(不入库),用于统一返回结构 * @param mixed $card * @param string $type free|discount * @return \app\api\model\app\vip\CardPrivilege */ protected function makeVirtualPrivilege($card, $type) { $privilege = new \app\api\model\app\vip\CardPrivilege(); $privilege->type = $type; $privilege->goods_id = 0; $privilege->card_id = $card['id']; //通过 setRelation 注入关联,避免再次查库 $cardData = is_object($card) ? $card : (new \app\api\model\app\vip\Card())->data($card); $privilege->setRelation('card', $cardData); return $privilege; } }