# 「今日任务」首页卡片 + 只读聚合接口设计
**优先级:** P1
**预计工时:** 后端 0.5d + 前端 1d
**状态:** pending(待用户审阅后 transition 到 writing-plans)
## 1. 概述
在首页(`pages/index-home/index.vue`)新增「今日任务」卡片组件 `daily-task-card.vue`,通过后端新增**一个只读聚合接口** `POST /api/daily-task/overview`,一次性返回当前登录成员的今日任务状态(打卡/任务/阅读活动/测评报告四类),用户点击卡片项直达对应功能页完成操作,返回首页时自动刷新勾选状态。目标:将分散的五维打卡、家庭任务、成长任务、阅读活动、测评报告统一为「每日任务」入口,简化用户使用逻辑。
**范围决策(用户已确认):**
- 仅小程序端主体改造 + 后端新增 1 个只读聚合查询端点(不改任何数据表 / 业务逻辑)
- 交互形态:首页今日卡片 + 自动勾选(返回刷新)
- 聚合范围:任务类 + 五维打卡类 + 阅读活动类 + 测评报告类(全选)
- 完成判定:后端聚合接口(复用现有 service 查询逻辑)
- 角色视角:固定本人视角(当前登录成员,不按 parent/child/teacher 分支)
- 卡片项交互:点击跳转 + 返回自动刷新
## 2. 背景与现状
### 2.1 已有基础设施(复用,不重建)
| 域 | 现有组件/接口 | 说明 |
|---|---|---|
| 家庭任务 | `TaskController` `/api/tasks/*` + `pages/tasks/tasks.vue` | 创建/下发/接受/审核,页面 3 Tab(待接受/今日任务/我创建的) |
| 成长任务 | `GrowthTaskController` `/api/growth-task/*` + `pages/tasks/daily-tasks.vue` | DAILY/NEWBIE 双 tab + 进度 + 领取,数据模型完整但首页未接入 |
| 打卡 | health/wealth/mind 各 checkin 接口 + `daily_checkin`/`health_checkins`/`health_exercise_records` 等表 | 维度打卡入口分散在 8+ 个页面 |
| 阅读活动 | `ArticleController` + `pages/article-center/*`、活动模块 | 文章阅读记录、活动参与 |
| 测评报告 | `DanAssessmentController` + `AssessmentAppointmentController` + `pages/assessment/*`、`pages/health/report-*` | 测评订单/报告状态 |
| 连续打卡 | `/api/streak/*` | 已存在 |
| 首屏路由 | 首页 `index-home` 快捷栏 | `navTo('/pages/tasks/tasks')` 等 |
### 2.2 核心缺口
- **入口分散**:家庭任务 / 成长任务 / 各维度打卡 / 文章 / 测评各自入口,用户无统一「今天该做什么」视图
- **成长任务页未打通**:`daily-tasks.vue` 有完整数据模型但仅 ProfileMenu 一个入口,首页未引用
- **无聚合视角**:前端无一处能同时看到「今日已打卡维度 + 未完成任务数 + 待办测评/报告」的概览
## 3. 架构
```
┌─────────────────────────────────────────────────────────────────┐
│ 首页 pages/index-home/index.vue(onShow 拉取) │
│ └─ 新组件 components/daily-task-card.vue │
│ ├─ 分组:打卡类 / 任务类 / 阅读活动 / 测评报告 │
│ ├─ 动作项:未完成 →「去完成」;完成 → ✓ │
│ └─ 点击 → uni.navigateTo(route) → 功能页 → 返回自动刷新 │
└──────────────────────────┬──────────────────────────────────────┘
│ POST /api/daily-task/overview (JWT)
▼
┌─────────────────────────────────────────────────────────────────┐
│ DailyTaskController.overview() 【新增,只读,唯一后端改动】 │
│ 1. memberId 回退链:currentChildId → currentMemberId → userId │
│ 2. 复用现有 service 查询(今日是否打卡/任务状态/阅读记录/ │
│ 测评订单状态),零新业务规则 │
│ 3. 组装 DailyOverviewVO 返回 │
└─────────────────────────────────────────────────────────────────┘
```
## 4. 接口设计
### 4.1 新增端点
```
POST /api/daily-task/overview
请求头:Authorization: Bearer
请求体:无
```
**响应(`Result`):**
```json
{
"code": 0,
"message": "success",
"data": {
"memberId": 1001,
"date": "2026-08-15",
"checkins": [
{ "key": "health", "label": "健康打卡", "done": true,
"route": "/pages/health/daily-checkin" },
{ "key": "wealth", "label": "财商打卡", "done": false,
"route": "/pages/wealth-sub/checkin" },
{ "key": "mind", "label": "情绪打卡", "done": false,
"route": "/pages/mind-detail/emotion-checkin" }
],
"tasks": {
"pendingAccept": 1,
"todoToday": 2,
"doneToday": 3,
"route": "/pages/tasks/tasks"
},
"activities": {
"articleReadToday": 1,
"activityAvailable": 0,
"articleRoute": "/pages/article-center/index",
"activityRoute": "/pages/activity/index"
},
"assessments": {
"ongoing": 1,
"reportPending": 0,
"route": "/pages/assessment/results"
},
"hasMore": false
}
}
```
### 4.2 字段说明
| 字段 | 类型 | 完成判定复用逻辑 |
|---|---|---|
| `checkins[]` | Array | 各维度「今日是否已打卡」——复用现有 checkin service 按日期查询逻辑 |
| `tasks.pendingAccept` | int | 家庭任务待接受数(TaskController 查询) |
| `tasks.todoToday` | int | 今日待完成任务数(growth-task DAILY 查询) |
| `tasks.doneToday` | int | 今日已完成数 |
| `activities.articleReadToday` | int | 今日已读文章数(阅读记录表) |
| `activities.activityAvailable` | int | 可参与活动数 |
| `assessments.ongoing` | int | 进行中测评数(测评订单状态) |
| `assessments.reportPending` | int | 待上传/待确认报告数 |
| `* .route` | String | **由后端下发**,前端 `uni.navigateTo`,零前端路由硬编码 |
**约束:**
- 全部 `@PostMapping`(项目规范,禁止 GET/PUT/DELETE)
- 响应统一 `Result` 包装
- 纯只读查询,**不得改动任何表结构 / 写库**
- 单次调用聚合查询,避免前端 N 次串行请求
## 5. 前端设计
### 5.1 新组件 `cfc-frontend/components/daily-task-card.vue`
- **放置位置**:`pages/index-home/index.vue`,位于 `JourneyCard` 与 `WuxingSandbox` 之间(改版v1 需求驱动旅程之后、能量沙盘之前),始终可见。
- **数据获取**:`onShow` 调用聚合接口 → 组件直接消费 `DailyOverviewVO`;登录态 `currentRole` 存在时才渲染(与现有首页登录容器一致)。
- **结构**(四分组,flexbox 布局,禁用 Grid):
```
┌─ 今日任务 ──────────────── 日期 ─┐
│ 【打卡类】 │
│ ✓ 健康打卡 去完成 财商打卡 │
│ ✓ 情绪打卡 │
│ 【任务类】 待完成 2 · 已完成 3 │
│ 【阅读活动】 今日已读 1 篇 │
│ 【测评报告】 进行中测评 1 项 │
│ (预留「查看全部」槽位) │
└─────────────────────────────────┘
```
- **每组展示上限**:打卡类最多 3 项(超过显示「+N 项」),任务/活动/测评各 1 行摘要。
- **状态样式**:完成项绿色 ✓ + 置灰文本;未完成项橙色「去完成」按钮。
- **空态**:全部完成 → 显示「今日任务已全部完成 🎉」;接口失败 → 卡片内降级提示 + 重试按钮,不阻塞首页其他模块。
### 5.2 交互流程
1. 首页 `onShow` → 拉取 `overview`
2. 点击动作项 → `uni.navigateTo({url: route})` 直达对应功能页(完全复用现有页面)
3. 用户完成操作后返回首页 → `onShow` 再次触发 → 重新拉取 → 完成项自动打 ✓
4. 无需前端本地状态同步(每次以接口为准)
### 5.3 小程序规范遵从(AGENTS.md 强制)
- 禁止可选链 `?.` → 用 `&&` 兜底
- 禁止 CSS Grid → flexbox
- 禁止 `:key` 表达式 → 方法调用 `:key="getItemKey(item)"`
- 禁止 `new Date(string)` → `utils/format.js` 的 `parseDate()`
- 禁止 `:class` 绑定中调用方法 → 内联表达式或计算属性
- 组件 Array 类型 prop 必须 `|| []` 兜底
- Vue 2 Options API,禁止 Composition API
## 6. 范围边界(明确不做)
| 不做 | 原因 |
|---|---|
| 新建任务表 / 改数据模型 / 写库 | 复用现有 growth-task/tasks/checkin 体系 |
| 任务中心页大改版(daily-tasks 重构) | 本期卡片优先,card 底部预留「查看全部」扩展位(二期) |
| 规划师 / Web 管理端改造 | 超出「仅小程序接入」范围 |
| 卡片内就地打卡 | 用户已确认「点击跳转 + 返回刷新」 |
| 后端聚合接口性能优化(缓存) | 首版直查即可,量级小 |
## 7. 验收标准
- [ ] 首页登录态下渲染「今日任务」卡片,未登录不显示
- [ ] 打卡/任务/阅读/测评四分组正确展示今日状态
- [ ] 点击任意动作项跳转到对应功能页
- [ ] 完成操作返回首页后,卡片自动刷新为 ✓(无需手动下拉)
- [ ] 聚合接口 `POST /api/daily-task/overview` 只读,不产生任何写操作
- [ ] memberId 回退链正确(currentChildId → currentMemberId → userId)
- [ ] 接口失败时卡片降级显示 + 可重试,不影响首页其他模块
- [ ] 通过 `node --check` 语法校验;不执行打包命令(HBuilderX 打包)