10 KiB
10 KiB
app-android 迁移至 React Web 应用计划
目标:将现有 Kotlin + Jetpack Compose 原生 Android 应用迁移为纯 React Web 应用,不再依赖任何原生 iOS/Android 代码,统一为浏览器端运行。
1. app-android 现状摘要
1.1 技术栈
| 层级 | 技术 | 说明 |
|---|---|---|
| 语言 | Kotlin 1.9+ | 主语言 |
| UI | Jetpack Compose | 声明式 UI |
| 架构 | MVVM | ViewModel + Compose |
| 网络 | Ktor | HTTP + WebSocket |
| 本地存储 | Room + DataStore | SQLite 数据库 + 键值存储 |
| 导航 | Navigation Compose | 声明式导航 |
| 图片 | Coil | 图片加载 |
| 主题 | Material 3 | 深色/浅色主题 |
| 支付 | 微信支付 / 支付宝 | 原生 SDK 集成 |
1.2 项目结构
app-android/
├── config/ # AppConfig (API 地址、BuildConfig)
├── data/ # 数据层
│ ├── auth/ # TokenManager (DataStore)
│ ├── database/ # Room (AppDatabase, Entity, DAO)
│ ├── preferences/ # TokenPreferences
│ └── repository/ # Conversation/Chapter/Message/Payment/Profile Repository
├── network/ # 网络层
│ ├── ApiService # REST API (Ktor + Bearer Auth)
│ ├── AuthService # 登录/注册/刷新 Token
│ ├── WebSocketClient
│ └── models/ # 请求/响应 DTO
├── ui/
│ ├── screens/ # 20+ 屏幕
│ ├── components/ # 可复用组件
│ ├── theme/ # Color, Theme, Type
│ ├── viewmodel/ # 7 个 ViewModel
│ └── settings/ # AppSettings (深色模式等)
├── navigation/ # Screen 路由 + AppNavigation
├── feature/ # VoiceRecorder 等
└── utils/ # 工具类
1.3 功能模块清单
| 模块 | screens / 组件 | ViewModel |
|---|---|---|
| 认证 | Login, Register, NicknameSetup, ResetPassword, AccountManagement | AuthViewModel |
| 对话 | ConversationList, CreateMemory | ConversationListViewModel, CreateMemoryViewModel |
| 回忆录 | MyMemoir, ChapterReading, FullTextReading | MyMemoirViewModel |
| 个人中心 | Profile, PersonalInfo | ProfileViewModel |
| 套餐/支付 | UpgradePlan, PlanDetails, PlanBalance, MyOrders | PaymentViewModel |
| 设置/帮助 | FAQ, Feedback, About, ExportData, LegalDocument | - |
1.4 核心能力
- 认证:手机号注册、登录、JWT Token 管理、刷新 Token、DataStore 持久化
- 对话:WebSocket 实时语音对话、消息收发、TTS 播放
- 回忆录:章节列表、阅读、全文、PDF 导出、对话整理为章节
- 支付:微信支付、支付宝、套餐、订单、余额
- 本地数据:Room 存储 Conversation/Chapter/Message,离线同步
- 主题:深色模式、Material 3
2. 迁移策略
- 新建 React Web 项目(Vite + React 或 Create React App),不复用 app-ios
- 按 模块/功能 逐步迁移,优先核心流程(登录 → 对话 → 回忆录)
- 保留 API 契约不变,仅替换客户端实现
- 零原生代码:纯 Web 技术栈,部署为静态站点或 SPA
3. 迁移步骤 TODO
Phase 0:环境与基建(前置)
| # | 任务 | 说明 | 优先级 |
|---|---|---|---|
| 0.1 | 初始化 React Web 项目 | npm create vite@latest app-web -- --template react-ts 或 CRA |
P0 |
| 0.2 | 配置 API 环境 | 将 AppConfig.kt 中 BASE_URL / WS_BASE_URL 迁移为 env (VITE_*) | P0 |
| 0.3 | 搭建项目目录结构 | src/screens, components, services, store, hooks, themes | P1 |
| 0.4 | 配置路由 | React Router v6 | P0 |
Phase 1:认证与 Token 管理
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 1.1 | Auth API 封装 | AuthService.kt | 注册、登录、刷新 Token | P0 |
| 1.2 | Token 持久化 | TokenManager + DataStore | localStorage 或 sessionStorage | P0 |
| 1.3 | 401 自动刷新 + 登出 | ApiService Auth plugin | axios 拦截器实现 Bearer + 刷新 | P0 |
| 1.4 | LoginScreen | LoginScreen.kt | 手机号 + 密码登录 | P0 |
| 1.5 | RegisterScreen | RegisterScreen.kt | 手机号注册 | P0 |
| 1.6 | NicknameSetupScreen | NicknameSetupScreen.kt | 首次登录昵称设置 | P1 |
| 1.7 | ResetPasswordScreen | ResetPasswordScreen.kt | 重置密码 | P1 |
| 1.8 | AccountManagementScreen | AccountManagementScreen.kt | 账号管理、登出 | P1 |
Phase 2:导航与主框架
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 2.1 | 路由定义 | Screen sealed class | 定义所有 route 常量 / 路径 | P0 |
| 2.2 | 底部 Tab 导航 | MainActivity BottomNav | 聊天 / 回忆录 / 我的 三个 Tab | P0 |
| 2.3 | 栈式页面导航 | AppNavigation.kt | React Router <Outlet> / 嵌套路由 |
P0 |
| 2.4 | 登录态路由守卫 | ProtectedRoute 组件 | 未登录 → 重定向 Login | P0 |
| 2.5 | 过渡动画 | NavigationTransitions | 视需求用 CSS transition 或 Framer Motion | P2 |
Phase 3:REST API 与数据层
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 3.1 | API Client 封装 | ApiService.kt | axios 实例、baseURL、timeout | P0 |
| 3.2 | 对话相关 API | ApiService 对话接口 | create/list/get conversation | P0 |
| 3.3 | 回忆录/章节 API | ApiService 章节/书籍接口 | books, chapters, PDF 等 | P0 |
| 3.4 | 支付/套餐 API | ApiService 支付接口 | plans, orders, balance | P1 |
| 3.5 | 用户/配置 API | ApiService Profile | 用户信息、FAQ、反馈 | P1 |
| 3.6 | 数据模型 (TypeScript) | network/models/*.kt | 定义请求/响应类型 | P0 |
Phase 4:WebSocket 与对话功能
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 4.1 | WebSocket Client | WebSocketClient.kt | 原生 WebSocket API,心跳、重连 |
P0 |
| 4.2 | WebSocket 消息协议 | WebSocketMessage.kt | type / payload 解析 | P0 |
| 4.3 | 消息收发逻辑 | CreateMemoryViewModel | sendAudio/sendText、接收 TTS/文本 | P0 |
| 4.4 | 浏览器录音 | VoiceRecorder.kt | MediaRecorder API(getUserMedia) |
P0 |
| 4.5 | ConversationListScreen | ConversationListScreen.kt | 对话列表 | P0 |
| 4.6 | CreateMemoryScreen | CreateMemoryScreen.kt | 聊天详情、语音输入 | P0 |
| 4.7 | MessageBubble / ChatInputField | 对应 Compose 组件 | 消息气泡、输入框 | P0 |
| 4.8 | 音频播放 (TTS) | CreateMemoryViewModel 中 TTS | HTMLAudioElement / new Audio() |
P0 |
Phase 5:回忆录模块
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 5.1 | MyMemoirScreen | MyMemoirScreen.kt | 回忆录 Tab 主页 | P0 |
| 5.2 | 章节列表 | ChapterCard, BookInfoCard | 书籍/章节列表展示 | P0 |
| 5.3 | ChapterReadingView | 章节阅读 | 单章阅读 | P0 |
| 5.4 | FullTextReadingView | 全文阅读 | 完整回忆录阅读 | P1 |
| 5.5 | PDF 导出 | MyMemoirViewModel 导出逻辑 | 调用 API 获取 PDF,blob 下载或新窗口打开 |
P1 |
| 5.6 | OrganizeConversationDialog | 对话整理为章节 | 弹窗 + API 调用 | P1 |
Phase 6:个人中心与支付
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 6.1 | ProfileScreen | ProfileScreen.kt | 我的 Tab、未登录/已登录 UI | P0 |
| 6.2 | PersonalInfoScreen | PersonalInfoScreen.kt | 个人信息、头像上传 | P1 |
| 6.3 | UpgradePlanScreen | UpgradePlanScreen.kt | 套餐选择 | P1 |
| 6.4 | PlanDetailsScreen / PlanBalanceScreen | 套餐详情、余额 | P1 | |
| 6.5 | MyOrdersScreen | 订单列表 | P1 | |
| 6.6 | 微信/支付宝支付 | PaymentUtils | 使用 H5 支付:微信 JSAPI / 支付宝网页支付 | P2 |
| 6.7 | FAQScreen / FeedbackScreen | 常见问题、反馈 | P1 | |
| 6.8 | AboutScreen / LegalDocumentScreen | 关于、条款、隐私 | P1 | |
| 6.9 | ExportDataScreen | 数据导出 | P2 |
Phase 7:本地存储(可选)
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 7.1 | 本地缓存 | Room + Repository | localStorage / IndexedDB(如 dexie.js) | P2 |
| 7.2 | 离线同步逻辑 | Repository 同步 | 视产品需求决定是否保留 | P2 |
Phase 8:主题、设置与收尾
| # | 任务 | 对应 Android 实现 | 说明 | 优先级 |
|---|---|---|---|---|
| 8.1 | 主题系统 | LifeechoTheme, Color.kt | CSS 变量 + 深色/浅色 media/切换 | P1 |
| 8.2 | 主题持久化 | AppSettings.kt | localStorage 保存用户偏好 | P1 |
| 8.3 | 国际化 (i18n) | strings.xml | react-i18next 或类似 | P2 |
| 8.4 | 麦克风权限 | RECORD_AUDIO | 浏览器 navigator.mediaDevices.getUserMedia 需 HTTPS |
P0 |
Phase 9:构建与发布
| # | 任务 | 说明 | 优先级 |
|---|---|---|---|
| 9.1 | 生产构建 | npm run build(Vite 输出 dist/) |
P0 |
| 9.2 | 静态托管部署 | 部署至 Vercel / Netlify / Nginx 等 | P0 |
| 9.3 | 版本号与 CI | 对齐现有 GitHub Actions(若有) | P1 |
4. 技术映射速查
| Android (Kotlin) | React Web 对应 |
|---|---|
| Jetpack Compose | React 组件 + CSS / Tailwind / styled-components |
| ViewModel + StateFlow | useState / useReducer / Zustand / React Query |
| Navigation Compose | React Router v6 |
| Ktor HttpClient | axios / fetch |
| Ktor WebSocket | 原生 WebSocket |
| Room | localStorage / IndexedDB(或仅网络) |
| DataStore | localStorage / sessionStorage |
| Coil | <img> / 原生加载 |
| Material 3 | 自定义主题 / MUI / shadcn/ui |
5. 风险与注意事项
- WebSocket + 语音:浏览器端 WebSocket 稳定,录音需
getUserMedia,HTTPS 环境下可用。 - 支付:Web 端使用微信 H5 支付、支付宝网页支付,无需原生 SDK。
- 本地数据:Web 无 SQLite,可用 localStorage 简单缓存或 IndexedDB 做离线。
- 性能:长列表用虚拟滚动(react-window / react-virtuoso)。
- PWA:可选做成 PWA,支持离线与「添加到主屏幕」。
6. 建议执行顺序
- Phase 0 + 1 + 2:基建 + 认证 + 导航,打通「登录 → 主框架」。
- Phase 3 + 4:API + WebSocket + 对话,实现核心对话流程。
- Phase 5:回忆录浏览与阅读。
- Phase 6:个人中心与基础套餐展示(支付可延后)。
- Phase 7 / 8 / 9:按需推进本地存储、主题、构建发布。
文档版本:1.0 | 更新日期:2025-02-15