ItemService.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. namespace App\Module\GameItems\Services;
  3. use App\Module\GameItems\Logics\Item as ItemLogic;
  4. use App\Module\GameItems\Models\Item;
  5. use App\Module\GameItems\Models\ItemUser;
  6. use Exception;
  7. use Illuminate\Database\Eloquent\Collection;
  8. /**
  9. * 物品服务类
  10. *
  11. * 提供物品相关的服务,包括获取用户物品、添加物品到用户背包、消耗用户物品等功能。
  12. * 该类是物品模块对外提供服务的主要入口,封装了物品操作的复杂逻辑,
  13. * 通过调用ItemLogic类实现具体的业务逻辑处理。
  14. */
  15. class ItemService
  16. {
  17. /**
  18. * 物品逻辑类
  19. *
  20. * @var ItemLogic
  21. */
  22. private $itemLogic;
  23. /**
  24. * 构造函数
  25. */
  26. public function __construct()
  27. {
  28. $this->itemLogic = new ItemLogic();
  29. }
  30. /**
  31. * 获取用户物品列表
  32. *
  33. * @param int $userId 用户ID
  34. * @param array $filters 过滤条件
  35. * @param bool $includeExpired 是否包含已过期物品
  36. * @return Collection|ItemUser[]
  37. */
  38. public function getUserItems(int $userId, array $filters = [], bool $includeExpired = false): Collection
  39. {
  40. $query = ItemUser::where('user_id', $userId)
  41. ->with(['item', 'instance']);
  42. // 应用过滤条件
  43. if (isset($filters['item_id'])) {
  44. $query->where('item_id', $filters['item_id']);
  45. }
  46. if (isset($filters['category_id'])) {
  47. $query->whereHas('item', function ($q) use ($filters) {
  48. $q->where('category_id', $filters['category_id']);
  49. });
  50. }
  51. if (isset($filters['type'])) {
  52. $query->whereHas('item', function ($q) use ($filters) {
  53. $q->where('type', $filters['type']);
  54. });
  55. }
  56. // 排除过期物品
  57. if (!$includeExpired) {
  58. $now = now();
  59. $query->where(function ($q) use ($now) {
  60. $q->whereNull('expire_at')
  61. ->orWhere('expire_at', '>', $now);
  62. })->whereHas('item', function ($q) use ($now) {
  63. $q->where(function ($subQ) use ($now) {
  64. $subQ->whereNull('global_expire_at')
  65. ->orWhere('global_expire_at', '>', $now);
  66. });
  67. });
  68. }
  69. return $query->get();
  70. }
  71. /**
  72. * 添加物品到用户背包
  73. *
  74. * @param int $userId 用户ID
  75. * @param int $itemId 物品ID
  76. * @param int $quantity 数量
  77. * @param array $options 选项
  78. * @return array 添加结果
  79. * @throws Exception
  80. */
  81. public function addItem(int $userId, int $itemId, int $quantity, array $options = []): array
  82. {
  83. // 获取物品信息
  84. $item = Item::findOrFail($itemId);
  85. // 检查物品是否已过期(全局过期)
  86. if ($this->itemLogic->isExpired($item)) {
  87. throw new Exception("物品 {$itemId} 已全局过期");
  88. }
  89. // 处理单独属性物品
  90. if ($item->is_unique) {
  91. return $this->itemLogic->addUniqueItem($userId, $itemId, $options);
  92. }
  93. // 处理统一属性物品
  94. return $this->itemLogic->addNormalItem($userId, $itemId, $quantity, $options);
  95. }
  96. /**
  97. * 消耗用户物品
  98. *
  99. * @param int $userId 用户ID
  100. * @param int $itemId 物品ID
  101. * @param int|null $instanceId 物品实例ID(单独属性物品)
  102. * @param int $quantity 数量
  103. * @param array $options 选项
  104. * @return array 消耗结果
  105. * @throws Exception
  106. */
  107. public function consumeItem(int $userId, int $itemId, ?int $instanceId, int $quantity, array $options = []): array
  108. {
  109. // 获取物品信息
  110. $item = Item::findOrFail($itemId);
  111. if ($instanceId) {
  112. // 消耗单独属性物品
  113. return $this->itemLogic->consumeUniqueItem($userId, $itemId, $instanceId, $options);
  114. } else {
  115. // 消耗统一属性物品
  116. return $this->itemLogic->consumeNormalItem($userId, $itemId, $quantity, $options);
  117. }
  118. }
  119. }