Files
happy-life-star/docs/superpowers/plans/2026-06-15-profile-merge.md
T

12 KiB
Raw Blame History

个人信息组件合并 实现计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 将人生轨迹页面(RecordView)的个人信息展示区域完整合并到我的页面(MineView),取并集展示所有字段,RecordView 移除个人信息区域。

Architecture: MineView 保留现有宇宙星空风格和居中头像布局,在 stats-grid 下方新增「个人档案」信息区块,使用三栏网格展示所有个人信息字段。RecordView 完全移除 profile-card 区域及相关代码。

Tech Stack: Vue 3 Composition API, Taro/UniApp 小程序, SCSS scoped styles

设计文档: docs/superpowers/specs/2026-06-15-profile-merge-design.md


文件结构

操作 文件路径 职责
修改 mini-program/src/pages/main/MineView.vue 新增「个人档案」区块(computed + template + styles
修改 mini-program/src/pages/main/RecordView.vue 移除 profile-card 区域及相关代码

Task 1: MineView — 新增 computed 属性

Files:

  • Modify: mini-program/src/pages/main/MineView.vue:63-138

  • Step 1: 在 <script setup> 中新增字段 computed 属性

harmonyPercent computed 之后、openProfileSettings 方法之前,新增以下 computed:

const genderText = computed(() => {
  const map = { male: '男', female: '女', other: '其他' }
  return map[profile.value.gender] || null
})

const age = computed(() => {
  const birthday = profile.value.birthday
  if (!birthday) return null
  const birthYear = Number(String(birthday).slice(0, 4))
  if (!birthYear) return null
  return new Date().getFullYear() - birthYear
})

const hobbyText = computed(() => {
  const hobbies = profile.value.hobbies
  if (Array.isArray(hobbies) && hobbies.length) return hobbies.slice(0, 4).join(' · ')
  return null
})

const goEditProfile = () => {
  uni.navigateTo({ url: '/pages/onboarding/index?edit=1' })
}
  • Step 2: 提交
git add mini-program/src/pages/main/MineView.vue
git commit -m "featMineView 新增个人档案字段 computed 属性"

Task 2: MineView — 新增「个人档案」模板

Files:

  • Modify: mini-program/src/pages/main/MineView.vue:32-34

  • Step 1: 在 stats-grid 和 menu-list 之间插入个人档案区块

在第 32 行 </view>stats-grid 结束标签)之后、第 34 行 <view class="menu-list"> 之前,插入以下模板:

    <view class="profile-section" @click="goEditProfile">
      <view class="section-header">
        <text class="section-star"></text>
        <text class="section-title">个人档案</text>
      </view>

      <view class="profile-grid">
        <view class="grid-item">
          <text class="grid-icon"></text>
          <text class="grid-label">星座</text>
          <text class="grid-value">{{ profile.zodiac || '未设置' }}</text>
        </view>
        <view class="grid-item">
          <text class="grid-icon"></text>
          <text class="grid-label">MBTI</text>
          <text class="grid-value">{{ profile.mbti || '未设置' }}</text>
        </view>
        <view class="grid-item no-border">
          <text class="grid-icon"></text>
          <text class="grid-label">职业</text>
          <text class="grid-value">{{ profile.profession || '未设置' }}</text>
        </view>
      </view>

      <view class="profile-grid">
        <view class="grid-item">
          <text class="grid-icon">📍</text>
          <text class="grid-label">城市</text>
          <text class="grid-value">{{ profile.city || '未设置' }}</text>
        </view>
        <view class="grid-item">
          <text class="grid-icon">🏢</text>
          <text class="grid-label">行业</text>
          <text class="grid-value">{{ profile.industry || '未设置' }}</text>
        </view>
        <view class="grid-item no-border">
          <text class="grid-icon">🏗</text>
          <text class="grid-label">公司</text>
          <text class="grid-value">{{ profile.company || '未设置' }}</text>
        </view>
      </view>

      <view class="profile-grid">
        <view class="grid-item">
          <text class="grid-icon">🎂</text>
          <text class="grid-label">生日</text>
          <text class="grid-value">{{ profile.birthday ? String(profile.birthday).slice(5).replace('-', '.') : '未设置' }}</text>
        </view>
        <view class="grid-item">
          <text class="grid-icon"></text>
          <text class="grid-label">性别</text>
          <text class="grid-value">{{ genderText || '未设置' }}</text>
        </view>
        <view class="grid-item no-border">
          <text class="grid-icon"></text>
          <text class="grid-label">年龄</text>
          <text class="grid-value">{{ age ? age + '岁' : '未设置' }}</text>
        </view>
      </view>

      <view class="hobby-line">
        <text class="hobby-heart"></text>
        <text class="hobby-label">爱好</text>
        <text class="hobby-value">{{ hobbyText || '未设置' }}</text>
      </view>
    </view>
  • Step 2: 提交
