userValidCoupons($user); $couponSkus = []; $availableCoupons = []; foreach ($coupons as $coupon) { if (!isset($couponSkus[$coupon->coupon_id])) { foreach ($skus as $sku) { //这个商品是否在这个券的可用范围 if ($this->isAvailableCouponToSku($sku, $coupon)) { //按coupon_id 分组商品 $couponSkus[$coupon->coupon_id][] = $sku; } } } } foreach ($coupons as $coupon) { // 这个券是否有可用的商品 if (isset($couponSkus[$coupon->coupon_id])) { //用户是否是vip if ($user->isVip()) { $totalAmount = collect($couponSkus[$coupon->coupon_id])->sum(function ($item) { return bcmul($item['vip_price'], $item['num']); }); } else { $totalAmount = collect($couponSkus[$coupon->coupon_id])->sum(function ($item) { return bcmul($item['sell_price'], $item['num']); }); } //针对这个券,可用的商品合计价格是否满足使用门槛 if ($totalAmount >= $coupon->coupon_threshold) { $availableCoupons[] = $coupon; } } } return collect($availableCoupons); } /** * 用户有效的优惠券 * * @param User $user * @return collection */ public function userValidCoupons(User $user): collection { return UserCoupon::with('ranges')->where([ 'user_id'=>$user->id, ])->onlyUnuse()->get(); } /** * 这批商品中,这个券是否可用 * * @return boolean */ protected function isAvailableCouponToSomeSku(collection $skus, UserCoupon $coupon) { $res = false; foreach ($skus as $sku) { if ($sku instanceof ProductSku && $this->isAvailableCouponToSku($sku, $coupon)) { $res = true; break;//提前退出循环 } } return $res; } /** * 这个商品是否可用这个券 * * @param array $productSku ['id', 'category_id', 'sell_price', 'vip_price', 'num'] * @param Coupon $coupon * @return boolean */ protected function isAvailableCouponToSku($sku, UserCoupon $coupon) { $res = false; if ($coupon->ranges->count() == 0) {//如果没有规则则通用 return true; } foreach ($coupon->ranges as $range) { switch ($range->type) { case 1://指定商品分类 if (in_array($sku['category_id'], explode(',', $range->ranges))) { $res = true; } break; case 2://指定商品IDS if (in_array($sku['id'], explode(',', $range->ranges))) { $res = true; } break; } if ($res) {//如果可用提前跳出循环; break; } } return $res; } }