feat(admin): 尾首概率弹窗增加相同明细数据
后端新增 tailSameDetail 和 headSameDetail 字段,统计相邻两期 特码尾数/首位相同的具体值及出现次数 前端弹窗新增两个明细表格展示
This commit is contained in:
@@ -988,7 +988,7 @@ class History extends Model
|
|||||||
* 尾首概率:下一期尾数/首位与前一期相同的概率
|
* 尾首概率:下一期尾数/首位与前一期相同的概率
|
||||||
* 统计相邻两期特码的尾数(num%10)和首位(floor(num/10))变化
|
* 统计相邻两期特码的尾数(num%10)和首位(floor(num/10))变化
|
||||||
* @param int $periods 查询最近多少期
|
* @param int $periods 查询最近多少期
|
||||||
* @return array {tailProb: float, headProb: float, totalTransitions: int, periodCount: int}
|
* @return array {tailProb: float, headProb: float, tailSameDetail: array, headSameDetail: array, totalTransitions: int, periodCount: int}
|
||||||
*/
|
*/
|
||||||
public function getTailHeadProbability($periods = 100)
|
public function getTailHeadProbability($periods = 100)
|
||||||
{
|
{
|
||||||
@@ -999,7 +999,7 @@ class History extends Model
|
|||||||
->select();
|
->select();
|
||||||
|
|
||||||
if (empty($history) || count($history) < 2) {
|
if (empty($history) || count($history) < 2) {
|
||||||
return ['tailProb' => 0, 'headProb' => 0, 'totalTransitions' => 0, 'periodCount' => 0];
|
return ['tailProb' => 0, 'headProb' => 0, 'tailSameDetail' => [], 'headSameDetail' => [], 'totalTransitions' => 0, 'periodCount' => 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按时间升序排列(旧→新)
|
// 按时间升序排列(旧→新)
|
||||||
@@ -1008,6 +1008,8 @@ class History extends Model
|
|||||||
$tailSame = 0;
|
$tailSame = 0;
|
||||||
$headSame = 0;
|
$headSame = 0;
|
||||||
$totalTransitions = 0;
|
$totalTransitions = 0;
|
||||||
|
$tailSameDetail = []; // 尾数相同明细: key为尾数, value为次数
|
||||||
|
$headSameDetail = []; // 首位相同明细: key为首数, value为次数
|
||||||
|
|
||||||
for ($i = 0; $i < count($history) - 1; $i++) {
|
for ($i = 0; $i < count($history) - 1; $i++) {
|
||||||
$currentNum = (int)$history[$i]['num7'];
|
$currentNum = (int)$history[$i]['num7'];
|
||||||
@@ -1018,21 +1020,51 @@ class History extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
$totalTransitions++;
|
$totalTransitions++;
|
||||||
|
$currentTail = $currentNum % 10;
|
||||||
|
$nextTail = $nextNum % 10;
|
||||||
|
$currentHead = intval(floor($currentNum / 10));
|
||||||
|
$nextHead = intval(floor($nextNum / 10));
|
||||||
|
|
||||||
// 尾数相同(个位相同)
|
// 尾数相同(个位相同)
|
||||||
if (($currentNum % 10) === ($nextNum % 10)) {
|
if ($currentTail === $nextTail) {
|
||||||
$tailSame++;
|
$tailSame++;
|
||||||
|
$key = $currentTail;
|
||||||
|
if (!isset($tailSameDetail[$key])) {
|
||||||
|
$tailSameDetail[$key] = 0;
|
||||||
|
}
|
||||||
|
$tailSameDetail[$key]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 首位相同(十位相同)
|
// 首位相同(十位相同)
|
||||||
if (intval(floor($currentNum / 10)) === intval(floor($nextNum / 10))) {
|
if ($currentHead === $nextHead) {
|
||||||
$headSame++;
|
$headSame++;
|
||||||
|
$key = $currentHead;
|
||||||
|
if (!isset($headSameDetail[$key])) {
|
||||||
|
$headSameDetail[$key] = 0;
|
||||||
|
}
|
||||||
|
$headSameDetail[$key]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序:尾数按0-9排序,首位按0-4排序
|
||||||
|
$tailResult = [];
|
||||||
|
for ($t = 0; $t <= 9; $t++) {
|
||||||
|
if (isset($tailSameDetail[$t])) {
|
||||||
|
$tailResult[] = ['tail' => $t, 'count' => $tailSameDetail[$t]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$headResult = [];
|
||||||
|
for ($h = 0; $h <= 4; $h++) {
|
||||||
|
if (isset($headSameDetail[$h])) {
|
||||||
|
$headResult[] = ['head' => $h, 'count' => $headSameDetail[$h]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'tailProb' => $totalTransitions > 0 ? round($tailSame / $totalTransitions * 100, 2) : 0,
|
'tailProb' => $totalTransitions > 0 ? round($tailSame / $totalTransitions * 100, 2) : 0,
|
||||||
'headProb' => $totalTransitions > 0 ? round($headSame / $totalTransitions * 100, 2) : 0,
|
'headProb' => $totalTransitions > 0 ? round($headSame / $totalTransitions * 100, 2) : 0,
|
||||||
|
'tailSameDetail' => $tailResult,
|
||||||
|
'headSameDetail' => $headResult,
|
||||||
'totalTransitions' => $totalTransitions,
|
'totalTransitions' => $totalTransitions,
|
||||||
'periodCount' => count($history)
|
'periodCount' => count($history)
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -2212,6 +2212,30 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
html += '<tr><td>下一期尾数与前一期尾数相同</td><td style="text-align:center;font-size:18px;font-weight:bold;color:#e65100;">' + d.tailProb + '%</td></tr>';
|
html += '<tr><td>下一期尾数与前一期尾数相同</td><td style="text-align:center;font-size:18px;font-weight:bold;color:#e65100;">' + d.tailProb + '%</td></tr>';
|
||||||
html += '<tr><td>下一期首位与前一期首位相同</td><td style="text-align:center;font-size:18px;font-weight:bold;color:#e65100;">' + d.headProb + '%</td></tr>';
|
html += '<tr><td>下一期首位与前一期首位相同</td><td style="text-align:center;font-size:18px;font-weight:bold;color:#e65100;">' + d.headProb + '%</td></tr>';
|
||||||
html += '</table></div>';
|
html += '</table></div>';
|
||||||
|
// 尾数相同明细
|
||||||
|
if (d.tailSameDetail && d.tailSameDetail.length > 0) {
|
||||||
|
html += '<div style="padding:15px;background:#f5f5f5;border-radius:8px;margin-bottom:12px;">';
|
||||||
|
html += '<div style="font-size:13px;font-weight:bold;color:#333;margin-bottom:8px;"><i class="fa fa-list-ol"></i> 尾数相同明细</div>';
|
||||||
|
html += '<table class="table table-bordered" style="margin-bottom:0;">';
|
||||||
|
html += '<tr><th>尾数</th><th>出现次数</th></tr>';
|
||||||
|
for (var i = 0; i < d.tailSameDetail.length; i++) {
|
||||||
|
var item = d.tailSameDetail[i];
|
||||||
|
html += '<tr><td style="text-align:center;">尾数 ' + item.tail + '</td><td style="text-align:center;font-weight:bold;">' + item.count + ' 次</td></tr>';
|
||||||
|
}
|
||||||
|
html += '</table></div>';
|
||||||
|
}
|
||||||
|
// 首位相同明细
|
||||||
|
if (d.headSameDetail && d.headSameDetail.length > 0) {
|
||||||
|
html += '<div style="padding:15px;background:#f5f5f5;border-radius:8px;margin-bottom:12px;">';
|
||||||
|
html += '<div style="font-size:13px;font-weight:bold;color:#333;margin-bottom:8px;"><i class="fa fa-list-ol"></i> 首位相同明细</div>';
|
||||||
|
html += '<table class="table table-bordered" style="margin-bottom:0;">';
|
||||||
|
html += '<tr><th>首位</th><th>出现次数</th></tr>';
|
||||||
|
for (var i = 0; i < d.headSameDetail.length; i++) {
|
||||||
|
var item = d.headSameDetail[i];
|
||||||
|
html += '<tr><td style="text-align:center;">首数 ' + item.head + '</td><td style="text-align:center;font-weight:bold;">' + item.count + ' 次</td></tr>';
|
||||||
|
}
|
||||||
|
html += '</table></div>';
|
||||||
|
}
|
||||||
html += '<div style="font-size:12px;color:#999;">共分析 ' + d.periodCount + ' 期数据,' + d.totalTransitions + ' 次转移</div>';
|
html += '<div style="font-size:12px;color:#999;">共分析 ' + d.periodCount + ' 期数据,' + d.totalTransitions + ' 次转移</div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
$('#tailheadprob-result').html(html);
|
$('#tailheadprob-result').html(html);
|
||||||
|
|||||||
Reference in New Issue
Block a user