新增解答题拍照判分:百炼 Qwen-VL 按评分点逐点判分,无 API Key 时演示判分回退;混合卷按真实分值加权计分;判分照片与评分点进错题本;补齐历史迁移缺口(0005 模板生效方式/0006 五张缺失表+grammar_progress point_id)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jacobxu666
2026-08-17 16:24:23 +08:00
co-authored by Claude Opus 4.8
parent 4033abc21d
commit f80a931ef0
21 changed files with 1377 additions and 45 deletions
+22
View File
@@ -0,0 +1,22 @@
CREATE TABLE `ai_grade_log` (
`id` bigint AUTO_INCREMENT NOT NULL,
`child_user_id` bigint NOT NULL,
`paper_id` varchar(191) NOT NULL,
`question_index` int NOT NULL,
`oss_key` varchar(300) NOT NULL,
`status` varchar(20) NOT NULL,
`earned` int NOT NULL DEFAULT 0,
`points` int NOT NULL DEFAULT 0,
`verdict` text,
`mock` boolean NOT NULL DEFAULT false,
`model` varchar(60),
`ms` int,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `ai_grade_log_id` PRIMARY KEY(`id`)
);
--> statement-breakpoint
ALTER TABLE `ai_grade_log` ADD CONSTRAINT `ai_grade_log_child_user_id_user_id_fk` FOREIGN KEY (`child_user_id`) REFERENCES `user`(`id`) ON DELETE cascade ON UPDATE no action;
--> statement-breakpoint
CREATE INDEX `idx_ai_grade_child_date` ON `ai_grade_log` (`child_user_id`,`created_at`);
--> statement-breakpoint
CREATE INDEX `idx_ai_grade_paper_q` ON `ai_grade_log` (`child_user_id`,`paper_id`,`question_index`);
+11
View File
@@ -0,0 +1,11 @@
-- xuchao: 补齐 task_template 的模板生效方式字段。生产库曾手工 ALTER 过这三列,
-- 故用 information_schema 判断实现幂等:已存在则跳过,保证生产与全新库都能安全执行。
SET @has_mode = (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'task_template' AND column_name = 'mode');
--> statement-breakpoint
SET @ddl = IF(@has_mode = 0, 'ALTER TABLE `task_template` ADD COLUMN `mode` varchar(10) NOT NULL DEFAULT ''weekly'', ADD COLUMN `date_start` date, ADD COLUMN `date_end` date', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt FROM @ddl;
--> statement-breakpoint
EXECUTE stmt;
--> statement-breakpoint
DEALLOCATE PREPARE stmt;
+118
View File
@@ -0,0 +1,118 @@
-- xuchao: 修复历史迁移缺口。早期这些表是用 drizzle push/手工 DDL 建进生产的,
-- 仓库里一直没有对应迁移,导致全新数据库建不出这些表。本迁移全部幂等:
-- 表已存在则 CREATE TABLE IF NOT EXISTS 跳过,生产库重复执行无副作用。
CREATE TABLE IF NOT EXISTS `grammar_point` (
`id` bigint AUTO_INCREMENT NOT NULL,
`point_id` varchar(191) NOT NULL,
`level` varchar(20) NOT NULL,
`level_name` varchar(50) NOT NULL,
`title` varchar(200) NOT NULL,
`difficulty` int NOT NULL DEFAULT 1,
`summary` text,
`prereq` text,
`md` mediumtext NOT NULL,
`seq` int NOT NULL,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `grammar_point_id` PRIMARY KEY(`id`),
CONSTRAINT `uq_grammar_point_id` UNIQUE(`point_id`)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS `weekly_test` (
`id` bigint AUTO_INCREMENT NOT NULL,
`child_user_id` bigint NOT NULL,
`week_key` varchar(12) NOT NULL,
`score` int,
`correct` int,
`total` int,
`passed` boolean NOT NULL DEFAULT false,
`questions` mediumtext,
`taken_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `weekly_test_id` PRIMARY KEY(`id`),
CONSTRAINT `uq_weekly_child_week` UNIQUE(`child_user_id`,`week_key`),
CONSTRAINT `fk_wt_child` FOREIGN KEY (`child_user_id`) REFERENCES `user`(`id`) ON DELETE cascade ON UPDATE no action
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS `word_progress` (
`id` bigint AUTO_INCREMENT NOT NULL,
`child_user_id` bigint NOT NULL,
`day` int NOT NULL,
`learned` mediumtext,
`score` int,
`passed` boolean NOT NULL DEFAULT false,
`completed_at` datetime,
CONSTRAINT `word_progress_id` PRIMARY KEY(`id`),
CONSTRAINT `uq_word_child_day` UNIQUE(`child_user_id`,`day`),
CONSTRAINT `fk_wp_child` FOREIGN KEY (`child_user_id`) REFERENCES `user`(`id`) ON DELETE cascade ON UPDATE no action
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS `word_recording` (
`id` bigint AUTO_INCREMENT NOT NULL,
`child_user_id` bigint NOT NULL,
`word` varchar(60) NOT NULL,
`day` int,
`oss_key` varchar(300) NOT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `word_recording_id` PRIMARY KEY(`id`),
KEY `idx_rec_child` (`child_user_id`),
CONSTRAINT `fk_wr_child` FOREIGN KEY (`child_user_id`) REFERENCES `user`(`id`) ON DELETE cascade ON UPDATE no action
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS `wrong_book` (
`id` bigint AUTO_INCREMENT NOT NULL,
`child_user_id` bigint NOT NULL,
`source_type` varchar(10) NOT NULL,
`source_id` varchar(60) NOT NULL,
`source_title` varchar(200),
`question` mediumtext NOT NULL,
`user_answer` mediumtext,
`correct_answer` mediumtext,
`mastered` boolean NOT NULL DEFAULT false,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT `wrong_book_id` PRIMARY KEY(`id`),
KEY `idx_wrong_child` (`child_user_id`,`mastered`),
CONSTRAINT `fk_wb_child` FOREIGN KEY (`child_user_id`) REFERENCES `user`(`id`) ON DELETE cascade ON UPDATE no action
);
--> statement-breakpoint
-- grammar_progress:0002 误用 seq 列建表,生产实际是 point_id。仅在缺 point_id 时转换。
-- 顺序关键:先加 point_id 与 uq_grammar_child_point(child_user_id 为最左前缀,可承接外键),
-- 之后才能安全删除被外键依赖的旧索引 uq_grammar_child_seq,全程不动外键本身。
SET @gp_has_point = (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'grammar_progress' AND column_name = 'point_id');
--> statement-breakpoint
SET @ddl = IF(@gp_has_point = 0, 'ALTER TABLE `grammar_progress` ADD COLUMN `point_id` varchar(191) NOT NULL', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt FROM @ddl;
--> statement-breakpoint
EXECUTE stmt;
--> statement-breakpoint
DEALLOCATE PREPARE stmt;
--> statement-breakpoint
SET @gp_has_point_idx = (SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'grammar_progress' AND index_name = 'uq_grammar_child_point');
--> statement-breakpoint
SET @ddl = IF(@gp_has_point_idx = 0, 'ALTER TABLE `grammar_progress` ADD CONSTRAINT `uq_grammar_child_point` UNIQUE (`child_user_id`,`point_id`)', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt FROM @ddl;
--> statement-breakpoint
EXECUTE stmt;
--> statement-breakpoint
DEALLOCATE PREPARE stmt;
--> statement-breakpoint
SET @gp_has_seq_idx = (SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'grammar_progress' AND index_name = 'uq_grammar_child_seq');
--> statement-breakpoint
SET @ddl = IF(@gp_has_seq_idx > 0, 'ALTER TABLE `grammar_progress` DROP INDEX `uq_grammar_child_seq`', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt FROM @ddl;
--> statement-breakpoint
EXECUTE stmt;
--> statement-breakpoint
DEALLOCATE PREPARE stmt;
--> statement-breakpoint
SET @gp_has_seq = (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'grammar_progress' AND column_name = 'seq');
--> statement-breakpoint
SET @ddl = IF(@gp_has_seq > 0, 'ALTER TABLE `grammar_progress` DROP COLUMN `seq`', 'SELECT 1');
--> statement-breakpoint
PREPARE stmt FROM @ddl;
--> statement-breakpoint
EXECUTE stmt;
--> statement-breakpoint
DEALLOCATE PREPARE stmt;
+21
View File
@@ -29,6 +29,27 @@
"when": 1785772800000,
"tag": "0003_math-and-exam",
"breakpoints": true
},
{
"idx": 4,
"version": "5",
"when": 1785859200000,
"tag": "0004_ai-grade-log",
"breakpoints": true
},
{
"idx": 5,
"version": "5",
"when": 1786060800000,
"tag": "0005_task-template-mode",
"breakpoints": true
},
{
"idx": 6,
"version": "5",
"when": 1786064400000,
"tag": "0006_fill-missing-tables",
"breakpoints": true
}
]
}