Compare commits
6 Commits
8b2590c5b5
...
d92cf6cfbc
| Author | SHA1 | Date | |
|---|---|---|---|
| d92cf6cfbc | |||
| 182d322b4e | |||
| 6c1754417c | |||
| 31cd375ff1 | |||
| e07d472dd1 | |||
| 919fbbc148 |
+98
-13
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lastScanned": 1777648534656,
|
"lastScanned": 1777820257271,
|
||||||
"projectRoot": "D:\\code\\php\\amlhc",
|
"projectRoot": "D:\\code\\php\\amlhc",
|
||||||
"techStack": {
|
"techStack": {
|
||||||
"languages": [
|
"languages": [
|
||||||
@@ -54,14 +54,14 @@
|
|||||||
"path": "addons",
|
"path": "addons",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 1,
|
"fileCount": 1,
|
||||||
"lastAccessed": 1777648534596,
|
"lastAccessed": 1777820257227,
|
||||||
"keyFiles": []
|
"keyFiles": []
|
||||||
},
|
},
|
||||||
"analysis": {
|
"analysis": {
|
||||||
"path": "analysis",
|
"path": "analysis",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 2,
|
"fileCount": 2,
|
||||||
"lastAccessed": 1777648534608,
|
"lastAccessed": 1777820257228,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"predict_analysis.php",
|
"predict_analysis.php",
|
||||||
"predict_analysis.py"
|
"predict_analysis.py"
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"path": "application",
|
"path": "application",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 8,
|
"fileCount": 8,
|
||||||
"lastAccessed": 1777648534609,
|
"lastAccessed": 1777820257239,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"build.php",
|
"build.php",
|
||||||
"command.php",
|
"command.php",
|
||||||
@@ -84,14 +84,14 @@
|
|||||||
"path": "extend",
|
"path": "extend",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 1,
|
"fileCount": 1,
|
||||||
"lastAccessed": 1777648534611,
|
"lastAccessed": 1777820257239,
|
||||||
"keyFiles": []
|
"keyFiles": []
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"path": "public",
|
"path": "public",
|
||||||
"purpose": "Public files",
|
"purpose": "Public files",
|
||||||
"fileCount": 5,
|
"fileCount": 5,
|
||||||
"lastAccessed": 1777648534612,
|
"lastAccessed": 1777820257240,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"admin.php",
|
"admin.php",
|
||||||
"index.php",
|
"index.php",
|
||||||
@@ -103,14 +103,14 @@
|
|||||||
"path": "runtime",
|
"path": "runtime",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 1,
|
"fileCount": 1,
|
||||||
"lastAccessed": 1777648534612,
|
"lastAccessed": 1777820257240,
|
||||||
"keyFiles": []
|
"keyFiles": []
|
||||||
},
|
},
|
||||||
"sql": {
|
"sql": {
|
||||||
"path": "sql",
|
"path": "sql",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 2,
|
"fileCount": 2,
|
||||||
"lastAccessed": 1777648534612,
|
"lastAccessed": 1777820257240,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"amlhc.sql",
|
"amlhc.sql",
|
||||||
"macaujc_history.sql"
|
"macaujc_history.sql"
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
"path": "thinkphp",
|
"path": "thinkphp",
|
||||||
"purpose": null,
|
"purpose": null,
|
||||||
"fileCount": 15,
|
"fileCount": 15,
|
||||||
"lastAccessed": 1777648534613,
|
"lastAccessed": 1777820257241,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"base.php",
|
"base.php",
|
||||||
"codecov.yml",
|
"codecov.yml",
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
"path": "vendor",
|
"path": "vendor",
|
||||||
"purpose": "Third-party code",
|
"purpose": "Third-party code",
|
||||||
"fileCount": 1,
|
"fileCount": 1,
|
||||||
"lastAccessed": 1777648534613,
|
"lastAccessed": 1777820257242,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"autoload.php"
|
"autoload.php"
|
||||||
]
|
]
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
"path": "application\\api",
|
"path": "application\\api",
|
||||||
"purpose": "API routes",
|
"purpose": "API routes",
|
||||||
"fileCount": 2,
|
"fileCount": 2,
|
||||||
"lastAccessed": 1777648534614,
|
"lastAccessed": 1777820257242,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"common.php",
|
"common.php",
|
||||||
"config.php"
|
"config.php"
|
||||||
@@ -152,12 +152,97 @@
|
|||||||
"path": "public\\assets",
|
"path": "public\\assets",
|
||||||
"purpose": "Static assets",
|
"purpose": "Static assets",
|
||||||
"fileCount": 1,
|
"fileCount": 1,
|
||||||
"lastAccessed": 1777648534615,
|
"lastAccessed": 1777820257246,
|
||||||
"keyFiles": [
|
"keyFiles": [
|
||||||
"index.html"
|
"index.html"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hotPaths": [],
|
"hotPaths": [
|
||||||
|
{
|
||||||
|
"path": "public\\assets\\js\\backend\\history.js",
|
||||||
|
"accessCount": 40,
|
||||||
|
"lastAccessed": 1777724915715,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "application\\admin\\model\\History.php",
|
||||||
|
"accessCount": 12,
|
||||||
|
"lastAccessed": 1777724152835,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "application\\admin\\controller\\History.php",
|
||||||
|
"accessCount": 10,
|
||||||
|
"lastAccessed": 1777724090471,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "application\\admin\\view\\history\\index.html",
|
||||||
|
"accessCount": 5,
|
||||||
|
"lastAccessed": 1777707308124,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".planning\\STATE.md",
|
||||||
|
"accessCount": 3,
|
||||||
|
"lastAccessed": 1777707396710,
|
||||||
|
"type": "directory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "C:\\Users\\91611\\.claude\\get-shit-done\\workflows\\do.md",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777706998579,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "C:\\Users\\91611\\.claude\\get-shit-done\\workflows\\quick.md",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707018668,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "sql",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707065981,
|
||||||
|
"type": "directory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "public\\assets\\js",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707066026,
|
||||||
|
"type": "directory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "application\\admin\\view\\history\\add.html",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707072623,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "application\\admin\\view\\history\\edit.html",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707072753,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "sql\\amlhc.sql",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707078109,
|
||||||
|
"type": "directory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".planning\\quick\\260502-ljh-history\\260502-ljh-PLAN.md",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707180604,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".planning\\quick\\260502-ljh-history\\260502-ljh-SUMMARY.md",
|
||||||
|
"accessCount": 1,
|
||||||
|
"lastAccessed": 1777707369645,
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
],
|
||||||
"userDirectives": []
|
"userDirectives": []
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"session_id": "48d5215c-775c-44f9-8ec6-6db1fd3b93eb",
|
||||||
|
"ended_at": "2026-05-02T07:44:06.062Z",
|
||||||
|
"reason": "prompt_input_exit",
|
||||||
|
"agents_spawned": 0,
|
||||||
|
"agents_completed": 0,
|
||||||
|
"modes_used": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"session_id": "4f5fb28f-8a85-463e-be5e-c99955a9aaf9",
|
||||||
|
"ended_at": "2026-05-02T07:44:04.023Z",
|
||||||
|
"reason": "clear",
|
||||||
|
"agents_spawned": 1,
|
||||||
|
"agents_completed": 1,
|
||||||
|
"modes_used": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"session_id": "5593524e-595e-428a-8b8b-24a839d4cc08",
|
||||||
|
"ended_at": "2026-05-02T14:36:45.873Z",
|
||||||
|
"reason": "prompt_input_exit",
|
||||||
|
"agents_spawned": 0,
|
||||||
|
"agents_completed": 0,
|
||||||
|
"modes_used": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"session_id": "c14a7924-1cf5-49df-8355-0fc9eb55d8fb",
|
||||||
|
"ended_at": "2026-05-03T14:57:39.936Z",
|
||||||
|
"reason": "prompt_input_exit",
|
||||||
|
"agents_spawned": 0,
|
||||||
|
"agents_completed": 0,
|
||||||
|
"modes_used": []
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"session_id":"a1d5e02a-7411-4199-815c-5ae711cf7291","transcript_path":"C:\\Users\\91611\\.claude\\projects\\D--code-php-amlhc\\a1d5e02a-7411-4199-815c-5ae711cf7291.jsonl","cwd":"D:\\code\\php\\amlhc","model":{"id":"qwen3.6-plus[1m]","display_name":"qwen3.6-plus[1m]"},"workspace":{"current_dir":"D:\\code\\php\\amlhc","project_dir":"D:\\code\\php\\amlhc","added_dirs":[]},"version":"2.1.126","output_style":{"name":"default"},"cost":{"total_cost_usd":0,"total_duration_ms":1008,"total_api_duration_ms":0,"total_lines_added":0,"total_lines_removed":0},"context_window":{"total_input_tokens":0,"total_output_tokens":0,"context_window_size":1000000,"current_usage":null,"used_percentage":null,"remaining_percentage":null},"exceeds_200k_tokens":false,"fast_mode":false,"effort":{"level":"high"},"thinking":{"enabled":true}}
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"updatedAt": "2026-05-02T07:44:04.057Z",
|
||||||
|
"missions": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2026-05-02T14:41:38.945Z",
|
||||||
|
"backgroundTasks": [],
|
||||||
|
"sessionStartTimestamp": "2026-05-02T14:40:41.364Z",
|
||||||
|
"sessionId": "0402461b-cd9c-400b-8fa2-405c6db26368"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2026-05-02T07:28:11.619Z",
|
||||||
|
"backgroundTasks": [],
|
||||||
|
"sessionStartTimestamp": "2026-05-02T07:28:04.316Z",
|
||||||
|
"sessionId": "4f5fb28f-8a85-463e-be5e-c99955a9aaf9"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2026-05-02T12:14:48.284Z",
|
||||||
|
"backgroundTasks": [],
|
||||||
|
"sessionStartTimestamp": "2026-05-02T12:14:30.545Z",
|
||||||
|
"sessionId": "5593524e-595e-428a-8b8b-24a839d4cc08"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2026-05-02T08:13:32.296Z",
|
||||||
|
"backgroundTasks": [],
|
||||||
|
"sessionStartTimestamp": "2026-05-02T08:05:12.717Z",
|
||||||
|
"sessionId": "8dafebc5-6242-4ed6-8370-bd53345e315e"
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"timestamp": "2026-05-02T12:12:11.936Z",
|
||||||
|
"backgroundTasks": [],
|
||||||
|
"sessionStartTimestamp": "2026-05-02T12:12:11.651Z",
|
||||||
|
"sessionId": "b7109af9-c36f-4869-8f05-c5c90c07b75e"
|
||||||
|
}
|
||||||
@@ -85,6 +85,8 @@ None yet.
|
|||||||
| 260424-roj | 在history页面新增特码冷热查询功能 | 2026-04-24 | 2513bbb | [260424-roj](./quick/260424-roj-history-y/) |
|
| 260424-roj | 在history页面新增特码冷热查询功能 | 2026-04-24 | 2513bbb | [260424-roj](./quick/260424-roj-history-y/) |
|
||||||
| 260425-w2i | 在控制台页面新增区域转移概率统计功能 | 2026-04-25 | 28415a1 | [260425-w2i](./quick/260425-w2i-5-10/) |
|
| 260425-w2i | 在控制台页面新增区域转移概率统计功能 | 2026-04-25 | 28415a1 | [260425-w2i](./quick/260425-w2i-5-10/) |
|
||||||
|
|
||||||
|
| 260502-ljh | 在history页面新增尾首概率分析弹窗 | 2026-05-02 | 919fbbc | [260502-ljh](./quick/260502-ljh-history/) |
|
||||||
|
|
||||||
## Deferred Items
|
## Deferred Items
|
||||||
|
|
||||||
| Category | Item | Status | Deferred At |
|
| Category | Item | Status | Deferred At |
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
title: "在history页面新增一个弹窗,显示:下一期尾数与前一期尾数相同的概率、下一期首位与前一期首位相同的概率"
|
||||||
|
mode: quick
|
||||||
|
status: in-progress
|
||||||
|
tasks_count: 3
|
||||||
|
created: 2026-05-02
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
|
||||||
|
### Task 1: 后端新增接口
|
||||||
|
- File: `application/admin/controller/History.php` — 新增 `tailHeadProbability` 方法
|
||||||
|
- File: `application/admin/model/History.php` — 新增 `getTailHeadProbability` 方法
|
||||||
|
- 逻辑:查询全部历史数据(按 openTime 升序),逐期对比相邻两期的尾数和首位,统计相同概率
|
||||||
|
|
||||||
|
### Task 2: 前端添加工具栏按钮
|
||||||
|
- File: `application/admin/view/history/index.html` — 在工具栏添加"尾首概率"按钮
|
||||||
|
|
||||||
|
### Task 3: 前端弹窗逻辑
|
||||||
|
- File: `public/assets/js/backend/history.js` — 新增按钮点击事件 + `showTailHeadProbabilityDialog` 方法
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
title: "在history页面新增一个弹窗,显示:下一期尾数与前一期尾数相同的概率、下一期首位与前一期首位相同的概率"
|
||||||
|
mode: quick
|
||||||
|
status: complete
|
||||||
|
date: 2026-05-02
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Completed quick task: Added a "尾首概率" (Tail-Head Probability) dialog to the history page.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- `application/admin/model/History.php` — Added `getTailHeadProbability()` method that analyzes consecutive period transitions of the special code (num7), calculating the probability of tail (ones digit) and head (tens digit) remaining the same
|
||||||
|
- `application/admin/controller/History.php` — Added `tailHeadProb` endpoint + added to `$noNeedRight`
|
||||||
|
- `application/admin/view/history/index.html` — Added toolbar button with `btn-tailheadprob` class
|
||||||
|
- `public/assets/js/backend/history.js` — Added click handler + `showTailHeadProbabilityDialog()` with period selector (30/50/100/200)
|
||||||
|
|
||||||
|
### Implementation details
|
||||||
|
- Tail = num % 10 (个位), Head = floor(num / 10) (十位)
|
||||||
|
- Only counts valid transitions (both numbers in 1-49 range)
|
||||||
|
- Displays probability as percentage with period count and transition count
|
||||||
@@ -22,7 +22,7 @@ class History extends Backend
|
|||||||
* 无需额外权限检查的方法(但仍在 admin 模块内,需要 admin 登录)
|
* 无需额外权限检查的方法(但仍在 admin 模块内,需要 admin 登录)
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction', 'zoneTransition', 'colorWaveTransition', 'zoneToColorTransition', 'zodiacTransition', 'tailNumberTransition', 'headNumberTransition', 'predict', 'predictV2', 'predictV3', 'optimizeWeights', 'predictByNormalRelation'];
|
protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction', 'zoneTransition', 'colorWaveTransition', 'zoneToColorTransition', 'zodiacTransition', 'tailNumberTransition', 'headNumberTransition', 'tailHeadProb', 'predict', 'predictV2', 'predictV3', 'predictV4', 'optimizeWeights', 'predictByNormalRelation'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
@@ -388,6 +388,18 @@ class History extends Backend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 尾首概率分析
|
||||||
|
*/
|
||||||
|
public function tailHeadProb()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$periods = $this->request->get('periods', 100, 'intval');
|
||||||
|
$result = $this->model->getTailHeadProbability($periods);
|
||||||
|
$this->success('查询成功', null, $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 综合预测号码
|
* 综合预测号码
|
||||||
* 基于历史多维度转移概率分析,给出号码预测建议
|
* 基于历史多维度转移概率分析,给出号码预测建议
|
||||||
@@ -488,6 +500,39 @@ class History extends Backend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多维度综合预测算法 V4
|
||||||
|
* 贝叶斯对数似然集成 + 指数时间衰减 + 形态匹配 + 周期性检测
|
||||||
|
* 六大子模型融合: EWMA频率 / 号码级马尔可夫 / 经验CDF遗漏 / 历史形态匹配 / 周期自相关 / 属性平衡
|
||||||
|
*/
|
||||||
|
public function predictV4()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$periods = $this->request->get('periods', 200, 'intval');
|
||||||
|
if ($periods < 30 || $periods > 500) {
|
||||||
|
$this->error('期数范围必须在 30-500 之间');
|
||||||
|
}
|
||||||
|
$weights = [];
|
||||||
|
$weightStr = $this->request->get('weights', '', 'trim');
|
||||||
|
if ($weightStr) {
|
||||||
|
$weightsArr = json_decode($weightStr, true);
|
||||||
|
if (is_array($weightsArr)) {
|
||||||
|
$weights = $weightsArr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$targetExpect = $this->request->get('target_expect', '', 'trim');
|
||||||
|
$backtestCount = $this->request->get('backtest', 50, 'intval');
|
||||||
|
if ($backtestCount < 10 || $backtestCount > 100) {
|
||||||
|
$backtestCount = 50;
|
||||||
|
}
|
||||||
|
$result = $this->model->getPredictionV4($periods, $weights, $targetExpect, false, $backtestCount);
|
||||||
|
if (isset($result['error'])) {
|
||||||
|
$this->error($result['error']);
|
||||||
|
}
|
||||||
|
$this->success('查询成功', null, $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权重网格搜索优化接口
|
* 权重网格搜索优化接口
|
||||||
* 执行多权重配置回测,返回最优权重组合
|
* 执行多权重配置回测,返回最优权重组合
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@
|
|||||||
<a href="javascript:;" class="btn btn-primary btn-numberfilter" title="筛号器"><i class="fa fa-filter"></i> 筛号器</a>
|
<a href="javascript:;" class="btn btn-primary btn-numberfilter" title="筛号器"><i class="fa fa-filter"></i> 筛号器</a>
|
||||||
<a href="javascript:;" class="btn btn-success btn-predict" title="智能预测"><i class="fa fa-magic"></i> 智能预测</a>
|
<a href="javascript:;" class="btn btn-success btn-predict" title="智能预测"><i class="fa fa-magic"></i> 智能预测</a>
|
||||||
<a href="javascript:;" class="btn btn-info btn-normal-relation" title="正码关联预测"><i class="fa fa-link"></i> 正码关联预测</a>
|
<a href="javascript:;" class="btn btn-info btn-normal-relation" title="正码关联预测"><i class="fa fa-link"></i> 正码关联预测</a>
|
||||||
|
<a href="javascript:;" class="btn btn-warning btn-tailheadprob" title="尾首概率"><i class="fa fa-percent"></i> 尾首概率</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-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>-->
|
<!-- <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>
|
</div>
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
$(document).off('click', '.btn-normal-relation').on('click', '.btn-normal-relation', function () {
|
$(document).off('click', '.btn-normal-relation').on('click', '.btn-normal-relation', function () {
|
||||||
Controller.api.showNormalRelationDialog();
|
Controller.api.showNormalRelationDialog();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 尾首概率按钮事件
|
||||||
|
$(document).off('click', '.btn-tailheadprob').on('click', '.btn-tailheadprob', function () {
|
||||||
|
Controller.api.showTailHeadProbabilityDialog();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
add: function () {
|
add: function () {
|
||||||
Controller.api.bindevent();
|
Controller.api.bindevent();
|
||||||
@@ -765,6 +770,11 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="nf-tail-list" style="margin-bottom:15px;display:flex;flex-wrap:wrap;gap:6px;"></div>' +
|
'<div id="nf-tail-list" style="margin-bottom:15px;display:flex;flex-wrap:wrap;gap:6px;"></div>' +
|
||||||
'<div style="margin-bottom:15px;">' +
|
'<div style="margin-bottom:15px;">' +
|
||||||
|
' <label>首位数筛选:</label>' +
|
||||||
|
' <button class="btn btn-xs btn-primary btn-nf-add-head"><i class="fa fa-plus"></i> 新增</button>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div id="nf-head-list" style="margin-bottom:15px;display:flex;flex-wrap:wrap;gap:6px;"></div>' +
|
||||||
|
'<div style="margin-bottom:15px;">' +
|
||||||
' <label style="margin-right:10px;">生肖:</label>' +
|
' <label style="margin-right:10px;">生肖:</label>' +
|
||||||
' <div id="nf-zodiac" style="display:inline-flex;gap:6px;flex-wrap:wrap;">' +
|
' <div id="nf-zodiac" style="display:inline-flex;gap:6px;flex-wrap:wrap;">' +
|
||||||
' <button class="btn btn-default btn-xs nf-zodiac" data-zodiac="鼠">鼠</button>' +
|
' <button class="btn btn-default btn-xs nf-zodiac" data-zodiac="鼠">鼠</button>' +
|
||||||
@@ -842,6 +852,21 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
Controller.api.applyNumberFilters(layero, blockedNums);
|
Controller.api.applyNumberFilters(layero, blockedNums);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 新增首位数
|
||||||
|
$('.btn-nf-add-head', layero).on('click', function () {
|
||||||
|
Controller.api.addHeadRow(layero, 0);
|
||||||
|
Controller.api.applyNumberFilters(layero, blockedNums);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首位数输入 & 删除事件委托
|
||||||
|
$('#nf-head-list', layero).on('input change', '.nf-head-select', function () {
|
||||||
|
Controller.api.applyNumberFilters(layero, blockedNums);
|
||||||
|
});
|
||||||
|
$('#nf-head-list', layero).on('click', '.nf-head-del', function () {
|
||||||
|
$(this).closest('.nf-head-row').remove();
|
||||||
|
Controller.api.applyNumberFilters(layero, blockedNums);
|
||||||
|
});
|
||||||
|
|
||||||
// 生肖按钮点击
|
// 生肖按钮点击
|
||||||
$('.nf-zodiac', layero).on('click', function () {
|
$('.nf-zodiac', layero).on('click', function () {
|
||||||
var $btn = $(this);
|
var $btn = $(this);
|
||||||
@@ -891,6 +916,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
$('.btn-nf-reset', layero).on('click', function () {
|
$('.btn-nf-reset', layero).on('click', function () {
|
||||||
blockedNums = [];
|
blockedNums = [];
|
||||||
$('#nf-tail-list', layero).html('');
|
$('#nf-tail-list', layero).html('');
|
||||||
|
$('#nf-head-list', layero).html('');
|
||||||
$('.nf-zodiac', layero).removeClass('btn-gray').addClass('btn-default');
|
$('.nf-zodiac', layero).removeClass('btn-gray').addClass('btn-default');
|
||||||
$('.nf-color-btn', layero).removeClass('btn-gray').addClass('btn-default');
|
$('.nf-color-btn', layero).removeClass('btn-gray').addClass('btn-default');
|
||||||
$('.nf-parity', layero).removeClass('btn-gray').addClass('btn-default');
|
$('.nf-parity', layero).removeClass('btn-gray').addClass('btn-default');
|
||||||
@@ -917,6 +943,22 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
$('#nf-tail-list', layero).append(html);
|
$('#nf-tail-list', layero).append(html);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增一行首位数筛选
|
||||||
|
*/
|
||||||
|
addHeadRow: function (layero, value) {
|
||||||
|
var rowId = 'nf-head-' + Date.now() + Math.random().toString(36).substr(2, 5);
|
||||||
|
var opts = '<option value="">首号</option>';
|
||||||
|
for (var h = 0; h <= 4; h++) {
|
||||||
|
opts += '<option value="' + h + '"' + (h === value ? ' selected' : '') + '>' + h + '</option>';
|
||||||
|
}
|
||||||
|
var html = '<div class="nf-head-row" id="' + rowId + '" style="display:inline-flex;align-items:center;gap:4px;">' +
|
||||||
|
' <select class="form-control nf-head-select" style="width:80px;display:inline-block;">' + opts + '</select>' +
|
||||||
|
' <button class="btn btn-xs btn-danger nf-head-del"><i class="fa fa-times"></i></button>' +
|
||||||
|
'</div>';
|
||||||
|
$('#nf-head-list', layero).append(html);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增一行区间筛选
|
* 新增一行区间筛选
|
||||||
*/
|
*/
|
||||||
@@ -948,7 +990,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
if (colorRaw.indexOf('红') !== -1) colorLabel = '红';
|
if (colorRaw.indexOf('红') !== -1) colorLabel = '红';
|
||||||
else if (colorRaw.indexOf('蓝') !== -1) colorLabel = '蓝';
|
else if (colorRaw.indexOf('蓝') !== -1) colorLabel = '蓝';
|
||||||
else if (colorRaw.indexOf('绿') !== -1) colorLabel = '绿';
|
else if (colorRaw.indexOf('绿') !== -1) colorLabel = '绿';
|
||||||
html += '<div class="nf-number" data-num="' + num + '" data-color="' + colorLabel + '" data-animal="' + animal + '" data-tail="' + (num % 10) + '" data-parity="' + (num % 2 === 1 ? '单' : '双') + '" style="text-align:center;background:#f9f9f9;padding:6px 4px;border-radius:6px;min-width:60px;transition:opacity 0.2s;cursor:pointer;" title="点击屏蔽/恢复">' +
|
html += '<div class="nf-number" data-num="' + num + '" data-color="' + colorLabel + '" data-animal="' + animal + '" data-tail="' + (num % 10) + '" data-head="' + Math.floor(num / 10) + '" data-parity="' + (num % 2 === 1 ? '单' : '双') + '" style="text-align:center;background:#f9f9f9;padding:6px 4px;border-radius:6px;min-width:60px;transition:opacity 0.2s;cursor:pointer;" title="点击屏蔽/恢复">' +
|
||||||
'<span style="display:inline-block;width:36px;height:36px;line-height:36px;text-align:center;border-radius:50%;color:#fff;background-color:' + colorHex + ';font-weight:bold;">' + num + '</span>' +
|
'<span style="display:inline-block;width:36px;height:36px;line-height:36px;text-align:center;border-radius:50%;color:#fff;background-color:' + colorHex + ';font-weight:bold;">' + num + '</span>' +
|
||||||
'<div style="font-size:10px;color:#666;line-height:1.2;">' + animal + '</div>' +
|
'<div style="font-size:10px;color:#666;line-height:1.2;">' + animal + '</div>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
@@ -971,6 +1013,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
excludedTails.push(parseInt(val));
|
excludedTails.push(parseInt(val));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 收集所有选中的首位数
|
||||||
|
var excludedHeads = [];
|
||||||
|
$('.nf-head-select', layero).each(function () {
|
||||||
|
var val = $(this).val();
|
||||||
|
if (val !== '' && excludedHeads.indexOf(parseInt(val)) === -1) {
|
||||||
|
excludedHeads.push(parseInt(val));
|
||||||
|
}
|
||||||
|
});
|
||||||
// 收集被点击(置灰)的生肖
|
// 收集被点击(置灰)的生肖
|
||||||
var excludedZodiacs = [];
|
var excludedZodiacs = [];
|
||||||
$('.nf-zodiac.btn-gray', layero).each(function () {
|
$('.nf-zodiac.btn-gray', layero).each(function () {
|
||||||
@@ -1000,6 +1050,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
var $num = $(this);
|
var $num = $(this);
|
||||||
var num = parseInt($num.data('num'));
|
var num = parseInt($num.data('num'));
|
||||||
var tail = $num.data('tail');
|
var tail = $num.data('tail');
|
||||||
|
var head = $num.data('head');
|
||||||
var animal = $num.data('animal');
|
var animal = $num.data('animal');
|
||||||
var color = $num.data('color');
|
var color = $num.data('color');
|
||||||
|
|
||||||
@@ -1011,6 +1062,10 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
if (excludedTails.length > 0 && excludedTails.indexOf(tail) !== -1) {
|
if (excludedTails.length > 0 && excludedTails.indexOf(tail) !== -1) {
|
||||||
hidden = true;
|
hidden = true;
|
||||||
}
|
}
|
||||||
|
// 首位数筛选:选中多个首位数,任一命中即屏蔽
|
||||||
|
if (excludedHeads.length > 0 && excludedHeads.indexOf(head) !== -1) {
|
||||||
|
hidden = true;
|
||||||
|
}
|
||||||
// 单双筛选:选中单或双,匹配则屏蔽
|
// 单双筛选:选中单或双,匹配则屏蔽
|
||||||
if (excludedParities.indexOf(parity) !== -1) {
|
if (excludedParities.indexOf(parity) !== -1) {
|
||||||
hidden = true;
|
hidden = true;
|
||||||
@@ -1542,12 +1597,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
' <div style="font-size:12px;color:#666;">' +
|
' <div style="font-size:12px;color:#666;">' +
|
||||||
' <b>V1版本</b>:基于转移概率分析(区域、生肖、尾号、首号、波色转移 + 冷热系数)<br>' +
|
' <b>V1版本</b>:基于转移概率分析(区域、生肖、尾号、首号、波色转移 + 冷热系数)<br>' +
|
||||||
' <b>V2版本</b>:基于统计回归分析(遗漏回归、频率回归、区域平衡、波色平衡等)+ 历史回测验证<br>' +
|
' <b>V2版本</b>:基于统计回归分析(遗漏回归、频率回归、区域平衡、波色平衡等)+ 历史回测验证<br>' +
|
||||||
' <b>V3版本(推荐)</b>:多维度综合预测,新增转移概率(马尔可夫链)、单双规律、大小规律、走势方向分析' +
|
' <b>V3版本</b>:多维度综合预测,新增转移概率(马尔可夫链)、单双规律、大小规律、走势方向分析<br>' +
|
||||||
|
' <b>V4版本(推荐)</b>:贝叶斯集成学习,6大子模型融合(EWMA频率/号码转移/遗漏CDF/形态匹配/周期检测/属性平衡)' +
|
||||||
' </div>' +
|
' </div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="form-group" style="border-bottom:1px solid #eee;padding-bottom:10px;margin-bottom:10px;">' +
|
'<div class="form-group" style="border-bottom:1px solid #eee;padding-bottom:10px;margin-bottom:10px;">' +
|
||||||
' <label style="margin-right:10px;">算法版本:</label>' +
|
' <label style="margin-right:10px;">算法版本:</label>' +
|
||||||
' <label class="radio-inline" style="margin-right:15px;"><input type="radio" name="predict-version" value="v3" checked> <b>V3</b>(多维度综合)</label>' +
|
' <label class="radio-inline" style="margin-right:15px;"><input type="radio" name="predict-version" value="v4" checked> <b>V4</b>(贝叶斯集成·推荐)</label>' +
|
||||||
|
' <label class="radio-inline" style="margin-right:15px;"><input type="radio" name="predict-version" value="v3"> <b>V3</b>(多维度综合)</label>' +
|
||||||
' <label class="radio-inline" style="margin-right:15px;"><input type="radio" name="predict-version" value="v2"> V2(统计回归)</label>' +
|
' <label class="radio-inline" style="margin-right:15px;"><input type="radio" name="predict-version" value="v2"> V2(统计回归)</label>' +
|
||||||
' <label class="radio-inline"><input type="radio" name="predict-version" value="v1"> V1(转移概率)</label>' +
|
' <label class="radio-inline"><input type="radio" name="predict-version" value="v1"> V1(转移概率)</label>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
@@ -1561,6 +1618,18 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
' <input type="number" id="predict-periods" class="form-control" value="200" min="30" max="500" style="width:120px;display:inline-block;">' +
|
' <input type="number" id="predict-periods" class="form-control" value="200" min="30" max="500" style="width:120px;display:inline-block;">' +
|
||||||
' <span style="font-size:11px;color:#999;margin-left:5px;">建议200期以上</span>' +
|
' <span style="font-size:11px;color:#999;margin-left:5px;">建议200期以上</span>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
|
// V4权重配置
|
||||||
|
'<div id="predict-v4-weights" style="border-bottom:1px solid #eee;padding-bottom:10px;margin-bottom:10px;">' +
|
||||||
|
' <label style="margin-right:10px;">V4子模型权重:</label>' +
|
||||||
|
' <div style="display:flex;flex-wrap:wrap;gap:10px;font-size:12px;">' +
|
||||||
|
' <div>EWMA频率: <input type="number" class="predict-weight-v4" data-key="freq_ewma" value="0.20" min="0" max="1" step="0.02" style="width:60px;"></div>' +
|
||||||
|
' <div>号码转移: <input type="number" class="predict-weight-v4" data-key="markov_number" value="0.22" min="0" max="1" step="0.02" style="width:60px;"></div>' +
|
||||||
|
' <div>遗漏CDF: <input type="number" class="predict-weight-v4" data-key="omit_empirical" value="0.17" min="0" max="1" step="0.02" style="width:60px;"></div>' +
|
||||||
|
' <div>形态匹配: <input type="number" class="predict-weight-v4" data-key="pattern_match" value="0.18" min="0" max="1" step="0.02" style="width:60px;"></div>' +
|
||||||
|
' <div>周期检测: <input type="number" class="predict-weight-v4" data-key="cyclical" value="0.09" min="0" max="1" step="0.02" style="width:60px;"></div>' +
|
||||||
|
' <div>属性平衡: <input type="number" class="predict-weight-v4" data-key="attr_balance" value="0.14" min="0" max="1" step="0.02" style="width:60px;"></div>' +
|
||||||
|
' </div>' +
|
||||||
|
'</div>' +
|
||||||
// V3权重配置
|
// V3权重配置
|
||||||
'<div id="predict-v3-weights" style="border-bottom:1px solid #eee;padding-bottom:10px;margin-bottom:10px;">' +
|
'<div id="predict-v3-weights" style="border-bottom:1px solid #eee;padding-bottom:10px;margin-bottom:10px;">' +
|
||||||
' <label style="margin-right:10px;">V3权重配置:</label>' +
|
' <label style="margin-right:10px;">V3权重配置:</label>' +
|
||||||
@@ -1615,10 +1684,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
// 切换版本时显示对应权重配置
|
// 切换版本时显示对应权重配置
|
||||||
$('input[name="predict-version"]', layero).on('change', function () {
|
$('input[name="predict-version"]', layero).on('change', function () {
|
||||||
var val = $(this).val();
|
var val = $(this).val();
|
||||||
|
$('#predict-v4-weights', layero).hide();
|
||||||
$('#predict-v3-weights', layero).hide();
|
$('#predict-v3-weights', layero).hide();
|
||||||
$('#predict-v2-weights', layero).hide();
|
$('#predict-v2-weights', layero).hide();
|
||||||
$('#predict-v1-weights', layero).hide();
|
$('#predict-v1-weights', layero).hide();
|
||||||
if (val === 'v3') {
|
if (val === 'v4') {
|
||||||
|
$('#predict-v4-weights', layero).show();
|
||||||
|
$('#predict-periods', layero).val(200);
|
||||||
|
} else if (val === 'v3') {
|
||||||
$('#predict-v3-weights', layero).show();
|
$('#predict-v3-weights', layero).show();
|
||||||
$('#predict-periods', layero).val(200);
|
$('#predict-periods', layero).val(200);
|
||||||
} else if (val === 'v2') {
|
} else if (val === 'v2') {
|
||||||
@@ -1650,7 +1723,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
var weights = {};
|
var weights = {};
|
||||||
|
|
||||||
// 根据版本获取权重
|
// 根据版本获取权重
|
||||||
if (version === 'v3') {
|
if (version === 'v4') {
|
||||||
|
$('.predict-weight-v4', layero).each(function () {
|
||||||
|
var key = $(this).data('key');
|
||||||
|
var val = parseFloat($(this).val()) || 0;
|
||||||
|
weights[key] = val;
|
||||||
|
});
|
||||||
|
} else if (version === 'v3') {
|
||||||
$('.predict-weight-v3', layero).each(function () {
|
$('.predict-weight-v3', layero).each(function () {
|
||||||
var key = $(this).data('key');
|
var key = $(this).data('key');
|
||||||
var val = parseFloat($(this).val()) || 0;
|
var val = parseFloat($(this).val()) || 0;
|
||||||
@@ -1672,7 +1751,9 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
|
|
||||||
// 根据版本选择URL
|
// 根据版本选择URL
|
||||||
var url = 'history/predict';
|
var url = 'history/predict';
|
||||||
if (version === 'v3') {
|
if (version === 'v4') {
|
||||||
|
url = 'history/predictV4';
|
||||||
|
} else if (version === 'v3') {
|
||||||
url = 'history/predictV3';
|
url = 'history/predictV3';
|
||||||
} else if (version === 'v2') {
|
} else if (version === 'v2') {
|
||||||
url = 'history/predictV2';
|
url = 'history/predictV2';
|
||||||
@@ -1725,7 +1806,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
var versionNames = {
|
var versionNames = {
|
||||||
'v1': 'V1(转移概率)',
|
'v1': 'V1(转移概率)',
|
||||||
'v2': 'V2(统计回归)',
|
'v2': 'V2(统计回归)',
|
||||||
'v3': 'V3(多维度综合)'
|
'v3': 'V3(多维度综合)',
|
||||||
|
'v4': 'V4(贝叶斯集成)'
|
||||||
};
|
};
|
||||||
|
|
||||||
var html = '<div style="padding:10px;">';
|
var html = '<div style="padding:10px;">';
|
||||||
@@ -1734,7 +1816,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
html += '<div style="font-size:12px;color:#666;margin-bottom:10px;">基于期号 <b>' + lastExpect + '</b>(特码 ' + lastSpecial + ')进行预测 | 算法版本: <b>' + versionNames[version] + '</b></div>';
|
html += '<div style="font-size:12px;color:#666;margin-bottom:10px;">基于期号 <b>' + lastExpect + '</b>(特码 ' + lastSpecial + ')进行预测 | 算法版本: <b>' + versionNames[version] + '</b></div>';
|
||||||
|
|
||||||
// 置信度评估展示(V2和V3版本)
|
// 置信度评估展示(V2和V3版本)
|
||||||
if (confidence && (version === 'v2' || version === 'v3')) {
|
if (confidence && (version === 'v2' || version === 'v3' || version === 'v4')) {
|
||||||
html += '<div style="background:#fff8e1;border:1px solid #ffb300;border-radius:6px;padding:12px;margin-bottom:15px;">';
|
html += '<div style="background:#fff8e1;border:1px solid #ffb300;border-radius:6px;padding:12px;margin-bottom:15px;">';
|
||||||
html += '<div style="font-size:13px;font-weight:bold;color:#ff8f00;margin-bottom:8px;"><i class="fa fa-star-half-o"></i> 预测置信度评估</div>';
|
html += '<div style="font-size:13px;font-weight:bold;color:#ff8f00;margin-bottom:8px;"><i class="fa fa-star-half-o"></i> 预测置信度评估</div>';
|
||||||
|
|
||||||
@@ -1744,19 +1826,23 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
}
|
}
|
||||||
|
|
||||||
html += '<div style="display:flex;gap:20px;align-items:center;">';
|
html += '<div style="display:flex;gap:20px;align-items:center;">';
|
||||||
html += '<div style="text-align:center;"><div style="font-size:24px;font-weight:bold;color:#ff8f00;">' + confidence.overall_confidence + '%</div><div style="font-size:12px;color:#666;">整体置信度</div></div>';
|
// 整体置信度(兼容 V3/V4 不同字段名)
|
||||||
|
var overallConf = confidence.overall_confidence || confidence.overall_score || 0;
|
||||||
|
html += '<div style="text-align:center;"><div style="font-size:24px;font-weight:bold;color:#ff8f00;">' + overallConf + '%</div><div style="font-size:12px;color:#666;">整体置信度</div></div>';
|
||||||
|
|
||||||
// 各排名置信度(使用得分集中度维度)
|
// V4 格式: confidence.items, V3 格式: confidence.confidence_scores
|
||||||
if (confidence.confidence_scores && confidence.confidence_scores.length > 0) {
|
var confItems = confidence.items || confidence.confidence_scores || [];
|
||||||
|
if (confItems.length > 0) {
|
||||||
html += '<div style="display:flex;gap:8px;">';
|
html += '<div style="display:flex;gap:8px;">';
|
||||||
for (var i = 0; i < confidence.confidence_scores.length; i++) {
|
for (var i = 0; i < confItems.length; i++) {
|
||||||
var cs = confidence.confidence_scores[i];
|
var cs = confItems[i];
|
||||||
// 阈值定义:>=70%高(绿)、50-70%中(橙)、<50%低(红)
|
var csConf = cs.confidence || cs.score || 0;
|
||||||
var confLevel = cs.confidence >= 70 ? '高' : (cs.confidence >= 50 ? '中' : '低');
|
var csRank = cs.rank || (i + 1);
|
||||||
var confColor = cs.confidence >= 70 ? '#4caf50' : (cs.confidence >= 50 ? '#ff9800' : '#f44336');
|
var confLevel = csConf >= 70 ? '高' : (csConf >= 50 ? '中' : '低');
|
||||||
|
var confColor = csConf >= 70 ? '#4caf50' : (csConf >= 50 ? '#ff9800' : '#f44336');
|
||||||
html += '<div style="text-align:center;padding:5px;background:#fff;border-radius:4px;">';
|
html += '<div style="text-align:center;padding:5px;background:#fff;border-radius:4px;">';
|
||||||
html += '<div style="font-size:14px;font-weight:bold;color:' + confColor + ';">' + cs.confidence + '%</div>';
|
html += '<div style="font-size:14px;font-weight:bold;color:' + confColor + ';">' + csConf + '%</div>';
|
||||||
html += '<div style="font-size:10px;color:#999;">#' + cs.rank + '</div>';
|
html += '<div style="font-size:10px;color:#999;">#' + csRank + '</div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
@@ -1765,7 +1851,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 回测验证结果(V2和V3版本)
|
// 回测验证结果(V2和V3版本)
|
||||||
if (backtest && (version === 'v2' || version === 'v3')) {
|
if (backtest && (version === 'v2' || version === 'v3' || version === 'v4')) {
|
||||||
html += '<div style="background:#e3f2fd;border:1px solid #2196f3;border-radius:6px;padding:12px;margin-bottom:15px;">';
|
html += '<div style="background:#e3f2fd;border:1px solid #2196f3;border-radius:6px;padding:12px;margin-bottom:15px;">';
|
||||||
html += '<div style="font-size:13px;font-weight:bold;color:#1565c0;margin-bottom:8px;"><i class="fa fa-chart-line"></i> 历史回测验证(最近' + backtest.total_tests + '期)</div>';
|
html += '<div style="font-size:13px;font-weight:bold;color:#1565c0;margin-bottom:8px;"><i class="fa fa-chart-line"></i> 历史回测验证(最近' + backtest.total_tests + '期)</div>';
|
||||||
|
|
||||||
@@ -1875,6 +1961,40 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// V4版本特有的分析信息
|
||||||
|
if (version === 'v4' && analysis) {
|
||||||
|
html += '<div style="background:#e8eaf6;border:1px solid #3f51b5;border-radius:6px;padding:10px;margin-bottom:15px;font-size:12px;">';
|
||||||
|
html += '<div style="font-weight:bold;color:#283593;margin-bottom:8px;"><i class="fa fa-cubes"></i> V4贝叶斯集成分析</div>';
|
||||||
|
html += '<div style="margin-bottom:5px;"><b>算法:</b> ' + (analysis.algorithm || 'Bayesian Ensemble') + '</div>';
|
||||||
|
html += '<div style="margin-bottom:5px;"><b>半衰期:</b> ' + (analysis.half_life || 50) + '期 | <b>历史数据:</b> ' + (analysis.history_count || 0) + '期</div>';
|
||||||
|
if (analysis.weights_adaptive) {
|
||||||
|
html += '<div style="margin-bottom:5px;color:#2e7d32;"><b>自适应权重:</b> 已启用(基于滚动回测性能调整)</div>';
|
||||||
|
}
|
||||||
|
if (analysis.pattern_match_info) {
|
||||||
|
var pmi = analysis.pattern_match_info;
|
||||||
|
html += '<div style="margin-bottom:5px;"><b>形态匹配:</b> 匹配' + pmi.matched_segments + '个历史片段 | 最佳相似度 ' + (pmi.best_similarity * 100).toFixed(1) + '%</div>';
|
||||||
|
}
|
||||||
|
if (analysis.cyclical_detected) {
|
||||||
|
var cyc = analysis.cyclical_detected;
|
||||||
|
html += '<div style="margin-bottom:5px;"><b>周期检测:</b> ' + (cyc.has_cyclical ? '发现' + cyc.significant_count + '个号码有显著周期性' : '无明显周期信号') + '</div>';
|
||||||
|
}
|
||||||
|
// 显示权重分布
|
||||||
|
if (analysis.weights) {
|
||||||
|
html += '<div style="margin-top:8px;"><b>子模型权重分布:</b></div>';
|
||||||
|
html += '<div style="display:flex;flex-wrap:wrap;gap:5px;margin-top:4px;">';
|
||||||
|
var wNames = {
|
||||||
|
'freq_ewma': 'EWMA频率', 'markov_number': '号码转移', 'omit_empirical': '遗漏CDF',
|
||||||
|
'pattern_match': '形态匹配', 'cyclical': '周期检测', 'attr_balance': '属性平衡'
|
||||||
|
};
|
||||||
|
for (var wk in analysis.weights) {
|
||||||
|
var wv = (analysis.weights[wk] * 100).toFixed(1);
|
||||||
|
html += '<span style="background:#e0e0e0;padding:2px 6px;border-radius:3px;font-size:11px;">' + (wNames[wk] || wk) + ': <b>' + wv + '%</b></span>';
|
||||||
|
}
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
// 遗漏统计信息(V2和V3版本)
|
// 遗漏统计信息(V2和V3版本)
|
||||||
if (analysis.omit_stats && (version === 'v2' || version === 'v3')) {
|
if (analysis.omit_stats && (version === 'v2' || version === 'v3')) {
|
||||||
html += '<div style="background:#fce4ec;border:1px solid #e91e63;border-radius:6px;padding:10px;margin-bottom:15px;font-size:12px;">';
|
html += '<div style="background:#fce4ec;border:1px solid #e91e63;border-radius:6px;padding:10px;margin-bottom:15px;font-size:12px;">';
|
||||||
@@ -1923,7 +2043,14 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
// 根据版本显示不同的详情信息
|
// 根据版本显示不同的详情信息
|
||||||
var detailInfo = '';
|
var detailInfo = '';
|
||||||
if (p.detail) {
|
if (p.detail) {
|
||||||
if (version === 'v3') {
|
if (version === 'v4') {
|
||||||
|
// V4版本显示子模型概率和属性
|
||||||
|
var omitCount = p.detail.omit_count || 0;
|
||||||
|
detailInfo = '<div style="font-size:9px;color:#999;line-height:1.3;">';
|
||||||
|
detailInfo += '遗漏:' + omitCount + '期 | ';
|
||||||
|
detailInfo += (p.detail.is_odd ? '单' : '双') + '/' + (p.detail.is_big ? '大' : '小');
|
||||||
|
detailInfo += '</div>';
|
||||||
|
} else if (version === 'v3') {
|
||||||
// V3版本显示更多维度信息
|
// V3版本显示更多维度信息
|
||||||
var omitInfo = p.detail.omit || 0;
|
var omitInfo = p.detail.omit || 0;
|
||||||
var transScore = p.detail.trans_score || 0;
|
var transScore = p.detail.trans_score || 0;
|
||||||
@@ -1947,14 +2074,18 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
html += '<div style="font-size:10px;color:#666;line-height:1.2;margin-top:2px;">' + animal + '</div>';
|
html += '<div style="font-size:10px;color:#666;line-height:1.2;margin-top:2px;">' + animal + '</div>';
|
||||||
html += '<div style="font-size:11px;color:#2e7d32;font-weight:bold;">得分:' + p.score + '</div>';
|
html += '<div style="font-size:11px;color:#2e7d32;font-weight:bold;">得分:' + p.score + '</div>';
|
||||||
|
|
||||||
// 显示置信度(V3版本)
|
// 显示置信度(V3和V4版本)
|
||||||
if (version === 'v3' && confidence && confidence.confidence_scores) {
|
if ((version === 'v3' || version === 'v4') && confidence) {
|
||||||
var csForNum = confidence.confidence_scores.find(function(c) { return c.num === p.num; });
|
var confItemsV4 = confidence.confidence_scores || confidence.items || [];
|
||||||
|
var csForNum = null;
|
||||||
|
for (var ci = 0; ci < confItemsV4.length; ci++) {
|
||||||
|
if (confItemsV4[ci].num === p.num) { csForNum = confItemsV4[ci]; break; }
|
||||||
|
}
|
||||||
if (csForNum) {
|
if (csForNum) {
|
||||||
// 阈值定义:>=70%高(绿)、50-70%中(橙)、<50%低(红)
|
var csValue = csForNum.confidence || csForNum.score || 0;
|
||||||
var confLevel = csForNum.confidence >= 70 ? '高' : (csForNum.confidence >= 50 ? '中' : '低');
|
var confLevel = csValue >= 70 ? '高' : (csValue >= 50 ? '中' : '低');
|
||||||
var confColor = csForNum.confidence >= 70 ? '#4caf50' : (csForNum.confidence >= 50 ? '#ff9800' : '#f44336');
|
var confColor = csValue >= 70 ? '#4caf50' : (csValue >= 50 ? '#ff9800' : '#f44336');
|
||||||
html += '<div style="font-size:10px;"><span style="color:' + confColor + ';font-weight:bold;">置信度:' + confLevel + '</span> <span style="color:#666;">(' + csForNum.confidence + '%)</span></div>';
|
html += '<div style="font-size:10px;"><span style="color:' + confColor + ';font-weight:bold;">置信度:' + confLevel + '</span> <span style="color:#666;">(' + csValue + '%)</span></div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2163,6 +2294,91 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||||||
}
|
}
|
||||||
|
|
||||||
$('#nr-result', layero).html(html);
|
$('#nr-result', layero).html(html);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 尾首概率弹窗
|
||||||
|
*/
|
||||||
|
showTailHeadProbabilityDialog: function () {
|
||||||
|
var content = '<div id="tailheadprob-content" style="padding:20px 30px;">';
|
||||||
|
content += '<div style="text-align:center;margin-bottom:20px;">';
|
||||||
|
content += '<label style="margin-right:10px;">统计期数:</label>';
|
||||||
|
content += '<select id="tailheadprob-periods" style="width:100px;padding:5px 10px;">';
|
||||||
|
content += '<option value="30">近30期</option>';
|
||||||
|
content += '<option value="50">近50期</option>';
|
||||||
|
content += '<option value="100" selected>近100期</option>';
|
||||||
|
content += '<option value="200">近200期</option>';
|
||||||
|
content += '</select>';
|
||||||
|
content += ' <button class="btn btn-primary btn-sm" id="btn-tailheadprob-query" style="margin-left:10px;"><i class="fa fa-search"></i> 查询</button>';
|
||||||
|
content += '</div>';
|
||||||
|
content += '<div id="tailheadprob-result"></div>';
|
||||||
|
content += '</div>';
|
||||||
|
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: '尾首概率分析',
|
||||||
|
area: ['700px', '650px'],
|
||||||
|
content: content,
|
||||||
|
success: function (layero) {
|
||||||
|
$('#btn-tailheadprob-query', layero).on('click', function () {
|
||||||
|
var periods = $('#tailheadprob-periods').val();
|
||||||
|
$.ajax({
|
||||||
|
url: 'history/tailHeadProb',
|
||||||
|
type: 'GET',
|
||||||
|
data: { periods: periods },
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret.code == 1) {
|
||||||
|
var d = ret.data;
|
||||||
|
var html = '<div style="margin-top:15px;">';
|
||||||
|
html += '<div style="padding:15px;background:#f0f9ff;border-radius:8px;margin-bottom:12px;">';
|
||||||
|
html += '<div style="font-size:14px;font-weight:bold;color:#1565c0;margin-bottom:10px;"><i class="fa fa-bar-chart"></i> 概率统计</div>';
|
||||||
|
html += '<table class="table table-bordered" style="margin-bottom:0;">';
|
||||||
|
html += '<tr><th style="width:50%;">对比项</th><th>相同概率</th></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 += '</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>';
|
||||||
|
$('#tailheadprob-result').html(html);
|
||||||
|
} else {
|
||||||
|
Toastr.error(ret.msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
Toastr.error('请求失败,请重试');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始加载
|
||||||
|
$('#btn-tailheadprob-query', layero).trigger('click');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user