Files

617 lines
18 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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));
}
}