'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)); } }