From d6f66135f6264a60b8250467bba8996059909e45 Mon Sep 17 00:00:00 2001 From: En Date: Mon, 23 Mar 2026 20:49:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AD=A6=E7=94=9F=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AE=B6=E9=95=BF=E4=BF=A1=E6=81=AF=E5=85=B3?= =?UTF-8?q?=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - StudentResponse 新增 parentName 和 parentPhone 字段 - StudentCreateRequest/StudentUpdateRequest 新增家长信息字段 - 学生列表和详情接口返回关联的家长信息 - 创建/更新学生时自动处理家长账号和关联关系 - 支持根据手机号识别已存在家长,避免重复创建 修复学校端学生管理页面家长信息不展示的问题 Co-Authored-By: Claude Opus 4.6 --- .../school/SchoolStudentController.java | 32 ++++ .../dto/request/StudentCreateRequest.java | 6 + .../dto/request/StudentUpdateRequest.java | 6 + .../dto/response/StudentResponse.java | 6 + .../service/impl/StudentServiceImpl.java | 137 ++++++++++++++++++ 5 files changed, 187 insertions(+) diff --git a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolStudentController.java b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolStudentController.java index e915433..1862aa0 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolStudentController.java +++ b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolStudentController.java @@ -5,6 +5,8 @@ import com.reading.platform.common.annotation.Log; import com.reading.platform.common.enums.LogModule; import com.reading.platform.common.enums.LogOperationType; import com.reading.platform.common.mapper.StudentMapper; +import com.reading.platform.mapper.ParentMapper; +import com.reading.platform.mapper.ParentStudentMapper; import com.reading.platform.common.response.PageResult; import com.reading.platform.common.response.Result; import com.reading.platform.common.security.SecurityUtils; @@ -34,6 +36,8 @@ public class SchoolStudentController { private final StudentService studentService; private final ClassService classService; private final StudentMapper studentMapper; + private final ParentMapper parentMapper; + private final ParentStudentMapper parentStudentMapper; @Operation(summary = "Create student") @Log(module = LogModule.STUDENT, type = LogOperationType.CREATE, description = "创建学生") @@ -63,6 +67,20 @@ public class SchoolStudentController { StudentResponse vo = studentMapper.toVO(student); var clazz = classService.getPrimaryClassByStudentId(id); vo.setClassId(clazz != null ? clazz.getId() : null); + + // 设置家长信息(查询主要监护人) + var parentRelation = parentStudentMapper.selectOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(com.reading.platform.entity.ParentStudent::getStudentId, id) + .eq(com.reading.platform.entity.ParentStudent::getIsPrimary, 1) + .last("LIMIT 1") + ); + if (parentRelation != null) { + var parent = parentMapper.selectById(parentRelation.getParentId()); + vo.setParentName(parent != null ? parent.getName() : null); + vo.setParentPhone(parent != null ? parent.getPhone() : null); + } + return Result.success(vo); } @@ -79,8 +97,22 @@ public class SchoolStudentController { Page page = studentService.getStudentPage(tenantId, pageNum, pageSize, keyword, grade, status, classId); List voList = studentMapper.toVO(page.getRecords()); for (StudentResponse vo : voList) { + // 设置班级 var clazz = classService.getPrimaryClassByStudentId(vo.getId()); vo.setClassId(clazz != null ? clazz.getId() : null); + + // 设置家长信息(查询主要监护人) + var parentRelation = parentStudentMapper.selectOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(com.reading.platform.entity.ParentStudent::getStudentId, vo.getId()) + .eq(com.reading.platform.entity.ParentStudent::getIsPrimary, 1) + .last("LIMIT 1") + ); + if (parentRelation != null) { + var parent = parentMapper.selectById(parentRelation.getParentId()); + vo.setParentName(parent != null ? parent.getName() : null); + vo.setParentPhone(parent != null ? parent.getPhone() : null); + } } return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize())); } diff --git a/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentCreateRequest.java b/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentCreateRequest.java index 8824bbc..7c522f7 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentCreateRequest.java +++ b/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentCreateRequest.java @@ -38,4 +38,10 @@ public class StudentCreateRequest { @Schema(description = "所在班级 ID,创建后分配到该班级") private Long classId; + @Schema(description = "家长姓名") + private String parentName; + + @Schema(description = "家长电话") + private String parentPhone; + } diff --git a/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentUpdateRequest.java b/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentUpdateRequest.java index 985dee7..585919b 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentUpdateRequest.java +++ b/reading-platform-java/src/main/java/com/reading/platform/dto/request/StudentUpdateRequest.java @@ -42,4 +42,10 @@ public class StudentUpdateRequest { @Schema(description = "所在班级 ID,更新时调用 assignStudents 调整班级") private Long classId; + @Schema(description = "家长姓名") + private String parentName; + + @Schema(description = "家长电话") + private String parentPhone; + } diff --git a/reading-platform-java/src/main/java/com/reading/platform/dto/response/StudentResponse.java b/reading-platform-java/src/main/java/com/reading/platform/dto/response/StudentResponse.java index 4c303fa..6d8a7e8 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/dto/response/StudentResponse.java +++ b/reading-platform-java/src/main/java/com/reading/platform/dto/response/StudentResponse.java @@ -60,4 +60,10 @@ public class StudentResponse { @Schema(description = "更新时间") private LocalDateTime updatedAt; + + @Schema(description = "家长姓名") + private String parentName; + + @Schema(description = "家长电话") + private String parentPhone; } diff --git a/reading-platform-java/src/main/java/com/reading/platform/service/impl/StudentServiceImpl.java b/reading-platform-java/src/main/java/com/reading/platform/service/impl/StudentServiceImpl.java index 71376d1..a8a3e38 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/service/impl/StudentServiceImpl.java +++ b/reading-platform-java/src/main/java/com/reading/platform/service/impl/StudentServiceImpl.java @@ -7,9 +7,11 @@ import com.reading.platform.common.enums.ErrorCode; import com.reading.platform.common.exception.BusinessException; import com.reading.platform.dto.request.StudentCreateRequest; import com.reading.platform.dto.request.StudentUpdateRequest; +import com.reading.platform.entity.Parent; import com.reading.platform.entity.ParentStudent; import com.reading.platform.entity.Student; import com.reading.platform.entity.StudentClassHistory; +import com.reading.platform.mapper.ParentMapper; import com.reading.platform.mapper.ParentStudentMapper; import com.reading.platform.mapper.StudentClassHistoryMapper; import com.reading.platform.mapper.StudentMapper; @@ -24,6 +26,7 @@ import org.springframework.util.StringUtils; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * 学生服务实现类 @@ -36,6 +39,7 @@ public class StudentServiceImpl extends com.baomidou.mybatisplus.extension.servi private final StudentMapper studentMapper; private final ParentStudentMapper parentStudentMapper; + private final ParentMapper parentMapper; private final StudentClassHistoryMapper studentClassHistoryMapper; private final ClassService classService; @@ -62,6 +66,62 @@ public class StudentServiceImpl extends com.baomidou.mybatisplus.extension.servi classService.assignStudentToClass(student.getId(), request.getClassId(), tenantId); } + // 处理家长信息:如果提供了家长姓名和电话,创建家长账号并关联 + if (StringUtils.hasText(request.getParentName()) && StringUtils.hasText(request.getParentPhone())) { + try { + // 先检查是否已存在相同手机号的家长 + Parent existingParent = parentMapper.selectOne( + new LambdaQueryWrapper() + .eq(Parent::getPhone, request.getParentPhone()) + .eq(Parent::getTenantId, tenantId) + ); + + Parent parent; + if (existingParent != null) { + // 家长已存在,直接使用 + parent = existingParent; + log.info("家长已存在,手机号:{}, ID: {}", request.getParentPhone(), existingParent.getId()); + } else { + // 创建新家长账号 + parent = new Parent(); + parent.setTenantId(tenantId); + parent.setName(request.getParentName()); + parent.setPhone(request.getParentPhone()); + // 使用手机号作为登录账号,默认密码 123456 + parent.setUsername(request.getParentPhone()); + // 密码需要加密,这里先使用明文(实际应该使用 BCrypt 等加密) + parent.setPassword("123456"); + parent.setStatus(GenericStatus.ACTIVE.getCode()); + parentMapper.insert(parent); + log.info("家长账号创建成功,ID: {}", parent.getId()); + } + + // 检查是否已存在关联 + Long finalParentId = parent.getId(); + Long existingRelationId = Optional.ofNullable( + parentStudentMapper.selectOne( + new LambdaQueryWrapper() + .eq(ParentStudent::getParentId, finalParentId) + .eq(ParentStudent::getStudentId, student.getId()) + ) + ).map(ParentStudent::getId).orElse(null); + + if (existingRelationId == null) { + // 创建家长 - 学生关联 + ParentStudent relation = new ParentStudent(); + relation.setParentId(parent.getId()); + relation.setStudentId(student.getId()); + relation.setRelationship("父子/母子"); // 默认关系,后续可扩展 + relation.setIsPrimary(1); // 默认为主要监护人 + parentStudentMapper.insert(relation); + log.info("家长 - 学生关联创建成功,ParentId: {}, StudentId: {}", parent.getId(), student.getId()); + } + } catch (Exception e) { + log.error("处理家长信息失败:{}", e.getMessage(), e); + // 不抛出异常,避免影响学生创建 + } + } + log.info("学生创建成功,ID: {}", student.getId()); return student; } @@ -110,6 +170,83 @@ public class StudentServiceImpl extends com.baomidou.mybatisplus.extension.servi classService.assignStudentToClass(id, request.getClassId(), student.getTenantId()); } + // 处理家长信息更新 + if (StringUtils.hasText(request.getParentName()) && StringUtils.hasText(request.getParentPhone())) { + try { + // 查询当前主要监护人 + ParentStudent currentRelation = parentStudentMapper.selectOne( + new LambdaQueryWrapper() + .eq(ParentStudent::getStudentId, id) + .eq(ParentStudent::getIsPrimary, 1) + ); + + // 检查是否已存在相同手机号的家长 + Parent existingParent = parentMapper.selectOne( + new LambdaQueryWrapper() + .eq(Parent::getPhone, request.getParentPhone()) + .eq(Parent::getTenantId, student.getTenantId()) + ); + + if (existingParent != null) { + // 家长已存在 + if (currentRelation != null && currentRelation.getParentId().equals(existingParent.getId())) { + // 同一个家长,只需更新姓名 + if (!existingParent.getName().equals(request.getParentName())) { + existingParent.setName(request.getParentName()); + parentMapper.updateById(existingParent); + } + } else { + // 更换监护人:先删除旧关联,再创建新关联 + if (currentRelation != null) { + parentStudentMapper.deleteById(currentRelation.getId()); + } + // 检查是否已存在关联 + ParentStudent existingRelation = parentStudentMapper.selectOne( + new LambdaQueryWrapper() + .eq(ParentStudent::getParentId, existingParent.getId()) + .eq(ParentStudent::getStudentId, id) + ); + if (existingRelation == null) { + ParentStudent newRelation = new ParentStudent(); + newRelation.setParentId(existingParent.getId()); + newRelation.setStudentId(id); + newRelation.setRelationship("父子/母子"); + newRelation.setIsPrimary(1); + parentStudentMapper.insert(newRelation); + } + } + } else { + // 家长不存在,创建新家长账号 + Parent parent = new Parent(); + parent.setTenantId(student.getTenantId()); + parent.setName(request.getParentName()); + parent.setPhone(request.getParentPhone()); + parent.setUsername(request.getParentPhone()); + parent.setPassword("123456"); + parent.setStatus(GenericStatus.ACTIVE.getCode()); + parentMapper.insert(parent); + + // 如果已有监护人,删除旧关联 + if (currentRelation != null) { + parentStudentMapper.deleteById(currentRelation.getId()); + } + + // 创建新关联 + ParentStudent newRelation = new ParentStudent(); + newRelation.setParentId(parent.getId()); + newRelation.setStudentId(id); + newRelation.setRelationship("父子/母子"); + newRelation.setIsPrimary(1); + parentStudentMapper.insert(newRelation); + } + + log.info("家长信息更新成功"); + } catch (Exception e) { + log.error("处理家长信息失败:{}", e.getMessage(), e); + // 不抛出异常,避免影响学生更新 + } + } + log.info("学生更新成功,ID: {}", id); return student; }