| | |
| | | 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; |
| | |
| | | @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<Map<String, Object>> login(@RequestBody Map<String, String> body) { |
| | | String username = body.get("username"); |
| | | String password = body.get("password"); |
| | | if (!"admin".equals(username) || (!"admin".equals(password) && !"admin123".equals(password))) { |
| | | return Result.error("用户名或密码错误,第一版请使用 admin/admin123"); |
| | | public Result<Map<String, Object>> login(@RequestBody Map<String, String> 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<String, Object> 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<String, Object> data = new LinkedHashMap<>(); |
| | | data.put("token", "demo-admin-token"); |
| | | data.put("username", "admin"); |
| | | data.put("realName", "系统管理员"); |
| | | data.put("deptName", resolveDepartmentName(username)); |
| | | 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("userId", String.valueOf(user.get("userId"))); |
| | | data.put("deptId", user.get("deptId") == null ? "" : String.valueOf(user.get("deptId"))); |
| | | data.put("engineeringMajor", stringValue(user.get("engineeringMajor"))); |
| | | data.put("teamMajor", stringValue(user.get("teamMajor"))); |
| | | data.put("deptResponsibleXNo", stringValue(user.get("deptResponsibleXNo"))); |
| | | data.put("responsibleXNo", stringValue(user.get("responsibleXNo"))); |
| | | data.put("roles", systemService.roleCodes(username)); |
| | | data.put("permissions", systemService.permissionCodes(username)); |
| | | return Result.ok(data); |
| | | } |
| | | |
| | | @GetMapping("/me") |
| | | public Result<Map<String, Object>> me() { |
| | | public Result<Map<String, Object>> me(@RequestHeader(value = "X-Username", required = false) String headerUser, |
| | | @RequestHeader(value = "Authorization", required = false) String authorization) { |
| | | String username = currentUsername(headerUser, authorization); |
| | | Map<String, Object> user = findUser(username); |
| | | if (user == null) { |
| | | return Result.error("登录状态已失效"); |
| | | } |
| | | Map<String, Object> data = new LinkedHashMap<>(); |
| | | data.put("username", "admin"); |
| | | data.put("realName", "系统管理员"); |
| | | data.put("deptName", resolveDepartmentName("admin")); |
| | | data.put("roles", new String[]{"SYSTEM_ADMIN"}); |
| | | 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("userId", String.valueOf(user.get("userId"))); |
| | | data.put("deptId", user.get("deptId") == null ? "" : String.valueOf(user.get("deptId"))); |
| | | data.put("engineeringMajor", stringValue(user.get("engineeringMajor"))); |
| | | data.put("teamMajor", stringValue(user.get("teamMajor"))); |
| | | data.put("deptResponsibleXNo", stringValue(user.get("deptResponsibleXNo"))); |
| | | data.put("responsibleXNo", stringValue(user.get("responsibleXNo"))); |
| | | data.put("roles", systemService.roleCodes(username)); |
| | | data.put("permissions", systemService.permissionCodes(username)); |
| | | return Result.ok(data); |
| | | } |
| | | |
| | | private String resolveDepartmentName(String username) { |
| | | private Map<String, Object> findUser(String username) { |
| | | if (!StringUtils.hasText(username)) { |
| | | return ""; |
| | | return null; |
| | | } |
| | | try { |
| | | List<String> names = jdbcTemplate.query( |
| | | "SELECT 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'", |
| | | List<Map<String, Object>> rows = jdbcTemplate.query( |
| | | "SELECT u.USER_ID, u.USER_NAME, u.NICK_NAME, u.PASSWORD, u.STATUS, u.DEPT_ID, d.DEPT_NAME, " |
| | | + "ue.ENGINEERING_MAJOR, ue.TEAM_MAJOR, ue.RESPONSIBLE_X_NO AS USER_RESPONSIBLE_X_NO, " |
| | | + "de.RESPONSIBLE_X_NO AS DEPT_RESPONSIBLE_X_NO " |
| | | + "FROM LX.SYS_USER u LEFT JOIN LX.SYS_DEPT d ON d.DEPT_ID = u.DEPT_ID " |
| | | + "LEFT JOIN LX.T_SYS_USER_EXT ue ON ue.USER_ID = u.USER_ID AND (ue.DEL_FLAG = 0 OR ue.DEL_FLAG IS NULL) " |
| | | + "LEFT JOIN LX.T_SYS_DEPT_EXT de ON de.DEPT_ID = u.DEPT_ID AND (de.DEL_FLAG = 0 OR de.DEL_FLAG IS NULL) " |
| | | + "WHERE u.USER_NAME = ? AND (u.DEL_FLAG = '0' OR u.DEL_FLAG IS NULL)", |
| | | new Object[]{username}, |
| | | (rs, rowNum) -> rs.getString(1)); |
| | | return names.isEmpty() || names.get(0) == null ? "" : names.get(0).trim(); |
| | | (rs, rowNum) -> { |
| | | Map<String, Object> 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")); |
| | | Object deptId = rs.getObject("DEPT_ID"); |
| | | row.put("deptId", deptId == null ? null : rs.getLong("DEPT_ID")); |
| | | row.put("engineeringMajor", rs.getString("ENGINEERING_MAJOR")); |
| | | row.put("teamMajor", rs.getString("TEAM_MAJOR")); |
| | | row.put("responsibleXNo", rs.getString("USER_RESPONSIBLE_X_NO")); |
| | | row.put("deptResponsibleXNo", rs.getString("DEPT_RESPONSIBLE_X_NO")); |
| | | 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<String, Object> 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<String, Object> 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(); |
| | | } |
| | | } |