# Architecture ## 分层架构 ```text ┌──────────────────────────────────────────────┐ │ iOS / Android / 鸿蒙 / macOS / Windows / Web │ ← 宿主 App ├──────────────────────────────────────────────┤ │ UniFFI C-ABI bridge │ ← zx_document_ffi ├──────────────────────────────────────────────┤ │ zx_document_core (Rust) │ ← 核心逻辑 │ ├─ file_type 文件类型识别 │ │ ├─ markdown MD 解析为 DocumentBlock │ │ ├─ text TXT 读取 │ │ ├─ image_meta 图片 metadata │ │ ├─ epub EPUB 结构解析 │ │ ├─ pdf PDF 位置模型 │ │ ├─ progress ReadingPosition │ │ ├─ events ReadingEvent │ │ ├─ search 基础搜索 │ │ └─ anchors NoteAnchor │ └──────────────────────────────────────────────┘ ``` ## 职责边界 ### Rust Core 负责 | 模块 | 职责 | |------|------| | 文件类型识别 | 根据 magic bytes → MIME → 扩展名判断 MaterialType | | Markdown 解析 | 读取 .md 文件,输出 DocumentBlock 列表 | | TXT 读取 | 读取 .txt 文件,输出段落/行 block | | 图片 metadata | 读取宽高、格式、文件大小 | | 阅读位置 | 提供统一的 ReadingPosition(跨格式) | | 阅读事件 | 生成 MaterialOpened/Closed/PositionChanged/Heartbeat 事件 | | 搜索 | 大小写不敏感,返回 block/snippet | | 笔记锚点 | 从 ReadingPosition 生成 NoteAnchor | | FFI 绑定 | 通过 UniFFI 暴露 API 给 Swift/Kotlin | ### 宿主 App 负责 | 模块 | 职责 | |------|------| | 网络请求 | COS 下载、API 调用、事件上报 | | Token 管理 | 用户登录、JWT 存储 | | UI 渲染 | SwiftUI/Compose 渲染 DocumentBlock | | 系统预览 | PDF/Office 通过 PDFKit/QuickLook 预览 | | 文件选择 | 系统文件选择器 | | 分享/删除 | 系统分享面板、文件管理 | ### Rust Core 明确不负责 - 不做网络请求 - 不保存 Token - 不直接访问后端 API - 不做 AI / RAG 解析 - 不做向量化 - 不做 Office 高保真预览 - 不做 OCR - 不做 PDF 标注 - 不做富文本编辑器 - 不做完整 UI ## 数据流 ```text 1. App 下载文件到本地(COS → 沙盒) 2. App 调用 detect_material_type(file_path) 3. 根据 MaterialType 决定预览方式: - NativeReader → 调用 open_document → get_xxx_blocks → 原生渲染 - PlatformPreview → iOS QuickLook / Android 系统预览 - ExternalOpen → 打开外部 App 4. 阅读过程中 App 调用 update_reading_position / heartbeat 5. App 定期调用 export_pending_events → 上传到后端 ``` ## Crate 拆分 | Crate | 类型 | 用途 | |-------|------|------| | zx_document_core | library | 核心 Rust 逻辑,纯计算 | | zx_document_ffi | library | UniFFI 绑定,类型转换 | | xtask | binary | 构建脚本,生成 binding,打包 artifact |