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
@@ -0,0 +1,99 @@
-- CreateTable
CREATE TABLE `Habit` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NOT NULL,
`name` VARCHAR(191) NOT NULL,
`period` VARCHAR(191) NOT NULL DEFAULT 'day',
`target` INTEGER NOT NULL DEFAULT 1,
`color` VARCHAR(191) NOT NULL DEFAULT '#1677ff',
`icon` VARCHAR(191) NOT NULL DEFAULT '',
`note` VARCHAR(191) NOT NULL DEFAULT '',
`archived` BOOLEAN NOT NULL DEFAULT false,
`sortOrder` INTEGER NOT NULL DEFAULT 0,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `Habit_userId_archived_sortOrder_idx`(`userId`, `archived`, `sortOrder`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `CheckIn` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`habitId` INTEGER NOT NULL,
`userId` INTEGER NOT NULL,
`date` VARCHAR(10) NOT NULL,
`seq` INTEGER NOT NULL DEFAULT 1,
`note` VARCHAR(191) NOT NULL DEFAULT '',
`source` VARCHAR(191) NOT NULL DEFAULT 'user',
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
UNIQUE INDEX `CheckIn_habitId_date_seq_key`(`habitId`, `date`, `seq`),
INDEX `CheckIn_userId_date_idx`(`userId`, `date`),
INDEX `CheckIn_habitId_date_idx`(`habitId`, `date`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `CheckList` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NOT NULL,
`title` VARCHAR(191) NOT NULL,
`scene` VARCHAR(191) NOT NULL DEFAULT '',
`note` VARCHAR(191) NOT NULL DEFAULT '',
`archived` BOOLEAN NOT NULL DEFAULT false,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `CheckList_userId_archived_idx`(`userId`, `archived`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `CheckListItem` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`listId` INTEGER NOT NULL,
`title` VARCHAR(191) NOT NULL,
`note` VARCHAR(191) NOT NULL DEFAULT '',
`done` BOOLEAN NOT NULL DEFAULT false,
`doneAt` DATETIME(3) NULL,
`sortOrder` INTEGER NOT NULL DEFAULT 0,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `CheckListItem_listId_sortOrder_idx`(`listId`, `sortOrder`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `CheckListTemplate` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`userId` INTEGER NULL,
`name` VARCHAR(191) NOT NULL,
`scene` VARCHAR(191) NOT NULL DEFAULT '',
`items` JSON NOT NULL,
`builtin` BOOLEAN NOT NULL DEFAULT false,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `CheckListTemplate_userId_builtin_idx`(`userId`, `builtin`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Habit` ADD CONSTRAINT `Habit_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `CheckIn` ADD CONSTRAINT `CheckIn_habitId_fkey` FOREIGN KEY (`habitId`) REFERENCES `Habit`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `CheckIn` ADD CONSTRAINT `CheckIn_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `CheckList` ADD CONSTRAINT `CheckList_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `CheckListItem` ADD CONSTRAINT `CheckListItem_listId_fkey` FOREIGN KEY (`listId`) REFERENCES `CheckList`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `CheckListTemplate` ADD CONSTRAINT `CheckListTemplate_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;