0, 'NS' => 0, '1H' => 1, 'HT' => 1, '2H' => 1, 'ET' => 1, 'BT' => 1, 'P' => 1, 'SUSP' => 1, 'INT' => 1, 'FT' => 2, 'AET' => 2, 'PEN' => 2, 'PST' => 3, 'CANC' => 4, 'ABD' => 4, 'AWD' => 4, 'WO' => 4, 'LIVE' => 1, ]; protected $long_status = [ 'Time To Be Defined' => 0, 'Not Started' => 0, 'First Half' => 1, 'First Half, Kick Off' => 1, 'Halftime' => 1, 'Second Half' => 1, 'Second Half, 2nd Half Started' => 1, 'Extra Time' => 1, 'Break Time' => 1, 'Penalty In Progress' => 1, 'Match Suspended' => 1, 'Match Interrupted' => 1, 'Match Finished' => 2, 'Match Finished' => 2, 'Match Finished' => 2, 'Match Postponed' => 3, 'Match Cancelled' => 4, 'Match Abandoned' => 4, 'Technical Loss' => 4, 'WalkOver' => 4, 'In Progress' => 1, ]; protected $fixture_status = [ 'First Half' => 1, 'First Half, Kick Off' => 1, 'Halftime' => 1, 'Second Half' => 1, 'Second Half, 2nd Half Started' => 1, 'Extra Time' => 1, 'Break Time' => 1, 'Penalty In Progress' => 1, ]; /** * 命令描述 * * @var string */ protected $description = '当天会去更新明天的赛事(23:59:00执行一次)'; /** * 执行命令 * * @return int */ public function handle() { // $this->info('开始执行统计比赛数据任务...'); $this->is_live = $this->argument('is_live'); if ($this->is_live == 0) { //未开始的赛事拉取 $this->fixtures(); } elseif ($this->is_live == 1) { //进行中的赛事,定时更新 $this->liveFixtures(); } elseif ($this->is_live == 2){ $this->checkLiveFixtures(); //$this->updateOvertimeFixtures(); } elseif ($this->is_live == 3) { $this->checkOvertimeFixtures(); } else { $this->initOdds(); } } //到了比赛开始时间,但是状态还是未开始,检查比赛 public function checkOvertimeFixtures() { //体育赛事结束前几(分钟)锁盘,90分钟结束 $sport_locked = Config::where('field', 'sport_locked')->first()->val ?? 1; // 比赛开始后,状态还是未开始的数据检测 $ids = SportModel::where('status', 1)->where('state', 0)->where('game_time', '<=', time())->pluck('data_id')->toArray(); if ($ids) { $ids = implode('-', $ids); $data = SportClientService::fixtures(['ids' => $ids]); $this->updateOrCreateSport($data, $sport_locked, 1); } return true; } //进行中超过3分钟没有更新数据的赛事,检查比赛是否结束 public function checkLiveFixtures() { //体育赛事结束前几(分钟)锁盘,90分钟结束 $sport_locked = Config::where('field', 'sport_locked')->first()->val ?? 1; //1. 统一锁盘时间(比赛开始前1分钟) SportModel::where(['is_locked' => 0, 'is_roll' => 0])->where('game_time', '<=', time() + 90)->update(['is_locked' => 1]); //2. 比赛进行中,超过3分钟未更新的数据检测 $end_time = date("Y-m-d H:i:s", time() - 180); $ids = SportModel::where('status', 1)->where('state', 1)->where('updated_at', '<=', $end_time)->pluck('data_id')->toArray(); if ($ids) { $chunks = array_chunk($ids, 10); foreach ($chunks as $chunk) { $ids = implode('-', $chunk); $data = SportClientService::fixtures(['ids' => $ids]); $this->updateOrCreateSport($data, $sport_locked, 1); } } return true; } //更新进行中的赛事 public function liveFixtures() { //体育赛事结束前几(分钟)锁盘,90分钟结束 $sport_locked = Config::where('field', 'sport_locked')->first()->val ?? 1; $data = SportClientService::fixtures(['live' => 'all']); file_put_contents("fixturesLive.json", json_encode($data)); $this->updateOrCreateSport($data, $sport_locked); return true; } private function updateOrCreateSport($data, $sport_locked, $is_check = 0) { $data = $data['response']; $tableData = []; $status = $this->short_status; foreach ($data as $item) { $home_statistics = !empty($item['statistics']) ? $item['statistics'][0]['statistics'] : ''; $away_statistics = !empty($item['statistics']) ? $item['statistics'][1]['statistics'] : ''; $sport_data = [ 'data_id' => $item['fixture']['id'], 'home_team_id' => $item['teams']['home']['id'], 'home_team_en' => $item['teams']['home']['name'], 'home_team' => lang($item['teams']['home']['name']), 'home_team_logo' => $item['teams']['home']['logo'], 'guest_team_id' => $item['teams']['away']['id'], 'guest_team_en' => $item['teams']['away']['name'], 'guest_team' => lang($item['teams']['away']['name']), 'guest_team_logo' => $item['teams']['away']['logo'], 'half_score' => "{$item['score']['halftime']['home']}-{$item['score']['halftime']['away']}", 'rbt' => $item['fixture']['timestamp'], 'score' => isset($item['goals']) ? "{$item['goals']['home']}-{$item['goals']['away']}":'-', 'extra_score' => isset($item['score']['extratime']) ? "{$item['score']['extratime']['home']}-{$item['score']['extratime']['away']}" : "",//加时赛比分 'league' => lang($item['league']['name']), 'league_en' => $item['league']['name'], 'state' => $status[$item['fixture']['status']['short']],//比赛状态:0未开始1进行中2已完场3延期4取消 'game_time' => $item['fixture']['timestamp'], 'updated_at' => now(), 'home_statistics' => $home_statistics, 'away_statistics' => $away_statistics, 'is_send' => 0, ]; $info = SportModel::where('data_id', $item['fixture']['id'])->first(); $fixture_status = null; if (empty($info->is_roll) && isset($item['fixture']['status']['long']) ) { $long = $item['fixture']['status']['long']; if (isset($this->fixture_status[$long])) { $fixture_status = json_encode($item['fixture']['status']); $sport_data['fixture_status'] = $fixture_status; } if (isset($this->long_status[$long])) { $sport_data['state'] = $this->long_status[$long]; } } //提前锁盘(比赛进行时长,分钟) if (isset($item['fixture']['status']['elapsed'])) { $elapsed = $item['fixture']['status']['elapsed']; if ((int)$elapsed >= 90 - $sport_locked ) { $sport_data['is_locked'] = 1; } } $sport_data['score'] = $sport_data['score'] == '-' ? '' : $sport_data['score']; $sport_data['half_score'] = $sport_data['half_score'] == '-' ? '' : $sport_data['half_score']; $sport_data['extra_score'] = $sport_data['extra_score'] == '-' ? '' : $sport_data['extra_score']; //锁盘 if (isset($item['fixture']['status']['blocked']) && $item['fixture']['status']['blocked']) { $sport_data['is_locked'] = 1; } //已结束 if (isset($item['fixture']['status']['finished']) && $item['fixture']['status']['finished']) { $sport_data['state'] = 2; } //如果赛事取消、延期等,标记需要退款 if ($sport_data['state'] > 2) { $sport_data['refund_status'] = 1; } if (!$info) { $sport_data['created_at'] = now(); $sport_data['status'] = 1; $tableData[] = $sport_data; } else { SportModel::where('data_id', $item['fixture']['id'])->update($sport_data); } //比赛结束,插入比赛事件 if ($sport_data['state'] == 2 && !empty($item['events'])) { foreach($item['events'] as $event) { SportEvent::create([ 'data_id' => $item['fixture']['id'], 'type' => $event['type'], 'time_elapsed' => $event['time']['elapsed'], 'time' => json_encode($event['time']), 'detail' => $event['detail'], 'player' => $event['player'] ? json_encode($event['player']) : $event['player'], 'team_id' => $event['team']['id'], 'comments' => $event['comments'], 'assist' => $event['assist'] ? json_encode($event['assist']) : $event['assist'], ]); } } } if ($tableData) { SportModel::insert($tableData); } return true; } /** * 获取指定日期的所有赛事 * * @return array */ public function fixtures() { //根据配置拉取多少天的赛事信息 $days = Config::where('field', 'sport_days')->first()->val ?? 1; for($i=0;$i<$days;$i++) { $date = Carbon::today()->addDay($i)->toDateString(); $data = SportClientService::fixtures(['date' => $date]); $data = $data['response']; $tableData = []; $status = $this->short_status; foreach ($data as $item) { $home_statistics = !empty($item['statistics']) ? $item['statistics'][0]['statistics'] : ''; $away_statistics = !empty($item['statistics']) ? $item['statistics'][1]['statistics'] : ''; $sport_data = [ 'data_id' => $item['fixture']['id'], 'home_team_id' => $item['teams']['home']['id'], 'home_team_en' => $item['teams']['home']['name'], 'home_team' => lang($item['teams']['home']['name']), 'home_team_logo' => $item['teams']['home']['logo'], 'guest_team_id' => $item['teams']['away']['id'], 'guest_team_en' => $item['teams']['away']['name'], 'guest_team' => lang($item['teams']['away']['name']), 'guest_team_logo' => $item['teams']['away']['logo'], 'half_score' => "{$item['score']['halftime']['home']}-{$item['score']['halftime']['away']}", 'rbt' => $item['fixture']['timestamp'], 'score' => isset($item['score']['fulltime']) ? "{$item['score']['fulltime']['home']}-{$item['score']['fulltime']['away']}":'-', 'league' => lang($item['league']['name']), 'league_en' => $item['league']['name'], // 'state' => $status[$item['fixture']['status']['short']],//比赛状态:0未开始1进行中2已完场3延期4取消 'game_time' => $item['fixture']['timestamp'], 'status' => 1, 'updated_at' => now(), 'home_statistics' => $home_statistics, 'away_statistics' => $away_statistics, 'is_send' => 0, ]; $status_short = strtoupper($item['fixture']['status']['short']); if (isset($status[$status_short])) { $sport_data['state'] = $status[$status_short]; } $sport_data['score'] = $sport_data['score'] == '-' ? '' : $sport_data['score']; $sport_data['half_score'] = $sport_data['half_score'] == '-' ? '' : $sport_data['half_score']; if (!SportModel::where('data_id', $item['fixture']['id'])->exists()) { $sport_data['created_at'] = now(); $tableData[] = $sport_data; } else { SportModel::where('data_id', $item['fixture']['id'])->update($sport_data); } //更新或创建球队和联赛信息 SportModel::addSportTeam($sport_data); SportModel::addSportLeague($item['league']); //比赛结束,插入比赛事件 if (isset($sport_data['state']) && $sport_data['state'] == 2 && !empty($item['events'])) { foreach($item['events'] as $event) { SportEvent::create([ 'data_id' => $item['fixture']['id'], 'type' => $event['type'], 'time_elapsed' => $event['time']['elapsed'], 'time' => json_encode($event['time']), 'detail' => $event['detail'], 'player' => $event['player'] ? json_encode($event['player']) : $event['player'], 'team_id' => $event['team']['id'], 'comments' => $event['comments'], 'assist' => $event['assist'] ? json_encode($event['assist']) : $event['assist'], ]); } } } if ($tableData) { SportModel::insert($tableData); } } return true; } public function initOdds(){ $page = 1; $limit = 10; while (true) { $list = SportModel::where('odds','<>', null)->forPage($page, $limit)->get()->toArray(); if (empty($list)) { break; } echo $page.PHP_EOL; foreach($list as $item) { $odds = json_decode($item['odds'], true); foreach($odds as $odd) { $odd_id = $odd['id']; $odd_name = $odd['name']; $info = DB::table('sport_odds')->where('odd_id',$odd_id)->where('odd_name_en',$odd_name)->first(); if ($info && (!$info->odd_name || $odd_name != $info->odd_name_en)) { DB::table('sport_odds')->where('id', $info->id)->update([ 'odd_name_en' => $odd_name, ]); } elseif (!$info) { DB::table('sport_odds')->insert([ 'odd_id' => $odd_id, 'odd_name_en' => $odd_name, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]); } } } $page++; } } //比赛开始后,超过3个小时,并且更新时间超过10分钟,还是进行中的数据,更新成已完成 public function updateOvertimeFixtures() { // 比赛开始后,状态还是未开始的数据检测 $end_time = date("Y-m-d H:i:s", time() - 600); SportModel::where('status', 1)->where('state', 1)->where('game_time', '<=', time() - 60*60*3)->where('updated_at', '<=', $end_time)->update(['state' =>2]); return true; } }