feat(history): 新增特码冷热查询功能 — 选定某一期向前y期判定冷热号
在history页面添加「特码冷热」按钮,用户可选择指定期号并设定向前期数 系统统计该期特码在向前范围内的出现频率,与平均值对比判定冷/温/热号
This commit is contained in:
@@ -468,6 +468,106 @@ class History extends Model
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定期号特码在向前y期范围内的冷热状态
|
||||
* @param string|int $expect 指定期号
|
||||
* @param int $lookback 向前推算期数
|
||||
* @return array|false 冷热状态数据,未找到返回false
|
||||
*/
|
||||
public function getSpecialHotColdByExpect($expect, $lookback = 30)
|
||||
{
|
||||
// 查询指定期号的数据
|
||||
$target = $this->where('expect', $expect)->field('expect,num7,openTime')->find();
|
||||
if (!$target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$specialNum = (int)$target['num7'];
|
||||
|
||||
// 查询该期往前lookback期的数据(按openTime排序,取目标期之前的lookback条)
|
||||
$history = $this
|
||||
->field('expect,num7,openTime')
|
||||
->where('openTime', '<', $target['openTime'])
|
||||
->order('openTime', 'desc')
|
||||
->limit($lookback)
|
||||
->select();
|
||||
|
||||
$totalPeriods = count($history);
|
||||
if ($totalPeriods === 0) {
|
||||
return [
|
||||
'expect' => (string)$expect,
|
||||
'specialNum' => $specialNum,
|
||||
'lookback' => $lookback,
|
||||
'count' => 0,
|
||||
'avgCount' => 0,
|
||||
'status' => 'cold',
|
||||
'rank' => 0,
|
||||
'totalPeriods' => 0,
|
||||
'allStats' => []
|
||||
];
|
||||
}
|
||||
|
||||
// 统计lookback范围内每个特码的出现次数
|
||||
$count = array_fill(1, 49, 0);
|
||||
foreach ($history as $row) {
|
||||
$num = (int)$row['num7'];
|
||||
if ($num >= 1 && $num <= 49) {
|
||||
$count[$num]++;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算目标特码的出现次数
|
||||
$targetCount = $count[$specialNum];
|
||||
|
||||
// 计算平均出现次数(49个号码,totalPeriods期)
|
||||
$avgCount = $totalPeriods / 49;
|
||||
|
||||
// 判定冷热
|
||||
$status = 'normal';
|
||||
if ($avgCount > 0) {
|
||||
if ($targetCount > $avgCount * 1.5) {
|
||||
$status = 'hot';
|
||||
} elseif ($targetCount < $avgCount * 0.5) {
|
||||
$status = 'cold';
|
||||
}
|
||||
}
|
||||
|
||||
// 计算排名(按出现次数降序)
|
||||
$sorted = [];
|
||||
for ($num = 1; $num <= 49; $num++) {
|
||||
$sorted[] = ['num' => $num, 'count' => $count[$num]];
|
||||
}
|
||||
usort($sorted, function ($a, $b) {
|
||||
return $b['count'] - $a['count'];
|
||||
});
|
||||
|
||||
$rank = 0;
|
||||
foreach ($sorted as $idx => $item) {
|
||||
if ($item['num'] === $specialNum) {
|
||||
$rank = $idx + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 构建所有号码的统计(只返回top和bottom用于展示)
|
||||
$hotNums = array_slice($sorted, 0, 5);
|
||||
$coldNums = array_slice($sorted, -5);
|
||||
$coldNums = array_reverse($coldNums);
|
||||
|
||||
return [
|
||||
'expect' => (string)$expect,
|
||||
'specialNum' => $specialNum,
|
||||
'lookback' => $lookback,
|
||||
'count' => $targetCount,
|
||||
'avgCount' => round($avgCount, 2),
|
||||
'status' => $status,
|
||||
'rank' => $rank,
|
||||
'totalPeriods' => $totalPeriods,
|
||||
'hotNums' => $hotNums,
|
||||
'coldNums' => $coldNums
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 特码热力图数据
|
||||
* @param int $periods 查询最近多少期
|
||||
|
||||
Reference in New Issue
Block a user