Basketball.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use App\Models\Sport as SportModel;
  5. use App\Models\SportTeam;
  6. use App\Models\SportLeague;
  7. use App\Services\SportClientService;
  8. use Carbon\Carbon;
  9. use Illuminate\Support\Facades\DB;
  10. use App\Models\Config;
  11. class Basketball extends Command
  12. {
  13. /**
  14. * 命令名称和签名
  15. *
  16. * @var string
  17. */
  18. protected $signature = 'basketball {is_live=0}';
  19. protected $is_live = 0;
  20. protected $short_status = [
  21. 'NS' => 0,
  22. 'Q1' => 1,
  23. 'Q2' => 1,
  24. 'Q3' => 1,
  25. 'Q4' => 1,
  26. 'OT' => 1,
  27. 'BT' => 1,
  28. 'HT' => 1,
  29. 'FT' => 2,
  30. 'AOT' => 2,
  31. 'POST' => 3,
  32. 'CANC' => 4,
  33. 'SUSP' => 4,
  34. 'AWD' => 4,
  35. 'ABD' => 4,
  36. ];
  37. protected $long_status = [
  38. 'Not Started' => 0,
  39. 'Quarter 1' => 1,
  40. 'Quarter 2' => 1,
  41. 'Quarter 3' => 1,
  42. 'Quarter 4' => 1,
  43. 'Over Time' => 1,
  44. 'Break Time' => 1,
  45. 'Halftime' => 1,
  46. 'Game Finished' => 2,
  47. 'After Over Time' => 2,
  48. 'Game Postponed' => 3,
  49. 'Game Cancelled' => 4,
  50. 'Game Suspended' => 4,
  51. 'Game Awarded' => 4,
  52. 'Game Abandoned' => 4,
  53. ];
  54. /**
  55. * 命令描述
  56. *
  57. * @var string
  58. */
  59. protected $description = '当天会去更新明天的赛事(23:59:00执行一次)';
  60. /**
  61. * 执行命令
  62. *
  63. * @return int
  64. */
  65. public function handle()
  66. {
  67. // $date = '2026-05-21';
  68. // // $data = SportClientService::basketballGames(['date' => $date]);
  69. // // file_put_contents('basketballGames-21.json', json_encode($data));
  70. // $data_id = 499637;
  71. // $data = SportClientService::basketballOdds(['game' => $data_id]);
  72. // file_put_contents('basketballOdds-499637.json', json_encode($data));
  73. // print_r($data);
  74. // die;
  75. // $this->info('开始执行统计比赛数据任务...');
  76. $this->is_live = $this->argument('is_live');
  77. if ($this->is_live == 0) {
  78. //未开始的赛事拉取
  79. $this->fixtures();
  80. } elseif ($this->is_live == 1) {
  81. } elseif ($this->is_live == 2){
  82. $this->checkLiveFixtures();
  83. } elseif ($this->is_live == 3) {
  84. $this->checkOvertimeFixtures();
  85. }
  86. }
  87. //到了比赛开始时间,但是状态还是未开始,检查比赛
  88. public function checkOvertimeFixtures()
  89. {
  90. // 比赛开始后,状态还是未开始的数据检测
  91. $ids = SportModel::where('type', 2)->where('state', 0)->where('game_time', '<=', time())->where('game_time', '>', strtotime(date('Y-m-d')))->pluck('data_id')->toArray();
  92. if ($ids) {
  93. foreach ($ids as $id) {
  94. $data = SportClientService::basketballGames(['id' => $id]);
  95. $this->updateOrCreateSport($data, 1);
  96. }
  97. }
  98. return true;
  99. }
  100. //进行中超过3分钟没有更新数据的赛事,检查比赛是否结束
  101. public function checkLiveFixtures()
  102. {
  103. //1. 统一锁盘时间(比赛开始前1分钟)
  104. SportModel::where('type', 2)->where(['is_locked' => 0, 'is_roll' => 0])->where('game_time', '<=', time() + 90)->update(['is_locked' => 1]);
  105. //2. 比赛进行中,超过3分钟未更新的数据检测
  106. $end_time = date("Y-m-d H:i:s", time() - 180);
  107. $ids = SportModel::where('type', 2)->where('state', 1)->where('updated_at', '<=', $end_time)->pluck('data_id')->toArray();
  108. if ($ids) {
  109. foreach ($ids as $id) {
  110. $data = SportClientService::basketballGames(['id' => $id]);
  111. $this->updateOrCreateSport($data, 1);
  112. }
  113. }
  114. return true;
  115. }
  116. private function updateOrCreateSport($data, $is_check = 0) {
  117. //体育赛事结束前几(分钟)锁盘,90分钟结束
  118. $sport_locked = Config::where('field', 'sport_locked')->first()->val ?? 1;
  119. $data = $data['response'];
  120. $tableData = [];
  121. $status = $this->short_status;
  122. foreach ($data as $item) {
  123. $data_id = $item['id'];
  124. $sport_data = [
  125. 'data_id' => $item['id'],
  126. 'type' => 2,
  127. 'home_team_id' => $item['teams']['home']['id'],
  128. 'home_team_en' => $item['teams']['home']['name'],
  129. 'home_team_logo' => $item['teams']['home']['logo'],
  130. 'guest_team_id' => $item['teams']['away']['id'],
  131. 'guest_team_en' => $item['teams']['away']['name'],
  132. 'guest_team_logo' => $item['teams']['away']['logo'],
  133. 'half_score' => "",
  134. 'rbt' => $item['timestamp'],
  135. 'score' => isset($item['scores']['home']) && isset($item['scores']['away']) ? "{$item['scores']['home']['total']}-{$item['scores']['away']['total']}":'-',
  136. 'extra_score' => isset($item['scores']['home']) && isset($item['scores']['away']) ? "{$item['scores']['home']['over_time']}-{$item['scores']['away']['over_time']}":'-',
  137. 'league_id' => $item['league']['id'],
  138. 'league_en' => $item['league']['name'],
  139. 'league_data' => json_encode($item['league']),
  140. 'scores' => json_encode($item['scores']),
  141. 'state' => $status[$item['status']['short']],//比赛状态:0未开始1进行中2已完场3延期4取消
  142. 'game_time' => $item['timestamp'],
  143. 'updated_at' => now(),
  144. 'is_send' => 0,
  145. ];
  146. $info = SportModel::where('type', 2)->where('data_id', $data_id)->first();
  147. $sport_data['score'] = $sport_data['score'] == '-' ? '' : $sport_data['score'];
  148. $sport_data['extra_score'] = $sport_data['extra_score'] == '-' ? '' : $sport_data['extra_score'];
  149. //如果赛事取消、延期等,标记需要退款
  150. if ($sport_data['state'] > 2) {
  151. $sport_data['refund_status'] = 1;
  152. }
  153. if (empty($info['league'])) {
  154. $sport_data['league'] = SportLeague::getLeagueName($sport_data['league_id'], 2);
  155. }
  156. if (empty($info['home_team'])) {
  157. $sport_data['home_team'] = SportTeam::getTeamName($sport_data['home_team_id'], 2);
  158. }
  159. if (empty($info['guest_team'])) {
  160. $sport_data['guest_team'] = SportTeam::getTeamName($sport_data['guest_team_id'], 2);
  161. }
  162. if (!$info) {
  163. $sport_data['created_at'] = date('Y-m-d H:i:s');
  164. $sport_data['status'] = 1;
  165. $tableData[] = $sport_data;
  166. } else {
  167. SportModel::where('type', 2)->where('data_id', $data_id)->update($sport_data);
  168. }
  169. //更新或创建球队和联赛信息
  170. SportModel::addSportTeam($sport_data);
  171. SportModel::addSportLeague($item['league']);
  172. //比赛结束,插入比赛事件
  173. if (isset($sport_data['state']) && $sport_data['state'] == 2 ) {
  174. }
  175. }
  176. if ($tableData) {
  177. SportModel::insert($tableData);
  178. }
  179. return true;
  180. }
  181. /**
  182. * 获取指定日期的所有赛事
  183. *
  184. * @return array
  185. */
  186. public function fixtures()
  187. {
  188. //根据配置拉取多少天的赛事信息
  189. $days = Config::where('field', 'sport_days')->first()->val ?? 1;
  190. for($i=0;$i<$days;$i++) {
  191. $date = Carbon::today()->addDay($i)->toDateString();
  192. $data = SportClientService::basketballGames(['date' => $date]);
  193. $this->updateOrCreateSport($data);
  194. }
  195. return true;
  196. }
  197. //比赛开始后,超过3个小时,并且更新时间超过10分钟,还是进行中的数据,更新成已完成
  198. public function updateOvertimeFixtures()
  199. {
  200. // 比赛开始后,状态还是未开始的数据检测
  201. $end_time = date("Y-m-d H:i:s", time() - 600);
  202. SportModel::where('type', 2)->where('status', 1)->where('state', 1)->where('game_time', '<=', time() - 60*60*3)->where('updated_at', '<=', $end_time)->update(['state' =>2]);
  203. return true;
  204. }
  205. }