DriftLedger/plugins/ppocr
fengmengqi 6767dd538a feat: 领域/组件/服务三层目录重构 + 微信无障碍绕过方案 + 新 UI 组件体系 + 账本增删改增强
### 架构重构:三层分层目录化
  - domain 拆分为 8 个子目录(core/pipeline/rules/finance/stats/taxonomy/transaction/platform)
  - components 拆分为 6 个子目录(form/ui/layout/account/category/stats/transaction)
  - services 拆分为 5 个子目录(automation/data/ocr/security),accessibilityParser 从 automationPipeline 提取
  - 新增 ruleConfig.ts — 规则配置唯一数据源(关键词/方向/OCR 模式),与业务逻辑解耦

  ### 微信账单抓取:节点混淆绕过(核心突破)
  - BillingAccessibilityService 重命名为 SelectToSpeakService,完整伪装为系统服务
  - 同时伪装包名+类名为 com.google.android.accessibility.selecttospeak,规避微信 8.0.52+ 白名单校验
  - Config Plugin 重写:8 个 kt 文件整体复制+package 正则替换+Manifest/import 联动
  - 支付宝/微信无障碍文本解析器全面增强(方向推断/账单分类提取/付款方式提取/容错)
  - 补充文档 accessibility-wechat-guide.md(伪装原理、踩坑全记录)

  ### 新 UI 组件体系
  - Toast:全局轻量 toast(Context Provider + 入场动画 + 操作按钮 + 自动消失)
  - ErrorBoundary:React class 错误边界(降级 UI + 重试)
  - EmptyState / ConfirmDialog / SegmentedControl / Skeleton / TimePicker
  - BottomSheet 重写:SafeAreaProvider 修复、手势下滑关闭、键盘响应式避让
  - FormModal 重构:拆出 FormFields 子组件(TextField/SelectField/DropdownField)
  - 新增 PeriodSwitcher、RangeStatsCard 独立组件

  ### 新 Hooks & 工具
  - useBottomInset — 统一底部安全区留白
  - useKeyboardAvoiding — 键盘高度响应式 hook(替代 translateY 方案)
  - sanitize.ts — 日志脱敏工具提取

  ### 账本增删改增强
  - 写锁增加代际计数器(lockGeneration),reset 后旧链 pending 任务自动跳过 set
  - 新增 restoreTransaction — 撤销删除(重新追加 raw 文本到 mobile.bean)
  - 删除交易时清除去重缓存(buildTxKeyFromRaw 重建去重键),支持「删了重记」
  - editTransaction/deleteTransaction 改用 dr-id 精确定位交易块(避免同名交易定位错误)
  - appendTransactionsBatch 改从存储直接读取,避免 zustand state 不一致

  ### OCR 原生模块增强
  - 异步 initEngine 增加 CountDownLatch 等待(最多 15s),解决竞态导致的「引擎未就绪」
  - setModelDir 增加去重判断 + file:// 前缀剥离,避免冗余 reload
  - 推理链路增加分阶段耗时日志(det 推理/det 后处理/rec 识别)
  - 图片缩放策略重命名(scaleDownForOcr → capLongEdge)

  ### OCR 模型按需下载
  - 移除了启动时自动下载 ~30MB OCR 模型的逻辑
  - 改为首次使用 OCR 时才触发下载

  ### 设置页重设计
  - ScrollView → SectionList 分组卡片布局(iOS 风格分组圆角行+右侧箭头)
  - 移除 Card 组件包装,直接使用独立分组头+底部关于卡片

  ### 首页优化
  - ScrollView → FlatList(ListHeaderComponent 承载净资产卡片+待办条)
  - 日期/金额格式化增加 locale 感知(zh/en)

  ### 通知管道增强
  - NotificationChannel MD5 去重改为批量淘汰(80% 阈值),替代逐个删除
  - 增加 debug 日志输出(过滤原因/包名)

  ### ESLint
  - 新增 eslint.config.mjs(typescript-eslint + react-hooks + react-native 规则集)
  - package.json 新增 lint/lint:fix 脚本,引入 5 个 devDependencies

  ### 文档
  - accessibility-wechat-guide.md — 微信无障碍伪装完整方案
  - modal-keyboard-guide.md — 弹窗键盘避让方案
  - ocr-pipeline-guide.md — OCR 三层层级管线
  - OCR及文本模型测试 / 账单元识别及账户分类设计 / 账户分类模型测试
2026-07-28 20:57:37 +08:00
..
android feat: 领域/组件/服务三层目录重构 + 微信无障碍绕过方案 + 新 UI 组件体系 + 账本增删改增强 2026-07-28 20:57:37 +08:00
app.plugin.js feat: OCR 模型按需下载 + 三层独立开关 + 日志持久化 + 原生浮层主题同步 + 文档重构 2026-07-23 19:03:38 +08:00
package.json feat: 品牌重命名为浮记(DriftLedger),全面升级精度安全与架构 2026-07-21 15:16:44 +08:00
README.md feat: OCR 模型按需下载 + 三层独立开关 + 日志持久化 + 原生浮层主题同步 + 文档重构 2026-07-23 19:03:38 +08:00

