#15 随机班级码实现

Gabung
BaiQi menggabungkan 7 komit dari FanYanPeng/feat/XuanKe menjadi FanYanPeng/refactor%! (template.HTML=1 tahun lalu)s

+ 2 - 2
application.yaml

@@ -10,11 +10,11 @@ spring:
 #    url: jdbc:mysql://127.0.0.1:3306/eai?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
   data:
     mongodb:
-      uri: mongodb://admin:eai123456@139.196.252.184:27017/eai?authSource=admin
+      uri: mongodb://admin:eai123456@8.130.28.19:27017/eai?authSource=admin
       authentication-database: admin
     #redis配置更新
     redis:
-      host: 139.196.252.184
+      host: 8.130.28.19
       port: 6378
       password: eai123456
   mail:

+ 341 - 0
eai.sql

@@ -0,0 +1,341 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server         : online_eai
+ Source Server Type    : MySQL
+ Source Server Version : 80027
+ Source Host           : 8.130.28.19:3306
+ Source Schema         : eai
+
+ Target Server Type    : MySQL
+ Target Server Version : 80027
+ File Encoding         : 65001
+
+ Date: 18/08/2025 15:30:09
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for ai_speaking_assignment
+-- ----------------------------
+DROP TABLE IF EXISTS `ai_speaking_assignment`;
+CREATE TABLE `ai_speaking_assignment`  (
+  `ai_speaking_assignment_id` bigint NOT NULL AUTO_INCREMENT COMMENT 'AI口语作业ID(自增主键)',
+  `assignment_id` bigint NOT NULL COMMENT '关联的基础作业ID',
+  `min_duration` int NOT NULL DEFAULT 60 COMMENT '最小持续时间(秒)',
+  `min_interaction` int NOT NULL DEFAULT 5 COMMENT '最小交互次数',
+  `survey_links` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '调查问卷链接(JSON格式)',
+  `survey_duration` int NULL DEFAULT NULL COMMENT '问卷预计完成时间(秒)',
+  PRIMARY KEY (`ai_speaking_assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 35 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI口语专项作业表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for assignment
+-- ----------------------------
+DROP TABLE IF EXISTS `assignment`;
+CREATE TABLE `assignment`  (
+  `assignment_id` bigint NOT NULL AUTO_INCREMENT COMMENT '作业ID(自增主键)',
+  `course_id` bigint NOT NULL COMMENT '所属课程ID(外键)',
+  `assignment_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '作业名称',
+  `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '作业描述',
+  `type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '作业类型(如HOMEWORK/QUIZ/EXAM等)',
+  `description_file` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '作业要求文件URL',
+  `attachments` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '附件URL列表(JSON格式)',
+  `teacher_id` bigint NOT NULL COMMENT '发布教师ID',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '截止时间',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `teacher_portal_id` bigint NULL DEFAULT NULL,
+  `correct_number` int NULL DEFAULT 0,
+  `engage_number` int NULL DEFAULT 0,
+  PRIMARY KEY (`assignment_id`) USING BTREE,
+  INDEX `idx_time_range`(`start_time`, `end_time`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 79 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '课程作业表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for behavior_record
+-- ----------------------------
+DROP TABLE IF EXISTS `behavior_record`;
+CREATE TABLE `behavior_record`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '行为记录ID(自增主键)',
+  `student_id` bigint NOT NULL COMMENT '学生ID',
+  `assignment_id` bigint NOT NULL COMMENT '作业ID',
+  `record_file_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '行为记录文件URL',
+  `time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_student_assignment`(`student_id`, `assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 76 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生学习行为记录表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for class
+-- ----------------------------
+DROP TABLE IF EXISTS `class`;
+CREATE TABLE `class`  (
+  `class_id` bigint NOT NULL AUTO_INCREMENT,
+  `class_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `class_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
+  `course_id` bigint NOT NULL,
+  `stu_number` int NULL DEFAULT NULL,
+  `teacher_id` bigint NULL DEFAULT NULL,
+  `class_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '班级码',
+  PRIMARY KEY (`class_id`) USING BTREE,
+  INDEX `idx_class_course`(`course_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for class_student
+-- ----------------------------
+DROP TABLE IF EXISTS `class_student`;
+CREATE TABLE `class_student`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `class_id` bigint NOT NULL,
+  `official_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `state` int NULL DEFAULT NULL,
+  `stu_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_class_student_class`(`class_id`) USING BTREE,
+  INDEX `idx_class_student_official`(`official_number`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 38 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for course
+-- ----------------------------
+DROP TABLE IF EXISTS `course`;
+CREATE TABLE `course`  (
+  `course_id` bigint NOT NULL AUTO_INCREMENT COMMENT '课程ID(自增主键)',
+  `course_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '课程名称',
+  `teacher_ids` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '教师ID列表(JSON序列化字符串)',
+  `teacher_portal_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '教师门户ID',
+  `enroll_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '选课码(唯一)',
+  `course_imgs` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '课程图片列表(JSON序列化字符串)',
+  `target_grade` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '目标年级',
+  `start_time` datetime NOT NULL COMMENT '课程开始时间',
+  `end_time` datetime NOT NULL COMMENT '课程结束时间',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '课程描述',
+  `course_images` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
+  PRIMARY KEY (`course_id`) USING BTREE,
+  INDEX `idx_time_range`(`start_time`, `end_time`) USING BTREE,
+  INDEX `idx_course_teacher_pid`(`teacher_portal_id`) USING BTREE,
+  INDEX `idx_course_time_range`(`start_time`, `end_time`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '课程信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for course_student
+-- ----------------------------
+DROP TABLE IF EXISTS `course_student`;
+CREATE TABLE `course_student`  (
+  `enrollment_id` bigint NOT NULL AUTO_INCREMENT COMMENT '选课记录ID(自增主键)',
+  `course_id` bigint NOT NULL COMMENT '课程ID',
+  `student_id` bigint NOT NULL COMMENT '学生ID',
+  PRIMARY KEY (`enrollment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生选课关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for evaluation
+-- ----------------------------
+DROP TABLE IF EXISTS `evaluation`;
+CREATE TABLE `evaluation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '评价ID(自增主键)',
+  `student_id` bigint NOT NULL COMMENT '学生ID',
+  `assignment_id` bigint NOT NULL COMMENT '作业ID',
+  `version` int NOT NULL DEFAULT 1 COMMENT '评价版本号',
+  `time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '评价时间',
+  `author` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '评价人',
+  `overall` int NULL DEFAULT NULL COMMENT '整体评分',
+  `sentence` int NULL DEFAULT NULL COMMENT '句子评分',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_student_assignment`(`student_id`, `assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '作业评价表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for general_log
+-- ----------------------------
+DROP TABLE IF EXISTS `general_log`;
+CREATE TABLE `general_log`  (
+  `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+  `user_host` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `thread_id` bigint UNSIGNED NOT NULL,
+  `server_id` int UNSIGNED NOT NULL,
+  `command_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `argument` mediumblob NOT NULL
+) ENGINE = CSV CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'General log' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for overall_evaluation
+-- ----------------------------
+DROP TABLE IF EXISTS `overall_evaluation`;
+CREATE TABLE `overall_evaluation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID(自增)',
+  `student_id` bigint NOT NULL COMMENT '学生ID',
+  `assignment_id` bigint NOT NULL COMMENT '作业ID',
+  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '作业内容',
+  `version` int NOT NULL DEFAULT 1 COMMENT '批改版本(跟随作业版本)',
+  `evaluation` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '整体评估结果',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_student_assignment`(`student_id`, `assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '作业整体评估表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for phone_verification
+-- ----------------------------
+DROP TABLE IF EXISTS `phone_verification`;
+CREATE TABLE `phone_verification`  (
+  `id` bigint NOT NULL,
+  `code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `code_time` datetime(6) NULL DEFAULT NULL,
+  `phone` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `UK_1ebndp9bn7nuiyqujcmeifojg`(`phone`) USING BTREE,
+  INDEX `verification_phone_index`(`phone`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for phone_verification_seq
+-- ----------------------------
+DROP TABLE IF EXISTS `phone_verification_seq`;
+CREATE TABLE `phone_verification_seq`  (
+  `next_val` bigint NULL DEFAULT NULL
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for sentence_evaluation
+-- ----------------------------
+DROP TABLE IF EXISTS `sentence_evaluation`;
+CREATE TABLE `sentence_evaluation`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID(自增)',
+  `student_id` bigint NOT NULL COMMENT '学生ID',
+  `assignment_id` bigint NOT NULL COMMENT '作业ID',
+  `no` int NOT NULL COMMENT '句子编号',
+  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '原始内容',
+  `sentence` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '待评估句子',
+  `evaluation` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '评估结果',
+  `version` int NULL DEFAULT 1 COMMENT '版本号',
+  `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '句子类型',
+  `category` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '句子类别',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_student_assignment`(`student_id`, `assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 74 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '句子评估表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for sign_records
+-- ----------------------------
+DROP TABLE IF EXISTS `sign_records`;
+CREATE TABLE `sign_records`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `official_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `sign_in_time` datetime(6) NULL DEFAULT NULL,
+  `sign_status` enum('SIGNED','NOT_SIGNED','FINISHED') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `sign_task_id` bigint NOT NULL,
+  `student_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sign_record_task`(`sign_task_id`) USING BTREE,
+  INDEX `idx_sign_record_official_task`(`official_number`, `sign_task_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for sign_tasks
+-- ----------------------------
+DROP TABLE IF EXISTS `sign_tasks`;
+CREATE TABLE `sign_tasks`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `class_id` bigint NOT NULL,
+  `course_id` bigint NOT NULL,
+  `create_time` timestamp NULL DEFAULT NULL,
+  `end_time` timestamp NULL DEFAULT NULL,
+  `sign_code` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `sign_type` enum('NUMBER','QR') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `signed_number` int NULL DEFAULT NULL,
+  `status` enum('PROCESSING','FINISHED') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+  `teacher_id` bigint NOT NULL,
+  `total_number` int NULL DEFAULT NULL,
+  `qr_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
+  `time` int NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_sign_task_teacher`(`teacher_id`) USING BTREE,
+  INDEX `idx_sign_task_class`(`class_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for slow_log
+-- ----------------------------
+DROP TABLE IF EXISTS `slow_log`;
+CREATE TABLE `slow_log`  (
+  `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+  `user_host` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `query_time` time(6) NOT NULL,
+  `lock_time` time(6) NOT NULL,
+  `rows_sent` int NOT NULL,
+  `rows_examined` int NOT NULL,
+  `db` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `last_insert_id` int NOT NULL,
+  `insert_id` int NOT NULL,
+  `server_id` int UNSIGNED NOT NULL,
+  `sql_text` mediumblob NOT NULL,
+  `thread_id` bigint UNSIGNED NOT NULL
+) ENGINE = CSV CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'Slow log' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for student_assignment
+-- ----------------------------
+DROP TABLE IF EXISTS `student_assignment`;
+CREATE TABLE `student_assignment`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID(自增)',
+  `assignment_id` bigint NOT NULL COMMENT '作业ID',
+  `student_id` bigint NOT NULL COMMENT '学生ID',
+  `score` decimal(5, 2) NULL DEFAULT NULL COMMENT '作业得分(百分制)',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '教师评语',
+  `file_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '作业文件OSS链接',
+  `version` int NOT NULL DEFAULT 1 COMMENT '文件版本(用于onlyoffice key构建)',
+  `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'UNSUBMITTED' COMMENT '完成状态:UNSUBMITTED/SUBMITTED/GRADED',
+  `quill_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT 'Quill富文本内容',
+  `text_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '纯文本内容',
+  `html_content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT 'HTML格式内容',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_student_assignment`(`student_id`, `assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 95 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '学生作业关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for translations
+-- ----------------------------
+DROP TABLE IF EXISTS `translations`;
+CREATE TABLE `translations`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '翻译记录唯一标识(自增)',
+  `user_id` bigint NOT NULL COMMENT '关联用户ID',
+  `assignment_id` bigint NULL DEFAULT NULL COMMENT '关联任务ID(可选)',
+  `query_text` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '待翻译原文',
+  `query_result` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '翻译结果',
+  `target_language` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '目标语言类型(如zh/en等)',
+  `query_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '翻译请求时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_user_id`(`user_id`) USING BTREE,
+  INDEX `idx_assignment_id`(`assignment_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '翻译记录表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for users
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'User唯一标识(自增)',
+  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '真实姓名(必填)',
+  `official_email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '南大官邮,xxx@smail.nju.edu.cn(必填)',
+  `official_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '南大学号、工号(必填)',
+  `role` smallint NULL DEFAULT NULL,
+  `user_avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'default_avatar_url' COMMENT '头像URL(有默认值、选填)',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,系统自动设置',
+  `last_login_time` datetime NULL DEFAULT NULL COMMENT '上一次登陆时间(可选)',
+  `english_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '英文名(选填)',
+  `gender` smallint NULL DEFAULT NULL,
+  `birthday` date NULL DEFAULT NULL COMMENT '生日(选填)',
+  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '联系方式(选填)',
+  `content_email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '联系邮箱(选填)',
+  `pid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '门户id',
+  `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码(加密存储)(必填)',
+  `contact_email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 77 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
+
+SET FOREIGN_KEY_CHECKS = 1;

+ 0 - 151
eaidb.sql

@@ -1,151 +0,0 @@
-CREATE DATABASE eai CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
-CREATE TABLE IF NOT EXISTS `eai`.`users` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'User唯一标识(自增)',
-  `name` varchar(50) NOT NULL COMMENT '真实姓名(必填)',
-  `official_email` varchar(100) NOT NULL COMMENT '南大官邮,xxx@smail.nju.edu.cn(必填)',
-  `official_number` varchar(20) NOT NULL COMMENT '南大学号、工号(必填)',
-  `role` tinyint NOT NULL COMMENT '用户角色:0-ADMIN, 1-STUDENT, 2-TEACHER(对应枚举code)',
-  `user_avatar` varchar(255) DEFAULT 'default_avatar_url' COMMENT '头像URL(有默认值、选填)',
-  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,系统自动设置',
-  `last_login_time` datetime COMMENT '上一次登陆时间(可选)',
-  `english_name` varchar(50) COMMENT '英文名(选填)',
-  `gender` tinyint COMMENT '性别:0-MAN, 1-WOMAN(对应枚举code)',
-  `birthday` date COMMENT '生日(选填)',
-  `phone` varchar(20) COMMENT '联系方式(选填)',
-  `content_email` varchar(100) COMMENT '联系邮箱(选填)',
-  `pid` varchar(50) COMMENT '门户id',
-  `password` varchar(100) NOT NULL COMMENT '密码(加密存储)(必填)',
-  PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`translations` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '翻译记录唯一标识(自增)',
-  `user_id` bigint NOT NULL COMMENT '关联用户ID',
-  `assignment_id` bigint COMMENT '关联任务ID(可选)',
-  `query_text` text NOT NULL COMMENT '待翻译原文',
-  `query_result` text NOT NULL COMMENT '翻译结果',
-  `target_language` varchar(20) NOT NULL COMMENT '目标语言类型(如zh/en等)',
-  `query_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '翻译请求时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_user_id` (`user_id`),
-  KEY `idx_assignment_id` (`assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='翻译记录表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`sentence_evaluation` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID(自增)',
-  `student_id` bigint NOT NULL COMMENT '学生ID',
-  `assignment_id` bigint NOT NULL COMMENT '作业ID',
-  `no` int NOT NULL COMMENT '句子编号',
-  `content` text COMMENT '原始内容',
-  `sentence` text NOT NULL COMMENT '待评估句子',
-  `evaluation` text COMMENT '评估结果',
-  `version` int DEFAULT 1 COMMENT '版本号',
-  `type` varchar(50) COMMENT '句子类型',
-  `category` varchar(50) COMMENT '句子类别',
-  PRIMARY KEY (`id`),
-  KEY `idx_student_assignment` (`student_id`, `assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='句子评估表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`overall_evaluation` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID(自增)',
-  `student_id` bigint NOT NULL COMMENT '学生ID',
-  `assignment_id` bigint NOT NULL COMMENT '作业ID',
-  `content` text COMMENT '作业内容',
-  `version` int NOT NULL DEFAULT 1 COMMENT '批改版本(跟随作业版本)',
-  `evaluation` text COMMENT '整体评估结果',
-  PRIMARY KEY (`id`),
-  KEY `idx_student_assignment` (`student_id`, `assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作业整体评估表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`evaluation` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '评价ID(自增主键)',
-  `student_id` bigint NOT NULL COMMENT '学生ID',
-  `assignment_id` bigint NOT NULL COMMENT '作业ID',
-  `version` int NOT NULL DEFAULT 1 COMMENT '评价版本号',
-  `time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '评价时间',
-  `author` varchar(100) NOT NULL COMMENT '评价人',
-  `overall` int COMMENT '整体评分',
-  `sentence` int COMMENT '句子评分',
-  PRIMARY KEY (`id`),
-  KEY `idx_student_assignment` (`student_id`, `assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作业评价表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`course_student` (
-  `enrollment_id` bigint NOT NULL AUTO_INCREMENT COMMENT '选课记录ID(自增主键)',
-  `course_id` bigint NOT NULL COMMENT '课程ID',
-  `student_id` bigint NOT NULL COMMENT '学生ID',
-  PRIMARY KEY (`enrollment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='学生选课关联表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`student_assignment` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID(自增)',
-  `assignment_id` bigint NOT NULL COMMENT '作业ID',
-  `student_id` bigint NOT NULL COMMENT '学生ID',
-  `score` decimal(5,2) COMMENT '作业得分(百分制)',
-  `remark` varchar(500) COMMENT '教师评语',
-  `file_url` varchar(255) COMMENT '作业文件OSS链接',
-  `version` int NOT NULL DEFAULT 1 COMMENT '文件版本(用于onlyoffice key构建)',
-  `status` varchar(20) NOT NULL DEFAULT 'UNSUBMITTED' COMMENT '完成状态:UNSUBMITTED/SUBMITTED/GRADED',
-  `quill_content` text COMMENT 'Quill富文本内容',
-  `text_content` text COMMENT '纯文本内容',
-  `html_content` text COMMENT 'HTML格式内容',
-  PRIMARY KEY (`id`),
-  KEY `idx_student_assignment` (`student_id`, `assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='学生作业关联表';
-
-
-CREATE TABLE IF NOT EXISTS `eai`.`course` (
-  `course_id` bigint NOT NULL AUTO_INCREMENT COMMENT '课程ID(自增主键)',
-  `course_name` varchar(100) NOT NULL COMMENT '课程名称',
-  `teacher_ids` text COMMENT '教师ID列表(JSON序列化字符串)',
-  `teacher_portal_id` varchar(50) COMMENT '教师门户ID',
-  `enroll_code` varchar(20) COMMENT '选课码(唯一)',
-  `course_imgs` text COMMENT '课程图片列表(JSON序列化字符串)',
-  `target_grade` varchar(50) COMMENT '目标年级',
-  `start_time` datetime NOT NULL COMMENT '课程开始时间',
-  `end_time` datetime NOT NULL COMMENT '课程结束时间',
-  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `description` text COMMENT '课程描述',
-  PRIMARY KEY (`course_id`),
-  KEY `idx_time_range` (`start_time`, `end_time`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='课程信息表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`behavior_record` (
-  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '行为记录ID(自增主键)',
-  `student_id` bigint NOT NULL COMMENT '学生ID',
-  `assignment_id` bigint NOT NULL COMMENT '作业ID',
-  `record_file_url` varchar(255) NOT NULL COMMENT '行为记录文件URL',
-  `time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录时间',
-  PRIMARY KEY (`id`),
-  KEY `idx_student_assignment` (`student_id`, `assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='学生学习行为记录表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`assignment` (
-  `assignment_id` bigint NOT NULL AUTO_INCREMENT COMMENT '作业ID(自增主键)',
-  `course_id` bigint NOT NULL COMMENT '所属课程ID(外键)',
-  `teacher_portal_id` varchar(50) COMMENT '教师门户ID',
-  `assignment_name` varchar(100) NOT NULL COMMENT '作业名称',
-  `description` text COMMENT '作业描述',
-  `type` varchar(30) NOT NULL COMMENT '作业类型(如HOMEWORK/QUIZ/EXAM等)',
-  `description_file` varchar(255) COMMENT '作业要求文件URL',
-  `attachments` text COMMENT '附件URL列表(JSON格式)',
-  `teacher_id` bigint NOT NULL COMMENT '发布教师ID',
-  `start_time` datetime NOT NULL COMMENT '开始时间',
-  `end_time` datetime NOT NULL COMMENT '截止时间',
-  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `engage_number` int  COMMENT '参与人数',
-  `correct_number` int  COMMENT '批改人数',
-  PRIMARY KEY (`assignment_id`),
-  KEY `idx_time_range` (`start_time`, `end_time`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='课程作业表';
-
-CREATE TABLE IF NOT EXISTS `eai`.`ai_speaking_assignment` (
-  `ai_speaking_assignment_id` bigint NOT NULL AUTO_INCREMENT COMMENT 'AI口语作业ID(自增主键)',
-  `assignment_id` bigint NOT NULL COMMENT '关联的基础作业ID',
-  `min_duration` int NOT NULL DEFAULT 60 COMMENT '最小持续时间(秒)',
-  `min_interaction` int NOT NULL DEFAULT 5 COMMENT '最小交互次数',
-  `survey_links` text COMMENT '调查问卷链接(JSON格式)',
-  `survey_duration` int COMMENT '问卷预计完成时间(秒)',
-  PRIMARY KEY (`ai_speaking_assignment_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='AI口语专项作业表';

+ 22 - 0
src/main/java/com/njuzr/eaibackend/controller/ClassController.java

@@ -4,6 +4,7 @@ import com.njuzr.eaibackend.dto.ClassDTO;
 import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.po.Class;
 import com.njuzr.eaibackend.service.ClassService;
+import com.njuzr.eaibackend.vo.ClassVO;
 import com.njuzr.eaibackend.vo.StudentInfoVO;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
@@ -23,11 +24,32 @@ public class ClassController {
         this.classService = classService;
     }
 
+    /**
+     * 原来的创建班级接口,已注释
+     */
+    /*
     @PostMapping("/create")
     public MyResponse createClass(@RequestBody ClassDTO classDTO){
         Class aClass = classService.createClass(classDTO);
         return MyResponse.success(aClass);
     }
+    */
+
+    /**
+     * 新的创建班级接口,生成班级码
+     */
+    @PostMapping("/create")
+    public MyResponse createClassWithCode(@RequestBody ClassDTO classDTO) {
+        try {
+            ClassVO result = classService.createClass(classDTO);
+            return MyResponse.success(result);
+        } catch (MyException e) {
+            return MyResponse.error(e.getErrCode(), e.getMessage());
+        } catch (Exception e) {
+            log.error("创建班级失败", e);
+            return MyResponse.error(500, "服务器内部错误");
+        }
+    }
 
     @PutMapping("/update")
     public MyResponse updateClass(@RequestBody ClassDTO classDTO){

+ 24 - 3
src/main/java/com/njuzr/eaibackend/controller/CourseController.java

@@ -242,20 +242,41 @@ public class CourseController {
     }
 
     /**
-     * 选课,通过studentId和courseId,完成选课。其中studentId从Token中获取。
+     * 原来的选课接口,已注释
+     */
+    /*
+    @PreAuthorize("hasRole('STUDENT')")
+    @PostMapping("/enroll")
+    public MyResponse enroll(
+            @AuthenticationPrincipal(expression = "id") Long studentId,
+            @RequestBody EnrollDTO enrollDTO
+    ) {
+        try {
+            enrollDTO.setStudentId(studentId);
+            courseService.enroll(enrollDTO);
+            return MyResponse.success("选课成功");
+        }
+        catch (MyException e){
+            return MyResponse.error(e.getErrCode(),e.getMessage());
+        }
+    }
+    */
+
+    /**
+     * 新的选课接口,通过班级码将学生加入对应班级
      * @param studentId
      * @param enrollDTO
      * @return
      */
     @PreAuthorize("hasRole('STUDENT')")
     @PostMapping("/enroll")
-    public MyResponse enroll(
+    public MyResponse enrollByClassCode(
             @AuthenticationPrincipal(expression = "id") Long studentId,
             @RequestBody EnrollDTO enrollDTO
     ) {
         try {
             enrollDTO.setStudentId(studentId);
-            courseService.enroll(enrollDTO);
+            courseService.enrollByClassCode(enrollDTO);
             return MyResponse.success("选课成功");
         }
         catch (MyException e){

+ 2 - 0
src/main/java/com/njuzr/eaibackend/po/Class.java

@@ -18,4 +18,6 @@ public class Class {
     private String classTime;
 
     private Long teacherId;
+
+    private String classCode;
 }

+ 8 - 1
src/main/java/com/njuzr/eaibackend/service/ClassService.java

@@ -3,12 +3,13 @@ package com.njuzr.eaibackend.service;
 import com.njuzr.eaibackend.dto.ClassDTO;
 import com.njuzr.eaibackend.po.Class;
 import com.njuzr.eaibackend.vo.StudentInfoVO;
+import com.njuzr.eaibackend.vo.ClassVO;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
 public interface ClassService {
-    Class createClass(ClassDTO classDTO);
+    ClassVO createClass(ClassDTO classDTO);
 
     Class updateClass(ClassDTO classDTO);
 
@@ -49,4 +50,10 @@ public interface ClassService {
      * @return 班级信息
      */
     Class getClassByStudentIdAndCourseId(Long studentId, Long courseId);
+
+    // 生成班级码
+    String generateClassCode();
+
+    // 检查班级码是否唯一
+    boolean isClassCodeUnique(String classCode);
 }

+ 4 - 1
src/main/java/com/njuzr/eaibackend/service/CourseService.java

@@ -32,7 +32,10 @@ public interface CourseService {
 
     void deleteById(MyUserDetails role, Long courseId);
 
-    void enroll(EnrollDTO enrollDTO);
+    // void enroll(EnrollDTO enrollDTO);
+
+    // 通过班级码选课
+    void enrollByClassCode(EnrollDTO enrollDTO);
 
     IPage<UserVO> getEnrollmentsByCourse(Page<User> page, Long teacherId, Long courseId);
 

+ 48 - 4
src/main/java/com/njuzr/eaibackend/service/impl/ClassServiceImpl.java

@@ -12,6 +12,7 @@ import com.njuzr.eaibackend.po.ClassStudent;
 import com.njuzr.eaibackend.po.User;
 import com.njuzr.eaibackend.service.ClassService;
 import com.njuzr.eaibackend.vo.StudentInfoVO;
+import com.njuzr.eaibackend.vo.ClassVO;
 import com.opencsv.CSVReader;
 import com.opencsv.exceptions.CsvValidationException;
 import lombok.extern.slf4j.Slf4j;
@@ -27,7 +28,9 @@ import java.io.InputStreamReader;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Random;
 import java.util.stream.Collectors;
+import org.springframework.beans.BeanUtils;
 
 @Slf4j
 @Service
@@ -43,18 +46,59 @@ public class ClassServiceImpl implements ClassService {
     }
 
     @Override
-    public Class createClass(ClassDTO classDTO) {
-        Class aClass =new Class();
+    public ClassVO createClass(ClassDTO classDTO) {
+        Class aClass = new Class();
         aClass.setClassName(classDTO.getClassName());
         aClass.setCourseId(classDTO.getCourseId());
         aClass.setClassTime(classDTO.getClassTime());
         aClass.setTeacherId(classDTO.getTeacherId());
+        aClass.setStuNumber(0); // 初始人数为0
+
+        // 生成班级码
+        String classCode = generateClassCode();
+        aClass.setClassCode(classCode);
+
         int status = classMapper.insert(aClass);
         if (status == 0) {
-            log.error("创建课程失败,数据库插入错误!");
+            log.error("创建班级失败,数据库插入错误!");
             throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"创建班级错误");
         }
-        return aClass;
+
+        return convertToVO(aClass);
+    }
+
+    public String generateClassCode() {
+        // 生成6位字母数字组合的班级码
+        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+        Random random = new Random();
+        StringBuilder codeBuilder = new StringBuilder();
+
+        for (int i = 0; i < 6; i++) {
+            int index = random.nextInt(characters.length());
+            codeBuilder.append(characters.charAt(index));
+        }
+
+        String classCode = codeBuilder.toString();
+
+        // 检查唯一性,如果不唯一则重新生成
+        if (!isClassCodeUnique(classCode)) {
+            return generateClassCode();
+        }
+
+        return classCode;
+    }
+
+    public boolean isClassCodeUnique(String classCode) {
+        QueryWrapper<Class> wrapper = new QueryWrapper<>();
+        wrapper.eq("class_code", classCode);
+        Class existingClass = classMapper.selectOne(wrapper);
+        return existingClass == null;
+    }
+
+    private ClassVO convertToVO(Class aClass) {
+        ClassVO classVO = new ClassVO();
+        BeanUtils.copyProperties(aClass, classVO);
+        return classVO;
     }
 
     @Override

+ 91 - 15
src/main/java/com/njuzr/eaibackend/service/impl/CourseServiceImpl.java

@@ -9,16 +9,17 @@ import com.njuzr.eaibackend.dto.course.CourseQueryDTO;
 import com.njuzr.eaibackend.dto.course.CourseUpdateDTO;
 import com.njuzr.eaibackend.dto.course.EnrollDTO;
 import com.njuzr.eaibackend.enums.AssignmentCompletionStatus;
+import com.njuzr.eaibackend.enums.ClassStudentState;
 import com.njuzr.eaibackend.enums.Role;
 import com.njuzr.eaibackend.exception.MyException;
 import com.njuzr.eaibackend.mapper.*;
 import com.njuzr.eaibackend.po.*;
+import com.njuzr.eaibackend.po.Class;
 import com.njuzr.eaibackend.service.CourseService;
 import com.njuzr.eaibackend.utils.ConvertUtil;
 import com.njuzr.eaibackend.utils.ModelMapperUtil;
 import com.njuzr.eaibackend.utils.PageMapperUtil;
-import com.njuzr.eaibackend.vo.CourseVO;
-import com.njuzr.eaibackend.vo.UserVO;
+import com.njuzr.eaibackend.vo.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,16 +27,6 @@ import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import com.njuzr.eaibackend.enums.AssignmentCompletionStatus;
-import com.njuzr.eaibackend.mapper.AssignmentMapper;
-import com.njuzr.eaibackend.mapper.StudentAssignmentMapper;
-import com.njuzr.eaibackend.mapper.UserMapper;
-import com.njuzr.eaibackend.po.Assignment;
-import com.njuzr.eaibackend.po.StudentAssignment;
-import com.njuzr.eaibackend.po.User;
-import com.njuzr.eaibackend.vo.StudentCourseAssignmentVO;
-import com.njuzr.eaibackend.vo.StudentCourseHomeworkVO;
-import org.springframework.stereotype.Service;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -63,14 +54,17 @@ public class CourseServiceImpl implements CourseService {
 
     private final ClassStudentMapper classStudentMapper;
 
+    private final ClassMapper classMapper;
+
     @Autowired
-    public CourseServiceImpl(CourseMapper courseMapper, UserMapper userMapper, CourseStudentMapper courseStudentMapper, AssignmentMapper assignmentMapper, StudentAssignmentMapper studentAssignmentMapper, ClassStudentMapper classStudentMapper) {
+    public CourseServiceImpl(CourseMapper courseMapper, UserMapper userMapper, CourseStudentMapper courseStudentMapper, AssignmentMapper assignmentMapper, StudentAssignmentMapper studentAssignmentMapper, ClassStudentMapper classStudentMapper, ClassMapper classMapper) {
         this.courseMapper = courseMapper;
         this.userMapper = userMapper;
         this.courseStudentMapper = courseStudentMapper;
         this.assignmentMapper = assignmentMapper;
         this.studentAssignmentMapper = studentAssignmentMapper;
         this.classStudentMapper = classStudentMapper;
+        this.classMapper = classMapper;
     }
 
 
@@ -145,7 +139,8 @@ public class CourseServiceImpl implements CourseService {
         }
 
         if (courseQueryDTO.getStudentId() != null) { // 联表查询学生所选课程
-            wrapper.inSql("course_id", "SELECT course_id FROM course_student WHERE student_id = " + courseQueryDTO.getStudentId());
+            // 使用安全的参数绑定方式
+            wrapper.apply("course_id IN (SELECT course_id FROM course_student WHERE student_id = {0})", courseQueryDTO.getStudentId());
         }
 
         if (courseQueryDTO.getSemester() != null && !courseQueryDTO.getSemester().trim().isEmpty()) { // 课程时间过滤,转换成具体日期
@@ -313,10 +308,12 @@ public class CourseServiceImpl implements CourseService {
         }
     }
 
+    
     /**
      * 学生选课。给course_student表添加记录。
      * @param enrollDTO
      */
+    /** 
     @Override
     @Transactional
     public void enroll(EnrollDTO enrollDTO) {
@@ -351,7 +348,7 @@ public class CourseServiceImpl implements CourseService {
         log.error("更新学生 {} 在课程 {} 中的加入状态失败", studentId, courseId);
         throw MyException.create(HttpStatus.BAD_REQUEST, "失败");
     }
-
+    */
 
     /**
      * 获取某课程的所有选课学生信息
@@ -442,6 +439,85 @@ public class CourseServiceImpl implements CourseService {
         return course;
     }
 
+    /**
+     * 通过班级码选课
+     * @param enrollDTO 包含学生ID和课程ID
+     */
+    @Override
+    @Transactional
+    public void enrollByClassCode(EnrollDTO enrollDTO) {
+        // 获取班级码
+        String classCode = enrollDTO.getEnrollCode();
+        Long studentId = enrollDTO.getStudentId();
+        Long courseId = enrollDTO.getCourseId();
+
+        // 根据班级码查询班级信息
+        QueryWrapper<Class> classWrapper = new QueryWrapper<>();
+        classWrapper.eq("class_code", classCode);
+        Class targetClass = classMapper.selectOne(classWrapper);
+
+        if (targetClass == null) {
+            throw MyException.create(HttpStatus.BAD_REQUEST, "班级码不存在");
+        }
+
+        // 验证班级是否属于指定课程
+        if (!targetClass.getCourseId().equals(courseId)) {
+            throw MyException.create(HttpStatus.BAD_REQUEST, "班级码与课程不匹配");
+        }
+
+        Long classId = targetClass.getClassId();
+
+        // 检查学生是否已经加入了该课程下的其他班级
+        QueryWrapper<ClassStudent> csWrapper = new QueryWrapper<>();
+        csWrapper.inSql("class_id", "SELECT class_id FROM class WHERE course_id = " + courseId);
+        csWrapper.inSql("official_number", "SELECT official_number FROM users WHERE id = " + studentId);
+        ClassStudent existingClassStudent = classStudentMapper.selectOne(csWrapper);
+
+        if (existingClassStudent != null) {
+            throw MyException.create(HttpStatus.BAD_REQUEST, "学生已经加入了该课程下的一个班级");
+        }
+
+        // 检查学生是否已经选过该课程
+        QueryWrapper<Enrollment> enrollmentWrapper = new QueryWrapper<>();
+        enrollmentWrapper.eq("student_id", studentId);
+        enrollmentWrapper.eq("course_id", courseId);
+        Enrollment existingEnrollment = courseStudentMapper.selectOne(enrollmentWrapper);
+
+        if (existingEnrollment == null) {
+            // 创建新的选课记录
+            Enrollment enrollment = new Enrollment();
+            enrollment.setStudentId(studentId);
+            enrollment.setCourseId(courseId);
+
+            int status = courseStudentMapper.insert(enrollment);
+            if (status == 0) {
+                log.error("选课失败,数据库插入错误!");
+                throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "选课错误");
+            }
+        }
+
+        // 将学生加入班级
+        ClassStudent classStudent = new ClassStudent();
+        classStudent.setClassId(classId);
+        classStudent.setState(ClassStudentState.JOINED); // 已加入状态
+
+        // 获取学生信息
+        User student = userMapper.selectById(studentId);
+        if (student != null) {
+            classStudent.setOfficialNumber(student.getOfficialNumber());
+            classStudent.setStuName(student.getName());
+        }
+
+        int csStatus = classStudentMapper.insert(classStudent);
+        if (csStatus == 0) {
+            log.error("加入班级失败,数据库插入错误!");
+            throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "加入班级错误");
+        }
+
+        // 更新班级人数
+        classMapper.increaseStuNumber(classId, 1);
+    }
+
     /**
      * 将PO转换成VO
      * @param course

+ 20 - 0
src/main/java/com/njuzr/eaibackend/vo/ClassVO.java

@@ -0,0 +1,20 @@
+package com.njuzr.eaibackend.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 班级VO类
+ */
+@Data
+public class ClassVO implements Serializable {
+    private Long classId;
+    private String className;
+    private Long courseId;
+    private Integer stuNumber;
+    private String classTime;
+    private Long teacherId;
+    private String classCode;
+}