From a6dcc0843d6535564051747c73ca83bc6ea33238 Mon Sep 17 00:00:00 2001 From: Peanut Date: Thu, 4 Jun 2026 00:34:05 +0800 Subject: [PATCH] docs: add mine view dynamic data design spec --- ...026-06-03-mine-view-dynamic-data-design.md | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-03-mine-view-dynamic-data-design.md diff --git a/docs/superpowers/specs/2026-06-03-mine-view-dynamic-data-design.md b/docs/superpowers/specs/2026-06-03-mine-view-dynamic-data-design.md new file mode 100644 index 0000000..6f3b85d --- /dev/null +++ b/docs/superpowers/specs/2026-06-03-mine-view-dynamic-data-design.md @@ -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` + +#### 头像区域 + +用 `` 组件替换 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 + +``` + +保留原有 `.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. 编辑资料保存后返回"我的"页面,数据已更新