打卡 / 日历 / 清单 —— 移动端静态高保真原型(设计基线 420 × 820,适配 375~430px)
沿用项目既有 :root 变量(src/styles/globals.css),本模块不引入新主题。
头部日期 + 完成数;未完成卡片排在前面。环形中心未达标显示 done/target,达标显示对勾(每天 1 次打完即刻闭合);超额在右上角显示 +n。点环或「打卡」按钮均可打卡,卡片底部提供撤销 / 编辑 / 归档。
周一起始月历 + 「昨天 / 今天 / 明天」快捷分段;日期下方状态点:绿=全部完成、黄=部分完成、紫=超额、无点=未完成或未来。今天用主色数字并选中高亮,未来日期数字弱化。下方为该日明细,可直接打卡;底部展示本月完成率。
卡片头部常显标题、场景标签、进度条与 8/12;点击展开逐条勾选(勾选后绿色圆底、文字加删除线并弱化)。底部可继续添加检查项,并提供全选 / 全不选 / 复制 / 存为模板 / 归档 / 删除。收起态只保留头部一行。
名称 ≤20 字;周期四选一(每天 / 每周 / 每月 / 每年);目标次数用 Stepper,最小 1;颜色 7 色预设;备注可选。编辑态标题变为「编辑打卡项」并回填当前值。
环形闭合 + 对勾缩放入场(0.32s);同时 14 颗粒子沿圆周扩散(26~58px,交替主色与金色)+ 主色光环脉冲(0.7s),总时长 ≤900ms,pointer-events:none 不阻塞后续操作;并触发 18ms 轻震动。特效恒开(V0.2 设计变更:头部不再有开关)。
未来日期不允许打卡:标题右侧显示「计划(不可打卡)」徽标,条目右侧只显示「待办」文案而不渲染按钮,月历上未来日期数字弱化且不打点。昨天视图则相反——可补打最近 7 天内的漏打卡。
进度条 100%、计数变为 12/12、卡片底色转 #f7fbf8,并播放与打卡一致的完成特效。清单完成后用户通常选择「归档」或「复制」复用。
还没有打卡项
三个视图均具备加载中 / 空态 / 错误(带重试)三态。空态给出明确引导按钮。V0.2 设计变更:打卡页头部不再有「特效开 / 特效关」开关,完成特效与触感反馈恒开,没有任何关闭入口。
「首页」Tab 取消,报警与新闻并入宏观。2026-10-23 调整:两者移到最左(报警 → 新闻 → 油价 → 经济数据 → 策略研究 → 经济文章),默认选中「新闻」;共 6 个子 Tab 可横向滚动,当前项底部有 3px 主色指示条;报警数量以红色角标挂在子 Tab 上。tab 条右侧增加渐变遮罩 + 箭头,提示还有未展示的 tab(详见 2.12 ④)。新闻详情为 /macro/news/:id,底部「宏观」保持高亮。
开关默认关闭 = 按版本号判新:取服务端 latest.json 的 version(如 0.2.0-ota),与当前运行版本按数字字段逐段比较,更高才提示更新。用于生产,避免旧分支被重建(sequence 变大但版本更小)把设备拉回旧版。开关值保存在设备端 localStorage.iboard_ota_dev_mode。
开关打开 = 按 build sequence 判新:走 hotswap 插件的 checkUpdate(),只要服务端 sequence 比本地大就算新版本——每次 CI 构建 sequence 都会变(默认取时间戳),所以任何一次提交都能推到设备上,适合开发联调。切换开关会清空上一次的检查结果,避免上一种口径的结论误导。
本节为 2026-10-23 提出的调整方案。其中 ①头部统一 / ③模板分类 / ④宏观 tab 溢出 已按本节实现; ②日历与打卡合并 为待确认草案,确认后再改代码。
| 页 | 调整前 | 调整后 |
|---|---|---|
| 打卡 | NavBar 45px,标题「打卡」17px 深色 | 23px,标题「打卡」12px 主色加粗,字距 1px |
| 宏观 | NavBar 45px,无标题(空白) | 23px + 标题「宏观」(同打卡规格) |
| 监控 | NavBar 45px,无标题(空白) | 23px + 标题「监控」(同打卡规格) |
| 我 | NavBar 45px 空白条 | 整条去掉,蓝色头像区直接顶到状态栏下方 |
实现为独立组件 PageHeader,只被打卡 / 宏观 / 监控 引用;「我」页不引用,因此三者互不影响。
头部背景取页面底色 #f5f5f5(不再是卡片白),视觉上更轻。
原 45px 白色 NavBar 换成 23px 底色条 + 主色标题,页面上移,首屏多出一张卡片的高度。
顺序:报警 → 新闻 → 油价 → 经济数据 → 策略研究 → 经济文章,默认选中「新闻」(/macro 自动跳 /macro/news)。
溢出提示:tab 条仍可向右滚动时,右边缘出现白色渐变遮罩 + 主色圆底箭头「›」(1.5s 轻微左右摆动,可点击向右翻页),滚到末尾自动消失;切换 tab 时自动把激活项滚到可视区中间。
antd-mobile Tabs 自带的右侧渐变遮罩只有 30px 且无箭头,用户难以察觉,故叠加此提示层。
把原来的「打卡」「日历」两个 tab 合成一个:上半部日历,下半部打卡卡片。取舍按下述规则:
| 项 | 规则 |
|---|---|
| 页面结构 | SwipeTabs 从 3 个减为 2 个:日历(含打卡) / 清单 |
| 上方日历 | 保留月历网格 + 月份左右切换 + 「回到今天」;去掉「昨天 / 今天 / 明天」分段控件(点日期即可,节省 38px 高度) |
| 日历高度 | 日期格子 38px → 31px,去掉 6 行补位中的空行;整块约 240px |
| 下方打卡 | 沿用现有打卡卡片样式,但紧凑化:内边距 12px → 8px,环形 58px → 42px(环宽 6 → 5),行高压缩,卡片间距 10 → 7px |
| 卡片内容 | 保留环形进度(含达标对勾 / 超额 +n)、名称、周期与目标、连续天数、打卡按钮;撤销 / 编辑 / 归档收进「⋯」,减少一行高度 |
| 分组 | 按周期类型分组:每天 → 每周 → 每月,每组一个小标题(左侧主色竖条 + 组名 + 条数);去掉「每年」分组(已有年目标项并入「每月」区末尾的「其他周期」小标题,或建议直接隐藏年视图) |
| 联动 | 点日历某日 → 下方卡片即该日数据(进度仍按该日所属周期算);未来日期只读,按钮变灰显示「计划」 |
| 空态 | 日历下方直接显示「该日没有打卡项」+「+ 新建」引导 |
卡片整体压缩:环形 42px、内边距 8px、行距 7px,单卡高度约 58px(原 92px),一屏可看 4~5 项。分组顺序固定为 每天 → 每周 → 每月, 组标题左侧 3px 主色竖条;无「每年」分组。日历顶部的「昨天 / 今天 / 明天」分段已去掉,直接点日期切换,选中日靠「今天」主色数字与蓝色实心块识别。
选中未来日期时,打卡按钮统一变灰显示「计划」,点击不生效;环形仍显示该日所属周期的既有进度(此处举例为周期初)。 补打窗口仍是最近 7 天,超出时同样只读。
紧凑化后卡片不再常显三个文字链接,改由右上角「⋯」唤出底部面板:撤销 / 编辑 / 归档。面板项 44px 高, 「归档」用危险色;撤销仅在当日有记录时可用,否则置灰。
清单页分段从 2 个变为 3 个:进行中 / 已归档 / 模板。模板拥有独立的增删改查,按名称字母顺序(中文按拼音、数字按数值)排序; 新建清单时只保留名称,去掉场景,模板改为点击后在右侧滑出的面板里选择。
模板卡片:名称 + 「预置」标记 + 项数;下方最多展示 4 个检查项摘要(超出折叠为 +n);底部操作「由此新建 / 编辑 / 删除」。
系统预置模板不可编辑、不可删除(只保留「由此新建」)。右上角按钮随分段切换:模板页为「+ 新建模板」,其余为「+ 新建」。
表单只剩两项:名称(≤20 字,必填)与 模板(可空)。场景选择器已移除——场景不再由用户填写,新建时沿用所选模板自带的场景(无模板则为空),历史数据仍正常展示场景标签。
点模板行从右侧滑出 78% 宽面板:首项固定为「不使用模板」,其后按字母顺序列出全部模板(预置带标记、右侧显示项数),选中项主色高亮,点遮罩或 × 关闭。
新建 / 编辑共用同一弹层:模板名称(≤20 字)+ 检查项列表(逐条 ≤40 字,可删除、可追加)。保存时至少需 1 条有效检查项,名称为空或全空则拦截并 Toast 提示。 删除模板需二次确认,且不影响已用该模板创建过的清单。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/checklists/templates | 模板列表(含预置),服务端按名称字母顺序排序 |
| GET | /api/checklists/templates/:id | 模板详情 |
| POST | /api/checklists/templates | 新建模板 { name, items[] } |
| PUT | /api/checklists/templates/:id | 改名称 / 检查项(预置模板拒绝) |
| DELETE | /api/checklists/templates/:id | 删自建模板(预置模板拒绝) |
排序口径:Intl.Collator('zh-Hans-CN', { numeric: true, sensitivity: 'base' }),中文按拼音、数字按数值比较,前后端一致。
| 项 | 取值 |
|---|---|
| 高度 | 23px(原 NavBar 45px 的一半),flex: 0 0 23px 不参与压缩 |
| 标题字号 / 字重 | 12px / 600 |
| 标题颜色 | 主色 #1677ff |
| 背景 | 页面底色 #f5f5f5 |
| 适用范围 | 打卡 / 宏观 / 监控;「我」页不使用 |
实现为独立组件 src/components/PageHeader.jsx,三页各自引用、互不影响;「我」页移除 NavBar 后头像区直接贴顶。
| 状态 | 条件 | 环形 | 中心 | 卡片底 | 按钮 |
|---|---|---|---|---|---|
| 未开始 | done = 0 | 仅灰底环 | 0/2 | 白 | 打卡(主色) |
| 进行中 | 0 < done < target | 按 done/target 填充(45°…330°) | 1/3 | 白 | 打卡(主色) |
| 已达标 | done = target | 闭合整圈 | 对勾(主色) | #f7fbf8 | 再打一次(灰) |
| 超额 | done > target | 闭合 + 右上角 +n 橙标 | 对勾 | #f7fbf8 | 再打一次(灰) |
| 每日 1 次达标 | target = 1 且已打卡 | 直接整圈闭合,不做渐增生长期 | 对勾 | #f7fbf8 | 再打一次 |
环形进度 = 周期完成度(done / n);日历日标记 = 当日份额(当日次数 / 日均期望),两者口径不同,互不影响。
| 状态 | 判定 | 视觉 |
|---|---|---|
全部完成 full | 所有打卡项当日次数 ≥ 日均期望,且无超额 | 绿色圆点 |
超额 over | 全部达标且存在任一打卡项当日次数 > 期望 | 紫色圆点 |
部分完成 partial | 有完成但未全部完成 | 黄色圆点 |
无 empty | 无记录 / 当天无打卡项 / 未来日期 | 不显示圆点 |
| 今天 | date = today | 数字主色加粗 |
| 选中 | 用户点击 | 主色实心底,数字与圆点转白 |
| 非本月 / 未来 | 月份不符 / date > today | 数字弱化(#c8c8c8 / #b0b0b0) |
| 状态 | 勾选框 | 文字 | 触发 |
|---|---|---|---|
| 未完成 | 1.5px 灰边圆圈,对勾透明 | #333 | 点击圆圈或文字切换 |
| 已完成 | 绿底绿边,白色对勾显现(0.2s) | #a0a0a0 + 删除线 | 同上,写 doneAt |
| 整单完成 | — | 进度条 100%、卡片转绿 | 最后一项勾选时播放特效 |
| 动效 | 时长 | 曲线 / 实现 | 说明 |
|---|---|---|---|
| 环形增长 | 450ms | cubic-bezier(.4,0,.2,1),stroke-dashoffset 过渡 | 12 点方向顺时针增长 |
| 对勾入场 | 320ms | scale(.4) → 1 + 透明度 | 达标瞬间出现 |
| 完成粒子 | ≤900ms | 14 颗粒子按角度 --a、距离 --d 扩散,交错 40ms 延迟 | 不阻塞点击 |
| 光环脉冲 | 700ms | 主色圆环放大淡出 | 与粒子同时开始 |
| 触感反馈 | 18ms | navigator.vibrate(18) | WebView 不支持则静默跳过 |
| 进度条填充 | 400ms | width 过渡 | 清单勾选后更新 |
| 视图切换 | — | SwipeTabs 跟手横滑 | 与既有模块一致 |
| 项 | 约定 |
|---|---|
| 视口 | 设计稿 420×820;375~430px 内元素不换行、不裁切;底部 TabBar 4 项每项 ≥ 44px 可点宽度 |
| 安全区 | TabBar 使用 antd-mobile safeArea,页面底部留出 tabbar-h + safe-bottom |
| 动效 | 特效恒开(V0.2 设计变更,无开关):单次 ≤900ms、pointer-events:none,不阻塞连续打卡;不再响应 prefers-reduced-motion |
| 大字号 | 卡片采用 grid 自适应列宽,文字超长换行不截断;名称限制 20 字、检查项 40 字 |
| 深色模式 | V0.2 沿用现有浅色主题,暂不适配 |
本文档为静态设计稿,不含脚本逻辑;实现对应 src/pages/checkin/*.jsx、src/components/RingProgress.jsx 与样式段(src/styles/globals.css)。接口与数据口径见《设计文档.md》与《数据库设计文档.md》。