Initial commit: macOS receipt workspace
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# 贴票台 · macOS 原生版
|
||||
|
||||
SwiftUI 原生报账材料工作台。无需浏览器、Java、Spring Boot、HTTP 服务或用户单独安装 Python。RapidOCR 模型、解释器及 Office 导出依赖随应用内的处理引擎打包,扫描和导出仅通过本地子进程的标准输入/输出交换数据,不监听网络端口。
|
||||
|
||||
## 开发环境
|
||||
|
||||
- Xcode 26.3,macOS 15.7 或更高版本。
|
||||
- 当前构建为 Apple Silicon(arm64);Intel Mac 需要另行构建对应架构的处理引擎。
|
||||
- 本机 Xcode:`/Users/yuxiaoting/Downloads/Xcode.app`。无需修改系统默认开发工具目录。
|
||||
- 原工程 `../fapiao` 不会被修改,也不是运行依赖。
|
||||
|
||||
## 在 Xcode 中运行
|
||||
|
||||
打开 `reimburse.xcodeproj`,选择 `reimburse` scheme 和 My Mac,运行即可。构建阶段会将 `native-engine/dist/receipt-engine-helper.app` 放进应用的 `Contents/Helpers`,并为辅助进程添加沙盒继承权限。
|
||||
|
||||
当前开发目录已经准备了本地依赖和引擎。重新下载源码、切换架构或修改 Python 代码后,需先重建引擎:
|
||||
|
||||
```sh
|
||||
python3.12 -m venv .build-tools
|
||||
.build-tools/bin/python -m pip install -r native-engine/requirements.txt
|
||||
bash native-engine/build-engine.sh
|
||||
```
|
||||
|
||||
依赖安装只发生在开发打包时,最终用户不需要上述工具。`dist`、依赖环境及构建产物不提交到版本控制;发布流程需先生成引擎,再构建应用。
|
||||
|
||||
```sh
|
||||
DEVELOPER_DIR=/Users/yuxiaoting/Downloads/Xcode.app/Contents/Developer \
|
||||
xcodebuild -project reimburse.xcodeproj -scheme reimburse \
|
||||
-configuration Debug -destination 'platform=macOS' \
|
||||
-derivedDataPath .derived-data build
|
||||
```
|
||||
|
||||
## 使用流程
|
||||
|
||||
1. 选择包含 `发票`、`付款截图`、`实物照片` 子目录的材料根目录。
|
||||
2. 材料复制到应用自己的本地工作区,原始文件不会修改。再次导入会替换当前工作区。
|
||||
3. 本地 OCR 提取信息,按旧项目规则自动匹配并分类。扫描显示真实处理进度。
|
||||
4. 在“人工配对”两侧多选材料,选择分类后确认;识别失败的材料仍可人工配对。
|
||||
5. “已核对”中可查看依据、改分类、撤销及导出。自动核对结果不代表已人工复核。
|
||||
6. 工作区自动持久化到应用沙盒内的 Application Support/ReceiptDesk;清空只删除工作区副本,不删除原始材料。
|
||||
|
||||
## 功能对应
|
||||
|
||||
| 原项目 | 原生实现 |
|
||||
|---|---|
|
||||
| App.vue、三个页面 | ContentView、ScanPage、PairPage、MatchedPage |
|
||||
| WorkspaceState / FileItem / MatchPair | Models.swift |
|
||||
| 前端请求、状态操作 | WorkspaceStore.swift |
|
||||
| OcrService / worker.py | native-engine/engine.py + 打包 RapidOCR |
|
||||
| OcrExtractor / WorkspaceService | native-engine/domain.py |
|
||||
| PptExportService | native-engine/exports.py / export_ppt |
|
||||
| TravelExcelExportService | native-engine/exports.py / export_travel |
|
||||
| PersonalExpenseExportService | native-engine/exports.py / export_expense |
|
||||
|
||||
保留一对一评分、多发票合计、多付款合计、同程多人归组、歧义判断、七类关键词分类、人工多对多、撤销、预览、金额统计和三类 Office 文件导出。
|
||||
|
||||
### 特意保留的业务口径
|
||||
|
||||
- 文件名不参与匹配;PDF 只识别、预览和导出首页。
|
||||
- 一对一分数达到 90 时可通过歧义检查;其他候选需要至少领先 8 分。
|
||||
- 一张发票对应多笔付款的唯一合计组合不另设商户/日期门槛。
|
||||
- 页面发票汇总、OCR 首金额和个人报销单最大金额的不同计算口径沿用旧代码,未擅自合并。
|
||||
- 订单截图与同金额支付凭证去重沿用旧规则,因此仍需人工检查不同订单同金额的情况。
|
||||
- “按类型分类”PPT 沿用先日期、后类别排序,并非重新设计分类封面或类别分区。
|
||||
- 实物照片不自动填入 PPT;除交通、住宿外保留手动粘贴占位页。
|
||||
- 个人报销单沿用原始 XLSX 模板,直接修改工作表 XML,保留样式、打印设置、公式和关联资源;每页 13 条明细,最多六个签字岗位。删除全部岗位时按旧规则回退默认岗位。
|
||||
|
||||
### 必须说明的环境差异
|
||||
|
||||
RapidOCR 主版本、模型及关键推理依赖与旧环境对齐,但 Windows x64 与 macOS arm64 的底层运行库不同。PDF 首页由本地 PDFium 栅格化,替代原来的 PDFBox。因此不能保证所有文件的 OCR 文本逐字或浮点结果完全一致,仍需用实际报账材料做回归验收。应用不会悄悄换用苹果 Vision 或云端 OCR。
|
||||
|
||||
## 验证
|
||||
|
||||
```sh
|
||||
.build-tools/bin/python -m unittest discover -s native-engine/tests -v
|
||||
.build-tools/bin/python native-engine/tests/smoke_engine.py \
|
||||
--binary "$PWD/native-engine/dist/receipt-engine-helper.app/Contents/MacOS/receipt-engine-helper" \
|
||||
--output "$PWD/.validation/packaged"
|
||||
```
|
||||
|
||||
覆盖原铁路多人凭证案例、火车与航班提取、金额歧义、分类、去重、PPT 页面安排、个人报销单分页与公式保留、行程表等。端到端测试使用 `../fapiao/demo-materials` 作为开发测试数据,运行中的应用本身不依赖该目录。
|
||||
|
||||
Debug 构建还提供应用沙盒内自检:用 `--verify-local-engine` 参数启动应用,生成独立测试图片,经过真正的 Swift → 本地引擎链路验证 OCR 和三种导出。结果写入沙盒 `Application Support/ReceiptDesk/diagnostics/report.json`,不替换用户工作区;自检后该应用进程自动退出。Release 不包含此入口。
|
||||
|
||||
## 发布说明
|
||||
|
||||
当前是本机开发运行构建,并非已经完成 Developer ID 签名和苹果公证的公开安装包。正式分发时需用同一 Developer ID 对辅助引擎的所有嵌套 Mach-O 库、辅助程序和主应用按由内到外顺序签名,再进行公证。请同时随发布包保留第三方依赖许可声明。
|
||||
Reference in New Issue
Block a user