# 「今日任务」首页卡片 + 只读聚合接口设计 **优先级:** 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 打包)