敏感数据加密和查看密文

This commit is contained in:
ZZM 2025-09-09 17:43:31 +08:00
parent 0c99c66172
commit b8d6718ec7
9 changed files with 296 additions and 5 deletions

View File

@ -19,6 +19,7 @@ import com.kakarote.crm.constant.CrmCodeEnum;
import com.kakarote.crm.constant.CrmEnum;
import com.kakarote.crm.entity.BO.*;
import com.kakarote.crm.entity.PO.CrmContacts;
import com.kakarote.crm.entity.VO.CrmGetPlaintextVO;
import com.kakarote.crm.entity.VO.CrmInfoNumVO;
import com.kakarote.crm.entity.VO.CrmMembersSelectVO;
import com.kakarote.crm.entity.VO.CrmModelFiledVO;
@ -29,6 +30,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -38,6 +40,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.kakarote.core.common.SystemCodeEnum.SYSTEM_NO_VALID;
/**
* <p>
* 联系人表 前端控制器
@ -58,6 +62,9 @@ public class CrmContactsController {
@Autowired
private ICrmTeamMembersService teamMembersService;
@Value("${app.verify_password}")
private String VERIFY_PASSWORD;
@PostMapping("/queryById/{contactsId}")
@ApiOperation("根据ID查询")
public Result<CrmModel> queryById(@PathVariable("contactsId") @ApiParam(name = "id", value = "id") Integer contactsId) {
@ -269,5 +276,16 @@ public class CrmContactsController {
teamMembersService.exitTeam(CrmEnum.CONTACTS,contactsId);
return R.ok();
}
@PostMapping("/getPlaintext")
public Result getPlaintext(@RequestBody CrmGetPlaintextVO plaintextVO) {
System.out.println(plaintextVO);
// 验证密码
if (!plaintextVO.getPassword().equals(VERIFY_PASSWORD) || plaintextVO.getPassword().equals("")) {
return Result.error(SYSTEM_NO_VALID,"密码错误或者密码不能为空!");
}
String plaintext = crmContactsService.getPlaintext(plaintextVO);
return Result.ok(plaintext);
}
}

View File

@ -25,15 +25,13 @@ import com.kakarote.crm.entity.BO.*;
import com.kakarote.crm.entity.PO.CrmContacts;
import com.kakarote.crm.entity.PO.CrmCustomer;
import com.kakarote.crm.entity.PO.CrmCustomerSetting;
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.entity.VO.*;
import com.kakarote.crm.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -43,6 +41,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.kakarote.core.common.SystemCodeEnum.SYSTEM_NO_VALID;
/**
* <p>
* 客户表 前端控制器
@ -75,6 +75,9 @@ public class CrmCustomerController {
@Autowired
private IBatchEncryptionService batchEncryptionService;
@Value("${app.verify_password}")
private String VERIFY_PASSWORD;
@PostMapping("/queryPageList")
@ApiOperation("查询列表页数据")
public Result<BasePage<Map<String, Object>>> queryPageList(@RequestBody CrmSearchBO search) {
@ -543,5 +546,25 @@ public class CrmCustomerController {
batchEncryptionService.batchEncryptCustomerData(pageSize);
return Result.ok();
}
@PostMapping("/getPlaintext")
public Result getPlaintext(@RequestBody CrmGetPlaintextVO plaintextVO) {
// 验证密码
if (!plaintextVO.getPassword().equals(VERIFY_PASSWORD) || plaintextVO.getPassword().equals("")) {
return Result.error(SYSTEM_NO_VALID,"密码错误或者密码不能为空!");
}
String plaintext = crmCustomerService.getPlaintext(plaintextVO);
return Result.ok(plaintext);
}
//企业画像验证
@PostMapping("/verifyPassword")
public Result verifyPassword(@RequestBody CrmGetPlaintextVO plaintextVO) {
// 验证密码
if (!plaintextVO.getPassword().equals(VERIFY_PASSWORD) || plaintextVO.getPassword().equals("")) {
return Result.error(SYSTEM_NO_VALID,"密码错误或者密码不能为空!");
}
return Result.ok();
}
}

View File

@ -27,7 +27,7 @@ public class CrmUsageReportController {
// }
@PostMapping("/findUsageReportByNsrsbhOrNsrmc")
@ApiOperation("查询报告筛查次数")
@ApiOperation("根据纳税人识别号或者纳税人名称查询")
public Result<CrmUsageReport> findUsageReportByNsrsbhOrNsrmc(@RequestBody CrmQueryUsageReportVO vo) throws IOException {
return R.ok(crmUsageReportService.findUsageReportByNsrsbhOrNsrmc(vo));
}

View File

@ -0,0 +1,21 @@
package com.kakarote.crm.entity.VO;
import lombok.Data;
import java.io.Serializable;
@Data
public class CrmGetPlaintextVO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String password;
private String field;
private Integer poolId;
private String crmType;
}

View File

@ -7,6 +7,7 @@ import com.kakarote.core.servlet.upload.FileEntity;
import com.kakarote.crm.common.CrmModel;
import com.kakarote.crm.entity.BO.*;
import com.kakarote.crm.entity.PO.CrmContacts;
import com.kakarote.crm.entity.VO.CrmGetPlaintextVO;
import com.kakarote.crm.entity.VO.CrmInfoNumVO;
import com.kakarote.crm.entity.VO.CrmModelFiledVO;
import org.springframework.web.bind.annotation.RequestBody;
@ -127,4 +128,8 @@ public interface ICrmContactsService extends BaseService<CrmContacts> {
void relateBusiness(CrmRelateBusinessBO relateBusinessBO);
void unrelateBusiness(CrmRelateBusinessBO relateBusinessBO);
String getPlaintext(CrmGetPlaintextVO plaintextVO);
String getContactsPlaintext(CrmGetPlaintextVO plaintextVO);
}

View File

@ -16,6 +16,7 @@ import com.kakarote.crm.entity.PO.CrmContacts;
import com.kakarote.crm.entity.PO.CrmCustomer;
import com.kakarote.crm.entity.PO.CrmCustomerSetting;
import com.kakarote.crm.entity.VO.CrmDataCheckVO;
import com.kakarote.crm.entity.VO.CrmGetPlaintextVO;
import com.kakarote.crm.entity.VO.CrmInfoNumVO;
import com.kakarote.crm.entity.VO.CrmModelFiledVO;
@ -273,4 +274,9 @@ public interface ICrmCustomerService extends BaseService<CrmCustomer> {
* @return
*/
Integer getCustomerByQyjbxx(CrmBusinessSaveBO crmModel);
/**
* 获取明文
*/
String getPlaintext(CrmGetPlaintextVO plaintextVO);
}

