diff --git a/src/main/java/com/onixbyte/helix/controller/AssetController.java b/src/main/java/com/onixbyte/helix/controller/AssetController.java index 270bfeb..eb2f566 100644 --- a/src/main/java/com/onixbyte/helix/controller/AssetController.java +++ b/src/main/java/com/onixbyte/helix/controller/AssetController.java @@ -4,8 +4,7 @@ import com.onixbyte.helix.shared.AssetPrefix; import com.onixbyte.helix.domain.web.response.FileUploadResponse; import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.service.AssetService; -import com.onixbyte.helix.shared.Message; -import com.onixbyte.helix.utils.MessageUtil; +import com.onixbyte.helix.shared.MessageName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -27,15 +26,10 @@ public class AssetController { private static final Logger log = LoggerFactory.getLogger(AssetController.class); private final AssetService assetService; - private final MessageUtil messageUtil; @Autowired - public AssetController( - AssetService assetService, - MessageUtil messageUtil - ) { + public AssetController(AssetService assetService) { this.assetService = assetService; - this.messageUtil = messageUtil; } /** @@ -50,7 +44,7 @@ public class AssetController { ) { try { if (file.isEmpty()) { - throw new BizException(HttpStatus.BAD_REQUEST, messageUtil.getMessage(Message.ASSET_NOT_EMPTY)); + throw new BizException(HttpStatus.BAD_REQUEST, MessageName.ASSET_NOT_EMPTY); } var fileUrl = assetService.uploadFile(AssetPrefix.UPLOADS, file); @@ -63,10 +57,13 @@ public class AssetController { file.getSize(), fileUrl )); + } catch (BizException ex) { + throw ex; } catch (Exception e) { log.error("File upload failed: {}", e.getMessage(), e); throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, - "Failed upload file: " + e.getMessage()); + MessageName.ASSET_UPLOAD_FAILED, + e.getMessage()); } } diff --git a/src/main/java/com/onixbyte/helix/controller/AuthorityController.java b/src/main/java/com/onixbyte/helix/controller/AuthorityController.java index ee5dd4f..127fd19 100644 --- a/src/main/java/com/onixbyte/helix/controller/AuthorityController.java +++ b/src/main/java/com/onixbyte/helix/controller/AuthorityController.java @@ -5,7 +5,7 @@ import com.onixbyte.helix.domain.web.request.AuthorityRequest; import com.onixbyte.helix.domain.web.request.QueryAuthorityRequest; import com.onixbyte.helix.domain.web.response.ActionResponse; import com.onixbyte.helix.service.AuthorityService; -import com.onixbyte.helix.shared.Message; +import com.onixbyte.helix.shared.MessageName; import com.onixbyte.helix.utils.MessageUtil; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -79,6 +79,6 @@ public class AuthorityController { @DeleteMapping("/{authorityId:\\d+}") public ActionResponse deleteAuthority(@PathVariable Long authorityId) { var name = authorityService.deleteAuthority(authorityId); - return ActionResponse.success(messageUtil.getMessage(Message.AUTHORITY_DELETED, name)); + return ActionResponse.success(messageUtil.getMessage(MessageName.AUTHORITY_DELETED, name)); } } diff --git a/src/main/java/com/onixbyte/helix/controller/ExceptionController.java b/src/main/java/com/onixbyte/helix/controller/ExceptionController.java index dbec193..2e27cee 100644 --- a/src/main/java/com/onixbyte/helix/controller/ExceptionController.java +++ b/src/main/java/com/onixbyte/helix/controller/ExceptionController.java @@ -2,6 +2,7 @@ package com.onixbyte.helix.controller; import com.onixbyte.helix.domain.web.response.BizExceptionResponse; import com.onixbyte.helix.exception.BizException; +import com.onixbyte.helix.utils.MessageUtil; import jakarta.validation.ConstraintViolationException; import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.HttpStatus; @@ -27,12 +28,22 @@ import java.util.stream.Collectors; @RestControllerAdvice public class ExceptionController { + private final MessageUtil messageUtil; + + public ExceptionController(MessageUtil messageUtil) { + this.messageUtil = messageUtil; + } + @ExceptionHandler(BizException.class) public ResponseEntity handleBizException(BizException ex) { + var message = ex.getMessageCode() == null + ? ex.getMessage() + : messageUtil.getMessage(ex.getMessageCode(), ex.getMessageArgs()); + return ResponseEntity.status(ex.getStatus()) .body(new BizExceptionResponse( LocalDateTime.now(), - ex.getMessage()) + message) ); } diff --git a/src/main/java/com/onixbyte/helix/controller/RoleController.java b/src/main/java/com/onixbyte/helix/controller/RoleController.java index f24068d..7350dee 100644 --- a/src/main/java/com/onixbyte/helix/controller/RoleController.java +++ b/src/main/java/com/onixbyte/helix/controller/RoleController.java @@ -1,15 +1,16 @@ package com.onixbyte.helix.controller; import com.onixbyte.helix.domain.entity.Role; -import com.onixbyte.helix.domain.web.request.AddRoleRequest; -import com.onixbyte.helix.domain.web.request.EditRoleRequest; import com.onixbyte.helix.domain.web.request.QueryRoleRequest; +import com.onixbyte.helix.domain.web.request.RoleRequest; +import com.onixbyte.helix.domain.web.response.ActionResponse; import com.onixbyte.helix.service.RoleService; +import com.onixbyte.helix.shared.MessageName; +import com.onixbyte.helix.utils.MessageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; -import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -24,10 +25,12 @@ import org.springframework.web.bind.annotation.*; public class RoleController { private final RoleService roleService; + private final MessageUtil messageUtil; @Autowired - public RoleController(RoleService roleService) { + public RoleController(RoleService roleService, MessageUtil messageUtil) { this.roleService = roleService; + this.messageUtil = messageUtil; } @GetMapping @@ -41,20 +44,21 @@ public class RoleController { } @PostMapping - public ResponseEntity addRole(@Validated @RequestBody AddRoleRequest request) { - roleService.addRole(request); - return ResponseEntity.ok(null); + public Role addRole(@Validated @RequestBody RoleRequest request) { + return roleService.addRole(request); } - @PutMapping - public ResponseEntity editRole(@Validated @RequestBody EditRoleRequest request) { - roleService.editRole(request); - return ResponseEntity.ok(null); + @PutMapping("/{id:\\d+}") + public Role editRole( + @PathVariable Long id, + @Validated @RequestBody RoleRequest request + ) { + return roleService.editRole(id, request); } @DeleteMapping("/{id:\\d+}") - public ResponseEntity deleteRole(@PathVariable Long id) { - roleService.deleteRole(id); - return ResponseEntity.ok(null); + public ActionResponse deleteRole(@PathVariable Long id) { + var name = roleService.deleteRole(id); + return ActionResponse.success(messageUtil.getMessage(MessageName.ROLE_DELETED, name)); } } diff --git a/src/main/java/com/onixbyte/helix/controller/UserController.java b/src/main/java/com/onixbyte/helix/controller/UserController.java index a2bf304..9a2dc1f 100644 --- a/src/main/java/com/onixbyte/helix/controller/UserController.java +++ b/src/main/java/com/onixbyte/helix/controller/UserController.java @@ -7,7 +7,7 @@ import com.onixbyte.helix.domain.web.request.ResetPasswordRequest; import com.onixbyte.helix.domain.web.response.ActionResponse; import com.onixbyte.helix.domain.web.response.UserDetailResponse; import com.onixbyte.helix.service.UserService; -import com.onixbyte.helix.shared.Message; +import com.onixbyte.helix.shared.MessageName; import com.onixbyte.helix.utils.MessageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -104,7 +104,7 @@ public class UserController { @Validated @RequestBody ResetPasswordRequest request ) { userService.resetPassword(id, request); - return ActionResponse.success(messageUtil.getMessage(Message.USER_PASSWORD_RESET_SUCCESS)); + return ActionResponse.success(messageUtil.getMessage(MessageName.USER_PASSWORD_RESET_SUCCESS)); } /** @@ -117,6 +117,6 @@ public class UserController { @DeleteMapping("/{userId:\\d+}") public ActionResponse deleteUser(@PathVariable Long userId) { userService.deleteUser(userId); - return ActionResponse.success(messageUtil.getMessage(Message.USER_DELETED)); + return ActionResponse.success(messageUtil.getMessage(MessageName.USER_DELETED, userId)); } } diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/AddRoleRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/AddRoleRequest.java deleted file mode 100644 index 1127ba2..0000000 --- a/src/main/java/com/onixbyte/helix/domain/web/request/AddRoleRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.onixbyte.helix.domain.web.request; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; - -public record AddRoleRequest( - @NotBlank(message = "角色名称不能为空") - String name, - @NotBlank(message = "角色编码不能为空") - String code, - @NotNull(message = "排序编号不能为空") - Integer sort, - Boolean defaultValue, - String description, - @Pattern( - regexp = "^(ACTIVE|INACTIVE)?$", - message = "状态仅可以是 ACTIVE、INACTIVE 其中之一") - String status -) { -} diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/AddUserRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/AddUserRequest.java index df7fca0..21a9ed8 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/AddUserRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/AddUserRequest.java @@ -1,16 +1,17 @@ package com.onixbyte.helix.domain.web.request; import com.onixbyte.helix.enumeration.UserStatus; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.NotBlank; import java.util.List; public record AddUserRequest( - @NotBlank(message = "Username cannot be empty.") + @NotBlank(message = "{" + MessageName.REQUEST_ADD_USER_USERNAME_NOT_EMPTY + "}") String username, - @NotBlank(message = "Password cannot be empty.") + @NotBlank(message = "{" + MessageName.REQUEST_ADD_USER_PASSWORD_NOT_EMPTY + "}") String password, - @NotBlank(message = "Full name cannot be empty.") + @NotBlank(message = "{" + MessageName.REQUEST_ADD_USER_FULL_NAME_NOT_EMPTY + "}") String fullName, String email, String regionAbbreviation, diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/AuthorityRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/AuthorityRequest.java index 844118b..e169516 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/AuthorityRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/AuthorityRequest.java @@ -1,6 +1,7 @@ package com.onixbyte.helix.domain.web.request; import com.onixbyte.helix.enumeration.Status; +import com.onixbyte.helix.shared.MessageName; import com.onixbyte.helix.validation.group.OnCreate; import com.onixbyte.helix.validation.group.OnUpdate; import jakarta.validation.constraints.NotBlank; @@ -8,11 +9,11 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Null; public record AuthorityRequest( - @Null(groups = {OnUpdate.class}, message = "Code cannot be edited.") - @NotNull(groups = {OnCreate.class}, message = "Code cannot be null.") + @Null(groups = {OnUpdate.class}, message = "{" + MessageName.REQUEST_AUTHORITY_CODE_NOT_EDITABLE + "}") + @NotNull(groups = {OnCreate.class}, message = "{" + MessageName.REQUEST_AUTHORITY_CODE_NOT_NULL + "}") String code, - @NotNull(message = "Name of the authority cannot be null") - @NotBlank(message = "Name of the authority cannot be null") + @NotNull(message = "{" + MessageName.REQUEST_AUTHORITY_NAME_NOT_NULL + "}") + @NotBlank(message = "{" + MessageName.REQUEST_AUTHORITY_NAME_NOT_NULL + "}") String name, String description, Status status diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/DepartmentRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/DepartmentRequest.java index 6b737a6..4937369 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/DepartmentRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/DepartmentRequest.java @@ -23,12 +23,13 @@ package com.onixbyte.helix.domain.web.request; import com.onixbyte.helix.enumeration.Status; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; public record DepartmentRequest( - @NotNull(message = "Name of the department should not be null") - @NotBlank(message = "Name of the department should not be null") + @NotNull(message = "{" + MessageName.REQUEST_DEPARTMENT_NAME_NOT_NULL + "}") + @NotBlank(message = "{" + MessageName.REQUEST_DEPARTMENT_NAME_NOT_NULL + "}") String name, Long parentId, Integer sort, diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/EditRoleRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/EditRoleRequest.java index 293311e..266dfea 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/EditRoleRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/EditRoleRequest.java @@ -1,10 +1,11 @@ package com.onixbyte.helix.domain.web.request; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; public record EditRoleRequest( - @NotNull(message = "角色 ID 不能为空") + @NotNull(message = "{" + MessageName.REQUEST_EDIT_ROLE_ID_NOT_NULL + "}") Long id, String name, String code, @@ -13,7 +14,7 @@ public record EditRoleRequest( String description, @Pattern( regexp = "^(ACTIVE|INACTIVE)?$", - message = "状态仅可以是 ACTIVE、INACTIVE 其中之一") + message = "{" + MessageName.REQUEST_EDIT_ROLE_STATUS_INVALID + "}") String status ) { } diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/EditUserRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/EditUserRequest.java index c294023..b5da25e 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/EditUserRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/EditUserRequest.java @@ -1,12 +1,13 @@ package com.onixbyte.helix.domain.web.request; import com.onixbyte.helix.enumeration.UserStatus; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; public record EditUserRequest( - @NotNull(message = "User ID cannot be null") - @Positive(message = "User ID must be positive") + @NotNull(message = "{" + MessageName.REQUEST_EDIT_USER_ID_NOT_NULL + "}") + @Positive(message = "{" + MessageName.REQUEST_EDIT_USER_ID_POSITIVE + "}") Long id, String fullName, String email, diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/QueryRoleRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/QueryRoleRequest.java index 6497c75..20ebe90 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/QueryRoleRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/QueryRoleRequest.java @@ -1,5 +1,6 @@ package com.onixbyte.helix.domain.web.request; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.Pattern; public record QueryRoleRequest( @@ -7,7 +8,7 @@ public record QueryRoleRequest( String code, @Pattern( regexp = "^(ACTIVE|INACTIVE)?$", - message = "状态仅可以是 ACTIVE、INACTIVE 其中之一") + message = "{" + MessageName.REQUEST_QUERY_ROLE_STATUS_INVALID + "}") String status ) { } diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/QueryUserRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/QueryUserRequest.java index 9d53f08..7b73b72 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/QueryUserRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/QueryUserRequest.java @@ -1,5 +1,6 @@ package com.onixbyte.helix.domain.web.request; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.Pattern; import java.time.LocalDateTime; @@ -11,7 +12,7 @@ public record QueryUserRequest( String phoneNumber, @Pattern( regexp = "^(ACTIVE|INACTIVE|LOCKED)?$", - message = "状态仅可以是 ACTIVE、INACTIVE 或 LOCKED 其中之一") + message = "{" + MessageName.REQUEST_QUERY_USER_STATUS_INVALID + "}") String status, LocalDateTime createdAtStart, LocalDateTime createdAtEnd diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/ResetPasswordRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/ResetPasswordRequest.java index d1ac2d3..1d835bd 100644 --- a/src/main/java/com/onixbyte/helix/domain/web/request/ResetPasswordRequest.java +++ b/src/main/java/com/onixbyte/helix/domain/web/request/ResetPasswordRequest.java @@ -1,9 +1,10 @@ package com.onixbyte.helix.domain.web.request; +import com.onixbyte.helix.shared.MessageName; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; public record ResetPasswordRequest( - @NotBlank(message = "密码不能为空") String password + @NotBlank(message = "{" + MessageName.REQUEST_RESET_PASSWORD_NOT_EMPTY + "}") String password ) { } diff --git a/src/main/java/com/onixbyte/helix/domain/web/request/RoleRequest.java b/src/main/java/com/onixbyte/helix/domain/web/request/RoleRequest.java new file mode 100644 index 0000000..e101a2f --- /dev/null +++ b/src/main/java/com/onixbyte/helix/domain/web/request/RoleRequest.java @@ -0,0 +1,20 @@ +package com.onixbyte.helix.domain.web.request; + +import com.onixbyte.helix.enumeration.Status; +import com.onixbyte.helix.shared.MessageName; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +public record RoleRequest( + @NotBlank(message = "{" + MessageName.REQUEST_ROLE_NAME_NOT_EMPTY + "}") + String name, + @NotBlank(message = "{" + MessageName.REQUEST_ROLE_CODE_NOT_EMPTY + "}") + String code, + @NotNull(message = "{" + MessageName.REQUEST_ROLE_SORT_NOT_NULL + "}") + Integer sort, + Boolean defaultValue, + String description, + Status status +) { +} diff --git a/src/main/java/com/onixbyte/helix/exception/BizException.java b/src/main/java/com/onixbyte/helix/exception/BizException.java index f898daf..8e99c74 100644 --- a/src/main/java/com/onixbyte/helix/exception/BizException.java +++ b/src/main/java/com/onixbyte/helix/exception/BizException.java @@ -41,6 +41,8 @@ public class BizException extends RuntimeException { * REST API endpoints. */ private final HttpStatus status; + private final String messageCode; + private final Object[] messageArgs; /** * Constructs a new business exception with the specified HTTP status and message. @@ -50,6 +52,8 @@ public class BizException extends RuntimeException { public BizException(String message) { super(message); this.status = HttpStatus.INTERNAL_SERVER_ERROR; + this.messageCode = null; + this.messageArgs = new Object[0]; } /** @@ -61,6 +65,22 @@ public class BizException extends RuntimeException { public BizException(HttpStatus status, String message) { super(message); this.status = status; + this.messageCode = null; + this.messageArgs = new Object[0]; + } + + public BizException(String messageCode, Object... messageArgs) { + super(messageCode); + this.status = HttpStatus.INTERNAL_SERVER_ERROR; + this.messageCode = messageCode; + this.messageArgs = messageArgs == null ? new Object[0] : messageArgs; + } + + public BizException(HttpStatus status, String messageCode, Object... messageArgs) { + super(messageCode); + this.status = status; + this.messageCode = messageCode; + this.messageArgs = messageArgs == null ? new Object[0] : messageArgs; } /** @@ -71,4 +91,12 @@ public class BizException extends RuntimeException { public HttpStatus getStatus() { return status; } + + public String getMessageCode() { + return messageCode; + } + + public Object[] getMessageArgs() { + return messageArgs; + } } diff --git a/src/main/java/com/onixbyte/helix/manager/AuthorityManager.java b/src/main/java/com/onixbyte/helix/manager/AuthorityManager.java index 0d5b774..dc1c2c5 100644 --- a/src/main/java/com/onixbyte/helix/manager/AuthorityManager.java +++ b/src/main/java/com/onixbyte/helix/manager/AuthorityManager.java @@ -8,6 +8,7 @@ import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.mapper.AuthorityMapper; import com.onixbyte.helix.repository.AuthorityRepository; import com.onixbyte.helix.shared.CacheName; +import com.onixbyte.helix.shared.MessageName; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Example; @@ -71,7 +72,7 @@ public class AuthorityManager { var updatedAt = LocalDateTime.now(); var authorityToUpdate = authorityRepository.findById(id) - .orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, "找不到指定的权限信息")); + .orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, MessageName.AUTHORITY_NOT_FOUND, id)); authorityToUpdate.setName(authority.getName()); authorityToUpdate.setDescription(authority.getDescription()); diff --git a/src/main/java/com/onixbyte/helix/manager/RoleManager.java b/src/main/java/com/onixbyte/helix/manager/RoleManager.java index 926549d..ad55450 100644 --- a/src/main/java/com/onixbyte/helix/manager/RoleManager.java +++ b/src/main/java/com/onixbyte/helix/manager/RoleManager.java @@ -5,12 +5,15 @@ import com.onixbyte.helix.domain.entity.Role; import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.mapper.RoleMapper; import com.onixbyte.helix.repository.RoleRepository; +import com.onixbyte.helix.shared.MessageName; +import com.onixbyte.helix.utils.MessageUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.*; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -19,16 +22,18 @@ public class RoleManager { private final RoleMapper roleMapper; private final RoleRepository roleRepository; + private final MessageUtil messageUtil; @Autowired - public RoleManager(RoleMapper roleMapper, RoleRepository roleRepository) { + public RoleManager(RoleMapper roleMapper, RoleRepository roleRepository, MessageUtil messageUtil) { this.roleMapper = roleMapper; this.roleRepository = roleRepository; + this.messageUtil = messageUtil; } public void validateRoles(List roleIds) { if (!roleMapper.areRolesExisted(roleIds)) { - throw new BizException(HttpStatus.BAD_REQUEST, "Role does not exist in database."); + throw new BizException(HttpStatus.BAD_REQUEST, MessageName.ROLE_NOT_EXISTS); } } @@ -52,23 +57,24 @@ public class RoleManager { } @Transactional - public void updateRole(Role role) { - var roleToUpdate = roleRepository.findById(role.getId()) - .orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, "找不到指定的角色信息。")); + public Role fullUpdateById(Long id, Role role) { + var updatedAt = LocalDateTime.now(); - Optional.ofNullable(role.getName()) - .ifPresent(roleToUpdate::setName); - - Optional.ofNullable(role.getCode()) - .ifPresent(roleToUpdate::setCode); - - Optional.ofNullable(role.getSort()) - .ifPresent(roleToUpdate::setSort); + var roleToUpdate = roleRepository.findById(id) + .orElseThrow(() -> new BizException( + HttpStatus.NOT_FOUND, + messageUtil.getMessage(MessageName.ROLE_NOT_FOUND, id)) + ); + roleToUpdate.setName(role.getName()); + roleToUpdate.setCode(role.getCode()); + roleToUpdate.setSort(role.getSort()); + roleToUpdate.setDefaultValue(role.getDefaultValue()); roleToUpdate.setDescription(role.getDescription()); + roleToUpdate.setStatus(role.getStatus()); + roleToUpdate.setUpdatedAt(updatedAt); - Optional.ofNullable(role.getStatus()) - .ifPresent(roleToUpdate::setStatus); + return role; } public void deleteRole(Long id) { diff --git a/src/main/java/com/onixbyte/helix/manager/UserManager.java b/src/main/java/com/onixbyte/helix/manager/UserManager.java index 3b19dee..2f5121b 100644 --- a/src/main/java/com/onixbyte/helix/manager/UserManager.java +++ b/src/main/java/com/onixbyte/helix/manager/UserManager.java @@ -33,6 +33,7 @@ import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.mapper.UserMapper; import com.onixbyte.helix.repository.UserRepository; import com.onixbyte.region.Region; +import com.onixbyte.helix.shared.MessageName; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CachePut; @@ -112,7 +113,7 @@ public class UserManager { @Transactional(rollbackFor = Throwable.class) public User updateUser(User user) { var userToUpdate = userRepository.findById(user.getId()) - .orElseThrow(() -> new BizException(HttpStatus.BAD_REQUEST, "找不到 ID 为" + user.getId() + "的用户信息")); + .orElseThrow(() -> new BizException(HttpStatus.BAD_REQUEST, MessageName.USER_NOT_FOUND, user.getId())); Optional.ofNullable(user.getFullName()) .filter(StringUtils::isNotBlank) diff --git a/src/main/java/com/onixbyte/helix/security/provider/UsernamePasswordAuthenticationProvider.java b/src/main/java/com/onixbyte/helix/security/provider/UsernamePasswordAuthenticationProvider.java index 35f72fc..254a844 100644 --- a/src/main/java/com/onixbyte/helix/security/provider/UsernamePasswordAuthenticationProvider.java +++ b/src/main/java/com/onixbyte/helix/security/provider/UsernamePasswordAuthenticationProvider.java @@ -8,6 +8,7 @@ import com.onixbyte.helix.manager.AuthorityManager; import com.onixbyte.helix.manager.UserManager; import com.onixbyte.helix.repository.UserCredentialRepository; import com.onixbyte.helix.security.authentication.UsernamePasswordAuthentication; +import com.onixbyte.helix.shared.MessageName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -46,14 +47,14 @@ public class UsernamePasswordAuthenticationProvider implements AuthenticationPro @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (!(authentication instanceof UsernamePasswordAuthentication usernamePasswordAuthentication)) { - throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, "用户认证失败,请稍后再试。"); + throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, MessageName.AUTH_PROVIDER_FAILED); } // get user from database var user = userManager.selectByUsername(usernamePasswordAuthentication.getPrincipal()); if (Objects.isNull(user)) { log.error("User {} is trying to authenticate but no user found.", usernamePasswordAuthentication.getPrincipal()); - throw new BizException(HttpStatus.UNAUTHORIZED, "用户名或密码错误。"); + throw new BizException(HttpStatus.UNAUTHORIZED, MessageName.AUTH_PROVIDER_BAD_CREDENTIALS); } // get user credentials from database @@ -61,12 +62,12 @@ public class UsernamePasswordAuthenticationProvider implements AuthenticationPro .provider(CredentialProvider.LOCAL) .userId(user.getId()) .build())) - .orElseThrow(() -> new BizException(HttpStatus.UNAUTHORIZED, "您还没有配置密码,请使用第三方账号登录")); + .orElseThrow(() -> new BizException(HttpStatus.UNAUTHORIZED, MessageName.AUTH_PROVIDER_PASSWORD_NOT_CONFIGURED)); // validate password if (!passwordEncoder.matches(usernamePasswordAuthentication.getCredentials(), userCredentials.getCredential())) { log.error("User {} is trying to authenticate but password is incorrect.", usernamePasswordAuthentication.getPrincipal()); - throw new BizException(HttpStatus.UNAUTHORIZED, "用户名或密码错误。"); + throw new BizException(HttpStatus.UNAUTHORIZED, MessageName.AUTH_PROVIDER_BAD_CREDENTIALS); } // erase credentials diff --git a/src/main/java/com/onixbyte/helix/service/AssetService.java b/src/main/java/com/onixbyte/helix/service/AssetService.java index 33f1dc0..95346e4 100644 --- a/src/main/java/com/onixbyte/helix/service/AssetService.java +++ b/src/main/java/com/onixbyte/helix/service/AssetService.java @@ -4,6 +4,7 @@ import com.onixbyte.helix.domain.entity.Asset; import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.manager.AssetManager; import com.onixbyte.helix.properties.AssetProperties; +import com.onixbyte.helix.shared.MessageName; import com.onixbyte.helix.utils.SecurityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -62,7 +63,7 @@ public class AssetService { if (Objects.isNull(prefix) || prefix.isBlank() || prefix.startsWith("/") || prefix.startsWith("..")) { throw new BizException( HttpStatus.INTERNAL_SERVER_ERROR, - "Prefix must not be empty, and should not start with '/' or '..'." + MessageName.ASSET_INVALID_PREFIX ); } @@ -108,7 +109,7 @@ public class AssetService { var asset = assetManager.queryByAssetId(assetId); if (!Objects.equals(currentUser.getId(), asset.getUploadBy())) { - throw new BizException(HttpStatus.FORBIDDEN, "You are not able to delete an asset that is not uploaded by you."); + throw new BizException(HttpStatus.FORBIDDEN, MessageName.ASSET_DELETE_FORBIDDEN); } assetManager.deleteById(assetId); diff --git a/src/main/java/com/onixbyte/helix/service/AuthService.java b/src/main/java/com/onixbyte/helix/service/AuthService.java index 1411a56..cc62efc 100644 --- a/src/main/java/com/onixbyte/helix/service/AuthService.java +++ b/src/main/java/com/onixbyte/helix/service/AuthService.java @@ -9,6 +9,7 @@ import com.onixbyte.helix.manager.CaptchaManager; import com.onixbyte.helix.manager.SecurityManager; import com.onixbyte.helix.manager.SettingManager; import com.onixbyte.helix.security.authentication.UsernamePasswordAuthentication; +import com.onixbyte.helix.shared.MessageName; import com.onixbyte.helix.shared.SettingName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,10 +64,10 @@ public class AuthService { var rawCaptcha = captchaManager.getCaptcha(uuid); if (Objects.isNull(rawCaptcha) || rawCaptcha.isBlank()) { - throw new BizException(HttpStatus.BAD_REQUEST, "未找到验证码"); + throw new BizException(HttpStatus.BAD_REQUEST, MessageName.AUTH_LOGIN_CAPTCHA_NOT_FOUND); } if (!rawCaptcha.equalsIgnoreCase(request.captcha())) { - throw new BizException(HttpStatus.BAD_REQUEST, "验证码错误"); + throw new BizException(HttpStatus.BAD_REQUEST, MessageName.AUTH_LOGIN_CAPTCHA_INCORRECT); } } @@ -78,7 +79,7 @@ public class AuthService { _authentication.getClass() ); throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, - "Cannot perform login due to server crashes."); + MessageName.AUTH_LOGIN_FAILED); } return authentication.getDetails(); diff --git a/src/main/java/com/onixbyte/helix/service/AuthorityService.java b/src/main/java/com/onixbyte/helix/service/AuthorityService.java index d63328e..189f5c2 100644 --- a/src/main/java/com/onixbyte/helix/service/AuthorityService.java +++ b/src/main/java/com/onixbyte/helix/service/AuthorityService.java @@ -7,6 +7,7 @@ import com.onixbyte.helix.domain.web.request.QueryAuthorityRequest; import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.manager.AuthorityManager; import com.onixbyte.helix.manager.RoleAuthorityManager; +import com.onixbyte.helix.shared.MessageName; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -40,7 +41,7 @@ public class AuthorityService { .build(); if (authorityManager.existsByCode(authority)) { - throw new BizException(HttpStatus.CONFLICT, "权限编码 `" + authority.getCode() + "` 已被使用"); + throw new BizException(HttpStatus.CONFLICT, MessageName.AUTHORITY_CODE_USED, authority.getCode()); } return authorityManager.save(authority); @@ -59,7 +60,7 @@ public class AuthorityService { var authorityName = authorityManager.findAuthorityNameById(authorityId); if (StringUtils.isBlank(authorityName)) { - throw new BizException(HttpStatus.NOT_FOUND, "Authority with ID '%d' not found.".formatted(authorityId)); + throw new BizException(HttpStatus.NOT_FOUND, MessageName.AUTHORITY_NOT_FOUND, authorityId); } roleAuthorityManager.deleteByAuthorityId(authorityId); diff --git a/src/main/java/com/onixbyte/helix/service/CaptchaService.java b/src/main/java/com/onixbyte/helix/service/CaptchaService.java index cda2d08..7f17a73 100644 --- a/src/main/java/com/onixbyte/helix/service/CaptchaService.java +++ b/src/main/java/com/onixbyte/helix/service/CaptchaService.java @@ -1,13 +1,14 @@ package com.onixbyte.helix.service; import com.onixbyte.captcha.Producer; -import com.onixbyte.helix.shared.FileType; -import com.onixbyte.helix.shared.SettingName; import com.onixbyte.helix.domain.entity.Setting; import com.onixbyte.helix.domain.web.response.CaptchaResponse; import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.manager.CaptchaManager; import com.onixbyte.helix.manager.SettingManager; +import com.onixbyte.helix.shared.FileType; +import com.onixbyte.helix.shared.MessageName; +import com.onixbyte.helix.shared.SettingName; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.FastByteArrayOutputStream; @@ -66,7 +67,7 @@ public class CaptchaService { Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()); return new CaptchaResponse(captchaDataUrl, uuid); } catch (IOException e) { - throw new BizException("无法生成验证码图片。"); + throw new BizException(MessageName.CAPTCHA_GENERATE_FAILED); } } } diff --git a/src/main/java/com/onixbyte/helix/service/RoleService.java b/src/main/java/com/onixbyte/helix/service/RoleService.java index 8deedd0..5717c83 100644 --- a/src/main/java/com/onixbyte/helix/service/RoleService.java +++ b/src/main/java/com/onixbyte/helix/service/RoleService.java @@ -1,19 +1,22 @@ package com.onixbyte.helix.service; -import com.onixbyte.helix.enumeration.Status; import com.onixbyte.helix.domain.database.query.wrapper.QueryRoleWrapper; import com.onixbyte.helix.domain.entity.Role; -import com.onixbyte.helix.domain.web.request.AddRoleRequest; -import com.onixbyte.helix.domain.web.request.EditRoleRequest; import com.onixbyte.helix.domain.web.request.QueryRoleRequest; +import com.onixbyte.helix.domain.web.request.RoleRequest; +import com.onixbyte.helix.enumeration.Status; +import com.onixbyte.helix.exception.BizException; import com.onixbyte.helix.manager.RoleAuthorityManager; import com.onixbyte.helix.manager.RoleManager; import com.onixbyte.helix.manager.UserRoleManager; +import com.onixbyte.helix.shared.MessageName; +import com.onixbyte.helix.utils.MessageUtil; import jakarta.transaction.Transactional; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import java.util.Optional; @@ -24,16 +27,19 @@ public class RoleService { private final RoleManager roleManager; private final RoleAuthorityManager roleAuthorityManager; private final UserRoleManager userRoleManager; + private final MessageUtil messageUtil; @Autowired public RoleService( RoleManager roleManager, RoleAuthorityManager roleAuthorityManager, - UserRoleManager userRoleManager + UserRoleManager userRoleManager, + MessageUtil messageUtil ) { this.roleManager = roleManager; this.roleAuthorityManager = roleAuthorityManager; this.userRoleManager = userRoleManager; + this.messageUtil = messageUtil; } public Page getRoles(Pageable pageable, QueryRoleRequest request) { @@ -55,11 +61,12 @@ public class RoleService { return roleManager.selectAll(pageable, wrapper); } - public Role addRole(AddRoleRequest request) { - var isDefaultRole = Optional.ofNullable(request.defaultValue()) + public Role addRole(RoleRequest request) { + var isDefaultRole = Optional.of(request) + .map(RoleRequest::defaultValue) .orElse(false); - var status = Optional.ofNullable(request.status()) - .map(Status::valueOf) + var status = Optional.of(request) + .map(RoleRequest::status) .orElse(Status.ACTIVE); var role = Role.builder() @@ -75,24 +82,29 @@ public class RoleService { } @Transactional - public void editRole(EditRoleRequest request) { - roleManager.updateRole(Role.builder() - .id(request.id()) + public Role editRole(Long id, RoleRequest request) { + return roleManager.fullUpdateById(id, Role.builder() .name(request.name()) .code(request.code()) .sort(request.sort()) .defaultValue(request.defaultValue()) .description(request.description()) - .status(Optional.ofNullable(request.status()) - .map(Status::valueOf) - .orElse(null)) + .status(request.status()) .build()); } @Transactional - public void deleteRole(Long id) { + public String deleteRole(Long id) { + var role = roleManager.getRoleById(id) + .orElseThrow(() -> new BizException( + HttpStatus.NOT_FOUND, + messageUtil.getMessage(MessageName.ROLE_NOT_FOUND, id)) + ); + roleAuthorityManager.deleteByRoleId(id); userRoleManager.deleteByRoleId(id); roleManager.deleteRole(id); + + return role.getName(); } } diff --git a/src/main/java/com/onixbyte/helix/shared/Message.java b/src/main/java/com/onixbyte/helix/shared/Message.java deleted file mode 100644 index 0111874..0000000 --- a/src/main/java/com/onixbyte/helix/shared/Message.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2024-2026 OnixByte - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.onixbyte.helix.shared; - -public class Message { - - public static final String ASSET_NOT_EMPTY = "asset.not-empty"; - - public static final String AUTHORITY_DELETED = "authority.deleted"; - - public static final String USER_PASSWORD_RESET_SUCCESS = "user.password-reset-success"; - public static final String USER_DELETED = "user.deleted"; -} diff --git a/src/main/java/com/onixbyte/helix/shared/MessageName.java b/src/main/java/com/onixbyte/helix/shared/MessageName.java new file mode 100644 index 0000000..c872f02 --- /dev/null +++ b/src/main/java/com/onixbyte/helix/shared/MessageName.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024-2026 OnixByte + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.onixbyte.helix.shared; + +public class MessageName { + + public static final String ASSET_NOT_EMPTY = "asset.not-empty"; + public static final String ASSET_INVALID_PREFIX = "asset.invalid-prefix"; + public static final String ASSET_DELETE_FORBIDDEN = "asset.delete-forbidden"; + public static final String ASSET_UPLOAD_FAILED = "asset.upload-failed"; + + public static final String AUTHORITY_DELETED = "authority.deleted"; + public static final String AUTHORITY_CODE_USED = "authority.code-used"; + public static final String AUTHORITY_NOT_FOUND = "authority.not-found"; + + public static final String AUTH_LOGIN_CAPTCHA_NOT_FOUND = "auth.login.captcha-not-found"; + public static final String AUTH_LOGIN_CAPTCHA_INCORRECT = "auth.login.captcha-incorrect"; + public static final String AUTH_LOGIN_FAILED = "auth.login.failed"; + + public static final String AUTH_PROVIDER_FAILED = "auth.provider.failed"; + public static final String AUTH_PROVIDER_BAD_CREDENTIALS = "auth.provider.bad-credentials"; + public static final String AUTH_PROVIDER_PASSWORD_NOT_CONFIGURED = "auth.provider.password-not-configured"; + + public static final String CAPTCHA_GENERATE_FAILED = "captcha.generate-failed"; + + public static final String ROLE_NOT_EXISTS = "role.not-exists"; + + public static final String USER_PASSWORD_RESET_SUCCESS = "user.password-reset-success"; + public static final String USER_DELETED = "user.deleted"; + public static final String USER_NOT_FOUND = "user.not-found"; + + public static final String SECURITY_CONTEXT_USER_NOT_FOUND = "security.context-user-not-found"; + public static final String TREE_MULTIPLE_ROOTS = "tree.multiple-roots"; + + public static final String ROLE_NOT_FOUND = "role.not-found"; + public static final String ROLE_DELETED = "role.deleted"; + + public static final String REQUEST_ADD_USER_USERNAME_NOT_EMPTY = "request.add-user.username.not-empty"; + public static final String REQUEST_ADD_USER_PASSWORD_NOT_EMPTY = "request.add-user.password.not-empty"; + public static final String REQUEST_ADD_USER_FULL_NAME_NOT_EMPTY = "request.add-user.full-name.not-empty"; + + public static final String REQUEST_AUTHORITY_CODE_NOT_EDITABLE = "request.authority.code.not-editable"; + public static final String REQUEST_AUTHORITY_CODE_NOT_NULL = "request.authority.code.not-null"; + public static final String REQUEST_AUTHORITY_NAME_NOT_NULL = "request.authority.name.not-null"; + + public static final String REQUEST_DEPARTMENT_NAME_NOT_NULL = "request.department.name.not-null"; + + public static final String REQUEST_EDIT_ROLE_ID_NOT_NULL = "request.edit-role.id.not-null"; + public static final String REQUEST_EDIT_ROLE_STATUS_INVALID = "request.edit-role.status.invalid"; + + public static final String REQUEST_EDIT_USER_ID_NOT_NULL = "request.edit-user.id.not-null"; + public static final String REQUEST_EDIT_USER_ID_POSITIVE = "request.edit-user.id.positive"; + + public static final String REQUEST_RESET_PASSWORD_NOT_EMPTY = "request.reset-password.password.not-empty"; + + public static final String REQUEST_ROLE_NAME_NOT_EMPTY = "request.role.name.not-empty"; + public static final String REQUEST_ROLE_CODE_NOT_EMPTY = "request.role.code.not-empty"; + public static final String REQUEST_ROLE_SORT_NOT_NULL = "request.role.sort.not-null"; + + public static final String REQUEST_QUERY_ROLE_STATUS_INVALID = "request.query-role.status.invalid"; + public static final String REQUEST_QUERY_USER_STATUS_INVALID = "request.query-user.status.invalid"; +} diff --git a/src/main/java/com/onixbyte/helix/utils/SecurityUtil.java b/src/main/java/com/onixbyte/helix/utils/SecurityUtil.java index acb59be..18b3ff9 100644 --- a/src/main/java/com/onixbyte/helix/utils/SecurityUtil.java +++ b/src/main/java/com/onixbyte/helix/utils/SecurityUtil.java @@ -2,6 +2,7 @@ package com.onixbyte.helix.utils; import com.onixbyte.helix.domain.entity.User; import com.onixbyte.helix.exception.BizException; +import com.onixbyte.helix.shared.MessageName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -32,7 +33,7 @@ public class SecurityUtil { if (!(_details instanceof User user)) { log.error("Authentication details is {}", _details); - throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, "Cannot retrieve user information from context."); + throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, MessageName.SECURITY_CONTEXT_USER_NOT_FOUND); } return user; diff --git a/src/main/java/com/onixbyte/helix/utils/TreeUtil.java b/src/main/java/com/onixbyte/helix/utils/TreeUtil.java index 848c65b..adc6514 100644 --- a/src/main/java/com/onixbyte/helix/utils/TreeUtil.java +++ b/src/main/java/com/onixbyte/helix/utils/TreeUtil.java @@ -3,6 +3,7 @@ package com.onixbyte.helix.utils; import com.onixbyte.helix.domain.common.Treeable; import com.onixbyte.helix.domain.common.TreeNode; import com.onixbyte.helix.exception.BizException; +import com.onixbyte.helix.shared.MessageName; import org.apache.commons.collections4.CollectionUtils; import org.springframework.http.HttpStatus; @@ -43,7 +44,7 @@ public class TreeUtil { // Ensure only 1 root node is included if (rootItems.size() > 1) { - throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, "Multiple root items found in given values."); + throw new BizException(HttpStatus.INTERNAL_SERVER_ERROR, MessageName.TREE_MULTIPLE_ROOTS); } // Get root item and build root node diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index dc7bbad..cd88c9e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -27,6 +27,8 @@ spring: hikari: minimum-idle: 1 maximum-pool-size: 10 + messages: + basename: i18n/messages flyway: enabled: true baseline-on-migrate: true diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index f9a18f6..a204e38 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -19,10 +19,28 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # - +tree.multiple-roots= +user.not-found=User with ID [{0}] not found. +security.context-user-not-found=Cannot retrieve user information from security context. +role.not-exists=Role does not exist in database. +captcha.generate-failed= +auth.provider.password-not-configured=Username or password is incorrect. +auth.provider.bad-credentials=Username or password is incorrect. +auth.provider.failed=Authentication failed, please try again later. +auth.login.failed=Cannot perform login due to server error. +auth.login.captcha-incorrect=Captcha is incorrect. +auth.login.captcha-not-found=Captcha not found. +authority.not-found=Authority with ID [{0}] not found. +authority.code-used=Authority code [{0}] is already in use. +asset.upload-failed=Failed to upload file: {0} +asset.delete-forbidden=You are not able to delete an asset that is not uploaded by you. +asset.invalid-prefix=Prefix must not be empty and must not start with '/' or '..'. asset.not-empty = File cannot be empty. authority.deleted = Authority [{0}] deleted. user.password-reset-success = Password has been reset. -user.deleted = User [{0}] deleted. \ No newline at end of file +user.deleted = User [{0}] deleted. +role.not-found=Role with ID {0} not found. +role.deleted=Role [{0}] deleted. +request.role.name.not-empty=Name of the role cannot be empty. \ No newline at end of file diff --git a/src/main/resources/i18n/messages_en_GB.properties b/src/main/resources/i18n/messages_en_GB.properties index f9a18f6..b5a19db 100644 --- a/src/main/resources/i18n/messages_en_GB.properties +++ b/src/main/resources/i18n/messages_en_GB.properties @@ -21,8 +21,56 @@ # asset.not-empty = File cannot be empty. +asset.invalid-prefix = Prefix must not be empty and must not start with '/' or '..'. +asset.delete-forbidden = You are not able to delete an asset that is not uploaded by you. +asset.upload-failed = Failed to upload file: {0} authority.deleted = Authority [{0}] deleted. +authority.code-used = Authority code [{0}] is already in use. +authority.not-found = Authority with ID [{0}] not found. + +auth.login.captcha-not-found = Captcha not found. +auth.login.captcha-incorrect = Captcha is incorrect. +auth.login.failed = Cannot perform login due to server error. + +auth.provider.failed = Authentication failed, please try again later. +auth.provider.bad-credentials = Username or password is incorrect. +auth.provider.password-not-configured = Password is not configured. Please sign in with a third-party account. + +captcha.generate-failed = Unable to generate captcha image. + +role.not-exists = Role does not exist in database. +role.not-found = Role with ID {0} not found. +role.deleted = Role [{0}] deleted. user.password-reset-success = Password has been reset. -user.deleted = User [{0}] deleted. \ No newline at end of file +user.deleted = User [{0}] deleted. +user.not-found = User with ID [{0}] not found. + +security.context-user-not-found = Cannot retrieve user information from security context. +tree.multiple-roots = Multiple root items found in given values. + +request.add-user.username.not-empty = Username cannot be empty. +request.add-user.password.not-empty = Password cannot be empty. +request.add-user.full-name.not-empty = Full name cannot be empty. + +request.authority.code.not-editable = Code cannot be edited. +request.authority.code.not-null = Code cannot be null. +request.authority.name.not-null = Name of the authority cannot be null. + +request.department.name.not-null = Name of the department should not be null. + +request.edit-role.id.not-null = Role ID cannot be null. +request.edit-role.status.invalid = Status can only be ACTIVE or INACTIVE. + +request.edit-user.id.not-null = User ID cannot be null. +request.edit-user.id.positive = User ID must be positive. + +request.reset-password.password.not-empty = Password cannot be empty. + +request.role.name.not-empty = Name of the role cannot be empty. +request.role.code.not-empty = Code of the role cannot be empty. +request.role.sort.not-null = Sort number cannot be null. + +request.query-role.status.invalid = Status can only be ACTIVE or INACTIVE. +request.query-user.status.invalid = Status can only be ACTIVE, INACTIVE, or LOCKED. diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties index 009ffa2..9c61320 100644 --- a/src/main/resources/i18n/messages_zh_CN.properties +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -21,8 +21,56 @@ # asset.not-empty = 文件不能为空。 +asset.invalid-prefix = 前缀不能为空,且不能以 '/' 或 '..' 开头。 +asset.delete-forbidden = 你不能删除非自己上传的文件。 +asset.upload-failed = 文件上传失败:{0} authority.deleted = 权限【{0}】删除成功。 +authority.code-used = 权限编码【{0}】已被使用。 +authority.not-found = 找不到 ID 为【{0}】的权限。 + +auth.login.captcha-not-found = 未找到验证码。 +auth.login.captcha-incorrect = 验证码错误。 +auth.login.failed = 登录失败,服务器出现错误。 + +auth.provider.failed = 用户认证失败,请稍后再试。 +auth.provider.bad-credentials = 用户名或密码错误。 +auth.provider.password-not-configured = 你还没有配置密码,请使用第三方账号登录。 + +captcha.generate-failed = 无法生成验证码图片。 + +role.not-exists = 角色不存在。 +role.not-found = 找不到 ID 为 {0} 的角色。 +role.deleted = 角色【{0}】删除成功。 user.password-reset-success = 密码修改成功。 -user.deleted = 用户【{0}】删除成功。 \ No newline at end of file +user.deleted = 用户【{0}】删除成功。 +user.not-found = 找不到 ID 为【{0}】的用户信息。 + +security.context-user-not-found = 无法从安全上下文中获取用户信息。 +tree.multiple-roots = 数据中包含多个根节点。 + +request.add-user.username.not-empty = 用户名不能为空。 +request.add-user.password.not-empty = 密码不能为空。 +request.add-user.full-name.not-empty = 姓名不能为空。 + +request.authority.code.not-editable = 权限编码不可修改。 +request.authority.code.not-null = 权限编码不能为空。 +request.authority.name.not-null = 权限名称不能为空。 + +request.department.name.not-null = 部门名称不能为空。 + +request.edit-role.id.not-null = 角色 ID 不能为空。 +request.edit-role.status.invalid = 状态只能是 ACTIVE 或 INACTIVE。 + +request.edit-user.id.not-null = 用户 ID 不能为空。 +request.edit-user.id.positive = 用户 ID 必须为正数。 + +request.reset-password.password.not-empty = 密码不能为空。 + +request.role.name.not-empty = 角色名称不能为空。 +request.role.code.not-empty = 角色编码不能为空。 +request.role.sort.not-null = 排序编号不能为空。 + +request.query-role.status.invalid = 状态只能是 ACTIVE 或 INACTIVE。 +request.query-user.status.invalid = 状态只能是 ACTIVE、INACTIVE 或 LOCKED。