CropLogic.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. <?php
  2. namespace App\Module\Farm\Logics;
  3. use App\Module\Farm\Dtos\CropInfoDto;
  4. use App\Module\Farm\Dtos\HarvestResultDto;
  5. use App\Module\Farm\Enums\GROWTH_STAGE;
  6. use App\Module\Farm\Enums\LAND_STATUS;
  7. use App\Module\Farm\Events\CropGrowthStageChangedEvent;
  8. use App\Module\Farm\Events\CropHarvestedEvent;
  9. use App\Module\Farm\Events\CropPlantedEvent;
  10. use App\Module\Farm\Events\DisasterClearedEvent;
  11. use App\Module\Farm\Events\LandStatusChangedEvent;
  12. use App\Module\Farm\Models\FarmCrop;
  13. use App\Module\Farm\Models\FarmHarvestLog;
  14. use App\Module\Farm\Models\FarmLand;
  15. use App\Module\Farm\Models\FarmSeed;
  16. use App\Module\Farm\Models\FarmSeedOutput;
  17. use App\Module\Farm\Models\FarmSowLog;
  18. use App\Module\GameItems\Services\ItemService;
  19. use Illuminate\Support\Facades\DB;
  20. use Illuminate\Support\Facades\Log;
  21. use UCore\Db\Helper;
  22. use UCore\DcatAdmin\Herlper;
  23. use UCore\Dto\Res;
  24. /**
  25. * 作物管理逻辑
  26. */
  27. class CropLogic
  28. {
  29. /**
  30. * 获取作物信息
  31. *
  32. * @param int $cropId
  33. * @return CropInfoDto|null
  34. */
  35. public function getCropInfo(int $cropId): ?CropInfoDto
  36. {
  37. try {
  38. $crop = FarmCrop::find($cropId);
  39. if (!$crop) {
  40. return null;
  41. }
  42. return CropInfoDto::fromModel($crop);
  43. } catch (\Exception $e) {
  44. Log::error('获取作物信息失败', [
  45. 'crop_id' => $cropId,
  46. 'error' => $e->getMessage(),
  47. 'trace' => $e->getTraceAsString()
  48. ]);
  49. return null;
  50. }
  51. }
  52. /**
  53. * 获取土地上的作物信息
  54. *
  55. * @param int $landId
  56. * @return CropInfoDto|null
  57. */
  58. public function getCropByLandId(int $landId): ?CropInfoDto
  59. {
  60. try {
  61. $crop = FarmCrop::where('land_id', $landId)->first();
  62. if (!$crop) {
  63. return null;
  64. }
  65. return CropInfoDto::fromModel($crop);
  66. } catch (\Exception $e) {
  67. Log::error('获取土地作物信息失败', [
  68. 'land_id' => $landId,
  69. 'error' => $e->getMessage(),
  70. 'trace' => $e->getTraceAsString()
  71. ]);
  72. return null;
  73. }
  74. }
  75. /**
  76. * 种植作物
  77. *
  78. * @param int $userId
  79. * @param int $landId
  80. * @param int $seedId
  81. * @return array|null 返回包含CropInfoDto和日志ID的数组,格式为['crop' => CropInfoDto, 'log_id' => int]
  82. * @throws \Exception
  83. */
  84. public function plantCrop(int $userId, int $landId, int $seedId): ?array
  85. {
  86. try {
  87. // 检查是否已开启事务
  88. \UCore\Db\Helper::check_tr();
  89. // 获取土地信息
  90. $land = FarmLand::where('id', $landId)
  91. ->where('user_id', $userId)
  92. ->first();
  93. if (!$land) {
  94. throw new \Exception('土地不存在');
  95. }
  96. // 检查土地状态
  97. if ($land->status !== LAND_STATUS::IDLE->value) {
  98. throw new \Exception('土地状态不允许种植');
  99. }
  100. // 获取种子信息
  101. $seed = FarmSeed::find($seedId);
  102. if (!$seed) {
  103. throw new \Exception('种子不存在');
  104. }
  105. // 创建作物记录
  106. $crop = new FarmCrop();
  107. $crop->land_id = $landId;
  108. $crop->user_id = $userId;
  109. $crop->seed_id = $seedId;
  110. $crop->plant_time = now();
  111. $crop->growth_stage = GROWTH_STAGE::SEED->value;
  112. $crop->stage_start_time = now(); // 设置当前阶段开始时间
  113. $crop->stage_end_time = now()->addSeconds($seed->seed_time);
  114. $crop->disasters = [];
  115. $crop->fertilized = false;
  116. $crop->save();
  117. // 创建种植日志
  118. $sowLog = new FarmSowLog();
  119. $sowLog->user_id = $userId;
  120. $sowLog->land_id = $landId;
  121. $sowLog->crop_id = $crop->id;
  122. $sowLog->seed_id = $seedId;
  123. $sowLog->sow_time = now();
  124. $sowLog->save();
  125. // 更新土地状态
  126. $land->status = LAND_STATUS::PLANTING->value;
  127. $land->save();
  128. // 触发作物种植事件
  129. event(new CropPlantedEvent($userId, $land, $crop));
  130. Log::info('作物种植成功', [
  131. 'user_id' => $userId,
  132. 'land_id' => $landId,
  133. 'seed_id' => $seedId,
  134. 'crop_id' => $crop->id,
  135. 'sow_log_id' => $sowLog->id
  136. ]);
  137. return [
  138. 'crop' => CropInfoDto::fromModel($crop),
  139. 'log_id' => $sowLog->id
  140. ];
  141. } catch (\Exception $e) {
  142. // 回滚事务
  143. DB::rollBack();
  144. Log::error('作物种植失败', [
  145. 'user_id' => $userId,
  146. 'land_id' => $landId,
  147. 'seed_id' => $seedId,
  148. 'error' => $e->getMessage(),
  149. 'trace' => $e->getTraceAsString()
  150. ]);
  151. return null;
  152. }
  153. }
  154. /**
  155. * 收获作物
  156. *
  157. * @param int $userId
  158. * @param int $landId
  159. * @return HarvestResultDto|null
  160. */
  161. public function harvestCrop(int $userId, int $landId): Res
  162. {
  163. try {
  164. // 事务检查
  165. Helper::check_tr();
  166. // 获取土地信息
  167. /**
  168. * @var FarmLand $land
  169. */
  170. $land = FarmLand::where('id', $landId)
  171. ->where('user_id', $userId)
  172. ->first();
  173. if (!$land) {
  174. throw new \Exception('土地不存在');
  175. }
  176. // 检查土地状态
  177. // if ($land->status !== LAND_STATUS::HARVESTABLE->value) {
  178. // throw new \Exception('土地状态不允许收获');
  179. // }
  180. // 获取作物信息
  181. $crop = FarmCrop::where('land_id', $landId)->first();
  182. if (!$crop) {
  183. throw new \Exception('作物不存在');
  184. }
  185. // 检查作物生长阶段
  186. if ($crop->growth_stage !== GROWTH_STAGE::MATURE) {
  187. throw new \Exception('作物未成熟,不能收获');
  188. }
  189. // 获取种子信息
  190. $seed = $crop->seed;
  191. if (!$seed) {
  192. throw new \Exception('种子信息不存在');
  193. }
  194. // 随机选择产出物品
  195. $outputInfo = $this->getRandomOutput($seed->id);
  196. $outputItemId = $outputInfo['item_id'];
  197. $outputAmount = mt_rand($outputInfo['min_amount'], $outputInfo['max_amount']);
  198. // 创建收获记录
  199. $harvestLog = new FarmHarvestLog();
  200. $harvestLog->user_id = $userId;
  201. $harvestLog->land_id = $landId;
  202. $harvestLog->crop_id = $crop->id;
  203. $harvestLog->seed_id = $seed->id;
  204. $harvestLog->output_amount = $outputAmount;
  205. $harvestLog->harvest_time = now();
  206. $harvestLog->created_at = now();
  207. $harvestLog->save();
  208. // 删除作物记录
  209. $crop->delete();
  210. // 更新土地状态
  211. $land->status = LAND_STATUS::IDLE;
  212. $land->save();
  213. // 触发作物收获事件
  214. event(new CropHarvestedEvent($userId, $land, $crop, $harvestLog, $outputItemId, $outputAmount));
  215. Log::info('作物收获成功', [
  216. 'user_id' => $userId,
  217. 'land_id' => $landId,
  218. 'crop_id' => $crop->id,
  219. 'seed_id' => $seed->id,
  220. 'output_item_id' => $outputItemId,
  221. 'output_amount' => $outputAmount,
  222. 'harvest_log_id' => $harvestLog->id
  223. ]);
  224. // 物品入包
  225. ItemService::addItem($userId, $outputItemId, $outputAmount,[
  226. 'source'=>'FarmHarve',
  227. 'FarmHarvestLog'=>$harvestLog->id
  228. ]);
  229. return Res::success();
  230. } catch (\Exception $e) {
  231. // 回滚事务
  232. Log::error('作物收获失败', [
  233. 'user_id' => $userId,
  234. 'land_id' => $landId,
  235. 'error' => $e->getMessage(),
  236. 'trace' => $e->getTraceAsString()
  237. ]);
  238. return Res::error('');
  239. }
  240. }
  241. /**
  242. * 使用化肥
  243. *
  244. * @param int $userId
  245. * @param int $landId
  246. * @return bool
  247. */
  248. public function useFertilizer(int $userId, int $landId,int $crop_growth_time): Res
  249. {
  250. try {
  251. Helper::check_tr();
  252. // 获取土地信息
  253. /**
  254. * @var FarmLand $land
  255. */
  256. $land = FarmLand::where('id', $landId)
  257. ->where('user_id', $userId)
  258. ->first();
  259. if (!$land) {
  260. throw new \Exception('土地不存在');
  261. }
  262. // 检查土地状态
  263. if ($land->status !== LAND_STATUS::PLANTING->valueInt()) {
  264. throw new \Exception('土地状态不允许使用化肥');
  265. }
  266. // 获取作物信息
  267. /**
  268. * @var FarmCrop $crop
  269. */
  270. $crop = FarmCrop::where('land_id', $landId)->first();
  271. if (!$crop) {
  272. throw new \Exception('作物不存在');
  273. }
  274. // 检查作物生长阶段
  275. if (!GROWTH_STAGE::canUseFertilizer($crop->growth_stage)) {
  276. throw new \Exception('当前生长阶段不能使用化肥');
  277. }
  278. // 检查是否已经使用过化肥
  279. if ($crop->fertilized) {
  280. throw new \Exception('当前阶段已经使用过化肥');
  281. }
  282. // 更新作物信息
  283. $crop->fertilized = true;
  284. // 根据 crop_growth_time 参数减少当前阶段时间
  285. if ($crop->stage_end_time) {
  286. $currentTime = now();
  287. $endTime = $crop->stage_end_time;
  288. // dd($endTime);
  289. $remainingTime = $currentTime->diffInSeconds($endTime, false);
  290. if ($remainingTime > 0) {
  291. // 确保减少的时间不超过剩余时间
  292. $reducedTime = min($crop_growth_time, $remainingTime);
  293. $crop->stage_end_time = $endTime->subSeconds($reducedTime);
  294. Log::info('化肥减少生长时间', [
  295. 'crop_id' => $crop->id,
  296. 'reduced_time' => $reducedTime,
  297. 'original_end_time' => $endTime->toDateTimeString(),
  298. 'new_end_time' => $crop->stage_end_time->toDateTimeString(),
  299. 'stage_start_time' => $crop->stage_start_time->toDateTimeString()
  300. ]);
  301. }
  302. }
  303. $crop->save();
  304. Log::info('使用化肥成功', [
  305. 'user_id' => $userId,
  306. 'land_id' => $landId,
  307. 'crop_id' => $crop->id,
  308. 'growth_stage' => $crop->growth_stage,
  309. 'stage_end_time' => $crop->stage_end_time
  310. ]);
  311. return Res::success('',[
  312. 'crop_id' => $crop->id,
  313. ]);
  314. } catch (\Exception $e) {
  315. Log::error('使用化肥失败', [
  316. 'user_id' => $userId,
  317. 'land_id' => $landId,
  318. 'error' => $e->getMessage(),
  319. 'trace' => $e->getTraceAsString()
  320. ]);
  321. return Res::error('使用化肥失败');
  322. }
  323. }
  324. /**
  325. * 清理灾害
  326. *
  327. * @param int $userId
  328. * @param int $landId
  329. * @param int $disasterType
  330. * @return bool
  331. */
  332. public function clearDisaster(int $userId, int $landId, int $disasterType): bool
  333. {
  334. try {
  335. // 获取土地信息
  336. $land = FarmLand::where('id', $landId)
  337. ->where('user_id', $userId)
  338. ->first();
  339. if (!$land) {
  340. throw new \Exception('土地不存在');
  341. }
  342. // 检查土地状态
  343. if ($land->status !== LAND_STATUS::DISASTER->value) {
  344. throw new \Exception('土地没有灾害');
  345. }
  346. // 获取作物信息
  347. $crop = FarmCrop::where('land_id', $landId)->first();
  348. if (!$crop) {
  349. throw new \Exception('作物不存在');
  350. }
  351. // 检查灾害是否存在
  352. $disasters = $crop->disasters ?? [];
  353. $disasterIndex = -1;
  354. $disasterInfo = null;
  355. foreach ($disasters as $index => $disaster) {
  356. if (($disaster['type'] ?? 0) == $disasterType && ($disaster['status'] ?? '') === 'active') {
  357. $disasterIndex = $index;
  358. $disasterInfo = $disaster;
  359. break;
  360. }
  361. }
  362. if ($disasterIndex === -1 || !$disasterInfo) {
  363. throw new \Exception('指定类型的灾害不存在');
  364. }
  365. // 更新灾害状态
  366. $disasters[$disasterIndex]['status'] = 'cleared';
  367. $disasters[$disasterIndex]['cleared_at'] = now()->toDateTimeString();
  368. $crop->disasters = $disasters;
  369. // 检查是否还有其他活跃灾害
  370. $hasActiveDisaster = false;
  371. foreach ($disasters as $disaster) {
  372. if (($disaster['status'] ?? '') === 'active') {
  373. $hasActiveDisaster = true;
  374. break;
  375. }
  376. }
  377. // 如果没有其他活跃灾害,更新土地状态
  378. if (!$hasActiveDisaster) {
  379. $land->status = LAND_STATUS::PLANTING->value;
  380. }
  381. // 保存更改
  382. $crop->save();
  383. $land->save();
  384. // 触发灾害清理事件
  385. event(new DisasterClearedEvent($userId, $crop, $disasterType, $disasterInfo));
  386. Log::info('灾害清理成功', [
  387. 'user_id' => $userId,
  388. 'land_id' => $landId,
  389. 'crop_id' => $crop->id,
  390. 'disaster_type' => $disasterType
  391. ]);
  392. return true;
  393. } catch (\Exception $e) {
  394. Log::error('灾害清理失败', [
  395. 'user_id' => $userId,
  396. 'land_id' => $landId,
  397. 'disaster_type' => $disasterType,
  398. 'error' => $e->getMessage(),
  399. 'trace' => $e->getTraceAsString()
  400. ]);
  401. return false;
  402. }
  403. }
  404. /**
  405. * 铲除作物
  406. *
  407. * @param int $userId
  408. * @param int $landId
  409. * @return bool
  410. */
  411. public function removeCrop(int $userId, int $landId): bool
  412. {
  413. try {
  414. // 开启事务
  415. DB::beginTransaction();
  416. // 获取土地信息
  417. $land = FarmLand::where('id', $landId)
  418. ->where('user_id', $userId)
  419. ->first();
  420. if (!$land) {
  421. throw new \Exception('土地不存在');
  422. }
  423. // 检查土地状态
  424. if ($land->status === LAND_STATUS::IDLE->value) {
  425. throw new \Exception('土地上没有作物');
  426. }
  427. // 获取作物信息
  428. $crop = FarmCrop::where('land_id', $landId)->first();
  429. if (!$crop) {
  430. // 如果没有作物但土地状态不是空闲,修正土地状态
  431. $land->status = LAND_STATUS::IDLE->value;
  432. $land->save();
  433. DB::commit();
  434. return true;
  435. }
  436. // 删除作物记录
  437. $crop->delete();
  438. // 更新土地状态
  439. $land->status = LAND_STATUS::IDLE->value;
  440. $land->save();
  441. // 提交事务
  442. DB::commit();
  443. Log::info('铲除作物成功', [
  444. 'user_id' => $userId,
  445. 'land_id' => $landId,
  446. 'crop_id' => $crop->id
  447. ]);
  448. return true;
  449. } catch (\Exception $e) {
  450. // 回滚事务
  451. DB::rollBack();
  452. Log::error('铲除作物失败', [
  453. 'user_id' => $userId,
  454. 'land_id' => $landId,
  455. 'error' => $e->getMessage(),
  456. 'trace' => $e->getTraceAsString()
  457. ]);
  458. return false;
  459. }
  460. }
  461. /**
  462. * 更新作物生长阶段
  463. *
  464. * @param int $cropId
  465. * @return bool
  466. */
  467. public function updateGrowthStage(int $cropId): bool
  468. {
  469. try {
  470. // 获取作物信息
  471. $crop = FarmCrop::find($cropId);
  472. if (!$crop) {
  473. throw new \Exception('作物不存在');
  474. }
  475. // 检查是否需要更新
  476. if (!$crop->stage_end_time || $crop->stage_end_time > now()) {
  477. return false;
  478. }
  479. // 获取当前生长阶段
  480. $oldStage = $crop->growth_stage;
  481. // 计算新的生长阶段
  482. $newStage = $this->calculateNextStage($crop);
  483. // 如果阶段没有变化,不需要更新
  484. if ($newStage === $oldStage) {
  485. return false;
  486. }
  487. // 计算新阶段的结束时间
  488. $stageEndTime = $this->calculateStageEndTime($crop, $newStage);
  489. // 更新作物信息
  490. $crop->growth_stage = $newStage;
  491. $crop->stage_start_time = now(); // 设置新阶段的开始时间
  492. $crop->stage_end_time = $stageEndTime;
  493. $crop->fertilized = false; // 重置施肥状态
  494. $crop->save();
  495. // 触发生长阶段变更事件
  496. event(new CropGrowthStageChangedEvent($crop->user_id, $crop, $oldStage->value, $newStage));
  497. Log::info('作物生长阶段更新成功', [
  498. 'crop_id' => $cropId,
  499. 'user_id' => $crop->user_id,
  500. 'old_stage' => $oldStage,
  501. 'new_stage' => $newStage,
  502. 'stage_end_time' => $stageEndTime
  503. ]);
  504. return true;
  505. } catch (\Exception $e) {
  506. Log::error('作物生长阶段更新失败', [
  507. 'crop_id' => $cropId,
  508. 'error' => $e->getMessage(),
  509. 'trace' => $e->getTraceAsString()
  510. ]);
  511. return false;
  512. }
  513. }
  514. /**
  515. * 计算下一个生长阶段
  516. *
  517. * @param FarmCrop $crop
  518. * @return int
  519. */
  520. public function calculateNextStage(FarmCrop $crop): int
  521. {
  522. $currentStage = $crop->growth_stage;
  523. // 如果当前是成熟期,且超过一定时间,则进入枯萎期
  524. if ($currentStage === GROWTH_STAGE::MATURE->value) {
  525. // 成熟期持续时间,默认为24小时
  526. $matureDuration = 24 * 60 * 60;
  527. // 如果成熟期已经超过指定时间,则进入枯萎期
  528. if ($crop->stage_end_time && $crop->stage_end_time instanceof \Carbon\Carbon) {
  529. $endTimeMinusDuration = $crop->stage_end_time->copy()->subSeconds($matureDuration);
  530. if (now()->diffInSeconds($endTimeMinusDuration) > $matureDuration) {
  531. return GROWTH_STAGE::WITHERED->value;
  532. }
  533. }
  534. return GROWTH_STAGE::MATURE->value;
  535. }
  536. // 使用阶段映射确定下一个阶段
  537. $stageMap = [
  538. GROWTH_STAGE::SEED->value => GROWTH_STAGE::SPROUT->value,
  539. GROWTH_STAGE::SPROUT->value => GROWTH_STAGE::GROWTH->value,
  540. GROWTH_STAGE::GROWTH->value => GROWTH_STAGE::MATURE->value,
  541. GROWTH_STAGE::MATURE->value => GROWTH_STAGE::WITHERED->value,
  542. GROWTH_STAGE::WITHERED->value => GROWTH_STAGE::WITHERED->value, // 枯萎期保持不变
  543. ];
  544. return $stageMap[$currentStage->value] ?? GROWTH_STAGE::WITHERED->value;
  545. }
  546. /**
  547. * 计算阶段结束时间
  548. *
  549. * @param FarmCrop $crop
  550. * @param int $stage
  551. * @return \Carbon\Carbon|null
  552. */
  553. private function calculateStageEndTime(FarmCrop $crop, int $stage)
  554. {
  555. $seed = $crop->seed;
  556. if (!$seed) {
  557. return null;
  558. }
  559. $now = now();
  560. switch ($stage) {
  561. case GROWTH_STAGE::SEED->value:
  562. return $now->addSeconds($seed->seed_time);
  563. case GROWTH_STAGE::SPROUT->value:
  564. return $now->addSeconds($seed->sprout_time);
  565. case GROWTH_STAGE::GROWTH->value:
  566. return $now->addSeconds($seed->growth_time);
  567. case GROWTH_STAGE::MATURE->value:
  568. // 成熟期持续24小时后进入枯萎期
  569. return $now->addHours(24);
  570. case GROWTH_STAGE::WITHERED->value:
  571. // 枯萎期没有结束时间
  572. return null;
  573. default:
  574. return null;
  575. }
  576. }
  577. /**
  578. * 获取随机产出
  579. *
  580. * @param int $seedId
  581. * @return array
  582. */
  583. private function getRandomOutput(int $seedId): array
  584. {
  585. // 获取种子的所有产出配置
  586. $outputs = FarmSeedOutput::where('seed_id', $seedId)->get();
  587. if ($outputs->isEmpty()) {
  588. // 如果没有产出配置,使用种子的默认产出
  589. $seed = FarmSeed::find($seedId);
  590. return [
  591. 'item_id' => $seed->item_id,
  592. 'min_amount' => $seed->min_output,
  593. 'max_amount' => $seed->max_output,
  594. ];
  595. }
  596. // 按概率排序
  597. $outputs = $outputs->sortByDesc('probability');
  598. // 获取默认产出
  599. $defaultOutput = $outputs->firstWhere('is_default', true);
  600. // 随机选择产出
  601. $random = mt_rand(1, 100);
  602. $cumulativeProbability = 0;
  603. foreach ($outputs as $output) {
  604. $cumulativeProbability += $output->probability;
  605. if ($random <= $cumulativeProbability) {
  606. return [
  607. 'item_id' => $output->item_id,
  608. 'min_amount' => $output->min_amount,
  609. 'max_amount' => $output->max_amount,
  610. ];
  611. }
  612. }
  613. // 如果随机值超过了所有概率之和,使用默认产出
  614. if ($defaultOutput) {
  615. return [
  616. 'item_id' => $defaultOutput->item_id,
  617. 'min_amount' => $defaultOutput->min_amount,
  618. 'max_amount' => $defaultOutput->max_amount,
  619. ];
  620. }
  621. // 如果没有默认产出,使用第一个产出
  622. $firstOutput = $outputs->first();
  623. return [
  624. 'item_id' => $firstOutput->item_id,
  625. 'min_amount' => $firstOutput->min_amount,
  626. 'max_amount' => $firstOutput->max_amount,
  627. ];
  628. }
  629. }