617 lines
18 KiB
PHP
617 lines
18 KiB
PHP
<?php
|
||
|
||
namespace app\admin\model\app\coupon;
|
||
use think\Model;
|
||
use app\admin\model\app\coupon\CouponUser as CouponUserModel;
|
||
use app\admin\model\app\coupon\CouponGoods;
|
||
|
||
class Coupon extends Model
|
||
{
|
||
// use SoftDelete;
|
||
protected $deleteTime = 'deletetime';
|
||
|
||
protected $name = 'app_coupon';
|
||
|
||
protected $type = [
|
||
// 'use_start_time' => 'timestamp',
|
||
// 'use_end_time' => 'timestamp',
|
||
];
|
||
|
||
// 追加属性
|
||
protected $append = [
|
||
'type_text',
|
||
'use_num',
|
||
'get_num',
|
||
'status_text',
|
||
'use_scope_text',
|
||
'amount_text',
|
||
'use_time_status',
|
||
'use_time_text',
|
||
'stock_all',
|
||
'stock_prop',
|
||
'received',
|
||
'goods_bind_ids'
|
||
];
|
||
|
||
|
||
|
||
|
||
/**
|
||
* 默认类型列表
|
||
*
|
||
* @return array
|
||
*/
|
||
public function getTypeList()
|
||
{
|
||
return [
|
||
'reduce' => '满减券',
|
||
'discount' => '折扣券'
|
||
];
|
||
}
|
||
/**
|
||
* 可用范围列表
|
||
*
|
||
* @return array
|
||
*/
|
||
public function useScopeList()
|
||
{
|
||
return [
|
||
'all_use' => '全场通用',
|
||
'goods' => '指定商品可用',
|
||
'disabled_goods' => '指定商品不可用'
|
||
];
|
||
}
|
||
|
||
|
||
/**
|
||
* 优惠券领取状态
|
||
*
|
||
* @return void
|
||
*/
|
||
public function getStatusList()
|
||
{
|
||
return [
|
||
'1'=>'进行中',
|
||
'2'=>'已停止',
|
||
'3'=>'已作废',
|
||
'4'=>'未开始',
|
||
'5'=>'已结束'
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 优惠券领取状态
|
||
*
|
||
* @return void
|
||
*/
|
||
public function getGetStatusList()
|
||
{
|
||
return [
|
||
'ing'=>'立即领取',
|
||
'cannot_get'=>'已达最大领取次数',
|
||
'get_stop'=>'已停止',
|
||
'get_destroy'=>'已作废',
|
||
'ended'=>'已结束',
|
||
'get_over'=>'已领完'
|
||
];
|
||
}
|
||
|
||
|
||
public function scopeCanGet($query)
|
||
{
|
||
|
||
// 当use_time_type=range代表可用时间区间, use_start_time代表开始时间,use_end_time代表结束时间。获取可用区间内的优惠券
|
||
// 当use_time_type=days代表可用天数
|
||
//获取有效期内'deletetime'=>NULL,'status'=>1的优惠券
|
||
//获取use_time_type=days,'deletetime'=>NULL,'status'=>1的优惠券
|
||
return $query->where([
|
||
'deletetime'=>NULL,
|
||
'status'=>1
|
||
])->where(function ($query) {
|
||
$query->where(function ($query) {
|
||
$query->where('use_time_type', 'range')
|
||
->where('use_start_time', '<=', time())
|
||
->where('use_end_time', '>=', time());
|
||
})->whereOr(function ($query) {
|
||
$query->where('use_time_type', 'days');
|
||
});
|
||
});
|
||
}
|
||
|
||
public function scopePublicShow($query)
|
||
{
|
||
return $query->where([
|
||
'public_status'=>1
|
||
]);
|
||
}
|
||
|
||
|
||
/**
|
||
* 查询指定商品满足的优惠券
|
||
* @param [type] $query
|
||
* @param [type] $goods
|
||
* @return void
|
||
*/
|
||
public function scopeGoods($query, $goods)
|
||
{
|
||
$goods_id = $goods['goods_id'];
|
||
$goods_type = $goods['goods_type'];
|
||
|
||
// 查询符合商品的优惠券
|
||
return $query->where(function ($query) use ($goods_id,$goods_type) {
|
||
$query->where('use_scope', 'all_use')
|
||
->whereOr(function ($query) use ($goods_id,$goods_type) {
|
||
$query->where('use_scope', 'goods')
|
||
->whereExists(function ($subQuery) use ($goods_id,$goods_type) {
|
||
$subQuery->table(CouponGoods::getTable())
|
||
->whereRaw('`coupon_id` = `'.self::getTable().'`.`id`')
|
||
->where('goods_id', $goods_id)
|
||
->where('goods_type', $goods_type);
|
||
});
|
||
})
|
||
->whereOr(function ($query) use ($goods_id,$goods_type) {
|
||
$query->where('use_scope', 'disabled_goods')
|
||
->whereNotExists(function ($subQuery) use ($goods_id,$goods_type) {
|
||
$subQuery->table(CouponGoods::getTable())
|
||
->whereRaw('`coupon_id` = `'.self::getTable().'`.`id`')
|
||
->where('goods_id', $goods_id)
|
||
->where('goods_type', $goods_type);
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
|
||
/**
|
||
* 可用范围获取器
|
||
*
|
||
* @param string $value
|
||
* @param array $data
|
||
* @return string
|
||
*/
|
||
public function getUseScopeTextAttr($value, $data)
|
||
{
|
||
$value = $value ?: ($data['use_scope'] ?? null);
|
||
|
||
$list = $this->useScopeList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
/**
|
||
* 类型
|
||
* @param string $value
|
||
* @param array $data
|
||
* @return string
|
||
*/
|
||
public function getTypeTextAttr($value, $data)
|
||
{
|
||
$value = $value ?: ($data['type'] ?? null);
|
||
|
||
$list = $this->getTypeList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
/**
|
||
* 状态
|
||
* @param string $value
|
||
* @param array $data
|
||
* @return string
|
||
*/
|
||
public function getStatusTextAttr($value, $data)
|
||
{
|
||
|
||
$value = $value ?: ($data['status'] ?? null);
|
||
|
||
$list = $this->getStatusList();
|
||
return isset($list[$value]) ? $list[$value] : '';
|
||
}
|
||
|
||
|
||
public function getAmountTextAttr($value, $data)
|
||
{
|
||
return '满' . $data['enough'] . '元,' . ($data['type'] == 'reduce' ? '减' . floatval($data['amount']) . '元' : '打' . floatval($data['discount']) . '折');
|
||
}
|
||
|
||
public function getGoodsValueAttr($value, $data)
|
||
{
|
||
$goods_value = [];
|
||
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
|
||
$query = \app\common\model\goods\Handle::getGoodsQuery();
|
||
|
||
$goods = CouponGoods::where([
|
||
'coupon_id'=>$data['id']
|
||
])->field(['goods_type','goods_id'])->select();
|
||
|
||
|
||
if($goods){
|
||
foreach ($goods as $item){
|
||
$query->whereOr(function ($query) use ($item){
|
||
$query->where([
|
||
'id'=>$item['goods_id'],
|
||
'type'=>$item['goods_type']
|
||
]);
|
||
});
|
||
}
|
||
$goods_value = $query->select();
|
||
$goods_value = collection($goods_value);
|
||
}
|
||
|
||
}
|
||
|
||
return $goods_value ?? [];
|
||
}
|
||
|
||
|
||
/**
|
||
* 通过优惠券 ids 集合获取可正常展示的优惠券
|
||
* @param $ids
|
||
* @return void
|
||
*/
|
||
public function idsGetCoupon($ids,$limit=0){
|
||
$user = user_info();
|
||
$coupons = self::canGet()
|
||
->publicShow()
|
||
->where([
|
||
'id'=>['in',$ids]
|
||
]) // 符合指定商品,并且检测商品所属分类
|
||
->order('id', 'desc');
|
||
|
||
if($limit){
|
||
$coupons = $coupons->limit($limit);
|
||
}
|
||
|
||
if ($user) {
|
||
// 关联用户优惠券
|
||
$coupons = $coupons->with(['userCoupons']);
|
||
}
|
||
$coupons = $coupons->select();
|
||
|
||
$coupons = collection($coupons)->each(function ($coupon) {
|
||
$coupon->get_status = $coupon->get_status;
|
||
$coupon->get_status_text = $coupon->get_status_text;
|
||
});
|
||
|
||
return $coupons;
|
||
}
|
||
|
||
/**
|
||
* 通过优惠券 ids 集合获取可正常展示的优惠券
|
||
* @param $ids
|
||
* @return void
|
||
*/
|
||
public function getNewCoupon($limit=0){
|
||
$user = user_info();
|
||
$coupons = self::canGet()
|
||
->publicShow()
|
||
->order('id', 'desc');
|
||
|
||
if($limit){
|
||
$coupons->limit($limit);
|
||
}
|
||
if ($user) {
|
||
// 关联用户优惠券
|
||
$coupons = $coupons->with(['userCoupons']);
|
||
}
|
||
$coupons = $coupons->select();
|
||
|
||
$coupons = collection($coupons)->each(function ($coupon) {
|
||
$coupon->get_status = $coupon->get_status;
|
||
$coupon->get_status_text = $coupon->get_status_text;
|
||
});
|
||
|
||
return $coupons;
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取优惠券绑定的商品列表
|
||
* @param $value
|
||
* @param $data
|
||
* @return array
|
||
*/
|
||
public function getGoodsBindIdsAttr($value, $data)
|
||
{
|
||
$goods_value = [];
|
||
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
|
||
$goods = CouponGoods::where([
|
||
'coupon_id'=>$data['id']
|
||
])->field(['goods_type','goods_id'])->select();
|
||
|
||
|
||
if($goods){
|
||
foreach ($goods as $item){
|
||
$goods_value[] = $item['goods_id']."_".$item['goods_type'];
|
||
}
|
||
}
|
||
}
|
||
|
||
return $goods_value ?? [];
|
||
}
|
||
|
||
|
||
/**
|
||
* 优惠券可使用的商品列表
|
||
* @param $value
|
||
* @param $data
|
||
* @return array
|
||
*/
|
||
public function getCanUseGoodsValueAttr($value, $data)
|
||
{
|
||
$query = \app\common\model\goods\Handle::getGoodsQuery();
|
||
|
||
$queryCondition = [
|
||
'pay_type'=>'pay',
|
||
'status'=>1
|
||
];
|
||
|
||
$excludeTypes = ['test'];
|
||
|
||
if (\app\common\library\Platform::getPlatform() === 'wxMiniProgram') {
|
||
$virtualPayConfig = \app\common\model\config\System::getConfig('virtual_pay');
|
||
if ($virtualPayConfig && ($virtualPayConfig['status'] ?? 'close') === 'open') {
|
||
$virtualGoodsTypes = $virtualPayConfig['virtual_goods_types'] ?? [];
|
||
if (!empty($virtualGoodsTypes)) {
|
||
$excludeTypes = array_merge($excludeTypes, $virtualGoodsTypes);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (in_array($data['use_scope'], ['goods', 'disabled_goods'])) {
|
||
|
||
$goods = CouponGoods::where([
|
||
'coupon_id'=>$data['id']
|
||
])->field(['goods_type','goods_id'])->select();
|
||
|
||
if($data['use_scope'] == 'goods'){
|
||
if(!$goods){
|
||
return [];
|
||
}
|
||
foreach ($goods as $item){
|
||
if (in_array($item['goods_type'], $excludeTypes, true)) {
|
||
continue;
|
||
}
|
||
$query->whereOr(function ($query) use ($item,$queryCondition){
|
||
$query->where([
|
||
'id'=>$item['goods_id'],
|
||
'type'=>$item['goods_type']
|
||
])->where($queryCondition);
|
||
});
|
||
}
|
||
}else{
|
||
if($goods){
|
||
$filteredGoods = [];
|
||
foreach ($goods as $item) {
|
||
if (in_array($item['goods_type'], $excludeTypes, true)) {
|
||
continue;
|
||
}
|
||
$filteredGoods[] = $item;
|
||
}
|
||
|
||
if (!empty($filteredGoods)) {
|
||
$subQuery = \app\common\model\goods\Handle::getGoodsQuery()->where(function ($query) use ($filteredGoods,$queryCondition) {
|
||
foreach ($filteredGoods as $item) {
|
||
$query->whereOr(function ($q) use ($item,$queryCondition) {
|
||
$q->where([
|
||
'id'=>$item['goods_id'],
|
||
'type'=>$item['goods_type']
|
||
])->where($queryCondition);
|
||
});
|
||
}
|
||
})->buildSql();
|
||
|
||
// 查询不满足条件的数据
|
||
$query->where('id', 'not in', function ($query) use ($subQuery) {
|
||
$query->table($subQuery . ' temp')->field('id');
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}else{
|
||
$query = $query->where($queryCondition);
|
||
if (!empty($excludeTypes)) {
|
||
$query->where('type', 'not in', $excludeTypes);
|
||
}
|
||
}
|
||
|
||
$goods_value = $query->limit(100)->order('goods.id',"desc")->select();
|
||
|
||
$goods_value = collection($goods_value);
|
||
|
||
return $goods_value ?? [];
|
||
}
|
||
|
||
/**
|
||
* 判断是否已领取
|
||
* @param $value
|
||
* @param $data
|
||
* @return void
|
||
*/
|
||
public function getReceivedAttr($value, $data)
|
||
{
|
||
$user = user_info();
|
||
if(!$user){
|
||
return false;
|
||
}
|
||
|
||
$canUse = CouponUserModel::where('user_id', $user->id)
|
||
->where('coupon_id', $data['id'])
|
||
->find();
|
||
|
||
if(!$canUse){
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public function getGetStatusAttr($value, $data)
|
||
{
|
||
|
||
if($data['status'] == 2){
|
||
return 'get_stop'; // 已停止
|
||
}
|
||
|
||
if($data['status'] == 3){
|
||
return 'get_destroy'; // 已作废
|
||
}
|
||
|
||
$limit_num = $data['limit_status'] == 1 ? 10000 : ($data['limit_num'] ?? 0);
|
||
// 不限制领取次数,或者限制次数,领取数量还没达到最大值
|
||
$get_status = (!$limit_num || ($limit_num && $limit_num > count($this->user_coupons))) ? 'can_get' : 'cannot_get';
|
||
|
||
if ($get_status == 'can_get' && $data['stock'] <= 0) {
|
||
$get_status = 'get_over'; // 已领完
|
||
}
|
||
|
||
// $user_coupon_id = request()->param('ucid', 0);
|
||
// if ($user_coupon_id) {
|
||
// // 从我领取的优惠券进详情,覆盖 状态
|
||
// $user = user_info();
|
||
// $userCoupon = CouponUserModel::where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
|
||
// if ($userCoupon) {
|
||
// $get_status = $userCoupon->status;
|
||
// }
|
||
// }
|
||
return $get_status;
|
||
}
|
||
|
||
|
||
public function getGetStatusTextAttr($value, $data)
|
||
{
|
||
$list = $this->getGetStatusList();
|
||
return isset($list[$this->get_status]) ? $list[$this->get_status] : '';
|
||
}
|
||
|
||
|
||
/**
|
||
* 后端发放状态
|
||
*
|
||
* @return string
|
||
*/
|
||
public function getUseTimeStatusAttr($value, $data) {
|
||
|
||
if($data['use_time_type'] == 'days'){
|
||
return 'ing';
|
||
}
|
||
|
||
if ($data['use_start_time'] > time()) {
|
||
$time_text = 'nostart'; // 未开始
|
||
} else if ($data['use_start_time'] <= time() && $data['use_end_time'] >= time()) {
|
||
$time_text = 'ing';
|
||
} else if ($data['use_end_time'] < time()) {
|
||
$time_text = 'ended';
|
||
}
|
||
|
||
return $time_text;
|
||
}
|
||
|
||
|
||
/**
|
||
* 后端发放状态
|
||
*
|
||
* @return string
|
||
*/
|
||
public function getUseTimeTextAttr($value, $data)
|
||
{
|
||
if ($this->use_time_status == 'nostart') {
|
||
$time_text = '未开始'; // 未开始
|
||
} else if ($this->use_time_status == 'ing') {
|
||
$time_text = '发放中';
|
||
} else if ($this->use_time_status == 'ended') {
|
||
$time_text = '已结束';
|
||
}
|
||
|
||
return $time_text;
|
||
}
|
||
|
||
/**
|
||
* 获取所有库存
|
||
* @param $value
|
||
* @param $data
|
||
* @return mixed
|
||
*/
|
||
public function getStockAllAttr($value, $data)
|
||
{
|
||
$useCount = CouponUserModel::where('coupon_id', $data['id'])->count();
|
||
return $data['stock'] + $useCount;
|
||
}
|
||
|
||
/**
|
||
* 获取所有库存
|
||
* @param $value
|
||
* @param $data
|
||
* @return mixed
|
||
*/
|
||
public function getStockPropAttr($value, $data)
|
||
{
|
||
$useCount = CouponUserModel::where('coupon_id', $data['id'])->count();
|
||
$stock = (int) $data['stock'];
|
||
$total = $stock + $useCount;
|
||
|
||
// 防止除以零
|
||
if ($total <= 0) {
|
||
return 0;
|
||
}
|
||
|
||
return floor($stock / $total * 100);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
public function getGetNumAttr($value, $data)
|
||
{
|
||
return CouponUserModel::where('coupon_id', $data['id'])->count();
|
||
}
|
||
|
||
|
||
public function getUseNumAttr($value, $data)
|
||
{
|
||
return CouponUserModel::where('coupon_id', $data['id'])->whereNotNull('use_time')->count();
|
||
}
|
||
|
||
|
||
|
||
public function getUseStartTimeAttr($value, $data)
|
||
{
|
||
$use_start_time = $value ? date('Y-m-d H:i', $value) : null;
|
||
$user_coupon_id = request()->param('ucid', 0);
|
||
if ($user_coupon_id && $data['use_time_type'] == 'days') {
|
||
// 从我领取的优惠券进详情,覆盖 状态
|
||
$user = user_info();
|
||
$userCoupon = CouponUserModel::cache(60)->where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
|
||
if ($userCoupon) {
|
||
$use_start_time = date('Y-m-d H:i', $userCoupon->getData('createtime') + ($this->start_days * 86400));
|
||
}
|
||
}
|
||
|
||
return $use_start_time;
|
||
}
|
||
|
||
public function getUseEndTimeAttr($value, $data)
|
||
{
|
||
$use_end_time = $value ? date('Y-m-d H:i', $value) : null;
|
||
$user_coupon_id = request()->param('ucid', 0);
|
||
if ($user_coupon_id && $data['use_time_type'] == 'days') {
|
||
// 从我领取的优惠券进详情,覆盖 状态
|
||
$user = user_info();
|
||
$userCoupon = CouponUserModel::cache(60)->where('user_id', ($user ? $user->id : 0))->find($user_coupon_id);
|
||
if ($userCoupon) {
|
||
$use_end_time = date('Y-m-d H:i', $userCoupon->getData('createtime') + (($this->start_days + $this->days) * 86400));
|
||
}
|
||
}
|
||
|
||
return $use_end_time;
|
||
}
|
||
|
||
|
||
public function userCoupons()
|
||
{
|
||
|
||
$user = user_info();
|
||
return $this->hasMany(CouponUserModel::class, 'coupon_id')->where('user_id', ($user ? $user->id : 0));
|
||
}
|
||
}
|