diff --git a/src/main/java/com/genepioneer/common/Result.java b/src/main/java/com/genepioneer/common/Result.java new file mode 100644 index 0000000..4841387 --- /dev/null +++ b/src/main/java/com/genepioneer/common/Result.java @@ -0,0 +1,27 @@ +package com.genepioneer.common; + +import lombok.Data; + +@Data +public class Result { + private Integer code; // 200成功,500失败 + private String msg; + private T data; + + // 成功返回 + public static Result success(T data) { + Result result = new Result<>(); + result.setCode(200); + result.setMsg("操作成功"); + result.setData(data); + return result; + } + + // 失败返回 + public static Result error(String msg) { + Result result = new Result<>(); + result.setCode(500); + result.setMsg(msg); + return result; + } +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/common/exception/CustomException.java b/src/main/java/com/genepioneer/common/exception/CustomException.java new file mode 100644 index 0000000..a659dd3 --- /dev/null +++ b/src/main/java/com/genepioneer/common/exception/CustomException.java @@ -0,0 +1,7 @@ +package com.genepioneer.common.exception; + +public class CustomException extends RuntimeException { + public CustomException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/common/utils/JwtUtil.java b/src/main/java/com/genepioneer/common/utils/JwtUtil.java new file mode 100644 index 0000000..523e882 --- /dev/null +++ b/src/main/java/com/genepioneer/common/utils/JwtUtil.java @@ -0,0 +1,49 @@ +package com.genepioneer.common.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Component +public class JwtUtil { + // 1. 自动生成符合256位要求的密钥(固定密钥,重启项目也不会变) + private static final SecretKey SECRET_KEY = Keys.secretKeyFor(io.jsonwebtoken.SignatureAlgorithm.HS256); + + // 2. JWT过期时间:1小时(3600000毫秒) + private static final Long EXPIRE = 3600000L; + + /** + * 生成JWT令牌 + */ + public String generateToken(Long userId) { + // 构建负载(存储用户ID) + Map claims = new HashMap<>(); + claims.put("userId", userId); + + // 生成令牌(使用自动生成的256位密钥) + return Jwts.builder() + .setClaims(claims) + .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) + .signWith(SECRET_KEY) + .compact(); + } + + /** + * 解析JWT令牌,获取用户ID + */ + public Long getUserIdFromToken(String token) { + Claims claims = Jwts.parserBuilder() + .setSigningKey(SECRET_KEY) + .build() + .parseClaimsJws(token) + .getBody(); + + return claims.get("userId", Long.class); + } +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/common/utils/MD5Util.java b/src/main/java/com/genepioneer/common/utils/MD5Util.java new file mode 100644 index 0000000..d73f13d --- /dev/null +++ b/src/main/java/com/genepioneer/common/utils/MD5Util.java @@ -0,0 +1,9 @@ +package com.genepioneer.common.utils; + +import org.apache.commons.codec.digest.DigestUtils; + +public class MD5Util { + public static String encrypt(String str) { + return DigestUtils.md5Hex(str); + } +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/controller/AuthController.java b/src/main/java/com/genepioneer/controller/AuthController.java new file mode 100644 index 0000000..04457fd --- /dev/null +++ b/src/main/java/com/genepioneer/controller/AuthController.java @@ -0,0 +1,41 @@ +package com.genepioneer.controller; + +import com.genepioneer.common.Result; +import com.genepioneer.common.utils.JwtUtil; +import com.genepioneer.dto.LoginDTO; +import com.genepioneer.entity.User; +import com.genepioneer.service.impl.UserService; +import com.genepioneer.vo.LoginVO; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import jakarta.annotation.Resource; +import jakarta.validation.Valid; + +@RestController +@RequestMapping("/api/auth") +public class AuthController { + @Resource + private UserService userService; + + @Resource + private JwtUtil jwtUtil; + + @PostMapping("/login") + public Result login(@Valid @RequestBody LoginDTO loginDTO) { + // 调用service登录(自动适配用户名/手机号) + User user = userService.login(loginDTO); + // 生成JWT令牌 + String token = jwtUtil.generateToken(user.getId()); + + // 封装返回结果 + LoginVO loginVO = new LoginVO(); + loginVO.setUserId(user.getId()); + loginVO.setUsername(user.getUsername()); // 仍返回用户名(前端展示用) + loginVO.setToken(token); + + return Result.success(loginVO); + } +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/dto/LoginDTO.java b/src/main/java/com/genepioneer/dto/LoginDTO.java new file mode 100644 index 0000000..d41fd07 --- /dev/null +++ b/src/main/java/com/genepioneer/dto/LoginDTO.java @@ -0,0 +1,13 @@ +package com.genepioneer.dto; + +import lombok.Data; +import jakarta.validation.constraints.NotBlank; + +@Data +public class LoginDTO { + @NotBlank(message = "登录账号不能为空(用户名/手机号)") + private String loginAccount; // 统一接收:用户名 或 手机号 + + @NotBlank(message = "密码不能为空") + private String password; +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/entity/User.java b/src/main/java/com/genepioneer/entity/User.java new file mode 100644 index 0000000..4bbe662 --- /dev/null +++ b/src/main/java/com/genepioneer/entity/User.java @@ -0,0 +1,14 @@ +package com.genepioneer.entity; + +import lombok.Data; +import java.util.Date; + +@Data +public class User { + private Long id; // 主键ID + private String username;// 账号 + private String password;// 加密后的密码 + private String role; // 角色(如admin) + private String phone; // 新增:手机号码 + private Date createTime;// 创建时间 +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/mapper/UserMapper.java b/src/main/java/com/genepioneer/mapper/UserMapper.java new file mode 100644 index 0000000..359e91a --- /dev/null +++ b/src/main/java/com/genepioneer/mapper/UserMapper.java @@ -0,0 +1,13 @@ +package com.genepioneer.mapper; + +import com.genepioneer.entity.User; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserMapper { + // 新增:根据用户名/手机号查询用户 + @Select("SELECT id, username, password, role, phone, create_time AS createTime " + + "FROM user WHERE username = #{loginAccount} OR phone = #{loginAccount}") + User selectByUsernameOrPhone(String loginAccount); +} \ No newline at end of file diff --git a/src/main/java/com/genepioneer/vo/LoginVO.java b/src/main/java/com/genepioneer/vo/LoginVO.java new file mode 100644 index 0000000..53e9f52 --- /dev/null +++ b/src/main/java/com/genepioneer/vo/LoginVO.java @@ -0,0 +1,10 @@ +package com.genepioneer.vo; + +import lombok.Data; + +@Data +public class LoginVO { + private Long userId; + private String username; + private String token; +} \ No newline at end of file