deploy: auto commit server changes 2026-07-09 23:26:00
This commit is contained in:
@@ -10,6 +10,7 @@ use app\common\model\match\MatchData;
|
|||||||
use app\common\model\match\MatchRecent;
|
use app\common\model\match\MatchRecent;
|
||||||
use app\common\model\match\MatchLiveText;
|
use app\common\model\match\MatchLiveText;
|
||||||
use app\common\model\match\MatchLineup;
|
use app\common\model\match\MatchLineup;
|
||||||
|
use app\common\model\match\MatchOdds;
|
||||||
use app\common\model\match\WorldCupPersonRanking;
|
use app\common\model\match\WorldCupPersonRanking;
|
||||||
use app\common\model\match\WorldCupStanding;
|
use app\common\model\match\WorldCupStanding;
|
||||||
use app\common\model\league\League;
|
use app\common\model\league\League;
|
||||||
@@ -17,7 +18,7 @@ use app\common\service\match\MatchLiveService;
|
|||||||
|
|
||||||
class MatchController extends BaseApiController
|
class MatchController extends BaseApiController
|
||||||
{
|
{
|
||||||
public array $notNeedLogin = ['lists', 'detail', 'leagues', 'sportTypes', 'liveText', 'lineup', 'worldCupStandings', 'worldCupRankings', 'worldCupSchedule', 'worldCupLiveCards'];
|
public array $notNeedLogin = ['lists', 'detail', 'leagues', 'sportTypes', 'liveText', 'lineup', 'worldCupStandings', 'worldCupRankings', 'worldCupSchedule', 'worldCupLiveCards', 'worldCupOdds'];
|
||||||
|
|
||||||
protected int $worldCupSeasonId = 26123;
|
protected int $worldCupSeasonId = 26123;
|
||||||
protected string $worldCupLeagueName = '世界杯';
|
protected string $worldCupLeagueName = '世界杯';
|
||||||
@@ -511,4 +512,185 @@ class MatchController extends BaseApiController
|
|||||||
'list' => MatchLiveService::getWorldCupLiveCards(),
|
'list' => MatchLiveService::getWorldCupLiveCards(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function worldCupOdds()
|
||||||
|
{
|
||||||
|
$showType = $this->request->get('show_type/s', '');
|
||||||
|
$includeSpecial = $this->request->get('include_special/d', 0);
|
||||||
|
$limit = min(max($this->request->get('limit/d', 120), 1), 300);
|
||||||
|
$validShowTypes = ['live', 'today', 'early'];
|
||||||
|
|
||||||
|
$query = MatchOdds::where('sport_type', 'FT')
|
||||||
|
->where('league_name', 'like', '%世界杯%');
|
||||||
|
if (!$includeSpecial) {
|
||||||
|
$query->where('league_name', 'not like', '%特定球员%');
|
||||||
|
}
|
||||||
|
if (in_array($showType, $validShowTypes, true)) {
|
||||||
|
$query->where('show_type', $showType);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = $query
|
||||||
|
->field('id,source_site,source_url,source_match_id,source_league_id,sport_type,show_type,odds_type,league_name,match_time_text,home_team,away_team,handicap_line,handicap_home_odds,handicap_away_odds,total_line,total_over_odds,total_under_odds,home_win_odds,draw_odds,away_win_odds,update_time')
|
||||||
|
->order('update_time desc')
|
||||||
|
->order('id desc')
|
||||||
|
->limit($limit)
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$eventMap = $this->buildWorldCupEventMap();
|
||||||
|
$matches = [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$matchKey = $this->buildOddsMatchKey($row);
|
||||||
|
if (!isset($matches[$matchKey])) {
|
||||||
|
$event = $eventMap[$this->buildTeamPairKey($row['home_team'] ?? '', $row['away_team'] ?? '')] ?? [];
|
||||||
|
$matches[$matchKey] = [
|
||||||
|
'id' => (int)($event['id'] ?? 0),
|
||||||
|
'match_id' => (int)($event['match_id'] ?? 0),
|
||||||
|
'source_match_ids' => [],
|
||||||
|
'league_name' => $row['league_name'],
|
||||||
|
'match_time_text' => $row['match_time_text'],
|
||||||
|
'match_time' => (int)($event['match_time'] ?? 0),
|
||||||
|
'home_team' => $row['home_team'],
|
||||||
|
'home_icon' => $event['home_icon'] ?? '',
|
||||||
|
'home_score' => (int)($event['home_score'] ?? 0),
|
||||||
|
'away_team' => $row['away_team'],
|
||||||
|
'away_icon' => $event['away_icon'] ?? '',
|
||||||
|
'away_score' => (int)($event['away_score'] ?? 0),
|
||||||
|
'status' => (int)($event['status'] ?? 0),
|
||||||
|
'current_minute' => $event['current_minute'] ?? '',
|
||||||
|
'platforms' => [],
|
||||||
|
'update_time' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$matches[$matchKey]['source_match_ids'][] = (string)$row['source_match_id'];
|
||||||
|
$matches[$matchKey]['platforms'][] = $this->formatOddsPlatform($row);
|
||||||
|
$matches[$matchKey]['update_time'] = max((int)$matches[$matchKey]['update_time'], (int)$row['update_time']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = array_values($matches);
|
||||||
|
foreach ($list as &$item) {
|
||||||
|
$item['source_match_ids'] = array_values(array_unique($item['source_match_ids']));
|
||||||
|
usort($item['platforms'], function ($left, $right) {
|
||||||
|
return (int)$right['update_time'] <=> (int)$left['update_time'];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
unset($item);
|
||||||
|
|
||||||
|
usort($list, function ($left, $right) {
|
||||||
|
return (int)$right['update_time'] <=> (int)$left['update_time'];
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->data([
|
||||||
|
'season_id' => $this->worldCupSeasonId,
|
||||||
|
'list' => $list,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildWorldCupEventMap(): array
|
||||||
|
{
|
||||||
|
$rows = MatchEvent::where('league_name', $this->worldCupLeagueName)
|
||||||
|
->where('sport_type', 1)
|
||||||
|
->where('is_show', 1)
|
||||||
|
->field('id,match_id,home_team,home_icon,home_score,away_team,away_icon,away_score,status,match_time,current_minute')
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$map = [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$key = $this->buildTeamPairKey($row['home_team'] ?? '', $row['away_team'] ?? '');
|
||||||
|
if ($key !== '') {
|
||||||
|
$map[$key] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildOddsMatchKey(array $row): string
|
||||||
|
{
|
||||||
|
return implode('|', [
|
||||||
|
trim((string)($row['league_name'] ?? '')),
|
||||||
|
trim((string)($row['match_time_text'] ?? '')),
|
||||||
|
$this->buildTeamPairKey($row['home_team'] ?? '', $row['away_team'] ?? ''),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildTeamPairKey(string $homeTeam, string $awayTeam): string
|
||||||
|
{
|
||||||
|
$homeTeam = preg_replace('/\s+/u', '', trim($homeTeam));
|
||||||
|
$awayTeam = preg_replace('/\s+/u', '', trim($awayTeam));
|
||||||
|
if ($homeTeam === '' || $awayTeam === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return $homeTeam . 'vs' . $awayTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatOddsPlatform(array $row): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'platform_key' => (string)$row['source_site'],
|
||||||
|
'platform_name' => $this->resolveOddsPlatformName((string)$row['source_site']),
|
||||||
|
'show_type' => (string)$row['show_type'],
|
||||||
|
'show_type_text' => $this->resolveOddsShowTypeText((string)$row['show_type']),
|
||||||
|
'odds_type' => (string)$row['odds_type'],
|
||||||
|
'source_match_id' => (string)$row['source_match_id'],
|
||||||
|
'update_time' => (int)$row['update_time'],
|
||||||
|
'markets' => array_values(array_filter([
|
||||||
|
$this->buildOddsMarket('独赢', '', [
|
||||||
|
['label' => '主胜', 'value' => $row['home_win_odds']],
|
||||||
|
['label' => '平', 'value' => $row['draw_odds']],
|
||||||
|
['label' => '客胜', 'value' => $row['away_win_odds']],
|
||||||
|
]),
|
||||||
|
$this->buildOddsMarket('让球', (string)$row['handicap_line'], [
|
||||||
|
['label' => '主队', 'value' => $row['handicap_home_odds']],
|
||||||
|
['label' => '客队', 'value' => $row['handicap_away_odds']],
|
||||||
|
]),
|
||||||
|
$this->buildOddsMarket('大小球', (string)$row['total_line'], [
|
||||||
|
['label' => '大', 'value' => $row['total_over_odds']],
|
||||||
|
['label' => '小', 'value' => $row['total_under_odds']],
|
||||||
|
]),
|
||||||
|
])),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildOddsMarket(string $label, string $line, array $values): ?array
|
||||||
|
{
|
||||||
|
$filtered = [];
|
||||||
|
foreach ($values as $item) {
|
||||||
|
$value = trim((string)($item['value'] ?? ''));
|
||||||
|
if ($value === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$filtered[] = [
|
||||||
|
'label' => $item['label'],
|
||||||
|
'value' => $value,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (empty($filtered)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'label' => $label,
|
||||||
|
'line' => trim($line),
|
||||||
|
'values' => $filtered,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveOddsPlatformName(string $sourceSite): string
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'hg' => '滚球',
|
||||||
|
];
|
||||||
|
return $map[$sourceSite] ?? ($sourceSite !== '' ? strtoupper($sourceSite) : '平台');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveOddsShowTypeText(string $showType): string
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'live' => '滚球盘',
|
||||||
|
'today' => '今日盘',
|
||||||
|
'early' => '早盘',
|
||||||
|
];
|
||||||
|
return $map[$showType] ?? '盘口';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\common\model\match;
|
||||||
|
|
||||||
|
use app\common\model\BaseModel;
|
||||||
|
|
||||||
|
class MatchOdds extends BaseModel
|
||||||
|
{
|
||||||
|
protected $name = 'match_odds';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user