From 616239392a882b22b770e4264d60d72161805ae8 Mon Sep 17 00:00:00 2001 From: leon <916117771@qq.com> Date: Tue, 21 Apr 2026 23:33:39 +0800 Subject: [PATCH] feat(phase-2): add trend chart analysis - grid view of number history --- application/admin/controller/History.php | 22 +++- application/admin/lang/zh-cn/history.php | 2 + application/admin/model/History.php | 50 +++++++++ application/admin/view/history/index.html | 1 + public/assets/js/backend/history.js | 129 ++++++++++++++++++++++ 5 files changed, 203 insertions(+), 1 deletion(-) diff --git a/application/admin/controller/History.php b/application/admin/controller/History.php index 87e3510..27120ac 100644 --- a/application/admin/controller/History.php +++ b/application/admin/controller/History.php @@ -22,7 +22,7 @@ class History extends Backend * 无需额外权限检查的方法(但仍在 admin 模块内,需要 admin 登录) * @var array */ - protected $noNeedRight = ['missingNum']; + protected $noNeedRight = ['missingNum', 'trendData']; public function _initialize() { @@ -52,5 +52,25 @@ class History extends Backend } } + /** + * 获取走势图数据 + * @return void + */ + public function trendData() + { + if ($this->request->isAjax()) { + $periods = $this->request->get('periods', 30, 'intval'); + if ($periods < 10 || $periods > 100) { + $this->error('期数范围必须在 10-100 之间'); + } + $type = $this->request->get('type', 'all'); + if (!in_array($type, ['all', 'special'])) { + $this->error('查询类型不正确'); + } + $result = $this->model->getTrendData($periods, $type); + $this->success('查询成功', null, $result); + } + } + } diff --git a/application/admin/lang/zh-cn/history.php b/application/admin/lang/zh-cn/history.php index 2138d21..9c9314f 100644 --- a/application/admin/lang/zh-cn/history.php +++ b/application/admin/lang/zh-cn/history.php @@ -15,4 +15,6 @@ return [ 'Query Type' => '查询类型', 'All Numbers' => '全部号码', 'Special Only' => '仅特码', + 'Trend Chart' => '走势图', + 'No data available' => '暂无数据', ]; diff --git a/application/admin/model/History.php b/application/admin/model/History.php index 3895bf9..be03d32 100644 --- a/application/admin/model/History.php +++ b/application/admin/model/History.php @@ -30,6 +30,56 @@ class History extends Model ]; + /** + * 获取走势图数据 + * @param int $periods 查询最近多少期 + * @param string $type 查询类型 all=全部号码 special=仅特码 + * @return array {expects: [], data: [[num1,...], ...], colorMap: []} + */ + public function getTrendData($periods = 30, $type = 'all') + { + // 查询波色映射 + $num_model = new Num(); + $colorMap = $num_model->column('color', 'num'); + + $history = $this + ->field('expect,num1,num2,num3,num4,num5,num6,num7,openTime') + ->order('openTime', 'asc') + ->limit($periods) + ->select(); + + if (empty($history)) { + return ['expects' => [], 'data' => [], 'colorMap' => []]; + } + + $expects = []; + $data = []; + foreach ($history as $row) { + $expects[] = (string)$row['expect']; + if ($type === 'special') { + $num = (int)$row['num7']; + $data[] = [ + 'num7' => $num, + 'num7_color' => isset($colorMap[$num]) ? $colorMap[$num] : '—' + ]; + } else { + $row_data = []; + for ($i = 1; $i <= 7; $i++) { + $num = (int)$row['num' . $i]; + $row_data['num' . $i] = $num; + $row_data['num' . $i . '_color'] = isset($colorMap[$num]) ? $colorMap[$num] : '—'; + } + $data[] = $row_data; + } + } + + return [ + 'expects' => $expects, + 'data' => $data, + 'colorMap' => $colorMap + ]; + } + /** * 计算遗漏号码 * @param int $periods 查询最近多少期 diff --git a/application/admin/view/history/index.html b/application/admin/view/history/index.html index 9556e79..f7fbe1d 100644 --- a/application/admin/view/history/index.html +++ b/application/admin/view/history/index.html @@ -8,6 +8,7 @@
{:__('Missing Number Analysis')} + {:__('Trend Chart')}
' + + ' ' + + ' ' + + ' ' + + '' + + '
' + + ' ' + + ' ' + + ' ' + + '
' + + '
' + + ''; + + Layer.open({ + type: 1, + title: __('Trend Chart'), + area: ['90%', '80%'], + content: html, + shadeClose: false, + maxmin: true, + success: function (layero, index) { + $('#btn-trend-query', layero).on('click', function () { + var periods = parseInt($('#trend-periods', layero).val()) || 30; + var type = $('input[name="trend-type"]:checked', layero).val(); + Controller.api.queryTrend(periods, type, layero); + }); + $('input[name="trend-type"]', layero).on('change', function () { + var periods = parseInt($('#trend-periods', layero).val()) || 30; + Controller.api.queryTrend(periods, $(this).val(), layero); + }); + } + }); + }, + + /** + * 查询走势图 + */ + queryTrend: function (periods, type, layero) { + var $btn = $('#btn-trend-query', layero); + $btn.prop('disabled', true); + $('#trend-result', layero).html('
' + __('Loading') + '
'); + $.ajax({ + url: 'history/trendData', + type: 'GET', + data: {periods: periods, type: type}, + dataType: 'json', + success: function (ret) { + if (ret.code == 1) { + Controller.api.renderTrend(ret.data, type, layero); + } else { + $('#trend-result', layero).html('
' + (ret.msg || __('Query failed')) + '
'); + } + }, + error: function () { + $('#trend-result', layero).html('
' + __('Query failed') + '
'); + }, + complete: function () { + $btn.prop('disabled', false); + } + }); + }, + + /** + * 渲染走势图(网格形式) + */ + renderTrend: function (data, type, layero) { + var expects = data.expects; + var rows = data.data; + var colorMap = data.colorMap; + + if (!expects || expects.length === 0) { + $('#trend-result', layero).html('
' + __('No data available') + '
'); + return; + } + + var getColor = function (num) { + var color = colorMap[num]; + if (!color) return '#95a5a6'; + if (color.indexOf('红') !== -1) return '#e74c3c'; + if (color.indexOf('蓝') !== -1) return '#3498db'; + if (color.indexOf('绿') !== -1) return '#2ecc71'; + return '#95a5a6'; + }; + + var html = '
'; + html += ''; + if (type === 'special') { + html += ''; + } else { + for (var c = 1; c <= 7; c++) { + html += ''; + } + } + html += ''; + + for (var i = 0; i < expects.length; i++) { + html += ''; + if (type === 'special') { + var num = rows[i].num7; + var color = getColor(num); + html += ''; + } else { + for (var j = 1; j <= 7; j++) { + var val = rows[i]['num' + j]; + var c = getColor(val); + html += ''; + } + } + html += ''; + } + html += '
期号特码' + c + '
' + expects[i] + '' + num + '' + val + '
'; + + $('#trend-result', layero).html(html); + }, + /** * 显示遗漏号码分析弹窗 */