Merge pull request 'djk' (#2) from djk into dev

Reviewed-on: #2
This commit is contained in:
lei 2025-12-07 19:02:52 +08:00
commit 8f3d32219b
16 changed files with 438 additions and 207 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="KubernetesApiProvider">{}</component> <component name="KubernetesApiProvider"><![CDATA[{}]]></component>
<component name="MavenProjectsManager"> <component name="MavenProjectsManager">
<option name="originalFiles"> <option name="originalFiles">
<list> <list>

242
readme.md
View File

@ -1,98 +1,184 @@
MySQL中创建数据库和表 --用户表 (user)
sql
-- 创建数据库
CREATE DATABASE campus_attendance DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE campus_attendance;
-- 创建学生表
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
student_id VARCHAR(20) NOT NULL UNIQUE,
class VARCHAR(50),
major VARCHAR(100)
);
-- 创建用户表
CREATE TABLE user ( CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT, id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE, username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(100) NOT NULL, password VARCHAR(100) NOT NULL,
role VARCHAR(20) NOT NULL role ENUM('ADMIN', 'TEACHER', 'STUDENT') NOT NULL,
created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
); );
--老师表 (teacher)
-- 插入测试数据 CREATE TABLE teacher (
INSERT INTO student (name, student_id, class, major) VALUES
('张三', '2023001', '计算机1班', '计算机科学与技术'),
('李四', '2023002', '软件1班', '软件工程');
INSERT INTO user (username, password, role) VALUES
('admin', 'admin123', 'ADMIN'),
('teacher1', 'teacher123', 'TEACHER');
![img.png](img.png)
-- 在已有的数据库基础上,添加考勤相关表
-- 考勤记录表
CREATE TABLE attendance_record (
id INT PRIMARY KEY AUTO_INCREMENT, id INT PRIMARY KEY AUTO_INCREMENT,
student_id VARCHAR(20) NOT NULL, user_id INT UNIQUE NOT NULL,
course_name VARCHAR(100) NOT NULL, name VARCHAR(50) NOT NULL,
attendance_date DATE NOT NULL, teacher_id VARCHAR(20) UNIQUE NOT NULL,
attendance_time TIME, department VARCHAR(100),
status VARCHAR(20) NOT NULL DEFAULT 'PRESENT', -- PRESENT/ABSENT/LATE title VARCHAR(50),
remarks VARCHAR(500),
created_by VARCHAR(50), -- 记录创建人(教师用户名)
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (student_id) REFERENCES student(student_id) ON DELETE CASCADE update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE
); );
-- 创建索引提高查询效率 --学生表 (student)
CREATE INDEX idx_student_date ON attendance_record(student_id, attendance_date); CREATE TABLE student (
CREATE INDEX idx_date_status ON attendance_record(attendance_date, status); id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT UNIQUE NOT NULL,
name VARCHAR(50) NOT NULL,
student_id VARCHAR(20) UNIQUE NOT NULL,
class_name VARCHAR(50),
major VARCHAR(100),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE
);
-- 课程表(可选) --课程表 (course)
CREATE TABLE course ( CREATE TABLE course (
id INT PRIMARY KEY AUTO_INCREMENT, id INT PRIMARY KEY AUTO_INCREMENT,
course_name VARCHAR(100) NOT NULL, course_name VARCHAR(100) NOT NULL,
teacher_id INT, -- 关联user表的id course_code VARCHAR(20) UNIQUE NOT NULL,
class_name VARCHAR(50), teacher_id INT NOT NULL,
schedule_time VARCHAR(100), -- 上课时间描述 description TEXT,
status INT DEFAULT 1 -- 1启用0停用 create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (teacher_id) REFERENCES teacher(id) ON DELETE CASCADE
); );
--学生-课程关联表 (student_course)
CREATE TABLE student_course (
id INT PRIMARY KEY AUTO_INCREMENT,
student_id INT NOT NULL,
course_id INT NOT NULL,
enroll_date DATE NOT NULL,
status ENUM('ACTIVE', 'COMPLETED', 'DROPPED') DEFAULT 'ACTIVE',
UNIQUE KEY uk_student_course (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES student(id) ON DELETE CASCADE,
FOREIGN KEY (course_id) REFERENCES course(id) ON DELETE CASCADE
);
--考勤记录表 (attendance_record)
CREATE TABLE attendance_record (
id INT PRIMARY KEY AUTO_INCREMENT,
student_id INT NOT NULL,
course_id INT NOT NULL,
attendance_date DATE NOT NULL,
attendance_time TIME NOT NULL,
status ENUM('PRESENT', 'ABSENT', 'LATE') NOT NULL,
remarks TEXT,
created_by INT NOT NULL, -- 记录创建者老师ID
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_student_course_date (student_id, course_id, attendance_date),
FOREIGN KEY (student_id) REFERENCES student(id) ON DELETE CASCADE,
FOREIGN KEY (course_id) REFERENCES course(id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES teacher(id) ON DELETE CASCADE
);
老师-学生管理关系表 (teacher_student)
CREATE TABLE teacher_student (
id INT PRIMARY KEY AUTO_INCREMENT,
teacher_id INT NOT NULL,
student_id INT NOT NULL,
relationship_type ENUM('ADVISOR', 'INSTRUCTOR') NOT NULL,
start_date DATE NOT NULL,
end_date DATE,
UNIQUE KEY uk_teacher_student (teacher_id, student_id, relationship_type),
FOREIGN KEY (teacher_id) REFERENCES teacher(id) ON DELETE CASCADE,
FOREIGN KEY (student_id) REFERENCES student(id) ON DELETE CASCADE
);
-- 添加更多测试数据到数据库 --系统日志表 (system_log)
CREATE TABLE system_log (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
action VARCHAR(100) NOT NULL,
target_type VARCHAR(50) NOT NULL,
target_id INT,
description TEXT,
ip_address VARCHAR(45),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES user(id)
);
-- 添加更多学生 -- 以下是插入的数据
INSERT INTO student (name, student_id, class, major) VALUES
('王五', '2023003', '计算机1班', '计算机科学与技术'),
('赵六', '2023004', '软件1班', '软件工程'),
('钱七', '2023005', '网络1班', '网络工程'),
('孙八', '2023006', '计算机1班', '计算机科学与技术');
-- 添加更多用户密码都是123456经过MD5加盐加密后的值
-- 实际密码需要加密存储,这里先用明文,系统会自动加密
INSERT INTO user (username, password, role) VALUES INSERT INTO user (username, password, role) VALUES
('2023001', '123456', 'STUDENT'), ('admin', 'admin123', 'ADMIN'),
('2023002', '123456', 'STUDENT'), ('teacher1', 'teacher123', 'TEACHER'),
('2023003', '123456', 'STUDENT'), ('teacher2', 'teacher456', 'TEACHER'),
('teacher2', '123456', 'TEACHER'), ('student1', 'student123', 'STUDENT'),
('admin','123456','ADMIN'), ('student2', 'student456', 'STUDENT'),
('student1', '123456', 'STUDENT'); ('student3', 'student789', 'STUDENT'),
('student4', 'student000', 'STUDENT');
-- 添加考勤测试数据
INSERT INTO attendance_record (student_id, course_name, attendance_date, attendance_time, status, remarks, created_by) VALUES INSERT INTO teacher (user_id, name, teacher_id, department, title) VALUES
('2023001', '高等数学', DATE_SUB(CURDATE(), INTERVAL 3 DAY), '08:30:00', 'PRESENT', '', 'teacher1'), (2, '张老师', 'T001', '计算机科学系', '副教授'),
('2023002', '高等数学', DATE_SUB(CURDATE(), INTERVAL 3 DAY), '08:35:00', 'LATE', '迟到5分钟', 'teacher1'), (3, '李老师', 'T002', '软件工程系', '讲师');
('2023001', '大学英语', DATE_SUB(CURDATE(), INTERVAL 2 DAY), '10:00:00', 'PRESENT', '', 'teacher1'),
('2023003', '高等数学', DATE_SUB(CURDATE(), INTERVAL 3 DAY), '08:30:00', 'ABSENT', '请假', 'teacher1'), INSERT INTO student (user_id, name, student_id, class_name, major) VALUES
('2023001', '数据结构', DATE_SUB(CURDATE(), INTERVAL 1 DAY), '14:00:00', 'PRESENT', '', 'teacher1'), (4, '张三', 'S2024001', '计算机1班', '计算机科学与技术'),
('2023002', '数据结构', DATE_SUB(CURDATE(), INTERVAL 1 DAY), '14:00:00', 'PRESENT', '', 'teacher1'); (5, '李四', 'S2024002', '计算机1班', '计算机科学与技术'),
(6, '王五', 'S2024003', '软件工程1班', '软件工程'),
(7, '赵六', 'S2024004', '软件工程1班', '软件工程');
INSERT INTO course (course_name, course_code, teacher_id, description) VALUES
('Java程序设计', 'CS001', 1, 'Java语言基础与面向对象编程'),
('数据库原理', 'CS002', 1, '数据库系统原理与应用'),
('Web开发技术', 'SE001', 2, '前端与后端Web开发技术'),
('软件工程', 'SE002', 2, '软件开发流程与方法论');
INSERT INTO student_course (student_id, course_id, enroll_date, status) VALUES
-- 张三选课
(1, 1, '2024-09-01', 'ACTIVE'),
(1, 2, '2024-09-01', 'ACTIVE'),
-- 李四选课
(2, 1, '2024-09-01', 'ACTIVE'),
(2, 3, '2024-09-01', 'ACTIVE'),
-- 王五选课
(3, 3, '2024-09-01', 'ACTIVE'),
(3, 4, '2024-09-01', 'ACTIVE'),
-- 赵六选课
(4, 2, '2024-09-01', 'ACTIVE'),
(4, 4, '2024-09-01', 'ACTIVE');
INSERT INTO attendance_record (student_id, course_id, attendance_date, attendance_time, status, remarks, created_by) VALUES
-- Java程序设计考勤记录
(1, 1, '2024-10-01', '08:30:00', 'PRESENT', '按时到课', 1),
(2, 1, '2024-10-01', '08:45:00', 'LATE', '迟到15分钟', 1),
(1, 1, '2024-10-08', '08:30:00', 'PRESENT', '', 1),
(2, 1, '2024-10-08', '08:30:00', 'ABSENT', '请假', 1),
-- 数据库原理考勤记录
(1, 2, '2024-10-02', '10:00:00', 'PRESENT', '', 1),
(4, 2, '2024-10-02', '10:00:00', 'PRESENT', '', 1),
-- Web开发技术考勤记录
(2, 3, '2024-10-03', '14:00:00', 'PRESENT', '', 2),
(3, 3, '2024-10-03', '14:10:00', 'LATE', '交通堵塞', 2),
-- 软件工程考勤记录
(3, 4, '2024-10-04', '16:00:00', 'PRESENT', '', 2),
(4, 4, '2024-10-04', '16:00:00', 'PRESENT', '', 2);
INSERT INTO teacher_student (teacher_id, student_id, relationship_type, start_date) VALUES
-- 张老师管理计算机1班学生
(1, 1, 'ADVISOR', '2024-09-01'),
(1, 2, 'ADVISOR', '2024-09-01'),
-- 李老师管理软件工程1班学生
(2, 3, 'ADVISOR', '2024-09-01'),
(2, 4, 'ADVISOR', '2024-09-01'),
-- 授课关系
(1, 1, 'INSTRUCTOR', '2024-09-01'),
(1, 2, 'INSTRUCTOR', '2024-09-01'),
(1, 4, 'INSTRUCTOR', '2024-09-01'),
(2, 2, 'INSTRUCTOR', '2024-09-01'),
(2, 3, 'INSTRUCTOR', '2024-09-01'),
(2, 4, 'INSTRUCTOR', '2024-09-01');
INSERT INTO system_log (user_id, action, target_type, target_id, description, ip_address) VALUES
(1, 'LOGIN', 'SYSTEM', NULL, '管理员登录系统', '192.168.1.100'),
(2, 'CREATE', 'ATTENDANCE', 1, '创建考勤记录', '192.168.1.101'),
(2, 'UPDATE', 'ATTENDANCE', 2, '更新考勤状态', '192.168.1.101'),
(3, 'CREATE', 'COURSE', 3, '创建新课程', '192.168.1.102'),
(1, 'DELETE', 'USER', 5, '删除用户', '192.168.1.100');

View File

@ -22,7 +22,7 @@ public class AttendanceController {
* 记录考勤教师使用 * 记录考勤教师使用
*/ */
@PostMapping("/record") @PostMapping("/record")
public Map<String, Object> recordAttendance(@RequestBody Map<String, String> params, public Map<String, Object> recordAttendance(@RequestBody Map<String, Object> params, // 改为Object类型
HttpSession session) { HttpSession session) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@ -41,23 +41,34 @@ public class AttendanceController {
} }
try { try {
String studentId = params.get("studentId"); // 类型转换处理
String courseName = params.get("courseName"); Integer studentId = null;
String status = params.get("status"); Integer courseId = null;
if (studentId == null || courseName == null || status == null) { try {
studentId = Integer.parseInt(params.get("studentId").toString());
courseId = Integer.parseInt(params.get("courseId").toString());
} catch (NumberFormatException e) {
result.put("success", false);
result.put("message", "学生ID或课程ID格式错误");
return result;
}
String status = (String) params.get("status");
if (studentId == null || courseId == null || status == null) {
result.put("success", false); result.put("success", false);
result.put("message", "参数不完整"); result.put("message", "参数不完整");
return result; return result;
} }
AttendanceRecord record = new AttendanceRecord(); AttendanceRecord record = new AttendanceRecord();
record.setStudentId(studentId); record.setStudentId(studentId); // 使用Integer类型
record.setCourseName(courseName); record.setCourseId(courseId); // 使用courseId
record.setAttendanceDate(new Date()); record.setAttendanceDate(new Date());
record.setStatus(status); record.setStatus(status);
record.setRemarks(params.get("remarks")); record.setRemarks((String) params.get("remarks"));
record.setCreatedBy(user.getUsername()); record.setCreatedBy(user.getId()); // 使用用户ID而不是用户名
boolean success = attendanceService.recordAttendance(record); boolean success = attendanceService.recordAttendance(record);
@ -80,7 +91,7 @@ public class AttendanceController {
* 补签考勤教师使用 * 补签考勤教师使用
*/ */
@PostMapping("/makeup") @PostMapping("/makeup")
public Map<String, Object> makeupAttendance(@RequestBody Map<String, String> params, public Map<String, Object> makeupAttendance(@RequestBody Map<String, Object> params, // 改为Object类型
HttpSession session) { HttpSession session) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@ -93,14 +104,19 @@ public class AttendanceController {
try { try {
AttendanceRecord record = new AttendanceRecord(); AttendanceRecord record = new AttendanceRecord();
record.setStudentId(params.get("studentId"));
record.setCourseName(params.get("courseName")); // 类型转换处理
record.setStatus(params.get("status")); Integer studentId = Integer.parseInt(params.get("studentId").toString());
record.setRemarks(params.get("remarks")); Integer courseId = Integer.parseInt(params.get("courseId").toString());
record.setCreatedBy(user.getUsername());
record.setStudentId(studentId);
record.setCourseId(courseId);
record.setStatus((String) params.get("status"));
record.setRemarks((String) params.get("remarks"));
record.setCreatedBy(user.getId()); // 使用用户ID
// 解析日期 // 解析日期
String dateStr = params.get("attendanceDate"); String dateStr = (String) params.get("attendanceDate");
if (dateStr != null) { if (dateStr != null) {
record.setAttendanceDate(new Date(Long.parseLong(dateStr))); record.setAttendanceDate(new Date(Long.parseLong(dateStr)));
} else { } else {
@ -138,12 +154,10 @@ public class AttendanceController {
return result; return result;
} }
// 学生只能查看自己的考勤记录
// 注意这里需要关联学生ID和用户ID暂时简化处理
// 实际应用中应该在User表中存储student_id字段
if ("STUDENT".equals(user.getRole())) { if ("STUDENT".equals(user.getRole())) {
// 假设学生用户名为学号简化处理 // 需要建立User和Student的关联这里假设可以通过用户ID查询学生ID
List<AttendanceRecord> records = attendanceService.getAttendanceByStudentId(user.getUsername()); // 实际实现需要在service层处理
List<AttendanceRecord> records = attendanceService.getAttendanceByStudentId(user.getId());
result.put("success", true); result.put("success", true);
result.put("records", records); result.put("records", records);
} else { } else {
@ -159,7 +173,7 @@ public class AttendanceController {
*/ */
@GetMapping("/query") @GetMapping("/query")
public Map<String, Object> queryAttendance( public Map<String, Object> queryAttendance(
@RequestParam(required = false) String studentId, @RequestParam(required = false) Integer studentId, // 改为Integer类型
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date date, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date date,
HttpSession session) { HttpSession session) {
@ -174,7 +188,7 @@ public class AttendanceController {
List<AttendanceRecord> records; List<AttendanceRecord> records;
if (studentId != null && !studentId.trim().isEmpty()) { if (studentId != null) {
records = attendanceService.getAttendanceByStudentId(studentId); records = attendanceService.getAttendanceByStudentId(studentId);
} else if (date != null) { } else if (date != null) {
records = attendanceService.getAttendanceByDate(date); records = attendanceService.getAttendanceByDate(date);
@ -188,47 +202,5 @@ public class AttendanceController {
return result; return result;
} }
/** // 其他方法保持不变...
* 获取考勤统计
*/
@GetMapping("/statistics")
public Map<String, Object> getStatistics(
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(required = false) String studentId,
HttpSession session) {
Map<String, Object> result = new HashMap<>();
User user = (User) session.getAttribute("currentUser");
if (user == null || (!"TEACHER".equals(user.getRole()) && !"ADMIN".equals(user.getRole()))) {
result.put("success", false);
result.put("message", "权限不足");
return result;
}
if (studentId != null && !studentId.trim().isEmpty()) {
// 学生考勤统计
Map<String, Object> summary = attendanceService.getStudentAttendanceSummary(studentId);
result.put("success", true);
result.put("summary", summary);
} else {
// 时间段统计
if (startDate == null) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -30);
startDate = calendar.getTime();
}
if (endDate == null) {
endDate = new Date();
}
List<Map<String, Object>> statistics = attendanceService.getAttendanceStatistics(startDate, endDate);
result.put("success", true);
result.put("statistics", statistics);
}
return result;
}
} }

View File

@ -22,7 +22,7 @@ public class StudentController {
} }
@GetMapping("/{studentId}") @GetMapping("/{studentId}")
public Map<String, Object> getByStudentId(@PathVariable String studentId) { public Map<String, Object> getByStudentId(@PathVariable Integer studentId) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
Student student = studentService.getByStudentId(studentId); Student student = studentService.getByStudentId(studentId);

View File

@ -5,24 +5,29 @@ import java.util.Date;
public class AttendanceRecord { public class AttendanceRecord {
private Integer id; private Integer id;
private String studentId; private Integer studentId;
private String courseName; private Integer courseID;
private Date attendanceDate; private Date attendanceDate;
private Date attendanceTime; private Date attendanceTime;
private String status; // PRESENT/ABSENT/LATE private String status; // PRESENT/ABSENT/LATE
private String remarks; private String remarks;
private String createdBy; private Integer createdBy;
private Date createTime; private Date createTime;
// 添加关联对象用于查询显示
// private Student student;
// private Course course;
// private Teacher teacher;
// getters and setters // getters and setters
public Integer getId() { return id; } public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; } public void setId(Integer id) { this.id = id; }
public String getStudentId() { return studentId; } public Integer getStudentId() { return studentId; }
public void setStudentId(String studentId) { this.studentId = studentId; } public void setStudentId(Integer studentId) { this.studentId = studentId; }
public String getCourseName() { return courseName; } public Integer getCourseId() { return courseID; }
public void setCourseName(String courseName) { this.courseName = courseName; } public void setCourseId(Integer courseID) { this.courseID = courseID; }
public Date getAttendanceDate() { return attendanceDate; } public Date getAttendanceDate() { return attendanceDate; }
public void setAttendanceDate(Date attendanceDate) { this.attendanceDate = attendanceDate; } public void setAttendanceDate(Date attendanceDate) { this.attendanceDate = attendanceDate; }
@ -36,9 +41,10 @@ public class AttendanceRecord {
public String getRemarks() { return remarks; } public String getRemarks() { return remarks; }
public void setRemarks(String remarks) { this.remarks = remarks; } public void setRemarks(String remarks) { this.remarks = remarks; }
public String getCreatedBy() { return createdBy; } public Integer getCreatedBy() { return createdBy; }
public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } public void setCreatedBy(Integer createdBy) { this.createdBy = createdBy; }
public Date getCreateTime() { return createTime; } public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; }
} }

View File

@ -0,0 +1,26 @@
// com/campus/entity/Course.java
package com.campus.entity;
public class Course {
private Integer id;
private String courseName;
private String courseCode;
private Integer teacherId;
private String description;
// getters and setters
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getCourseName() { return courseName; }
public void setCourseName(String courseName) { this.courseName = courseName; }
public String getCourseCode() { return courseCode; }
public void setCourseCode(String courseCode) { this.courseCode = courseCode; }
public Integer getTeacherId() { return teacherId; }
public void setTeacherId(Integer teacherId) { this.teacherId = teacherId; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
}

View File

@ -6,6 +6,7 @@ public class Student {
private String studentId; private String studentId;
private String class_; private String class_;
private String major; private String major;
private Integer userId;
public Integer getId() { public Integer getId() {
return id; return id;

View File

@ -0,0 +1,95 @@
package com.campus.entity;
import java.time.LocalDateTime;
public class Teacher {
private Integer id;
private String name;
private String teacherId;
private String department;
private String title;
private LocalDateTime createTime;
private LocalDateTime updateTime;
public Teacher() {
}
// 全参构造方法
public Teacher(Integer id, String name, String teacherId, String department, String title) {
this.id = id;
this.name = name;
this.teacherId = teacherId;
this.department = department;
this.title = title;
}
// Getter Setter 方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTeacherId() {
return teacherId;
}
public void setTeacherId(String teacherId) {
this.teacherId = teacherId;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
", teacherId='" + teacherId + '\'' +
", department='" + department + '\'' +
", title='" + title + '\'' +
'}';
}
}

View File

@ -6,7 +6,8 @@ public class User {
private String username; private String username;
private String password; private String password;
private String role; // ADMIN/TEACHER/STUDENT private String role; // ADMIN/TEACHER/STUDENT
private Integer studentId; // 如果是学生角色关联学生ID
private Integer teacherId; // 如果是教师角色关联教师ID
// 新增构造方法 // 新增构造方法
public User() {} public User() {}

View File

@ -1,4 +1,3 @@
// com/campus/mapper/AttendanceMapper.java
package com.campus.mapper; package com.campus.mapper;
import com.campus.entity.AttendanceRecord; import com.campus.entity.AttendanceRecord;
@ -12,29 +11,28 @@ import java.util.Map;
@Mapper @Mapper
public interface AttendanceMapper { public interface AttendanceMapper {
// 添加考勤记录 // 基础CRUD操作
int insert(AttendanceRecord record); int insert(AttendanceRecord record);
int update(AttendanceRecord record);
int delete(@Param("id") Integer id);
// 根据学生ID查询考勤记录 // 查询方法
List<AttendanceRecord> selectByStudentId(@Param("studentId") String studentId); AttendanceRecord selectById(@Param("id") Integer id);
List<AttendanceRecord> selectByStudentId(@Param("studentId") Integer studentId);
// 根据日期查询考勤记录
List<AttendanceRecord> selectByDate(@Param("date") Date date); List<AttendanceRecord> selectByDate(@Param("date") Date date);
AttendanceRecord selectByStudentAndDate(@Param("studentId") Integer studentId,
// 根据学生ID和日期查询
AttendanceRecord selectByStudentAndDate(@Param("studentId") String studentId,
@Param("date") Date date); @Param("date") Date date);
// 更新考勤记录补签 // 批量操作新增
int update(AttendanceRecord record); int batchInsert(@Param("records") List<AttendanceRecord> records);
// 删除考勤记录 // 统计查询
int delete(Integer id);
// 统计考勤情况
List<Map<String, Object>> getAttendanceStatistics(@Param("startDate") Date startDate, List<Map<String, Object>> getAttendanceStatistics(@Param("startDate") Date startDate,
@Param("endDate") Date endDate); @Param("endDate") Date endDate);
Map<String, Object> getStudentAttendanceSummary(@Param("studentId") Integer studentId);
// 查询某个学生的考勤统计 // 分页查询新增
Map<String, Object> getStudentAttendanceSummary(@Param("studentId") String studentId); List<AttendanceRecord> selectByCondition(@Param("record") AttendanceRecord condition,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
} }

View File

@ -1,4 +1,3 @@
// com/campus/mapper/StudentMapper.java
package com.campus.mapper; package com.campus.mapper;
import com.campus.entity.Student; import com.campus.entity.Student;
@ -9,11 +8,17 @@ import java.util.List;
@Mapper @Mapper
public interface StudentMapper { public interface StudentMapper {
List<Student> selectAll(); // 基础CRUD
void insert(Student student); int insert(Student student);
void update(Student student); int update(Student student);
void delete(Integer id); int delete(@Param("id") Integer id);
// 新增根据学号查询学生 // 查询方法
Student selectByStudentId(@Param("studentId") String studentId); Student selectById(@Param("id") Integer id);
Student selectByStudentId(@Param("studentId") Integer studentId);
List<Student> selectAll();
// 条件查询新增
List<Student> selectByCondition(@Param("student") Student condition);
List<Student> selectByIds(@Param("ids") List<Integer> ids);
} }

View File

@ -1,14 +1,20 @@
// com/campus/mapper/UserMapper.java
package com.campus.mapper; package com.campus.mapper;
import com.campus.entity.User; import com.campus.entity.User;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper @Mapper
public interface UserMapper { public interface UserMapper {
// 根据用户名查询用户 // 基础操作
User selectByUsername(String username); int insert(User user);
int update(User user);
int delete(@Param("id") Long id);
// 新增用户(注册) // 查询方法
void insert(User user); User selectById(@Param("id") Long id);
User selectByUsername(@Param("username") String username);
// 安全检查新增
User selectByUsernameForAuth(@Param("username") String username);
} }

View File

@ -1,4 +1,3 @@
// com/campus/service/AttendanceService.java
package com.campus.service; package com.campus.service;
import com.campus.entity.AttendanceRecord; import com.campus.entity.AttendanceRecord;
@ -15,8 +14,8 @@ public interface AttendanceService {
// 补签考勤 // 补签考勤
boolean makeUpAttendance(AttendanceRecord record); boolean makeUpAttendance(AttendanceRecord record);
// 查询学生考勤记录 // 查询学生考勤记录 - 参数类型改为 Integer
List<AttendanceRecord> getAttendanceByStudentId(String studentId); List<AttendanceRecord> getAttendanceByStudentId(Integer studentId);
// 查询日期考勤记录 // 查询日期考勤记录
List<AttendanceRecord> getAttendanceByDate(Date date); List<AttendanceRecord> getAttendanceByDate(Date date);
@ -24,9 +23,9 @@ public interface AttendanceService {
// 查询统计信息 // 查询统计信息
List<Map<String, Object>> getAttendanceStatistics(Date startDate, Date endDate); List<Map<String, Object>> getAttendanceStatistics(Date startDate, Date endDate);
// 查询学生考勤统计 // 查询学生考勤统计 - 参数类型改为 Integer
Map<String, Object> getStudentAttendanceSummary(String studentId); Map<String, Object> getStudentAttendanceSummary(Integer studentId);
// 检查是否已考勤 // 检查是否已考勤 - 参数类型改为 Integer
boolean checkAttendanceExists(String studentId, Date date); boolean checkAttendanceExists(Integer studentId, Date date);
} }

View File

@ -1,4 +1,3 @@
// com/campus/service/StudentService.java
package com.campus.service; package com.campus.service;
import com.campus.entity.Student; import com.campus.entity.Student;
@ -21,17 +20,15 @@ public class StudentService {
studentMapper.insert(student); studentMapper.insert(student);
} }
// 添加新方法根据学号查询学生 // 参数类型改为 Integer
public Student getByStudentId(String studentId) { public Student getByStudentId(Integer studentId) {
return studentMapper.selectByStudentId(studentId); return studentMapper.selectByStudentId(studentId);
} }
// 添加更新方法
public void update(Student student) { public void update(Student student) {
studentMapper.update(student); studentMapper.update(student);
} }
// 添加删除方法
public void delete(Integer id) { public void delete(Integer id) {
studentMapper.delete(id); studentMapper.delete(id);
} }

View File

@ -1,4 +1,3 @@
// com/campus/service/impl/AttendanceServiceImpl.java
package com.campus.service.impl; package com.campus.service.impl;
import com.campus.entity.AttendanceRecord; import com.campus.entity.AttendanceRecord;
@ -21,19 +20,19 @@ public class AttendanceServiceImpl implements AttendanceService {
private AttendanceMapper attendanceMapper; private AttendanceMapper attendanceMapper;
@Autowired @Autowired
private StudentMapper studentMapper; // 使用你定义的StudentMapper private StudentMapper studentMapper;
@Override @Override
@Transactional @Transactional
public boolean recordAttendance(AttendanceRecord record) { public boolean recordAttendance(AttendanceRecord record) {
// 验证学生是否存在 - 使用 selectByStudentId 方法 // 验证学生是否存在 - 参数类型改为 Integer
Student student = studentMapper.selectByStudentId(record.getStudentId()); Student student = studentMapper.selectByStudentId(record.getStudentId());
if (student == null) { if (student == null) {
throw new RuntimeException("学生不存在,学号:" + record.getStudentId()); throw new RuntimeException("学生不存在,学号:" + record.getStudentId());
} }
// 检查是否已考勤 // 检查是否已考勤 - 参数类型改为 Integer
if (checkAttendanceExists(record.getStudentId(), record.getAttendanceDate())) { if (checkAttendanceExists(record.getStudentId(), record.getAttendanceDate())) {
throw new RuntimeException("该学生今天已考勤,学号:" + record.getStudentId()); throw new RuntimeException("该学生今天已考勤,学号:" + record.getStudentId());
} }
@ -49,13 +48,13 @@ public class AttendanceServiceImpl implements AttendanceService {
@Override @Override
@Transactional @Transactional
public boolean makeUpAttendance(AttendanceRecord record) { public boolean makeUpAttendance(AttendanceRecord record) {
// 验证学生是否存在 // 验证学生是否存在 - 参数类型改为 Integer
Student student = studentMapper.selectByStudentId(record.getStudentId()); Student student = studentMapper.selectByStudentId(record.getStudentId());
if (student == null) { if (student == null) {
throw new RuntimeException("学生不存在,学号:" + record.getStudentId()); throw new RuntimeException("学生不存在,学号:" + record.getStudentId());
} }
// 检查是否已有记录 // 检查是否已有记录 - 参数类型改为 Integer
AttendanceRecord existing = attendanceMapper.selectByStudentAndDate( AttendanceRecord existing = attendanceMapper.selectByStudentAndDate(
record.getStudentId(), record.getAttendanceDate()); record.getStudentId(), record.getAttendanceDate());
@ -73,7 +72,7 @@ public class AttendanceServiceImpl implements AttendanceService {
} }
@Override @Override
public List<AttendanceRecord> getAttendanceByStudentId(String studentId) { public List<AttendanceRecord> getAttendanceByStudentId(Integer studentId) { // 改为 Integer
return attendanceMapper.selectByStudentId(studentId); return attendanceMapper.selectByStudentId(studentId);
} }
@ -88,12 +87,12 @@ public class AttendanceServiceImpl implements AttendanceService {
} }
@Override @Override
public Map<String, Object> getStudentAttendanceSummary(String studentId) { public Map<String, Object> getStudentAttendanceSummary(Integer studentId) { // 改为 Integer
return attendanceMapper.getStudentAttendanceSummary(studentId); return attendanceMapper.getStudentAttendanceSummary(studentId);
} }
@Override @Override
public boolean checkAttendanceExists(String studentId, Date date) { public boolean checkAttendanceExists(Integer studentId, Date date) { // 改为 Integer
AttendanceRecord record = attendanceMapper.selectByStudentAndDate(studentId, date); AttendanceRecord record = attendanceMapper.selectByStudentAndDate(studentId, date);
return record != null; return record != null;
} }

View File

@ -21,7 +21,8 @@
VALUES(#{studentId}, #{courseName}, #{attendanceDate}, #{attendanceTime}, #{status}, #{remarks}, #{createdBy}) VALUES(#{studentId}, #{courseName}, #{attendanceDate}, #{attendanceTime}, #{status}, #{remarks}, #{createdBy})
</insert> </insert>
<select id="selectByStudentId" parameterType="string" resultMap="attendanceMap"> <!-- 修改参数类型为 integer -->
<select id="selectByStudentId" parameterType="integer" resultMap="attendanceMap">
SELECT * FROM attendance_record SELECT * FROM attendance_record
WHERE student_id = #{studentId} WHERE student_id = #{studentId}
ORDER BY attendance_date DESC, attendance_time DESC ORDER BY attendance_date DESC, attendance_time DESC
@ -33,6 +34,7 @@
ORDER BY student_id, attendance_time ORDER BY student_id, attendance_time
</select> </select>
<!-- 多参数方法不需要指定 parameterType -->
<select id="selectByStudentAndDate" resultMap="attendanceMap"> <select id="selectByStudentAndDate" resultMap="attendanceMap">
SELECT * FROM attendance_record SELECT * FROM attendance_record
WHERE student_id = #{studentId} AND attendance_date = #{date} WHERE student_id = #{studentId} AND attendance_date = #{date}
@ -51,6 +53,43 @@
DELETE FROM attendance_record WHERE id = #{id} DELETE FROM attendance_record WHERE id = #{id}
</delete> </delete>
<!-- 新增selectById 方法 -->
<select id="selectById" parameterType="int" resultMap="attendanceMap">
SELECT * FROM attendance_record WHERE id = #{id}
</select>
<!-- 新增batchInsert 方法 -->
<insert id="batchInsert" parameterType="list">
INSERT INTO attendance_record(student_id, course_name, attendance_date, attendance_time, status, remarks, created_by)
VALUES
<foreach collection="records" item="record" separator=",">
(#{record.studentId}, #{record.courseName}, #{record.attendanceDate}, #{record.attendanceTime}, #{record.status}, #{record.remarks}, #{record.createdBy})
</foreach>
</insert>
<!-- 新增selectByCondition 方法 -->
<select id="selectByCondition" resultMap="attendanceMap">
SELECT * FROM attendance_record
<where>
<if test="record.studentId != null">
AND student_id = #{record.studentId}
</if>
<if test="record.courseName != null and record.courseName != ''">
AND course_name = #{record.courseName}
</if>
<if test="record.attendanceDate != null">
AND attendance_date = #{record.attendanceDate}
</if>
<if test="record.status != null and record.status != ''">
AND status = #{record.status}
</if>
</where>
ORDER BY attendance_date DESC, attendance_time DESC
<if test="limit != null and offset != null">
LIMIT #{offset}, #{limit}
</if>
</select>
<select id="getAttendanceStatistics" resultType="map"> <select id="getAttendanceStatistics" resultType="map">
SELECT SELECT
attendance_date as date, attendance_date as date,
@ -64,6 +103,7 @@
ORDER BY attendance_date DESC ORDER BY attendance_date DESC
</select> </select>
<!-- 这个方法的参数类型保持为 string -->
<select id="getStudentAttendanceSummary" parameterType="string" resultType="map"> <select id="getStudentAttendanceSummary" parameterType="string" resultType="map">
SELECT SELECT
student_id, student_id,