2026-08-15-daily-task-overview-design.md 9.9 KB

「今日任务」首页卡片 + 只读聚合接口设计

优先级: 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 拉取)                    │
│   └─ <DailyTaskCard /> 新组件 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 <JWT>
请求体:无

响应(Result<DailyOverviewVO>):

{
  "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<T> 包装
  • 纯只读查询,不得改动任何表结构 / 写库
  • 单次调用聚合查询,避免前端 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 打包)