From 8f457010d51da8da60b16453920f5e410bcb8df8 Mon Sep 17 00:00:00 2001 From: zichun Date: Wed, 29 Apr 2026 17:47:34 +0800 Subject: [PATCH] feat(mod): module update dto + service happy path REQ-MOD-002 --- backend/src/main/java/com/xly/erp/module/mod/dto/UpdateModuleDTO.java | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ backend/src/main/java/com/xly/erp/module/mod/service/ModuleService.java | 3 +++ backend/src/main/java/com/xly/erp/module/mod/service/impl/ModuleServiceImpl.java | 25 +++++++++++++++++++++++++ backend/src/test/java/com/xly/erp/module/mod/service/ModuleServiceImplTest.java | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 0 deletions(-) create mode 100644 backend/src/main/java/com/xly/erp/module/mod/dto/UpdateModuleDTO.java diff --git a/backend/src/main/java/com/xly/erp/module/mod/dto/UpdateModuleDTO.java b/backend/src/main/java/com/xly/erp/module/mod/dto/UpdateModuleDTO.java new file mode 100644 index 0000000..476e684 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/module/mod/dto/UpdateModuleDTO.java @@ -0,0 +1,51 @@ +package com.xly.erp.module.mod.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public class UpdateModuleDTO { + + @JsonProperty("sDisplayType") + @NotBlank + private String sDisplayType; + + @JsonProperty("sModuleType") + @NotBlank + @Size(max = 50) + private String sModuleType; + + @JsonProperty("sManageDeptEn") + @NotBlank + @Size(max = 50) + private String sManageDeptEn; + + @JsonProperty("bShowPermission") + private Boolean bShowPermission; + + @JsonProperty("sModuleNameZh") + @NotBlank + @Size(max = 100) + private String sModuleNameZh; + + @JsonProperty("iParentId") + private Integer iParentId; + + @JsonProperty("iSortOrder") + private Integer iSortOrder; + + public String getSDisplayType() { return sDisplayType; } + public void setSDisplayType(String sDisplayType) { this.sDisplayType = sDisplayType; } + public String getSModuleType() { return sModuleType; } + public void setSModuleType(String sModuleType) { this.sModuleType = sModuleType; } + public String getSManageDeptEn() { return sManageDeptEn; } + public void setSManageDeptEn(String sManageDeptEn) { this.sManageDeptEn = sManageDeptEn; } + public Boolean getBShowPermission() { return bShowPermission; } + public void setBShowPermission(Boolean bShowPermission) { this.bShowPermission = bShowPermission; } + public String getSModuleNameZh() { return sModuleNameZh; } + public void setSModuleNameZh(String sModuleNameZh) { this.sModuleNameZh = sModuleNameZh; } + public Integer getIParentId() { return iParentId; } + public void setIParentId(Integer iParentId) { this.iParentId = iParentId; } + public Integer getISortOrder() { return iSortOrder; } + public void setISortOrder(Integer iSortOrder) { this.iSortOrder = iSortOrder; } +} diff --git a/backend/src/main/java/com/xly/erp/module/mod/service/ModuleService.java b/backend/src/main/java/com/xly/erp/module/mod/service/ModuleService.java index 19913f3..214b94c 100644 --- a/backend/src/main/java/com/xly/erp/module/mod/service/ModuleService.java +++ b/backend/src/main/java/com/xly/erp/module/mod/service/ModuleService.java @@ -1,7 +1,10 @@ package com.xly.erp.module.mod.service; import com.xly.erp.module.mod.dto.CreateModuleDTO; +import com.xly.erp.module.mod.dto.UpdateModuleDTO; public interface ModuleService { Integer create(CreateModuleDTO dto); + + Integer update(Integer id, UpdateModuleDTO dto); } diff --git a/backend/src/main/java/com/xly/erp/module/mod/service/impl/ModuleServiceImpl.java b/backend/src/main/java/com/xly/erp/module/mod/service/impl/ModuleServiceImpl.java index b488a18..f0180e1 100644 --- a/backend/src/main/java/com/xly/erp/module/mod/service/impl/ModuleServiceImpl.java +++ b/backend/src/main/java/com/xly/erp/module/mod/service/impl/ModuleServiceImpl.java @@ -5,6 +5,7 @@ import com.xly.erp.common.config.TenantProperties; import com.xly.erp.common.exception.BizException; import com.xly.erp.common.security.SecurityContextHelper; import com.xly.erp.module.mod.dto.CreateModuleDTO; +import com.xly.erp.module.mod.dto.UpdateModuleDTO; import com.xly.erp.module.mod.entity.Module; import com.xly.erp.module.mod.mapper.ModuleMapper; import com.xly.erp.module.mod.service.ModuleService; @@ -65,4 +66,28 @@ public class ModuleServiceImpl implements ModuleService { } return m.getIIncrement(); } + + @Override + public Integer update(Integer id, UpdateModuleDTO dto) { + Module original = moduleMapper.selectById(id); + if (original == null || Boolean.TRUE.equals(original.getBDeleted())) { + throw new BizException(40400, "模块不存在或已删除"); + } + if (!DISPLAY_TYPES.contains(dto.getSDisplayType())) { + throw new BizException(40010, "显示类型枚举不合法"); + } + + Module entity = new Module(); + entity.setIIncrement(id); + entity.setSDisplayType(dto.getSDisplayType()); + entity.setSModuleType(dto.getSModuleType()); + entity.setSManageDeptEn(dto.getSManageDeptEn()); + entity.setBShowPermission(dto.getBShowPermission() != null ? dto.getBShowPermission() : false); + entity.setSModuleNameZh(dto.getSModuleNameZh()); + entity.setIParentId(dto.getIParentId()); + entity.setISortOrder(dto.getISortOrder() != null ? dto.getISortOrder() : 0); + + moduleMapper.updateById(entity); + return id; + } } diff --git a/backend/src/test/java/com/xly/erp/module/mod/service/ModuleServiceImplTest.java b/backend/src/test/java/com/xly/erp/module/mod/service/ModuleServiceImplTest.java index fd0c70b..ec69741 100644 --- a/backend/src/test/java/com/xly/erp/module/mod/service/ModuleServiceImplTest.java +++ b/backend/src/test/java/com/xly/erp/module/mod/service/ModuleServiceImplTest.java @@ -4,6 +4,7 @@ import com.xly.erp.common.config.StubSecurityProperties; import com.xly.erp.common.config.TenantProperties; import com.xly.erp.common.exception.BizException; import com.xly.erp.module.mod.dto.CreateModuleDTO; +import com.xly.erp.module.mod.dto.UpdateModuleDTO; import com.xly.erp.module.mod.entity.Module; import com.xly.erp.module.mod.mapper.ModuleMapper; import com.xly.erp.module.mod.service.impl.ModuleServiceImpl; @@ -132,6 +133,76 @@ class ModuleServiceImplTest { assertThat(captor.getValue().getSCreatedBy()).isEqualTo("ALICE"); } + @Test + void updateWithValidDto_invokesUpdateById_withEditableFieldsOnly() { + Module original = stubExistingModule(10); + when(moduleMapper.selectById(10)).thenReturn(original); + when(moduleMapper.updateById(any(Module.class))).thenReturn(1); + + UpdateModuleDTO dto = baseUpdateDto(); + dto.setSModuleNameZh("新名"); + + Integer result = service.update(10, dto); + assertThat(result).isEqualTo(10); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Module.class); + verify(moduleMapper).updateById(captor.capture()); + Module passed = captor.getValue(); + assertThat(passed.getIIncrement()).isEqualTo(10); + assertThat(passed.getSModuleNameZh()).isEqualTo("新名"); + assertThat(passed.getSDisplayType()).isEqualTo("手机端"); + assertThat(passed.getSProcedureName()).isNull(); + assertThat(passed.getSCreatedBy()).isNull(); + assertThat(passed.getTCreateDate()).isNull(); + assertThat(passed.getSBrandsId()).isNull(); + assertThat(passed.getSSubsidiaryId()).isNull(); + assertThat(passed.getBDeleted()).isNull(); + } + + @Test + void updateWithTargetNotFound_throws40400() { + when(moduleMapper.selectById(99)).thenReturn(null); + UpdateModuleDTO dto = baseUpdateDto(); + + assertThatThrownBy(() -> service.update(99, dto)) + .isInstanceOf(BizException.class) + .hasFieldOrPropertyWithValue("code", 40400); + verify(moduleMapper, never()).updateById(any(Module.class)); + } + + @Test + void updateWithBShowPermissionNull_setsFalseInEntity() { + when(moduleMapper.selectById(10)).thenReturn(stubExistingModule(10)); + when(moduleMapper.updateById(any(Module.class))).thenReturn(1); + UpdateModuleDTO dto = baseUpdateDto(); + dto.setBShowPermission(null); + + service.update(10, dto); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Module.class); + verify(moduleMapper).updateById(captor.capture()); + assertThat(captor.getValue().getBShowPermission()).isFalse(); + } + + private UpdateModuleDTO baseUpdateDto() { + UpdateModuleDTO dto = new UpdateModuleDTO(); + dto.setSDisplayType("手机端"); + dto.setSModuleType("业务模块"); + dto.setSManageDeptEn("IT"); + dto.setSModuleNameZh("更新后"); + dto.setBShowPermission(false); + return dto; + } + + private Module stubExistingModule(Integer id) { + Module m = new Module(); + m.setIIncrement(id); + m.setSProcedureName("sp_test_existing"); + m.setSCreatedBy("ORIG_USER"); + m.setBDeleted(false); + return m; + } + private CreateModuleDTO baseDto() { CreateModuleDTO dto = new CreateModuleDTO(); dto.setSDisplayType("手机端"); -- libgit2 0.22.2