7.2 KiB
7.2 KiB
小程序头像上传优化说明
🔧 问题描述
旧逻辑:
- 小程序换头像时直接保存微信临时图片路径
- 临时路径会过期,导致头像无法显示
- 数据库存储的是微信的临时URL
问题:
- ❌ 微信临时图片有效期有限(通常几天后失效)
- ❌ 头像无法长期显示
- ❌ 用户体验差
✅ 解决方案
新逻辑:
- 用户选择头像后,先上传图片到自己的服务器
- 服务器保存图片到
public/assets/avatars/目录 - 返回永久可访问的URL
- 将永久URL保存到数据库
优势:
- ✅ 图片永久保存在自己服务器
- ✅ 头像不会失效
- ✅ 完全可控
🔧 修改的文件
1. miniprogram/pages/my/my.js
修改函数: onChooseAvatar()
旧逻辑:
// 直接使用临时路径
const avatarUrl = e.detail.avatarUrl
userInfo.avatar = avatarUrl
// 保存临时路径到数据库
await app.request('/api/user/update', {
data: { userId: userInfo.id, avatar: avatarUrl }
})
新逻辑:
// 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
数据库存储
// users 表
{
id: "user_123",
avatar: "https://soul.quwanzhi.com/assets/avatars/1738756123456_abc123.jpg"
}
🔄 上传流程
完整流程图
用户点击更换头像
↓
微信弹出头像选择器(chooseAvatar / getUserProfile)
↓
获取临时图片路径(tempAvatarUrl)
↓
调用 wx.uploadFile 上传到服务器
↓
服务器保存图片到 public/assets/avatars/
↓
服务器返回永久URL
↓
更新本地 userInfo(app.globalData / storage)
↓
调用 /api/user/update 保存到数据库
↓
完成!
代码实现
// 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. 上传失败
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')
返回:
{
"success": true,
"data": {
"url": "/assets/avatars/1738756123456_abc123.jpg",
"fileName": "1738756123456_abc123.jpg",
"size": 45678,
"type": "image/jpeg"
}
}
文件命名规则:
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. 确保目录存在
# 在服务器上创建目录
mkdir -p /www/wwwroot/soul.quwanzhi.com/public/assets/avatars
chmod 755 /www/wwwroot/soul.quwanzhi.com/public/assets/avatars
2. 部署代码
# 本地构建
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: 提示用户重新上传
// 在小程序中检查头像URL
if (userInfo.avatar && userInfo.avatar.includes('weixin')) {
// 提示用户重新上传头像
wx.showModal({
title: '头像过期',
content: '请重新上传您的头像',
confirmText: '立即上传'
})
}
方案2: 自动下载并上传(服务器端)
// 在服务器端批量处理
// 1. 查询所有微信临时路径的头像
// 2. 下载图片
// 3. 上传到自己服务器
// 4. 更新数据库
// (需要开发专门的迁移脚本)
✅ 完成状态
- ✅ 修改
my.js的onChooseAvatar()函数 - ✅ 修改
settings.js的getWechatAvatar()函数 - ✅ 使用现有的
/api/upload接口 - ✅ 添加错误处理和日志
- ✅ 创建说明文档
📚 相关文档
后台订单显示优化说明.md- 后台显示头像相关/api/upload接口文档
优化完成!小程序头像将永久保存在自己的服务器上,不会再失效!