value => 'fram_drought_rate', // 干旱 -> 浇水概率 DISASTER_TYPE::PEST->value => 'fram_pesticide_rate', // 虫害 -> 除虫概率 DISASTER_TYPE::WEED->value => 'fram_weedicide_rate', // 杂草 -> 除草概率 ]; /** * 灾害类型与操作名称的映射关系 */ private const DISASTER_ACTION_NAMES = [ DISASTER_TYPE::DROUGHT->value => '浇水', DISASTER_TYPE::PEST->value => '除虫', DISASTER_TYPE::WEED->value => '除草', ]; /** * 验证物品是否为有效的灾害去除道具 * * @param mixed $value 物品ID * @param array $data 包含用户ID和灾害类型的数组 * @return bool 验证是否通过 */ public function validate(mixed $value, array $data): bool { $itemId = (int)$value; // 从 args 获取字段键名 $userIdKey = $this->args[0] ?? 'user_id'; $disasterTypeKey = $this->args[1] ?? 'disaster_type'; $userId = $data[$userIdKey] ?? null; $disasterType = $data[$disasterTypeKey] ?? null; if (!$userId) { $this->addError('用户ID不能为空'); return false; } if (!$disasterType) { $this->addError('灾害类型不能为空'); return false; } // 验证灾害类型是否支持 if (!isset(self::DISASTER_ITEM_ATTRIBUTES[$disasterType])) { $this->addError("不支持的灾害类型: {$disasterType}"); return false; } try { // 验证用户是否拥有该物品 if (!$this->validateUserHasItem($userId, $itemId, $disasterType)) { return false; } // 验证物品是否具有对应的灾害去除属性 if (!$this->validateItemAttribute($itemId, $disasterType)) { return false; } return true; } catch (\Exception $e) { $this->addError('验证物品时发生错误: ' . $e->getMessage()); return false; } } /** * 验证用户是否拥有指定物品 * * @param int $userId 用户ID * @param int $itemId 物品ID * @param int $disasterType 灾害类型 * @return bool */ private function validateUserHasItem(int $userId, int $itemId, int $disasterType): bool { $hasItem = ItemService::getUserItems($userId, ['item_id' => $itemId]); if ($hasItem->isEmpty()) { $actionName = self::DISASTER_ACTION_NAMES[$disasterType]; $this->addError("您没有该{$actionName}物品"); return false; } return true; } /** * 验证物品是否具有对应的灾害去除属性 * * @param int $itemId 物品ID * @param int $disasterType 灾害类型 * @return bool */ private function validateItemAttribute(int $itemId, int $disasterType): bool { $attributeName = self::DISASTER_ITEM_ATTRIBUTES[$disasterType]; $rate = ItemService::getItemNumericAttribute($itemId, $attributeName); if ($rate <= 0) { $actionName = self::DISASTER_ACTION_NAMES[$disasterType]; $this->addError("不是{$actionName}物品"); return false; } return true; } }