Commit b2b67f4754e38687422da44c564ff0372aac0682

Authored by zichun
1 parent 3be59f71

feat(usr): jjwt deps + login DTO/VO + error codes REQ-USR-004

backend/pom.xml
... ... @@ -82,6 +82,25 @@
82 82 <version>${hutool.version}</version>
83 83 </dependency>
84 84  
  85 + <!-- REQ-USR-004 JWT (jjwt 0.12.x) -->
  86 + <dependency>
  87 + <groupId>io.jsonwebtoken</groupId>
  88 + <artifactId>jjwt-api</artifactId>
  89 + <version>0.12.6</version>
  90 + </dependency>
  91 + <dependency>
  92 + <groupId>io.jsonwebtoken</groupId>
  93 + <artifactId>jjwt-impl</artifactId>
  94 + <version>0.12.6</version>
  95 + <scope>runtime</scope>
  96 + </dependency>
  97 + <dependency>
  98 + <groupId>io.jsonwebtoken</groupId>
  99 + <artifactId>jjwt-jackson</artifactId>
  100 + <version>0.12.6</version>
  101 + <scope>runtime</scope>
  102 + </dependency>
  103 +
85 104 <dependency>
86 105 <groupId>org.springframework.boot</groupId>
87 106 <artifactId>spring-boot-starter-test</artifactId>
... ...
backend/src/main/java/com/xly/erp/common/response/ErrorCode.java
... ... @@ -6,6 +6,8 @@ import lombok.Getter;
6 6 public enum ErrorCode {
7 7 SUCCESS(200, "操作成功"),
8 8 PARAM_INVALID(40010, "参数错误"),
  9 + LOGIN_INVALID_CREDENTIALS(40101, "用户名或密码错误"),
  10 + LOGIN_ACCOUNT_LOCKED(40301, "账号已临时锁定"),
9 11 MOD_PARENT_NOT_FOUND(40411, "父模块不存在或已删除"),
10 12 MOD_NOT_FOUND(40421, "模块不存在或已删除"),
11 13 STAFF_NOT_FOUND(40421, "职员不存在或已删除"),
... ...
backend/src/main/java/com/xly/erp/module/usr/dto/LoginDTO.java 0 → 100644
  1 +package com.xly.erp.module.usr.dto;
  2 +
  3 +import jakarta.validation.constraints.NotBlank;
  4 +import jakarta.validation.constraints.Pattern;
  5 +import jakarta.validation.constraints.Size;
  6 +import lombok.Data;
  7 +
  8 +/** REQ-USR-004 用户登录入参 */
  9 +@Data
  10 +public class LoginDTO {
  11 +
  12 + @NotBlank
  13 + @Size(max = 50)
  14 + private String sUserName;
  15 +
  16 + @NotBlank
  17 + @Size(max = 100)
  18 + private String sPassword;
  19 +
  20 + @NotBlank
  21 + @Pattern(regexp = "^standard$", message = "sVersion 仅支持 standard")
  22 + private String sVersion;
  23 +}
... ...
backend/src/main/java/com/xly/erp/module/usr/vo/LoginResultVO.java 0 → 100644
  1 +package com.xly.erp.module.usr.vo;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +/** REQ-USR-004 登录结果 VO(含 JWT + 用户基本信息) */
  8 +@Data
  9 +@NoArgsConstructor
  10 +@AllArgsConstructor
  11 +public class LoginResultVO {
  12 + private String accessToken;
  13 + private long expiresIn;
  14 + private LoginUserInfo user;
  15 +
  16 + @Data
  17 + @NoArgsConstructor
  18 + @AllArgsConstructor
  19 + public static class LoginUserInfo {
  20 + private Integer iIncrement;
  21 + private String sUserNo;
  22 + private String sUserName;
  23 + private String sUserType;
  24 + private String sLanguage;
  25 + }
  26 +}
... ...
backend/src/test/java/com/xly/erp/common/response/ApiResponseTest.java
... ... @@ -55,5 +55,7 @@ class ApiResponseTest {
55 55 assertThat(ErrorCode.PERM_CATEGORY_NOT_FOUND.getCode()).isEqualTo(40422);
56 56 assertThat(ErrorCode.USR_USER_NAME_OR_NO_DUP.getCode()).isEqualTo(40921);
57 57 assertThat(ErrorCode.USR_NOT_FOUND.getCode()).isEqualTo(40431);
  58 + assertThat(ErrorCode.LOGIN_INVALID_CREDENTIALS.getCode()).isEqualTo(40101);
  59 + assertThat(ErrorCode.LOGIN_ACCOUNT_LOCKED.getCode()).isEqualTo(40301);
58 60 }
59 61 }
... ...
backend/src/test/java/com/xly/erp/module/usr/dto/LoginDTOValidationTest.java 0 → 100644
  1 +package com.xly.erp.module.usr.dto;
  2 +
  3 +import jakarta.validation.ConstraintViolation;
  4 +import jakarta.validation.Validation;
  5 +import jakarta.validation.Validator;
  6 +import jakarta.validation.ValidatorFactory;
  7 +import org.junit.jupiter.api.Test;
  8 +
  9 +import java.util.Set;
  10 +
  11 +import static org.assertj.core.api.Assertions.assertThat;
  12 +
  13 +class LoginDTOValidationTest {
  14 +
  15 + private static final ValidatorFactory FACTORY = Validation.buildDefaultValidatorFactory();
  16 + private final Validator validator = FACTORY.getValidator();
  17 +
  18 + private LoginDTO valid() {
  19 + LoginDTO d = new LoginDTO();
  20 + d.setSUserName("alice");
  21 + d.setSPassword("666666");
  22 + d.setSVersion("standard");
  23 + return d;
  24 + }
  25 +
  26 + @Test
  27 + void allValid_yieldsNoViolations() {
  28 + Set<ConstraintViolation<LoginDTO>> v = validator.validate(valid());
  29 + assertThat(v).isEmpty();
  30 + }
  31 +
  32 + @Test
  33 + void blankRequiredFields_yieldsViolations() {
  34 + LoginDTO d = new LoginDTO();
  35 + Set<ConstraintViolation<LoginDTO>> v = validator.validate(d);
  36 + assertThat(v).extracting(cv -> cv.getPropertyPath().toString())
  37 + .contains("sUserName", "sPassword", "sVersion");
  38 + }
  39 +
  40 + @Test
  41 + void invalidVersion_yieldsViolation() {
  42 + LoginDTO d = valid();
  43 + d.setSVersion("experimental");
  44 + Set<ConstraintViolation<LoginDTO>> v = validator.validate(d);
  45 + assertThat(v).extracting(cv -> cv.getPropertyPath().toString()).contains("sVersion");
  46 + }
  47 +
  48 + @Test
  49 + void overSized_yieldsViolation() {
  50 + LoginDTO d = valid();
  51 + d.setSUserName("a".repeat(51));
  52 + d.setSPassword("p".repeat(101));
  53 + Set<ConstraintViolation<LoginDTO>> v = validator.validate(d);
  54 + assertThat(v).extracting(cv -> cv.getPropertyPath().toString())
  55 + .contains("sUserName", "sPassword");
  56 + }
  57 +}
... ...