Commit 14050e5773ff6ba8062fd8898fa13a7995cc2b88

Authored by zichun
1 parent 1f446979

feat(usr): UpdateUserReq + UserDetailVo REQ-USR-003

backend/src/main/java/com/xly/erp/module/usr/dto/UpdateUserReq.java 0 → 100644
  1 +package com.xly.erp.module.usr.dto;
  2 +
  3 +import jakarta.validation.constraints.Min;
  4 +import jakarta.validation.constraints.Pattern;
  5 +import jakarta.validation.constraints.Size;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * PATCH 语义:所有字段都可选;缺省 / 显式 null 视为不变。
  12 + * 特例:employeeId == 0 视为解除关联(DB 写 NULL)。
  13 + */
  14 +@Data
  15 +public class UpdateUserReq {
  16 +
  17 + @Size(max = 50)
  18 + @Pattern(regexp = "^\\S+$", message = "userCode 不可为空白")
  19 + private String userCode;
  20 +
  21 + @Pattern(regexp = "NORMAL|SUPER_ADMIN",
  22 + message = "userType 必须为 NORMAL 或 SUPER_ADMIN")
  23 + private String userType;
  24 +
  25 + @Pattern(regexp = "zh-CN|en-US|zh-TW",
  26 + message = "language 必须为 zh-CN / en-US / zh-TW")
  27 + private String language;
  28 +
  29 + private Boolean canEditDocument;
  30 +
  31 + @Min(value = 0, message = "employeeId 必须 >= 0;0 表示解除关联")
  32 + private Integer employeeId;
  33 +
  34 + private Boolean isDeleted;
  35 +
  36 + private List<Integer> permissionCategoryIds;
  37 +}
... ...
backend/src/main/java/com/xly/erp/module/usr/vo/UserDetailVo.java 0 → 100644
  1 +package com.xly.erp.module.usr.vo;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonInclude;
  4 +import lombok.Builder;
  5 +import lombok.Data;
  6 +
  7 +import java.time.LocalDateTime;
  8 +import java.util.List;
  9 +
  10 +@Data
  11 +@Builder
  12 +@JsonInclude(JsonInclude.Include.NON_NULL)
  13 +public class UserDetailVo {
  14 + private Integer userId;
  15 + private String username;
  16 + private String userCode;
  17 + private String userType;
  18 + private String language;
  19 + private Boolean canEditDocument;
  20 + private Boolean isDeleted;
  21 + private Integer employeeId;
  22 + private String employeeName;
  23 + private List<Integer> permissionCategoryIds;
  24 + private String updatedBy;
  25 + private LocalDateTime updatedDate;
  26 +}
... ...
backend/src/test/java/com/xly/erp/module/usr/dto/UpdateUserReqValidationTest.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 org.junit.jupiter.api.Test;
  7 +
  8 +import java.util.Set;
  9 +
  10 +import static org.junit.jupiter.api.Assertions.*;
  11 +
  12 +class UpdateUserReqValidationTest {
  13 +
  14 + private static final Validator V =
  15 + Validation.buildDefaultValidatorFactory().getValidator();
  16 +
  17 + @Test
  18 + void emptyBody_isValid() {
  19 + assertTrue(V.validate(new UpdateUserReq()).isEmpty());
  20 + }
  21 +
  22 + @Test
  23 + void invalidUserType_fails() {
  24 + UpdateUserReq r = new UpdateUserReq();
  25 + r.setUserType("ROOT");
  26 + assertFalse(V.validate(r).isEmpty());
  27 + }
  28 +
  29 + @Test
  30 + void invalidLanguage_fails() {
  31 + UpdateUserReq r = new UpdateUserReq();
  32 + r.setLanguage("ja-JP");
  33 + assertFalse(V.validate(r).isEmpty());
  34 + }
  35 +
  36 + @Test
  37 + void userCodeTooLong_fails() {
  38 + UpdateUserReq r = new UpdateUserReq();
  39 + r.setUserCode("X".repeat(51));
  40 + assertFalse(V.validate(r).isEmpty());
  41 + }
  42 +
  43 + @Test
  44 + void userCodeBlank_fails() {
  45 + UpdateUserReq r = new UpdateUserReq();
  46 + r.setUserCode(" ");
  47 + assertFalse(V.validate(r).isEmpty());
  48 + }
  49 +
  50 + @Test
  51 + void employeeIdNegative_fails() {
  52 + UpdateUserReq r = new UpdateUserReq();
  53 + r.setEmployeeId(-1);
  54 + assertFalse(V.validate(r).isEmpty());
  55 + }
  56 +
  57 + @Test
  58 + void employeeIdZero_isValid_meansUnsetRelation() {
  59 + UpdateUserReq r = new UpdateUserReq();
  60 + r.setEmployeeId(0);
  61 + assertTrue(V.validate(r).isEmpty());
  62 + }
  63 +
  64 + @Test
  65 + void allValidFields_passes() {
  66 + UpdateUserReq r = new UpdateUserReq();
  67 + r.setUserCode("U999");
  68 + r.setUserType("NORMAL");
  69 + r.setLanguage("zh-CN");
  70 + r.setCanEditDocument(true);
  71 + r.setEmployeeId(7);
  72 + r.setIsDeleted(false);
  73 + r.setPermissionCategoryIds(java.util.List.of(1, 2));
  74 + Set<ConstraintViolation<UpdateUserReq>> v = V.validate(r);
  75 + assertTrue(v.isEmpty(), () -> "should be empty but got: " + v);
  76 + }
  77 +}
... ...