Compare commits
2 Commits
852f52a2b3
...
c96663187e
| Author | SHA1 | Date |
|---|---|---|
|
|
c96663187e | |
|
|
1924cc6cb3 |
|
|
@ -75,4 +75,10 @@ public class Const implements Serializable {
|
|||
public static final String ADMIN_USER_DEPT_CACHE_NAME = "ADMIN:USER:DEPT:CACHE:";
|
||||
|
||||
|
||||
/**
|
||||
* 加密前缀
|
||||
*/
|
||||
public static final String ENCRYPTED_PREFIX = "ENCRYPTED:";
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
|||
import com.baomidou.mybatisplus.extension.MybatisMapWrapperFactory;
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
|
||||
import com.kakarote.core.security.converter.SensitiveDataConverter;
|
||||
import com.kakarote.core.utils.BaseUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.type.TypeHandlerRegistry;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
|
@ -22,11 +24,22 @@ public class MybatisPlusConfig {
|
|||
return paginationInterceptor;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public ConfigurationCustomizer configurationCustomizer() {
|
||||
// return i -> i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public ConfigurationCustomizer configurationCustomizer() {
|
||||
return i -> i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
|
||||
return i -> {
|
||||
i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
|
||||
// 注册敏感数据类型处理器
|
||||
TypeHandlerRegistry registry = i.getTypeHandlerRegistry();
|
||||
registry.register(SensitiveDataConverter.class);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public IdentifierGenerator idGenerator() {
|
||||
return new CustomIdGenerator();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
package com.kakarote.core.security;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Security;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class EncryptionService {
|
||||
// AES-GCM参数配置
|
||||
private static final int GCM_IV_LENGTH = 12;
|
||||
private static final int GCM_TAG_LENGTH = 16;
|
||||
private static final String AES_ALGORITHM = "AES/GCM/NoPadding";
|
||||
private static final String AES_KEY_ALGORITHM = "AES";
|
||||
|
||||
// 系统主密钥(生产环境应从KMS获取)
|
||||
@Value("${encryption.system-key}")
|
||||
private String systemKey;
|
||||
|
||||
static {
|
||||
// 注册BouncyCastle加密提供者
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
* @param plaintext 明文
|
||||
* @return Base64编码的密文
|
||||
*/
|
||||
public String encryptAes(String plaintext) {
|
||||
try {
|
||||
// 生成随机IV
|
||||
byte[] iv = new byte[GCM_IV_LENGTH];
|
||||
SecureRandom random = new SecureRandom();
|
||||
random.nextBytes(iv);
|
||||
|
||||
// 初始化密钥
|
||||
SecretKey secretKey = new SecretKeySpec(Base64.getDecoder().decode(systemKey), AES_KEY_ALGORITHM);
|
||||
|
||||
// 初始化加密器
|
||||
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
|
||||
GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
|
||||
|
||||
// 执行加密
|
||||
byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
// 组合IV和密文
|
||||
byte[] result = new byte[iv.length + ciphertext.length];
|
||||
System.arraycopy(iv, 0, result, 0, iv.length);
|
||||
System.arraycopy(ciphertext, 0, result, iv.length, ciphertext.length);
|
||||
|
||||
return Base64.getEncoder().encodeToString(result);
|
||||
} catch (Exception e) {
|
||||
log.error("AES加密失败", e);
|
||||
throw new SecurityException("数据加密失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密
|
||||
* @param ciphertext Base64编码的密文
|
||||
* @return 明文
|
||||
*/
|
||||
public String decryptAes(String ciphertext) {
|
||||
try {
|
||||
// 解码Base64密文
|
||||
byte[] decoded = Base64.getDecoder().decode(ciphertext);
|
||||
|
||||
// 提取IV
|
||||
byte[] iv = new byte[GCM_IV_LENGTH];
|
||||
System.arraycopy(decoded, 0, iv, 0, iv.length);
|
||||
|
||||
// 提取实际密文
|
||||
byte[] encryptedData = new byte[decoded.length - iv.length];
|
||||
System.arraycopy(decoded, iv.length, encryptedData, 0, encryptedData.length);
|
||||
|
||||
// 初始化密钥
|
||||
SecretKey secretKey = new SecretKeySpec(Base64.getDecoder().decode(systemKey), AES_KEY_ALGORITHM);
|
||||
|
||||
// 初始化解密器
|
||||
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
|
||||
GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec);
|
||||
|
||||
// 执行解密
|
||||
byte[] plaintext = cipher.doFinal(encryptedData);
|
||||
return new String(plaintext, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
log.error("AES解密失败", e);
|
||||
throw new SecurityException("数据解密失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.kakarote.core.security;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class KeyManager {
|
||||
// 密钥版本
|
||||
@Value("${encryption.key-version:V1}")
|
||||
private String keyVersion;
|
||||
|
||||
// 主密钥(生产环境应从KMS获取)
|
||||
@Value("${encryption.system-key}")
|
||||
private String systemKey;
|
||||
|
||||
/**
|
||||
* 生成新的AES密钥
|
||||
* @return Base64编码的密钥
|
||||
*/
|
||||
public String generateNewAesKey() {
|
||||
try {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
keyGenerator.init(256, new SecureRandom());
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
|
||||
} catch (Exception e) {
|
||||
log.error("生成AES密钥失败", e);
|
||||
throw new SecurityException("密钥生成失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密钥轮换管理
|
||||
*/
|
||||
public void rotateKey() {
|
||||
// 1. 生成新密钥
|
||||
String newKey = generateNewAesKey();
|
||||
|
||||
// 2. 记录密钥版本
|
||||
String newVersion = "V" + (Integer.parseInt(keyVersion.substring(1)) + 1);
|
||||
|
||||
// 3. 将新密钥存储到安全位置
|
||||
// ... 密钥存储逻辑 ...
|
||||
|
||||
// 4. 异步更新数据库中所有旧版本加密数据
|
||||
// ... 数据迁移逻辑 ...
|
||||
|
||||
log.info("密钥轮换完成,新版本: {}", newVersion);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package com.kakarote.core.security.converter;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
|
||||
import com.kakarote.core.common.Const;
|
||||
import com.kakarote.core.security.EncryptionService;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@MappedTypes({String.class})
|
||||
@MappedJdbcTypes({JdbcType.VARCHAR})
|
||||
@Component
|
||||
public class SensitiveDataConverter extends AbstractJsonTypeHandler<String> implements ApplicationContextAware {
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
private EncryptionService encryptionService;
|
||||
|
||||
// 无参构造函数,供MyBatis使用
|
||||
public SensitiveDataConverter() {
|
||||
}
|
||||
|
||||
// 带参构造函数,供Spring使用
|
||||
public SensitiveDataConverter(EncryptionService encryptionService) {
|
||||
this.encryptionService = encryptionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SensitiveDataConverter.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
private EncryptionService getEncryptionService() {
|
||||
if (encryptionService == null) {
|
||||
encryptionService = applicationContext.getBean(EncryptionService.class);
|
||||
}
|
||||
return encryptionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType) throws SQLException {
|
||||
if (s != null && !s.isEmpty() && !s.startsWith(Const.ENCRYPTED_PREFIX)) {
|
||||
s = getEncryptionService().encryptAes(s);
|
||||
}
|
||||
preparedStatement.setString(i, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet resultSet, String s) throws SQLException {
|
||||
String value = resultSet.getString(s);
|
||||
if (value != null && value.startsWith(Const.ENCRYPTED_PREFIX)) {
|
||||
value = getEncryptionService().decryptAes(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet resultSet, int i) throws SQLException {
|
||||
String value = resultSet.getString(i);
|
||||
if (value != null && value.startsWith(Const.ENCRYPTED_PREFIX)) {
|
||||
value = getEncryptionService().decryptAes(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
|
||||
String value = callableStatement.getString(i);
|
||||
if (value != null && value.startsWith(Const.ENCRYPTED_PREFIX)) {
|
||||
value = getEncryptionService().decryptAes(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parse(String json) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJson(String obj) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ jetcache:
|
|||
maxTotal: 50
|
||||
host: ${spring.redis.host}
|
||||
port: ${spring.redis.port}
|
||||
password: ${spring.redis.password}
|
||||
password:
|
||||
expireAfterWriteInMillis: 1800000
|
||||
|
||||
crm:
|
||||
|
|
@ -86,4 +86,9 @@ crm:
|
|||
bucketName:
|
||||
0:
|
||||
1:
|
||||
encryption:
|
||||
system-key: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=
|
||||
key-version: V1
|
||||
mybatis:
|
||||
type-handlers-package: com.kakarote.core.security.converter
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,7 @@ import com.kakarote.crm.entity.VO.CrmDataCheckVO;
|
|||
import com.kakarote.crm.entity.VO.CrmInfoNumVO;
|
||||
import com.kakarote.crm.entity.VO.CrmMembersSelectVO;
|
||||
import com.kakarote.crm.entity.VO.CrmModelFiledVO;
|
||||
import com.kakarote.crm.service.CrmUploadExcelService;
|
||||
import com.kakarote.crm.service.ICrmCustomerService;
|
||||
import com.kakarote.crm.service.ICrmOpenApiService;
|
||||
import com.kakarote.crm.service.ICrmTeamMembersService;
|
||||
import com.kakarote.crm.service.*;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
|
|
@ -75,6 +72,9 @@ public class CrmCustomerController {
|
|||
@Autowired
|
||||
private ICrmOpenApiService crmOpenApiService;
|
||||
|
||||
@Autowired
|
||||
private IBatchEncryptionService batchEncryptionService;
|
||||
|
||||
@PostMapping("/queryPageList")
|
||||
@ApiOperation("查询列表页数据")
|
||||
public Result<BasePage<Map<String, Object>>> queryPageList(@RequestBody CrmSearchBO search) {
|
||||
|
|
@ -553,5 +553,13 @@ public class CrmCustomerController {
|
|||
String customerName = crmCustomerService.getCustomerName(customerId);
|
||||
return R.ok(customerName);
|
||||
}
|
||||
|
||||
@PostMapping("/queryEncryptCustomerData")
|
||||
@ApiOperation("批量加密客户数据")
|
||||
@ParamAspect
|
||||
public Result encryptCustomerData(@RequestParam(defaultValue = "1000") int pageSize) {
|
||||
batchEncryptionService.batchEncryptCustomerData(pageSize);
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package com.kakarote.crm.entity.PO;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.kakarote.core.security.converter.SensitiveDataConverter;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
|
@ -52,17 +54,33 @@ public class CrmCustomer implements Serializable {
|
|||
private Integer contactsId;
|
||||
|
||||
@ApiModelProperty(value = "手机")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "电话")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String telephone;
|
||||
|
||||
@ApiModelProperty(value = "网址")
|
||||
private String website;
|
||||
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String email;
|
||||
|
||||
@ApiModelProperty(value = "省市区")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String address;
|
||||
|
||||
@ApiModelProperty(value = "详细地址")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String detailAddress;
|
||||
|
||||
@ApiModelProperty(value = "地理位置经度")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String lng;
|
||||
|
||||
@ApiModelProperty(value = "地理位置维度")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String lat;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
|
@ -73,21 +91,11 @@ public class CrmCustomer implements Serializable {
|
|||
@ApiModelProperty(value = "负责人ID")
|
||||
private Long ownerUserId;
|
||||
|
||||
@ApiModelProperty(value = "省市区")
|
||||
private String address;
|
||||
|
||||
@ApiModelProperty(value = "定位信息")
|
||||
@TableField(typeHandler = SensitiveDataConverter.class, jdbcType = JdbcType.VARCHAR)
|
||||
private String location;
|
||||
|
||||
@ApiModelProperty(value = "详细地址")
|
||||
private String detailAddress;
|
||||
|
||||
@ApiModelProperty(value = "地理位置经度")
|
||||
private String lng;
|
||||
|
||||
@ApiModelProperty(value = "地理位置维度")
|
||||
private String lat;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package com.kakarote.crm.service;
|
||||
|
||||
import com.kakarote.core.servlet.BaseService;
|
||||
|
||||
public interface IBatchEncryptionService {
|
||||
/**
|
||||
* 批量加密客户数据
|
||||
* @param pageSize 每页处理数量
|
||||
*/
|
||||
void batchEncryptCustomerData(int pageSize);
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package com.kakarote.crm.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.kakarote.core.common.Const;
|
||||
import com.kakarote.core.security.converter.SensitiveDataConverter;
|
||||
import com.kakarote.core.security.EncryptionService;
|
||||
import com.kakarote.crm.entity.PO.CrmCustomer;
|
||||
import com.kakarote.crm.mapper.CrmCustomerMapper;
|
||||
import com.kakarote.crm.service.IBatchEncryptionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class BatchEncryptionServiceImpl implements IBatchEncryptionService {
|
||||
|
||||
@Autowired
|
||||
private CrmCustomerMapper customerMapper;
|
||||
|
||||
@Autowired
|
||||
private EncryptionService encryptionService;
|
||||
|
||||
// 我们可以移除不需要的SensitiveDataConverter依赖
|
||||
// @Autowired
|
||||
// private SensitiveDataConverter sensitiveDataConverter;
|
||||
|
||||
/**
|
||||
* 批量加密客户数据
|
||||
* @param pageSize 每页处理数量
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void batchEncryptCustomerData(int pageSize) {
|
||||
int currentPage = 1;
|
||||
boolean hasMoreData = true;
|
||||
|
||||
while (hasMoreData) {
|
||||
// 分页查询客户数据
|
||||
IPage<CrmCustomer> page = new Page<>(currentPage, pageSize);
|
||||
LambdaQueryWrapper<CrmCustomer> wrapper = new LambdaQueryWrapper<>();
|
||||
// 可以添加条件来过滤未加密的数据
|
||||
// wrapper.isNull(CrmCustomer::getEncryptedFlag);
|
||||
|
||||
IPage<CrmCustomer> result = customerMapper.selectPage(page, wrapper);
|
||||
List<CrmCustomer> customerList = result.getRecords();
|
||||
|
||||
if (customerList.isEmpty()) {
|
||||
hasMoreData = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// 加密每个客户的敏感数据
|
||||
for (CrmCustomer customer : customerList) {
|
||||
// 加密敏感字段
|
||||
if (customer.getMobile() != null) {
|
||||
customer.setMobile(encryptionService.encryptAes(customer.getMobile()));
|
||||
}
|
||||
if (customer.getTelephone() != null) {
|
||||
customer.setTelephone(encryptionService.encryptAes(customer.getTelephone()));
|
||||
}
|
||||
if (customer.getEmail() != null) {
|
||||
customer.setEmail(encryptionService.encryptAes(customer.getEmail()));
|
||||
}
|
||||
if (customer.getAddress() != null) {
|
||||
customer.setAddress(encryptionService.encryptAes(customer.getAddress()));
|
||||
}
|
||||
if (customer.getDetailAddress() != null) {
|
||||
customer.setDetailAddress(encryptionService.encryptAes(customer.getDetailAddress()));
|
||||
}
|
||||
if (customer.getLocation() != null) {
|
||||
customer.setLocation(encryptionService.encryptAes(customer.getLocation()));
|
||||
}
|
||||
// 标记为已加密
|
||||
// customer.setEncryptedFlag(1);
|
||||
|
||||
// 更新客户数据
|
||||
customerMapper.updateById(customer);
|
||||
}
|
||||
|
||||
currentPage++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ import com.kakarote.core.feign.crm.entity.QueryEventCrmPageBO;
|
|||
import com.kakarote.core.feign.crm.entity.SimpleCrmEntity;
|
||||
import com.kakarote.core.field.FieldService;
|
||||
import com.kakarote.core.redis.Redis;
|
||||
import com.kakarote.core.security.EncryptionService;
|
||||
import com.kakarote.core.servlet.ApplicationContextHolder;
|
||||
import com.kakarote.core.servlet.BaseServiceImpl;
|
||||
import com.kakarote.core.servlet.upload.FileEntity;
|
||||
|
|
@ -127,6 +128,8 @@ public class CrmCustomerServiceImpl extends BaseServiceImpl<CrmCustomerMapper, C
|
|||
@Autowired
|
||||
private FieldService fieldService;
|
||||
|
||||
@Autowired
|
||||
private EncryptionService encryptionService;
|
||||
/**
|
||||
* 查询字段配置
|
||||
*
|
||||
|
|
@ -331,6 +334,8 @@ public class CrmCustomerServiceImpl extends BaseServiceImpl<CrmCustomerMapper, C
|
|||
CrmModel crmModel;
|
||||
if (id != null) {
|
||||
crmModel = getBaseMapper().queryById(id, UserUtil.getUserId());
|
||||
// 添加解密逻辑
|
||||
decryptSensitiveData(crmModel);
|
||||
crmModel.setLabel(CrmEnum.CUSTOMER.getType());
|
||||
crmModel.setOwnerUserName(UserCacheUtil.getUserName(crmModel.getOwnerUserId()));
|
||||
crmCustomerDataService.setDataByBatchId(crmModel);
|
||||
|
|
@ -369,6 +374,17 @@ public class CrmCustomerServiceImpl extends BaseServiceImpl<CrmCustomerMapper, C
|
|||
return crmModel;
|
||||
}
|
||||
|
||||
private void decryptSensitiveData(CrmModel model) {
|
||||
String[] sensitiveFields = {"mobile", "email", "idCard", "bankCard"};
|
||||
for (String field : sensitiveFields) {
|
||||
Object value = model.get(field);
|
||||
if (value instanceof String) {
|
||||
model.put(field, encryptionService.decryptAes((String) value));
|
||||
System.out.println(encryptionService.decryptAes((String) value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存或新增信息
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import com.kakarote.core.feign.admin.entity.SimpleUser;
|
|||
import com.kakarote.core.feign.admin.service.AdminService;
|
||||
import com.kakarote.core.feign.crm.entity.BiAuthority;
|
||||
import com.kakarote.core.feign.crm.entity.BiParams;
|
||||
import com.kakarote.core.feign.crm.service.CrmUserAnalyseService;
|
||||
import com.kakarote.core.servlet.ApplicationContextHolder;
|
||||
import com.kakarote.core.utils.BiTimeUtil;
|
||||
import com.kakarote.core.utils.UserCacheUtil;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import cn.hutool.core.date.DateUnit;
|
|||
import cn.hutool.core.lang.UUID;
|
||||
import com.aliyun.oss.ServiceException;
|
||||
import com.ctc.wstx.util.DataUtil;
|
||||
import com.foresee.platform.api.exception.PlatformApiException;
|
||||
//import com.foresee.platform.api.exception.PlatformApiException;
|
||||
import com.kakarote.core.exception.CrmException;
|
||||
import com.kakarote.crm.util.AecUtils;
|
||||
import com.kakarote.crm.util.xml.XmlUtils;
|
||||
|
|
@ -80,9 +80,6 @@ public class WebServiceUtil {
|
|||
}else {
|
||||
return XmlUtils.xmlToJson(ss);
|
||||
}
|
||||
}catch (PlatformApiException ex){
|
||||
log.error("响应报文body解密失败:"+responseStr,ex);
|
||||
throw new CrmException(500,"解密失败");
|
||||
}catch (JAXBException ex){
|
||||
log.error("响应报文xml格式错误:"+responseStr,ex);
|
||||
throw new CrmException(500,"xml格式错误");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.kakarote.crm;
|
||||
|
||||
import com.kakarote.core.security.EncryptionService;
|
||||
import com.kakarote.crm.entity.PO.*;
|
||||
import com.kakarote.crm.service.*;
|
||||
import com.kakarote.crm.util.AecUtils;
|
||||
|
|
@ -24,6 +25,9 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
@SpringBootTest
|
||||
public class testQyjxfp {
|
||||
|
||||
@Autowired
|
||||
EncryptionService encryptionService;
|
||||
|
||||
@Autowired
|
||||
private ICrmQyjxfpService iCrmQyjxfpService;
|
||||
|
||||
|
|
@ -478,6 +482,13 @@ public class testQyjxfp {
|
|||
|
||||
System.out.println ("respJson = " + respJson);
|
||||
}
|
||||
@Test
|
||||
public void encryptionService(){
|
||||
String s = encryptionService.encryptAes("江西方欣信息技术有限公司(1)");
|
||||
System.out.println("加密后数据:"+s);
|
||||
String s1 = encryptionService.decryptAes(s);
|
||||
System.out.println("解密数据:"+s1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,3 +55,7 @@ crm:
|
|||
upgradeFile:
|
||||
#升级文件地址
|
||||
url: D:/工具/version.json
|
||||
|
||||
encryption:
|
||||
system-key: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=
|
||||
key-version: V1
|
||||
|
|
@ -11,7 +11,7 @@ spring:
|
|||
pool:
|
||||
max-active: 300
|
||||
datasource:
|
||||
url: jdbc:${DATASOURCE_DBTYPE:mysql}://${DATASOURCE_HOST:127.0.0.1}:${DATASOURCE_PORT:3306}/wk_crm_single?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&serverTimezone=Asia/Shanghai&useAffectedRows=true
|
||||
url: jdbc:${DATASOURCE_DBTYPE:mysql}://${DATASOURCE_HOST:127.0.0.1}:${DATASOURCE_PORT:3307}/wk_crm_single?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&serverTimezone=Asia/Shanghai&useAffectedRows=true
|
||||
username: ${DATASOURCE_USERNAME:devuser}
|
||||
password: ${DATASOURCE_PASSWORD:ckly@9069&Uk}
|
||||
elasticsearch:
|
||||
|
|
|
|||
Loading…
Reference in New Issue