|
|
@@ -1,273 +1,295 @@
|
|
|
-package com.zxyj.controller.admin;
|
|
|
-
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
-import com.zxyj.common.Result;
|
|
|
-import com.zxyj.config.JwtConfig;
|
|
|
-import com.zxyj.dto.AdminLoginDTO;
|
|
|
-import com.zxyj.dto.SendCodeDTO;
|
|
|
-import com.zxyj.entity.Admin;
|
|
|
-import com.zxyj.mapper.AdminMapper;
|
|
|
-import com.zxyj.service.LoginAttemptService;
|
|
|
-import com.zxyj.service.VerificationCodeService;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import javax.annotation.Resource;
|
|
|
-import org.springframework.web.bind.annotation.*;
|
|
|
-
|
|
|
-import javax.servlet.http.HttpServletRequest;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-@Slf4j
|
|
|
-@RestController
|
|
|
-@RequestMapping("/api/admin-auth")
|
|
|
-public class AdminAuthController {
|
|
|
-
|
|
|
- @Resource
|
|
|
- private AdminMapper adminMapper;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private VerificationCodeService verificationCodeService;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private JwtConfig jwtConfig;
|
|
|
-
|
|
|
- @Resource
|
|
|
- private LoginAttemptService loginAttemptService;
|
|
|
-
|
|
|
- /**
|
|
|
- * 发送管理员登录验证码
|
|
|
- */
|
|
|
- @PostMapping("/send-code")
|
|
|
- public Result<Boolean> sendCode(@RequestBody SendCodeDTO dto) {
|
|
|
- if (dto.getPhone() == null || dto.getPhone().isEmpty()) {
|
|
|
- return Result.error("手机号不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- // 验证手机号格式
|
|
|
- if (!dto.getPhone().matches("^1[3-9]\\d{9}$")) {
|
|
|
- return Result.error("手机号格式不正确");
|
|
|
- }
|
|
|
-
|
|
|
- // 验证该手机号是否已注册为管理员
|
|
|
- Admin admin = adminMapper.selectOne(new LambdaQueryWrapper<Admin>()
|
|
|
- .eq(Admin::getPhone, dto.getPhone()));
|
|
|
-
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("该手机号未注册为管理员");
|
|
|
- }
|
|
|
-
|
|
|
- // 生成验证码
|
|
|
- verificationCodeService.generateCode(dto.getPhone(), "admin_login");
|
|
|
- return Result.success(true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 管理员验证码登录
|
|
|
- */
|
|
|
- @PostMapping("/login")
|
|
|
- public Result<Map<String, Object>> login(@RequestBody AdminLoginDTO dto, HttpServletRequest request) {
|
|
|
- if (dto.getPhone() == null || dto.getCode() == null) {
|
|
|
- return Result.error("手机号和验证码不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- String ip = getClientIP(request);
|
|
|
- if (loginAttemptService.isBlocked(ip)) {
|
|
|
- long remaining = loginAttemptService.getLockRemainingTime(ip);
|
|
|
- return Result.error("登录尝试过多,请" + (remaining / 60000 + 1) + "分钟后重试");
|
|
|
- }
|
|
|
-
|
|
|
- boolean valid = verificationCodeService.verifyCode(dto.getPhone(), dto.getCode(), "admin_login");
|
|
|
- if (!valid) {
|
|
|
- loginAttemptService.recordFailure(ip);
|
|
|
- return Result.error("验证码错误或已过期");
|
|
|
- }
|
|
|
-
|
|
|
- Admin admin = adminMapper.selectOne(new LambdaQueryWrapper<Admin>()
|
|
|
- .eq(Admin::getPhone, dto.getPhone()));
|
|
|
-
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("管理员不存在");
|
|
|
- }
|
|
|
-
|
|
|
- if (admin.getStatus() != null && admin.getStatus() != 1) {
|
|
|
- return Result.error("账号已被禁用");
|
|
|
- }
|
|
|
-
|
|
|
- loginAttemptService.clearSuccess(ip);
|
|
|
-
|
|
|
- String token = jwtConfig.generateToken(admin.getId(), "admin");
|
|
|
-
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
- result.put("token", token);
|
|
|
- result.put("adminId", admin.getId());
|
|
|
- result.put("username", admin.getUsername());
|
|
|
- result.put("realName", admin.getRealName());
|
|
|
-
|
|
|
- return Result.success(result);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前登录管理员信息
|
|
|
- */
|
|
|
- @PostMapping("/info")
|
|
|
- public Result<Admin> getAdminInfo(@RequestAttribute("userId") Long adminId) {
|
|
|
- Admin admin = adminMapper.selectById(adminId);
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("管理员不存在");
|
|
|
- }
|
|
|
- // 隐藏密码
|
|
|
- admin.setPassword(null);
|
|
|
- return Result.success(admin);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 管理员修改密码
|
|
|
- */
|
|
|
- @PostMapping("/change-password")
|
|
|
- public Result<Boolean> changePassword(@RequestAttribute("userId") Long adminId,
|
|
|
- @RequestBody Map<String, String> params) {
|
|
|
- String oldPassword = params.get("oldPassword");
|
|
|
- String newPassword = params.get("newPassword");
|
|
|
-
|
|
|
- Admin admin = adminMapper.selectById(adminId);
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("管理员不存在");
|
|
|
- }
|
|
|
-
|
|
|
- // 验证旧密码
|
|
|
- String encryptedOldPassword = encryptPassword(oldPassword);
|
|
|
- if (!encryptedOldPassword.equals(admin.getPassword())) {
|
|
|
- return Result.error("原密码错误");
|
|
|
- }
|
|
|
-
|
|
|
- // 更新密码
|
|
|
- admin.setPassword(encryptPassword(newPassword));
|
|
|
- admin.setUpdatedAt(new Date());
|
|
|
- adminMapper.updateById(admin);
|
|
|
-
|
|
|
- return Result.success(true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新管理员个人信息
|
|
|
- */
|
|
|
- @PostMapping("/update-info")
|
|
|
- public Result<Admin> updateInfo(@RequestAttribute("userId") Long adminId,
|
|
|
- @RequestBody Map<String, Object> params) {
|
|
|
- Admin admin = adminMapper.selectById(adminId);
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("管理员不存在");
|
|
|
- }
|
|
|
-
|
|
|
- if (params.containsKey("nickname")) {
|
|
|
- admin.setNickname((String) params.get("nickname"));
|
|
|
- }
|
|
|
- if (params.containsKey("phone")) {
|
|
|
- admin.setPhone((String) params.get("phone"));
|
|
|
- }
|
|
|
- if (params.containsKey("email")) {
|
|
|
- admin.setEmail((String) params.get("email"));
|
|
|
- }
|
|
|
-
|
|
|
- admin.setUpdatedAt(new Date());
|
|
|
- adminMapper.updateById(admin);
|
|
|
- admin.setPassword(null);
|
|
|
- return Result.success(admin);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 通过验证码重置密码
|
|
|
- */
|
|
|
- @PostMapping("/reset-password")
|
|
|
- public Result<Boolean> resetPassword(@RequestAttribute("userId") Long adminId,
|
|
|
- @RequestBody Map<String, String> params) {
|
|
|
- String phone = params.get("phone");
|
|
|
- String code = params.get("code");
|
|
|
- String newPassword = params.get("newPassword");
|
|
|
-
|
|
|
- if (phone == null || code == null || newPassword == null) {
|
|
|
- return Result.error("手机号、验证码和新密码不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- if (!verificationCodeService.verifyCode(phone, code, "resetpwd")) {
|
|
|
- return Result.error("验证码错误或已过期");
|
|
|
- }
|
|
|
-
|
|
|
- Admin admin = adminMapper.selectById(adminId);
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("管理员不存在");
|
|
|
- }
|
|
|
-
|
|
|
- admin.setPassword(encryptPassword(newPassword));
|
|
|
- admin.setUpdatedAt(new Date());
|
|
|
- adminMapper.updateById(admin);
|
|
|
-
|
|
|
- return Result.success(true);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 管理员用户名密码登录
|
|
|
- */
|
|
|
- @PostMapping("/login-by-password")
|
|
|
- public Result<Map<String, Object>> loginByPassword(@RequestBody AdminLoginDTO dto, HttpServletRequest request) {
|
|
|
- if (dto.getPhone() == null || dto.getPassword() == null) {
|
|
|
- return Result.error("用户名和密码不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- String ip = getClientIP(request);
|
|
|
- if (loginAttemptService.isBlocked(ip)) {
|
|
|
- long remaining = loginAttemptService.getLockRemainingTime(ip);
|
|
|
- return Result.error("登录尝试过多,请" + (remaining / 60000 + 1) + "分钟后重试");
|
|
|
- }
|
|
|
-
|
|
|
- Admin admin = adminMapper.selectOne(new LambdaQueryWrapper<Admin>()
|
|
|
- .eq(Admin::getPhone, dto.getPhone())
|
|
|
- .or()
|
|
|
- .eq(Admin::getUsername, dto.getPhone()));
|
|
|
-
|
|
|
- if (admin == null) {
|
|
|
- return Result.error("管理员不存在");
|
|
|
- }
|
|
|
-
|
|
|
- String encryptedPassword = encryptPassword(dto.getPassword());
|
|
|
- if (!encryptedPassword.equals(admin.getPassword())) {
|
|
|
- loginAttemptService.recordFailure(ip);
|
|
|
- int remaining = loginAttemptService.getRemainingAttempts(ip);
|
|
|
- return Result.error("密码错误,剩余" + remaining + "次尝试机会");
|
|
|
- }
|
|
|
-
|
|
|
- if (admin.getStatus() != null && admin.getStatus() != 1) {
|
|
|
- return Result.error("账号已被禁用");
|
|
|
- }
|
|
|
-
|
|
|
- loginAttemptService.clearSuccess(ip);
|
|
|
-
|
|
|
- String token = jwtConfig.generateToken(admin.getId(), admin.getRole() != null ? admin.getRole() : "admin");
|
|
|
-
|
|
|
- Map<String, Object> result = new HashMap<>();
|
|
|
- result.put("token", token);
|
|
|
- result.put("adminId", admin.getId());
|
|
|
- result.put("username", admin.getUsername());
|
|
|
- result.put("realName", admin.getRealName());
|
|
|
- result.put("role", admin.getRole() != null ? admin.getRole() : "admin");
|
|
|
-
|
|
|
- return Result.success(result);
|
|
|
- }
|
|
|
-
|
|
|
- private String getClientIP(HttpServletRequest request) {
|
|
|
- String ip = request.getHeader("X-Forwarded-For");
|
|
|
- if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
|
|
- ip = request.getHeader("X-Real-IP");
|
|
|
- }
|
|
|
- if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
|
|
- ip = request.getRemoteAddr();
|
|
|
- }
|
|
|
- return ip;
|
|
|
- }
|
|
|
-
|
|
|
- private String encryptPassword(String password) {
|
|
|
- // MD5加密,实际项目应使用BCrypt等更安全的加密方式
|
|
|
- return org.springframework.util.DigestUtils.md5DigestAsHex(("xzyj_admin_salt_" + password).getBytes());
|
|
|
- }
|
|
|
-}
|
|
|
+package com.zxyj.controller.admin;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.zxyj.common.Result;
|
|
|
+import com.zxyj.config.JwtConfig;
|
|
|
+import com.zxyj.dto.AdminLoginDTO;
|
|
|
+import com.zxyj.dto.SendCodeDTO;
|
|
|
+import com.zxyj.entity.User;
|
|
|
+import com.zxyj.mapper.UserMapper;
|
|
|
+import com.zxyj.service.LoginAttemptService;
|
|
|
+import com.zxyj.service.UserService;
|
|
|
+import com.zxyj.service.VerificationCodeService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import javax.annotation.Resource;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@RestController
|
|
|
+@RequestMapping("/api/admin-auth")
|
|
|
+public class AdminAuthController {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private UserMapper userMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private UserService userService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private VerificationCodeService verificationCodeService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private JwtConfig jwtConfig;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private LoginAttemptService loginAttemptService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送管理员登录验证码
|
|
|
+ */
|
|
|
+ @PostMapping("/send-code")
|
|
|
+ public Result<Boolean> sendCode(@RequestBody SendCodeDTO dto) {
|
|
|
+ if (dto.getPhone() == null || dto.getPhone().isEmpty()) {
|
|
|
+ return Result.error("手机号不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证手机号格式
|
|
|
+ if (!dto.getPhone().matches("^1[3-9]\\d{9}$")) {
|
|
|
+ return Result.error("手机号格式不正确");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证该手机号是否已注册且为管理员/规划师
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
+ .eq(User::getPhone, dto.getPhone()));
|
|
|
+
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("该手机号未注册");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否有管理员或规划师角色
|
|
|
+ if (!"admin".equals(user.getRole()) && !userService.hasRole(user.getId(), "teacher")) {
|
|
|
+ return Result.error("该账号没有管理权限");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成验证码
|
|
|
+ verificationCodeService.generateCode(dto.getPhone(), "admin_login");
|
|
|
+ return Result.success(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 管理员验证码登录
|
|
|
+ */
|
|
|
+ @PostMapping("/login")
|
|
|
+ public Result<Map<String, Object>> login(@RequestBody AdminLoginDTO dto, HttpServletRequest request) {
|
|
|
+ if (dto.getPhone() == null || dto.getCode() == null) {
|
|
|
+ return Result.error("手机号和验证码不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ String ip = getClientIP(request);
|
|
|
+ String lockKey = dto.getPhone() + ":" + ip;
|
|
|
+ if (loginAttemptService.isBlocked(lockKey)) {
|
|
|
+ long remaining = loginAttemptService.getLockRemainingTime(lockKey);
|
|
|
+ return Result.error("登录尝试过多,请" + (remaining / 60000 + 1) + "分钟后重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean valid = verificationCodeService.verifyCode(dto.getPhone(), dto.getCode(), "admin_login");
|
|
|
+ if (!valid) {
|
|
|
+ loginAttemptService.recordFailure(lockKey);
|
|
|
+ return Result.error("验证码错误或已过期");
|
|
|
+ }
|
|
|
+
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
+ .eq(User::getPhone, dto.getPhone()));
|
|
|
+
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ loginAttemptService.clearSuccess(lockKey);
|
|
|
+
|
|
|
+ // 使用用户的角色,如果是admin或teacher
|
|
|
+ String role = user.getRole() != null ? user.getRole() : "admin";
|
|
|
+
|
|
|
+ String token = jwtConfig.generateToken(user.getId(), role);
|
|
|
+
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("token", token);
|
|
|
+ result.put("adminId", user.getId());
|
|
|
+ result.put("username", user.getNickname() != null ? user.getNickname() : user.getPhone());
|
|
|
+ result.put("realName", user.getRealName() != null ? user.getRealName() : user.getNickname());
|
|
|
+ result.put("role", role);
|
|
|
+
|
|
|
+ return Result.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前登录管理员信息
|
|
|
+ */
|
|
|
+ @PostMapping("/info")
|
|
|
+ public Result<Map<String, Object>> getAdminInfo(@RequestAttribute("userId") Long userId) {
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("用户不存在");
|
|
|
+ }
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("id", user.getId());
|
|
|
+ result.put("nickname", user.getNickname());
|
|
|
+ result.put("phone", user.getPhone());
|
|
|
+ result.put("email", "");
|
|
|
+ result.put("username", user.getNickname() != null ? user.getNickname() : user.getPhone());
|
|
|
+ result.put("realName", user.getRealName() != null ? user.getRealName() : user.getNickname());
|
|
|
+ result.put("role", user.getRole());
|
|
|
+ // 清除敏感信息
|
|
|
+ user.setPassword(null);
|
|
|
+ result.put("user", user);
|
|
|
+ return Result.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 管理员修改密码
|
|
|
+ */
|
|
|
+ @PostMapping("/change-password")
|
|
|
+ public Result<Boolean> changePassword(@RequestAttribute("userId") Long userId,
|
|
|
+ @RequestBody Map<String, String> params) {
|
|
|
+ String oldPassword = params.get("oldPassword");
|
|
|
+ String newPassword = params.get("newPassword");
|
|
|
+
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证旧密码
|
|
|
+ if (!userService.verifyPassword(userId, oldPassword)) {
|
|
|
+ return Result.error("原密码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新密码
|
|
|
+ userService.setPassword(userId, newPassword);
|
|
|
+
|
|
|
+ return Result.success(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新管理员个人信息
|
|
|
+ */
|
|
|
+ @PostMapping("/update-info")
|
|
|
+ public Result<Map<String, Object>> updateInfo(@RequestAttribute("userId") Long userId,
|
|
|
+ @RequestBody Map<String, Object> params) {
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (params.containsKey("nickname")) {
|
|
|
+ user.setNickname((String) params.get("nickname"));
|
|
|
+ }
|
|
|
+ if (params.containsKey("phone")) {
|
|
|
+ user.setPhone((String) params.get("phone"));
|
|
|
+ }
|
|
|
+
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
+ userMapper.updateById(user);
|
|
|
+
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("nickname", user.getNickname());
|
|
|
+ result.put("phone", user.getPhone());
|
|
|
+ return Result.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过验证码重置密码
|
|
|
+ */
|
|
|
+ @PostMapping("/reset-password")
|
|
|
+ public Result<Boolean> resetPassword(@RequestAttribute("userId") Long userId,
|
|
|
+ @RequestBody Map<String, String> params) {
|
|
|
+ String phone = params.get("phone");
|
|
|
+ String code = params.get("code");
|
|
|
+ String newPassword = params.get("newPassword");
|
|
|
+
|
|
|
+ if (phone == null || code == null || newPassword == null) {
|
|
|
+ return Result.error("手机号、验证码和新密码不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!verificationCodeService.verifyCode(phone, code, "resetpwd")) {
|
|
|
+ return Result.error("验证码错误或已过期");
|
|
|
+ }
|
|
|
+
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ userService.resetPassword(userId, newPassword);
|
|
|
+
|
|
|
+ return Result.success(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 管理员用户名密码登录
|
|
|
+ */
|
|
|
+ @PostMapping("/login-by-password")
|
|
|
+ public Result<Map<String, Object>> loginByPassword(@RequestBody AdminLoginDTO dto, HttpServletRequest request) {
|
|
|
+ if (dto.getPhone() == null || dto.getPassword() == null) {
|
|
|
+ return Result.error("用户名和密码不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ String ip = getClientIP(request);
|
|
|
+ String lockKey = dto.getPhone() + ":" + ip;
|
|
|
+ if (loginAttemptService.isBlocked(lockKey)) {
|
|
|
+ long remaining = loginAttemptService.getLockRemainingTime(lockKey);
|
|
|
+ return Result.error("登录尝试过多,请" + (remaining / 60000 + 1) + "分钟后重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 通过手机号查找用户
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
|
|
|
+ .eq(User::getPhone, dto.getPhone()));
|
|
|
+
|
|
|
+ if (user == null) {
|
|
|
+ return Result.error("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证密码(兼容两种hash方式)
|
|
|
+ java.nio.charset.Charset utf8 = java.nio.charset.StandardCharsets.UTF_8;
|
|
|
+ String hash1 = org.springframework.util.DigestUtils.md5DigestAsHex(
|
|
|
+ ("xzyj_salt_" + dto.getPassword()).getBytes(utf8));
|
|
|
+ String hash2 = org.springframework.util.DigestUtils.md5DigestAsHex(
|
|
|
+ ("xzyj_admin_salt_" + dto.getPassword()).getBytes(utf8));
|
|
|
+ if (!hash1.equals(user.getPassword()) && !hash2.equals(user.getPassword())) {
|
|
|
+ loginAttemptService.recordFailure(lockKey);
|
|
|
+ int remaining = loginAttemptService.getRemainingAttempts(lockKey);
|
|
|
+ return Result.error("密码错误,剩余" + remaining + "次尝试机会");
|
|
|
+ }
|
|
|
+
|
|
|
+ loginAttemptService.clearSuccess(lockKey);
|
|
|
+
|
|
|
+ // 确定角色
|
|
|
+ String role;
|
|
|
+ if ("admin".equals(user.getRole())) {
|
|
|
+ role = "admin";
|
|
|
+ } else if ("teacher".equals(user.getRole()) || userService.hasRole(user.getId(), "teacher")) {
|
|
|
+ role = "teacher";
|
|
|
+ } else {
|
|
|
+ // 如果用户既不是admin也不是teacher,给个默认角色,但记录警告
|
|
|
+ role = user.getRole() != null ? user.getRole() : "admin";
|
|
|
+ log.warn("用户 {} 登录后台管理,角色为: {}", user.getId(), role);
|
|
|
+ }
|
|
|
+
|
|
|
+ String token = jwtConfig.generateToken(user.getId(), role);
|
|
|
+
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
+ result.put("token", token);
|
|
|
+ result.put("adminId", user.getId());
|
|
|
+ result.put("username", user.getNickname() != null ? user.getNickname() : user.getPhone());
|
|
|
+ result.put("realName", user.getRealName() != null ? user.getRealName() : user.getNickname());
|
|
|
+ result.put("role", role);
|
|
|
+
|
|
|
+ return Result.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getClientIP(HttpServletRequest request) {
|
|
|
+ String ip = request.getHeader("X-Forwarded-For");
|
|
|
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getHeader("X-Real-IP");
|
|
|
+ }
|
|
|
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
|
|
+ ip = request.getRemoteAddr();
|
|
|
+ }
|
|
|
+ return ip;
|
|
|
+ }
|
|
|
+}
|