| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- <?php
- namespace App\Module\Game\Logics;
- use App\Module\Game\Dtos\PetCreatedTempDto;
- use App\Module\Game\Dtos\PetDataSimpleTempDto;
- use App\Module\Game\Dtos\PetStatusTempDto;
- use App\Module\Pet\Events\PetCreatedEvent;
- use App\Module\Pet\Events\PetStatusChangedEvent;
- use App\Module\Pet\Events\PetUpdateEvent;
- use App\Module\Pet\Services\PetService;
- use Illuminate\Support\Facades\Log;
- use UCore\Helper\Cache;
- /**
- * 宠物临时数据逻辑类
- *
- * 负责处理宠物相关事件的临时数据存储逻辑,包括:
- * 1. 将宠物创建数据临时存储
- * 2. 将宠物状态变更数据临时存储
- * 3. 按照用户进行存储
- * 4. 同一宠物多次变更进行数据覆盖
- */
- class PetTemp
- {
- // 已移除 TEMP_KEY_CREATED_PREFIX,与 TEMP_KEY_UPDATE_PREFIX 合并
- /**
- * 临时数据键前缀 - 宠物状态变更
- */
- const TEMP_KEY_STATUS_PREFIX = 'game:pet:status:';
- /**
- * 临时数据键前缀 - 宠物更新
- */
- const TEMP_KEY_UPDATE_PREFIX = 'game:pet:update:';
- /**
- * 临时数据过期时间(秒)
- */
- const TEMP_TTL = 3600; // 1小时
- /**
- * 处理宠物完整数据事件
- *
- * 将宠物完整数据临时存储,按用户ID进行存储
- * 这是一个通用方法,用于处理PetCreatedEvent和PetUpdateEvent事件
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @param string $eventType 事件类型,用于日志
- * @return void
- */
- private static function handlePetFullData(int $userId, int $petId, string $eventType): void
- {
- try {
- // 构建临时数据键,按用户ID进行存储
- $tempKey = self::TEMP_KEY_UPDATE_PREFIX . $userId;
- // 获取当前用户的宠物临时数据
- $userPetsTemp = Cache::get($tempKey, []);
- try {
- // 使用服务层获取宠物数据,避免跨模块直接访问Model
- $petDto = PetService::getPetStatus($userId, $petId);
- // 创建PetStatusTempDto对象
- $tempDto = new PetStatusTempDto();
- // 复制属性
- foreach ($petDto->toArray() as $key => $value) {
- $property = \UCore\Dto\BaseDto::snakeToCamel($key);
- if (property_exists($tempDto, $property)) {
- $tempDto->{$property} = $value;
- }
- }
- // 设置更新时间
- $tempDto->updatedAt = time();
- // 使用宠物ID作为键,实现同一宠物多次变更的数据覆盖
- // 直接存储DTO对象,而不是转换为数组
- $userPetsTemp[$petId] = $tempDto;
- // 将更新后的数据存回临时存储
- Cache::put($tempKey, $userPetsTemp, self::TEMP_TTL);
- Log::info("宠物{$eventType}数据已临时存储", [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'name' => $tempDto->name,
- 'level' => $tempDto->level,
- 'grade' => $tempDto->grade,
- ]);
- } catch (\Exception $e) {
- // 如果服务层调用失败,记录错误并抛出异常
- Log::error("获取宠物数据失败", [
- 'error' => $e->getMessage(),
- 'user_id' => $userId,
- 'pet_id' => $petId,
- ]);
- throw $e;
- }
- } catch (\Exception $e) {
- Log::error("宠物{$eventType}数据临时存储失败", [
- 'error' => $e->getMessage(),
- 'user_id' => $userId,
- 'pet_id' => $petId,
- ]);
- }
- }
- /**
- * 处理宠物创建事件
- *
- * 将宠物创建数据临时存储,按用户ID进行存储
- *
- * @param PetCreatedEvent $event 宠物创建事件
- * @return void
- */
- public static function handlePetCreated(PetCreatedEvent $event): void
- {
- self::handlePetFullData($event->userId, $event->petId, '创建');
- }
- /**
- * 处理宠物状态变更事件
- *
- * 将宠物状态变更数据临时存储,按用户ID进行存储
- *
- * @param PetStatusChangedEvent $event 宠物状态变更事件
- * @return void
- */
- public static function handlePetStatusChanged(PetStatusChangedEvent $event): void
- {
- try {
- // 构建临时数据键,按用户ID进行存储
- $tempKey = self::TEMP_KEY_STATUS_PREFIX . $event->userId;
- // 获取当前用户的宠物状态变更临时数据
- $userPetsStatusTemp = Cache::get($tempKey, []);
- // 创建PetDataSimpleTempDto对象
- $tempDto = new PetDataSimpleTempDto();
- // 从事件中复制宠物基本数据
- $tempDto->id = $event->petId;
- $tempDto->typeId = $event->petData->typeId;
- $tempDto->name = $event->petData->name;
- $tempDto->level = $event->petData->level;
- $tempDto->exp = $event->petData->exp;
- $tempDto->power = $event->petData->power;
- $tempDto->maxpower = $event->petData->maxpower;
- $tempDto->score = $event->petData->score;
- $tempDto->status = $event->newStatusData->status;
- $tempDto->grade = $event->petData->grade;
- // 设置状态变更相关属性
- $tempDto->oldStatus = $event->oldStatusData->status;
- $tempDto->newStatus = $event->newStatusData->status;
- $tempDto->reason = $event->reason;
- $tempDto->updatedAt = time();
- // 使用宠物ID作为键,实现同一宠物多次变更的数据覆盖
- // 直接存储DTO对象,而不是转换为数组
- $userPetsStatusTemp[$event->petId] = $tempDto;
- // 将更新后的数据存回临时存储
- Cache::put($tempKey, $userPetsStatusTemp, self::TEMP_TTL);
- Log::info('宠物状态变更数据已临时存储', [
- 'user_id' => $event->userId,
- 'pet_id' => $event->petId,
- 'old_status' => $event->oldStatusData->status,
- 'new_status' => $event->newStatusData->status,
- 'pet_name' => $event->petData->name,
- ]);
- } catch (\Exception $e) {
- Log::error('宠物状态变更数据临时存储失败', [
- 'error' => $e->getMessage(),
- 'user_id' => $event->userId,
- 'pet_id' => $event->petId,
- ]);
- }
- }
- /**
- * 获取用户的宠物创建临时数据
- *
- * @param int $userId 用户ID
- * @return PetStatusTempDto[] 用户的宠物创建数据
- */
- public static function getUserPetCreated(int $userId): array
- {
- // 使用统一的前缀,与宠物更新数据共用一个缓存键
- return self::getUserPetUpdates($userId);
- }
- /**
- * 获取用户特定宠物的创建临时数据
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @return PetStatusTempDto|null 宠物创建数据,不存在时返回null
- */
- public static function getUserPetCreatedById(int $userId, int $petId): ?PetStatusTempDto
- {
- // 使用统一的方法,与宠物更新数据共用一个获取方法
- return self::getUserPetUpdateById($userId, $petId);
- }
- /**
- * 获取用户的宠物状态变更临时数据
- *
- * @param int $userId 用户ID
- * @return PetDataSimpleTempDto[] 用户的宠物状态变更数据
- */
- public static function getUserPetStatus(int $userId): array
- {
- $tempKey = self::TEMP_KEY_STATUS_PREFIX . $userId;
- $cachedData = Cache::get($tempKey, []);
- // 使用fromCache方法处理缓存数据,确保返回正确类型的DTO对象
- return PetDataSimpleTempDto::fromCache($cachedData);
- }
- /**
- * 获取用户特定宠物的状态变更临时数据
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @return PetDataSimpleTempDto|null 宠物状态变更数据,不存在时返回null
- */
- public static function getUserPetStatusById(int $userId, int $petId): ?PetDataSimpleTempDto
- {
- $userPetStatus = self::getUserPetStatus($userId);
- return $userPetStatus[$petId] ?? null;
- }
- /**
- * 处理宠物更新事件
- *
- * 将宠物更新数据临时存储,按用户ID进行存储
- *
- * @param PetUpdateEvent $event 宠物更新事件
- * @return void
- */
- public static function handlePetUpdate(PetUpdateEvent $event): void
- {
- self::handlePetFullData($event->userId, $event->petId, '更新');
- }
- /**
- * 获取用户的宠物更新临时数据
- *
- * @param int $userId 用户ID
- * @return PetStatusTempDto[] 用户的宠物更新数据
- */
- public static function getUserPetUpdates(int $userId): array
- {
- $tempKey = self::TEMP_KEY_UPDATE_PREFIX . $userId;
- $cachedData = Cache::get($tempKey, []);
- // 使用fromCache方法处理缓存数据,确保返回正确类型的DTO对象
- return PetStatusTempDto::fromCache($cachedData);
- }
- /**
- * 获取用户特定宠物的更新临时数据
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @return PetStatusTempDto|null 宠物更新数据,不存在时返回null
- */
- public static function getUserPetUpdateById(int $userId, int $petId): ?PetStatusTempDto
- {
- $userPetUpdates = self::getUserPetUpdates($userId);
- return $userPetUpdates[$petId] ?? null;
- }
- /**
- * 清除用户的宠物创建临时数据
- *
- * @param int $userId 用户ID
- * @return void
- */
- public static function clearUserPetCreated(int $userId): void
- {
- // 使用统一的方法,与宠物更新数据共用一个清除方法
- self::clearUserPetUpdates($userId);
- }
- /**
- * 清除用户的宠物状态变更临时数据
- *
- * @param int $userId 用户ID
- * @return void
- */
- public static function clearUserPetStatus(int $userId): void
- {
- $tempKey = self::TEMP_KEY_STATUS_PREFIX . $userId;
- Cache::put($tempKey, [], 0);
- }
- /**
- * 清除用户的所有宠物临时数据
- *
- * @param int $userId 用户ID
- * @return void
- */
- public static function clearUserAllPetTemp(int $userId): void
- {
- self::clearUserPetCreated($userId);
- self::clearUserPetStatus($userId);
- }
- }
|