初始化项目:添加后端代码、ThinkPHP框架、前端资源

This commit is contained in:
amb
2026-09-03 12:42:39 +08:00
commit 482bece22e
3726 changed files with 416708 additions and 0 deletions
@@ -0,0 +1,267 @@
<?php
namespace app\api\controller\app\vip;
use app\common\controller\Api;
/**
* 付费会员卡
*/
class CardPrivilege extends Api
{
protected $noNeedLogin = ["getGoodsPrivilege"];
protected $noNeedRight = ['*'];
protected $model = null;
protected $cardPrivilegeModel = null;
public function _initialize()
{
parent::_initialize();
\app\common\model\fill\Handle::check('app_config','vip');
$this->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;
}
}