GenerateFarmDailyStatsCommand.php 7.5 KB

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