feat(dashboard): 新增区域→波色交叉转移概率表格

This commit is contained in:
2026-04-25 23:53:33 +08:00
parent 8c8dec620e
commit c3e430a24b
3 changed files with 103 additions and 3 deletions
+1 -1
View File
@@ -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()
{
+77 -1
View File
@@ -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 查询最近多少期
+25 -1
View File
@@ -130,7 +130,31 @@ define(['jquery'], function ($) {
}
html += '</tbody></table></div>';
}
html += '</div></div>';
html += '</div>';
// 下方:区域→波色交叉转移
var ztc = data.zonetocolortransition;
if (ztc && ztc.matrix && ztc.matrix.length > 0) {
html += '<div style="margin-top:20px;font-size:12px;color:#999;margin-bottom:8px;">区域→波色交叉转移(共 ' + ztc.total_transitions + ' 次)</div>';
html += '<table class="table table-bordered table-condensed text-center" style="max-width:500px;margin:0 auto;"><thead><tr><th style="width:80px;position:relative;"><div style="width:100%;height:35px;border-bottom:1px solid #e5e5e5;position:relative;"><span style="position:absolute;top:2px;right:5px;font-size:12px;">波色</span><span style="position:absolute;bottom:2px;left:5px;font-size:12px;">特码</span></div></th>';
var cwColors2 = ['#e74c3c', '#3498db', '#2ecc71'];
for (var z = 0; z < ztc.colors.length; z++) {
html += '<th><span style="color:' + cwColors2[z] + '">' + ztc.colors[z] + '</span></th>';
}
html += '</tr></thead><tbody>';
for (var r = 0; r < 5; r++) {
html += '<tr><td style="font-weight:bold;">' + ztc.zones[r] + '</td>';
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 += '<td style="background-color:' + bg + ';color:' + txt + ';">' + cnt + '次<br>' + pct + '%</td>';
}
html += '</tr>';
}
html += '</tbody></table>';
}
html += '</div>';
}
// 热力图部分