28 Commits

Author SHA1 Message Date
16b1cb62d3 Merge remote-tracking branch 'origin/feature/menu-mng' into feature/menu-mng 2023-04-15 22:06:34 +08:00
e9fe187c43 添加 TODO 2023-04-15 05:24:49 +08:00
6ba7d9b906 修改对 TencentCloudSDKException 的处理。 2023-04-15 05:24:48 +08:00
e4b06d8b2d 应抛出 SysException。 2023-04-15 05:24:48 +08:00
fcdf69026f 简化、重构代码。修复错误。 2023-04-15 05:24:48 +08:00
4e4debaec9 添加查询 2023-04-15 05:24:48 +08:00
0e0d6f1808 plusone-commons 做了调整。 2023-04-15 05:24:03 +08:00
0dc78a2b89 添加 TODO 2023-04-04 01:08:08 +08:00
7ef0776296 修改对 TencentCloudSDKException 的处理。 2023-04-04 00:55:04 +08:00
b2bc6b3a6f 应抛出 SysException。 2023-04-04 00:54:15 +08:00
b6301d2dc9 简化、重构代码。修复错误。 2023-04-04 00:48:22 +08:00
e59dc804ab 添加查询 2023-04-04 00:33:54 +08:00
06ffc8d858 避免实例化。 2023-04-04 00:32:25 +08:00
60b4f18e8c 更改 hutool 版本。 2023-04-04 00:27:53 +08:00
2b282039ad 更新 plusone-validator 和 plusone-exception-handler。 2023-04-04 00:24:31 +08:00
67313938e1 提交代码。 2023-03-28 15:41:15 +08:00
27be582bfb 升级 Spring Boot 版本。 2023-03-28 15:40:49 +08:00
288ce9689f postgresql:42.3.8 依赖 checker-qual:3.5.0,将 guava 的版本更改为 30.1-jre,避免依赖冲突。 2023-03-21 15:52:38 +08:00
71edaa60a4 整理依赖。 2023-03-17 18:46:39 +08:00
39cd57e675 使用原生哈希算法。使用自己实现的随机盐生成方法。 2023-03-17 18:46:06 +08:00
7a44c43402 使用原生 UUID。 2023-03-17 18:44:51 +08:00
55395ed327 自己实现随机字符串的生成。 2023-03-17 18:44:33 +08:00
956da350ed 更改 plusone-exception-handler 版本。 2023-03-17 18:43:24 +08:00
78cdded667 int 数组的值总和可能大于 int 的最大值,使用 long 类型的变量存储其结果。 2023-03-17 18:42:43 +08:00
cc3c4be8de 升级 hutool。 2023-03-14 18:10:02 +08:00
1e31e1f327 使用 Integer 接收前端的参数,而不是枚举类。 2023-03-14 10:51:11 +08:00
993ba7fa7b 枚举类不允许继承。 2023-03-12 13:44:28 +08:00
8ae0faa04d 优化正则的使用。 2023-03-12 13:42:08 +08:00
48 changed files with 278 additions and 224 deletions

View File

@@ -44,12 +44,12 @@
<dependency>
<groupId>xyz.zhouxy.plusone</groupId>
<artifactId>plusone-validator</artifactId>
<version>0.1.2-SNAPSHOT</version>
<version>0.1.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>xyz.zhouxy.plusone</groupId>
<artifactId>plusone-exception-handler</artifactId>
<version>0.0.6-SNAPSHOT</version>
<version>0.0.8-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -2,4 +2,8 @@ package xyz.zhouxy.plusone.constant;
public class ErrorCodeConsts {
public static final int DEFAULT_ERROR_CODE = 9999999;
private ErrorCodeConsts() {
throw new IllegalStateException("Utility class");
}
}

View File

@@ -0,0 +1,18 @@
package xyz.zhouxy.plusone.util;
import java.util.concurrent.ThreadLocalRandom;
public final class RandomUtil {
private RandomUtil() {
throw new IllegalStateException("Utility class");
}
public static String randomStr(char[] sourceCharacters, int length) {
ThreadLocalRandom random = ThreadLocalRandom.current();
char[] result = new char[length];
for (int i = 0; i < length; i++) {
result[i] = sourceCharacters[random.nextInt(sourceCharacters.length)];
}
return String.valueOf(result);
}
}

View File

@@ -0,0 +1,23 @@
package xyz.zhouxy.plusone.util;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class RandomUtilTests {
@Test
void testRandom() {
String[] s = new String[20];
for (int i = 0; i < 20; i++) {
s[i] = RandomUtil.randomStr(
"0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM~`!@#$%^&*()_-+={[\\|/:;\"',.<>?]}"
.toCharArray(),
28);
}
log.info("{}", Arrays.toString(s));
}
}