PP-OCR (ONNX Runtime) Config Plugin

本插件在 expo prebuild 时注入 PP-OCR 本地 OCR 原生模块plan.md 决策 4

引擎选用 ONNX Runtime跨平台、微软官方、Windows 友好),替代原 NCNN 方案。

当前版本

PP-OCRv6 smalldet 2.5M 参数 + rec 5.3M 参数,精度显著优于 v5 mobile

指标 PP-OCRv5 mobile PP-OCRv6 small
det Hmean 75.2% 84.1%
rec W-Avg 73.7% 81.3%
rec ONNX 大小 ~17 MB ~21 MB

文件结构

plugins/ppocr/
├── app.plugin.js              # Config Plugin 入口prebuild 时执行)
├── android/                   # Kotlin 原生实现prebuild 时复制进原生工程)
│   ├── OcrModule.kt           # React Native BridgeONNX Runtime 推理 + det/rec 前后处理
│   └── OcrPackage.kt          # RN Package 注册(注入到 MainApplication.getPackages
└── assets/                    # ONNX 模型 + 字典(需自行下载放置)
    ├── ppocrv6_det.onnx       # 文本检测模型PP-OCRv6 small
    ├── ppocrv6_rec.onnx       # 文本识别模型PP-OCRv6 small多语言
    └── ppocrv6_dict.txt       # PP-OCRv6 多语言字典CTC 解码用)

模型获取(一键下载)

PP-OCRv6 官方 ONNX 模型来自 PaddlePaddle/PP-OCRv6 系列

# 在项目根目录执行
mkdir -p plugins/ppocr/assets
cd plugins/ppocr/assets

# det 模型PP-OCRv6 small
curl -L -o ppocrv6_det.onnx \
  https://huggingface.co/PaddlePaddle/PP-OCRv6_small_det_onnx/resolve/main/inference.onnx

# rec 模型PP-OCRv6 small
curl -L -o ppocrv6_rec.onnx \
  https://huggingface.co/PaddlePaddle/PP-OCRv6_small_rec_onnx/resolve/main/inference.onnx

# PP-OCRv6 多语言字典(必须与上面的 rec 模型配套)
curl -L -o ppocrv6_dict.txt \
  https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/main/ppocr/utils/dict/ppocrv6_dict.txt

⚠️ 字典必须与 rec 模型配套v6 字典字符集与 v5 完全不同,混用会导致 CTC 解码乱码。 若之前使用过 v5 模型,务必删除旧文件(ppocrv5_det.onnxppocrv5_rec.onnxppocrv5_dict.txt)。

性能配置(参考 AutoAccounting OcrProcessor.kt

优化项 配置
引擎 ONNX Runtime Android
执行器 CPU兼容性最稳部分设备 GPU 会崩溃)
线程 intraOp=2 / interOp=2
det 图像 最大边 960px短边压缩 720px
rec 图像 固定高度 48px
ABI arm64-v8a主流设备

使用

app.json 注册插件:

{
  "plugins": ["./plugins/ppocr"]
}

JS 层通过 src/services/ocrBridge.tsNativeOcrBridge 调用,桥接到 NativeModules.PpOcr

  • recognizeText(base64) → 返回纯文本(多行用 \n 连接)
  • recognizeTextBlocks(base64) → 返回带坐标的文本块数组 [{text, x, y, width, height, confidence}]
  • isReady() → 模型是否加载完成

当前状态

  • app.plugin.js Config Plugin 逻辑prebuild 注入 Kotlin + 模型 + gradle 依赖 + MainApplication 注册)
  • android/OcrModule.kt ONNX Runtime 推理det DB 后处理 + rec CTC 解码)
  • android/OcrPackage.kt RN Package 注册
  • assets/:需自行下载放置(见上「模型获取」),版权/体积原因不入仓库

真机构建步骤:放置模型文件 → npx expo prebuild --platform androidConfig Plugin 会把 Kotlin 源码与 assets/ 下的模型/字典复制进 android/)→ npx expo run:android

若之前已 prebuild 过且更换过字典/模型文件,务必重新执行 npx expo prebuild --clean,否则 android/app/src/main/assets/ 下可能残留旧模型/字典。

v5 → v6 迁移说明

若从 PP-OCRv5 升级,需完成以下步骤:

  1. 下载新模型:按上述「模型获取」章节下载 v6 模型和字典
  2. 删除旧文件:移除 ppocrv5_det.onnxppocrv5_rec.onnxppocrv5_dict.txt
  3. 代码已自动适配OcrModule.kt 中的常量已更新为 v6 文件名
  4. 重新 prebuildnpx expo prebuild --clean 确保旧资产被清理
  5. 验证 tensor 名称v6 ONNX 模型的输入 tensor 名可能与 v5 不同,若推理报错需用 Netron 检查并调整 OcrModule.kt 中的 detInputs/recInputs map key