Files
huihuiSquare/uniapp-avatar

会会数字分身 · uniapp + H5 混合架构

移动端采用 uniapp 原生壳 + web-view 内嵌现有 H5 的混合模式,与会会主 App 一致。 业务页面(数字分身管理 / 知识库 / 对话等)继续用 digital-avatar-app(Vue3 SPA)开发并构建为 H5, 由本工程的 uniapp 壳通过 <web-view> 加载,原生侧只负责登录、会会资料、导航壳。


1. 整体架构

┌─────────────────────────────────────────────┐
│  会会 App(uniapp 原生壳)  uniapp-avatar/     │
│  ├─ 会会统一登录(token / userId / 资料)       │
│  ├─ 原生导航壳(自定义导航栏 / 可选 tabBar)     │
│  └─ <web-view :src="H5?token=...&userId=..."> │
└───────────────────────┬─────────────────────┘
                         │  web-view
                         ▼
┌─────────────────────────────────────────────┐
│  会会数字分身 H5   digital-avatar-app/         │
│  ├─ Vue3 + Vite SPA(构建产物即 H5)           │
│  ├─ 从 URL / window.__uniBridgeHandle__ 取认证 │
│  └─ 通过 uni.webView.postMessage 回传原生事件   │
└─────────────────────────────────────────────┘
                         │  HTTPS /api
                         ▼
                   FastAPI 后端(:8000)

职责边界

层 负责
uniapp 壳 会会登录与会话、注入 token/用户、原生导航与返回、可承载原生能力(推送/分享/支付)
H5 业务 全部数字分身业务 UI 与交互、调用后端 API、知识库/问答/对话
后端 业务数据与 AI 能力(维持不变)

2. 桥接协议(壳 ↔ H5)

2.1 握手(URL 注入,最可靠)

壳加载 web-view 时把认证与会会资料拼进 H5 地址的 query:

H5_BASE_URL/?token=<accessToken>&userId=<uid>&nickname=<urlencode>&avatar=<urlencode>&ts=<ms>

H5 在 main.ts 启动前用 getLaunchParams() 解析;nickname / avatar 需 encodeURIComponent。

2.2 H5 → 原生(uni.webView.postMessage)

H5 引入 uniapp web-view bridge 后调用:

type payload 含义
ready — H5 已完成首屏渲染
needLogin — token 失效,请求壳重新登录
setTitle title 设置原生导航栏标题
navigate path 请求原生跳转(打开原生页/新 web-view)
payment payment 拉起会会原生支付;包含 orderId/orderNo/payType/payWay/payMessage/paymentParams
back — 请求原生返回

2.3 原生 → H5(壳主动推送)

壳通过 web-view.evalJS 调用 H5 全局函数 window.__uniBridgeHandle__(message):

type payload 含义
context surface, version 注入运行环境;surface 为 app / mp-weixin / h5
tokenRefresh token 登录刷新后下发新 token
userUpdate user 会会资料变更
paymentResult orderId,status 原生支付结束通知;status 为 success/cancelled/failed

H5 侧用 onNativeMessage(cb) 注册 window.__uniBridgeHandle__,见 digital-avatar-app/src/utils/uniapp-bridge.ts。

壳收到 payment 后应调用会会 App 已有的微信/支付宝支付能力(或 uni.requestPayment),把 payMessage/paymentParams 原样交给对应渠道。原生 SDK 返回后再发送 paymentResult;H5 不以原生返回作为到账依据,只会轮询本地订单,最终由会会服务端支付回调确认并增加积分。

微信小程序虚拟支付本期只交付后端能力(登录态交换、签名下单参数、服务端查单/退款和回调验收)。小程序原生充值页接入 requestVirtualPayment 后,应把后端返回的 signData/paySig/signature/mode/env/offerId 原样传入微信 API;不要在 web-view 中发起虚拟支付。


3. 项目结构(uni CLI / src 布局,已验证可编译)

uniapp-avatar/
├── index.html              # H5 入口模板(项目根,uni h5 在此找入口)
├── vite.config.js          # 注册 @dcloudio/vite-plugin-uni(.vue 编译必须)
├── package.json
├── README.md
└── src/                    # 源码根(uni CLI 要求 manifest/pages 在此)
    ├── manifest.json       # 应用配置(名称/AppID/模块)
    ├── pages.json          # 页面路由
    ├── uni.scss            # 全局样式变量
    ├── App.vue             # 启动时恢复会会登录态(onLaunch → userStore.init)
    ├── main.js             # createSSRApp + pinia
    ├── pages/index/index.vue  # web-view 容器(内嵌 digital-avatar-app H5)
    ├── store/user.js       # 会会会话(宿主调用 applySession 注入并缓存)
    └── utils/
        ├── bridge.js       # H5 URL 构造 + 原生→H5 推送
        └── payment.js      # App 微信/支付宝原生支付适配

构建产物:npm run build:h5 → dist/build/h5/(含 index.html + assets)。

4. 运行与打包

方式一:HBuilderX(推荐,与生产一致)

  1. HBuilderX → 导入 uniapp-avatar/ 目录(已含 manifest.json/pages.json)。
  2. 顶部菜单「运行」→ 运行到手机/模拟器/浏览器(H5)。
  3. 修改 src/pages/index/index.vue 的 H5_BASE_URL 指向你的 H5 部署地址:
    • 本地联调用的局域网 IP + Vite 端口(如 http://192.168.1.100:5173),不要用 localhost。
    • 生产填 digital-avatar-app 构建后的 H5 线上域名。
  4. 打包:发行 → 原生 App(云打包/本地打包)。

方式二:CLI(dev:h5 本地自测,已验证通过)

cd uniapp-avatar
npm install            # 依赖版本已对齐本机 HBuilderX(3.0.0-4010520240507001)
npm run dev:h5         # 起 H5 版壳,web-view 会加载 H5_BASE_URL 指向的 H5
npm run build:h5       # 生产构建 → dist/build/h5/

若 npm 依赖版本与本地 HBuilderX 不一致,执行 npx @dcloudio/uvm 对齐。

会会登录接入

  • 壳只恢复会会宿主已经持有的登录态,不内置演示账号,也不会伪造会会 token。
  • 会会主 App 完成登录或刷新后调用 userStore.applySession({ token, userId, nickname, avatarUrl });数字分身 H5 会把一次性会会 token 换成本系统会话并立即从地址中清除。
  • 独立打开且没有宿主会话时,H5 会进入已有的短信登录流程。

4. H5 侧改动清单(digital-avatar-app)

  • 新增 src/utils/uniapp-bridge.ts:环境探测、参数解析、双向消息。
  • src/api/index.ts:baseURL 改为可配置(支持 web-view 内绝对地址)。
  • src/store/avatar.ts:优先采用壳传入的会会资料;新增 setNativeProfile。
  • src/main.ts:挂载前注入 token/用户,注册原生消息处理,渲染后发 ready。
  • src/router/index.ts:改用 createWebHashHistory()(web-view 下返回键更稳)。
  • index.html:引入 uniapp web-view bridge 脚本,注入 apiBase 配置。