Compare commits
10 Commits
aebb693ee7
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| dedf95865e | |||
| 9d2fc024ea | |||
| 6f29904349 | |||
| 08c18fea90 | |||
| 776ddd28c1 | |||
| a3596ad086 | |||
| e1ad5cdfd8 | |||
| 712a675325 | |||
| 8b343af4e8 | |||
| 69e3f84bec |
@@ -1,7 +1,6 @@
|
||||
package com.onixbyte.helix.config;
|
||||
|
||||
import com.onixbyte.identitygenerator.IdentityGenerator;
|
||||
import com.onixbyte.identitygenerator.impl.SequentialUuidGenerator;
|
||||
import com.onixbyte.identitygenerator.impl.SnowflakeIdentityGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -28,24 +27,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class GuidConfig {
|
||||
|
||||
/**
|
||||
* Creates a Snowflake-based identity generator for user IDs.
|
||||
* <p>
|
||||
* This method configures a {@link SnowflakeIdentityGenerator} with machine ID and data centre
|
||||
* ID both set to 0. The generator produces unique 64-bit Long identifiers suitable for user
|
||||
* entity primary keys in distributed environments.
|
||||
* <p>
|
||||
* The generated IDs are:
|
||||
* <ul>
|
||||
* <li>Globally unique across all instances</li>
|
||||
* <li>Time-ordered (newer IDs have higher values)</li>
|
||||
* <li>Highly performant with minimal coordination overhead</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return a configured {@link SnowflakeIdentityGenerator} instance for generating user IDs
|
||||
* @see SnowflakeIdentityGenerator
|
||||
* @see IdentityGenerator
|
||||
*/
|
||||
@Bean
|
||||
public IdentityGenerator<Long> userIdentityGenerator() {
|
||||
return new SnowflakeIdentityGenerator(0x0, 0x0);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Configuration
|
||||
public class I18nConfig {
|
||||
|
||||
@Bean
|
||||
public LocaleResolver localeResolver() {
|
||||
var slr = new AcceptHeaderLocaleResolver();
|
||||
slr.setDefaultLocale(Locale.UK);
|
||||
return slr;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.onixbyte.helix.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.onixbyte.helix.common.jackson.JacksonModules;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
@Configuration
|
||||
public class ValidationConfig {
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
@Autowired
|
||||
public ValidationConfig(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalValidatorFactoryBean getValidator() {
|
||||
var factoryBean = new LocalValidatorFactoryBean();
|
||||
factoryBean.setValidationMessageSource(messageSource);
|
||||
return factoryBean;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +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.MessageName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -26,11 +27,6 @@ public class AssetController {
|
||||
|
||||
private final AssetService assetService;
|
||||
|
||||
/**
|
||||
* Constructs a new FileController with the specified file service.
|
||||
*
|
||||
* @param assetService the file service to use for file operations
|
||||
*/
|
||||
@Autowired
|
||||
public AssetController(AssetService assetService) {
|
||||
this.assetService = assetService;
|
||||
@@ -48,7 +44,7 @@ public class AssetController {
|
||||
) {
|
||||
try {
|
||||
if (file.isEmpty()) {
|
||||
throw new BizException(HttpStatus.BAD_REQUEST, "File cannot be empty.");
|
||||
throw new BizException(HttpStatus.BAD_REQUEST, MessageName.ASSET_NOT_EMPTY);
|
||||
}
|
||||
|
||||
var fileUrl = assetService.uploadFile(AssetPrefix.UPLOADS, file);
|
||||
@@ -61,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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ import com.onixbyte.helix.service.AuthService;
|
||||
import com.onixbyte.helix.service.TokenService;
|
||||
import com.onixbyte.helix.service.UserService;
|
||||
import com.onixbyte.helix.shared.TokenConstant;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -27,7 +25,6 @@ import java.time.Duration;
|
||||
@RequestMapping("/auth")
|
||||
public class AuthController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AuthController.class);
|
||||
private final AuthService authService;
|
||||
private final TokenService tokenService;
|
||||
private final UserService userService;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.onixbyte.helix.controller;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.Authority;
|
||||
import com.onixbyte.helix.domain.web.request.AddAuthorityRequest;
|
||||
import com.onixbyte.helix.domain.web.request.EditAuthorityRequest;
|
||||
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.MessageName;
|
||||
import com.onixbyte.helix.utils.MessageUtil;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -21,9 +23,14 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class AuthorityController {
|
||||
|
||||
private final AuthorityService authorityService;
|
||||
private final MessageUtil messageUtil;
|
||||
|
||||
public AuthorityController(AuthorityService authorityService) {
|
||||
public AuthorityController(
|
||||
AuthorityService authorityService,
|
||||
MessageUtil messageUtil
|
||||
) {
|
||||
this.authorityService = authorityService;
|
||||
this.messageUtil = messageUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +58,7 @@ public class AuthorityController {
|
||||
* @return created authority
|
||||
*/
|
||||
@PostMapping
|
||||
public Authority addAuthority(@Validated @RequestBody AddAuthorityRequest request) {
|
||||
public Authority addAuthority(@Validated @RequestBody AuthorityRequest request) {
|
||||
return authorityService.addAuthority(request);
|
||||
}
|
||||
|
||||
@@ -61,8 +68,17 @@ public class AuthorityController {
|
||||
* @param request authority specs
|
||||
* @return edited authority
|
||||
*/
|
||||
@PutMapping
|
||||
public Authority editAuthority(@Validated @RequestBody EditAuthorityRequest request) {
|
||||
return authorityService.editAuthority(request);
|
||||
@PutMapping("/{id:\\d+}")
|
||||
public Authority editAuthority(
|
||||
@PathVariable Long id,
|
||||
@Validated @RequestBody AuthorityRequest request
|
||||
) {
|
||||
return authorityService.editAuthority(id, request);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{authorityId:\\d+}")
|
||||
public ActionResponse deleteAuthority(@PathVariable Long authorityId) {
|
||||
var name = authorityService.deleteAuthority(authorityId);
|
||||
return ActionResponse.success(messageUtil.getMessage(MessageName.AUTHORITY_DELETED, name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.onixbyte.helix.controller;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.Department;
|
||||
import com.onixbyte.helix.domain.common.TreeNode;
|
||||
import com.onixbyte.helix.domain.web.request.AddDepartmentRequest;
|
||||
import com.onixbyte.helix.domain.web.request.DepartmentRequest;
|
||||
import com.onixbyte.helix.service.DepartmentService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -38,7 +38,15 @@ public class DepartmentController {
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Department addDepartment(@Validated @RequestBody AddDepartmentRequest request) {
|
||||
public Department addDepartment(@Validated @RequestBody DepartmentRequest request) {
|
||||
return departmentService.addDepartment(request);
|
||||
}
|
||||
|
||||
@PutMapping("/{id:\\d+}")
|
||||
public Department editDepartment(
|
||||
@PathVariable Long id,
|
||||
@Validated @RequestBody DepartmentRequest request
|
||||
) {
|
||||
return departmentService.editDepartment(id, request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BizExceptionResponse> 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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Void> 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<Void> 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<Void> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,12 @@ 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.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.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -27,10 +28,12 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
private final MessageUtil messageUtil;
|
||||
|
||||
@Autowired
|
||||
public UserController(UserService userService) {
|
||||
public UserController(UserService userService, MessageUtil messageUtil) {
|
||||
this.userService = userService;
|
||||
this.messageUtil = messageUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,13 +81,16 @@ public class UserController {
|
||||
/**
|
||||
* Edit a user.
|
||||
*
|
||||
* @param id user ID
|
||||
* @param request user to be edited
|
||||
* @return edited user
|
||||
*/
|
||||
@PutMapping
|
||||
public ResponseEntity<Void> editUser(@Validated @RequestBody EditUserRequest request) {
|
||||
userService.updateUser(request);
|
||||
return ResponseEntity.ok(null);
|
||||
@PutMapping("/{id:\\d+}")
|
||||
public UserDetailResponse editUser(
|
||||
@PathVariable Long id,
|
||||
@Validated @RequestBody EditUserRequest request
|
||||
) {
|
||||
return userService.updateUser(id, request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,10 +100,13 @@ public class UserController {
|
||||
* @return action response
|
||||
*/
|
||||
@PreAuthorize("hasAnyAuthority('system:user:reset-password')")
|
||||
@PatchMapping("/reset-password")
|
||||
public ActionResponse resetPassword(@Validated @RequestBody ResetPasswordRequest request) {
|
||||
userService.resetPassword(request);
|
||||
return ActionResponse.success("密码修改成功");
|
||||
@PatchMapping("/reset-password/{id:\\d+}")
|
||||
public ActionResponse resetPassword(
|
||||
@PathVariable Long id,
|
||||
@Validated @RequestBody ResetPasswordRequest request
|
||||
) {
|
||||
userService.resetPassword(id, request);
|
||||
return ActionResponse.success(messageUtil.getMessage(MessageName.USER_PASSWORD_RESET_SUCCESS));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +119,6 @@ public class UserController {
|
||||
@DeleteMapping("/{userId:\\d+}")
|
||||
public ActionResponse deleteUser(@PathVariable Long userId) {
|
||||
userService.deleteUser(userId);
|
||||
return ActionResponse.success("删除成功");
|
||||
return ActionResponse.success(messageUtil.getMessage(MessageName.USER_DELETED, userId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +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 AddAuthorityRequest(
|
||||
@NotNull @NotBlank(message = "权限编码不能为空") String code,
|
||||
@NotNull @NotBlank(message = "权限名称不能为空") String name,
|
||||
String description,
|
||||
@Pattern(
|
||||
regexp = "^(ACTIVE|INACTIVE)?$",
|
||||
message = "状态错误") String status
|
||||
) {
|
||||
}
|
||||
@@ -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
|
||||
) {
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
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;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
|
||||
public record AuthorityRequest(
|
||||
@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 = "{" + MessageName.REQUEST_AUTHORITY_NAME_NOT_NULL + "}")
|
||||
@NotBlank(message = "{" + MessageName.REQUEST_AUTHORITY_NAME_NOT_NULL + "}")
|
||||
String name,
|
||||
String description,
|
||||
Status status
|
||||
) {
|
||||
}
|
||||
+4
-3
@@ -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 AddDepartmentRequest(
|
||||
@NotNull(message = "Name of the department should not be null")
|
||||
@NotBlank(message = "Name of the department should not be null")
|
||||
public record DepartmentRequest(
|
||||
@NotNull(message = "{" + MessageName.REQUEST_DEPARTMENT_NAME_NOT_NULL + "}")
|
||||
@NotBlank(message = "{" + MessageName.REQUEST_DEPARTMENT_NAME_NOT_NULL + "}")
|
||||
String name,
|
||||
Long parentId,
|
||||
Integer sort,
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.onixbyte.helix.domain.web.request;
|
||||
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
|
||||
public record EditAuthorityRequest(
|
||||
Long id,
|
||||
String name,
|
||||
String description,
|
||||
@Pattern(
|
||||
regexp = "^(ACTIVE|INACTIVE)?$",
|
||||
message = "状态参数错误")
|
||||
String status
|
||||
) {
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.onixbyte.helix.domain.web.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
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,
|
||||
@@ -14,7 +14,7 @@ public record EditRoleRequest(
|
||||
String description,
|
||||
@Pattern(
|
||||
regexp = "^(ACTIVE|INACTIVE)?$",
|
||||
message = "状态仅可以是 ACTIVE、INACTIVE 其中之一")
|
||||
message = "{" + MessageName.REQUEST_EDIT_ROLE_STATUS_INVALID + "}")
|
||||
String status
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,10 +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(
|
||||
@NotNull(message = "用户 ID 不能为空") Long id,
|
||||
@NotBlank(message = "密码不能为空") String password
|
||||
@NotBlank(message = "{" + MessageName.REQUEST_RESET_PASSWORD_NOT_EMPTY + "}") String password
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
}
|
||||
@@ -41,26 +41,19 @@ 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.
|
||||
*
|
||||
* @param message the detailed error message explaining the business logic violation
|
||||
*/
|
||||
public BizException(String message) {
|
||||
super(message);
|
||||
public BizException(String messageCode, Object... messageArgs) {
|
||||
this.status = HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
this.messageCode = messageCode;
|
||||
this.messageArgs = messageArgs == null ? new Object[0] : messageArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new business exception with the specified HTTP status and message.
|
||||
*
|
||||
* @param status the HTTP status code to associate with this exception
|
||||
* @param message the detailed error message explaining the business logic violation
|
||||
*/
|
||||
public BizException(HttpStatus status, String message) {
|
||||
super(message);
|
||||
public BizException(HttpStatus status, String messageCode, Object... messageArgs) {
|
||||
this.status = status;
|
||||
this.messageCode = messageCode;
|
||||
this.messageArgs = messageArgs == null ? new Object[0] : messageArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,4 +64,12 @@ public class BizException extends RuntimeException {
|
||||
public HttpStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public String getMessageCode() {
|
||||
return messageCode;
|
||||
}
|
||||
|
||||
public Object[] getMessageArgs() {
|
||||
return messageArgs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.shared.CacheName;
|
||||
import com.onixbyte.helix.domain.entity.Asset;
|
||||
import com.onixbyte.helix.mapper.AssetMapper;
|
||||
import com.onixbyte.helix.repository.AssetRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@@ -13,12 +12,10 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class AssetManager {
|
||||
|
||||
private final AssetMapper assetMapper;
|
||||
private final AssetRepository assetRepository;
|
||||
|
||||
@Autowired
|
||||
public AssetManager(AssetMapper assetMapper, AssetRepository assetRepository) {
|
||||
this.assetMapper = assetMapper;
|
||||
public AssetManager(AssetRepository assetRepository) {
|
||||
this.assetRepository = assetRepository;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,13 @@ package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.domain.database.query.wrapper.QueryAuthorityWrapper;
|
||||
import com.onixbyte.helix.domain.entity.Authority;
|
||||
import com.onixbyte.helix.domain.web.request.EditAuthorityRequest;
|
||||
import com.onixbyte.helix.domain.web.request.AuthorityRequest;
|
||||
import com.onixbyte.helix.enumeration.Status;
|
||||
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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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;
|
||||
@@ -19,13 +18,13 @@ 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;
|
||||
|
||||
@Component
|
||||
public class AuthorityManager {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AuthorityManager.class);
|
||||
private final AuthorityMapper authorityMapper;
|
||||
private final AuthorityRepository authorityRepository;
|
||||
|
||||
@@ -56,20 +55,38 @@ public class AuthorityManager {
|
||||
return authorityRepository.save(authority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully updates an existing authority by ID.
|
||||
* <p>
|
||||
* The method loads the target authority, replaces mutable fields ({@code name},
|
||||
* {@code description}, {@code status}), and refreshes {@code updatedAt} to the current time.
|
||||
* The update runs within a transactional context.
|
||||
*
|
||||
* @param id the ID of the authority to update
|
||||
* @param authority the source data carrying new field values
|
||||
* @return the supplied {@link Authority} object
|
||||
* @throws BizException if the target authority does not exist
|
||||
*/
|
||||
@Transactional
|
||||
public Authority update(EditAuthorityRequest request) {
|
||||
var authority = authorityRepository.findById(request.id())
|
||||
.orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, "找不到指定的权限信息"));
|
||||
public Authority fullUpdateById(Long id, Authority authority) {
|
||||
var updatedAt = LocalDateTime.now();
|
||||
|
||||
Optional.ofNullable(request.name())
|
||||
.ifPresent(authority::setName);
|
||||
var authorityToUpdate = authorityRepository.findById(id)
|
||||
.orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, MessageName.AUTHORITY_NOT_FOUND, id));
|
||||
|
||||
authority.setDescription(request.description());
|
||||
|
||||
Optional.ofNullable(request.status())
|
||||
.map(Status::valueOf)
|
||||
.ifPresent(authority::setStatus);
|
||||
authorityToUpdate.setName(authority.getName());
|
||||
authorityToUpdate.setDescription(authority.getDescription());
|
||||
authorityToUpdate.setStatus(authority.getStatus());
|
||||
authorityToUpdate.setUpdatedAt(updatedAt);
|
||||
|
||||
return authority;
|
||||
}
|
||||
|
||||
public String findAuthorityNameById(Long authorityId) {
|
||||
return authorityRepository.findAuthorityNameById(authorityId);
|
||||
}
|
||||
|
||||
public void deleteById(Long authorityId) {
|
||||
authorityRepository.deleteById(authorityId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.Department;
|
||||
import com.onixbyte.helix.mapper.DepartmentMapper;
|
||||
import com.onixbyte.helix.exception.BizException;
|
||||
import com.onixbyte.helix.repository.DepartmentRepository;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
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.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class DepartmentManager {
|
||||
|
||||
private final DepartmentMapper departmentMapper;
|
||||
private final DepartmentRepository departmentRepository;
|
||||
|
||||
@Autowired
|
||||
public DepartmentManager(DepartmentMapper departmentMapper, DepartmentRepository departmentRepository) {
|
||||
this.departmentMapper = departmentMapper;
|
||||
public DepartmentManager(DepartmentRepository departmentRepository) {
|
||||
this.departmentRepository = departmentRepository;
|
||||
}
|
||||
|
||||
@@ -37,4 +40,38 @@ public class DepartmentManager {
|
||||
public Department save(Department department) {
|
||||
return departmentRepository.save(department);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully updates an existing department by ID.
|
||||
* <p>
|
||||
* The method loads the target department, replaces mutable fields ({@code name},
|
||||
* {@code parentId}, {@code sort}, {@code status}), and refreshes {@code updatedAt} to the
|
||||
* current time.
|
||||
*
|
||||
* @param id the ID of the department to update
|
||||
* @param department the source data carrying new field values
|
||||
* @return the managed and updated {@link Department} entity
|
||||
* @throws BizException if the target department does not exist
|
||||
*/
|
||||
@Transactional
|
||||
public Department fullUpdateById(Long id, Department department) {
|
||||
var updatedAt = LocalDateTime.now();
|
||||
|
||||
var departmentToEdit = departmentRepository.findById(id)
|
||||
.orElseThrow(() -> new BizException(
|
||||
HttpStatus.NOT_FOUND,
|
||||
"Department (ID: %d) to be edited not found.".formatted(department.getId()))
|
||||
);
|
||||
|
||||
departmentToEdit.setName(department.getName());
|
||||
departmentToEdit.setParentId(department.getParentId());
|
||||
departmentToEdit.setSort(department.getSort());
|
||||
departmentToEdit.setStatus(department.getStatus());
|
||||
departmentToEdit.setUpdatedAt(updatedAt);
|
||||
return departmentToEdit;
|
||||
}
|
||||
|
||||
public boolean existsByName(String name) {
|
||||
return departmentRepository.existsByName(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.Menu;
|
||||
import com.onixbyte.helix.mapper.MenuMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -11,7 +9,7 @@ import java.util.List;
|
||||
|
||||
@Component
|
||||
public class MenuManager {
|
||||
private static final Logger log = LoggerFactory.getLogger(MenuManager.class);
|
||||
|
||||
private final MenuMapper menuMapper;
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.Position;
|
||||
import com.onixbyte.helix.mapper.PositionMapper;
|
||||
import com.onixbyte.helix.repository.PositionRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -11,12 +10,10 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class PositionManager {
|
||||
|
||||
private final PositionMapper positionMapper;
|
||||
private final PositionRepository positionRepository;
|
||||
|
||||
@Autowired
|
||||
public PositionManager(PositionMapper positionMapper, PositionRepository positionRepository) {
|
||||
this.positionMapper = positionMapper;
|
||||
public PositionManager(PositionRepository positionRepository) {
|
||||
this.positionRepository = positionRepository;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.repository.RoleAuthorityRepository;
|
||||
import com.onixbyte.helix.mapper.RoleAuthorityMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -9,14 +9,20 @@ import org.springframework.stereotype.Component;
|
||||
public class RoleAuthorityManager {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RoleAuthorityManager.class);
|
||||
private final RoleAuthorityRepository roleAuthorityRepository;
|
||||
private final RoleAuthorityMapper roleAuthorityMapper;
|
||||
|
||||
public RoleAuthorityManager(RoleAuthorityRepository roleAuthorityRepository) {
|
||||
this.roleAuthorityRepository = roleAuthorityRepository;
|
||||
public RoleAuthorityManager(RoleAuthorityMapper roleAuthorityMapper) {
|
||||
this.roleAuthorityMapper = roleAuthorityMapper;
|
||||
}
|
||||
|
||||
public void deleteByRoleId(Long roleId) {
|
||||
var affectedRows = roleAuthorityRepository.deleteByRoleId(roleId);
|
||||
log.info("角色 {} 关联的权限绑定已全部移除(共 {} 条)", roleId, affectedRows);
|
||||
var affectedRows = roleAuthorityMapper.deleteByRoleId(roleId);
|
||||
log.info("A total of {} authorities linked to Role ID: {} have been successfully cleared.",
|
||||
affectedRows, roleId);
|
||||
}
|
||||
|
||||
public void deleteByAuthorityId(Long authorityId) {
|
||||
var affectedRows = roleAuthorityMapper.deleteByAuthorityId(authorityId);
|
||||
log.info("The binding between {} authorities and the role has been cleared.", affectedRows);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,17 @@ package com.onixbyte.helix.manager;
|
||||
import com.onixbyte.helix.domain.database.query.wrapper.QueryRoleWrapper;
|
||||
import com.onixbyte.helix.domain.entity.Role;
|
||||
import com.onixbyte.helix.exception.BizException;
|
||||
import com.onixbyte.helix.mapper.RoleAuthorityMapper;
|
||||
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;
|
||||
|
||||
@@ -20,18 +22,18 @@ public class RoleManager {
|
||||
|
||||
private final RoleMapper roleMapper;
|
||||
private final RoleRepository roleRepository;
|
||||
private final RoleAuthorityMapper roleAuthorityMapper;
|
||||
private final MessageUtil messageUtil;
|
||||
|
||||
@Autowired
|
||||
public RoleManager(RoleMapper roleMapper, RoleRepository roleRepository, RoleAuthorityMapper roleAuthorityMapper) {
|
||||
public RoleManager(RoleMapper roleMapper, RoleRepository roleRepository, MessageUtil messageUtil) {
|
||||
this.roleMapper = roleMapper;
|
||||
this.roleRepository = roleRepository;
|
||||
this.roleAuthorityMapper = roleAuthorityMapper;
|
||||
this.messageUtil = messageUtil;
|
||||
}
|
||||
|
||||
public void validateRoles(List<Long> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,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) {
|
||||
|
||||
@@ -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)
|
||||
@@ -150,9 +151,9 @@ public class UserManager {
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public void updateUserPassword(ResetPasswordRequest request) {
|
||||
public void updatePasswordById(Long id, ResetPasswordRequest request) {
|
||||
userCredentialMapper.updateUserCredential(
|
||||
request.id(),
|
||||
id,
|
||||
passwordEncoder.encode(request.password())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.onixbyte.helix.manager;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.UserRole;
|
||||
import com.onixbyte.helix.domain.entity.embeddable.UserRoleId;
|
||||
import com.onixbyte.helix.mapper.UserRoleMapper;
|
||||
import com.onixbyte.helix.repository.UserRoleRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -15,12 +13,10 @@ import java.util.List;
|
||||
public class UserRoleManager {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(UserRoleManager.class);
|
||||
private final UserRoleMapper userRoleMapper;
|
||||
private final UserRoleRepository userRoleRepository;
|
||||
|
||||
@Autowired
|
||||
public UserRoleManager(UserRoleMapper userRoleMapper, UserRoleRepository userRoleRepository) {
|
||||
this.userRoleMapper = userRoleMapper;
|
||||
public UserRoleManager(UserRoleRepository userRoleRepository) {
|
||||
this.userRoleRepository = userRoleRepository;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,4 +7,6 @@ import org.apache.ibatis.annotations.Param;
|
||||
public interface RoleAuthorityMapper {
|
||||
|
||||
int deleteByRoleId(@Param("roleId") Long roleId);
|
||||
|
||||
int deleteByAuthorityId(@Param("authorityId") Long authorityId);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,16 @@ package com.onixbyte.helix.repository;
|
||||
|
||||
import com.onixbyte.helix.domain.entity.Authority;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface AuthorityRepository extends JpaRepository<Authority, Long> {
|
||||
|
||||
@Query("""
|
||||
select a.name
|
||||
from Authority a
|
||||
where a.id = :authorityId
|
||||
""")
|
||||
String findAuthorityNameById(Long authorityId);
|
||||
}
|
||||
|
||||
@@ -15,4 +15,6 @@ public interface DepartmentRepository extends JpaRepository<Department, Long> {
|
||||
or d.parentId = :parentId
|
||||
""")
|
||||
Integer findMaxSort(Long parentId);
|
||||
|
||||
boolean existsByName(String name);
|
||||
}
|
||||
|
||||
+5
-4
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -2,26 +2,28 @@ package com.onixbyte.helix.service;
|
||||
|
||||
import com.onixbyte.helix.domain.database.query.wrapper.QueryAuthorityWrapper;
|
||||
import com.onixbyte.helix.domain.entity.Authority;
|
||||
import com.onixbyte.helix.domain.web.request.AddAuthorityRequest;
|
||||
import com.onixbyte.helix.domain.web.request.EditAuthorityRequest;
|
||||
import com.onixbyte.helix.domain.web.request.AuthorityRequest;
|
||||
import com.onixbyte.helix.domain.web.request.QueryAuthorityRequest;
|
||||
import com.onixbyte.helix.enumeration.Status;
|
||||
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;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class AuthorityService {
|
||||
|
||||
private final AuthorityManager authorityManager;
|
||||
private final RoleAuthorityManager roleAuthorityManager;
|
||||
|
||||
public AuthorityService(AuthorityManager authorityManager) {
|
||||
public AuthorityService(AuthorityManager authorityManager, RoleAuthorityManager roleAuthorityManager) {
|
||||
this.authorityManager = authorityManager;
|
||||
this.roleAuthorityManager = roleAuthorityManager;
|
||||
}
|
||||
|
||||
public Page<Authority> getAuthorities(Pageable pageable, QueryAuthorityRequest request) {
|
||||
@@ -30,24 +32,40 @@ public class AuthorityService {
|
||||
return authorityManager.selectAll(pageable, wrapper);
|
||||
}
|
||||
|
||||
public Authority addAuthority(AddAuthorityRequest request) {
|
||||
public Authority addAuthority(AuthorityRequest request) {
|
||||
var authority = Authority.builder()
|
||||
.code(request.code())
|
||||
.name(request.name())
|
||||
.description(request.description())
|
||||
.status(Optional.ofNullable(request.status())
|
||||
.map(Status::valueOf)
|
||||
.orElse(Status.ACTIVE))
|
||||
.status(request.status())
|
||||
.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);
|
||||
}
|
||||
|
||||
public Authority editAuthority(EditAuthorityRequest request) {
|
||||
return authorityManager.update(request);
|
||||
public Authority editAuthority(Long id, AuthorityRequest request) {
|
||||
return authorityManager.fullUpdateById(id, Authority.builder()
|
||||
.name(request.name())
|
||||
.description(request.description())
|
||||
.status(request.status())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public String deleteAuthority(Long authorityId) {
|
||||
var authorityName = authorityManager.findAuthorityNameById(authorityId);
|
||||
|
||||
if (StringUtils.isBlank(authorityName)) {
|
||||
throw new BizException(HttpStatus.NOT_FOUND, MessageName.AUTHORITY_NOT_FOUND, authorityId);
|
||||
}
|
||||
|
||||
roleAuthorityManager.deleteByAuthorityId(authorityId);
|
||||
authorityManager.deleteById(authorityId);
|
||||
|
||||
return authorityName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package com.onixbyte.helix.service;
|
||||
|
||||
import com.onixbyte.helix.domain.common.TreeNode;
|
||||
import com.onixbyte.helix.domain.entity.Department;
|
||||
import com.onixbyte.helix.domain.web.request.AddDepartmentRequest;
|
||||
import com.onixbyte.helix.domain.web.request.DepartmentRequest;
|
||||
import com.onixbyte.helix.enumeration.Status;
|
||||
import com.onixbyte.helix.exception.BizException;
|
||||
import com.onixbyte.helix.manager.DepartmentManager;
|
||||
import com.onixbyte.helix.shared.MessageName;
|
||||
import com.onixbyte.helix.utils.TreeUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -35,9 +38,13 @@ public class DepartmentService {
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public Department addDepartment(AddDepartmentRequest request) {
|
||||
public Department addDepartment(DepartmentRequest request) {
|
||||
var createdAt = LocalDateTime.now();
|
||||
|
||||
if (departmentManager.existsByName(request.name())) {
|
||||
throw new BizException(HttpStatus.CONFLICT, MessageName.REQUEST_CREATE_DEPARTMENT_NAME_DUPLICATED);
|
||||
}
|
||||
|
||||
var parentId = request.parentId();
|
||||
var sort = Optional.ofNullable(request.sort())
|
||||
.orElseGet(() -> departmentManager.getNextSort(parentId));
|
||||
@@ -51,4 +58,17 @@ public class DepartmentService {
|
||||
.updatedAt(createdAt)
|
||||
.build());
|
||||
}
|
||||
|
||||
public Department editDepartment(Long id, DepartmentRequest request) {
|
||||
if (departmentManager.existsByName(request.name())) {
|
||||
throw new BizException(HttpStatus.CONFLICT, MessageName.REQUEST_CREATE_DEPARTMENT_NAME_DUPLICATED);
|
||||
}
|
||||
|
||||
return departmentManager.fullUpdateById(id, Department.builder()
|
||||
.name(request.name())
|
||||
.parentId(request.parentId())
|
||||
.sort(request.sort())
|
||||
.status(request.status())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import com.onixbyte.helix.domain.common.TreeNode;
|
||||
import com.onixbyte.helix.manager.MenuManager;
|
||||
import com.onixbyte.helix.utils.SecurityUtil;
|
||||
import com.onixbyte.helix.utils.TreeUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -14,7 +12,7 @@ import java.util.List;
|
||||
|
||||
@Service
|
||||
public class MenuService {
|
||||
private static final Logger log = LoggerFactory.getLogger(MenuService.class);
|
||||
|
||||
private final MenuManager menuManager;
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -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<Role> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,9 +143,9 @@ public class UserService {
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public void updateUser(EditUserRequest request) {
|
||||
public UserDetailResponse updateUser(Long id, EditUserRequest request) {
|
||||
userManager.updateUser(User.builder()
|
||||
.id(request.id())
|
||||
.id(id)
|
||||
.fullName(request.fullName())
|
||||
.email(request.email())
|
||||
.regionAbbreviation(request.regionAbbreviation())
|
||||
@@ -155,6 +155,8 @@ public class UserService {
|
||||
.departmentId(request.departmentId())
|
||||
.positionId(request.positionId())
|
||||
.build());
|
||||
|
||||
return getUserDetailByUserId(id);
|
||||
}
|
||||
|
||||
public UserDetailResponse getUserDetailByUserId(Long userId) {
|
||||
@@ -162,8 +164,8 @@ public class UserService {
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public void resetPassword(ResetPasswordRequest request) {
|
||||
userManager.updateUserPassword(request);
|
||||
public void resetPassword(Long id, ResetPasswordRequest request) {
|
||||
userManager.updatePasswordById(id, request);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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";
|
||||
|
||||
public static final String REQUEST_CREATE_DEPARTMENT_NAME_DUPLICATED = "request.create-department.name-duplicated";
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MessageUtil {
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
public MessageUtil(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
public String getMessage(String code, Object... args) {
|
||||
var locale = LocaleContextHolder.getLocale();
|
||||
return messageSource.getMessage(code, args, locale);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,6 +27,8 @@ spring:
|
||||
hikari:
|
||||
minimum-idle: 1
|
||||
maximum-pool-size: 10
|
||||
messages:
|
||||
basename: i18n/messages
|
||||
flyway:
|
||||
enabled: true
|
||||
baseline-on-migrate: true
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
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=Username or password is incorrect.
|
||||
|
||||
captcha.generate-failed = Unable to generate captcha image.
|
||||
role.not-exists=Name of the authority cannot be null.
|
||||
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.
|
||||
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.
|
||||
request.create-department.name-duplicated=Name of the department already exists.
|
||||
@@ -0,0 +1,77 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
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.
|
||||
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.
|
||||
request.create-department.name-duplicated=Name of the department already exists.
|
||||
@@ -0,0 +1,77 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
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}】删除成功。
|
||||
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。
|
||||
request.create-department.name-duplicated=部门名称已存在。
|
||||
@@ -2,7 +2,7 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.onixbyte.helix.mapper.AuthorityMapper">
|
||||
<select id="selectByUserId" parameterType="long">
|
||||
<select id="selectByUserId" parameterType="long" resultType="com.onixbyte.helix.domain.entity.Authority">
|
||||
SELECT DISTINCT a.id, a.code, a.name, a.description, a.status, a.created_at, a.updated_at
|
||||
FROM authority a
|
||||
JOIN role_authority ra ON a.id = ra.authority_id
|
||||
|
||||
@@ -7,4 +7,10 @@
|
||||
FROM role_authority
|
||||
WHERE role_id = #{roleId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteByAuthorityId" parameterType="long">
|
||||
DELETE
|
||||
FROM role_authority
|
||||
WHERE authority_id = #{authorityId}
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -52,7 +52,7 @@
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="count" parameterType="com.onixbyte.helix.domain.database.query.wrapper.QueryRoleWrapper">
|
||||
<select id="count" parameterType="com.onixbyte.helix.domain.database.query.wrapper.QueryRoleWrapper" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM role
|
||||
<where>
|
||||
|
||||
Reference in New Issue
Block a user