ShopItemDto.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. namespace App\Module\Shop\Dtos;
  3. use App\Module\Shop\Models\ShopItem;
  4. use UCore\Dto\BaseDto;
  5. /**
  6. * 商店商品数据传输对象
  7. *
  8. * 用于在服务层和控制器层之间传递商店商品数据,避免直接暴露模型
  9. */
  10. class ShopItemDto extends BaseDto
  11. {
  12. /**
  13. * 商品ID
  14. *
  15. * @var int
  16. */
  17. public int $id;
  18. /**
  19. * 商品名称
  20. *
  21. * @var string
  22. */
  23. public string $name;
  24. /**
  25. * 商品描述
  26. *
  27. * @var string|null
  28. */
  29. public ?string $description;
  30. /**
  31. * 分类ID
  32. *
  33. * @var int|null
  34. */
  35. public ?int $categoryId;
  36. /**
  37. * 分类名称(字符串格式)
  38. *
  39. * @var string|null
  40. */
  41. public ?string $categoryName;
  42. /**
  43. * 消耗组ID
  44. *
  45. * @var int|null
  46. */
  47. public ?int $consumeGroupId;
  48. /**
  49. * 消耗组名称
  50. *
  51. * @var string|null
  52. */
  53. public ?string $consumeGroupName;
  54. /**
  55. * 消耗组描述
  56. *
  57. * @var string|null
  58. */
  59. public ?string $consumeGroupDescription;
  60. /**
  61. * 奖励组ID
  62. *
  63. * @var int|null
  64. */
  65. public ?int $rewardGroupId;
  66. /**
  67. * 奖励组名称
  68. *
  69. * @var string|null
  70. */
  71. public ?string $rewardGroupName;
  72. /**
  73. * 奖励组描述
  74. *
  75. * @var string|null
  76. */
  77. public ?string $rewardGroupDescription;
  78. /**
  79. * 最大购买数量(0表示无限制)
  80. *
  81. * @var int
  82. */
  83. public int $maxBuy;
  84. /**
  85. * 是否激活
  86. *
  87. * @var bool
  88. */
  89. public bool $isActive;
  90. /**
  91. * 排序权重
  92. *
  93. * @var int
  94. */
  95. public int $sortOrder;
  96. /**
  97. * 展示属性
  98. *
  99. * @var array|null
  100. */
  101. public ?array $displayAttributes;
  102. /**
  103. * 上架时间(时间戳)
  104. *
  105. * @var int|null
  106. */
  107. public ?int $startTime;
  108. /**
  109. * 下架时间(时间戳)
  110. *
  111. * @var int|null
  112. */
  113. public ?int $endTime;
  114. /**
  115. * 创建时间
  116. *
  117. * @var string
  118. */
  119. public string $createdAt;
  120. /**
  121. * 更新时间
  122. *
  123. * @var string
  124. */
  125. public string $updatedAt;
  126. /**
  127. * 用户已购买数量(可选,需要传入用户ID时才设置)
  128. *
  129. * @var int|null
  130. */
  131. public ?int $userBoughtCount = null;
  132. /**
  133. * 当前有效的促销活动(可选)
  134. *
  135. * @var ShopPromotionDto|null
  136. */
  137. public ?ShopPromotionDto $activePromotion = null;
  138. /**
  139. * 从模型创建DTO
  140. *
  141. * @param ShopItem $shopItem 商店商品模型
  142. * @param int|null $userId 用户ID(可选,用于获取用户购买数量)
  143. * @return self
  144. */
  145. public static function fromModel(ShopItem $shopItem, ?int $userId = null): self
  146. {
  147. $dto = new self();
  148. $dto->id = $shopItem->id;
  149. $dto->name = $shopItem->name;
  150. $dto->description = $shopItem->description;
  151. $dto->categoryId = $shopItem->category_id;
  152. $dto->categoryName = $shopItem->category_name ?? ($shopItem->category->name ?? null);
  153. $dto->consumeGroupId = $shopItem->consume_group_id;
  154. $dto->consumeGroupName = $shopItem->consumeGroup->name ?? null;
  155. $dto->consumeGroupDescription = $shopItem->consumeGroup->description ?? null;
  156. $dto->rewardGroupId = $shopItem->reward_group_id;
  157. $dto->rewardGroupName = $shopItem->rewardGroup->name ?? null;
  158. $dto->rewardGroupDescription = $shopItem->rewardGroup->description ?? null;
  159. $dto->maxBuy = $shopItem->max_single_buy;
  160. $dto->isActive = $shopItem->is_active;
  161. $dto->sortOrder = $shopItem->sort_order;
  162. $dto->displayAttributes = $shopItem->display_attributes ? $shopItem->display_attributes->toArray() : null;
  163. $dto->startTime = $shopItem->start_time ? $shopItem->start_time->timestamp : null;
  164. $dto->endTime = $shopItem->end_time ? $shopItem->end_time->timestamp : null;
  165. $dto->createdAt = $shopItem->created_at->toDateTimeString();
  166. $dto->updatedAt = $shopItem->updated_at->toDateTimeString();
  167. // 如果提供了用户ID,获取用户已购买数量
  168. if ($userId !== null) {
  169. $dto->userBoughtCount = $shopItem->getUserBoughtCount($userId);
  170. }
  171. // 获取当前有效的促销活动
  172. $activePromotion = $shopItem->getActivePromotion();
  173. if ($activePromotion) {
  174. $dto->activePromotion = ShopPromotionDto::fromModel($activePromotion);
  175. }
  176. return $dto;
  177. }
  178. /**
  179. * 从模型创建DTO(优化版本,避免N+1查询)
  180. *
  181. * @param ShopItem $shopItem 商店商品模型
  182. * @param int|null $userId 用户ID(可选,用于获取用户购买数量)
  183. * @param array $userBoughtCounts 用户购买数量数组(预先查询)
  184. * @return self
  185. */
  186. public static function fromModelOptimized(ShopItem $shopItem, ?int $userId = null, array $userBoughtCounts = []): self
  187. {
  188. $dto = new self();
  189. $dto->id = $shopItem->id;
  190. $dto->name = $shopItem->name;
  191. $dto->description = $shopItem->description;
  192. $dto->categoryId = $shopItem->category_id;
  193. $dto->categoryName = $shopItem->category_name ?? ($shopItem->category->name ?? null);
  194. $dto->consumeGroupId = $shopItem->consume_group_id;
  195. $dto->consumeGroupName = $shopItem->consumeGroup->name ?? null;
  196. $dto->consumeGroupDescription = $shopItem->consumeGroup->description ?? null;
  197. $dto->rewardGroupId = $shopItem->reward_group_id;
  198. $dto->rewardGroupName = $shopItem->rewardGroup->name ?? null;
  199. $dto->rewardGroupDescription = $shopItem->rewardGroup->description ?? null;
  200. $dto->maxBuy = $shopItem->max_single_buy;
  201. $dto->isActive = $shopItem->is_active;
  202. $dto->sortOrder = $shopItem->sort_order;
  203. $dto->displayAttributes = $shopItem->display_attributes ? $shopItem->display_attributes->toArray() : null;
  204. $dto->startTime = $shopItem->start_time ? $shopItem->start_time->timestamp : null;
  205. $dto->endTime = $shopItem->end_time ? $shopItem->end_time->timestamp : null;
  206. $dto->createdAt = $shopItem->created_at->toDateTimeString();
  207. $dto->updatedAt = $shopItem->updated_at->toDateTimeString();
  208. // 使用预先查询的用户购买数量,避免N+1查询
  209. if ($userId !== null) {
  210. $dto->userBoughtCount = $userBoughtCounts[$shopItem->id] ?? 0;
  211. }
  212. // 获取当前有效的促销活动(已通过with预加载)
  213. $activePromotion = $shopItem->promotions->first();
  214. if ($activePromotion) {
  215. $dto->activePromotion = ShopPromotionDto::fromModel($activePromotion);
  216. }
  217. return $dto;
  218. }
  219. }