View File

@@ -15,11 +15,6 @@
<groupId>xyz.zhouxy</groupId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@@ -1,5 +1,9 @@
package xyz.zhouxy.plusone.constant;
import java.util.Collection;
import javax.annotation.Nonnull;
import xyz.zhouxy.plusone.commons.util.Enumeration;
/**
@@ -7,26 +11,26 @@ import xyz.zhouxy.plusone.commons.util.Enumeration;
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public class EntityStatus extends Enumeration<EntityStatus> {
public final class EntityStatus extends Enumeration<EntityStatus> {
private EntityStatus(int value, String name) {
super(value, name);
private EntityStatus(int id, @Nonnull String name) {
super(id, name);
}
// 常量
public static final EntityStatus AVAILABLE = new EntityStatus(0, "正常");
public static final EntityStatus DISABLED = new EntityStatus(1, "禁用");
private static final EnumerationValuesHolder<EntityStatus> ENUMERATION_VALUES = new EnumerationValuesHolder<>(
AVAILABLE,
DISABLED);
private static final ValueSet<EntityStatus> VALUE_SET = new ValueSet<>(
AVAILABLE, DISABLED);
public static EntityStatus of(int value) {
return ENUMERATION_VALUES.get(value);
@Nonnull
public static EntityStatus of(int id) {
return VALUE_SET.get(id);
}
@Override
public String toString() {
return "EntityStatus" + super.toString();
@Nonnull
public static Collection<EntityStatus> constants() {
return VALUE_SET.getValues();
}
}

View File

@@ -1,27 +0,0 @@
package xyz.zhouxy.plusone.constant;
/**
* 正则表达式常量
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public final class RegexConsts {
public static final String DATE = "^\\d{4}-\\d{2}-\\d{2}";
public static final String PASSWORD = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[\\w\\\\!#$%&'*\\+\\-/=?^`{|}~@\\(\\)\\[\\]\",\\.;':><]{8,32}$";
public static final String CAPTCHA = "^[0-9A-Za-z]{4,6}$";
public static final String EMAIL = "^\\w+([-+.]\\w+)*@[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*(\\.(?![0-9]+$)[a-zA-Z0-9][-0-9A-Za-z]{0,62})$";
public static final String MOBILE_PHONE = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
public static final String USERNAME = "^[\\da-zA-Z_.@\\\\]{4,36}$";
public static final String NICKNAME = "^[\\da-zA-Z_.@\\\\]{4,36}$";
private RegexConsts() {
throw new IllegalStateException("Utility class");
}
}

View File

@@ -1,6 +1,7 @@
package xyz.zhouxy.plusone.domain;
import cn.hutool.core.lang.UUID;
import java.util.UUID;
import lombok.Getter;
/**
@@ -20,7 +21,7 @@ public abstract class DomainEvent {
private long happenedAt;
protected DomainEvent() {
this.identifier = UUID.randomUUID().toString(true);
this.identifier = UUID.randomUUID().toString();
this.happenedAt = System.currentTimeMillis();
}
}

View File

@@ -1,6 +1,7 @@
package xyz.zhouxy.plusone.domain;
import java.util.Optional;
import java.util.regex.Pattern;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;
@@ -13,15 +14,15 @@ import com.fasterxml.jackson.annotation.JsonValue;
public abstract class ValidatableStringRecord implements IValueObject {
protected String value;
protected final String format;
protected final Pattern format;
protected ValidatableStringRecord(String format) {
protected ValidatableStringRecord(Pattern format) {
this.format = format;
}
@JsonIgnore
protected boolean isValid() {
return value.matches(format);
return format.matcher(value).matches();
}
@JsonValue

View File

@@ -86,18 +86,18 @@ public abstract class PlusoneJdbcDaoSupport {
return update(sql, new MapSqlParameterSource(paramName, value));
}
protected final int batchUpdate(String sql, SqlParameterSource[] batchArgs) {
protected final long batchUpdate(String sql, SqlParameterSource[] batchArgs) {
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
return NumberUtil.sum(i);
}
protected final <T> int batchUpdate(String sql, Stream<T> c,
protected final <T> long batchUpdate(String sql, Stream<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
int[] i = this.jdbc.batchUpdate(sql, buildSqlParameterSourceArray(c, paramSourceBuilder));
return NumberUtil.sum(i);
}
protected final <T> int batchUpdate(String sql, Collection<T> c,
protected final <T> long batchUpdate(String sql, Collection<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
int[] i = this.jdbc.batchUpdate(sql, buildSqlParameterSourceArray(c, paramSourceBuilder));
return NumberUtil.sum(i);

View File

@@ -1,5 +1,7 @@
package xyz.zhouxy.plusone.sms;
import org.springframework.stereotype.Service;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
@@ -8,11 +10,8 @@ import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import xyz.zhouxy.plusone.constant.ErrorCodeConsts;
import xyz.zhouxy.plusone.exception.BizException;
import xyz.zhouxy.plusone.exception.SysException;
import xyz.zhouxy.plusone.sms.SmsProperties.SmsCredentialProperties;
import xyz.zhouxy.plusone.sms.SmsProperties.SmsHttpProperties;
import xyz.zhouxy.plusone.sms.SmsProperties.SmsProxyProperties;
@@ -62,14 +61,13 @@ public class TencentSmsServiceImpl implements SmsService {
var res = client.SendSms(req);
// 输出json格式的字符串回包
System.out.println(SendSmsResponse.toJsonString(res));
log.info(SendSmsResponse.toJsonString(res));
// 也可以取出单个值你可以通过官网接口文档或跳转到response对象的定义处查看返回字段的定义
// System.out.println(res.getRequestId());
} catch (TencentCloudSDKException e) {
log.error(e.getMessage(), e);
throw new BizException(ErrorCodeConsts.DEFAULT_ERROR_CODE, e);
throw new SysException(e);
}
}

View File

@@ -1,5 +1,7 @@
package xyz.zhouxy.plusone;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import javax.annotation.Resource;
import org.junit.jupiter.api.Test;
@@ -25,6 +27,7 @@ class TestAop {
command.setPrincipal("Code108");
command.setPassword("2333");
command.setRememberMe(false);
assertNotNull(service);
LoginInfoViewObject loginInfo = service.loginByPassword(command);
System.err.println(loginInfo);
}

View File

@@ -1,18 +1,20 @@
package xyz.zhouxy.plusone.system.application.common.util;
import java.util.regex.Pattern;
import lombok.Getter;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
public enum PrincipalType {
EMAIL(RegexConsts.EMAIL),
MOBILE_PHONE(RegexConsts.MOBILE_PHONE),
USERNAME(RegexConsts.USERNAME)
EMAIL(PatternConsts.EMAIL),
MOBILE_PHONE(PatternConsts.MOBILE_PHONE),
USERNAME(PatternConsts.USERNAME)
;
@Getter
private final String regex;
private final Pattern regex;
PrincipalType(String regex) {
PrincipalType(Pattern regex) {
this.regex = regex;
}
}

View File

@@ -30,7 +30,7 @@ public class PrincipalUtil {
}
PrincipalType[] principalTypes = PrincipalType.values();
for (var principalType : principalTypes) {
if (principal.matches(principalType.getRegex())) {
if (principalType.getRegex().matcher(principal).matches()) {
return principalType;
}
}

View File

@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import xyz.zhouxy.plusone.system.application.query.params.MenuQueryParams;
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.UpdateMenuCommand;
@@ -66,7 +67,14 @@ public class MenuManagementController {
public RestfulResult findById(@PathVariable("id") Long id) {
adminAuthLogic.checkPermission("sys-menu-details");
var result = service.findById(id);
return RestfulResult.success("查询成功", result);
return success("查询成功", result);
}
@GetMapping
public RestfulResult queryMenuTree(MenuQueryParams queryParams) {
adminAuthLogic.checkPermission("sys-menu-query");
var result = service.queryMenuTree(queryParams);
return success("查询成功", result);
}
@GetMapping("queryByAccountId")

View File

@@ -0,0 +1,23 @@
package xyz.zhouxy.plusone.system.application.query;
import java.util.List;
import org.springframework.stereotype.Component;
import xyz.zhouxy.plusone.system.application.query.params.MenuQueryParams;
import xyz.zhouxy.plusone.system.application.query.result.MenuViewObject;
/**
*
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
@Component
public class MenuQueries {
public List<MenuViewObject> queryMenuTree(MenuQueryParams queryParams) {
// TODO【添加】 实现该查询
return null;
}
}

View File

@@ -1,10 +0,0 @@
package xyz.zhouxy.plusone.system.application.query;
/**
*
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public interface PermissionQueries {
// TODO【添加】 权限信息查询器
}

View File

@@ -0,0 +1,18 @@
package xyz.zhouxy.plusone.system.application.query.params;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import xyz.zhouxy.plusone.constant.EntityStatus;
@ToString
public class MenuQueryParams {
private @Getter @Setter String name;
private @Getter @Setter String path;
private @Getter @Setter String title;
private @Getter @Setter Boolean hidden;
private @Getter @Setter EntityStatus status;
private @Getter @Setter String component;
private @Getter @Setter Boolean cache;
private @Getter @Setter String resource;
}

View File

@@ -25,60 +25,28 @@ import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MenuViewObject implements IWithOrderNumber {
@Getter
@Setter
Integer type;
private @Getter @Setter Integer type;
@Getter
@Setter
String typeName;
private @Getter @Setter String typeName;
@Getter
@Setter
Long id;
@Getter
@Setter
Long parentId;
private @Getter @Setter Long id;
private @Getter @Setter Long parentId;
@Getter
@Setter
String name;
private @Getter @Setter String name;
// 若 type 为 MENU_ITEM 且 path 以 http:// 或 https:// 开头则被识别为外链
@Getter
@Setter
String path;
@Getter
@Setter
String title;
@Getter
@Setter
String icon;
@Getter
@Setter
boolean hidden;
@Getter
@Setter
int orderNumber;
@Getter
@Setter
Integer status;
@Getter
@Setter
String remarks;
private @Getter @Setter String path;
private @Getter @Setter String title;
private @Getter @Setter String icon;
private @Getter @Setter boolean hidden;
private @Getter @Setter int orderNumber;
private @Getter @Setter Integer status;
private @Getter @Setter String remarks;
// MENU_ITEM
@Getter
@Setter
String component;
@Getter
@Setter
Boolean cache;
@Getter
@Setter
String resource;
@Getter
@Setter
List<Action> actions;
private @Getter @Setter String component;
private @Getter @Setter Boolean cache;
private @Getter @Setter String resource;
private @Getter @Setter List<Action> actions;
// MENU_LIST
List<MenuViewObject> children;
@@ -109,7 +77,7 @@ public class MenuViewObject implements IWithOrderNumber {
viewObject.icon = menu.getIcon();
viewObject.hidden = menu.isHidden();
viewObject.orderNumber = menu.getOrderNumber();
viewObject.status = menu.getStatus().getValue();
viewObject.status = menu.getStatus().getId();
viewObject.remarks = menu.getRemarks();
if (viewObject.type == MenuType.MENU_ITEM.ordinal()) {
viewObject.component = menu.getComponent();

View File

@@ -26,8 +26,10 @@ import xyz.zhouxy.plusone.system.application.service.command.UpdateAccountComman
import xyz.zhouxy.plusone.system.domain.model.account.Account;
import xyz.zhouxy.plusone.system.domain.model.account.AccountInfo;
import xyz.zhouxy.plusone.system.domain.model.account.AccountRepository;
import xyz.zhouxy.plusone.system.domain.model.account.AccountStatus;
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.Sex;
import xyz.zhouxy.plusone.system.domain.model.account.Username;
import xyz.zhouxy.plusone.util.AssertResult;
@@ -67,12 +69,12 @@ public class AccountManagementService {
mobilePhone,
command.getPassword(),
command.getPasswordConfirmation(),
command.getStatus(),
AccountStatus.of(command.getStatus()),
command.getRoleRefs(),
AccountInfo.builder()
.nickname(command.getNickname())
.avatar(command.getAvatar())
.sex(command.getSex())
.sex(Sex.of(command.getSex()))
.build(),
adminAuthLogic.getLoginIdAsLong());
accountRepository.save(account);
@@ -91,7 +93,7 @@ public class AccountManagementService {
Assert.isTrue(Objects.equals(id, command.getId()), "参数错误: id 不匹配");
Account account = accountRepository.find(id)
.orElseThrow(() -> new DataNotExistException("该账号不存在"));
account.setAccountInfo(command.getNickname(), command.getAvatar(), command.getSex());
account.setAccountInfo(command.getNickname(), command.getAvatar(), Sex.of(command.getSex()));
account.setUpdatedBy(adminAuthLogic.getLoginIdAsLong());
accountRepository.save(account);
}

View File

@@ -13,9 +13,12 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.domain.IWithOrderNumber;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.system.application.exception.UnsupportedMenuTypeException;
import xyz.zhouxy.plusone.system.application.query.MenuQueries;
import xyz.zhouxy.plusone.system.application.query.params.MenuQueryParams;
import xyz.zhouxy.plusone.system.application.query.result.MenuViewObject;
import xyz.zhouxy.plusone.system.application.service.command.CreateMenuCommand;
import xyz.zhouxy.plusone.system.application.service.command.UpdateMenuCommand;
@@ -35,10 +38,12 @@ public class MenuManagementService {
private final MenuService menuService;
private final MenuRepository menuRepository;
private final MenuQueries menuQueries;
MenuManagementService(MenuService roleRepository, MenuRepository menuRepository) {
this.menuService = roleRepository;
MenuManagementService(MenuService menuService, MenuRepository menuRepository, MenuQueries menuQueries) {
this.menuService = menuService;
this.menuRepository = menuRepository;
this.menuQueries = menuQueries;
}
// ==================== create ====================
@@ -66,7 +71,7 @@ public class MenuManagementService {
command.getIcon(),
command.getHidden(),
command.getOrderNumber(),
command.getStatus(),
EntityStatus.of(command.getStatus()),
command.getRemarks());
}
@@ -79,7 +84,7 @@ public class MenuManagementService {
command.getIcon(),
command.getHidden(),
command.getOrderNumber(),
command.getStatus(),
EntityStatus.of(command.getStatus()),
command.getComponent(),
command.getResource(),
command.getCache(),
@@ -107,7 +112,7 @@ public class MenuManagementService {
command.getIcon(),
command.getHidden(),
command.getOrderNumber(),
command.getStatus(),
EntityStatus.of(command.getStatus()),
command.getComponent(),
command.getResource(),
command.getCache(),
@@ -122,6 +127,11 @@ public class MenuManagementService {
return MenuViewObject.of(menu.orElseThrow(DataNotExistException::new));
}
@Transactional(propagation = Propagation.SUPPORTS)
public List<MenuViewObject> queryMenuTree(MenuQueryParams queryParams) {
return menuQueries.queryMenuTree(queryParams);
}
@Transactional(propagation = Propagation.SUPPORTS)
public List<MenuViewObject> queryByAccountId(Long accountId) {
var menus = menuService.queryAllMenuListByAccountId(accountId);

View File

@@ -10,6 +10,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.system.application.query.RoleQueries;
import xyz.zhouxy.plusone.system.application.query.params.RoleQueryParams;
@@ -54,7 +55,7 @@ public class RoleManagementService {
Role roleToCreate = Role.newInstance(
command.getName(),
command.getIdentifier(),
command.getStatus(),
EntityStatus.of(command.getStatus()),
command.getRemarks(),
menuRefs,
permissionRefs);
@@ -67,7 +68,7 @@ public class RoleManagementService {
roleToUpdate.update(
command.getName(),
command.getIdentifier(),
command.getStatus(),
EntityStatus.of(command.getStatus()),
command.getRemarks(),
Set.copyOf(_menuRepository.findByIdIn(command.getMenus())),
Set.copyOf(_menuRepository.findPermissionsByIdIn(command.getPermissions())));

View File

@@ -10,10 +10,8 @@ import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import lombok.Data;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.RegexConsts;
import xyz.zhouxy.plusone.domain.ICommand;
import xyz.zhouxy.plusone.system.domain.model.account.AccountStatus;
import xyz.zhouxy.plusone.system.domain.model.account.Sex;
/**
* 创建账号命令
@@ -41,7 +39,7 @@ public class CreateAccountCommand implements ICommand {
String passwordConfirmation;
@NotNull
AccountStatus status;
Integer status;
Set<Long> roleRefs;
@@ -52,5 +50,5 @@ public class CreateAccountCommand implements ICommand {
@URL
String avatar;
Sex sex;
Integer sex;
}

View File

@@ -5,7 +5,6 @@ import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.domain.ICommand;
import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
@@ -42,7 +41,7 @@ public class CreateMenuCommand implements ICommand {
private Integer orderNumber;
@NotNull
private EntityStatus status;
private Integer status;
private String component;

View File

@@ -6,7 +6,6 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.domain.ICommand;
/**
@@ -23,7 +22,7 @@ public class CreateRoleCommand implements ICommand {
String identifier;
@NotNull
EntityStatus status;
Integer status;
String remarks;
Set<Long> menus;

View File

@@ -4,7 +4,7 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import lombok.Data;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.RegexConsts;
import xyz.zhouxy.plusone.domain.ICommand;
/**

View File

@@ -6,9 +6,8 @@ import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import lombok.Data;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.RegexConsts;
import xyz.zhouxy.plusone.domain.ICommand;
import xyz.zhouxy.plusone.system.domain.model.account.Sex;
/**
* 更新账号信息命令
@@ -27,5 +26,5 @@ public class UpdateAccountCommand implements ICommand {
@URL
String avatar;
Sex sex;
Integer sex;
}

View File

@@ -5,7 +5,6 @@ import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.domain.ICommand;
import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
@@ -46,7 +45,7 @@ public class UpdateMenuCommand implements ICommand {
private Integer orderNumber;
@NotNull
private EntityStatus status;
private Integer status;
private String component;

View File

@@ -6,7 +6,6 @@ import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.domain.ICommand;
/**
@@ -27,7 +26,7 @@ public class UpdateRoleCommand implements ICommand {
String identifier;
@NotNull
EntityStatus status;
Integer status;
@NotBlank
String remarks;

View File

@@ -14,10 +14,6 @@
<groupId>xyz.zhouxy</groupId>
<artifactId>plusone-basic-common</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,11 +1,14 @@
package xyz.zhouxy.plusone.system.util;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.annotation.Nonnull;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import xyz.zhouxy.plusone.constant.ErrorCodeConsts;
import xyz.zhouxy.plusone.exception.BizException;
import xyz.zhouxy.plusone.exception.SysException;
import xyz.zhouxy.plusone.util.RandomUtil;
/**
* 密码工具类
@@ -13,7 +16,8 @@ import xyz.zhouxy.plusone.exception.BizException;
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public final class PasswordUtil {
private static final String SALT_BASE_STRING = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+={}[]|\\:;\"',.<>?/";
private static final char[] SALT_BASE_CHAR_ARRAY = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+={}[]|\\:;\"',.<>?/"
.toCharArray();
/**
* 将密码和随机盐混合,并进行哈希加密。
@@ -28,12 +32,12 @@ public final class PasswordUtil {
int i = length > 0 ? length / 2 : 0;
var passwordWithSalt = salt.substring(0, i)
+ password
+ salt.substring(1);
String sha512Hex = DigestUtil.sha512Hex(passwordWithSalt);
if (sha512Hex == null) {
throw new BizException(ErrorCodeConsts.DEFAULT_ERROR_CODE, "未知错误:哈希加密失败!");
+ salt.substring(i);
try {
return sha512Hex(passwordWithSalt);
} catch (NoSuchAlgorithmException e) {
throw new SysException(e);
}
return sha512Hex;
}
/**
@@ -42,11 +46,20 @@ public final class PasswordUtil {
* @return 生成的随机盐
*/
public static String generateRandomSalt() {
return RandomUtil.randomString(SALT_BASE_STRING, 24);
return RandomUtil.randomStr(SALT_BASE_CHAR_ARRAY, 24);
}
private PasswordUtil() {
// 不允许实例化
throw new IllegalStateException("Utility class");
}
@Nonnull
@SuppressWarnings("null")
private static String sha512Hex(String data) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
messageDigest.update(data.getBytes(StandardCharsets.UTF_8));
byte[] result = messageDigest.digest();
return new BigInteger(1, result).toString(16);
}
}

