feat: add department name uniqueness check and corresponding error message
This commit is contained in:
@@ -44,40 +44,13 @@ public class BizException extends RuntimeException {
|
||||
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);
|
||||
this.status = HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
this.messageCode = null;
|
||||
this.messageArgs = new Object[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.onixbyte.helix.manager;
|
||||
import com.onixbyte.helix.domain.entity.Department;
|
||||
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;
|
||||
@@ -68,4 +70,8 @@ public class DepartmentManager {
|
||||
departmentToEdit.setUpdatedAt(updatedAt);
|
||||
return departmentToEdit;
|
||||
}
|
||||
|
||||
public boolean existsByName(String name) {
|
||||
return departmentRepository.existsByName(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,6 @@ public interface DepartmentRepository extends JpaRepository<Department, Long> {
|
||||
or d.parentId = :parentId
|
||||
""")
|
||||
Integer findMaxSort(Long parentId);
|
||||
|
||||
boolean existsByName(String name);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@ import com.onixbyte.helix.domain.common.TreeNode;
|
||||
import com.onixbyte.helix.domain.entity.Department;
|
||||
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;
|
||||
|
||||
@@ -38,6 +41,10 @@ public class DepartmentService {
|
||||
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));
|
||||
|
||||
@@ -79,4 +79,6 @@ public class MessageName {
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
@@ -19,28 +19,58 @@
|
||||
# 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -74,3 +74,4 @@ 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.
|
||||
|
||||
@@ -74,3 +74,4 @@ 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=部门名称已存在。
|
||||
|
||||
Reference in New Issue
Block a user