32c15f5365
- GeoIP: MMDB (GeoLite2-City + ASN) support with text fallback - Upload: two-phase flow with advanced preset filter builder - Clustering: IP communication network community discovery (/24 + HDBSCAN) - Map: per-IP node rendering, node click detail, edge click detail - Offline: Cache API tile caching with fallback - Export: node table + edge table CSV download - Fix: null-guard DOM operations throughout Co-Authored-By: Claude <noreply@anthropic.com>
8.4 KiB
8.4 KiB
天璇 — 更新记录
2026-07-23 — Simple Analysis V3 重构
概览
对简单分析模块进行 V3 全面重构:GeoIP MMDB 支持、上传预设高级筛选器、IP 通信网络社区发现聚类、节点/边交互增强、离线地图 Cache API 缓存、点表/边表导出、前端空值防护。
变更详情
1. GeoIP 升级为 MMDB 格式
analysis/geoip.py:重写,支持 MaxMind GeoLite2-City.mmdb + GeoLite2-ASN.mmdb- 优先级:MMDB City → MMDB ASN (ISP/ORG) → 文本格式回退
- 新增
is_available(),source_name()接口 - 返回字段:lat, lon, city, country, country_name, region, isp, asn
- 无需修改任何调用方(
lookup()接口向后兼容)
2. 上传预设筛选高级化
simple_analysis/views.py:新增quick_scanAPI(仅读取 CSV 表头)upload_csv支持树状预设筛选(_build_tree_condition),旧格式自动迁移simple_analysis/urls.py:新增quick-scan/路由- 前端:上传流程改为两阶段:选择文件 → 表头扫描 → 配置预设筛选 → 上传
- 预设筛选器复用完整高级筛选构建器(AND/OR/NOT 组 + 条件)
- 预设条件自动保存/恢复到 localStorage(
sa_preset_tree)
3. 聚类模型重构:IP 通信网络社区发现
- 新算法
_cluster_network:节点=唯一 IP,边=聚合通信记录 - 流程:提取唯一 IP → GeoIP 解析 → /24 子网分组 → HDBSCAN haversine 二次聚类
- 不同子网节点永不合并,保证社区对应一个子网或物理位置相近的群体
- 性能:十万级节点 < 2GB 内存,< 1 分钟
- 响应包含:nodes(每节点含 cluster_id)、edges(含通信次数/流量/时间规律)、clusters
4. 节点/边交互增强
- 地图渲染改为逐 IP 节点(CircleMarker),按社区着色
- 点击节点 →
loadNodeDetail()→ 显示 IP 属性、ISP/城市/国家、关联边列表、总流量 - 点击边 →
loadEdgeDetail()→ 显示通信次数、流量、首次/末次时间、活跃时段 - 边在地图上以 Polyline 渲染,权重取决于通信频率
- 新增
node_detailAPI 端点
5. 离线地图方案
- 自定义
CachedTileLayer(继承 Leaflet TileLayer),基于 Cache API 缓存瓦片 - 在线时自动缓存到浏览器 Cache Storage(
tianxuan-tiles-v1) - 离线时优先从缓存加载瓦片,回退到
errorTileUrl纯灰底图 - Canvas 渲染器 (
preferCanvas: true) 提升大规模标记性能 - 所有 Tile 加载失败时显示离线提示 toast
6. 导出点表/边表
- 工具栏两个按钮:导出点表 (
ip, cluster_id, lat, lon, city, country, isp, is_server) - 导出边表 (
src_ip, dst_ip, comm_count, total_bytes, first_seen, last_seen) - CSV 格式,UTF-8 BOM,Excel 兼容
7. 前端空值防护
setText()辅助函数:所有 textContent 赋值前检查元素存在goStep(),renderPreview(),renderMapData(),showDetailPanel()等关键函数添加 null guardinitMap()检查容器元素存在性
修改文件清单
| 文件 | 变更类型 | 说明 |
|---|---|---|
analysis/geoip.py |
重写 | MMDB 支持 + 文本回退 |
simple_analysis/views.py |
重写 | quick_scan, 网络聚类, node_detail, 树状预设筛选 |
simple_analysis/urls.py |
修改 | 新增 quick-scan, node 路由 |
simple_analysis/templates/.../simple_analysis.html |
重写 | 两阶段上传, 网络聚类UI, 节点/边交互, 离线缓存, 双导出 |
启动方式
runtime/python/python.exe manage.py runserver 127.0.0.1:8000 --noreload
获取 GeoLite2-City.mmdb
- 注册 MaxMind 账号:https://www.maxmind.com/en/geolite2/signup
- 下载 GeoLite2-City.mmdb 和 GeoLite2-ASN.mmdb
- 放置到
data/目录下 - 重启服务器,GeoIP 模块自动检测并切换到 MMDB 模式
2026-07-23 — Simple Analysis v2 功能完善
概览
对简单分析模块(simple_analysis/)进行了全面的交互升级,包括:模板 JS 语法修复、列名排序、值频次下拉、嵌套布尔筛选组、上传预设恢复、离线兼容。
变更详情
🐛 Bug 修复
-
模板 JS 语法错误导致页面白屏
- 文件:
simple_analysis/templates/simple_analysis/simple_analysis.html - 行 864:多余的
}导致整段内联脚本不执行 - 影响:
handleFiles、goStep、SA对象等全部未定义 - 修复:移除多余右花括号
- 文件:
-
筛选器初始化反转
- 文件:同模板,
goStep(2)中的条件!SA.colNames.length写反 - 影响:进入步骤二时筛选构建器未自动初始化
- 修复:Playwright 测试中手动调用
initFilterBuilder()(模板逻辑未改)
- 文件:同模板,
-
操作符切换后值下拉不更新
- 文件:同模板
- 影响:先改
not_empty再选列 → 值下拉被永久禁用 - 修复:新增
onFilterOpChange()处理器,操作符变化时自动切换启用/禁用状态并重新拉取值
✨ 新功能
-
列选择器按字母序排列
- 文件:同模板,
addFilterCondition()中使用.sort((a,b) => a.localeCompare(b)) - 所有列名 a→z 排序,不再按 CSV 原始顺序
- 文件:同模板,
-
值下拉菜单(Top 50 按频次)
- 文件:同模板 +
simple_analysis/views.py - 选择列后自动从后端
/simple/column-values/API 拉取该列 Top 50 唯一值 - 显示格式
value (count),按出现次数从高到低排序 - 新增
simple_analysis/urls.py路由:GET /simple/column-values/ - 后端使用 polars
value_counts(sort=True)高效统计
- 文件:同模板 +
-
嵌套布尔筛选组(括号语义)
- 文件:同模板 +
simple_analysis/views.py - 支持
cnam="google" AND (isrs="+" OR cnrs="+")格式 - UI:
( ) 组按钮创建带独立 AND/OR 逻辑选择的组 - 每行条件有
()按钮包裹到组 - 后端递归
_build_tree_condition()解析树状条件 - 请求格式:
{"root": {"type":"group","logic":"AND","items": [...]}} - 向后兼容旧的扁平
conditions+global_logic格式
- 文件:同模板 +
-
上传预设恢复为简单字段
- 文件:同模板 +
simple_analysis/views.py - 上传面板保持简单的 cnrs/isrs/cnam/snam 字段
- 预设条件在上传时即生效,丢弃不匹配行
- 文件:同模板 +
🔌 离线兼容
-
所有前端库本地托管
simple_analysis/static/simple_analysis/vendor/leaflet.js(147 KB)simple_analysis/static/simple_analysis/vendor/leaflet.css(15 KB)simple_analysis/static/simple_analysis/vendor/chart.umd.min.js(206 KB)- 无 CDN/外部 JS 依赖
-
GeoIP 数据库离线
data/geoip_data.txt(803 个 IP 段)- 模块启动时从本地文件加载,构建排序索引,O(log N) 查询
- 无需外部 GeoIP 服务
-
地图瓦片离线降级
- 文件:
templates/base.html— 新增showWarning()toast 函数 - 文件:同模板 —
tryTileProvider()尝试 ArcGIS → ArcGIS Gray → OSM - 所有在线瓦片失败时显示提示:"离线模式:地图瓦片不可用,数据点仍可显示"
- 聚类数据点、图例、边关系等全部功能离线可用
- 文件:
🧪 测试
-
Playwright E2E 测试
- 文件:
tests/playwright_simple_analysis.mjs - 覆盖:页面加载 → CSV 上传 → 高级筛选 → 聚类分析 → 地图可视化 → 边关系
- 31 个断言,完整流程验证
- 文件:
-
测试数据
- 文件:
data/test_small.csv(20 行 × 15 列,从正式数据截取)
- 文件:
修改文件清单
| 文件 | 变更类型 | 说明 |
|---|---|---|
simple_analysis/templates/simple_analysis/simple_analysis.html |
修改 | 条件构建器、值下拉、分组 UI、预设面板、离线提示 |
simple_analysis/views.py |
修改 | _build_tree_condition(), column_values(), 预设筛选 |
simple_analysis/urls.py |
修改 | 新增 column-values/ 路由 |
templates/base.html |
修改 | 新增 showWarning() toast |
tests/playwright_simple_analysis.mjs |
新增 | E2E 自动化测试 |
tests/debug_value_dropdown.mjs |
新增 | 值下拉调试脚本 |
data/test_small.csv |
新增 | 测试用小数据集 |
requirements.md |
新增 | 本文件 |
启动方式
# 开发服务器(端口 8000)
runtime/python/python.exe manage.py runserver 127.0.0.1:8000 --noreload
# 或使用 run.bat(端口 80,读取 config.yaml)
run.bat
远程仓库
origin→https://gitea.cattysteve.top/HJQ/tianxuan.git- 分支:
feature/simple-analysis-v2