ItemRecipe.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. namespace App\Module\GameItems\Models;
  3. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  4. use Illuminate\Database\Eloquent\Relations\HasMany;
  5. use UCore\ModelCore;
  6. /**
  7. * 物品合成配方
  8. *
  9. * field start
  10. * @property int $id 配方ID,主键
  11. * @property string $name 配方名称
  12. * @property string $code 配方编码(唯一)
  13. * @property string $description 配方描述
  14. * @property int $consume_group_id 消耗组ID
  15. * @property int $reward_group_id 奖励组ID
  16. * @property int $condition_group_id 条件组ID
  17. * @property float $success_rate 成功率(0-1之间的小数)
  18. * @property int $cooldown_seconds 冷却时间(秒)
  19. * @property int $category_id 配方分类ID
  20. * @property int $sort_order 排序权重
  21. * @property bool $is_active 是否激活(0:否, 1:是)
  22. * @property \Carbon\Carbon $created_at 创建时间
  23. * @property \Carbon\Carbon $updated_at 更新时间
  24. * field end
  25. */
  26. class ItemRecipe extends ModelCore
  27. {
  28. /**
  29. * 与模型关联的表名
  30. *
  31. * @var string
  32. */
  33. protected $table = 'item_recipes';
  34. // attrlist start
  35. protected $fillable = [
  36. 'id',
  37. 'name',
  38. 'code',
  39. 'description',
  40. 'consume_group_id',
  41. 'reward_group_id',
  42. 'condition_group_id',
  43. 'success_rate',
  44. 'cooldown_seconds',
  45. 'category_id',
  46. 'sort_order',
  47. 'is_active',
  48. ];
  49. // attrlist end
  50. /**
  51. * 应该被转换为原生类型的属性
  52. *
  53. * @var array
  54. */
  55. protected $casts = [
  56. 'consume_group_id' => 'integer',
  57. 'reward_group_id' => 'integer',
  58. 'condition_group_id' => 'integer',
  59. 'success_rate' => 'float',
  60. 'cooldown_seconds' => 'integer',
  61. 'category_id' => 'integer',
  62. 'sort_order' => 'integer',
  63. 'is_active' => 'boolean',
  64. ];
  65. /**
  66. * 获取消耗组
  67. *
  68. * @return BelongsTo
  69. */
  70. public function consumeGroup(): BelongsTo
  71. {
  72. return $this->belongsTo(\App\Module\Game\Models\GameConsumeGroup::class, 'consume_group_id');
  73. }
  74. /**
  75. * 获取奖励组
  76. *
  77. * @return BelongsTo
  78. */
  79. public function rewardGroup(): BelongsTo
  80. {
  81. return $this->belongsTo(\App\Module\Game\Models\GameRewardGroup::class, 'reward_group_id');
  82. }
  83. /**
  84. * 获取条件组
  85. *
  86. * @return BelongsTo
  87. */
  88. public function conditionGroup(): BelongsTo
  89. {
  90. return $this->belongsTo(\App\Module\Game\Models\GameConditionGroup::class, 'condition_group_id');
  91. }
  92. /**
  93. * 获取用户配方解锁状态
  94. *
  95. * @return HasMany
  96. */
  97. public function userRecipes(): HasMany
  98. {
  99. return $this->hasMany(ItemUserRecipe::class, 'recipe_id');
  100. }
  101. /**
  102. * 获取合成记录
  103. *
  104. * @return HasMany
  105. */
  106. public function craftLogs(): HasMany
  107. {
  108. return $this->hasMany(ItemCraftLog::class, 'recipe_id');
  109. }
  110. /**
  111. * 检查用户是否已解锁该配方
  112. *
  113. * @param int $userId 用户ID
  114. * @return bool
  115. */
  116. public function isUnlockedByUser(int $userId): bool
  117. {
  118. $userRecipe = $this->userRecipes()
  119. ->where('user_id', $userId)
  120. ->first();
  121. return $userRecipe && $userRecipe->is_unlocked;
  122. }
  123. /**
  124. * 格式化消耗组详情用于显示
  125. *
  126. * @return string
  127. */
  128. public function formatConsumeDetails(): string
  129. {
  130. if (!$this->consumeGroup) {
  131. return '<span class="text-muted">无消耗组</span>';
  132. }
  133. return $this->consumeGroup->formatConsumeDetails();
  134. }
  135. /**
  136. * 格式化奖励组详情用于显示
  137. *
  138. * @return string
  139. */
  140. public function formatRewardDetails(): string
  141. {
  142. if (!$this->rewardGroup) {
  143. return '<span class="text-muted">无奖励组</span>';
  144. }
  145. return $this->rewardGroup->formatRewardDetails();
  146. }
  147. /**
  148. * 格式化条件组详情用于显示
  149. *
  150. * @return string
  151. */
  152. public function formatConditionDetails(): string
  153. {
  154. if (!$this->conditionGroup) {
  155. return '<span class="text-muted">无条件组</span>';
  156. }
  157. return $this->conditionGroup->formatConditionDetails();
  158. }
  159. /**
  160. * 检查用户是否可以合成该配方
  161. *
  162. * @param int $userId 用户ID
  163. * @return array 检查结果,包含是否可合成和原因
  164. */
  165. public function canCraftByUser(int $userId): array
  166. {
  167. // 检查配方是否激活
  168. if (!$this->is_active) {
  169. return [
  170. 'can_craft' => false,
  171. 'reason' => '配方未激活',
  172. ];
  173. }
  174. // 检查条件组(如果设置了条件组)
  175. if ($this->condition_group_id && $this->conditionGroup) {
  176. $conditionService = app(\App\Module\Game\Services\ConditionService::class);
  177. $conditionResult = $conditionService->checkCondition($userId, $this->condition_group_id);
  178. if (!$conditionResult['success']) {
  179. return [
  180. 'can_craft' => false,
  181. 'reason' => '条件不满足: ' . $conditionResult['message'],
  182. ];
  183. }
  184. }
  185. // 检查消耗组是否满足
  186. if ($this->consume_group_id && $this->consumeGroup) {
  187. $consumeService = app(\App\Module\Game\Services\ConsumeService::class);
  188. $consumeResult = $consumeService->checkConsume($userId, $this->consume_group_id);
  189. if (!$consumeResult['success']) {
  190. return [
  191. 'can_craft' => false,
  192. 'reason' => '材料不足: ' . $consumeResult['message'],
  193. ];
  194. }
  195. }
  196. return [
  197. 'can_craft' => true,
  198. ];
  199. }
  200. }