feat(history): 新增特码冷热查询功能 — 选定某一期向前y期判定冷热号
在history页面添加「特码冷热」按钮,用户可选择指定期号并设定向前期数 系统统计该期特码在向前范围内的出现频率,与平均值对比判定冷/温/热号
This commit is contained in:
@@ -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'];
|
||||
protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction'];
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
@@ -236,6 +236,28 @@ class History extends Backend
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 特码冷热查询(指定期号向前y期判定)
|
||||
*/
|
||||
public function specialHotColdAction()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
$expect = $this->request->get('expect', '');
|
||||
if (empty($expect)) {
|
||||
$this->error('请输入期号');
|
||||
}
|
||||
$lookback = $this->request->get('lookback', 30, 'intval');
|
||||
if ($lookback < 10 || $lookback > 100) {
|
||||
$this->error('向前期数范围必须在 10-100 之间');
|
||||
}
|
||||
$result = $this->model->getSpecialHotColdByExpect($expect, $lookback);
|
||||
if ($result === false) {
|
||||
$this->error('未找到该期号数据');
|
||||
}
|
||||
$this->success('查询成功', null, $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 特码热力图
|
||||
*/
|
||||
|
||||
@@ -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 查询最近多少期
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<a href="javascript:;" class="btn btn-success btn-sumchart" title="{:__('Sum Chart')}"><i class="fa fa-line-chart"></i> {:__('Sum Chart')}</a>
|
||||
<a href="javascript:;" class="btn btn-warning btn-consecutive" title="{:__('Consecutive')}"><i class="fa fa-link"></i> {:__('Consecutive')}</a>
|
||||
<a href="javascript:;" class="btn btn-default btn-tailnums" title="{:__('Tail Numbers')}"><i class="fa fa-list-ol"></i> {:__('Tail Numbers')}</a>
|
||||
<a href="javascript:;" class="btn btn-danger btn-specialhotcold" title="{:__('Special Hot/Cold')}"><i class="fa fa-fire"></i> {:__('Special Hot/Cold')}</a>
|
||||
<!-- <a href="javascript:;" class="btn btn-success btn-dashboard" title="{:__('Dashboard')}"><i class="fa fa-tachometer"></i> {:__('Dashboard')}</a>-->
|
||||
<!-- <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('history/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>-->
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user