Skip to content

Latest commit

 

History

History
101 lines (92 loc) · 8.69 KB

File metadata and controls

101 lines (92 loc) · 8.69 KB

程序结构 / Architecture

NekoCardReader 是一个单机 PyQt6 桌面应用,约 45 个 Python 模块,按「读卡核心 → 解码字典 → 数据档案 → 分析/地图 → UI」分层。核心设计约束是:读卡核心冻结且与上层完全解耦—— 分析、地图、UI 只消费已解析的 Transaction,永远不碰卡片 I/O。

                          ┌─────────────────────────────────────────────┐
                          │                UI 层 (PyQt6)                 │
   main.py ───────────────┤  主窗口 · 刷卡页 · 统计图 · 设置 · 系统托盘    │
                          │  archive_widget.py  档案 LAB (分析/修复/地图) │
                          │  web_map.py         Leaflet 地图 HTML 生成    │
                          │  diagnostics.py     安全诊断中心 (不开读卡器)  │
                          └───────────────┬─────────────────────────────┘
                                          │ 只传递已解析 Transaction
         ┌────────────────────────────────┼────────────────────────────────┐
         ▼                                ▼                                ▼
┌──────────────────┐         ┌──────────────────────┐        ┌──────────────────────┐
│  数据档案层        │         │   分析 / 导出层        │        │   地图 / 几何层        │
│ history_store.py │◀───────▶│ trip_analytics.py    │        │ map_pipeline.py (线程)│
│  SQLite v3 档案   │         │  纯分析,零副作用      │        │ rail_route.py  OSM 路由│
│  迁移·备份·撤销   │         │ yearbook_export.py   │        │ rail_geom.py   铁轨几何│
│ data_portability │         │  年鉴 HTML           │        │ map_tiles / offline  │
│  DPAPI 加密备份   │         │ plugin_registry.py   │        │  瓦片 · 离线包缓存    │
└──────────────────┘         │  后处理插件沙箱       │        └──────────────────────┘
                             └──────────────────────┘
         ▲ 解析后的 Transaction / CardData
         │
┌────────┴───────────────────────────────────────────────────────────────────┐
│                        🧊 读卡核心 (冻结, SHA-256 校验)                        │
│  card_reader.py     统一调度; 进程锁串行访问同一台读卡器                       │
│  ┌── 日本 FeliCa ────────────────────┐   ┌── 中国交通联合 (T-Union) ───────┐  │
│  │ felica64_reader.py 64位 felica.dll │   │ pboc_reader.py  PC/SC + EMV /   │  │
│  │ felica_suica.py    Suica 块解码    │   │                 JT/T 978        │  │
│  │ felica_reader.py   32位 SFCAccLib  │   │ cn_read.py      子进程读卡入口   │  │
│  │                    (PowerShell 桥) │   │                                 │  │
│  └────────────────────────────────────┘   └─────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────────────┘
         ▲ 站码 / 坐标 / 线路字典
┌────────┴───────────────────────────────────────────────────────────────────┐
│                          解码字典 / 铁路网络层                                 │
│  中国: cn_data(城市码) cn_lines(线路站名) cn_coords(坐标)                      │
│        cn_network(地铁图+换乘) cn_trips(进出站→行程段)                         │
│  日本: station_data / station_db(站点码)  jp_network(全国铁路网络)             │
└──────────────────────────────────────────────────────────────────────────────┘

  支撑: paths(打包路径) · settings(配置) · fx(汇率换算) · 诊断脚本 detect_read / diag_reader

分层职责

模块 职责
UI (PyQt6) main.py 主窗口、刷卡/统计/设置标签页、连续采集、系统托盘
archive_widget.py 档案 LAB:数据质量修复、路线频次、通勤候选、三模式地图
web_map.py 生成内嵌 Leaflet 地图 HTML(高德/OSM 双底图,终端风格 UI)
diagnostics.py 不打开读卡器的安全诊断中心
🧊 读卡核心(冻结) card_reader.py 统一后端调度,进程锁串行访问单一读卡器
felica64_reader.py 64 位 Sony felica.dll 直调,取 IDm / 余额 / 历史
felica_suica.py Suica/PASMO 16 字节历史块解码
felica_reader.py 旧 32 位 SFCAccLib(PowerShell 桥接)后备路径
pboc_reader.py 中国交通联合卡:PC/SC + EMV / 交通部 JT/T 978
cn_read.py 中国卡读取的独立子进程入口
解码字典 cn_data cn_lines cn_coords 城市码 / 线路站名 / 站点坐标
cn_network cn_trips 地铁换乘图 / 进出站配对成行程段
station_db station_data jp_network 日本站点码与全国铁路网络
数据档案 history_store.py SQLite v3 档案、v2→v3 迁移、每日备份、撤销读取
data_portability.py SQLite/JSON 导入导出、DPAPI 本地加密备份
分析 / 导出 trip_analytics.py 纯分析层(频次/通勤/日历),零副作用、可离线单测
yearbook_export.py 无外部依赖的交通年鉴 HTML
plugin_registry.py 后处理插件沙箱,异常隔离,不进入读卡核心
地图 / 几何 map_pipeline.py 地图前处理,运行在可取消的 Qt 后台线程
rail_route.py rail_geom.py OSM 最短路 + 真实铁轨几何,持久化缓存
map_tiles.py offline_maps.py 瓦片管理 / 离线缓存包
支撑 paths settings fx 打包路径、配置持久化、多币种汇率换算
detect_read diag_reader 独立读卡器检测 / 占用诊断脚本

关键设计决策

  • 读卡核心冻结 + 完整性校验felica64_reader / felica_suica / pboc_reader / card_reader / felica_reader 五个文件锁定在 v0.2 的 SHA-256(清单 .reader-core-v0.2.sha256)。任何新功能 都在上层实现,杜绝对已验证读卡路径的回归。
  • 读卡与分析彻底解耦trip_analytics / map_pipeline 的输入只有已解析的 Transaction, 因此可离线单元测试,也可安全放入 Qt 后台线程而不阻塞 UI。
  • 单一读卡器的并发安全:两套后端(32/64 位、中/日)通过 card_reader 的进程锁串行访问, 避免同时抢占 PaSoRi。
  • 响应式地图:OSM 路由与几何在后台线程计算,切卡时自动取消旧任务;相同区间命中持久化缓存 不重复请求 Overpass。
  • 本地优先 / 隐私:无服务器,历史只存本机 SQLite;联网仅用于下载可缓存的线路/瓦片/汇率。
  • 可扩展:后处理插件只接触解析结果,异常被隔离并汇报到诊断页,不会中断读卡。

数据流(一次刷卡)

读卡器 → card_reader (选后端, 加锁)
        → felica64_reader / pboc_reader  (原生读取)
        → felica_suica / cn_trips        (解码为 Transaction)
        → history_store                  (合并去重, 写 SQLite, 备份)
        → trip_analytics / map_pipeline  (分析 + 地图, 后台线程)
        → main.py / archive_widget / web_map  (渲染)