GenerateDailyPriceTrendsCommand.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace App\Module\Mex\Commands;
  3. use App\Module\Mex\Service\MexConfigService;
  4. use App\Module\Mex\Service\MexDailyPriceTrendService;
  5. use Carbon\Carbon;
  6. use Illuminate\Console\Command;
  7. /**
  8. * 生成每日价格趋势数据命令
  9. */
  10. class GenerateDailyPriceTrendsCommand extends Command
  11. {
  12. /**
  13. * 命令签名
  14. */
  15. protected $signature = 'mex:generate-daily-trends
  16. {--date= : 指定日期 (Y-m-d 格式,默认为昨天)}
  17. {--start-date= : 开始日期 (Y-m-d 格式)}
  18. {--end-date= : 结束日期 (Y-m-d 格式)}
  19. {--item-id= : 指定商品ID}
  20. {--force : 强制执行,忽略配置检查}';
  21. /**
  22. * 命令描述
  23. */
  24. protected $description = '生成农贸市场每日价格趋势数据';
  25. /**
  26. * 执行命令
  27. */
  28. public function handle(): int
  29. {
  30. $this->info('开始生成每日价格趋势数据...');
  31. // 检查配置是否启用自动生成功能
  32. if (!$this->option('force') && !MexConfigService::isAutoGenerateDailyTrendsEnabled()) {
  33. $this->warn('自动生成每日价格趋势功能已被禁用');
  34. $this->info('如需强制执行,请使用 --force 选项');
  35. return 0;
  36. }
  37. try {
  38. $date = $this->option('date');
  39. $startDate = $this->option('start-date');
  40. $endDate = $this->option('end-date');
  41. $itemId = $this->option('item-id');
  42. if ($startDate && $endDate) {
  43. // 批量生成指定日期范围的趋势数据
  44. $this->generateDateRangeTrends($startDate, $endDate, $itemId);
  45. } elseif ($date) {
  46. // 生成指定日期的趋势数据
  47. $this->generateSingleDateTrends($date, $itemId);
  48. } else {
  49. // 默认生成昨天的趋势数据
  50. $yesterday = Carbon::yesterday()->format('Y-m-d');
  51. $this->generateSingleDateTrends($yesterday, $itemId);
  52. }
  53. $this->info('每日价格趋势数据生成完成!');
  54. return 0;
  55. } catch (\Exception $e) {
  56. $this->error('生成每日价格趋势数据失败: ' . $e->getMessage());
  57. $this->error('错误详情: ' . $e->getTraceAsString());
  58. return 1;
  59. }
  60. }
  61. /**
  62. * 生成单个日期的趋势数据
  63. */
  64. private function generateSingleDateTrends(string $date, ?int $itemId = null): void
  65. {
  66. $this->info("正在生成 {$date} 的价格趋势数据...");
  67. if ($itemId) {
  68. $this->info("指定商品ID: {$itemId}");
  69. }
  70. $trends = MexDailyPriceTrendService::generateMultipleDaysTrends(
  71. $date,
  72. $date,
  73. $itemId
  74. );
  75. $count = $trends->count();
  76. $this->info("成功生成 {$count} 条价格趋势记录");
  77. if ($count > 0) {
  78. $this->table(
  79. ['商品ID', '开盘价', '收盘价', '最高价', '最低价', '成交量', '成交额'],
  80. $trends->map(function ($trend) {
  81. return [
  82. $trend->itemId,
  83. number_format($trend->openPrice, 5),
  84. number_format($trend->closePrice, 5),
  85. number_format($trend->highPrice, 5),
  86. number_format($trend->lowPrice, 5),
  87. $trend->totalVolume,
  88. number_format($trend->totalAmount, 5),
  89. ];
  90. })->toArray()
  91. );
  92. }
  93. }
  94. /**
  95. * 生成日期范围的趋势数据
  96. */
  97. private function generateDateRangeTrends(string $startDate, string $endDate, ?int $itemId = null): void
  98. {
  99. $this->info("正在生成 {$startDate} 到 {$endDate} 的价格趋势数据...");
  100. if ($itemId) {
  101. $this->info("指定商品ID: {$itemId}");
  102. }
  103. $start = Carbon::parse($startDate);
  104. $end = Carbon::parse($endDate);
  105. $totalDays = $start->diffInDays($end) + 1;
  106. $this->info("总共需要处理 {$totalDays} 天的数据");
  107. $progressBar = $this->output->createProgressBar($totalDays);
  108. $progressBar->start();
  109. $totalTrends = 0;
  110. $current = $start->copy();
  111. while ($current <= $end) {
  112. $dateStr = $current->format('Y-m-d');
  113. $trends = MexDailyPriceTrendService::generateMultipleDaysTrends(
  114. $dateStr,
  115. $dateStr,
  116. $itemId
  117. );
  118. $totalTrends += $trends->count();
  119. $progressBar->advance();
  120. $current->addDay();
  121. }
  122. $progressBar->finish();
  123. $this->newLine();
  124. $this->info("成功生成 {$totalTrends} 条价格趋势记录");
  125. }
  126. }