plusone-commons 重构,代码随之重构调整。
This commit is contained in:
parent
9293ba6817
commit
a0b16afde2
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
|||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认异常的处理器
|
* 默认异常的处理器
|
||||||
|
@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
|||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
import xyz.zhouxy.plusone.exception.SysException;
|
import xyz.zhouxy.plusone.exception.SysException;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package xyz.zhouxy.plusone.exception;
|
package xyz.zhouxy.plusone.exception;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.exception.BaseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 业务异常
|
* 业务异常
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package xyz.zhouxy.plusone.exception;
|
package xyz.zhouxy.plusone.exception;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.exception.BaseException;
|
||||||
|
|
||||||
public class SysException extends BaseException {
|
public class SysException extends BaseException {
|
||||||
@java.io.Serial
|
@java.io.Serial
|
||||||
private static final long serialVersionUID = 8821240827443168118L;
|
private static final long serialVersionUID = 8821240827443168118L;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package xyz.zhouxy.plusone.constant;
|
package xyz.zhouxy.plusone.constant;
|
||||||
|
|
||||||
import xyz.zhouxy.plusone.util.Enumeration;
|
import xyz.zhouxy.plusone.commons.util.Enumeration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体状态
|
* 实体状态
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package xyz.zhouxy.plusone.util;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class RegexUtil {
|
|
||||||
|
|
||||||
private RegexUtil() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean matches(CharSequence input, String regex) {
|
|
||||||
return Pattern.matches(regex, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean matchesOr(CharSequence input, String... regexs) {
|
|
||||||
boolean isMatched;
|
|
||||||
for (var regex : regexs) {
|
|
||||||
isMatched = Pattern.matches(regex, input);
|
|
||||||
if (isMatched) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean matchesAnd(CharSequence input, String... regexs) {
|
|
||||||
boolean isMatched;
|
|
||||||
for (var regex : regexs) {
|
|
||||||
isMatched = Pattern.matches(regex, input);
|
|
||||||
if (!isMatched) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,8 +15,8 @@ import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.util.NumberUtil;
|
||||||
import xyz.zhouxy.plusone.exception.DataOperationResultException;
|
import xyz.zhouxy.plusone.exception.DataOperationResultException;
|
||||||
import xyz.zhouxy.plusone.util.NumberUtil;
|
|
||||||
|
|
||||||
public abstract class PlusoneJdbcDaoSupport {
|
public abstract class PlusoneJdbcDaoSupport {
|
||||||
protected final NamedParameterJdbcTemplate jdbc;
|
protected final NamedParameterJdbcTemplate jdbc;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package xyz.zhouxy.plusone.validatortest;
|
package xyz.zhouxy.plusone.validatortest;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import xyz.zhouxy.plusone.constant.RegexConsts;
|
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
|
||||||
import xyz.zhouxy.plusone.validator.BaseValidator;
|
import xyz.zhouxy.plusone.validator.BaseValidator;
|
||||||
|
|
||||||
class BaseValidatorTest {
|
class BaseValidatorTest {
|
||||||
@ -34,11 +36,11 @@ class LoginCommandValidator extends BaseValidator<LoginCommand> {
|
|||||||
private LoginCommandValidator() {
|
private LoginCommandValidator() {
|
||||||
ruleForString(LoginCommand::getAccount)
|
ruleForString(LoginCommand::getAccount)
|
||||||
.notNull("邮箱地址不能为空")
|
.notNull("邮箱地址不能为空")
|
||||||
.matchesOr(new String[] { RegexConsts.EMAIL, RegexConsts.MOBILE_PHONE },
|
.matchesOr(new Pattern[] { PatternConsts.EMAIL, PatternConsts.MOBILE_PHONE },
|
||||||
value -> new RuntimeException('"' + value + "\" 不是邮箱地址或手机号"));
|
value -> new RuntimeException('"' + value + "\" 不是邮箱地址或手机号"));
|
||||||
ruleForString(LoginCommand::getPwd)
|
ruleForString(LoginCommand::getPwd)
|
||||||
.notNull("密码不能为空")
|
.notNull("密码不能为空")
|
||||||
.notEmpty("密码不能为空")
|
.notEmpty("密码不能为空")
|
||||||
.matches(RegexConsts.PASSWORD, "密码格式错误");
|
.matches(PatternConsts.PASSWORD, "密码格式错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package xyz.zhouxy.plusone.system.application.common.exception;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.exception.BizException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的 Principal 类型出现时抛出的异常
|
||||||
|
*
|
||||||
|
* @author <a href="https://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
|
||||||
|
*/
|
||||||
|
public class UnsupportedPrincipalTypeException extends BizException {
|
||||||
|
|
||||||
|
public static final int ERR_CODE = 4040201;
|
||||||
|
|
||||||
|
public UnsupportedPrincipalTypeException() {
|
||||||
|
super(ERR_CODE, "不支持的 PrincipalType");
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedPrincipalTypeException(String msg) {
|
||||||
|
super(ERR_CODE, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedPrincipalTypeException(Throwable cause) {
|
||||||
|
super(ERR_CODE, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedPrincipalTypeException(String msg, Throwable cause) {
|
||||||
|
super(ERR_CODE, msg, cause);
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,11 @@ package xyz.zhouxy.plusone.system.application.common.util;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.system.application.common.exception.UnsupportedPrincipalTypeException;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Principal;
|
import xyz.zhouxy.plusone.system.domain.model.account.Principal;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
||||||
import xyz.zhouxy.plusone.validator.InvalidInputException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据字面值,判断并生成 {@link Principal} 值对象。
|
* 根据字面值,判断并生成 {@link Principal} 值对象。
|
||||||
@ -16,7 +16,7 @@ import xyz.zhouxy.plusone.validator.InvalidInputException;
|
|||||||
* @see Username
|
* @see Username
|
||||||
* @see Email
|
* @see Email
|
||||||
* @see MobilePhone
|
* @see MobilePhone
|
||||||
* @see InvalidInputException
|
* @see UnsupportedPrincipalTypeException
|
||||||
*/
|
*/
|
||||||
public class PrincipalUtil {
|
public class PrincipalUtil {
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ public class PrincipalUtil {
|
|||||||
return principalType;
|
return principalType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw InvalidInputException.unsupportedPrincipalTypeException();
|
throw new UnsupportedPrincipalTypeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Principal getPrincipal(@Nullable String principal) {
|
public static Principal getPrincipal(@Nullable String principal) {
|
||||||
@ -48,7 +48,7 @@ public class PrincipalUtil {
|
|||||||
if (principalType == PrincipalType.USERNAME) {
|
if (principalType == PrincipalType.USERNAME) {
|
||||||
return Username.of(principal);
|
return Username.of(principal);
|
||||||
}
|
}
|
||||||
throw InvalidInputException.unsupportedPrincipalTypeException();
|
throw new UnsupportedPrincipalTypeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Principal getEmailOrMobilePhone(@Nullable String principal) {
|
public static Principal getEmailOrMobilePhone(@Nullable String principal) {
|
||||||
@ -59,6 +59,6 @@ public class PrincipalUtil {
|
|||||||
if (principalType == PrincipalType.MOBILE_PHONE) {
|
if (principalType == PrincipalType.MOBILE_PHONE) {
|
||||||
return MobilePhone.of(principal);
|
return MobilePhone.of(principal);
|
||||||
}
|
}
|
||||||
throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
throw new UnsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,10 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
import xyz.zhouxy.plusone.system.application.service.AccountContextService;
|
import xyz.zhouxy.plusone.system.application.service.AccountContextService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordCommand;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordWithoutLoginCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordWithoutLoginCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号查询本身相关信息
|
* 账号查询本身相关信息
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package xyz.zhouxy.plusone.system.application.controller;
|
package xyz.zhouxy.plusone.system.application.controller;
|
||||||
|
|
||||||
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
|
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
|
||||||
import static xyz.zhouxy.plusone.util.RestfulResult.success;
|
import static xyz.zhouxy.plusone.commons.util.RestfulResult.success;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -16,11 +16,11 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams;
|
import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams;
|
||||||
import xyz.zhouxy.plusone.system.application.service.AccountManagementService;
|
import xyz.zhouxy.plusone.system.application.service.AccountManagementService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.CreateAccountCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.CreateAccountCommand;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.UpdateAccountCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.UpdateAccountCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号管理
|
* 账号管理
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package xyz.zhouxy.plusone.system.application.controller;
|
package xyz.zhouxy.plusone.system.application.controller;
|
||||||
|
|
||||||
import static xyz.zhouxy.plusone.util.RestfulResult.success;
|
import static xyz.zhouxy.plusone.commons.util.RestfulResult.success;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import xyz.zhouxy.plusone.system.application.service.AdminLoginService;
|
import xyz.zhouxy.plusone.system.application.service.AdminLoginService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.LoginByOtpCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.LoginByOtpCommand;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.LoginByPasswordCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.LoginByPasswordCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin 账号登录
|
* Admin 账号登录
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package xyz.zhouxy.plusone.system.application.controller;
|
package xyz.zhouxy.plusone.system.application.controller;
|
||||||
|
|
||||||
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
|
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
|
||||||
import static xyz.zhouxy.plusone.util.RestfulResult.success;
|
import static xyz.zhouxy.plusone.commons.util.RestfulResult.success;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ import xyz.zhouxy.plusone.system.application.query.params.DictQueryParams;
|
|||||||
import xyz.zhouxy.plusone.system.application.service.DictManagementService;
|
import xyz.zhouxy.plusone.system.application.service.DictManagementService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.CreateDictCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.CreateDictCommand;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.UpdateDictCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.UpdateDictCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据字典管理
|
* 数据字典管理
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package xyz.zhouxy.plusone.system.application.controller;
|
package xyz.zhouxy.plusone.system.application.controller;
|
||||||
|
|
||||||
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
|
import static xyz.zhouxy.plusone.system.constant.AuthLogic.adminAuthLogic;
|
||||||
import static xyz.zhouxy.plusone.util.RestfulResult.success;
|
import static xyz.zhouxy.plusone.commons.util.RestfulResult.success;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import xyz.zhouxy.plusone.system.application.service.MenuManagementService;
|
import xyz.zhouxy.plusone.system.application.service.MenuManagementService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.CreateMenuCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.CreateMenuCommand;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.UpdateMenuCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.UpdateMenuCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单管理
|
* 菜单管理
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package xyz.zhouxy.plusone.system.application.controller;
|
package xyz.zhouxy.plusone.system.application.controller;
|
||||||
|
|
||||||
import static xyz.zhouxy.plusone.util.RestfulResult.success;
|
import static xyz.zhouxy.plusone.commons.util.RestfulResult.success;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
import xyz.zhouxy.plusone.system.application.service.RegisterAccountService;
|
import xyz.zhouxy.plusone.system.application.service.RegisterAccountService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.RegisterAccountCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.RegisterAccountCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册账号服务
|
* 注册账号服务
|
||||||
|
@ -17,7 +17,7 @@ import xyz.zhouxy.plusone.system.application.query.params.RoleQueryParams;
|
|||||||
import xyz.zhouxy.plusone.system.application.service.RoleManagementService;
|
import xyz.zhouxy.plusone.system.application.service.RoleManagementService;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.CreateRoleCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.CreateRoleCommand;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.UpdateRoleCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.UpdateRoleCommand;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色管理服务
|
* 角色管理服务
|
||||||
|
@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|||||||
|
|
||||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
||||||
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class AccountLoginExceptionHandler extends BaseExceptionHandler {
|
public class AccountLoginExceptionHandler extends BaseExceptionHandler {
|
||||||
|
@ -15,7 +15,7 @@ import cn.dev33.satoken.exception.SaTokenException;
|
|||||||
import cn.dev33.satoken.exception.SameTokenInvalidException;
|
import cn.dev33.satoken.exception.SameTokenInvalidException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
||||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
import xyz.zhouxy.plusone.commons.util.RestfulResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sa-Token 异常处理器
|
* Sa-Token 异常处理器
|
||||||
|
@ -4,10 +4,10 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.util.PageDTO;
|
||||||
import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams;
|
import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams;
|
||||||
import xyz.zhouxy.plusone.system.application.query.result.AccountDetails;
|
import xyz.zhouxy.plusone.system.application.query.result.AccountDetails;
|
||||||
import xyz.zhouxy.plusone.system.application.query.result.AccountOverview;
|
import xyz.zhouxy.plusone.system.application.query.result.AccountOverview;
|
||||||
import xyz.zhouxy.plusone.util.PageDTO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号信息查询器
|
* 账号信息查询器
|
||||||
|
@ -5,7 +5,7 @@ import java.time.LocalDate;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import xyz.zhouxy.plusone.util.PagingAndSortingQueryParams;
|
import xyz.zhouxy.plusone.commons.util.PagingAndSortingQueryParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号信息查询参数
|
* 账号信息查询参数
|
||||||
|
@ -4,7 +4,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import xyz.zhouxy.plusone.util.PagingAndSortingQueryParams;
|
import xyz.zhouxy.plusone.commons.util.PagingAndSortingQueryParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据字典查询参数
|
* 数据字典查询参数
|
||||||
|
@ -5,7 +5,7 @@ import java.time.LocalDate;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import xyz.zhouxy.plusone.util.PagingAndSortingQueryParams;
|
import xyz.zhouxy.plusone.commons.util.PagingAndSortingQueryParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色信息查询参数
|
* 角色信息查询参数
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package xyz.zhouxy.plusone.system.application.service;
|
package xyz.zhouxy.plusone.system.application.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
@ -9,6 +8,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import cn.dev33.satoken.stp.StpLogic;
|
import cn.dev33.satoken.stp.StpLogic;
|
||||||
|
import xyz.zhouxy.plusone.system.application.common.exception.UnsupportedPrincipalTypeException;
|
||||||
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
|
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
|
||||||
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
||||||
import xyz.zhouxy.plusone.system.application.query.AccountQueries;
|
import xyz.zhouxy.plusone.system.application.query.AccountQueries;
|
||||||
@ -23,7 +23,6 @@ import xyz.zhouxy.plusone.system.domain.model.account.AccountRepository;
|
|||||||
import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Principal;
|
import xyz.zhouxy.plusone.system.domain.model.account.Principal;
|
||||||
import xyz.zhouxy.plusone.validator.InvalidInputException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号对当前帐号进行操作
|
* 账号对当前帐号进行操作
|
||||||
@ -91,13 +90,14 @@ public class AccountContextService {
|
|||||||
public void changePasswordByOtp(ChangePasswordByOtpCommand command) {
|
public void changePasswordByOtp(ChangePasswordByOtpCommand command) {
|
||||||
|
|
||||||
var principal = command.getAccount();
|
var principal = command.getAccount();
|
||||||
Optional<Account> account = switch (command.getPrincipalType()) {
|
boolean accountExists = switch (command.getPrincipalType()) {
|
||||||
case EMAIL -> accountRepository.findByEmail(Email.of(principal));
|
case EMAIL -> accountRepository.existsEmail(Email.of(principal));
|
||||||
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
|
case MOBILE_PHONE -> accountRepository.existsMobilePhone(MobilePhone.of(principal));
|
||||||
default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
default -> throw new UnsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
||||||
};
|
};
|
||||||
account.orElseThrow(AccountLoginException::accountNotExistException);
|
if (accountExists) {
|
||||||
|
throw AccountLoginException.accountNotExistException();
|
||||||
|
}
|
||||||
mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
|
mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.util.PageDTO;
|
||||||
import xyz.zhouxy.plusone.exception.DataNotExistException;
|
import xyz.zhouxy.plusone.exception.DataNotExistException;
|
||||||
import xyz.zhouxy.plusone.system.application.exception.AccountRegisterException;
|
import xyz.zhouxy.plusone.system.application.exception.AccountRegisterException;
|
||||||
import xyz.zhouxy.plusone.system.application.query.AccountQueries;
|
import xyz.zhouxy.plusone.system.application.query.AccountQueries;
|
||||||
@ -29,7 +30,6 @@ import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
|||||||
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
||||||
import xyz.zhouxy.plusone.util.AssertResult;
|
import xyz.zhouxy.plusone.util.AssertResult;
|
||||||
import xyz.zhouxy.plusone.util.PageDTO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号管理
|
* 账号管理
|
||||||
|
@ -6,6 +6,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import xyz.zhouxy.plusone.system.application.common.exception.UnsupportedPrincipalTypeException;
|
||||||
import xyz.zhouxy.plusone.system.application.common.util.PrincipalType;
|
import xyz.zhouxy.plusone.system.application.common.util.PrincipalType;
|
||||||
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
|
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
|
||||||
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
||||||
@ -18,7 +19,6 @@ import xyz.zhouxy.plusone.system.domain.model.account.AccountRepository;
|
|||||||
import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
import xyz.zhouxy.plusone.system.domain.model.account.Email;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
||||||
import xyz.zhouxy.plusone.validator.InvalidInputException;
|
|
||||||
import xyz.zhouxy.plusone.validator.ValidateDto;
|
import xyz.zhouxy.plusone.validator.ValidateDto;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +63,7 @@ public class AdminLoginService {
|
|||||||
Account account = (switch (command.getPrincipalType()) {
|
Account account = (switch (command.getPrincipalType()) {
|
||||||
case EMAIL -> accountRepository.findByEmail(Email.of(principal));
|
case EMAIL -> accountRepository.findByEmail(Email.of(principal));
|
||||||
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
|
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
|
||||||
default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
default -> throw new UnsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
||||||
}).orElseThrow(AccountLoginException::accountNotExistException);
|
}).orElseThrow(AccountLoginException::accountNotExistException);
|
||||||
|
|
||||||
mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
|
mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
|
||||||
|
@ -5,6 +5,7 @@ import java.util.Set;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.system.application.common.exception.UnsupportedPrincipalTypeException;
|
||||||
import xyz.zhouxy.plusone.system.application.common.util.PrincipalType;
|
import xyz.zhouxy.plusone.system.application.common.util.PrincipalType;
|
||||||
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
|
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
|
||||||
import xyz.zhouxy.plusone.system.application.exception.AccountRegisterException;
|
import xyz.zhouxy.plusone.system.application.exception.AccountRegisterException;
|
||||||
@ -18,7 +19,6 @@ import xyz.zhouxy.plusone.system.domain.model.account.MobilePhone;
|
|||||||
import xyz.zhouxy.plusone.system.domain.model.account.Password;
|
import xyz.zhouxy.plusone.system.domain.model.account.Password;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Sex;
|
import xyz.zhouxy.plusone.system.domain.model.account.Sex;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
import xyz.zhouxy.plusone.system.domain.model.account.Username;
|
||||||
import xyz.zhouxy.plusone.validator.InvalidInputException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册账号服务
|
* 注册账号服务
|
||||||
@ -70,7 +70,7 @@ public class RegisterAccountService {
|
|||||||
throw AccountRegisterException.emailAlreadyExists(mobilePhone.value());
|
throw AccountRegisterException.emailAlreadyExists(mobilePhone.value());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw InvalidInputException.unsupportedPrincipalTypeException();
|
throw new UnsupportedPrincipalTypeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyService.checkCode(emailOrMobilePhone, command.getCode());
|
verifyService.checkCode(emailOrMobilePhone, command.getCode());
|
||||||
@ -93,7 +93,7 @@ public class RegisterAccountService {
|
|||||||
} else if (principalType == PrincipalType.MOBILE_PHONE) {
|
} else if (principalType == PrincipalType.MOBILE_PHONE) {
|
||||||
verifyService.sendCodeToMobilePhone(MobilePhone.of(principal));
|
verifyService.sendCodeToMobilePhone(MobilePhone.of(principal));
|
||||||
} else {
|
} else {
|
||||||
throw InvalidInputException.unsupportedPrincipalTypeException();
|
throw new UnsupportedPrincipalTypeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import xyz.zhouxy.plusone.constant.RegexConsts;
|
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.LoginByOtpCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.LoginByOtpCommand;
|
||||||
import xyz.zhouxy.plusone.validator.BaseValidator;
|
import xyz.zhouxy.plusone.validator.BaseValidator;
|
||||||
import xyz.zhouxy.plusone.validator.DtoValidator;
|
import xyz.zhouxy.plusone.validator.DtoValidator;
|
||||||
@ -16,10 +16,10 @@ public class LoginByOtpCommandValidator extends BaseValidator<LoginByOtpCommand>
|
|||||||
ruleForString(LoginByOtpCommand::getPrincipal)
|
ruleForString(LoginByOtpCommand::getPrincipal)
|
||||||
.notNull("输入邮箱地址或手机号")
|
.notNull("输入邮箱地址或手机号")
|
||||||
.notEmpty("输入邮箱地址或手机号")
|
.notEmpty("输入邮箱地址或手机号")
|
||||||
.matchesOr(List.of(RegexConsts.EMAIL, RegexConsts.MOBILE_PHONE), "输入用户名、邮箱地址或手机号");
|
.matchesOr(List.of(PatternConsts.EMAIL, PatternConsts.MOBILE_PHONE), "输入用户名、邮箱地址或手机号");
|
||||||
ruleForString(LoginByOtpCommand::getOtp)
|
ruleForString(LoginByOtpCommand::getOtp)
|
||||||
.notNull("验证码不能为空")
|
.notNull("验证码不能为空")
|
||||||
.notEmpty("验证码不能为空")
|
.notEmpty("验证码不能为空")
|
||||||
.matches(RegexConsts.CAPTCHA, "验证码格式不正确");
|
.matches(PatternConsts.CAPTCHA, "验证码格式不正确");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ package xyz.zhouxy.plusone.system.application.service.command.validator;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import xyz.zhouxy.plusone.constant.RegexConsts;
|
|
||||||
|
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
|
||||||
import xyz.zhouxy.plusone.system.application.service.command.LoginByPasswordCommand;
|
import xyz.zhouxy.plusone.system.application.service.command.LoginByPasswordCommand;
|
||||||
import xyz.zhouxy.plusone.validator.BaseValidator;
|
import xyz.zhouxy.plusone.validator.BaseValidator;
|
||||||
import xyz.zhouxy.plusone.validator.DtoValidator;
|
import xyz.zhouxy.plusone.validator.DtoValidator;
|
||||||
@ -14,11 +15,11 @@ public class LoginByPasswordCommandValidator extends BaseValidator<LoginByPasswo
|
|||||||
ruleForString(LoginByPasswordCommand::getPrincipal)
|
ruleForString(LoginByPasswordCommand::getPrincipal)
|
||||||
.notNull("输入用户名、邮箱地址或手机号")
|
.notNull("输入用户名、邮箱地址或手机号")
|
||||||
.notEmpty("输入用户名、邮箱地址或手机号")
|
.notEmpty("输入用户名、邮箱地址或手机号")
|
||||||
.matchesOr(List.of(RegexConsts.USERNAME, RegexConsts.EMAIL, RegexConsts.MOBILE_PHONE),
|
.matchesOr(List.of(PatternConsts.USERNAME, PatternConsts.EMAIL, PatternConsts.MOBILE_PHONE),
|
||||||
"输入用户名、邮箱地址或手机号");
|
"输入用户名、邮箱地址或手机号");
|
||||||
ruleForString(LoginByPasswordCommand::getPassword)
|
ruleForString(LoginByPasswordCommand::getPassword)
|
||||||
.notNull("密码不能为空")
|
.notNull("密码不能为空")
|
||||||
.notEmpty("密码不能为空")
|
.notEmpty("密码不能为空")
|
||||||
.matches(RegexConsts.PASSWORD, "密码格式不正确");
|
.matches(PatternConsts.PASSWORD, "密码格式不正确");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package xyz.zhouxy.plusone.system.domain.model.account;
|
package xyz.zhouxy.plusone.system.domain.model.account;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import xyz.zhouxy.plusone.commons.util.Enumeration;
|
||||||
import xyz.zhouxy.plusone.domain.IValueObject;
|
import xyz.zhouxy.plusone.domain.IValueObject;
|
||||||
import xyz.zhouxy.plusone.util.Enumeration;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号状态
|
* 账号状态
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package xyz.zhouxy.plusone.system.domain.model.account;
|
package xyz.zhouxy.plusone.system.domain.model.account;
|
||||||
|
|
||||||
|
import xyz.zhouxy.plusone.commons.util.Enumeration;
|
||||||
import xyz.zhouxy.plusone.domain.IValueObject;
|
import xyz.zhouxy.plusone.domain.IValueObject;
|
||||||
import xyz.zhouxy.plusone.util.Enumeration;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 值对象:性别
|
* 值对象:性别
|
||||||
|
@ -17,12 +17,12 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import xyz.zhouxy.plusone.commons.util.EnumUtil;
|
||||||
import xyz.zhouxy.plusone.constant.EntityStatus;
|
import xyz.zhouxy.plusone.constant.EntityStatus;
|
||||||
import xyz.zhouxy.plusone.exception.DataNotExistException;
|
import xyz.zhouxy.plusone.exception.DataNotExistException;
|
||||||
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
|
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
|
||||||
import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
|
import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
|
||||||
import xyz.zhouxy.plusone.util.AssertResult;
|
import xyz.zhouxy.plusone.util.AssertResult;
|
||||||
import xyz.zhouxy.plusone.util.EnumUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MenuRepository 实现类
|
* MenuRepository 实现类
|
||||||
|
10
pom.xml
10
pom.xml
@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@ -28,7 +27,7 @@
|
|||||||
|
|
||||||
<spring-boot.version>2.7.8</spring-boot.version>
|
<spring-boot.version>2.7.8</spring-boot.version>
|
||||||
<sa-token.version>1.34.0</sa-token.version>
|
<sa-token.version>1.34.0</sa-token.version>
|
||||||
<hutool.version>5.8.11</hutool.version>
|
<hutool.version>5.8.12</hutool.version>
|
||||||
<mybatis-starter.version>3.0.1</mybatis-starter.version>
|
<mybatis-starter.version>3.0.1</mybatis-starter.version>
|
||||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||||
<commons-io.version>2.11.0</commons-io.version>
|
<commons-io.version>2.11.0</commons-io.version>
|
||||||
@ -87,11 +86,6 @@
|
|||||||
<version>${mybatis-plus.version}</version>
|
<version>${mybatis-plus.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.hutool</groupId>
|
|
||||||
<artifactId>hutool-all</artifactId>
|
|
||||||
<version>${hutool.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-core</artifactId>
|
<artifactId>hutool-core</artifactId>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user