新增积分系统:打卡/测试达标赚积分,纯累计可配置

- point_rule 规则表 + point_log 流水表(0008 迁移),唯一键防刷:同一事件首次达标才发放,重复静默返回 0
- 打卡分值随任务设置(模板/实例 points 字段,默认 10);测试类 6 种事件按规则表取值,各有默认分(单词 20/数学课 15/语法点 15/周测 50×2/考试通过 100)
- 发放埋点 6 处:打卡、单词检测、数学课、语法知识点、英语/数学周测、考试通过;周测达标联动打卡实例不重复计分
- 孩子端:/kid 总积分徽章,新增 /points 积分页(总积分+流水),测验结果页即时显示「+N 积分」,周测结果页刷新后从流水取回已发积分
- 家长端:功能管理新增「积分管理」Section(规则分值配置+每孩子总积分/最近流水);任务管理内联编辑任务分值
- 修复:drizzle 将 mysql2 重复键错误包进 cause,沿错误链识别 ER_DUP_ENTRY

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jacobxu666
2026-08-18 17:58:53 +08:00
co-authored by Claude Opus 4.8
parent 841f937b8e
commit 7a11a89031
27 changed files with 592 additions and 41 deletions
+42
View File
@@ -0,0 +1,42 @@
-- xuchao: 积分系统——规则表 + 流水表(唯一键防刷) + 任务表加 points 列。全部幂等。
CREATE TABLE IF NOT EXISTS `point_rule` (
`id` bigint AUTO_INCREMENT NOT NULL,
`event_type` varchar(30) NOT NULL,
`points` int NOT NULL DEFAULT 0,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `point_rule_id` PRIMARY KEY(`id`),
UNIQUE KEY `uq_point_rule_event` (`event_type`)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS `point_log` (
`id` bigint AUTO_INCREMENT NOT NULL,
`child_user_id` bigint NOT NULL,
`event_type` varchar(30) NOT NULL,
`ref_key` varchar(100) NOT NULL,
`points` int NOT NULL,
`remark` varchar(200) NOT NULL DEFAULT '',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `point_log_id` PRIMARY KEY(`id`),
UNIQUE KEY `uq_point_log_dedup` (`child_user_id`, `event_type`, `ref_key`),
KEY `idx_point_log_child` (`child_user_id`)
);
--> statement-breakpoint
SET @has_tpl_points = (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'task_template' AND column_name = 'points');
--> statement-breakpoint
SET @ddl = IF(@has_tpl_points = 0, 'ALTER TABLE `task_template` ADD COLUMN `points` int NOT NULL DEFAULT 10', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt FROM @ddl;
--> statement-breakpoint
EXECUTE stmt;
--> statement-breakpoint
DEALLOCATE PREPARE stmt;
--> statement-breakpoint
SET @has_inst_points = (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'task_instance' AND column_name = 'points');
--> statement-breakpoint
SET @ddl2 = IF(@has_inst_points = 0, 'ALTER TABLE `task_instance` ADD COLUMN `points` int NOT NULL DEFAULT 10', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt2 FROM @ddl2;
--> statement-breakpoint
EXECUTE stmt2;
--> statement-breakpoint
DEALLOCATE PREPARE stmt2;