# Reading Position Model ## 概述 统一的阅读位置模型,跨所有支持格式。用于记录用户读到哪里、支持继续阅读。 ## ReadingPosition ```rust enum ReadingPosition { Markdown { block_id: String, scroll_progress: f32 }, Text { line_number: u32, scroll_progress: f32 }, Pdf { page_number: u32, page_progress: f32, overall_progress: f32 }, Image { zoom_scale: f32, offset_x: f32, offset_y: f32 }, Epub { chapter_id: String, chapter_progress: f32, overall_progress: f32 }, Unknown, } ``` ## 各格式说明 ### Markdown - `block_id`:对应的 DocumentBlock ID - `scroll_progress`:0.0 ~ 1.0,在该 block 内的滚动比例 恢复阅读时,App 应滚动到对应 block 的对应位置。 ### Text - `line_number`:当前顶部可见行号(1-based) - `scroll_progress`:0.0 ~ 1.0,全文滚动比例 ### PDF - `page_number`:当前页码(1-based) - `page_progress`:0.0 ~ 1.0,该页内滚动比例 - `overall_progress`:0.0 ~ 1.0,全文进度 ### Image - `zoom_scale`:当前缩放倍数(1.0 = 原始尺寸) - `offset_x` / `offset_y`:视口偏移(像素) ### Epub - `chapter_id`:当前章节 ID(来自 spine) - `chapter_progress`:0.0 ~ 1.0,章节内滚动比例 - `overall_progress`:0.0 ~ 1.0,全书进度 ## 序列化 所有位置信息通过 serde 序列化为 JSON,方便 App 读取和上传。 ```json // Markdown 示例 { "type": "markdown", "block_id": "heading-3", "scroll_progress": 0.45 } ``` ## 继续阅读流程 ```text 1. App 请求后端:GET /materials/{id}/last-position 2. 后端返回 JSON 格式的 ReadingPosition 3. App 反序列化为 ReadingPosition 4. App 根据 format 类型恢复到对应位置 5. 如果无历史位置,从开头开始 ```