跳到主要内容

Swee-Mobile PWA

Swee Mobile 是 Swee AI 社交娱乐平台的核心移动端 Web 应用,基于 Next.js 13 + PWA 构建。作为平台最复杂的前端应用,集成了 AI 伴侣聊天、环信即时通讯(Easemob IM)、好感度/亲密度系统、特权等级、直播互动、语音克隆、数字人创作等核心功能,是一款将 AI 生成内容与社交娱乐深度融合的移动优先应用。


一、项目技术架构

1.1 整体架构图

1.2 核心技术栈

领域技术选型版本
框架Next.js (Pages Router)13.4.1
UI 库React + Ant Design Mobile18.x / 5.37.1
PWAnext-pwa5.6.0
状态管理Zustand5.0.3
即时通讯Easemob WebSDK (MiniCore)4.13.0
动画Framer Motion11.3.30
轮播Swiper11.0.5
国际化next-i18next + i18next15.3.1 / 23.16.5
二进制协议protobufjs7.2.3
样式Tailwind CSS + SCSS3.4.10
错误监控Sentry7.105.0
日志Pino8.11.0
调试VConsole3.15.1

二、PWA 与移动端适配

2.1 PWA 配置

关键配置
  • 自动注册register: true
  • 即时更新skipWaiting: true,新版本立即激活
  • 开发禁用disable: process.env.NODE_ENV === 'development'
  • 深色主题theme_color: "#101010" / background_color: "#101010"

2.2 移动端视口适配

页面 viewport 配置
<!-- 固定 375px 宽度(iPhone 标准) -->
<meta name="viewport" content="width=375, user-scalable=no, viewport-fit=cover" />
固定宽度策略

固定 375px 宽度是一种取舍方案:虽然保证了跨设备视觉一致性,但在大屏设备上会出现两侧留白。这种方案适合移动优先且嵌入 WebView 的场景,不建议用于需要适配平板/桌面端的项目。

  • 固定宽度 375px:保证所有设备上一致的视觉效果
  • 禁止缩放user-scalable=no 避免双击放大
  • 刘海屏适配viewport-fit=cover + SafeArea 组件

三、AI 伴侣聊天系统

3.1 聊天架构

3.2 消息类型支持

消息类型说明处理方式
txt文本消息直接渲染文本内容
custom自定义事件解析 customEvent 类型
welcome_event欢迎消息特殊 UI 展示

3.3 消息转换管线

utils/transformMessages.ts
const transformMessages = ({
messages, // Easemob 原始消息列表
userId, // 当前用户 ID
currentUserInfo, // 当前用户信息
assistantUserInfo, // AI 伴侣信息
}) => {
return messages.map(msg => ({
role: msg.from === userId ? 'user' : 'assistant',
content: msg.type === 'txt' ? msg.msg : parseCustomEvent(msg),
// 统一为 ChatDialog 组件消费的格式
}));
}

四、Easemob IM 即时通讯

4.1 IM 架构设计

4.2 关键实现细节

架构决策:MiniCore 模式

Easemob SDK 提供完整版和 MiniCore 两种模式。项目选择 MiniCore + 按需插件的方式,相比完整版 SDK 显著减小了初始包体积,只加载实际使用的 Contact 和 LocalCache 功能。

初始化流程

  1. 动态导入 easemob-websdk/miniCore(减小初始包体积)
  2. 注册 Contact + LocalCache 插件
  3. 从后端获取 IM Token:getUserToken() API
  4. 调用 miniCore.open() 建立连接
  5. 注册连接状态事件监听

用户信息缓存策略

store/easemobStore.ts
// Zustand Store - 避免重复请求
const fetchUserInfoByIdInStore = async (userId: string | string[]) => {
if (Array.isArray(userId)) {
// 批量获取:过滤已缓存的,只请求未缓存的
const unFetchInfoList = userId.filter(uid => !userInfoMap.get(uid));
const res = await miniCore.contact.fetchUserInfoById(unFetchInfoList);
// 缓存到 store
} else {
// 单个获取:先查缓存
const cached = userInfoMap.get(userId);
if (cached) return cached;
}
};

五、好感度/亲密度系统

5.1 亲密度等级架构

5.2 权益系统

等级指南配置

等级指南类型说明
1Interaction Guide基础互动教程
2Occasional Event偶遇事件触发
3Real Connection真实情感连接
4Task Guide任务系统引导

5.3 UI 组件体系

组件功能路径
BenefitBar亲密度进度条components/BenefitBar/
BenefitProgress亲密度信息卡components/BenefitProgress/
BenefitInfo权益详情展示components/BenefitInfo/
IntimacyLevel等级图标@swee/uikit

六、直播与音视频

6.1 直播 API 体系

6.2 语音克隆系统

FormData 文件上传:支持 File 对象 + JSON 参数混合提交


七、页面转场动画

