Files
soul-yongping/开发文档/8、部署/小程序头像上传优化说明.md
2026-02-09 15:09:29 +08:00

346 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 小程序头像上传优化说明
## 🔧 问题描述
**旧逻辑**
- 小程序换头像时直接保存微信临时图片路径
- 临时路径会过期,导致头像无法显示
- 数据库存储的是微信的临时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` 接口文档
---
**优化完成!小程序头像将永久保存在自己的服务器上,不会再失效!**