feat(admin): 新增尾首概率分析弹窗

在history页面工具栏添加"尾首概率"按钮,弹窗显示:
- 下一期尾数与前一期尾数相同的概率
- 下一期首位与前一期首位相同的概率
支持切换统计期数(30/50/100/200期)
This commit is contained in:
2026-05-02 15:36:00 +08:00
parent 8b2590c5b5
commit 919fbbc148
4 changed files with 134 additions and 1 deletions
+54
View File
@@ -984,6 +984,60 @@ class History extends Model
];
}
/**
* 尾首概率:下一期尾数/首位与前一期相同的概率
* 统计相邻两期特码的尾数(num%10)和首位(floor(num/10))变化
* @param int $periods 查询最近多少期
* @return array {tailProb: float, headProb: float, totalTransitions: int, periodCount: int}
*/
public function getTailHeadProbability($periods = 100)
{
$history = $this
->field('expect,num7,openTime')
->order('openTime', 'desc')
->limit($periods)
->select();
if (empty($history) || count($history) < 2) {
return ['tailProb' => 0, 'headProb' => 0, 'totalTransitions' => 0, 'periodCount' => 0];
}
// 按时间升序排列(旧→新)
$history = array_reverse($history);
$tailSame = 0;
$headSame = 0;
$totalTransitions = 0;
for ($i = 0; $i < count($history) - 1; $i++) {
$currentNum = (int)$history[$i]['num7'];
$nextNum = (int)$history[$i + 1]['num7'];
if ($currentNum < 1 || $currentNum > 49 || $nextNum < 1 || $nextNum > 49) {
continue;
}
$totalTransitions++;
// 尾数相同(个位相同)
if (($currentNum % 10) === ($nextNum % 10)) {
$tailSame++;
}
// 首位相同(十位相同)
if (intval(floor($currentNum / 10)) === intval(floor($nextNum / 10))) {
$headSame++;
}
}
return [
'tailProb' => $totalTransitions > 0 ? round($tailSame / $totalTransitions * 100, 2) : 0,
'headProb' => $totalTransitions > 0 ? round($headSame / $totalTransitions * 100, 2) : 0,
'totalTransitions' => $totalTransitions,
'periodCount' => count($history)
];
}
/**
* 区域→区域转移矩阵,单元格内显示波色概率
* 统计上一期特码所在区域后,下一期特码在各区域的分布,以及每个区域内的波色占比