7.1 Framer Motion 页面过渡

components/PageTransition.tsx
<AnimatePresence mode="wait">
<motion.div
key={router.route}
initial={{ opacity: 0, x: 300 }} // 从右侧滑入
animate={{ opacity: 1, x: 0 }} // 显示
exit={{ opacity: 0, x: -300 }} // 向左侧滑出
transition={{ duration: 0.3 }} // 300ms
/>
</AnimatePresence>

7.2 自定义动画效果

tailwind.config.ts
// Tailwind 自定义 shake 动画
keyframes: {
shake: {
'0%': { transform: 'scale(0.8) rotate(10deg)' },
'25%': { transform: 'scale(1) rotate(0deg)' },
'50%': { transform: 'scale(0.95) rotate(-10deg)' },
'75%': { transform: 'scale(0.9) rotate(10deg)' },
'100%': { transform: 'scale(0.8) rotate(10deg)' },
},
}
// 使用: animate-[shake_1.1s_ease-in-out_infinite]

八、API 服务层

8.1 API 模块分布

8.2 关键 API 模块

模块文件数核心功能
im/26聊天消息、偶遇剧情、用户 Token、声音管理
model/19AI 模型管理、数字人、语音克隆、KOL 入驻
live/16直播管理、房间查询、关注系统、认证令牌
user/17登录认证、个人信息、支付密码、Web3
recommend/8直播推荐流、AI 恋人推荐
interact/7好感度查询、权益管理

8.3 类型定义规模

模块类型文件大小
im/typings.d.ts33 KB
model/typings.d.ts33 KB
live/typings.d.ts22 KB
总计~100 KB

九、状态管理设计

9.1 混合状态管理方案

9.2 Zustand 设计原则

最小化 Store 原则

Zustand Store 只存储需要跨组件共享且需要缓存的数据(如 IM 用户信息)。API 请求数据交给 useRequest 管理,组件内部状态使用 useState,避免全局状态过度膨胀。

store/easemobStore.ts
// 最小化 Store - 只存储需要跨组件共享且需要缓存的数据
export const useEasemobStore = create<EasemobStore>((set) => ({
userInfoMap: new Map<string, UpdateOwnUserInfoParams>(),
setUserInfoMap: (userId, userInfo) =>
set(({ userInfoMap }) => ({
userInfoMap: new Map(userInfoMap).set(userId, userInfo),
})),
}));

十、部署与环境

10.1 多环境配置

环境端口APP_ENV域名
开发3110developmentlocalhost
测试-testtest.swee.live
生产3111 / 16666(Docker)productionswee.live

10.2 Docker 部署


十一、技术亮点总结

11.1 AI 伴侣聊天系统

  • Easemob MiniCore:轻量级 IM SDK,按需加载插件,减小包体积
  • 消息转换管线:统一格式转换,支持文本、自定义事件、欢迎消息
  • 用户信息缓存:Zustand + Map 结构,批量获取 + 按需请求

11.2 PWA 离线优先

  • Service Worker:自动注册、即时更新
  • 可安装应用:完整的 manifest 配置,支持 Add to Home Screen
  • 深色主题:原生应用级别的视觉体验

11.3 流畅的页面转场

  • Framer Motion:AnimatePresence + motion.div 实现页面级动画
  • 滑动效果:进入(从右滑入)→ 退出(向左滑出)仿原生体验
  • 自定义动画:Tailwind keyframes 实现 shake 等特效

11.4 亲密度情感引擎

  • 5 级亲密度系统:从初识到灵魂伴侣的完整情感递进
  • 权益解锁机制:每个等级对应特定功能权益
  • 等级指南:互动引导用户提升亲密度

11.5 移动端深度适配

  • 375px 固定宽度:保证跨设备视觉一致性
  • 刘海屏适配:viewport-fit=cover + SafeArea 组件
  • 禁止缩放:原生应用级交互体验

11.6 性能优化策略

核心性能优化成果

通过动态导入、ISR、长缓存和精确状态订阅等组合策略,在移动端弱网环境下也能保证流畅的用户体验。

  • 动态导入next/dynamic 懒加载大组件(Inbox 等)
  • ISR 模式fallback: 'blocking' 增量静态再生
  • 图片长缓存:1 年 immutable 缓存策略
  • Zustand 选择器:精确订阅避免不必要重渲染

11.7 语音克隆创作

  • 支持朗读内容列表获取
  • FormData 混合上传(File + JSON 参数)
  • 个人声音库管理

十二、项目数据概览

指标数据
页面路由9 个
视图组件8 个
可复用组件11+
API 文件94+
类型定义~100 KB
Zustand Store1 个
支持语言3 种(en-US / zh-TW / id-ID)
AI API 模块model(19) + im(26) = 45 个
PWA 图标192x192 / 512x512
页面转场动画300ms 滑动过渡