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
+28
View File
@@ -0,0 +1,28 @@
import { useState } from 'react'
import { NavBar } from 'antd-mobile'
import SwipeTabs from '../../components/SwipeTabs.jsx'
import HabitView from './HabitView.jsx'
import CalendarView from './CalendarView.jsx'
import ListView from './ListView.jsx'
import { toDateStr } from './date.js'
// 打卡页: 一个页面三个视图 —— 打卡(环形进度) / 日历(今天·昨天·明天) / 清单(场景检查)
export default function CheckinPage() {
const [active, setActive] = useState('habit')
const [date, setDate] = useState(() => toDateStr())
const tabs = [
{ key: 'habit', label: '打卡', render: () => <HabitView date={date} /> },
{ key: 'calendar', label: '日历', render: () => <CalendarView date={date} onDateChange={setDate} /> },
{ key: 'list', label: '清单', render: () => <ListView /> },
]
return (
<div className="page-with-navbar">
<NavBar back={null}>打卡</NavBar>
<div className="checkin-content">
<SwipeTabs tabs={tabs} active={active} onChange={setActive} />
</div>
</div>
)
}