View File

@ -18,6 +18,7 @@ import com.kakarote.core.feign.admin.entity.SimpleUser;
import com.kakarote.core.feign.admin.service.AdminFileService;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.feign.crm.entity.SimpleCrmEntity;
import com.kakarote.core.security.util.SensitiveDataMaskUtil;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.servlet.upload.FileEntity;
@ -163,6 +164,24 @@ public class CrmActivityServiceImpl extends BaseServiceImpl<CrmActivityMapper, C
}
activityVO.setTime(time);
activityVO.setLastPage(times.size() < 2);
return encryptSensitiveData(activityVO);
}
/**
* 敏感数据加密
* @param activityVO
* @return
*/
private CrmActivityVO encryptSensitiveData(CrmActivityVO activityVO){
List<CrmActivity> activityList = activityVO.getList();
for (CrmActivity activity : activityList) {
System.out.println(activity);
if (activity.getActivityType() == 3) {
String maskName = SensitiveDataMaskUtil.maskName(activity.getActivityTypeName());
activity.setActivityTypeName(maskName);
}
}
return activityVO;
}

View File

@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.kakarote.core.common.Const;
import com.kakarote.core.common.FieldEnum;
import com.kakarote.core.common.SystemCodeEnum;
import com.kakarote.core.common.log.BehaviorEnum;
@ -16,6 +17,8 @@ import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.admin.service.AdminFileService;
import com.kakarote.core.feign.crm.entity.SimpleCrmEntity;
import com.kakarote.core.field.FieldService;
import com.kakarote.core.security.EncryptionService;
import com.kakarote.core.security.util.SensitiveDataMaskUtil;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.servlet.upload.FileEntity;
@ -33,6 +36,7 @@ import com.kakarote.crm.constant.CrmEnum;
import com.kakarote.crm.entity.BO.*;
import com.kakarote.crm.entity.PO.*;
import com.kakarote.crm.entity.VO.CrmFieldSortVO;
import com.kakarote.crm.entity.VO.CrmGetPlaintextVO;
import com.kakarote.crm.entity.VO.CrmInfoNumVO;
import com.kakarote.crm.entity.VO.CrmModelFiledVO;
import com.kakarote.crm.mapper.CrmContactsMapper;
@ -93,6 +97,12 @@ public class CrmContactsServiceImpl extends BaseServiceImpl<CrmContactsMapper, C
@Autowired
private FieldService fieldService;
@Autowired
private ICrmContactsService crmContactsService;
@Autowired
private EncryptionService encryptionService;
/**
* 查询字段配置
*
@ -124,6 +134,7 @@ public class CrmContactsServiceImpl extends BaseServiceImpl<CrmContactsMapper, C
@Override
public List<List<CrmModelFiledVO>> queryFormPositionField(Integer id) {
System.out.println("标记一下");
CrmModel crmModel = queryById(id);
if (id != null) {
List<JSONObject> customerList = new ArrayList<>();
@ -161,6 +172,7 @@ public class CrmContactsServiceImpl extends BaseServiceImpl<CrmContactsMapper, C
*/
@Override
public CrmModel queryById(Integer id) {
System.out.println("loading......");
CrmModel crmModel;
if (id != null) {
crmModel = getBaseMapper().queryById(id, UserUtil.getUserId());
@ -172,6 +184,31 @@ public class CrmContactsServiceImpl extends BaseServiceImpl<CrmContactsMapper, C
} else {
crmModel = new CrmModel(CrmEnum.CONTACTS.getType());
}
return maskContactsDetail(crmModel);
}
private CrmModel maskContactsDetail(CrmModel crmModel) {
//crmModel.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));
if (crmModel != null) {
// 获取数据
String name = (String) crmModel.get("name");
String mobile = (String) crmModel.get("mobile");
String telephone = (String) crmModel.get("telephone");
String address = (String) crmModel.get("address");
String email = (String) crmModel.get("email");
// 数据加密
String maskName = SensitiveDataMaskUtil.maskName(name);
String maskMobile = SensitiveDataMaskUtil.maskPhone(mobile);
String maskTelephone = SensitiveDataMaskUtil.maskPhone(telephone);
String maskAddress = SensitiveDataMaskUtil.maskAddress(address);
String maskEmail = SensitiveDataMaskUtil.maskEmail(email);
// 替换数据
crmModel.replace("name", maskName);
crmModel.replace("mobile", maskMobile);
crmModel.replace("telephone", maskTelephone);
crmModel.replace("address", maskAddress);
crmModel.replace("email", maskEmail);
}
return crmModel;
}
@ -584,4 +621,65 @@ public class CrmContactsServiceImpl extends BaseServiceImpl<CrmContactsMapper, C
.eq(CrmBusiness::getContactsId, relateBusinessBO.getContactsId())
.in(CrmBusiness::getBusinessId, relateBusinessBO.getBusinessIds()).update();
}
// 手动解密
private CrmContacts decryptSensitiveData(CrmGetPlaintextVO plaintextVO) {
CrmContacts contacts = crmContactsService.lambdaQuery()
.eq(CrmContacts::getContactsId, plaintextVO.getId())
.one();
if (contacts != null) {
// 手动解密敏感数据
// 恢复前缀检查并增加异常处理
if (contacts.getMobile() != null && contacts.getMobile().startsWith(Const.ENCRYPTED_PREFIX)) {
try {
contacts.setMobile(encryptionService.decryptAes(contacts.getMobile()));
} catch (Exception e) {
log.error("解密mobile失败: {}", contacts.getContactsId(), e);
contacts.setMobile(null); // 或保留原始值
}
}
// 对telephone和email字段执行相同修复
if (contacts.getTelephone() != null && contacts.getTelephone().startsWith(Const.ENCRYPTED_PREFIX)) {
try {
contacts.setTelephone(encryptionService.decryptAes(contacts.getTelephone()));
} catch (Exception e) {
log.error("解密telephone失败: {}", contacts.getContactsId(), e);
contacts.setTelephone(null);
}
}
if (contacts.getEmail() != null && contacts.getEmail().startsWith(Const.ENCRYPTED_PREFIX)) {
try {
contacts.setEmail(encryptionService.decryptAes(contacts.getEmail()));
} catch (Exception e) {
log.error("解密email失败: {}", contacts.getContactsId(), e);
contacts.setEmail(null);
}
}
}
return contacts;
}
@Override
public String getPlaintext(CrmGetPlaintextVO plaintextVO) {
CrmContacts contacts = decryptSensitiveData(plaintextVO);
return "姓名:" + contacts.getName() + "\n\n手机:" + contacts.getMobile();
}
@Override
public String getContactsPlaintext(CrmGetPlaintextVO plaintextVO) {
CrmContacts crmContacts = decryptSensitiveData(plaintextVO);
String plaintext = null;
if (plaintextVO.getField().equals("name")) {
plaintext = crmContacts.getName();
} else if (plaintextVO.getField().equals("mobile")) {
plaintext = crmContacts.getMobile();
} else if (plaintextVO.getField().equals("telephone")) {
plaintext = crmContacts.getTelephone();
} else if (plaintextVO.getField().equals("email")) {
plaintext = crmContacts.getEmail();
} else if (plaintextVO.getField().equals("address")) {
plaintext = crmContacts.getAddress();
}
return plaintext;
}
}

