163 lines
5.4 KiB
Markdown
163 lines
5.4 KiB
Markdown
# Profile 页面 State 绑定更新文档
|
||
|
||
## 📋 更新概述
|
||
|
||
已将 `pages/sport/student/profile.uvue` 页面的用户信息与全局 `state.userProfile` 绑定,实现了数据的统一管理和同步。
|
||
|
||
## 🔧 主要修改
|
||
|
||
### 1. 导入 Store 模块
|
||
```typescript
|
||
import { state, setUserProfile } from '@/utils/store.uts'
|
||
```
|
||
|
||
### 2. 更新用户信息获取逻辑
|
||
|
||
#### `getUserName()` 函数
|
||
- **优先级**:`state.userProfile.username` > `userInfo.value.username` > 默认值
|
||
- **改进**:优先从全局状态获取用户名,确保数据一致性
|
||
|
||
#### `getUserId()` 函数
|
||
- **优先级**:`state.userProfile.id` > `userInfo.value.id` > 默认值
|
||
- **改进**:统一使用 `state.userProfile.id`,而不是 `student_id` 字段
|
||
|
||
#### `getCurrentUserId()` 函数
|
||
- **优先级**:`state.userProfile.id` > `supaClient.getSession()` > 本地存储
|
||
- **改进**:增加了对全局状态的检查,提高获取用户ID的可靠性
|
||
|
||
### 3. 用户资料加载策略
|
||
|
||
#### `loadUserProfile()` 函数重构
|
||
```typescript
|
||
const loadUserProfile = async () => {
|
||
// 1. 优先使用 state.userProfile 填充界面(快速显示)
|
||
if (state.userProfile && state.userProfile.id) {
|
||
userInfo.value = {
|
||
id: state.userProfile.id,
|
||
username: state.userProfile.username || '',
|
||
email: state.userProfile.email || '',
|
||
avatar_url: state.userProfile.avatar_url || '',
|
||
created_at: new Date().toISOString()
|
||
}
|
||
|
||
if (state.userProfile.avatar_url) {
|
||
userAvatar.value = state.userProfile.avatar_url
|
||
}
|
||
}
|
||
|
||
// 2. 从数据库获取最新数据并同步到 state
|
||
const result = await supaClient.from('ak_users')...
|
||
|
||
// 3. 更新全局状态
|
||
setUserProfile(updatedProfile)
|
||
}
|
||
```
|
||
|
||
**优势**:
|
||
- ✅ 快速显示:优先使用缓存的用户信息
|
||
- ✅ 数据同步:从数据库获取最新数据更新全局状态
|
||
- ✅ 一致性:确保界面和全局状态保持同步
|
||
|
||
### 4. 头像更新优化
|
||
|
||
#### `changeAvatar()` 函数增强
|
||
```typescript
|
||
const changeAvatar = () => {
|
||
uni.chooseImage({
|
||
success: async (res) => {
|
||
const tempFilePath = res.tempFilePaths[0]
|
||
userAvatar.value = tempFilePath
|
||
|
||
// 同步更新 state.userProfile
|
||
if (state.userProfile) {
|
||
const updatedProfile = { ...state.userProfile }
|
||
updatedProfile.avatar_url = tempFilePath
|
||
setUserProfile(updatedProfile)
|
||
}
|
||
|
||
// 更新数据库
|
||
await supaClient.from('ak_users')
|
||
.update({ avatar_url: tempFilePath })...
|
||
}
|
||
})
|
||
}
|
||
```
|
||
|
||
**改进**:
|
||
- ✅ 双向同步:同时更新界面、全局状态和数据库
|
||
- ✅ 即时反馈:立即更新界面显示
|
||
- ✅ 数据持久化:保存到数据库确保数据不丢失
|
||
|
||
### 5. 登出逻辑优化
|
||
|
||
#### `logout()` 函数增强
|
||
```typescript
|
||
const logout = () => {
|
||
uni.showModal({
|
||
success: async (res) => {
|
||
if (res.confirm) {
|
||
await supaClient.signOut()
|
||
|
||
// 清空全局状态
|
||
setUserProfile({ username: '', email: '' })
|
||
|
||
uni.reLaunch({ url: '/pages/index/index' })
|
||
}
|
||
}
|
||
})
|
||
}
|
||
```
|
||
|
||
**改进**:
|
||
- ✅ 状态清理:退出时清空全局用户状态
|
||
- ✅ 彻底登出:确保用户信息完全清除
|
||
|
||
## 🏗️ 数据流架构
|
||
|
||
```
|
||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||
│ 界面显示 │◄───│ state.userProfile │◄───│ 数据库 │
|
||
│ (profile.uvue) │ │ (全局状态) │ │ (ak_users) │
|
||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||
▲ ▲ ▲
|
||
│ │ │
|
||
│ ┌─────────────────────┼────────────────────────┘
|
||
│ │ │
|
||
│ │ 同步更新操作
|
||
│ │ (头像更新、资料修改等)
|
||
└──┼─────────────────────┘
|
||
│
|
||
快速界面渲染
|
||
(使用缓存的用户信息)
|
||
```
|
||
|
||
## ✅ 预期效果
|
||
|
||
1. **性能提升**:优先使用缓存数据,减少数据库查询延迟
|
||
2. **数据一致性**:统一的用户信息来源,避免数据不同步
|
||
3. **用户体验**:快速显示用户信息,后台同步最新数据
|
||
4. **状态管理**:标准化的全局状态使用模式
|
||
5. **扩展性**:为其他页面使用相同的用户信息提供基础
|
||
|
||
## 🔍 测试验证
|
||
|
||
建议测试以下场景:
|
||
- [ ] 页面首次加载用户信息显示
|
||
- [ ] 头像更新后的界面和状态同步
|
||
- [ ] 用户登出后状态清理
|
||
- [ ] 网络异常时的降级处理
|
||
- [ ] 多页面间用户信息的一致性
|
||
|
||
## 📝 注意事项
|
||
|
||
1. **类型安全**:保持 `UserProfile` 类型定义与数据库字段的一致性
|
||
2. **错误处理**:网络异常或数据库错误时的优雅降级
|
||
3. **缓存策略**:合理使用缓存,避免显示过期信息
|
||
4. **状态更新**:确保所有用户信息修改都同步到全局状态
|
||
|
||
---
|
||
|
||
**更新完成时间**:2025-06-12
|
||
**影响文件**:`pages/sport/student/profile.uvue`
|
||
**兼容性**:向后兼容,不影响现有功能
|