# 头像上传功能实现说明 ## 完成时间 2026-01-27 ## 功能概述 将Profile页面的头像上传功能从Base64编码改为调用后端文件上传接口,获取云存储URL。 ## 实现细节 ### 1. API接口配置 在 `lottery-app/src/api/index.js` 中已添加文件上传接口: ```javascript // 上传文件 uploadFile(file) { const formData = new FormData() formData.append('file', file) return api.post('/file/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) } ``` **接口地址**: `POST /api/file/upload` **请求格式**: `multipart/form-data` **响应格式**: ```json { "code": 0, "data": { "fileName": "a1b2c3d4-e5f6-7890-abcd-ef1234567890.jpg", "fileUrl": "https://yicaishuzhi-1326058838.cos.ap-beijing.myqcloud.com/a1b2c3d4-e5f6-7890-abcd-ef1234567890.jpg", "originalFilename": "avatar.jpg" }, "message": "ok" } ``` ### 2. 数据状态管理 在 `lottery-app/src/views/Profile.vue` 的 data 中添加了上传状态标志: ```javascript data() { return { // ... 其他属性 uploadingAvatar: false, // 新增:头像上传状态 // ... } } ``` ### 3. 头像上传方法实现 修改了 `handleAvatarChange` 方法: **主要改动**: - 从读取文件为Base64改为调用 `lotteryApi.uploadFile(file)` 接口 - 添加上传状态管理 (`uploadingAvatar`) - 从响应中获取 `fileUrl` 并设置到 `editForm.userAvatar` - 添加完整的错误处理和用户提示 - 清空文件输入框,允许重新选择同一文件 **代码实现**: ```javascript async handleAvatarChange(event) { const file = event.target.files[0] if (!file) return // 验证文件类型 if (!file.type.startsWith('image/')) { this.$toast.error('请选择图片文件') return } // 验证文件大小(限制2MB) if (file.size > 2 * 1024 * 1024) { this.$toast.error('图片大小不能超过2MB') return } this.uploadingAvatar = true try { // 显示上传提示 this.$toast.info('正在上传头像...') // 调用上传接口 const response = await lotteryApi.uploadFile(file) if (response.code === 0 && response.data && response.data.fileUrl) { // 上传成功,设置头像URL this.editForm.userAvatar = response.data.fileUrl this.$toast.success('头像上传成功!') } else { this.$toast.error(response.message || '头像上传失败') } } catch (error) { console.error('头像上传失败:', error) this.$toast.error('头像上传失败,请稍后重试') } finally { this.uploadingAvatar = false // 清空文件输入框,允许重新选择同一文件 event.target.value = '' } } ``` ### 4. UI交互优化 #### 4.1 头像预览区域 添加了上传中的遮罩层和加载动画: ```vue
头像
{{ editForm.userName ? editForm.userName.charAt(0) : 'U' }}
``` #### 4.2 上传按钮 添加了禁用状态和文字变化: ```vue ``` #### 4.3 CSS样式 添加了以下样式: ```css /* 禁用状态 */ .upload-btn:disabled { opacity: 0.6; cursor: not-allowed; background: #f5f5f5; border-color: #e0e6ed; color: #999; } /* 上传遮罩层 */ .upload-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; border-radius: 50%; } /* 加载动画 */ .upload-spinner { width: 24px; height: 24px; border: 3px solid rgba(255, 255, 255, 0.3); border-top-color: white; border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } ``` ## 功能特性 ### ✅ 已实现 1. **文件验证** - 验证文件类型(仅允许图片) - 验证文件大小(限制2MB) 2. **上传流程** - 调用后端上传接口 - 获取云存储URL - 更新头像预览 3. **用户反馈** - 上传中提示 - 上传成功提示 - 上传失败提示 - 按钮禁用状态 - 加载动画 4. **错误处理** - 网络错误处理 - 接口错误处理 - 文件验证错误处理 5. **用户体验** - 上传中显示遮罩和加载动画 - 按钮文字动态变化 - 清空文件输入框,允许重新选择 ## 测试建议 ### 1. 功能测试 - [ ] 选择图片文件,验证上传成功 - [ ] 选择非图片文件,验证错误提示 - [ ] 选择超过2MB的图片,验证错误提示 - [ ] 上传过程中验证按钮禁用 - [ ] 上传成功后验证头像更新 - [ ] 保存用户信息后验证头像持久化 ### 2. UI测试 - [ ] 验证上传中的遮罩层显示 - [ ] 验证加载动画正常运行 - [ ] 验证按钮文字变化 - [ ] 验证按钮禁用样式 ### 3. 错误场景测试 - [ ] 网络断开时上传 - [ ] 后端接口返回错误 - [ ] 上传超时处理 ## 相关文件 - `lottery-app/src/views/Profile.vue` - 主要实现文件 - `lottery-app/src/api/index.js` - API接口定义 ## 开发服务器 当前运行在: http://localhost:5174/ ## 注意事项 1. 确保后端 `/api/file/upload` 接口正常运行 2. 确保云存储服务配置正确 3. 上传的图片URL需要支持跨域访问 4. 建议在生产环境中添加图片压缩功能