git add mini-program/src/pages/main/MineView.vue
git commit -m "featMineView 新增个人档案区块模板"

Task 3: MineView — 新增「个人档案」样式

Files:

  • Modify: mini-program/src/pages/main/MineView.vue:141-435

  • Step 1: 在 <style scoped> 中新增个人档案区块样式

.stat-value 样式块之后、.menu-list 样式块之前,插入以下样式:

.profile-section {
  position: relative;
  z-index: 1;
  margin-top: 42rpx;
}

.section-header {
  display: flex;
  align-items: center;
  gap: 12rpx;
  margin-bottom: 28rpx;
}

.section-star {
  color: #ffd184;
  font-size: 28rpx;
}

.section-title {
  color: #fff;
  font-size: 40rpx;
  font-weight: 800;
}

.profile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-bottom: 24rpx;
}

.grid-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6rpx;
  padding-right: 16rpx;
  border-right: 1rpx solid rgba(180, 139, 255, 0.22);
}

.grid-item + .grid-item {
  padding-left: 16rpx;
}

.grid-item.no-border {
  border-right: 0;
}

.grid-icon {
  font-size: 30rpx;
  line-height: 1;
  margin-bottom: 4rpx;
}

.grid-label {
  color: rgba(219, 204, 247, 0.54);
  font-size: 20rpx;
}

