Skip to content

Commit

Permalink
feat: 新增用户批量导入功能 (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
jskils committed Jun 19, 2024
1 parent b512ea9 commit c2ad055
Show file tree
Hide file tree
Showing 17 changed files with 831 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public class CacheConstants {
*/
public static final String USER_PASSWORD_ERROR_KEY_PREFIX = USER_KEY_PREFIX + "PASSWORD_ERROR" + DELIMITER;

/**
* 数据导入临时会话key
*/
public static final String DATA_IMPORT_KEY = "SYSTEM" + DELIMITER + "DATA_IMPORT" + DELIMITER;

private CacheConstants() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.extra.spring.SpringUtil;
import top.continew.admin.common.config.properties.RsaProperties;
import top.continew.starter.core.exception.BusinessException;
import top.continew.starter.core.util.validate.ValidationUtils;
import top.continew.starter.security.crypto.autoconfigure.CryptoProperties;
import top.continew.starter.security.crypto.encryptor.AesEncryptor;
import top.continew.starter.security.crypto.encryptor.IEncryptor;
import java.util.List;
import java.util.stream.Collectors;

/**
* 加密/解密工具类
Expand All @@ -33,29 +40,6 @@ public class SecureUtils {
private SecureUtils() {
}

/**
* 公钥加密
*
* @param data 要加密的内容
* @param publicKey 公钥
* @return 公钥加密并 Base64 加密后的内容
*/
public static String encryptByRsaPublicKey(String data, String publicKey) {
return Base64.encode(SecureUtil.rsa(null, publicKey).encrypt(data, KeyType.PublicKey));
}

/**
* 公钥加密
*
* @param data 要加密的内容
* @return 公钥加密并 Base64 加密后的内容
*/
public static String encryptByRsaPublicKey(String data) {
String publicKey = RsaProperties.PUBLIC_KEY;
ValidationUtils.throwIfBlank(publicKey, "请配置 RSA 公钥");
return encryptByRsaPublicKey(data, publicKey);
}

/**
* 私钥解密
*
Expand All @@ -78,4 +62,22 @@ public static String decryptByRsaPrivateKey(String data) {
public static String decryptByRsaPrivateKey(String data, String privateKey) {
return new String(SecureUtil.rsa(privateKey, null).decrypt(Base64.decode(data), KeyType.PrivateKey));
}

/**
* 对普通加密字段列表进行AES加密,优化starter加密模块后优化这个方法
*
* @param values 待加密内容
* @return 加密后内容
*/
public static List<String> encryptFieldByAes(List<String> values) {
IEncryptor encryptor = new AesEncryptor();
CryptoProperties properties = SpringUtil.getBean(CryptoProperties.class);
return values.stream().map(value -> {
try {
return encryptor.encrypt(value, properties.getPassword(), properties.getPublicKey());
} catch (Exception e) {
throw new BusinessException("字段加密异常");
}
}).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package top.continew.admin.system.enums;

import cn.hutool.core.collection.CollUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.continew.starter.data.mybatis.plus.base.IBaseEnum;

import java.util.List;

/**
* 数据导入策略
*
* @author Kils
* @since 2024-06-17 18:33
*/
@Getter
@RequiredArgsConstructor
public enum ImportPolicyEnum implements IBaseEnum<Integer> {

/**
* 跳过该行
*/
SKIP(1, "跳过该行"),

/**
* 修改数据
*/
UPDATE(2, "修改数据"),

/**
* 停止导入
*/
EXIT(3, "停止导入");

private final Integer value;
private final String description;

public boolean validate(ImportPolicyEnum importPolicy, String data, List<String> existList) {
return this == importPolicy && CollUtil.isNotEmpty(existList) && existList.contains(data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package top.continew.admin.system.model.req;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import top.continew.admin.common.enums.DisEnableStatusEnum;
import top.continew.admin.system.enums.ImportPolicyEnum;
import top.continew.starter.extension.crud.model.req.BaseReq;

import java.io.Serial;

/**
* 用户导入参数
*
* @author Kils
* @since 2024-6-17 16:42
*/
@Data
@Schema(description = "用户导入参数")
public class UserImportReq extends BaseReq {

@Serial
private static final long serialVersionUID = 1L;

/**
* 导入会话KEY
*/
@Schema(description = "导入会话KEY", example = "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed")
@NotBlank(message = "导入已过期,请重新上传")
private String importKey;

/**
* 用户重复策略
*/
@Schema(description = "重复用户策略", type = "Integer", allowableValues = {"1", "2", "3", "4"}, example = "1")
@NotNull(message = "重复用户策略不能为空")
private ImportPolicyEnum duplicateUser;

/**
* 重复邮箱策略
*/
@Schema(description = "重复邮箱策略", type = "Integer", allowableValues = {"1", "2", "3", "4"}, example = "1")
@NotNull(message = "重复邮箱策略不能为空")
private ImportPolicyEnum duplicateEmail;

/**
* 重复手机策略
*/
@Schema(description = "重复手机策略", type = "Integer", allowableValues = {"1", "2", "3", "4"}, example = "1")
@NotNull(message = "重复手机策略不能为空")
private ImportPolicyEnum duplicatePhone;

/**
* 默认状态
*/
@Schema(description = "默认状态(1:启用;2:禁用)", type = "Integer", allowableValues = {"1", "2"}, example = "1")
private DisEnableStatusEnum defaultStatus;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package top.continew.admin.system.model.req;

import cn.hutool.core.lang.RegexPool;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import top.continew.admin.common.constant.RegexConstants;
import top.continew.starter.extension.crud.model.req.BaseReq;
import top.continew.starter.extension.crud.util.ValidateGroup;

import java.io.Serial;

/**
* 用户导入行数据
*
* @author Kils
* @since 2024-6-17 16:42
*/
@Data
@Schema(description = "用户导入行数据")
public class UserImportRowReq extends BaseReq {

@Serial
private static final long serialVersionUID = 1L;

/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
@Pattern(regexp = RegexConstants.USERNAME, message = "用户名长度为 4-64 个字符,支持大小写字母、数字、下划线,以字母开头")
private String username;

/**
* 昵称
*/
@NotBlank(message = "昵称不能为空")
@Pattern(regexp = RegexConstants.GENERAL_NAME, message = "昵称长度为 2-30 个字符,支持中文、字母、数字、下划线,短横线")
private String nickname;

/**
* 密码
*/
@NotBlank(message = "密码不能为空", groups = ValidateGroup.Crud.Add.class)
private String password;

/**
* 部门名称
*/
@NotNull(message = "所属部门不能为空")
private String deptName;

/**
* 角色
*/
@NotBlank(message = "所属角色不能为空")
private String roleName;

/**
* 性别
*/
private String gender;

/**
* 邮箱
*/
@Pattern(regexp = "^$|" + RegexPool.EMAIL, message = "邮箱格式错误")
@Length(max = 255, message = "邮箱长度不能超过 {max} 个字符")
private String email;

/**
* 手机号码
*/
@Pattern(regexp = "^$|" + RegexPool.MOBILE, message = "手机号码格式错误")
private String phone;

/**
* 描述
*/
private String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package top.continew.admin.system.model.resp;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* 用户导入结果
*
* @author kils
* @since 2024-06-18 14:37
*/
@Data
@Schema(description = "用户导入结果")
@AllArgsConstructor
@NoArgsConstructor
public class UserImportParseResp {

private static final long serialVersionUID = 1L;

/**
* 导入会话KEY
*/
@Schema(description = "导入会话KEY", example = "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed")
private String importKey;

/**
* 总计行数
*/
@Schema(description = "总计行数", example = "100")
private Integer totalRows;

/**
* 有效行数
*/
@Schema(description = "有效行数", example = "100")
private Integer validRows;

/**
* 用户重复行数
*/
@Schema(description = "用户重复行数", example = "100")
private Integer duplicateUserRows;

/**
* 重复邮箱行数
*/
@Schema(description = "重复邮箱行数", example = "100")
private Integer duplicateEmailRows;

/**
* 重复手机行数
*/
@Schema(description = "重复手机行数", example = "100")
private Integer duplicatePhoneRows;
}
Loading

0 comments on commit c2ad055

Please sign in to comment.