ItemTemp.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace App\Module\Game\Logics;
  3. use App\Module\Game\Dtos\ItemChangeTempDto;
  4. use App\Module\GameItems\Events\ItemQuantityChanged;
  5. use Illuminate\Support\Facades\Log;
  6. use UCore\Helper\Cache;
  7. /**
  8. * 物品临时数据逻辑类
  9. *
  10. * 负责处理物品变更事件的临时数据存储逻辑,包括:
  11. * 1. 将物品变更数据临时存储
  12. * 2. 按照用户进行存储
  13. * 3. 同一物品多次变更进行数据覆盖
  14. */
  15. class ItemTemp
  16. {
  17. /**
  18. * 临时数据键前缀
  19. */
  20. const TEMP_KEY_PREFIX = 'game:item:changed:';
  21. /**
  22. * 临时数据过期时间(秒)
  23. */
  24. const TEMP_TTL = 3600; // 1小时
  25. /**
  26. * 处理物品数量变更事件
  27. *
  28. * 将物品变更数据临时存储,按用户ID和物品ID进行存储
  29. * 同一物品多次变更会覆盖之前的数据
  30. *
  31. * @param ItemQuantityChanged $event 物品数量变更事件
  32. * @return void
  33. */
  34. public static function handleItemQuantityChanged(ItemQuantityChanged $event): void
  35. {
  36. try {
  37. // 构建临时数据键,按用户ID进行存储
  38. $tempKey = self::TEMP_KEY_PREFIX . $event->userId;
  39. // 获取当前用户的物品变更临时数据
  40. $userItemsTemp = Cache::get($tempKey, []);
  41. // 构建物品变更数据
  42. $itemData = [
  43. 'item_id' => $event->itemId,
  44. 'instance_id' => $event->instanceId,
  45. 'old_quantity' => $event->oldQuantity,
  46. 'new_quantity' => $event->newQuantity,
  47. 'change_amount' => $event->changeAmount,
  48. 'user_item_id' => $event->userItemId,
  49. 'old_frozen_status' => $event->oldFrozenStatus,
  50. 'new_frozen_status' => $event->newFrozenStatus,
  51. 'updated_at' => time(),
  52. ];
  53. // 使用用户物品记录ID作为键,避免同一物品的不同堆叠相互覆盖
  54. // 这样可以正确处理拆堆等场景下的多个物品堆状态同步
  55. $userItemsTemp[$event->userItemId] = $itemData;
  56. // 将更新后的数据存回临时存储
  57. Cache::put($tempKey, $userItemsTemp, self::TEMP_TTL);
  58. Log::info('物品变更数据已临时存储', [
  59. 'user_id' => $event->userId,
  60. 'item_id' => $event->itemId,
  61. 'change_amount' => $event->changeAmount,
  62. ]);
  63. } catch (\Exception $e) {
  64. Log::error('物品变更数据临时存储失败', [
  65. 'error' => $e->getMessage(),
  66. 'user_id' => $event->userId,
  67. 'item_id' => $event->itemId,
  68. ]);
  69. }
  70. }
  71. /**
  72. * 获取用户的物品变更临时数据
  73. *
  74. * @param int $userId 用户ID
  75. * @return ItemChangeTempDto[] 用户的物品变更数据
  76. */
  77. public static function getUserItemChanges(int $userId): array
  78. {
  79. $tempKey = self::TEMP_KEY_PREFIX . $userId;
  80. $rawData = Cache::get($tempKey, []);
  81. $result = [];
  82. foreach ($rawData as $userItemId => $itemData) {
  83. $result[] = ItemChangeTempDto::fromArray($itemData);
  84. }
  85. return $result;
  86. }
  87. /**
  88. * 获取用户特定物品的变更临时数据(通过物品ID)
  89. *
  90. * @param int $userId 用户ID
  91. * @param int $itemId 物品ID
  92. * @return ItemChangeTempDto[] 该物品的所有变更数据
  93. */
  94. public static function getUserItemChange(int $userId, int $itemId): array
  95. {
  96. $userItemChanges = self::getUserItemChanges($userId);
  97. $result = [];
  98. foreach ($userItemChanges as $itemChange) {
  99. if ($itemChange->itemId === $itemId) {
  100. $result[] = $itemChange;
  101. }
  102. }
  103. return $result;
  104. }
  105. /**
  106. * 获取用户特定用户物品记录的变更临时数据(通过用户物品记录ID)
  107. *
  108. * @param int $userId 用户ID
  109. * @param int $userItemId 用户物品记录ID
  110. * @return ItemChangeTempDto|null 物品变更数据,不存在时返回null
  111. */
  112. public static function getUserItemChangeByUserItemId(int $userId, int $userItemId): ?ItemChangeTempDto
  113. {
  114. $tempKey = self::TEMP_KEY_PREFIX . $userId;
  115. $rawData = Cache::get($tempKey, []);
  116. if (!isset($rawData[$userItemId])) {
  117. return null;
  118. }
  119. return ItemChangeTempDto::fromArray($rawData[$userItemId]);
  120. }
  121. /**
  122. * 清除用户的物品变更临时数据
  123. *
  124. * @param int $userId 用户ID
  125. * @return void
  126. */
  127. public static function clearUserItemChanges(int $userId): void
  128. {
  129. $tempKey = self::TEMP_KEY_PREFIX . $userId;
  130. Cache::put($tempKey, [], 0);
  131. }
  132. }