package rd.controller.user; import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.crypto.digest.BCrypt; import lombok.extern.slf4j.Slf4j; import rd.data.code.ServiceCode; import rd.data.db.table.UserBasic; import rd.data.enums.UserType; import rd.data.model.request.auth.UserLoginRequest; import rd.data.model.response.Response; import rd.data.model.response.auth.UserLoginStatusResponse; import rd.data.model.response.user.UserBasicInfo; import rd.service.user.StudentUserService; import rd.service.user.UserBasicService; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * 登录认证Controller */ @Slf4j @RestController @RequestMapping("/user/auth") public class UserAuthController { private final UserBasicService userBasicService; private final StudentUserService studentUserService; public UserAuthController(UserBasicService userBasicService, StudentUserService studentUserService) { this.userBasicService = userBasicService; this.studentUserService = studentUserService; } @RequestMapping("/login") public Response login(@RequestBody UserLoginRequest loginRequest) { String username = loginRequest.username(); String password = loginRequest.password(); UserBasic userBasic = userBasicService.getUserBasicByUsername(username); if (userBasic == null || userBasic.getPassword() == null || userBasic.getPassword().isEmpty()) { // 用户不存在,尝试从教务处获取用户信息 log.info("用户'{}'不存在,尝试从教务处获取用户信息", username); try { var newStudentDto = studentUserService.tryAddStudentFromOfficial(username, password); userBasic = newStudentDto.userBasic(); } catch (Exception e) { return Response.error(ServiceCode.StuNumDoesNotExists, "从教务处获取用户信息失败,\n" + "如果是非学生学生用户,请检查用户名是否正确;\n" + "如果是学生用户,请检查用户名和密码,或者再重试重试一下。\nException:" + e ); } } else { // 用户已经存在,直接从数据库获取数据 if (!BCrypt.checkpw(password, userBasic.getPassword())) { return Response.error(ServiceCode.UserPasswordWrong); } } StpUtil.login(userBasic.getId()); UserType userType = switch (userBasic.getType()) { case 0 -> UserType.STUDENT; case 1 -> UserType.TEACHER; case 2 -> UserType.ADMIN; default -> { log.warn("未知的用户类型:{}", userBasic.getType()); yield UserType.STUDENT; } }; var basicInfoResponse = UserBasicInfo.builder() .id(userBasic.getId()) .username(userBasic.getUsername()) .userType(userType) .build(); return Response.success(basicInfoResponse); } @RequestMapping("/logout") public Response logout() { StpUtil.logout(); return Response.success(); } @RequestMapping("/check") public Response checkLogin() { boolean login = StpUtil.isLogin(); if (!login) { return Response.success(new UserLoginStatusResponse(null, null, false)); } Long uid = StpUtil.getLoginIdAsLong(); String role = StpUtil.getRoleList().get(0); return Response.success(new UserLoginStatusResponse(uid, role, true)); } @SaCheckLogin @RequestMapping("/modify-password") public Response modifyPassword(@RequestParam("old") String oldPassword, @RequestParam("new") String newPassword) { Long uid = StpUtil.getLoginIdAsLong(); var userBasic = userBasicService.getUserBasicById(uid); if (!BCrypt.checkpw(oldPassword, userBasic.getPassword())) { return Response.error(ServiceCode.UserPasswordWrong); } userBasicService.updatePassword(uid, newPassword); StpUtil.logout(); return Response.success(); } }