feat(textbooks): 知识图谱功能全面重构 — 前置依赖 + dagre 布局 + React Flow 可视化 + 师生双视角
将教材模块图谱从基本无用状态升级为完整知识图谱可视化系统。 数据层:新增 knowledgePointPrerequisites 表(复合主键+双外键 cascade);新增 data-access-graph.ts(server-only)知识点关联聚合、学生/班级掌握度查询;utils.ts 新增 hasCycleAfterAddingEdge(DFS 循环依赖检测)。 业务层:3 个新 Server Action(getKnowledgeGraphDataAction 三视图模式、createPrerequisiteAction 含循环检测、deletePrerequisiteAction);graph-layout.ts 重写为 dagre 分层有向图布局。 视图层:knowledge-graph.tsx 重写为 React Flow 主组件(全书视图+搜索高亮+关联节点高亮+章节着色);4 个新组件(graph-kp-node/graph-prerequisite-edge/graph-toolbar/graph-node-detail-panel);use-graph-data.ts 派生值模式避免 effect 中 setState。 架构:严格三层架构,客户端通过 Server Action 间接访问 server-only 数据层;权限校验+ i18n 全覆盖;架构文档 004/005 同步。 测试:utils.test.ts 新增 5 个循环检测测试,graph-layout.test.ts 重写 5 个 dagre 布局测试,全部 30 个教材模块单元测试通过。 附带提交 drizzle/0005 error-book 迁移文件以保持 journal 一致性。
This commit is contained in:
11
drizzle/0004_calm_sandman.sql
Normal file
11
drizzle/0004_calm_sandman.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE `knowledge_point_prerequisites` (
|
||||
`knowledge_point_id` varchar(128) NOT NULL,
|
||||
`prerequisite_kp_id` varchar(128) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `knowledge_point_prerequisites_knowledge_point_id_prerequisite_kp_id_pk` PRIMARY KEY(`knowledge_point_id`,`prerequisite_kp_id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `knowledge_point_prerequisites` ADD CONSTRAINT `kp_prereq_kp_fk` FOREIGN KEY (`knowledge_point_id`) REFERENCES `knowledge_points`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `knowledge_point_prerequisites` ADD CONSTRAINT `kp_prereq_prereq_fk` FOREIGN KEY (`prerequisite_kp_id`) REFERENCES `knowledge_points`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `kp_prereq_kp_idx` ON `knowledge_point_prerequisites` (`knowledge_point_id`);--> statement-breakpoint
|
||||
CREATE INDEX `kp_prereq_prereq_idx` ON `knowledge_point_prerequisites` (`prerequisite_kp_id`);
|
||||
48
drizzle/0005_messy_pride.sql
Normal file
48
drizzle/0005_messy_pride.sql
Normal file
@@ -0,0 +1,48 @@
|
||||
CREATE TABLE `error_book_items` (
|
||||
`id` varchar(128) NOT NULL,
|
||||
`student_id` varchar(128) NOT NULL,
|
||||
`question_id` varchar(128) NOT NULL,
|
||||
`source_type` enum('exam','homework','manual') NOT NULL DEFAULT 'manual',
|
||||
`source_id` varchar(128),
|
||||
`student_answer` json,
|
||||
`correct_answer` json,
|
||||
`subject_id` varchar(128),
|
||||
`knowledge_point_ids` json,
|
||||
`error_status` enum('new','learning','mastered','archived') NOT NULL DEFAULT 'new',
|
||||
`mastery_level` int NOT NULL DEFAULT 0,
|
||||
`next_review_at` timestamp,
|
||||
`review_interval` int NOT NULL DEFAULT 1,
|
||||
`review_count` int NOT NULL DEFAULT 0,
|
||||
`correct_streak` int NOT NULL DEFAULT 0,
|
||||
`note` text,
|
||||
`error_tags` json,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
`updated_at` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT `error_book_items_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `error_book_reviews` (
|
||||
`id` varchar(128) NOT NULL,
|
||||
`item_id` varchar(128) NOT NULL,
|
||||
`student_id` varchar(128) NOT NULL,
|
||||
`review_result` enum('again','hard','good','easy') NOT NULL,
|
||||
`reviewed_at` timestamp NOT NULL DEFAULT (now()),
|
||||
`new_interval` int,
|
||||
`new_mastery_level` int,
|
||||
`created_at` timestamp NOT NULL DEFAULT (now()),
|
||||
CONSTRAINT `error_book_reviews_id` PRIMARY KEY(`id`)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `error_book_items` ADD CONSTRAINT `error_book_items_student_id_users_id_fk` FOREIGN KEY (`student_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `error_book_items` ADD CONSTRAINT `error_book_items_question_id_questions_id_fk` FOREIGN KEY (`question_id`) REFERENCES `questions`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `error_book_reviews` ADD CONSTRAINT `error_book_reviews_item_id_error_book_items_id_fk` FOREIGN KEY (`item_id`) REFERENCES `error_book_items`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE `error_book_reviews` ADD CONSTRAINT `error_book_reviews_student_id_users_id_fk` FOREIGN KEY (`student_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX `eb_item_student_idx` ON `error_book_items` (`student_id`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_item_student_status_idx` ON `error_book_items` (`student_id`,`error_status`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_item_student_review_idx` ON `error_book_items` (`student_id`,`next_review_at`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_item_question_idx` ON `error_book_items` (`question_id`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_item_subject_idx` ON `error_book_items` (`subject_id`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_item_source_idx` ON `error_book_items` (`source_type`,`source_id`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_review_item_idx` ON `error_book_reviews` (`item_id`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_review_student_idx` ON `error_book_reviews` (`student_id`);--> statement-breakpoint
|
||||
CREATE INDEX `eb_review_student_reviewed_idx` ON `error_book_reviews` (`student_id`,`reviewed_at`);
|
||||
7644
drizzle/meta/0004_snapshot.json
Normal file
7644
drizzle/meta/0004_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
8001
drizzle/meta/0005_snapshot.json
Normal file
8001
drizzle/meta/0005_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,27 @@
|
||||
"when": 1781789296745,
|
||||
"tag": "0002_tiny_lionheart",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "5",
|
||||
"when": 1782118370256,
|
||||
"tag": "0003_diagnostic_student_nullable",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "5",
|
||||
"when": 1782136411839,
|
||||
"tag": "0004_calm_sandman",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "5",
|
||||
"when": 1782141546400,
|
||||
"tag": "0005_messy_pride",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user