Files
nianxx-h5/docs/MIGRATION_PLAN.md
2026-05-26 12:14:31 +08:00

457 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# YGChatCS Vue3 Web 技术栈改造计划
## 文档状态
- 状态:规划中
- 日期2026-05-25
- 目标技术栈Vue 3 + Pinia + TypeScript + Tailwind CSS + Vite
- 当前技术栈uni-app 3 + Vue 3 + Pinia + SCSS + Vite
## 背景
当前项目是基于 uni-app 的多端应用,配置重点面向微信小程序,业务核心是酒店/文旅场景的 AI 聊天助手,并包含发现内容、商品/房型详情、订单、工单服务、快捷预订、WebView 桥接等模块。
本次改造目标是逐步抛弃 uni-app 技术栈,转向标准 Vue3 Web 技术栈。由于项目中大量能力依赖 `uni.*` 运行时 API、uni 页面生命周期、`pages.json` 路由配置、小程序专属能力和 uni 组件标签,不能采用一次性全量替换。推荐采用“新 Web 工程并行建设 + 功能分阶段迁移 + 旧项目作为回归基线”的方式,降低代码缺失和功能缺失风险。
## 改造原则
1. 旧项目先保持可运行,作为行为基线和回归对照。
2. 新 Vue3 Web 工程并行建设,优先迁移基础设施,再迁移业务页面。
3. 每个阶段都必须有可验证产物,避免长期处于不可运行状态。
4. 迁移按业务闭环纵向切片,不按“所有组件一次性搬完”的横向方式推进。
5. 先封装平台适配层,再逐步替换页面中的 `uni.*` 调用。
6. 微信小程序专属能力必须单独评估 Web/H5 替代方案,不能默认等价迁移。
7. TypeScript 类型补齐随迁移同步推进,不把 JS 全量机械改名为 TS 后再补类型。
## 当前项目关键依赖面
### 入口与配置
- `src/main.js`:创建 uni-app Vue 应用,注册 Pinia 和 `pinia-plugin-unistorage`
- `src/App.vue`应用生命周期负责服务地址初始化、token 刷新、网络恢复重载。
- `src/pages.json`uni-app 页面、分包和页面样式配置。
- `src/manifest.json`:小程序 appid、权限、插件和平台配置。
- `vite.config.js`:当前依赖 `@dcloudio/vite-plugin-uni`
### 核心业务模块
- `src/pages/ChatMain/ChatMainList/index.vue`聊天主流程包含消息列表、WebSocket 初始化、消息发送、工具卡渲染和滚动控制。
- `src/request/api/AgentChatStream.js`:微信小程序分块/流式请求封装,依赖 `uni.request({ enableChunked: true })`
- `src/utils/WebSocketManager.js`:跨端 WebSocket 管理器,当前优先使用 `uni.connectSocket`
- `src/request/base/request.js`:统一请求封装,依赖 `uni.request`、token、客户端配置和位置请求头。
- `src/manager/LoginManager.js``src/hooks/useGoLogin.js`:登录、刷新 token、跳转登录、登录成功事件。
- `src/pages/goods/``src/pages-booking/``src/pages-order/``src/pages-service/`:商品、预订、订单和工单业务链路。
### 高风险 uni 能力
| 当前能力 | 使用场景 | Web 改造方向 | 风险 |
| -------------------------------------- | ------------------- | -------------------------------- | ---- |
| `uni.navigateTo/reLaunch/navigateBack` | 页面跳转 | Vue Router 服务封装 | 中 |
| `uni.request/uploadFile` | HTTP 请求、文件上传 | `fetch` 或 Axios + 上传封装 | 中 |
| `uni.$emit/$on/$off` | 跨组件事件 | `mitt` 或 typed event bus | 中 |
| `uni.showToast/showModal/showLoading` | 用户反馈 | UI 组件库或自研反馈服务 | 低 |
| `uni.connectSocket` | AI 聊天实时通信 | 浏览器原生 `WebSocket` | 高 |
| `uni.request enableChunked` | AI 流式回复 | `fetch + ReadableStream` 或 SSE | 高 |
| `uni.login` | 微信登录 | 微信 Web 授权或后端 H5 登录方案 | 高 |
| `uni.requestPayment` | 支付 | 微信 JS-SDK/H5 支付/后端支付跳转 | 高 |
| `uni.chooseImage` | 图片选择上传 | `<input type="file">` + 上传服务 | 中 |
| `uni.saveImageToPhotosAlbum` | 保存图片 | 浏览器下载能力,移动端受限 | 中 |
| `uni.getLocation/openLocation` | 定位和地图 | Geolocation API + 地图 URL/SDK | 中 |
| `uni.createSelectorQuery` | 尺寸测量 | DOM API、ResizeObserver | 中 |
| `uni.onKeyboardHeightChange` | 输入框键盘适配 | 视口监听、CSS env、安全区适配 | 高 |
| `<view>/<text>/<image>/<scroll-view>` | 页面模板 | HTML 标签或基础组件替换 | 中 |
| `<web-view>` | 内嵌页面 | `iframe` + `postMessage` 协议 | 中 |
| `<canvas>` + uni canvas API | 二维码/图片 | 浏览器 Canvas 或第三方库 | 中 |
## 目标架构
### 推荐目录结构
建议在仓库内新建 `web/` 目录承载新 Web 应用,旧 uni-app 代码暂时保留:
```text
web/
src/
app/
main.ts
router.ts
pinia.ts
assets/
components/
constants/
features/
chat/
discovery/
goods/
booking/
order/
service/
bridge/
services/
http/
auth/
router/
storage/
event-bus/
feedback/
websocket/
stream/
browser/
stores/
styles/
types/
```
### 基础技术选型
| 能力 | 建议方案 |
| ---------- | --------------------------------------------------- |
| 框架 | Vue 3 + Composition API |
| 类型 | TypeScript严格模式分阶段开启 |
| 状态管理 | Pinia |
| 状态持久化 | `pinia-plugin-persistedstate` 或自研 storage plugin |
| 路由 | Vue Router |
| 样式 | Tailwind CSS + 少量全局 CSS 变量 |
| 请求 | Axios 或标准 `fetch` 封装,二选一后统一使用 |
| 事件总线 | `mitt`,建议加类型约束 |
| WebSocket | 浏览器原生 `WebSocket` |
| 流式响应 | `fetch + ReadableStream`,必要时兼容 SSE |
| 构建 | Vite |
| 测试 | Vitest + Vue Test Utils关键流程补 Playwright |
## 分阶段改造计划
### 阶段 0迁移盘点和基线冻结
目标:明确迁移范围,冻结旧项目行为基线。
任务:
- 梳理 `src/pages.json`,生成旧路由到 Vue Router 的映射表。
- 统计所有 `uni.*``wx.*``@dcloudio/uni-app` 生命周期和 uni 组件标签使用点。
- 按业务域列出功能清单聊天、发现、商品、预订、订单、工单、WebView、图片、支付、定位。
- 标记每个页面和组件的迁移策略:保留、合并、重写、废弃、延后。
- 为核心流程录制或截图旧项目行为,作为新版本验收依据。
验收标准:
- 有完整的路由映射表。
- 有完整的 uni API 替换清单。
- 每个业务模块有明确迁移优先级。
- 旧项目可继续 `yarn build:mp-weixin` 或对应环境构建。
### 阶段 1搭建 Vue3 Web 工程骨架
目标:建立新 Web 应用的最小可运行基础。
任务:
- 新建 `web/` 工程,配置 Vue3、TypeScript、Vite、Pinia、Vue Router、Tailwind CSS。
- 配置 `@/` 路径别名、环境变量、构建脚本和基础目录结构。
- 建立全局样式入口,迁移必要字体、主题色和基础 CSS reset。
- 建立基础布局:移动端主容器、安全区、页面滚动策略。
- 增加最小健康页和 404 页,验证路由可用。
验收标准:
- `web` 工程可以独立安装、启动和构建。
- TypeScript、Tailwind、Router、Pinia 都可用。
- 新项目不依赖 `@dcloudio/*` 包。
### 阶段 2建设平台适配层
目标:先统一替代 uni 运行时能力,避免业务页面直接依赖浏览器 API。
任务:
- 实现 `services/router`:封装 `push``replace``back``reLaunch` 等语义。
- 实现 `services/http`:封装 baseUrl、clientId、token、位置请求头、424 登出处理。
- 实现 `services/storage`:替代同步 storage API并兼容 token 持久化。
- 实现 `services/event-bus`:替代 `uni.$emit/$on/$off`,事件名沿用现有常量。
- 实现 `services/feedback`:封装 toast、modal、loading。
- 实现 `services/browser`:封装图片选择、下载、定位、电话、复制等浏览器能力。
- 实现 `services/auth`:封装 token、刷新、登出、登录跳转。
验收标准:
- 请求层、事件、路由、反馈、存储均有统一入口。
- 页面迁移时不得新增裸 `fetch`、裸 `localStorage`、裸 `window.location` 作为业务逻辑入口。
- 424 登出逻辑在新请求层可复用。
### 阶段 3迁移配置、Store 和 API
目标:先迁移非 UI 业务基础,让后续页面迁移有稳定依赖。
任务:
- 迁移 `src/constant/``web/src/constants/`,补充 TypeScript 类型。
- 迁移 `client-configs.json` 和当前客户端配置读取逻辑。
- 迁移 Pinia store`app``location``picture``selectedDate`
- 替换 `pinia-plugin-unistorage` 为 Web 持久化方案。
验收标准:
- 新 Web 应用能读取客户端配置和服务地址。
- token 可以持久化、刷新和清除。
- 普通业务 API 可以通过新请求层调用。
- API 模块不再依赖 `uni.request`
### 阶段 4迁移 AI 聊天核心链路
目标:优先打通项目最高价值、最高风险的聊天闭环。
任务:
- 拆分聊天主页面,避免继续维护单个超大组件。
- 迁移消息模型:`MessageRole``MessageType``CompName``Command`
- 改造 `WebSocketManager` 为浏览器原生 WebSocket 实现,保留重连、队列、心跳和销毁逻辑。
- 改造流式回复:用 `fetch + ReadableStream` 或 SSE 替代 `enableChunked`
- 迁移消息列表、用户消息、AI 消息、加载态、停止生成、超时处理。
- 迁移工具卡分发逻辑:快捷预订、发现卡、地图卡、反馈卡、商品图文卡、问卷卡、长文本卡。
- 重做滚动到底、输入框键盘、移动端视口适配。
验收标准:
- 用户可以进入首页聊天。
- 可以发送普通文本消息。
- 可以收到流式 AI 回复。
- 可以渲染至少一类 `toolCall` 卡片。
- 可以停止当前回复。
- WebSocket 断线重连和消息发送失败有可感知反馈。
- 登录失效后能跳转登录或触发登录流程。
### 阶段 5迁移首页和发现模块
目标:完成用户进入应用后的主要浏览路径。
任务:
- 迁移首页壳、顶部导航、欢迎区、Tab 切换。
- 迁移发现页内容流、快捷问题、卡片轮播和定位逻辑。
- 迁移快捷问题触发聊天事件的逻辑。
-`scroll-view` 改造成浏览器滚动容器。
-`uni.createSelectorQuery` 相关逻辑替换为 DOM API 或 ResizeObserver。
验收标准:
- 首页视觉结构和旧版本一致或有明确设计调整。
- 发现页可以正常加载数据。
- 快捷问题可以切换到聊天并发送内容。
- 移动端滚动不会和输入框区域冲突。
### 阶段 6迁移商品、预订和订单闭环
目标:完成从商品详情到下单、支付前、订单查看的业务闭环。
任务:
- 迁移商品/房型详情、图片相册、设施、套餐、日期选择。
- 迁移预订确认页、联系人、入住人、数量、金额计算。
- 迁移订单列表和订单详情。
- 迁移退款、取消、订单状态展示。
- 评估支付能力Web H5 支付、微信 JS-SDK 支付或后端支付跳转。
验收标准:
- 商品详情可打开并展示完整信息。
- 酒店类商品日期选择和预订参数正确。
- 可以提交订单或完成支付前置参数生成。
- 订单列表和详情可查看。
- 支付能力有明确环境方案和失败兜底。
### 阶段 7迁移工单、反馈、快捷入口和桥接能力
目标:补齐非聊天核心业务能力。
任务:
- 迁移工单列表和工单卡片。
- 迁移服务呼叫、反馈表单、图片上传。
- 迁移快捷入口列表和快捷入口卡片。
- 将 WebView 改造为 iframe 或外链跳转。
- 重建桥接协议:`postMessage`、token 注入、图片上传回传、保存图片。
验收标准:
- 工单、反馈、快捷入口可完成主要操作。
- 图片选择和上传在 Web 环境可用。
- 外部 H5 页面能通过新桥接协议与主应用通信。
- 保存图片或下载能力有浏览器兼容说明。
### 阶段 8Tailwind 样式迁移和 UI 收敛
目标:逐步替换旧 SCSS 工具类,建立 Web 版统一视觉系统。
任务:
-`src/uni.scss` 中主题变量迁移到 Tailwind config 和 CSS variables。
- 将常用工具类映射到 Tailwind避免一次性改完所有样式。
- 优先改造新迁移页面中的 SCSS旧代码不做无意义格式化。
- 移除 `rpx``page`、小程序专属样式语义。
- 建立移动端安全区、底部固定栏、弹窗、滚动容器的统一样式模式。
验收标准:
- 新 Web 页面主要使用 Tailwind 和少量局部 CSS。
- 不再依赖 `src/static/scss` 的 uni 工具类。
- 移动端主流程无明显文字溢出、遮挡、滚动穿透。
### 阶段 9测试、灰度和旧栈下线
目标:在新版本稳定后再删除旧 uni-app 技术栈。
任务:
- 为请求层、事件总线、WebSocket、流式解析补单元测试。
- 为聊天、商品、订单、登录失效等核心流程补端到端测试。
- 新旧版本并行验收,建立问题清单。
- 小范围灰度新 Web 版本,监控白屏、接口错误、聊天失败、支付失败。
- 稳定后冻结旧 uni-app 项目。
- 最后删除 `@dcloudio/*` 依赖、`src/uni_modules/``pages.json``manifest.json`、条件编译代码和废弃适配逻辑。
验收标准:
- 新版本核心功能覆盖旧版本核心路径。
- 回归问题关闭或有明确延期说明。
- 旧 uni-app 代码零活跃依赖后再移除。
## 建议迁移优先级
| 优先级 | 模块 | 原因 |
| ------ | ---------------------------------- | ------------------------ |
| P0 | 平台适配层、配置、请求、token | 所有业务依赖,必须先稳定 |
| P0 | AI 聊天主链路 | 产品核心价值,风险最高 |
| P1 | 首页、发现、快捷问题 | 用户入口和聊天联动 |
| P1 | 商品详情、预订、订单 | 核心商业闭环 |
| P2 | 工单、反馈、快捷入口 | 重要但可后续分批迁移 |
| P2 | WebView 桥接、图片保存 | 依赖外部页面和浏览器兼容 |
| P3 | 非核心 demo、README 示例、废弃组件 | 最后清理 |
## 路由迁移初稿
| uni-app 路由 | Vue Router 建议路由 | 说明 |
| -------------------------------------------------- | ---------------------- | ------------------------------ |
| `/pages/index/index` | `/` | 首页和聊天主入口 |
| `/pages/login/index` | `/login` | 登录页 |
| `/pages/goods/index` | `/goods/:commodityId?` | 商品/房型详情 |
| `/pages/goods/album/index` | `/goods/album` | 商品相册 |
| `/pages/webview/index` | `/bridge/webview` | iframe 或外链桥接 |
| `/pages/ChatMain/ChatLongAnswer/index` | `/chat/long-answer` | 长回答页 |
| `/pages/ChatModule/LongTextGuideCardPreview/guide` | `/chat/guide/guide` | 长文本 guide 详情 |
| `/pages/ChatModule/LongTextGuideCardPreview/poi` | `/chat/guide/poi` | 长文本 poi 详情 |
| `/pages/ChatModule/LongTextGuideCardPreview/route` | `/chat/guide/route` | 长文本 route 详情 |
| `/pages/ChatModule/LongTextGuideCardPreview/photo` | `/chat/guide/photo` | 长文本 photo 详情 |
| `/pages/ChatMain/NoticeMessage/detail` | `/notice/:id?` | 通知详情 |
| `/pages-order/order/list` | `/orders` | 订单列表 |
| `/pages-order/order/detail` | `/orders/:orderId` | 订单详情 |
| `/pages-service/order/list` | `/service-orders` | 工单列表 |
| `/pages-quick/list` | `/quick` | 快捷入口 |
| `/pages-booking/index` | `/booking` | 预订确认 |
| `/pages-bridge/UploadImage` | `/bridge/upload-image` | 图片上传桥接,可被新协议替代 |
| `/pages-bridge/SaveImage` | `/bridge/save-image` | 保存图片桥接,可被下载能力替代 |
## 关键验收清单
### 聊天
- 可以创建/恢复会话。
- 可以发送文本和快捷指令。
- AI 回复支持流式展示。
- 工具卡按 `componentName` 正确渲染。
- 长文本卡可以进入详情页。
- 停止生成、超时、失败、重试都有明确状态。
- WebSocket 断线重连不丢当前消息状态。
### 登录与权限
- 无 token 时跳转登录。
- refresh token 可自动刷新。
- HTTP 424 会清除 token 并触发登出。
- 登录成功事件能刷新聊天、通知等依赖模块。
- 微信 Web/H5 授权方案明确。
### 商品与订单
- 商品详情、相册、套餐、设施、日期选择正常。
- 预订参数、联系人、入住人、金额计算正确。
- 订单列表、订单详情、退款状态正常。
- 支付方案在目标平台可用。
### Web 能力
- 图片选择和上传可用。
- 地理位置授权失败有降级提示。
- 电话能力在 Web 上有明确降级方式。
- WebView/iframe 桥接协议可用。
- 保存图片能力在浏览器限制下有替代方案。
### UI 与兼容
- 移动端首屏高度、底部输入框、安全区正确。
- 滚动区域不穿透,聊天列表能稳定滚到底。
- 键盘弹出时输入区不遮挡。
- 主要页面在常见移动端 viewport 下无明显错位。
## 风险和缓解措施
| 风险 | 影响 | 缓解措施 |
| ---------------------------------- | ---- | ---------------------------------------------------- |
| 一次性替换导致功能缺失 | 高 | 新旧并行,按业务闭环迁移 |
| 聊天流式协议在 Web 不兼容 | 高 | 优先做流式原型,确认后端支持 `ReadableStream` 或 SSE |
| 微信登录/支付无法等价迁移 | 高 | 提前确认目标是 H5、公众号、企业微信还是普通浏览器 |
| 键盘和滚动体验退化 | 高 | 聊天页单独验收移动端视口和输入行为 |
| Tailwind 全量替换成本过高 | 中 | 页面迁移时渐进替换,不做纯样式大爆炸 |
| 旧 SCSS 工具类和 Tailwind 混用混乱 | 中 | 建立映射规则和废弃清单 |
| JS 改 TS 产生大量类型债 | 中 | 按模块补类型,优先 API、store、消息模型 |
| 外部 H5 桥接协议变化影响存量页面 | 中 | 保留兼容层,先支持旧 query/token 方式 |
## 不建议的做法
- 不建议在当前 `src/` 中直接删除 uni-app 依赖后边报错边修。
- 不建议先全量把 `.js` 改成 `.ts`,再统一解决类型错误。
- 不建议先全量替换 `<view>``<text>``<image>`,再处理业务逻辑。
- 不建议一开始重写全部 SCSS 到 Tailwind。
- 不建议在未确认微信 Web 登录/支付方案前删除旧小程序能力。
- 不建议迁移期间手工修改 `dist/` 构建产物。
## 推荐里程碑
### M1新 Web 基座可运行
- Web 工程启动、构建正常。
- Router、Pinia、Tailwind、请求层、事件总线、反馈服务可用。
### M2聊天主链路可用
- 首页聊天可打开。
- 文本发送、流式回复、工具卡渲染、停止生成可用。
### M3首页和发现可用
- 首页、发现页、快捷问题和聊天联动完成。
### M4交易闭环可用
- 商品详情、预订确认、订单列表、订单详情完成。
- 支付方案完成或明确接入边界。
### M5辅助模块补齐
- 工单、反馈、快捷入口、WebView/桥接、图片能力完成。
### M6旧 uni-app 下线
- 新版本核心路径验收通过。
- 旧代码无活跃依赖。
- 移除 uni-app 依赖和废弃文件。
## 后续建议
下一步建议先执行阶段 0输出三份更细的落地清单
1. `docs/ROUTE_MIGRATION_MAP.md`:完整路由映射。
2. `docs/UNI_API_REPLACEMENT_MATRIX.md`uni API 替换矩阵。
3. `docs/FEATURE_MIGRATION_CHECKLIST.md`:业务功能迁移验收清单。
完成这三份清单后,再开始搭建 `web/` 工程,能最大限度减少遗漏。