feat(V0.2): 打卡 / 日历 / 清单模块

- 数据: Habit/CheckIn/CheckList/CheckListItem/CheckListTemplate + 迁移 + 重新生成 client
- 后端: server/checkin/period.js 周期计算(日/周/月/年, 周一起始, Asia/Shanghai)
        /api/checkin/* 打卡项CRUD/打卡/撤销/补打/某日详情/月历
        /api/checklists/* 清单与检查项CRUD/勾选/全选/复制/模板(系统预置出差·回老家)
- 前端: 底部新增「打卡」Tab -> /checkin, 页内三视图
        环形进度 RingProgress + 完成特效(粒子/光晕/触感, 可关闭)
        打卡视图: 待办列表/乐观更新/撤销/新建编辑
        日历视图: 月历网格 + 今天·昨天·明天 + 日期标记/完成率
        清单视图: 场景清单/勾选进度条/模板生成/另存模板/归档
- 文档: docs/V0.2/需求文档.md 补充实现约定(附录B)与接口清单
This commit is contained in:
cheney
2026-10-22 11:37:16 +08:00
parent 54a3224f00
commit 004f8c262d
32 changed files with 11030 additions and 63 deletions
@@ -68,7 +68,12 @@ export const ModelName = {
MihomeHome: 'MihomeHome',
MihomeDevice: 'MihomeDevice',
MihomeEnvSample: 'MihomeEnvSample',
MihomeEnvHour: 'MihomeEnvHour'
MihomeEnvHour: 'MihomeEnvHour',
Habit: 'Habit',
CheckIn: 'CheckIn',
CheckList: 'CheckList',
CheckListItem: 'CheckListItem',
CheckListTemplate: 'CheckListTemplate'
} as const
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
@@ -363,6 +368,81 @@ export const MihomeEnvHourScalarFieldEnum = {
export type MihomeEnvHourScalarFieldEnum = (typeof MihomeEnvHourScalarFieldEnum)[keyof typeof MihomeEnvHourScalarFieldEnum]
export const HabitScalarFieldEnum = {
id: 'id',
userId: 'userId',
name: 'name',
period: 'period',
target: 'target',
color: 'color',
icon: 'icon',
note: 'note',
archived: 'archived',
sortOrder: 'sortOrder',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type HabitScalarFieldEnum = (typeof HabitScalarFieldEnum)[keyof typeof HabitScalarFieldEnum]
export const CheckInScalarFieldEnum = {
id: 'id',
habitId: 'habitId',
userId: 'userId',
date: 'date',
seq: 'seq',
note: 'note',
source: 'source',
createdAt: 'createdAt'
} as const
export type CheckInScalarFieldEnum = (typeof CheckInScalarFieldEnum)[keyof typeof CheckInScalarFieldEnum]
export const CheckListScalarFieldEnum = {
id: 'id',
userId: 'userId',
title: 'title',
scene: 'scene',
note: 'note',
archived: 'archived',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type CheckListScalarFieldEnum = (typeof CheckListScalarFieldEnum)[keyof typeof CheckListScalarFieldEnum]
export const CheckListItemScalarFieldEnum = {
id: 'id',
listId: 'listId',
title: 'title',
note: 'note',
done: 'done',
doneAt: 'doneAt',
sortOrder: 'sortOrder',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type CheckListItemScalarFieldEnum = (typeof CheckListItemScalarFieldEnum)[keyof typeof CheckListItemScalarFieldEnum]
export const CheckListTemplateScalarFieldEnum = {
id: 'id',
userId: 'userId',
name: 'name',
scene: 'scene',
items: 'items',
builtin: 'builtin',
createdAt: 'createdAt',
updatedAt: 'updatedAt'
} as const
export type CheckListTemplateScalarFieldEnum = (typeof CheckListTemplateScalarFieldEnum)[keyof typeof CheckListTemplateScalarFieldEnum]
export const SortOrder = {
asc: 'asc',
desc: 'desc'
@@ -566,3 +646,48 @@ export const MihomeEnvSampleOrderByRelevanceFieldEnum = {
export type MihomeEnvSampleOrderByRelevanceFieldEnum = (typeof MihomeEnvSampleOrderByRelevanceFieldEnum)[keyof typeof MihomeEnvSampleOrderByRelevanceFieldEnum]
export const HabitOrderByRelevanceFieldEnum = {
name: 'name',
period: 'period',
color: 'color',
icon: 'icon',
note: 'note'
} as const
export type HabitOrderByRelevanceFieldEnum = (typeof HabitOrderByRelevanceFieldEnum)[keyof typeof HabitOrderByRelevanceFieldEnum]
export const CheckInOrderByRelevanceFieldEnum = {
date: 'date',
note: 'note',
source: 'source'
} as const
export type CheckInOrderByRelevanceFieldEnum = (typeof CheckInOrderByRelevanceFieldEnum)[keyof typeof CheckInOrderByRelevanceFieldEnum]
export const CheckListOrderByRelevanceFieldEnum = {
title: 'title',
scene: 'scene',
note: 'note'
} as const
export type CheckListOrderByRelevanceFieldEnum = (typeof CheckListOrderByRelevanceFieldEnum)[keyof typeof CheckListOrderByRelevanceFieldEnum]
export const CheckListItemOrderByRelevanceFieldEnum = {
title: 'title',
note: 'note'
} as const
export type CheckListItemOrderByRelevanceFieldEnum = (typeof CheckListItemOrderByRelevanceFieldEnum)[keyof typeof CheckListItemOrderByRelevanceFieldEnum]
export const CheckListTemplateOrderByRelevanceFieldEnum = {
name: 'name',
scene: 'scene'
} as const
export type CheckListTemplateOrderByRelevanceFieldEnum = (typeof CheckListTemplateOrderByRelevanceFieldEnum)[keyof typeof CheckListTemplateOrderByRelevanceFieldEnum]