GenerateFarmDailyStatsCommand.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. namespace App\Module\Farm\Commands;
  3. use App\Module\Farm\Models\FarmDailyStats;
  4. use App\Module\Farm\Models\FarmUser;
  5. use App\Module\Farm\Models\FarmLand;
  6. use App\Module\Farm\Models\FarmCrop;
  7. use App\Module\Farm\Enums\GROWTH_STAGE;
  8. use UCore\Command\Command;
  9. use Carbon\Carbon;
  10. use Illuminate\Support\Facades\DB;
  11. /**
  12. * 生成农场每日统计数据命令
  13. */
  14. class GenerateFarmDailyStatsCommand extends Command
  15. {
  16. /**
  17. * 命令签名
  18. *
  19. * @var string
  20. */
  21. protected $signature = 'farm:generate-daily-stats
  22. {--date= : 指定统计日期 (Y-m-d 格式,默认为昨天)}
  23. {--force : 强制重新生成已存在的统计数据}';
  24. /**
  25. * 命令描述
  26. *
  27. * @var string
  28. */
  29. protected $description = '生成农场每日统计数据,包括土地和房屋等级统计';
  30. /**
  31. * 执行命令的具体逻辑
  32. *
  33. * @return void
  34. */
  35. public function handleRun(): void
  36. {
  37. $date = $this->option('date') ? Carbon::parse($this->option('date')) : Carbon::yesterday();
  38. $force = $this->option('force');
  39. $this->info("开始生成农场每日统计数据...");
  40. $this->info("统计日期: {$date->toDateString()}");
  41. try {
  42. // 检查是否已存在统计数据
  43. $existingStats = FarmDailyStats::findByDate($date);
  44. if ($existingStats && !$force) {
  45. $this->warn("日期 {$date->toDateString()} 的统计数据已存在,使用 --force 参数强制重新生成");
  46. return;
  47. }
  48. // 生成统计数据
  49. $statsData = $this->generateStatsData($date);
  50. // 保存或更新统计数据
  51. if ($existingStats) {
  52. $existingStats->update($statsData);
  53. $this->info("已更新统计数据");
  54. } else {
  55. FarmDailyStats::create($statsData);
  56. $this->info("已创建新的统计数据");
  57. }
  58. // 显示统计结果
  59. $this->displayStatsResult($statsData);
  60. $this->info("农场每日统计数据生成完成!");
  61. } catch (\Exception $e) {
  62. $this->error("生成统计数据时发生错误: " . $e->getMessage());
  63. $this->error("错误位置: " . $e->getFile() . ':' . $e->getLine());
  64. throw $e;
  65. }
  66. }
  67. /**
  68. * 生成统计数据
  69. *
  70. * @param Carbon $date
  71. * @return array
  72. */
  73. protected function generateStatsData(Carbon $date): array
  74. {
  75. $this->info("正在统计用户数据...");
  76. // 统计用户数据
  77. $totalUsers = FarmUser::count();
  78. // 活跃用户数(当日有操作的用户,这里简化为有农场记录的用户)
  79. $activeUsers = FarmUser::whereDate('updated_at', $date)->count();
  80. $this->info("正在统计房屋等级数据...");
  81. // 统计房屋等级数据
  82. $houseLevelStats = FarmUser::select('house_level', DB::raw('count(*) as count'))
  83. ->groupBy('house_level')
  84. ->pluck('count', 'house_level')
  85. ->toArray();
  86. $this->info("正在统计土地类型数据...");
  87. // 统计土地类型数据
  88. $landTypeStats = FarmLand::select('land_type', DB::raw('count(*) as count'))
  89. ->groupBy('land_type')
  90. ->pluck('count', 'land_type')
  91. ->toArray();
  92. $this->info("正在统计土地状态数据...");
  93. // 统计土地状态数据
  94. $landStatusStats = FarmLand::select('status', DB::raw('count(*) as count'))
  95. ->groupBy('status')
  96. ->pluck('count', 'status')
  97. ->toArray();
  98. $this->info("正在统计作物和灾害数据...");
  99. // 统计总土地数量
  100. $totalLands = FarmLand::count();
  101. // 统计特殊土地数量(类型4、5、6)
  102. $totalSpecialLands = FarmLand::whereIn('land_type', [4, 5, 6])->count();
  103. // 统计总作物数量
  104. $totalCrops = FarmCrop::count();
  105. // 统计按生长阶段分组的作物数量
  106. $this->info("正在统计作物生长阶段数据...");
  107. $cropStageStats = FarmCrop::select('growth_stage', DB::raw('count(*) as count'))
  108. ->groupBy('growth_stage')
  109. ->pluck('count', 'growth_stage')
  110. ->toArray();
  111. // 统计总灾害数量(有活跃灾害的作物)
  112. $totalDisasters = FarmCrop::whereNotNull('disasters')
  113. ->where('disasters', '!=', '[]')
  114. ->where('disasters', '!=', 'null')
  115. ->count();
  116. // 组装统计数据
  117. $statsData = [
  118. 'stats_date' => $date->toDateString(),
  119. 'total_users' => $totalUsers,
  120. 'active_users' => $activeUsers,
  121. 'total_lands' => $totalLands,
  122. 'total_special_lands' => $totalSpecialLands,
  123. 'total_crops' => $totalCrops,
  124. 'total_disasters' => $totalDisasters,
  125. ];
  126. // 添加房屋等级统计
  127. for ($level = 1; $level <= 10; $level++) {
  128. $statsData["house_level_{$level}"] = $houseLevelStats[$level] ?? 0;
  129. }
  130. // 添加土地类型统计
  131. for ($type = 1; $type <= 6; $type++) {
  132. $statsData["land_type_{$type}"] = $landTypeStats[$type] ?? 0;
  133. }
  134. // 添加土地状态统计
  135. for ($status = 0; $status <= 4; $status++) {
  136. $statsData["land_status_{$status}"] = $landStatusStats[$status] ?? 0;
  137. }
  138. // 添加作物生长阶段统计
  139. // 使用GROWTH_STAGE枚举的值作为键
  140. $statsData['crops_seed_stage'] = $cropStageStats[GROWTH_STAGE::SEED->value] ?? 0;
  141. $statsData['crops_sprout_stage'] = $cropStageStats[GROWTH_STAGE::SPROUT->value] ?? 0;
  142. $statsData['crops_growth_stage'] = $cropStageStats[GROWTH_STAGE::GROWTH->value] ?? 0;
  143. $statsData['crops_fruit_stage'] = $cropStageStats[GROWTH_STAGE::FRUIT->value] ?? 0;
  144. $statsData['crops_mature_stage'] = $cropStageStats[GROWTH_STAGE::MATURE->value] ?? 0;
  145. $statsData['crops_withered_stage'] = $cropStageStats[GROWTH_STAGE::WITHERED->value] ?? 0;
  146. return $statsData;
  147. }
  148. /**
  149. * 显示统计结果
  150. *
  151. * @param array $statsData
  152. */
  153. protected function displayStatsResult(array $statsData): void
  154. {
  155. $this->line('');
  156. $this->info('=== 统计结果 ===');
  157. // 用户统计
  158. $this->line("总用户数: {$statsData['total_users']}");
  159. $this->line("活跃用户数: {$statsData['active_users']}");
  160. // 房屋等级统计
  161. $this->line('');
  162. $this->info('房屋等级统计:');
  163. for ($level = 1; $level <= 10; $level++) {
  164. $count = $statsData["house_level_{$level}"];
  165. if ($count > 0) {
  166. $this->line(" {$level}级房屋: {$count}个");
  167. }
  168. }
  169. // 土地类型统计
  170. $this->line('');
  171. $this->info('土地类型统计:');
  172. $landTypeNames = [
  173. 1 => '普通土地',
  174. 2 => '红土地',
  175. 3 => '黑土地',
  176. 4 => '金色特殊土地',
  177. 5 => '蓝色特殊土地',
  178. 6 => '紫色特殊土地',
  179. ];
  180. for ($type = 1; $type <= 6; $type++) {
  181. $count = $statsData["land_type_{$type}"];
  182. if ($count > 0) {
  183. $typeName = $landTypeNames[$type];
  184. $this->line(" {$typeName}: {$count}块");
  185. }
  186. }
  187. // 土地状态统计
  188. $this->line('');
  189. $this->info('土地状态统计:');
  190. $landStatusNames = [
  191. 0 => '空闲',
  192. 1 => '种植中',
  193. 2 => '灾害',
  194. 3 => '可收获',
  195. 4 => '枯萎',
  196. ];
  197. for ($status = 0; $status <= 4; $status++) {
  198. $count = $statsData["land_status_{$status}"];
  199. if ($count > 0) {
  200. $statusName = $landStatusNames[$status];
  201. $this->line(" {$statusName}土地: {$count}块");
  202. }
  203. }
  204. // 总计统计
  205. $this->line('');
  206. $this->info('总计统计:');
  207. $this->line("总土地数: {$statsData['total_lands']}块");
  208. $this->line("特殊土地数: {$statsData['total_special_lands']}块");
  209. $this->line("总作物数: {$statsData['total_crops']}个");
  210. $this->line("总灾害数: {$statsData['total_disasters']}个");
  211. }
  212. }