diff --git a/backend/src/main/java/com/xly/erp/module/mod/dto/ModuleUpdateDTO.java b/backend/src/main/java/com/xly/erp/module/mod/dto/ModuleUpdateDTO.java new file mode 100644 index 0000000..1368f05 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/module/mod/dto/ModuleUpdateDTO.java @@ -0,0 +1,41 @@ +package com.xly.erp.module.mod.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import lombok.Data; + +/** + * REQ-MOD-002 模块修改入参。 + * 与 {@link ModuleCreateDTO} 相比剥除了 sProcedureName(不可改);其余 7 个字段规则一致。 + */ +@Data +public class ModuleUpdateDTO { + + @NotBlank + @Pattern(regexp = "^(手机端|前端业务|系统配置|接口)$", message = "sDisplayType 必须是 手机端/前端业务/系统配置/接口 之一") + private String sDisplayType; + + @NotBlank + @Size(max = 50) + private String sModuleType; + + @NotBlank + @Size(max = 50) + private String sManageDeptEn; + + /** 可空:null 表示保持原值 */ + private Boolean bShowPermission; + + @NotBlank + @Size(max = 100) + private String sModuleNameZh; + + /** 可空:null 表示设为根模块 */ + private Integer iParentId; + + /** 可空:null 表示保持原值 */ + @Min(0) + private Integer iSortOrder; +} diff --git a/backend/src/test/java/com/xly/erp/module/mod/dto/ModuleUpdateDTOValidationTest.java b/backend/src/test/java/com/xly/erp/module/mod/dto/ModuleUpdateDTOValidationTest.java new file mode 100644 index 0000000..98418ed --- /dev/null +++ b/backend/src/test/java/com/xly/erp/module/mod/dto/ModuleUpdateDTOValidationTest.java @@ -0,0 +1,61 @@ +package com.xly.erp.module.mod.dto; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class ModuleUpdateDTOValidationTest { + + private static final ValidatorFactory FACTORY = Validation.buildDefaultValidatorFactory(); + private final Validator validator = FACTORY.getValidator(); + + private ModuleUpdateDTO valid() { + ModuleUpdateDTO d = new ModuleUpdateDTO(); + d.setSDisplayType("前端业务"); + d.setSModuleType("USR"); + d.setSManageDeptEn("IT"); + d.setBShowPermission(true); + d.setSModuleNameZh("用户管理(修订)"); + d.setIParentId(null); + d.setISortOrder(0); + return d; + } + + @Test + void allValidFields_yieldsNoViolations() { + Set> v = validator.validate(valid()); + assertThat(v).isEmpty(); + } + + @Test + void blankRequiredFields_yieldsViolations() { + ModuleUpdateDTO d = new ModuleUpdateDTO(); + Set> v = validator.validate(d); + // 5 个 @NotBlank:sDisplayType / sModuleType / sManageDeptEn / sModuleNameZh + // (bShowPermission / iParentId / iSortOrder 可空) + assertThat(v).extracting(cv -> cv.getPropertyPath().toString()) + .contains("sDisplayType", "sModuleType", "sManageDeptEn", "sModuleNameZh"); + } + + @Test + void invalidDisplayTypeEnum_yieldsViolation() { + ModuleUpdateDTO d = valid(); + d.setSDisplayType("非法值"); + Set> v = validator.validate(d); + assertThat(v).extracting(cv -> cv.getPropertyPath().toString()).contains("sDisplayType"); + } + + @Test + void negativeSortOrder_yieldsViolation() { + ModuleUpdateDTO d = valid(); + d.setISortOrder(-1); + Set> v = validator.validate(d); + assertThat(v).extracting(cv -> cv.getPropertyPath().toString()).contains("iSortOrder"); + } +}