function ($q) { $now = Carbon::now(); $q->where('is_active', true) ->where(function ($q) use ($now) { $q->whereNull('start_time') ->orWhere('start_time', '<=', $now); }) ->where(function ($q) use ($now) { $q->whereNull('end_time') ->orWhere('end_time', '>=', $now); }) ->orderBy('sort_order', 'asc'); } ]) ->where('is_active', true) ->where(function ($q) { $now = Carbon::now(); $q->where(function ($q) use ($now) { $q->whereNull('start_time') ->whereNull('end_time'); })->orWhere(function ($q) use ($now) { $q->where('start_time', '<=', $now) ->where('end_time', '>=', $now); })->orWhere(function ($q) use ($now) { $q->where('start_time', '<=', $now) ->whereNull('end_time'); })->orWhere(function ($q) use ($now) { $q->whereNull('start_time') ->where('end_time', '>=', $now); }); }); // 应用过滤条件 if (isset($filters['category_id'])) { $query->where('category_id', $filters['category_id']); } // 注意:由于商品结构已改为消耗组和奖励组模式,不再支持按item_id过滤 // if (isset($filters['item_id'])) { // $query->where('item_id', $filters['item_id']); // } if (isset($filters['keyword'])) { $keyword = $filters['keyword']; $query->where(function ($q) use ($keyword) { $q->where('name', 'like', "%{$keyword}%") ->orWhere('description', 'like', "%{$keyword}%"); // 注意:由于商品结构已改为消耗组和奖励组模式,不再支持按关联物品名称搜索 // ->orWhereHas('item', function ($q) use ($keyword) { // $q->where('name', 'like', "%{$keyword}%"); // }); }); } // 是否只获取促销商品 if (isset($filters['only_promotion']) && $filters['only_promotion']) { $query->whereHas('promotions', function ($q) { $now = Carbon::now(); $q->where('is_active', true) ->where(function ($q) use ($now) { $q->whereNull('start_time') ->orWhere('start_time', '<=', $now); }) ->where(function ($q) use ($now) { $q->whereNull('end_time') ->orWhere('end_time', '>=', $now); }); }); } // 按促销活动过滤 if (isset($filters['promotion_id'])) { $query->whereHas('promotions', function ($q) use ($filters) { $q->where('id', $filters['promotion_id']); }); } // 排序 $query->orderBy('sort_order', 'asc') ->orderBy('id', 'asc'); // 获取商品列表 $items = $query->get(); // 注意:由于商品结构已改为消耗组和奖励组模式,不再有固定价格 // 折扣价格计算需要根据消耗组和促销活动重新实现 // foreach ($items as $item) { // $item->original_price = $item->price; // $item->discounted_price = $item->getDiscountedPrice(); // $item->has_discount = $item->discounted_price < $item->original_price; // $item->discount_percentage = $item->original_price > 0 // ? round((1 - $item->discounted_price / $item->original_price) * 100) // : 0; // } return $items; } /** * 获取商店分类列表 * * @param bool $onlyActive 是否只获取激活的分类 * @return Collection 分类列表 */ public function getShopCategories(bool $onlyActive = true): Collection { $query = ShopCategory::query(); if ($onlyActive) { $query->where('is_active', true); } return $query->orderBy('sort_order', 'asc')->get(); } /** * 获取商店分类树 * * @param bool $onlyActive 是否只获取激活的分类 * @return array 分类树 */ public function getShopCategoryTree(bool $onlyActive = true): array { return ShopCategory::getCategoryTree($onlyActive); } /** * 检查用户购买限制 * * @param int $userId 用户ID * @param ShopItem $shopItem 商品 * @param int $quantity 购买数量 * @return array [是否可购买, 错误消息] */ public function checkBuyLimit(int $userId, ShopItem $shopItem, int $quantity): array { // 检查商品是否激活 if (!$shopItem->is_active) { return [false, '该商品已下架']; } // 检查商品是否在有效期内 $now = Carbon::now(); if (($shopItem->start_time && $now < $shopItem->start_time) || ($shopItem->end_time && $now > $shopItem->end_time)) { return [false, '该商品不在销售时间内']; } // 检查购买数量是否有效 if ($quantity <= 0) { return [false, '购买数量必须大于0']; } // 检查购买限制 if ($shopItem->max_buy > 0) { $boughtCount = $shopItem->getUserBoughtCount($userId); if ($boughtCount + $quantity > $shopItem->max_buy) { return [false, "超出购买限制,最多还能购买" . ($shopItem->max_buy - $boughtCount) . "个"]; } } // 注意:由于商品结构已改为消耗组和奖励组模式,不再检查单一关联物品 // 需要检查消耗组和奖励组是否存在 if ($shopItem->consume_group_id && !$shopItem->consumeGroup) { return [false, '商品关联的消耗组不存在']; } if ($shopItem->reward_group_id && !$shopItem->rewardGroup) { return [false, '商品关联的奖励组不存在']; } return [true, '']; } /** * 记录购买日志 * * @param int $userId 用户ID * @param ShopItem $shopItem 商品 * @param int $quantity 购买数量 * @param int $totalPrice 总价 * @return ShopPurchaseLog 购买日志 */ public function recordPurchase(int $userId, ShopItem $shopItem, int $quantity, int $totalPrice): ShopPurchaseLog { return $shopItem->recordPurchase($userId, $quantity, $totalPrice); } /** * 获取用户购买记录 * * @param int $userId 用户ID * @param array $filters 过滤条件 * @return Collection 购买记录 */ public function getUserPurchaseHistory(int $userId, array $filters = []): Collection { $query = ShopPurchaseLog::with(['shopItem']) ->where('user_id', $userId); // 应用过滤条件 if (isset($filters['shop_item_id'])) { $query->where('shop_item_id', $filters['shop_item_id']); } if (isset($filters['item_id'])) { $query->where('item_id', $filters['item_id']); } if (isset($filters['start_date'])) { $query->where('purchase_time', '>=', $filters['start_date']); } if (isset($filters['end_date'])) { $query->where('purchase_time', '<=', $filters['end_date']); } // 排序 $query->orderBy('purchase_time', 'desc'); return $query->get(); } /** * 获取促销活动列表 * * @param array $filters 过滤条件 * @return Collection 促销活动列表 */ public function getPromotions(array $filters = []): Collection { $query = ShopPromotion::with('items'); // 是否只获取激活的促销活动 if (isset($filters['only_active']) && $filters['only_active']) { $query->where('is_active', true); } // 是否只获取当前有效的促销活动 if (isset($filters['only_valid']) && $filters['only_valid']) { $now = Carbon::now(); $query->where('is_active', true) ->where(function ($q) use ($now) { $q->whereNull('start_time') ->orWhere('start_time', '<=', $now); }) ->where(function ($q) use ($now) { $q->whereNull('end_time') ->orWhere('end_time', '>=', $now); }); } // 按分类过滤 if (isset($filters['category_id'])) { $query->whereHas('items', function ($q) use ($filters) { $q->where('category_id', $filters['category_id']); }); } // 按关键词搜索 if (isset($filters['keyword'])) { $keyword = $filters['keyword']; $query->where(function ($q) use ($keyword) { $q->where('name', 'like', "%{$keyword}%") ->orWhere('description', 'like', "%{$keyword}%"); }); } // 排序 $query->orderBy('sort_order', 'asc') ->orderBy('id', 'asc'); return $query->get(); } /** * 获取促销活动详情 * * @param int $promotionId 促销活动ID * @return ShopPromotion|null 促销活动详情 */ public function getPromotionDetail(int $promotionId): ?ShopPromotion { return ShopPromotion::with('items')->find($promotionId); } /** * 添加商品到促销活动 * * @param int $promotionId 促销活动ID * @param int $shopItemId 商品ID * @param int|null $customDiscountValue 自定义折扣值 * @return ShopPromotionItem 促销商品关联 */ public function addItemToPromotion(int $promotionId, int $shopItemId, ?int $customDiscountValue = null): ShopPromotionItem { // 检查促销活动是否存在 ShopPromotion::findOrFail($promotionId); // 检查商品是否存在 ShopItem::findOrFail($shopItemId); // 检查商品是否已经在促销活动中 $existingItem = ShopPromotionItem::where('promotion_id', $promotionId) ->where('shop_item_id', $shopItemId) ->first(); if ($existingItem) { // 更新自定义折扣值 $existingItem->custom_discount_value = $customDiscountValue; $existingItem->save(); return $existingItem; } // 创建新的关联 $promotionItem = new ShopPromotionItem([ 'promotion_id' => $promotionId, 'shop_item_id' => $shopItemId, 'custom_discount_value' => $customDiscountValue, ]); $promotionItem->save(); return $promotionItem; } /** * 从促销活动中移除商品 * * @param int $promotionId 促销活动ID * @param int $shopItemId 商品ID * @return bool 是否成功 */ public function removeItemFromPromotion(int $promotionId, int $shopItemId): bool { return ShopPromotionItem::where('promotion_id', $promotionId) ->where('shop_item_id', $shopItemId) ->delete() > 0; } }