Compare commits
1
Commits
dev-0.1
...
54a3224f00
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54a3224f00 |
@@ -0,0 +1,295 @@
|
|||||||
|
# iBoard V0.2 需求文档 — 打卡 / 日历 / 清单
|
||||||
|
|
||||||
|
> 版本:V0.2 · 分支:`dev-0.2` · 状态:待评审 · 日期:2026-10-22
|
||||||
|
> 目标项目:iboard(Tauri 2 + React 18 + antd-mobile + Express + Prisma/MariaDB,移动端优先)
|
||||||
|
> 基线版本:V0.1(`dev-0.1`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 总体描述
|
||||||
|
|
||||||
|
在 iBoard 移动端新增一个「打卡」模块,用**一个页面、三个视图**解决两类日常需求:
|
||||||
|
|
||||||
|
1. **周期性打卡**(习惯养成):用户定义"每天 n 次 / 每周 n 次 / 每月 n 次 / 每年 n 次"的目标,
|
||||||
|
每次打卡后卡片上的**环形进度**按 `已完成次数 / 目标次数` 增长,达标时环形闭合并播放完成特效;
|
||||||
|
2. **日历回看**:以日历为载体,快速查看**今天**(要做什么)、**昨天**(做得怎样)、
|
||||||
|
**明天**(计划做什么),日期上以圆点/实心标记完成情况;
|
||||||
|
3. **检查清单**(场景化一次性事项):面向**出差、回老家**等临时场景,逐条勾选确认,
|
||||||
|
避免遗漏;清单可复用为模板,下次一键生成。
|
||||||
|
|
||||||
|
一句话:**用环形进度做周期性打卡,用日历做时间维度的回看与计划,用清单覆盖临时性的检查场景。**
|
||||||
|
|
||||||
|
### 1.1 本期范围
|
||||||
|
|
||||||
|
- 单用户使用,数据按登录用户隔离(复用现有 JWT 鉴权)。
|
||||||
|
- 移动端优先(`MobileShell` + 底部 TabBar 体系),桌面浏览器兼容可用即可。
|
||||||
|
- 数据落库 MariaDB,通过现有 Express `/api/*` 提供接口。
|
||||||
|
|
||||||
|
### 1.2 不在本期范围(明确排除)
|
||||||
|
|
||||||
|
- 多人协作 / 共享打卡 / 打卡排行榜。
|
||||||
|
- 系统通知、推送提醒、定时提醒(V0.2 不引入通知能力)。
|
||||||
|
- 复杂统计报表(周报/月报/趋势图),本期只提供完成率概览。
|
||||||
|
- 桌面端专用布局、横屏适配。
|
||||||
|
- 清单的周期性重复(如"每次出差都生成"),本期只做**临时清单 + 模板手动复用**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 术语与概念定义
|
||||||
|
|
||||||
|
| 术语 | 定义 |
|
||||||
|
| --- | --- |
|
||||||
|
| **打卡项(Habit)** | 一个被跟踪的周期性目标,如"喝水 每天 8 次""健身 每周 3 次" |
|
||||||
|
| **周期类型** | `day` / `week` / `month` / `year`,决定进度统计窗口 |
|
||||||
|
| **目标次数 n** | 一个周期内需要完成的打卡次数,n ≥ 1 |
|
||||||
|
| **周期窗口** | 日=自然日;周=自然周(周一 00:00 至周日 23:59);月=自然月;年=自然年。时区统一 Asia/Shanghai |
|
||||||
|
| **打卡记录(CheckIn)** | 一次打卡动作,归属到某个**本地日历日**(可补打到过去日期) |
|
||||||
|
| **环形进度** | 卡片上的圆环组件,`进度 = min(已完成次数 / n, 1)`;达标=闭合 |
|
||||||
|
| **清单(CheckList)** | 一次性检查清单,如"出差 · 10月杭州",含若干检查项 |
|
||||||
|
| **检查项(CheckItem)** | 清单中的单条待检查事项,勾选即完成 |
|
||||||
|
| **模板(Template)** | 可被复用的清单结构(一组检查项标题),用于一键生成新清单 |
|
||||||
|
| **日期状态** | 某日的打卡完成情况:全部完成 / 部分完成 / 未开始 / 超额完成 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 需求点
|
||||||
|
|
||||||
|
**编号规则**:`类型-模块-序号`。类型:F=功能需求、U=交互与体验、D=数据、N=非功能、E=异常与边界。
|
||||||
|
模块:CK=打卡、CL=日历、LS=清单、SY=通用。
|
||||||
|
|
||||||
|
**优先级**:P0 = 本期必须有;P1 = 本期应该有;P2 = 有则更好(可延后)。
|
||||||
|
|
||||||
|
### 3.1 功能需求 — 打卡(F-CK)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| F-CK-01 | 支持新建打卡项:名称、周期类型、目标次数 n、颜色、图标、备注 | 表单校验:名称必填且 ≤ 20 字;n 为 ≥1 的整数 | P0 |
|
||||||
|
| F-CK-02 | 周期类型支持**每天 n 次 / 每周 n 次 / 每月 n 次 / 每年 n 次**四种 | 四种类型均可创建并正确统计 | P0 |
|
||||||
|
| F-CK-03 | 卡片以**环形进度**展示当前周期完成情况,环中心显示 `已完成/n` | 进度 = 已完成次数 / n,上限 100% | P0 |
|
||||||
|
| F-CK-04 | **每天 1 次**的打卡项:打卡后环形**直接闭合**(100%),卡片进入"已完成"态 | 一次点击即闭合,不出现 50% 之类的中间态 | P0 |
|
||||||
|
| F-CK-05 | **每周 n 次**(及月/年):每打卡一次环形闭合对应百分比(如 n=3,打 1 次=33.3%、2 次=66.7%、3 次=100% 闭合) | 进度随每次打卡实时刷新,带过渡动画 | P0 |
|
||||||
|
| F-CK-06 | 打卡主操作:点击卡片上的打卡按钮即完成一次打卡 | 单击即生效,响应 < 300ms(乐观更新) | P0 |
|
||||||
|
| F-CK-07 | 打卡**完成特效**:达标(进度达 100%)时播放特效——环形闭合动画 + 光晕/粒子扩散 + 轻量触感反馈 | 特效时长 ≤ 800ms,不阻塞后续操作 | P0 |
|
||||||
|
| F-CK-08 | 打卡记录需记录**发生日期**(本地日历日)与时间戳 | 支持按日回看,跨零点归属正确 | P0 |
|
||||||
|
| F-CK-09 | 支持**撤销**:可撤销本周期内最近一次打卡(主要是误触场景) | 撤销后进度回退,记录物理删除或标记撤销 | P1 |
|
||||||
|
| F-CK-10 | 支持**补打卡**:对过去日期补记一次打卡,默认允许回溯 7 天 | 补打后对应日期的状态与进度同步更新 | P1 |
|
||||||
|
| F-CK-11 | **不允许提前打卡**(未来日期不可打卡) | 明天的项只展示为"计划",按钮置灰 | P0 |
|
||||||
|
| F-CK-12 | 展示**连续完成天数/周期数(streak)** | 如"已连续 5 天",断签归零 | P1 |
|
||||||
|
| F-CK-13 | 打卡项可**编辑**(改名/改 n/改颜色/改周期)与**停用(归档)** | 归档后不出现在今日待办,历史保留 | P1 |
|
||||||
|
| F-CK-14 | 修改目标次数 n 后,**当前周期**进度按新 n 重算展示,不改写历史记录 | 例如 n 由 3 改 5,已完成 3 次 → 显示 3/5(60%) | P1 |
|
||||||
|
| F-CK-15 | **超额打卡**:周期内超过 n 仍可继续打卡,环形保持闭合,中心显示 `n+k`(如 3+1) | 不清零、不报错 | P2 |
|
||||||
|
| F-CK-16 | 打卡项支持**排序**(拖动或置顶)与分组展示 | 今日列表按"未完成在前、已完成在后"默认排序 | P2 |
|
||||||
|
| F-CK-17 | 打卡时可附带**备注**(可选,纯文本) | 列表详情中可查看 | P2 |
|
||||||
|
|
||||||
|
### 3.2 功能需求 — 日历(F-CL)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| F-CL-01 | 提供**月历视图**:当月日历网格,可切换上/下月,点击日期查看当日详情 | 周一起始,周一~周日七列 | P0 |
|
||||||
|
| F-CL-02 | **今天**视图(默认):列出今天应打卡的项及完成状态,可直接打卡 | 打开页面默认定位今天 | P0 |
|
||||||
|
| F-CL-03 | **昨天**视图:展示昨天各打卡项的**已完成结果**(完成/未完成/超额),未完成项可进行补打 | 以回看为主,标记为"已完成的历史" | P0 |
|
||||||
|
| F-CL-04 | **明天**视图:展示**明天计划要打卡的项**(按周期规则推算),只读,不可打卡 | 明确标注"计划",打卡按钮不可用 | P0 |
|
||||||
|
| F-CL-05 | 今天/昨天/明天**快捷切换**(顶部 Segmented 或左右滑动) | 一键切换,切换有过渡动画 | P0 |
|
||||||
|
| F-CL-06 | **日期标记**:月历中每个日期按完成情况标记——全部完成(实心)、部分完成(半填充)、未开始(空心/无标记)、超额完成(特殊标记) | 一眼能看出当月坚持情况 | P0 |
|
||||||
|
| F-CL-07 | **日期详情**:点击某日期,展示当天每个打卡项的"目标次数 / 已完成次数 / 状态" | 过去日期可补打,未来日期只读 | P0 |
|
||||||
|
| F-CL-08 | 日历与打卡**数据同源**:打卡操作在日历视图与打卡列表视图中即时一致 | 任一处打卡,另一处刷新 | P0 |
|
||||||
|
| F-CL-09 | 月历顶部展示**当月完成率**(完成次数 / 应完成次数) | 百分比展示 | P1 |
|
||||||
|
| F-CL-10 | 支持左右**滑动手势**切换月份 | 与按钮切换等价 | P2 |
|
||||||
|
| F-CL-11 | 月视图支持简单的**完成热力**(按完成率深浅着色) | 可选展示,默认关闭 | P2 |
|
||||||
|
|
||||||
|
### 3.3 功能需求 — 清单(F-LS)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| F-LS-01 | 支持新建**检查清单**:名称、场景标签(出差 / 回老家 / 自定义)、备注 | 名称必填,场景标签可空 | P0 |
|
||||||
|
| F-LS-02 | 清单内可**增删改检查项**,支持排序 | 单条 ≤ 40 字 | P0 |
|
||||||
|
| F-LS-03 | **勾选完成**:点击检查项前的复选框即打勾,已完成项置灰 + 删除线;可取消勾选 | 单击切换,状态即时保存 | P0 |
|
||||||
|
| F-LS-04 | 清单头部显示**进度**:`已完成 / 总数` + 进度条;全部完成时显示完成态 | 全部勾完触发完成提示 | P0 |
|
||||||
|
| F-LS-05 | 清单**全部完成**时播放完成特效(与 F-CK-07 同一套特效组件) | 复用,风格统一 | P1 |
|
||||||
|
| F-LS-06 | **模板**:系统预置常用模板(出差、回老家),一键基于模板生成新清单 | 至少 2 个预置模板 | P1 |
|
||||||
|
| F-LS-07 | **另存为模板**:用户可将自己的清单保存为自定义模板,后续复用 | 自定义模板可删除 | P1 |
|
||||||
|
| F-LS-08 | **复用历史清单**:从历史清单复制生成一份新清单(勾选状态重置) | 原清单保持不变 | P1 |
|
||||||
|
| F-LS-09 | 清单**归档/删除**:完成的清单可归档(不出现在进行中列表),可查看历史 | 删除需二次确认 | P1 |
|
||||||
|
| F-LS-10 | 清单项支持**备注/数量**说明(如"充电器 ×1") | 展示在标题下方,弱色小字 | P2 |
|
||||||
|
| F-LS-11 | 清单支持**一键全部勾选 / 全部取消** | 批量操作入口 | P2 |
|
||||||
|
|
||||||
|
### 3.4 功能需求 — 通用(F-SY)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| F-SY-01 | 底部 TabBar 新增**「打卡」页**(现有 4 个 Tab → 5 个),作为本模块唯一入口 | 图标风格与现有 TabIcon 一致 | P0 |
|
||||||
|
| F-SY-02 | 「打卡」页内以子 Tab(Segmented / SwipeTabs)切换 **打卡 / 日历 / 清单** 三个视图 | 复用现有 `SwipeTabs` 组件 | P0 |
|
||||||
|
| F-SY-03 | 所有接口复用现有鉴权(`authRequired`,JWT),数据按 `userId` 隔离 | 未登录跳转 `/login` | P0 |
|
||||||
|
| F-SY-04 | 后端新增 REST 路由(建议 `/api/checkin/*`、`/api/checklist/*`),挂载到 `server/index.js` | 与现有路由风格一致 | P0 |
|
||||||
|
| F-SY-05 | 时间处理统一 **Asia/Shanghai**,前端与后端对"日历日"的判定一致 | 跨零点打卡归属当天 | P0 |
|
||||||
|
| F-SY-06 | 打卡/勾选操作采用**乐观更新**,接口失败时回滚并 Toast 提示 | 失败可见、状态不失真 | P1 |
|
||||||
|
| F-SY-07 | 写接口**幂等/防抖**:同一打卡项 1 秒内重复点击只记一次 | 前端防抖 + 后端唯一约束双保险 | P1 |
|
||||||
|
| F-SY-08 | 页面可见性变化时刷新数据(复用 `useRefreshOnVisible`) | 从后台切回自动同步 | P1 |
|
||||||
|
|
||||||
|
### 3.5 交互与体验需求(U)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| U-01 | **环形进度组件**:SVG 圆环,背景环 + 进度环,进度变化带 400ms ease-out 动画 | 组件可复用(打卡卡片、清单进度共用) | P0 |
|
||||||
|
| U-02 | **完成特效**:达标瞬间环形闭合 + 光晕/粒子扩散,约 600ms;可重复观看不烦扰 | 不阻塞操作,动画结束自动清理 | P0 |
|
||||||
|
| U-03 | **触感反馈**:完成打卡时轻量震动(Web Vibration API / Tauri),可在设置中关闭 | 默认开启,关闭后仅视觉反馈 | P1 |
|
||||||
|
| U-04 | 移动端适配:375~430px 视口,复用 `globals.css` 的 `.card` 体系,安全区与底部 TabBar 不遮挡内容 | 真机无横向滚动、无遮挡 | P0 |
|
||||||
|
| U-05 | 空态 / 加载态 / 错误态三态齐全(首次使用引导"创建第一个打卡项") | 空态有明确 CTA | P0 |
|
||||||
|
| U-06 | 打卡按钮足够大(点击热区 ≥ 44×44),符合移动端触控规范 | 误触率低 | P1 |
|
||||||
|
| U-07 | 动效**性能降级**:低端设备或 `prefers-reduced-motion` 时关闭粒子特效,仅保留进度动画 | 不卡顿 | P1 |
|
||||||
|
| U-08 | 深浅色:跟随现有浅色主题,卡片/分割线风格与首页、监控页一致 | 视觉统一 | P1 |
|
||||||
|
| U-09 | 清单勾选有明确的勾选动画(勾形描边动画) | 反馈即时 | P2 |
|
||||||
|
|
||||||
|
### 3.6 数据需求(D)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| D-01 | 新增 Prisma 模型:`Habit`(打卡项)、`CheckIn`(打卡记录) | 字段见附录 A | P0 |
|
||||||
|
| D-02 | 新增 Prisma 模型:`CheckList`(清单)、`CheckListItem`(检查项)、`CheckListTemplate`(模板,P1) | 字段见附录 A | P0 |
|
||||||
|
| D-03 | `Habit` / `CheckList` 均带 `userId` 外键,删除用户级联删除 | 数据隔离 | P0 |
|
||||||
|
| D-04 | `CheckIn` 建立 `(habitId, date)` 索引,支持按日期范围查询 | 日历月查询走索引 | P0 |
|
||||||
|
| D-05 | 提供迁移 SQL 并纳入 `prisma migrate deploy` 流程 | 与 V0.1 迁移流程一致 | P0 |
|
||||||
|
| D-06 | 软删除语义:`Habit.archived`、`CheckList.archived`,历史记录保留 | 不物理删除历史 | P1 |
|
||||||
|
|
||||||
|
### 3.7 非功能需求(N)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 验收要点 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| N-01 | 页面首屏数据加载 < 1.5s(内网/正常网络),交互响应 < 300ms(乐观更新) | 真机可感知流畅 | P0 |
|
||||||
|
| N-02 | 兼容 Android WebView(Tauri 打包)与移动端浏览器,不依赖桌面专有 API | 真机验证 | P0 |
|
||||||
|
| N-03 | 单用户数据量按"千级记录/年"设计,无需分表;月查询一次请求返回 | 日历切月无等待感 | P1 |
|
||||||
|
| N-04 | 所有接口 `authRequired`,越权访问返回 401 | 安全基线 | P0 |
|
||||||
|
| N-05 | 前端代码组织遵循现有约定:`src/pages/checkin/*` + `src/components/*` + `server/routes/*` | 结构一致 | P0 |
|
||||||
|
|
||||||
|
### 3.8 异常与边界需求(E)
|
||||||
|
|
||||||
|
| 编号 | 需求描述 | 处理约定 | 优先级 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| E-01 | 重复点击打卡 | 前端防抖 + 后端唯一约束,只记一次 | P0 |
|
||||||
|
| E-02 | 接口失败 / 断网 | 乐观更新回滚 + Toast 提示,可重试 | P0 |
|
||||||
|
| E-03 | **周期中途新建**打卡项(如周三创建"每周 3 次") | 本期按**完整目标 n** 计算,不按剩余天数折算 | P1 |
|
||||||
|
| E-04 | 每月 n 次在天数不同的月份 | 按**自然月**窗口,不折算 | P0 |
|
||||||
|
| E-05 | 每年 n 次跨年 | 按**自然年**窗口,年末清零 | P0 |
|
||||||
|
| E-06 | 删除打卡项 | 归档(软删除)为主;硬删除需二次确认并提示"历史记录将一并删除" | P1 |
|
||||||
|
| E-07 | 清单项全部删除后清单进度为 0/0 | 显示空清单,不显示 100% | P1 |
|
||||||
|
| E-08 | 跨零点打卡(23:59 → 00:00) | 以**提交时刻的本地日历日**归属 | P0 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 优先级汇总(本期交付范围)
|
||||||
|
|
||||||
|
- **P0(必须)**:F-CK-01~08、F-CK-11;F-CL-01~08;F-LS-01~04;F-SY-01~05;U-01、U-02、U-04、U-05;D-01~05;N-01、N-02、N-04、N-05;E-01、E-02、E-04、E-05、E-08。
|
||||||
|
- **P1(应该)**:F-CK-09、10、12~14;F-CL-09;F-LS-05~09;F-SY-06~08;U-03、U-06~08;D-06;N-03;E-03、E-06、E-07。
|
||||||
|
- **P2(可选/延后)**:F-CK-15~17;F-CL-10、11;F-LS-10、11;U-09。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 里程碑建议
|
||||||
|
|
||||||
|
| 里程碑 | 内容 |
|
||||||
|
| --- | --- |
|
||||||
|
| **M1 数据与接口** | Prisma 模型 + 迁移;`server/routes/checkin.js`、`checklist.js`;周期进度计算与日期查询 |
|
||||||
|
| **M2 打卡视图** | 环形进度组件 + 打卡卡片列表 + 打卡/撤销/补打 + 完成特效 |
|
||||||
|
| **M3 日历视图** | 月历网格 + 今天/昨天/明天三视图 + 日期标记 + 日期详情 |
|
||||||
|
| **M4 清单视图** | 清单 CRUD + 勾选交互 + 进度条 + 模板与复用 |
|
||||||
|
| **M5 联调打磨** | 真机验证、动效降级、空态/错误态、性能与跨天边界 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 待确认问题(评审时决策)
|
||||||
|
|
||||||
|
| # | 问题 | 建议 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 1 | 是否新增第 5 个底部 Tab「打卡」,还是放在首页入口? | 建议新增 Tab,入口最清晰 |
|
||||||
|
| 2 | 周起始日是周一还是周日? | 建议周一(国内习惯) |
|
||||||
|
| 3 | 是否允许"明天提前打卡"? | 建议**不允许**(F-CK-11),保持统计口径干净 |
|
||||||
|
| 4 | 删除打卡项时历史是否保留? | 建议默认归档保留,硬删除才清历史 |
|
||||||
|
| 5 | 预置模板具体包含哪些项? | 评审时列出"出差/回老家"各 8~12 条初始项 |
|
||||||
|
| 6 | 完成特效是否可全局关闭? | 建议在"我"页提供开关(默认开) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 附录 A:核心实体草案(供设计阶段参考,非最终表结构)
|
||||||
|
|
||||||
|
```prisma
|
||||||
|
// 打卡项
|
||||||
|
model Habit {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
userId Int
|
||||||
|
name String
|
||||||
|
period String // day | week | month | year
|
||||||
|
target Int @default(1) // 周期内目标次数 n
|
||||||
|
color String @default("#1677ff")
|
||||||
|
icon String @default("")
|
||||||
|
note String @default("")
|
||||||
|
archived Boolean @default(false)
|
||||||
|
sortOrder Int @default(0)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
records CheckIn[]
|
||||||
|
|
||||||
|
@@index([userId, archived])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打卡记录(一次打卡 = 一条;同日多次为多条)
|
||||||
|
model CheckIn {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
habitId Int
|
||||||
|
habit Habit @relation(fields: [habitId], references: [id], onDelete: Cascade)
|
||||||
|
userId Int
|
||||||
|
date String // 本地日历日 "YYYY-MM-DD" (Asia/Shanghai)
|
||||||
|
seq Int @default(1) // 当日第几次 (1..n, 超额继续累加)
|
||||||
|
note String @default("")
|
||||||
|
source String @default("user") // user | backfill(补打)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
@@unique([habitId, date, seq])
|
||||||
|
@@index([userId, date])
|
||||||
|
@@index([habitId, date])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查清单
|
||||||
|
model CheckList {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
userId Int
|
||||||
|
title String
|
||||||
|
scene String @default("") // 出差 | 回老家 | 自定义
|
||||||
|
note String @default("")
|
||||||
|
archived Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
items CheckListItem[]
|
||||||
|
|
||||||
|
@@index([userId, archived])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查项
|
||||||
|
model CheckListItem {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
listId Int
|
||||||
|
list CheckList @relation(fields: [listId], references: [id], onDelete: Cascade)
|
||||||
|
title String
|
||||||
|
note String @default("")
|
||||||
|
done Boolean @default(false)
|
||||||
|
doneAt DateTime?
|
||||||
|
sortOrder Int @default(0)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
@@index([listId, sortOrder])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清单模板(P1)
|
||||||
|
model CheckListTemplate {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
userId Int? // null = 系统预置
|
||||||
|
name String
|
||||||
|
scene String @default("")
|
||||||
|
items Json // [{ title, note }]
|
||||||
|
builtin Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 说明:周期进度由 `CheckIn` 按周期窗口现场聚合(不冗余计数字段),避免并发与修改 n 后的一致性问题。
|
||||||
Reference in New Issue
Block a user