# 5-Tab Pages Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Complete all 5 bottom-tab pages (首页/parent-index, 首页/child-index, 首页/teacher-index, 行远, 富沛) to match the detailed design in `docs/需求分析/底签页面详细设计.md`
**Architecture:** Each tab page is an independent Vue component. The 首页 uses role-based conditional rendering (parent-index / child-index / teacher-index). Shared components (EnergyWeekCard, TaskItem, BadgeGrid) are extracted to `components/`.
**Tech Stack:** uni-app Vue 2 (Options API), SCSS, flexbox layout
**Design Tokens:** `--color-primary: #F97316` (warm orange), `--color-accent: #5B9BD5` (blue), `--bg-header: #1A2A4A → #1E3A5F` (deep blue gradient)
---
### Task 1: parent-index — Add 待处理事项 action-cards and 成长建议 section
**Files:**
- Modify: `cfc-frontend/pages/index/parent-index.vue`
- [ ] **Step 1: Add "待处理事项" section with action cards**
Insert after the `milestone-section` div and before `review-section`:
```html
📋 待处理事项
📝
{{ pendingReviewTasks.length }}
待审核任务
💝
{{ pendingReviewWishes.length }}
待审批心愿
📊
{{ hasNewReport ? '有新' : '暂无' }}
最新测评报告
🎉
{{ hotActivityCount }}
活动推荐
```
- [ ] **Step 2: Add "成长建议" section**
Insert after `pending-section`:
```html
💡 成长建议
💡
{{ advice.title }}
{{ advice.summary }}
›
```
- [ ] **Step 3: Add data properties and methods**
In the `data()` function, add:
```js
pendingReviewWishes: [],
hotActivityCount: 0,
hasNewReport: false,
growthAdvice: []
```
In methods, add:
```js
goToWishApprove() {
uni.navigateTo({ url: '/pages/wishes/approve' })
},
goToAssessmentReport() {
uni.navigateTo({ url: '/pages/assessment/report' })
},
goToActivities() {
uni.switchTab({ url: '/pages/discover/index' })
},
goToAdviceDetail(advice) {
if (advice.link) uni.navigateTo({ url: advice.link })
}
```
- [ ] **Step 4: Add CSS styles for pending and advice sections**
```css
.pending-section { margin-bottom: 48rpx; }
.pending-grid { display: flex; flex-wrap: wrap; gap: 16rpx; }
.pending-card {
width: calc(50% - 8rpx);
background: #fff;
border-radius: 20rpx;
padding: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
display: flex;
align-items: center;
}
.pending-icon {
width: 72rpx; height: 72rpx;
border-radius: 16rpx;
display: flex; align-items: center; justify-content: center;
margin-right: 16rpx; flex-shrink: 0;
}
.pending-icon--blue { background: rgba(91,155,213,0.12); }
.pending-icon--pink { background: rgba(236,72,153,0.12); }
.pending-icon--green { background: rgba(16,185,129,0.12); }
.pending-icon--orange { background: rgba(249,115,22,0.12); }
.pending-emoji { font-size: 32rpx; }
.pending-info { flex: 1; min-width: 0; }
.pending-count { font-size: 36rpx; font-weight: 800; display: block; }
.pending-label { font-size: 22rpx; color: #666; margin-top: 4rpx; display: block; }
.pink-color { color: #EC4899; }
.orange-color { color: #F97316; }
.advice-section { margin-bottom: 48rpx; }
.advice-card { margin-bottom: 12rpx; }
.advice-content {
display: flex; align-items: center; padding: 24rpx;
}
.advice-icon-wrap {
width: 56rpx; height: 56rpx;
border-radius: 14rpx;
background: rgba(91,155,213,0.1);
display: flex; align-items: center; justify-content: center;
margin-right: 16rpx; flex-shrink: 0;
}
.advice-icon { font-size: 28rpx; }
.advice-text-wrap { flex: 1; min-width: 0; }
.advice-title { font-size: 28rpx; font-weight: 600; color: #333; display: block; }
.advice-desc { font-size: 24rpx; color: #999; margin-top: 4rpx; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.advice-arrow { font-size: 36rpx; color: #ccc; margin-left: 12rpx; }
```
---
### Task 2: child-index — Add 最近能量变动 section
**Files:**
- Modify: `cfc-frontend/pages/index/child-index.vue`
- [ ] **Step 1: Add energy logs section after achievements**
Insert after `achievement-section` div and before `bottom-spacer`:
```html
{{ log.amount >= 0 ? '⬆' : '⬇' }}
{{ log.reason || log.description }}
{{ log.createdAt || log.time }}
{{ log.amount >= 0 ? '+' : '' }}{{ log.amount }}
```
- [ ] **Step 2: Add data property and data loading**
In `data()`, add:
```js
energyLogs: []
```
In `loadData()`, after energy overview load, add:
```js
try {
const logsRes = await getEnergyLogs({ childId: energyChildId, size: 5 })
if (logsRes && logsRes.data) {
this.energyLogs = logsRes.data.records || logsRes.data
}
} catch (e) {
console.log('获取能量日志失败', e)
this.energyLogs = []
}
```
In the import section, add `getEnergyLogs`:
```js
import { ..., getEnergyLogs } from '../../utils/api.js'
```
- [ ] **Step 3: Add method and CSS**
Add method:
```js
goToEnergyDetail() {
if (this.childId) {
uni.navigateTo({ url: '/pages/energy/detail?childId=' + this.childId + '&code=all' })
}
}
```
Add CSS:
```css
.energy-log-section { margin-bottom: 28rpx; }
.energy-log-list { background: #fff; border-radius: 20rpx; overflow: hidden; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
.energy-log-item {
display: flex; align-items: center;
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.energy-log-item:last-child { border-bottom: none; }
.log-icon-wrap {
width: 56rpx; height: 56rpx;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
margin-right: 16rpx; flex-shrink: 0;
}
.log-icon--up { background: rgba(16,185,129,0.12); }
.log-icon--down { background: rgba(239,68,68,0.12); }
.log-icon { font-size: 24rpx; }
.log-info { flex: 1; min-width: 0; }
.log-title { font-size: 26rpx; color: #333; display: block; }
.log-time { font-size: 20rpx; color: #999; margin-top: 4rpx; display: block; }
.log-amount { font-size: 28rpx; font-weight: 700; margin-left: 12rpx; }
.log-amount--up { color: #10B981; }
.log-amount--down { color: #EF4444; }
```
---
### Task 3: teacher-index — Redesign per design spec
**Files:**
- Modify: `cfc-frontend/pages/teacher/index.vue`
- [ ] **Step 1: Replace header with 规划师工作台 brand header**
Replace the current header section:
```html
```
- [ ] **Step 2: Add 今日日程 section**
```html
📅 今日日程
{{ apt.appointmentTime || apt.time }}
{{ apt.title }}
{{ apt.description }}
```
- [ ] **Step 3: Add 绑定家庭 section (replacing current stats grid)**
```html
👨👩👧👦 绑定家庭
{{ family.familyName || family.name }}
{{ family.childCount || 0 }}个孩子
最近: {{ family.latestTask }}
```
- [ ] **Step 4: Add 快捷操作 grid**
```html
⚡ 快捷操作
📝
下发任务
📊
录入测评
💬
联系家长
💰
查看收入
```
- [ ] **Step 5: Add data, methods, and CSS**
Data additions:
```js
todayAppointments: [],
boundFamilies: []
```
Methods:
```js
goToFamilyDetail(family) {
uni.navigateTo({ url: '/pages/guide/family-detail?familyId=' + family.id })
},
goToAssignTask() {
uni.navigateTo({ url: '/pages/guide/assign-task' })
},
goToInputAssessment() {
uni.navigateTo({ url: '/pages/assessment/input-result' })
},
goToContactParent() {
uni.navigateTo({ url: '/pages/guide/messages' })
},
goToIncome() {
uni.navigateTo({ url: '/pages/guide/income' })
}
```
---
### Task 4: Create Shared Components
**Files:**
- Create: `cfc-frontend/components/EnergyWeekCard.vue`
- Create: `cfc-frontend/components/TaskItem.vue`
- Create: `cfc-frontend/components/BadgeGrid.vue`
- [ ] **Step 1: Create EnergyWeekCard.vue**
```vue
本周获取
+{{ weekGain }}
上周
{{ lastWeekGain }}
{{ gainTrend >= 0 ? '↑' : '↓' }}{{ Math.abs(gainTrend) }}%
{{ tip }}
```
- [ ] **Step 2: Create TaskItem.vue**
```vue
{{ task.title }}
⏰ {{ task.deadline }}
+{{ task.points }}⭐
去完成
```
- [ ] **Step 3: Create BadgeGrid.vue**
```vue
{{ badge.unlocked ? badge.icon : '🔒' }}
{{ badge.name }}
```
---
### Task 5: Verify all 5 tab pages against design spec
**Files:**
- Review: `cfc-frontend/pages/index/index.vue` — check role routing
- Review: `cfc-frontend/pages/index/parent-index.vue` — verify all sections
- Review: `cfc-frontend/pages/index/child-index.vue` — verify all sections
- Review: `cfc-frontend/pages/teacher/index.vue` — verify all sections
- Review: `cfc-frontend/pages/body/index.vue` — verify against design
- Review: `cfc-frontend/pages/mind/index.vue` — verify against design
- Review: `cfc-frontend/pages/action/index.vue` — verify against design
- Review: `cfc-frontend/pages/profile/profile.vue` — verify against design
- [ ] **Step 1: Check that index.vue properly routes to all 3 role components**
- [ ] **Step 2: Verify parent-index has: philosophy banner, children row, health overview, pending items, growth advice**
- [ ] **Step 3: Verify child-index has: energy sandbox, streak badge, points card, today tasks, quick actions, energy logs**
- [ ] **Step 4: Verify teacher-index has: workbench header, today schedule, bound families, quick actions**
- [ ] **Step 5: Check LSP diagnostics clean on all changed files**