View File

@ -14,6 +14,7 @@ import com.alibaba.fastjson.util.TypeUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.kakarote.core.common.Const;
import com.kakarote.core.common.FieldEnum;
@ -33,6 +34,7 @@ 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.security.util.SensitiveDataMaskUtil;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.servlet.upload.FileEntity;
@ -380,9 +382,106 @@ public class CrmCustomerServiceImpl extends BaseServiceImpl<CrmCustomerMapper, C
} else {
crmModel = new CrmModel(CrmEnum.CUSTOMER.getType());
}
// 数据脱敏
return encryptSensitiveData(crmModel);
}
/**
* 数据脱敏
* @param crmModel
*/
private CrmModel encryptSensitiveData(CrmModel crmModel){
//遍历数据
//crmModel.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));
// 获取数据
String contactsMobile = (String)crmModel.get("contactsMobile");
String fieldCbiasz = (String)crmModel.get("fieldCbiasz");//详情页的联系人姓名
//String contactsName = (String)crmModel.get("contactsName");
String email = (String)crmModel.get("email");
String fliedKjhmgc = (String) crmModel.get("fliedKjhmgc");//详情页的详细地址
//String contactsAddress = (String) crmModel.get("contactsAddress");
// 脱敏处理
String maskMobile = SensitiveDataMaskUtil.maskPhone(contactsMobile);
String maskFieldCbiasz = SensitiveDataMaskUtil.maskName(fieldCbiasz);
//String maskName = SensitiveDataMaskUtil.maskName(contactsName);
String maskEmail = SensitiveDataMaskUtil.maskEmail(email);
String maskFliedKjhmgc = SensitiveDataMaskUtil.maskAddress(fliedKjhmgc);
//String maskAddress = SensitiveDataMaskUtil.maskAddress(contactsAddress);
// 重新组装crmModel
crmModel.replace("mobile", maskMobile);
crmModel.replace("fieldCbiasz", maskFieldCbiasz);
//crmModel.replace("contactsName", maskName);
crmModel.replace("email", maskEmail);
crmModel.replace("fliedKjhmgc", maskFliedKjhmgc);
//crmModel.replace("contactsAddress", maskAddress);
return crmModel;
}
/**
* 获取客户明文
* @param plaintextVO
* @return
*/
private String getCustomerPlaintext(CrmGetPlaintextVO plaintextVO) {
CrmModel crmModel = getBaseMapper().queryById(plaintextVO.getId(), UserUtil.getUserId());
// 添加解密逻辑decryptSensitiveData(crmModel);
crmModel.setLabel(CrmEnum.CUSTOMER.getType());
crmModel.setOwnerUserName(UserCacheUtil.getUserName(crmModel.getOwnerUserId()));
crmCustomerDataService.setDataByBatchId(crmModel);
List<String> stringList = ApplicationContextHolder.getBean(ICrmRoleFieldService.class).queryNoAuthField(crmModel.getLabel());
stringList.forEach(crmModel::remove);
if (ObjectUtil.isNotEmpty(plaintextVO.getPoolId())) {
LambdaQueryWrapper<CrmCustomerPoolFieldSetting> wrapper = new LambdaQueryWrapper<>();
wrapper.select(CrmCustomerPoolFieldSetting::getFieldName);
wrapper.eq(CrmCustomerPoolFieldSetting::getPoolId, plaintextVO.getPoolId()).eq(CrmCustomerPoolFieldSetting::getIsHidden, 1);
List<String> nameList = ApplicationContextHolder.getBean(ICrmCustomerPoolFieldSettingService.class).listObjs(wrapper, Object::toString);
nameList.forEach(crmModel::remove);
JSONObject poolAuthList = crmCustomerPoolService.queryAuthByPoolId(plaintextVO.getPoolId());
crmModel.put("poolAuthList", poolAuthList);
} else {
Long isPool = (Long) crmModel.get("isPool");
if (Objects.equals(isPool, 1L)) {
String poolIdStr = baseMapper.queryPoolIdsByCustomer(plaintextVO.getId());
if (StrUtil.isNotEmpty(poolIdStr)) {
List<String> poolIds = StrUtil.splitTrim(poolIdStr, Const.SEPARATOR);
List<Integer> poolIdList = poolIds.stream().map(Integer::valueOf).collect(Collectors.toList());
JSONObject poolAuthList = crmCustomerPoolService.getOnePoolAuthByPoolIds(poolIdList);
crmModel.put("poolAuthList", poolAuthList);
}
}
}
//遍历数据
//crmModel.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));
String plaintext = null;
if (plaintextVO.getField().equals("mobile")){
plaintext = (String) crmModel.get("mobile");
} else if (plaintextVO.getField().equals("email")){
plaintext = (String) crmModel.get("email");
} else if (plaintextVO.getField().equals("fieldCbiasz")){
int contactsId = (Integer) crmModel.get("contactsId");
plaintext = crmContactsService.getContactsName(contactsId);
} else if (plaintextVO.getField().equals("fliedKjhmgc")){
plaintext = (String) crmModel.get("fliedKjhmgc");
}
return plaintext;
}
/**
* 判断crmType
* @param plaintextVO
*/
@Override
public String getPlaintext(CrmGetPlaintextVO plaintextVO){
// 判断类型
String plaintext = null;
if (plaintextVO.getCrmType().equals("customer")) {
plaintext = getCustomerPlaintext(plaintextVO);
} else if (plaintextVO.getCrmType().equals("contacts")) {
plaintext = crmContactsService.getContactsPlaintext(plaintextVO);
}
return plaintext;
}
private void decryptSensitiveData(CrmModel model) {
String[] sensitiveFields = {"mobile", "email", "idCard", "bankCard"};
for (String field : sensitiveFields) {
@ -1267,6 +1366,8 @@ public class CrmCustomerServiceImpl extends BaseServiceImpl<CrmCustomerMapper, C
contacts.setEmail(null);
}
}
contacts.setName(SensitiveDataMaskUtil.maskName(contacts.getName()));
contacts.setMobile(SensitiveDataMaskUtil.maskPhone(contacts.getMobile()));
}
return result;