AI 情绪陪伴助手:从 0 到 1 的 PWA + 跨端应用实战
一个基于 React + Vite + PWA 的 AI 情绪陪伴助手,支持人设自定义、AI 情绪分析、离线使用,并可打包为 Android APK。
一、项目概述
1.1 需求背景
在日常学习和工作中,人们经常面临压力和情绪波动。传统的日记或社交倾诉方式存在隐私顾虑和即时性不足的问题。本项目旨在构建一个AI 个性化情绪陪伴助手,用户可以选择不同的 AI 人设(温柔姐姐、理性导师、快乐伙伴等),向 AI 倾诉心情,获得即时、个性化的情绪分析与建议。
1.2 核心功能
| 功能模块 | 说明 |
|---|---|
| 人设系统 | 4 种预设人设 + 自定义人设管理,支持 AI 通过人物图片推导人设 |
| 情绪分析 | 接入火山方舟大模型,输入心情后 AI 返回情绪类型与个性化建议 |
| 历史记录 | 本地存储最近 30 条分析记录,支持单条删除和清空 |
| PWA 离线 | Service Worker 缓存,断网可用,支持安装到桌面 |
| 跨端打包 | Capacitor 生成 Android APK,一套代码多端运行 |
1.3 技术栈
| 层级 | 技术 |
|---|---|
| 前端框架 | React 18 + Vite 5 |
| 路由 | 原生状态管理(无路由库,单页面切换) |
| PWA | vite-plugin-pwa(Service Worker + Manifest) |
| 跨端 | Capacitor + Android Gradle |
| AI 接口 | 火山方舟 Responses API(兼容 OpenAI 协议) |
| 样式 | 纯 CSS,无 UI 框架 |
| 存储 | localStorage |
二、项目结构
csharp
ai-mood-companion/
├── public/
│ └── manifest.json # PWA 配置
├── src/
│ ├── assets/ # 静态资源占位
│ ├── components/
│ │ └── LoadingSpinner.jsx # 加载动画组件
│ ├── pages/
│ │ ├── PersonaSet.jsx # 人设设置页
│ │ └── Home.jsx # 情绪分析主页
│ ├── utils/
│ │ ├── storage.js # localStorage 封装
│ │ └── request.js # AI 接口封装
│ ├── App.jsx # 应用入口
│ └── main.jsx # 项目入口
├── index.html # 头部优化(OG/PWA/字体)
├── vite.config.js # Vite + PWA 配置
├── capacitor.config.json # 跨端配置
└── package.json
三、核心实现
3.1 前端工程规范
HTML 头部全优化
index.html 中必须包含完整的 SEO 和 PWA 相关标签:
meta description+theme-color+viewport-fit=cover- OG 标签 :
og:title、og:description、og:type - 苹果沉浸式 :
apple-mobile-web-app-capable、apple-mobile-web-app-status-bar-style - 字体非阻塞加载 :
preconnect+preload+media="print" onload技巧 - PWA Manifest :
<link rel="manifest">
资源 CDN 化
所有字体、图标均通过 CDN 加载,减少本地资源体积,提升首屏速度。
3.2 PWA 离线化
使用 vite-plugin-pwa 自动生成 Service Worker:
js
// vite.config.js
VitePWA({
registerType: 'autoUpdate',
manifest: false, // 使用独立的 public/manifest.json
workbox: {
globPatterns: ['**/*.{html,js,css,png,svg}'],
runtimeCaching: [{
urlPattern: /^https:\/\/fonts\.googleapis\.com/,
handler: 'CacheFirst'
}]
}
})
构建后自动生成 sw.js,离线状态下页面仍可正常打开。
3.3 AI 接口封装
接入火山方舟 Responses API ,统一封装在 src/utils/request.js 中:
情绪分析接口
js
export async function analyzeMood(content, persona) {
const response = await fetch('https://ark.cn-beijing.volces.com/api/v3/responses', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`,
},
body: JSON.stringify({
model: 'doubao-seed-2-0-lite-260215',
input: [
{
role: 'system',
content: [{ type: 'input_text', text: buildSystemPrompt(persona) }]
},
{
role: 'user',
content: [{ type: 'input_text', text: content }]
}
]
})
});
// 解析返回的 JSON:{ emotion, advice }
}
Prompt 工程:将用户设置的人设名称、语气、描述注入 system prompt,要求模型严格返回 JSON 格式,便于前端解析。
AI 看图推导人设
利用 Responses API 的多模态能力,上传人物图片让 AI 分析气质:
js
export async function analyzePersonaImage(imageBase64) {
// 发送图片 + prompt,让 AI 返回 {name, tone, description}
}
图片压缩:前端使用 Canvas 将图片压缩至 400px 宽度、JPEG 质量 70%,避免 localStorage 溢出。
3.4 本地存储统一管理
所有 localStorage 操作集中在 storage.js,避免分散:
js
const STORAGE_KEY = {
CUSTOM_PERSONAS: 'ai_mood_custom_personas',
ACTIVE_PERSONA: 'ai_mood_active_persona',
HISTORY: 'ai_mood_history'
};
- 人设:支持多个人设增删改查 + 当前激活人设
- 历史记录:最多保留 30 条,自动覆盖旧数据
3.5 多个人设管理
预设人设(只读)
代码中硬编码 4 种经典人设:温柔助手、理性导师、快乐伙伴、严格教练。
自定义人设(可增删改)
- 用户可自由输入名称、语气风格、描述
- 支持上传人物参考图,AI 自动推导人设参数
- 编辑时回填历史数据(包括参考图)
四、遇到的问题与解决方案
4.1 CORS 跨域
问题:前端直接请求方舟 API,浏览器可能拦截跨域请求。
方案:目前接口可正常访问。如后续出现 CORS 限制,建议增加简易后端代理层。
4.2 图片存储体积
问题:人物参考图以 base64 存入 localStorage,原图几 MB 容易撑满。
方案:使用 Canvas 前端压缩,400px 宽度 + JPEG 70% 质量,压缩后约 100KB。
4.3 Gradle 下载超时
问题:部分环境网络下载 Gradle 发行版极慢,构建 APK 超时。
方案:在自己电脑本地构建,网络更稳定;或配置国内 Gradle 镜像源。
五、如何运行
bash
# 1. 安装依赖
npm install
# 2. 配置 API Key(复制 .env.example 为 .env)
# VITE_ARK_API_KEY=your-key
# 3. 本地开发
npm run dev
# 4. 生产构建
npm run build
# 5. Android APK 打包
npx cap sync
cd android
.\gradlew.bat assembleDebug
六、总结
本项目从零搭建了一个完整的 PWA + 跨端应用,涵盖:
- ✅ 前端工程化(Vite + React + PWA)
- ✅ AI 大模型接入(火山方舟 Responses API)
- ✅ 多模态交互(文本 + 图片分析)
- ✅ 本地数据持久化(localStorage 统一封装)
- ✅ 跨端打包(Capacitor → Android APK)
整个项目代码量精简,功能聚焦,适合作为前端实习/校招的项目展示。
项目地址 :gitee.com/zhang-huair...