19 KiB
19 KiB
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 工程并行建设 + 功能分阶段迁移 + 旧项目作为回归基线”的方式,降低代码缺失和功能缺失风险。
改造原则
- 旧项目先保持可运行,作为行为基线和回归对照。
- 新 Vue3 Web 工程并行建设,优先迁移基础设施,再迁移业务页面。
- 每个阶段都必须有可验证产物,避免长期处于不可运行状态。
- 迁移按业务闭环纵向切片,不按“所有组件一次性搬完”的横向方式推进。
- 先封装平台适配层,再逐步替换页面中的
uni.*调用。 - 微信小程序专属能力必须单独评估 Web/H5 替代方案,不能默认等价迁移。
- 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 代码暂时保留:
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 持久化方案。 - 迁移
src/request/api/,统一改用新http服务。 - 为主要 API 响应定义基础类型,优先覆盖登录、首页、会话、商品、订单。
验收标准:
- 新 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 页面能通过新桥接协议与主应用通信。
- 保存图片或下载能力有浏览器兼容说明。
阶段 8:Tailwind 样式迁移和 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,输出三份更细的落地清单:
docs/ROUTE_MIGRATION_MAP.md:完整路由映射。docs/UNI_API_REPLACEMENT_MATRIX.md:uni API 替换矩阵。docs/FEATURE_MIGRATION_CHECKLIST.md:业务功能迁移验收清单。
完成这三份清单后,再开始搭建 web/ 工程,能最大限度减少遗漏。