diff --git a/application/admin/controller/History.php b/application/admin/controller/History.php index 91c8341..72ab07e 100644 --- a/application/admin/controller/History.php +++ b/application/admin/controller/History.php @@ -22,7 +22,7 @@ class History extends Backend * 无需额外权限检查的方法(但仍在 admin 模块内,需要 admin 登录) * @var array */ - protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction', 'zoneTransition', 'colorWaveTransition']; + protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction', 'zoneTransition', 'colorWaveTransition', 'zoneToColorTransition']; public function _initialize() { diff --git a/application/admin/model/History.php b/application/admin/model/History.php index 4761cdf..92456e8 100644 --- a/application/admin/model/History.php +++ b/application/admin/model/History.php @@ -466,7 +466,8 @@ class History extends Model 'tailnumbers' => $this->getTailNumbers($periods, 'special'), 'heatmap' => $this->getSpecialHeatmap($periods), 'zonetransition' => $this->getZoneTransition($periods), - 'colorwavetransition' => $this->getColorWaveTransition($periods) + 'colorwavetransition' => $this->getColorWaveTransition($periods), + 'zonetocolortransition' => $this->getZoneToColorTransition($periods) ]; } @@ -795,6 +796,81 @@ class History extends Model ]; } + /** + * 区域→波色交叉转移概率 + * 统计上一期特码所在数字区域后,下一期特码波色(红/蓝/绿)的分布概率 + * @param int $periods 查询最近多少期 + * @return array {zones: [], colors: [], matrix: [], probabilities: [], row_totals: [], total_transitions: int} + */ + public function getZoneToColorTransition($periods = 100) + { + $history = $this + ->field('expect,num7,openTime') + ->order('openTime', 'desc') + ->limit($periods) + ->select(); + + if (empty($history) || count($history) < 2) { + return ['zones' => ['1-10','11-20','21-30','31-40','41-49'], 'colors' => ['红波','蓝波','绿波'], 'matrix' => [], 'probabilities' => [], 'row_totals' => [], 'total_transitions' => 0]; + } + + $history = array_reverse($history); + $num_model = new Num(); + $colorMap = $num_model->column('color', 'num'); + + $zoneLabels = ['1-10', '11-20', '21-30', '31-40', '41-49']; + $colorLabels = ['红波', '蓝波', '绿波']; + $matrix = array_fill(0, 5, array_fill(0, 3, 0)); + $rowTotals = array_fill(0, 5, 0); + + $getZone = function ($num) { + if ($num <= 10) return 0; + if ($num <= 20) return 1; + if ($num <= 30) return 2; + if ($num <= 40) return 3; + return 4; + }; + + $getColorIdx = function ($num) use ($colorMap) { + $color = $colorMap[$num] ?? ''; + if (strpos($color, '红') !== false) return 0; + if (strpos($color, '蓝') !== false) return 1; + if (strpos($color, '绿') !== false) return 2; + return -1; + }; + + $totalTransitions = 0; + for ($i = 0; $i < count($history) - 1; $i++) { + $currentNum = (int)$history[$i]['num7']; + $nextNum = (int)$history[$i + 1]['num7']; + $from = $getZone($currentNum); + $to = $getColorIdx($nextNum); + if ($to < 0) continue; + + $matrix[$from][$to]++; + $rowTotals[$from]++; + $totalTransitions++; + } + + $probabilities = array_fill(0, 5, array_fill(0, 3, 0)); + for ($i = 0; $i < 5; $i++) { + if ($rowTotals[$i] > 0) { + for ($j = 0; $j < 3; $j++) { + $probabilities[$i][$j] = round($matrix[$i][$j] / $rowTotals[$i] * 100, 1); + } + } + } + + return [ + 'zones' => $zoneLabels, + 'colors' => $colorLabels, + 'matrix' => $matrix, + 'probabilities' => $probabilities, + 'row_totals' => $rowTotals, + 'total_transitions' => $totalTransitions + ]; + } + /** * 特码热力图数据 * @param int $periods 查询最近多少期 diff --git a/public/assets/js/backend/dashboard.js b/public/assets/js/backend/dashboard.js index 04ebabf..e66502b 100644 --- a/public/assets/js/backend/dashboard.js +++ b/public/assets/js/backend/dashboard.js @@ -130,7 +130,31 @@ define(['jquery'], function ($) { } html += ''; } - html += ''; + html += ''; + // 下方:区域→波色交叉转移 + var ztc = data.zonetocolortransition; + if (ztc && ztc.matrix && ztc.matrix.length > 0) { + html += '
波色特码 | ';
+ var cwColors2 = ['#e74c3c', '#3498db', '#2ecc71'];
+ for (var z = 0; z < ztc.colors.length; z++) {
+ html += '' + ztc.colors[z] + ' | '; + } + html += '
|---|---|
| ' + ztc.zones[r] + ' | '; + for (var c = 0; c < 3; c++) { + var pct = ztc.probabilities[r][c]; + var cnt = ztc.matrix[r][c]; + var bg = pct > 40 ? cwColors2[c] : pct > 20 ? cwColors2[c] + 'cc' : pct > 0 ? '#95a5a6' : '#f5f5f5'; + var txt = pct > 20 ? '#fff' : '#333'; + html += '' + cnt + '次 ' + pct + '% | ';
+ }
+ html += '