.grid-value {
  color: #fff;
  font-size: 23rpx;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.hobby-line {
  display: flex;
  align-items: center;
  gap: 16rpx;
  padding-top: 20rpx;
  border-top: 1rpx solid rgba(180, 139, 255, 0.22);
}

.hobby-heart {
  color: #a855ff;
  font-size: 30rpx;
  text-shadow: 0 0 24rpx rgba(168, 85, 255, 0.7);
}

.hobby-label {
  color: rgba(219, 204, 247, 0.54);
  font-size: 20rpx;
  flex-shrink: 0;
}

.hobby-value {
  color: #fff;
  font-size: 23rpx;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
  • Step 2: 提交
git add mini-program/src/pages/main/MineView.vue
git commit -m "featMineView 新增个人档案区块样式"

Task 4: RecordView — 移除 profile-card 模板

Files:

  • Modify: mini-program/src/pages/main/RecordView.vue:1-59

  • Step 1: 移除 profile-card 区域的模板代码

将模板中的第 3-59 行(从 <view class="profile-card kos-card"> 到其闭合 </view>)完全删除。

删除后,模板应从 <view class="record-view"> 直接开始,紧接 <view class="section-head">

修改后的模板开头应为:

<template>
  <view class="record-view">
    <view class="section-head">
      <view>
        <view class="title-line">
          <text class="section-title">人生轨迹</text>
          <text class="star gold"></text>
        </view>
        <text class="section-subtitle">你的成长之路,正在展开</text>
      </view>
      <view class="social-import-btn" @click="openSocialImport">
        <text>导入社交数据</text>
      </view>
    </view>

    <scroll-view class="filters" scroll-x :show-scrollbar="false">
      ...(后续保持不变)
  • Step 2: 提交
git add mini-program/src/pages/main/RecordView.vue
git commit -m "featRecordView 移除 profile-card 模板"

Task 5: RecordView — 移除相关 script 代码

Files:

  • Modify: mini-program/src/pages/main/RecordView.vue:126-247

  • Step 1: 移除不再需要的 computed 和方法

<script setup> 中删除以下内容:

  1. 删除 profile computed(约第 143 行):
const profile = computed(() => store.userProfile || store.registrationData || {})
  1. 删除 heroTags computed(约第 145-149 行):
const heroTags = computed(() => {
  const hobbies = profile.value.hobbies
  if (Array.isArray(hobbies) && hobbies.length) return hobbies.slice(0, 4)
  return []
})
  1. 删除 avatar computed(约第 151-154 行):
const avatar = computed(() => {
  const nickname = profile.value.nickname || 'User'
  return `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(nickname)}&backgroundColor=b982ff`
})
  1. 删除 editProfile 方法(约第 223-225 行):
const editProfile = () => {
  uni.navigateTo({ url: '/pages/onboarding/index?edit=1' })
}
  1. getAgeText 方法中仍使用 profile.value.birthYear,需要保留 profile computed 或改为直接引用。由于 getAgeText 仍需要 profile 数据,保留 profile computed,只删除 heroTagsavatareditProfile
  • Step 2: 提交
git add mini-program/src/pages/main/RecordView.vue
git commit -m "featRecordView 移除无用的 computed 和方法"

Task 6: RecordView — 移除相关样式

Files:

  • Modify: mini-program/src/pages/main/RecordView.vue:249-784

  • Step 1: 移除 profile-card 相关的所有样式

删除以下样式规则:

  • .profile-card 及其 ::after 伪元素
  • .profile-top, .avatar-wrap, .avatar, .avatar-edit, .edit-pen, .tiny-pen
  • .profile-info, .name-row, .profile-name, .star(注意:.star 在 section-head 中也有使用,只删除 profile 相关的,保留 .star.gold
  • .profile-subtitle, .edit-profile
  • .profile-divider, .profile-divider.small
  • .meta-grid, .meta-item, .meta-icon, .meta-label, .meta-value
  • .person-icon, .job-icon 及其伪元素
  • .hobby-row, .hobby-text
  • .heart

保留的样式(不要删除):

  • .record-view

  • .section-head, .title-line, .section-title, .gold, .section-subtitle

  • .social-import-btn

  • .filters, .filter-row, .filter-chip, .add-filter

  • .timeline 及所有子样式

  • .event-card 及所有子样式

  • .empty-card, .empty-title, .empty-text

  • .create-fab, .plus-core

  • .star.goldsection-head 中使用)

  • Step 2: 提交

git add mini-program/src/pages/main/RecordView.vue
git commit -m "featRecordView 移除 profile-card 相关样式"

Task 7: 浏览器验证

  • Step 1: 启动 H5 开发服务器
cd mini-program
npm run dev:h5
  • Step 2: 验证 MineView(我的页面)

打开浏览器访问 http://localhost:5173,切换到「我的」tab

检查项:

  • 头像和昵称正常显示

  • 觉醒深度和星历契合正常显示

  • 「个人档案」区块正常显示,包含:

    • 星座、MBTI、职业三栏
    • 城市、行业、公司三栏
    • 生日、性别、年龄三栏
    • 爱好行
  • 未设置的字段显示"未设置"

  • 点击「个人档案」区块可跳转到编辑页

  • 菜单列表和退出按钮正常

  • 整体星空风格无变化

  • Step 3: 验证 RecordView(人生轨迹页面)

切换到「人生轨迹」tab

检查项:

  • 个人信息卡片已完全移除

  • "人生轨迹"标题和"导入社交数据"按钮正常

  • 筛选器正常

  • 事件时间线正常显示

  • 创建 FAB 按钮正常

  • 页面无 Console 报错

  • Step 4: 最终提交

git add .
git commit -m "feat:完成个人信息组件合并,RecordView 移除个人信息区域,MineView 新增完整个人档案区块"