package com.emergencyrepair.auth; import com.emergencyrepair.common.Result; import com.emergencyrepair.system.entity.SysLoginLog; import com.emergencyrepair.system.mapper.SysLoginLogMapper; import com.emergencyrepair.system.service.SystemService; import lombok.RequiredArgsConstructor; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.time.LocalDateTime; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/auth") @RequiredArgsConstructor public class AuthController { private final JdbcTemplate jdbcTemplate; private final SysLoginLogMapper loginLogMapper; private final SystemService systemService; private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); @PostMapping("/login") public Result> login(@RequestBody Map body, HttpServletRequest request) { String username = body == null || body.get("username") == null ? "" : body.get("username").trim(); String password = body == null || body.get("password") == null ? "" : body.get("password"); Map user = findUser(username); boolean success = false; String message = "用户名或密码错误"; if (user != null) { if (isDisabled(user)) { message = "账号已停用"; } else if (matches(password, stringValue(user.get("password")))) { success = true; } else if ("admin".equals(username) && ("admin".equals(password) || "admin123".equals(password))) { // Keep the original demo credential working for the built-in administrator. success = true; } } recordLogin(username, user, request, success, success ? "登录成功" : message); if (!success) { return Result.error(message); } Map data = new LinkedHashMap<>(); data.put("token", "demo-" + username + "-token"); data.put("username", username); data.put("realName", StringUtils.hasText(stringValue(user.get("nickName"))) ? stringValue(user.get("nickName")) : username); data.put("deptName", stringValue(user.get("deptName"))); data.put("roles", systemService.roleCodes(username)); data.put("permissions", systemService.permissionCodes(username)); return Result.ok(data); } @GetMapping("/me") public Result> me(@RequestHeader(value = "X-Username", required = false) String headerUser, @RequestHeader(value = "Authorization", required = false) String authorization) { String username = currentUsername(headerUser, authorization); Map user = findUser(username); if (user == null) { return Result.error("登录状态已失效"); } Map data = new LinkedHashMap<>(); data.put("username", username); data.put("realName", StringUtils.hasText(stringValue(user.get("nickName"))) ? stringValue(user.get("nickName")) : username); data.put("deptName", stringValue(user.get("deptName"))); data.put("roles", systemService.roleCodes(username)); data.put("permissions", systemService.permissionCodes(username)); return Result.ok(data); } private Map findUser(String username) { if (!StringUtils.hasText(username)) { return null; } try { List> rows = jdbcTemplate.query( "SELECT u.USER_ID, u.USER_NAME, u.NICK_NAME, u.PASSWORD, u.STATUS, d.DEPT_NAME " + "FROM LX.SYS_USER u LEFT JOIN LX.SYS_DEPT d ON d.DEPT_ID = u.DEPT_ID " + "WHERE u.USER_NAME = ? AND (u.DEL_FLAG = '0' OR u.DEL_FLAG IS NULL)", new Object[]{username}, (rs, rowNum) -> { Map row = new LinkedHashMap<>(); row.put("userId", rs.getLong("USER_ID")); row.put("userName", rs.getString("USER_NAME")); row.put("nickName", rs.getString("NICK_NAME")); row.put("password", rs.getString("PASSWORD")); row.put("status", rs.getString("STATUS")); row.put("deptName", rs.getString("DEPT_NAME")); return row; }); return rows.isEmpty() ? null : rows.get(0); } catch (DataAccessException ex) { return null; } } private boolean matches(String rawPassword, String encodedPassword) { if (!StringUtils.hasText(rawPassword) || !StringUtils.hasText(encodedPassword)) { return false; } try { return passwordEncoder.matches(rawPassword, encodedPassword.trim()); } catch (Exception ex) { return false; } } private boolean isDisabled(Map user) { return "1".equals(stringValue(user.get("status"))); } private String stringValue(Object value) { return value == null ? "" : String.valueOf(value).trim(); } private String currentUsername(String headerUser, String authorization) { if (StringUtils.hasText(headerUser)) { return headerUser.trim(); } if (!StringUtils.hasText(authorization)) { return ""; } String token = authorization.trim(); if (token.startsWith("Bearer ")) { token = token.substring(7).trim(); } if (token.startsWith("demo-") && token.endsWith("-token")) { return token.substring(5, token.length() - 6); } return token; } private void recordLogin(String username, Map user, HttpServletRequest request, boolean success, String message) { try { SysLoginLog log = new SysLoginLog(); log.setUserId(user == null ? null : (Long) user.get("userId")); log.setUserName(username); log.setNickName(user == null ? null : stringValue(user.get("nickName"))); log.setDeptName(user == null ? "" : stringValue(user.get("deptName"))); log.setLoginIp(clientIp(request)); log.setStatus(success ? "SUCCESS" : "FAIL"); log.setMessage(message); log.setLoginTime(LocalDateTime.now()); loginLogMapper.insert(log); } catch (Exception ignored) { // Login must not fail because the audit table is unavailable. } } private String clientIp(HttpServletRequest request) { if (request == null) { return ""; } String forwarded = request.getHeader("X-Forwarded-For"); if (StringUtils.hasText(forwarded)) { return forwarded.split(",")[0].trim(); } return request.getRemoteAddr(); } }