docs: add mine view dynamic data design spec
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
# 个人中心页面动态数据修复设计文档
|
||||
|
||||
## 问题描述
|
||||
|
||||
小程序"我的"(个人中心)页面(`MineView.vue`)当前显示的是写死的固定信息,而非当前登录用户的实际数据:
|
||||
|
||||
- 头像区域显示纯 CSS 绘制的通用人形图标,未使用用户头像
|
||||
- 昵称 fallback 为固定值 `'张义明'`
|
||||
- 身份标签 fallback 为固定值 `'ENFJ · 狮子座 · 星民'`
|
||||
- 统计数据 `觉醒深度 Lv.4` 和 `星历契合 98%` 为硬编码
|
||||
|
||||
## 方案概述
|
||||
|
||||
采用**方案 A**:从现有 store 数据动态生成头像和统计,替换所有写死内容。仅修改 `MineView.vue`,无后端改动。
|
||||
|
||||
## 具体改动
|
||||
|
||||
### 1. `mini-program/src/pages/main/MineView.vue`
|
||||
|
||||
#### 头像区域
|
||||
|
||||
用 `<image>` 组件替换 CSS 人形图标(`.person-head` 和 `.person-body`)。
|
||||
|
||||
新增 `avatarUrl` computed:
|
||||
```javascript
|
||||
const avatarUrl = computed(() => {
|
||||
const seed = profile.value.nickname || 'user'
|
||||
return `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(seed)}&backgroundColor=b982ff`
|
||||
})
|
||||
```
|
||||
|
||||
模板中:
|
||||
```html
|
||||
<image class="avatar-img" :src="avatarUrl" mode="aspectFill" />
|
||||
```
|
||||
|
||||
保留原有 `.avatar-circle` 的圆形边框和发光效果。
|
||||
|
||||
#### 昵称与身份标签
|
||||
|
||||
- `displayName` 的 fallback 从 `'张义明'` 改为 `'未设置昵称'`
|
||||
- `metaLine`:当 `mbti`、`zodiac`、`profession` 均为空时显示 `'点击设置个人档案'`;否则按 `${mbti} · ${zodiac} · ${identity}` 拼接
|
||||
|
||||
#### 统计数据
|
||||
|
||||
**觉醒深度**:基于 `store.events.length` 映射等级:
|
||||
| 事件数量 | 等级 |
|
||||
|---------|------|
|
||||
| 0 | Lv.1 |
|
||||
| 1-2 | Lv.2 |
|
||||
| 3-5 | Lv.3 |
|
||||
| 6-9 | Lv.4 |
|
||||
| 10+ | Lv.5 |
|
||||
|
||||
```javascript
|
||||
const awakenLevel = computed(() => {
|
||||
const count = store.events?.length || 0
|
||||
if (count >= 10) return 'Lv.5'
|
||||
if (count >= 6) return 'Lv.4'
|
||||
if (count >= 3) return 'Lv.3'
|
||||
if (count >= 1) return 'Lv.2'
|
||||
return 'Lv.1'
|
||||
})
|
||||
```
|
||||
|
||||
**星历契合**:基于资料完整度计算百分比。检查字段:`nickname`、`gender`、`zodiac`、`mbti`、`profession`、`hobbies`(数组有长度计 1 分)、以及人生经历是否填写(`childhood.text`、`joy.text`、`low.text`、`future.ideal` 任一非空计 1 分)。满分 7 分。
|
||||
|
||||
```javascript
|
||||
const harmonyPercent = computed(() => {
|
||||
const hasLifeStory = profile.value.childhood?.text ||
|
||||
profile.value.joy?.text ||
|
||||
profile.value.low?.text ||
|
||||
profile.value.future?.ideal
|
||||
const fields = [
|
||||
profile.value.nickname,
|
||||
profile.value.gender,
|
||||
profile.value.zodiac,
|
||||
profile.value.mbti,
|
||||
profile.value.profession,
|
||||
profile.value.hobbies?.length,
|
||||
hasLifeStory
|
||||
]
|
||||
const filled = fields.filter(Boolean).length
|
||||
return Math.round((filled / 7) * 100) + '%'
|
||||
})
|
||||
```
|
||||
|
||||
模板中将硬编码的 `Lv.4` 和 `98%` 分别替换为 `{{ awakenLevel }}` 和 `{{ harmonyPercent }}`。
|
||||
|
||||
## 数据依赖
|
||||
|
||||
`MineView.vue` 通过 `useAppStore()` 访问 store。`main/index.vue` 在 `onMounted` 中已经调用了:
|
||||
- `store.fetchUserProfile()`
|
||||
- `store.fetchEvents()`
|
||||
|
||||
因此 `MineView.vue` 无需新增数据加载逻辑,可直接读取 `store.userProfile` 和 `store.events`。
|
||||
|
||||
## 未修改内容
|
||||
|
||||
- `stores/app.js` 不做修改
|
||||
- `services/userProfile.js` 不做修改
|
||||
- `onboarding/index.vue` 不做修改
|
||||
- 页面样式(`.profile-center`、`.stats-grid` 等)保持原样
|
||||
|
||||
## 测试验证
|
||||
|
||||
1. 有完整资料的用户进入"我的"页面,显示 Dicebear 生成头像、真实昵称、MBTI/星座/职业、根据事件数计算的觉醒深度、根据资料完整度计算的星历契合百分比
|
||||
2. 新用户(无资料)进入"我的"页面,显示默认头像、`未设置昵称`、`点击设置个人档案`、觉醒深度 Lv.1、星历契合 0%
|
||||
3. 点击"个人档案设置"仍能正常跳转到 onboarding 编辑资料页
|
||||
4. 编辑资料保存后返回"我的"页面,数据已更新
|
||||
Reference in New Issue
Block a user