Files
cpzs-frontend/头像上传功能实现说明.md

242 lines
5.7 KiB
Markdown
Raw Permalink 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.

# 头像上传功能实现说明
## 完成时间
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
<div class="avatar-preview" :class="{ 'uploading': uploadingAvatar }">
<img v-if="editForm.userAvatar" :src="editForm.userAvatar" alt="头像" />
<div v-else class="avatar-placeholder">{{ editForm.userName ? editForm.userName.charAt(0) : 'U' }}</div>
<div v-if="uploadingAvatar" class="upload-overlay">
<div class="upload-spinner"></div>
</div>
</div>
```
#### 4.2 上传按钮
添加了禁用状态和文字变化:
```vue
<button class="upload-btn" @click="triggerFileUpload" :disabled="uploadingAvatar">
<svg viewBox="0 0 24 24" class="camera-icon">
<!-- SVG路径 -->
</svg>
{{ uploadingAvatar ? '上传中...' : '更换头像' }}
</button>
```
#### 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. 建议在生产环境中添加图片压缩功能