Files
soul-yongping/开发文档/8、部署/小程序头像上传优化说明.md

346 lines
7.2 KiB
Markdown
Raw Normal View History

# 小程序头像上传优化说明
## 🔧 问题描述
**旧逻辑**
- 小程序换头像时直接保存微信临时图片路径
- 临时路径会过期,导致头像无法显示
- 数据库存储的是微信的临时URL
**问题**
- ❌ 微信临时图片有效期有限(通常几天后失效)
- ❌ 头像无法长期显示
- ❌ 用户体验差
---
## ✅ 解决方案
**新逻辑**
1. 用户选择头像后,先上传图片到自己的服务器
2. 服务器保存图片到 `public/assets/avatars/` 目录
3. 返回永久可访问的URL
4. 将永久URL保存到数据库
**优势**
- ✅ 图片永久保存在自己服务器
- ✅ 头像不会失效
- ✅ 完全可控
---
## 🔧 修改的文件
### 1. `miniprogram/pages/my/my.js`
**修改函数**: `onChooseAvatar()`
**旧逻辑**
```javascript
// 直接使用临时路径
const avatarUrl = e.detail.avatarUrl
userInfo.avatar = avatarUrl
// 保存临时路径到数据库
await app.request('/api/user/update', {
data: { userId: userInfo.id, avatar: avatarUrl }
})
```
**新逻辑**
```javascript
// 1. 上传到服务器
const uploadRes = await wx.uploadFile({
url: app.globalData.baseUrl + '/api/upload',
filePath: tempAvatarUrl,
name: 'file',
formData: { folder: 'avatars' }
})
// 2. 获取永久URL
const avatarUrl = app.globalData.baseUrl + uploadRes.data.url
// 3. 保存永久URL到数据库
await app.request('/api/user/update', {
data: { userId: userInfo.id, avatar: avatarUrl }
})
```
---
### 2. `miniprogram/pages/settings/settings.js`
**修改函数**: `getWechatAvatar()`
**功能**: 使用 `wx.getUserProfile` 获取微信头像
**修改内容**: 与 `my.js` 相同先上传图片再保存URL
---
## 📁 服务器存储路径
### 图片保存位置
```
public/assets/avatars/
├── 1738756123456_abc123.jpg
├── 1738756234567_def456.png
└── ...
```
### 访问URL格式
```
https://soul.quwanzhi.com/assets/avatars/1738756123456_abc123.jpg
```
### 数据库存储
```javascript
// users 表
{
id: "user_123",
avatar: "https://soul.quwanzhi.com/assets/avatars/1738756123456_abc123.jpg"
}
```
---
## 🔄 上传流程
### 完整流程图
```
用户点击更换头像
微信弹出头像选择器chooseAvatar / getUserProfile
获取临时图片路径tempAvatarUrl
调用 wx.uploadFile 上传到服务器
服务器保存图片到 public/assets/avatars/
服务器返回永久URL
更新本地 userInfoapp.globalData / storage
调用 /api/user/update 保存到数据库
完成!
```
### 代码实现
```javascript
// 1. 获取临时头像
const tempAvatarUrl = e.detail.avatarUrl
// 2. 上传到服务器
const uploadRes = await new Promise((resolve, reject) => {
wx.uploadFile({
url: app.globalData.baseUrl + '/api/upload',
filePath: tempAvatarUrl,
name: 'file',
formData: {
folder: 'avatars' // 保存到 avatars 文件夹
},
success: (res) => {
const data = JSON.parse(res.data)
if (data.success) {
resolve(data) // { success: true, data: { url: '/assets/avatars/xxx.jpg' } }
} else {
reject(new Error(data.error))
}
},
fail: reject
})
})
// 3. 拼接完整URL
const avatarUrl = app.globalData.baseUrl + uploadRes.data.url
// 结果: https://soul.quwanzhi.com/assets/avatars/xxx.jpg
// 4. 保存到数据库
await app.request('/api/user/update', {
method: 'POST',
data: { userId: userInfo.id, avatar: avatarUrl }
})
```
---
## 🔍 错误处理
### 1. 上传失败
```javascript
try {
// ... 上传逻辑
} catch (e) {
wx.showToast({
title: e.message || '上传失败,请重试',
icon: 'none'
})
}
```
### 2. 网络错误
- 自动重试机制(可选)
- 清晰的错误提示
### 3. 文件格式错误
- 服务器会验证文件类型
- 只允许 JPG、PNG、GIF、WebP、SVG
- 文件大小限制 5MB
---
## 📊 服务器API
### `/api/upload` - 图片上传接口
**请求方式**: POST (multipart/form-data)
**参数**:
- `file`: 图片文件
- `folder`: 保存文件夹(如 'avatars'
**返回**:
```json
{
"success": true,
"data": {
"url": "/assets/avatars/1738756123456_abc123.jpg",
"fileName": "1738756123456_abc123.jpg",
"size": 45678,
"type": "image/jpeg"
}
}
```
**文件命名规则**:
```javascript
const timestamp = Date.now()
const randomStr = Math.random().toString(36).substring(2, 8)
const fileName = `${timestamp}_${randomStr}.${ext}`
// 例如: 1738756123456_abc123.jpg
```
---
## ✅ 测试清单
### 功能测试
- [ ] 在"我的"页面点击头像,选择图片后成功上传
- [ ] 上传后头像立即显示
- [ ] 刷新页面后头像依然正常显示
- [ ] 在设置页面使用"获取微信头像"功能正常
- [ ] 后台管理页面能正确显示用户头像
### 数据验证
- [ ] 数据库 `users.avatar` 字段保存的是完整URL
- [ ] URL格式: `https://soul.quwanzhi.com/assets/avatars/xxx.jpg`
- [ ] 不是微信临时路径(不包含 `weixin``tmp`
### 文件验证
- [ ] 服务器 `public/assets/avatars/` 目录存在
- [ ] 上传的图片文件正常保存
- [ ] 文件可通过浏览器直接访问
---
## 🚀 部署步骤
### 1. 确保目录存在
```bash
# 在服务器上创建目录
mkdir -p /www/wwwroot/soul.quwanzhi.com/public/assets/avatars
chmod 755 /www/wwwroot/soul.quwanzhi.com/public/assets/avatars
```
### 2. 部署代码
```bash
# 本地构建
pnpm build
# 部署到服务器
python devlop.py
# 重启PM2
pm2 restart soul
```
### 3. 小程序代码上传
- 在微信开发者工具中上传代码
- 提交审核
- 发布新版本
---
## 📝 注意事项
### 1. 兼容性
- 旧版本用户的头像可能还是微信临时路径
- 建议提示用户重新上传头像
### 2. 存储空间
- 每个头像约 50-200KB
- 10000个用户约 0.5-2GB
- 定期清理无用头像(可选)
### 3. CDN优化可选
- 如果用户量大考虑使用CDN加速
-`public/assets/avatars/` 目录同步到CDN
### 4. 图片压缩(可选)
- 可以在上传时自动压缩图片
- 减少存储空间和加载时间
---
## 🔄 数据迁移(可选)
如果需要迁移旧数据(微信临时路径 → 永久URL
### 方案1: 提示用户重新上传
```javascript
// 在小程序中检查头像URL
if (userInfo.avatar && userInfo.avatar.includes('weixin')) {
// 提示用户重新上传头像
wx.showModal({
title: '头像过期',
content: '请重新上传您的头像',
confirmText: '立即上传'
})
}
```
### 方案2: 自动下载并上传(服务器端)
```javascript
// 在服务器端批量处理
// 1. 查询所有微信临时路径的头像
// 2. 下载图片
// 3. 上传到自己服务器
// 4. 更新数据库
// (需要开发专门的迁移脚本)
```
---
## ✅ 完成状态
- ✅ 修改 `my.js``onChooseAvatar()` 函数
- ✅ 修改 `settings.js``getWechatAvatar()` 函数
- ✅ 使用现有的 `/api/upload` 接口
- ✅ 添加错误处理和日志
- ✅ 创建说明文档
---
## 📚 相关文档
- `后台订单显示优化说明.md` - 后台显示头像相关
- `/api/upload` 接口文档
---
**优化完成!小程序头像将永久保存在自己的服务器上,不会再失效!**