'integer', 'success_rate' => 'float', 'coin_cost' => TransactionDetailsCast::class, 'cooldown_seconds' => 'integer', 'is_visible' => 'boolean', 'unlock_condition' => TransactionDetailsCast::class, ]; /** * 获取合成结果物品 * * @return BelongsTo */ public function resultItem(): BelongsTo { return $this->belongsTo(Item::class, 'result_item_id'); } /** * 获取配方材料 * * @return HasMany */ public function materials(): HasMany { return $this->hasMany(ItemRecipeMaterial::class, 'recipe_id'); } /** * 获取用户配方解锁状态 * * @return HasMany */ public function userRecipes(): HasMany { return $this->hasMany(ItemUserRecipe::class, 'recipe_id'); } /** * 获取合成记录 * * @return HasMany */ public function craftLogs(): HasMany { return $this->hasMany(ItemCraftLog::class, 'recipe_id'); } /** * 检查用户是否已解锁该配方 * * @param int $userId 用户ID * @return bool */ public function isUnlockedByUser(int $userId): bool { $userRecipe = $this->userRecipes() ->where('user_id', $userId) ->first(); return $userRecipe && $userRecipe->is_unlocked; } /** * 检查用户是否可以合成该配方 * * @param int $userId 用户ID * @return array 检查结果,包含是否可合成和原因 */ public function canCraftByUser(int $userId): array { // 检查配方是否已解锁 if (!$this->isUnlockedByUser($userId)) { return [ 'can_craft' => false, 'reason' => '配方未解锁', ]; } // 检查冷却时间 if ($this->cooldown_seconds > 0) { $lastCraft = $this->craftLogs() ->where('user_id', $userId) ->where('created_at', '>', now()->subSeconds($this->cooldown_seconds)) ->first(); if ($lastCraft) { $remainingSeconds = $this->cooldown_seconds - now()->diffInSeconds($lastCraft->created_at); return [ 'can_craft' => false, 'reason' => '冷却中', 'remaining_seconds' => $remainingSeconds, ]; } } // 检查材料是否足够 $materials = $this->materials; $missingMaterials = []; foreach ($materials as $material) { $userItem = ItemUser::where('user_id', $userId) ->where('item_id', $material->item_id) ->whereNull('instance_id') ->sum('quantity'); if ($userItem < $material->quantity) { $missingMaterials[] = [ 'item_id' => $material->item_id, 'item_name' => $material->item->name, 'required' => $material->quantity, 'available' => $userItem, ]; } } if (!empty($missingMaterials)) { return [ 'can_craft' => false, 'reason' => '材料不足', 'missing_materials' => $missingMaterials, ]; } return [ 'can_craft' => true, ]; } }