ReadingEvent V2 → API 上传协议映射
字段映射
| Rust ReadingEventV2 |
API ReadingEventUploadItem |
来源 |
| event_id |
eventId |
Rust 生成 UUID |
| client_session_id |
clientSessionId |
Rust 生成 UUID(start_reading_session_v2) |
| material_id |
materialId |
Rust 保存,iOS 传入 |
| event_type |
eventType |
Rust→iOS 转 snake_case |
| position |
position |
Rust(camelCase JSON,clamped) |
| active_seconds_delta |
activeSecondsDelta |
Rust ActiveTimeTracker 计算 |
| timestamp_ms |
clientTimestampMs |
Rust |
| sequence |
sequence |
Rust(session 内递增) |
| — |
readingTargetType |
iOS 补充 |
| — |
platform |
iOS 补充(= "ios") |
| — |
appVersion |
iOS 补充 |
| — |
clientTimezoneOffsetMinutes |
iOS 补充 |
iOS 上传适配流程
1. Rust export_pending_events_v2(limit, ts)
2. iOS 获得 Vec<ReadingEventV2>
3. iOS 遍历每个 event,补充 readingTargetType/platform/appVersion/timezone
4. iOS 写入本地上传队列
5. 成功后调用 Rust ack_events_v2(eventIds)
6. 失败后调用 Rust mark_events_failed_v2(eventIds)
7. App 启动时调用 reload_stale_events_v2() 恢复未 ack 的事件
eventType 映射
| Rust |
API |
| MaterialOpened |
material_opened |
| MaterialClosed |
material_closed |
| PositionChanged |
position_changed |
| Heartbeat |
heartbeat |
| MarkedAsRead |
marked_as_read |
delta 规则
| 事件 |
delta |
| MaterialOpened |
0 |
| PositionChanged |
0 |
| MarkedAsRead |
0 |
| Heartbeat |
tracker.tick() 返回值 |
| MaterialClosed |
tracker.close() 返回值 |