日期: 2026-08-18
状态: pending(待用户审阅)
设计: specs/2026-08-18-homepage-health-funnel-design.md(方案 A,已确认)
目标文件: cfc-frontend/pages/index-home/index.vue
关联背景: specs/2026-07-22-active-health-six-stage-design.md(主动健康六阶模型 P0-P3 已交付)
设计文档 2026-08-18-homepage-health-funnel-design.md 写于 commit 07d897a1(全局移除 PageBanner)之后,但其中 ① 了解区仍引用 PageBanner theme="action"。当前代码已无 PageBanner,① 了解区只剩"自测大卡"一个元素,品牌头部不再渲染。本次实现先修正设计文档该处引用,再实现代码。
已有数据判定:设计文档建议数据源 getLatestHealthReport / getAssessmentLatestResult。实现时复用现有 sandboxData 状态判定(sandboxData 存在 ⟺ 已完五维自检,沙盘解锁),避免首页新增 2 个 API 调用(YAGNI)。综合得分展示 sandboxData.overallScore。如后续需要更细的报告摘要,可再接入报告接口。
docs/superpowers/specs/2026-08-18-homepage-health-funnel-design.md│ ① 了解区 │ 品牌头部 + 理念语 + 自测大卡 → │ ① 了解区 │ 自测大卡(品牌头部已由 07d897a1 全局移除)- **品牌头部**:保留 \PageBanner theme="action"`` 一行- **自测大卡(新增)**:置于品牌头部下方 → - **自测大卡(新增,首屏首个元素)**:已有数据判定复用首页已加载的 sandboxData(沙盘解锁即有自检数据),得分摘要取 sandboxData.overallScore,避免新增 API 调用docs(specs): 首页漏斗设计修正 — PageBanner 已全局移除,了解区仅自测卡cfc-frontend/pages/index-home/index.vue 第 54-200 行(<view v-if="currentRole" class="logged-in-container"> 整个容器)@action/@click/v-if/v-for 绑定全部不变。当前顺序 → 目标顺序:
| 目标区块 | 内容 | 来源 |
|---|---|---|
| ① 了解区 | 自测大卡(新增) | 新增 |
| ② 发现区 | GateLock/WuxingSandbox 能量沙盘 | 原第 2 位,原位保留 |
| ② 发现区 | ReportUploadCard 上传报告 | 原第 10 位,上移 |
| ③ 行动区 | JourneyCard 旅程卡 | 原第 1 位,下移 |
| ③ 行动区 | DailyTaskCard 今日任务 | 原第 9 位,上移 |
| ③ 行动区 | 我的任务(v-if hasPendingTasks) | 原第 6 位,原位 |
| ③ 行动区 | 家庭挑战(FamilyChallengeCard) | 原第 7 位,原位 |
| ③ 行动区 | 会员入口(v-if showMemberEntry) | 原第 4 位,下移 |
| ④ 内容区 | 快捷栏(quick-bar) | 原第 5 位,下移 |
| ④ 内容区 | FamilyFeed 家庭动态 | 原第 3 位,下移 |
| ④ 内容区 | 推荐阅读(ArticleBookshelf) | 原第 11 位,原位 |
| ④ 内容区 | 推荐商品(DimensionProducts) | 原第 12 位,原位(最底) |
| — | 底部占位 bottom-spacer | 原位 |
目标模板(整块替换,含新增自测卡):
<view v-if="currentRole" class="logged-in-container">
<!-- ① 了解区 — 自测大卡(首屏,引导"从了解开始") -->
<view class="self-test-card" @click="goSelfTest">
<view class="self-test-head">
<text class="self-test-icon">⚡</text>
<view class="self-test-info">
<text class="self-test-title">{{ selfTestTitle }}</text>
<text class="self-test-sub">{{ selfTestSub }}</text>
</view>
<text class="self-test-arrow">›</text>
</view>
</view>
<!-- ② 发现区 — 能量沙盘 — Canvas 五行星图(未测评时显示引导卡) -->
<GateLock v-if="sandboxLocked && sandboxLockGate" :gate="sandboxLockGate" />
<WuxingSandbox
v-else-if="sandboxData"
mode="live"
:scores="sandboxScores"
:overallScore="sandboxData.overallScore || 0"
:members="sandboxData.members || []"
showDimensionBar
starHeight="480rpx" />
<!-- ② 发现区 — 上传报告 -->
<view class="section">
<ReportUploadCard
title="上传报告"
desc="体检报告 · 菌群检测 · 认知测评 · 心理测评 · 情绪打卡"
:tags="['体检报告', '菌群检测', '认知测评', '心理测评', '情绪打卡']"
@click="goToUploadReport" />
</view>
<!-- ③ 行动区 — 旅程状态卡 — 改版v1 需求驱动(A类·随便看看 不展示旅程卡) -->
<JourneyCard
v-if="userIntent && userIntent.intentType !== 'A'"
:intent="userIntent"
@action="handleJourneyAction" />
<!-- ③ 行动区 — 今日任务 -->
<DailyTaskCard />
<!-- ③ 行动区 — 我的任务(仅当有待完成时显示) -->
<view v-if="hasPendingTasks" class="section">
<view class="section-header">
<text class="section-title">📝 我的任务</text>
<text class="section-more" @click="navTo('/pages/tasks/tasks')">全部 ›</text>
</view>
<view class="task-quick-list">
<view
v-for="task in pendingTasks"
:key="task.id"
class="task-quick-item"
>
<view class="task-quick-info">
<text class="task-quick-title line-clamp-1">{{ task.title }}</text>
<text class="task-quick-meta">+{{ task.points }}分</text>
</view>
<button class="btn-quick-complete" @click="quickCompleteTask(task)">完成</button>
</view>
</view>
</view>
<!-- ③ 行动区 — 家庭挑战任务 -->
<view class="section">
<view class="section-header">
<text class="section-title">🔥 家庭挑战</text>
<text class="section-more" @click="goChallengeManage">管理 ›</text>
</view>
<FamilyChallengeCard
v-for="ch in activeChallenges"
:key="ch.id"
:challenge="ch"
:showCheckin="showCheckinBtn"
@checkin="onChallengeCheckin"
@respond="onChallengeRespond" />
<view v-if="activeChallenges.length === 0" class="challenge-empty">
<text class="challenge-empty-icon">🏆</text>
<text class="challenge-empty-text">您还没有挑战,去添加吧</text>
<button class="challenge-add-btn" @click="goChallengeManage">去添加</button>
</view>
</view>
<!-- ③ 行动区 — 会员入口:非会员显示开通 / 快到期显示续费 -->
<view v-if="showMemberEntry" class="member-entry" @click="goMembership">
<view class="member-entry-icon-wrap">
<text class="member-entry-icon">👑</text>
</view>
<view class="member-entry-texts">
<text class="member-entry-title">{{ memberEntryTitle }}</text>
<text class="member-entry-desc">{{ memberEntryDesc }}</text>
</view>
<view class="member-entry-btn">
<text class="member-entry-btn-text">{{ memberEntryBtn }}</text>
</view>
</view>
<!-- ④ 内容区 — 快捷功能入口(单排) -->
<view class="section">
<view class="quick-bar">
<view class="quick-item" @click="navTo('/pages/tasks/tasks')">
<view class="quick-icon" style="background:rgba(99,102,241,0.15)"><text>📋</text></view>
<text class="quick-label">任务</text>
</view>
<view class="quick-item" @click="navTo('/pages/action-detail/interaction-log')">
<view class="quick-icon" style="background:rgba(16,185,129,0.15)"><text>💬</text></view>
<text class="quick-label">互动</text>
</view>
<view class="quick-item" @click="navTo('/pages/mind-detail/family-dashboard')">
<view class="quick-icon" style="background:rgba(139,92,246,0.15)"><text>🏠</text></view>
<text class="quick-label">天盘</text>
</view>
<view class="quick-item" @click="navTo('/pages/profile-extra/family-members')">
<view class="quick-icon" style="background:rgba(245,158,11,0.15)"><text>👨👩👧👦</text></view>
<text class="quick-label">成员</text>
</view>
<view class="quick-item" @click="navTo('/pages/discover/circles')">
<view class="quick-icon" style="background:rgba(255,107,157,0.15)"><text>🤝</text></view>
<text class="quick-label">圈子</text>
</view>
<view class="quick-item" @click="navTo('/pages/shop/index/index')">
<view class="quick-icon" style="background:rgba(249,115,22,0.15)"><text>🛒</text></view>
<text class="quick-label">商城</text>
</view>
</view>
</view>
<!-- ④ 内容区 — 家庭动态 -->
<FamilyFeed
:items="familyFeed"
:notices="notices"
:showHeader="true" />
<!-- ④ 内容区 — 推荐文章 -->
<view class="section">
<view class="section-header">
<text class="section-title">📖 推荐阅读</text>
<text class="section-more" @click="goMoreArticles">更多 ›</text>
</view>
<ArticleBookshelf
:articles="actionArticles"
:isLoggedIn="true"
@articleClick="goArticleDetail" />
</view>
<!-- ④ 内容区 — 推荐商品 -->
<view class="section">
<view class="section-header">
<text class="section-title">🛍️ 推荐商品</text>
<text class="section-more" @click="goMoreProducts">更多 ›</text>
</view>
<DimensionProducts
:isLoggedIn="true"
:showMore="false"
@productClick="goProductDetail" />
</view>
<!-- 底部占位 -->
<view class="bottom-spacer" style="height: 40rpx;"></view>
</view>
<view> 开闭计数一致),确认无遗漏/多闭合cfc-frontend/pages/index-home/index.vue改动 A(methods,goToUploadReport 方法 ~847 行旁): 新增方法:
goSelfTest: function() {
uni.navigateTo({ url: '/pages/health/survey-questionnaire?dim=all' })
},
改动 B(computed,memberEntryBtn 计算属性 ~481-484 行后): 新增计算属性:
// 自测大卡:已有数据(沙盘解锁)显示"再次了解",否则显示引导文案
selfTestTitle: function() {
return this.sandboxData ? '再次了解 · 看看变化' : '先花 1 分钟,了解全家健康状况'
},
selfTestSub: function() {
if (this.sandboxData) {
return '最近综合得分 ' + (this.sandboxData.overallScore || 0) + ' 分 · 点击重新自检'
}
return '15 题五维自检 · 约 20 秒'
},
验证: 提取 script 块 node --check 通过
cfc-frontend/pages/index-home/index.vue <style> 块(1159 行起)做法: 在 .logged-in-container 样式(1705 行)附近新增以下样式(从 health-main 复制,水平外边距对齐首页 .section 的 30rpx、底部对齐 16rpx):
/* ===== ① 了解区 — 自测大卡(引导"从了解开始") ===== */
.self-test-card {
margin: 20rpx 30rpx 16rpx;
background: linear-gradient(135deg, #667eea, #764ba2);
border-radius: 20rpx;
padding: 24rpx 28rpx;
}
.self-test-head { display: flex; align-items: center; }
.self-test-icon { font-size: 40rpx; margin-right: 16rpx; }
.self-test-info { flex: 1; }
.self-test-title { font-size: 28rpx; font-weight: bold; color: #fff; display: block; }
.self-test-sub { font-size: 22rpx; color: rgba(255,255,255,0.8); display: block; margin-top: 4rpx; }
.self-test-arrow { font-size: 36rpx; color: rgba(255,255,255,0.7); }
验证: 无 JS 变更,检查样式类名与模板引用一致(self-test-card / self-test-head / self-test-icon / self-test-info / self-test-title / self-test-sub / self-test-arrow 共 7 个类)
node --check(复用此前验证脚本,0 错误)<view> 开闭标签平衡(0 差异)PageBanner 引用为 0(设计文档已同步修正)goSelfTest 方法存在、selfTestTitle/selfTestSub 计算属性存在feat(home): 首页健康漏斗重构 — 了解区自测卡 + 四段式区块重排(仅含 index-home/index.vue)git push origin cfclubdocs/superpowers/PROJECT-OVERVIEW.mdplans/2026-08-18-homepage-health-funnel.md 条目docs(overview): 同步首页健康漏斗实现计划(与任务 5 同一提交或独立提交均可)/pages/health/survey-questionnaire?dim=allReportUploadCard 位于能量沙盘下方(发现区)DailyTaskCard 位于行动区(旅程卡下方)JourneyCard 从首屏移到行动区顶部,C 类意图显示 / A 类隐藏逻辑不变showMemberEntry 逻辑不变