View File

@@ -1,5 +1,9 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.Collection;
import javax.annotation.Nonnull;
import lombok.Getter;
import xyz.zhouxy.plusone.commons.util.Enumeration;
import xyz.zhouxy.plusone.domain.IValueObject;
@@ -10,20 +14,25 @@ import xyz.zhouxy.plusone.domain.IValueObject;
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
@Getter
public class AccountStatus extends Enumeration<AccountStatus> implements IValueObject {
public final class AccountStatus extends Enumeration<AccountStatus> implements IValueObject {
private AccountStatus(int value, String name) {
super(value, name);
private AccountStatus(int id, @Nonnull String name) {
super(id, name);
}
public static final AccountStatus AVAILABLE = new AccountStatus(0, "账号正常");
public static final AccountStatus LOCKED = new AccountStatus(1, "账号被锁定");
private static final EnumerationValuesHolder<AccountStatus> ENUMERATION_VALUES = new EnumerationValuesHolder<>(
private static final ValueSet<AccountStatus> VALUE_SET = new ValueSet<>(
AVAILABLE,
LOCKED);
public static AccountStatus of(int value) {
return ENUMERATION_VALUES.get(value);
public static AccountStatus of(int id) {
return VALUE_SET.get(id);
}
@Nonnull
public static Collection<AccountStatus> constants() {
return VALUE_SET.getValues();
}
}

View File

@@ -1,9 +1,10 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.Objects;
import java.util.regex.Pattern;
import cn.hutool.core.util.DesensitizedUtil;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
/**
* 值对象:电子邮箱地址
@@ -12,7 +13,7 @@ import xyz.zhouxy.plusone.constant.RegexConsts;
*/
public class Email extends Principal {
public static final String REGEX = RegexConsts.EMAIL;
public static final Pattern REGEX = PatternConsts.EMAIL;
private Email(String email) {
super(REGEX);

View File

@@ -1,9 +1,10 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.Objects;
import java.util.regex.Pattern;
import cn.hutool.core.util.DesensitizedUtil;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
/**
* 值对象:手机号码
@@ -12,7 +13,7 @@ import xyz.zhouxy.plusone.constant.RegexConsts;
*/
public class MobilePhone extends Principal {
public static final String REGEX = RegexConsts.MOBILE_PHONE;
public static final Pattern REGEX = PatternConsts.MOBILE_PHONE;
private MobilePhone(String mobilePhone) {
super(REGEX);

View File

@@ -1,8 +1,9 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.Objects;
import java.util.regex.Pattern;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
import xyz.zhouxy.plusone.domain.ValidatableStringRecord;
/**
@@ -12,7 +13,7 @@ import xyz.zhouxy.plusone.domain.ValidatableStringRecord;
*/
public class Nickname extends ValidatableStringRecord {
public static final String REGEX = RegexConsts.NICKNAME;
public static final Pattern REGEX = PatternConsts.NICKNAME;
private Nickname(String value) {
super(REGEX);

View File

@@ -7,10 +7,9 @@ import javax.annotation.Nonnull;
import org.springframework.util.Assert;
import xyz.zhouxy.plusone.constant.ErrorCodeConsts;
import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
import xyz.zhouxy.plusone.domain.IValueObject;
import xyz.zhouxy.plusone.exception.BizException;
import xyz.zhouxy.plusone.exception.SysException;
import xyz.zhouxy.plusone.system.util.PasswordUtil;
/**
@@ -20,7 +19,7 @@ import xyz.zhouxy.plusone.system.util.PasswordUtil;
*/
public class Password implements IValueObject {
private static final Pattern PATTERN = Pattern.compile(RegexConsts.PASSWORD);
private static final Pattern PATTERN = PatternConsts.PASSWORD;
private static final String DEFAULT_PASSWORD = "A1b2C3d4";
@Nonnull
@@ -37,7 +36,7 @@ public class Password implements IValueObject {
}
var salt = PasswordUtil.generateRandomSalt();
if (salt == null) {
throw new BizException(ErrorCodeConsts.DEFAULT_ERROR_CODE, "未知错误:生成随机盐失败");
throw new SysException("未知错误:生成随机盐失败");
}
this.saltVal = salt;
this.passwordVal = PasswordUtil.hashPassword(password, salt);

View File

@@ -1,5 +1,7 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.regex.Pattern;
import xyz.zhouxy.plusone.domain.ValidatableStringRecord;
/**
@@ -8,7 +10,7 @@ import xyz.zhouxy.plusone.domain.ValidatableStringRecord;
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public abstract class Principal extends ValidatableStringRecord {
protected Principal(String format) {
protected Principal(Pattern format) {
super(format);
}
}

View File

@@ -1,5 +1,7 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.Collection;
import javax.annotation.Nonnull;
import xyz.zhouxy.plusone.commons.util.Enumeration;
@@ -10,7 +12,7 @@ import xyz.zhouxy.plusone.domain.IValueObject;
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/
public class Sex extends Enumeration<Sex> implements IValueObject {
public final class Sex extends Enumeration<Sex> implements IValueObject {
@Nonnull
public static final Sex UNSET = new Sex(0, "未设置");
@Nonnull
@@ -18,16 +20,19 @@ public class Sex extends Enumeration<Sex> implements IValueObject {
@Nonnull
public static final Sex FEMALE = new Sex(2, "女性");
private Sex(int value, String name) {
super(value, name);
private Sex(int id, @Nonnull String name) {
super(id, name);
}
private static EnumerationValuesHolder<Sex> values = new EnumerationValuesHolder<>(
UNSET,
MALE,
FEMALE);
private static final ValueSet<Sex> VALUE_SET = new ValueSet<>(UNSET, MALE, FEMALE);
@Nonnull
public static Sex of(int value) {
return values.get(value);
return VALUE_SET.get(value);
}
@Nonnull
public static Collection<Sex> constants() {
return VALUE_SET.getValues();
}
}

View File

@@ -1,6 +1,8 @@
package xyz.zhouxy.plusone.system.domain.model.account;
import xyz.zhouxy.plusone.constant.RegexConsts;
import java.util.regex.Pattern;
import xyz.zhouxy.plusone.commons.constant.PatternConsts;
/**
* 值对象:用户名
@@ -9,7 +11,7 @@ import xyz.zhouxy.plusone.constant.RegexConsts;
*/
public class Username extends Principal {
public static final String REGEX = RegexConsts.USERNAME;
public static final Pattern REGEX = PatternConsts.USERNAME;
private Username(String username) {
super(REGEX);

View File

@@ -206,9 +206,9 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
.addValue("password", entity.getPassword().value())
.addValue("salt", entity.getPassword().getSalt())
.addValue("avatar", accountInfo.getAvatar().toString())
.addValue("sex", accountInfo.getSex().getValue())
.addValue("sex", accountInfo.getSex().getId())
.addValue("nickname", getValueOrNull(accountInfo.getNickname()))
.addValue("status", entity.getStatus().getValue())
.addValue("status", entity.getStatus().getId())
.addValue("createdBy", entity.getCreatedBy())
.addValue("createTime", now)
.addValue("updatedBy", entity.getUpdatedBy())

View File

@@ -31,7 +31,7 @@ class AccountRoleRefDAO extends PlusoneJdbcDaoSupport {
}
void insertAccountRoleRefs(Long accountId, Set<Long> roleRefs) {
int i = batchUpdate(
long i = batchUpdate(
"INSERT INTO sys_account_role (account_id, role_id) VALUES (:accountId, :roleId)",
roleRefs,
(Long roleId) -> new MapSqlParameterSource()

View File

@@ -21,11 +21,11 @@ class DictValueDAO extends PlusoneJdbcDaoSupport {
void updateDictValues(Dict entity) {
update("DELETE FROM sys_dict_value WHERE dict_type = :dictType",
"dictType", entity.getId().orElseThrow());
int i = insertDictValues(entity.getId().orElseThrow(), entity);
long i = insertDictValues(entity.getId().orElseThrow(), entity);
assertResultEquals(i, entity.count());
}
int insertDictValues(Long dictId, Dict entity) {
long insertDictValues(Long dictId, Dict entity) {
if (Objects.isNull(dictId) || Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getValues())) {
return 0;
}

View File

@@ -188,7 +188,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
.addValue("icon", entity.getIcon())
.addValue("hidden", entity.isHidden())
.addValue("orderNumber", entity.getOrderNumber())
.addValue("status", entity.getStatus().getValue())
.addValue("status", entity.getStatus().getId())
.addValue("remarks", entity.getRemarks())
.addValue("component", entity.getComponent())
.addValue("cache", entity.getCache())

View File

@@ -29,7 +29,7 @@ class RoleMenuRefDAO extends PlusoneJdbcDaoSupport {
}
void saveRoleMenuRefs(Long roleId, Role entity) {
int i = batchUpdate(
long i = batchUpdate(
"INSERT INTO sys_role_menu(role_id, menu_id) VALUES (:roleId, :menuId)",
entity.getMenus(),
menuRef -> new MapSqlParameterSource()

View File

@@ -30,7 +30,7 @@ class RolePermissionRefDAO extends PlusoneJdbcDaoSupport {
}
void saveRolePermissionRefs(Long roleId, Role entity) {
int i = batchUpdate(
long i = batchUpdate(
"INSERT INTO sys_role_permission(role_id, permission_id) VALUES (:roleId, :permissionId)",
entity.getPermissions(),
actionRef -> new MapSqlParameterSource()

View File

@@ -135,7 +135,7 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
.addValue("id", id)
.addValue("name", entity.getName())
.addValue("identifier", entity.getIdentifier())
.addValue("status", entity.getStatus().getValue())
.addValue("status", entity.getStatus().getId())
.addValue("remarks", entity.getRemarks())
.addValue("createTime", now)
.addValue("createdBy", loginId)

View File

@@ -67,6 +67,10 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>

22
pom.xml
View File

@@ -25,15 +25,15 @@
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<spring-boot.version>2.7.9</spring-boot.version>
<spring-boot.version>2.7.10</spring-boot.version>
<sa-token.version>1.34.0</sa-token.version>
<hutool.version>5.8.14</hutool.version>
<hutool.version>5.8.16</hutool.version>
<mybatis-starter.version>3.0.1</mybatis-starter.version>
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<commons-io.version>2.11.0</commons-io.version>
<mica.version>2.7.5</mica.version>
<mapstruct.version>1.5.3.Final</mapstruct.version>
<guava.version>31.1-jre</guava.version>
<guava.version>30.1-jre</guava.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-math3.version>3.6.1</commons-math3.version>
@@ -91,16 +91,7 @@
<artifactId>hutool-core</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-crypto</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
@@ -186,11 +177,6 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>