日常代码开发截图
接口代码

package com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2; import com.differ.jackyun.jackyunassbase.infrastructure.datacore.BaseContextInfo; import java.util.List; /** * 电商平台敏感数据处理方案接口。 * * @Author hgw * @Date 2021-11-01 */ public interface ISensitiveDataProcessV2 { /** * 数据解密 * * @param contextInfo 会员名称 * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param sensitiveDataModule 解密业务模块 * @param beSensitiveDataItemList 待解密项集合 */ void decrypt(BaseContextInfo contextInfo, boolean hasFuzzy, SensitiveDataModuleEnumV2 sensitiveDataModule, List<BeSensitiveDataItem> beSensitiveDataItemList); }
基类代码

package com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2; import com.differ.jackyun.jackyunassbase.infrastructure.datacore.BaseContextInfo; import org.apache.commons.collections.CollectionUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.util.List; /** * 电商平台敏感数据处理方案(OaId解密方式)。 * * @Author hgw * @Date 2021-11-01 */ @Component @Lazy(true) public class BaseSensitiveDataProcessV2 implements ISensitiveDataProcessV2 { //region 变量 //endregion //region ISensitiveDataProcess /** * 数据解密 * * @param contextInfo 会员名称 * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param sensitiveDataModule 解密业务模块 * @param beSensitiveDataItemList 待解密项集合 */ @Override public void decrypt(BaseContextInfo contextInfo, boolean hasFuzzy, SensitiveDataModuleEnumV2 sensitiveDataModule, List<BeSensitiveDataItem> beSensitiveDataItemList) { //如果没有任何解密项则直接返回。 if (CollectionUtils.isEmpty(beSensitiveDataItemList)) { return; } //校验输入参数 if (!this.validateInput(hasFuzzy, sensitiveDataModule, beSensitiveDataItemList)) { return; } //校验业务逻辑 if (!this.validateBusinessLogic(hasFuzzy, sensitiveDataModule, beSensitiveDataItemList)) { return; } //数据解密详情方法 this.decryptProfile(contextInfo, hasFuzzy, sensitiveDataModule, beSensitiveDataItemList); } //endregion //region 继承类需要重写方法 /** * 数据解密详情方法。 * * @param contextInfo 会员名称 * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param sensitiveDataModule 解密业务模块 * @param beSensitiveDataItemList 待解密项集合 */ protected void decryptProfile(BaseContextInfo contextInfo, boolean hasFuzzy, SensitiveDataModuleEnumV2 sensitiveDataModule, List<BeSensitiveDataItem> beSensitiveDataItemList) { } /** * 校验输入参数。 * * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param sensitiveDataModule 解密业务模块 * @param beSensitiveDataItemList 待解密项集合 * @return 校验成功或失败(不建议直接抛出异常 , 以免影响其他数据解密) */ protected boolean validateInput(boolean hasFuzzy, SensitiveDataModuleEnumV2 sensitiveDataModule, List<BeSensitiveDataItem> beSensitiveDataItemList) { return true; } /** * 校验业务逻辑。 * * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param sensitiveDataModule 解密业务模块 * @param beSensitiveDataItemList 待解密项集合 * @return 校验成功或失败(不建议直接抛出异常 , 以免影响其他数据解密) */ protected boolean validateBusinessLogic(boolean hasFuzzy, SensitiveDataModuleEnumV2 sensitiveDataModule, List<BeSensitiveDataItem> beSensitiveDataItemList) { return true; } //endregion }
Plugins某子类代码

package com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2.plugins; import com.differ.jackyun.jackyunassbase.infrastructure.datacore.BaseContextInfo; import com.differ.jackyun.jackyunassbase.infrastructure.enums.ErrorCodes; import com.differ.jackyun.jackyunassbase.infrastructure.exception.AppException; import com.differ.jackyun.jackyunassbase.infrastructure.utils.CoreUtils; import com.differ.jackyun.jackyunassbase.infrastructure.utils.ExtUtils; import com.differ.jackyun.jackyunassservice.dao.jackyunmultidb.common.DaoCommonDBSwitchMapper; import com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2.*; import com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2.core.DecryptionDataInfo; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.util.List; import java.util.stream.Collectors; /** * 电商平台敏感数据处理方案(明文脱敏)。 * 从数据库获取明文返回或打码返回 * * @Author hgw * @Date 2021-11-01 */ @Component @Lazy(true) public class CleartextSensitiveDataProcess extends BaseSensitiveDataProcessV2 { //region 变量 /** * 通用查询数据仓储切库服务 */ @Autowired private DaoCommonDBSwitchMapper daoCommonDBSwitchMapper; //endregion //region 重写基类方法 /** * 数据解密 * * @param contextInfo 会员名称 * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param sensitiveDataModule 解密业务模块 * @param beSensitiveDataItemList 待解密项集合 */ @Override protected void decryptProfile(BaseContextInfo contextInfo, boolean hasFuzzy, SensitiveDataModuleEnumV2 sensitiveDataModule, List<BeSensitiveDataItem> beSensitiveDataItemList) { /** * 本模式适用: * 1. 明文脱敏 * 2. 平台密文数据为带掩码格式(淘系平台),打码解密直接从数据库取出数据掐头去尾即可而无需请求平台。 * ---------------- * 业务说明: * 1. 明文脱敏,直接从数据库中获取明文数据。 * 2. 如果需要打码,则打码输出,否则输出明文。 */ //如果待解密集合为空则直接返回。 if (CollectionUtils.isEmpty(beSensitiveDataItemList)) { return; } //获取指定模块的所有数据列配置。 List<SensitiveDataColumnConfigEnumV2> columnConfigList = SensitiveDataColumnConfigEnumV2.getColumnConfig(sensitiveDataModule); if (columnConfigList.size() == 0) { throw new AppException(ErrorCodes.LOGICERROR, "明文脱敏解密模块“" + sensitiveDataModule.name() + "”下没有任何配置列"); } //对待解密项集合进行分页,防止SQL过大发生异常。 List<List<BeSensitiveDataItem>> pagingList = CoreUtils.lstPaging(beSensitiveDataItemList, 20); //分页数据解密详情方法。 for (List<BeSensitiveDataItem> list : pagingList) { decryptFromDb(contextInfo, hasFuzzy, list, sensitiveDataModule); } } //endregion //region 其他方法 /** * 数据解密(从数据库获取)。 * * @param contextInfo 上下文环境信息 * @param hasFuzzy 是否为打码输出(打码输出=true;明文输出=false) * @param beSensitiveDataItemList 待解密项集合 * @param sensitiveDataModule 解密业务模块 */ private void decryptFromDb(BaseContextInfo contextInfo, boolean hasFuzzy, List<BeSensitiveDataItem> beSensitiveDataItemList, SensitiveDataModuleEnumV2 sensitiveDataModule) { /** * 业务说明: * 1. 拼接SQL语句并执行 * 2. 循环填充结果 * 1) 过滤掉无效项:数据库中无数据、解密数据为空、非(明文或打码输出且平台密文数据为带掩码格式) * 2) 如果需要打码输出,则进行打码。 * .明文直接打码 * .平台密文数据为带掩码格式(淘系平台),则只需掐头去尾。 * 3) 所有数据加入字典集 * 4) 通用字段一一赋值。 */ //region 拼接SQL语句并执行 //拼接业务主键 String businessKeys = beSensitiveDataItemList.stream().map(g -> g.getBusinessKey()).collect(Collectors.joining(",")); //获取各个模块的敏感数据。 List<DecryptionDataInfo> resultList = SensitiveDataProcessUtilsV2.getDecryptionData(contextInfo, this.daoCommonDBSwitchMapper, sensitiveDataModule, businessKeys); //endregion //region 循环填充结果 for (BeSensitiveDataItem beSensitiveDataItem : beSensitiveDataItemList) { //根据业务主键获取数据查询结果集,如果没有任何数据则略过。 List<DecryptionDataInfo> resultItemList = resultList.stream().filter(g -> beSensitiveDataItem.getBusinessKey().equalsIgnoreCase(g.getBusinessKey().toString())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(resultItemList)) { SensitiveDataProcessUtilsV2.appendDecryptionFailuresMessage(beSensitiveDataItem, "数据库无数据"); continue; } //判断是否为打码输出 且 平台密文数据为带掩码格式(淘系平台) boolean isMaskData = hasFuzzy && SensitiveDataPlatFeatures.isMaskData(beSensitiveDataItem.getPolyAPIPlat()); //循环所有解密项。 resultItemList.forEach(resultItem -> { //如果获取到的解密值为空则略过。 if (ExtUtils.isNullOrEmpty(resultItem.getSensitiveValue())) { return; } //判断当前数据是否为明文。 boolean isClearText = SensitiveDataProcessUtilsV2.isClearText(resultItem.getSensitiveValue()); /** * 业务说明: * 以下情况会略过,原因: * 1) 当从数据库中查询出来的数据为明文时,会覆盖其他解密模式的解密值(以明文为准)。 * 当解密项既有明文又有密文时,会同时调用两种解密模式,先其他解密模式,后明文解密模式,从数据库获取到明文覆盖之前的解密值。 * 2) 打码输出 且 平台密文数据为带掩码格式(淘系平台),此类只需从数据库查出数据掐头去尾即可。 */ if (!(isClearText || isMaskData)) { return; } //获取列配置枚举 SensitiveDataColumnConfigEnumV2 columnConfig = SensitiveDataColumnConfigEnumV2.create(resultItem.getDataType()); //如果是打码输出,则根据模式进行对应的处理。 if (hasFuzzy) { String usedMaskText = ClearTextUseMaskUtils.smartUseMaskForJust(columnConfig.getFieldType(), resultItem.getSensitiveValue()); resultItem.setSensitiveValue(usedMaskText); } //加入Map集 beSensitiveDataItem.getDecryptedResult().getDecryptedDataMap().put(columnConfig, resultItem.getSensitiveValue()); //通用字段一一赋值 if (null != columnConfig.getFieldType()) { SensitiveDataProcessUtilsV2.fillSensitiveDataItem(beSensitiveDataItem, columnConfig.getFieldType(), resultItem.getSensitiveValue()); } }); } //endregion } //endregion }
工厂代码

package com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2; import com.differ.jackyun.jackyunassbase.infrastructure.enums.ErrorCodes; import com.differ.jackyun.jackyunassbase.infrastructure.exception.AppException; import com.differ.jackyun.jackyunassbase.infrastructure.utils.SpringResolveManager; import com.differ.jackyun.jackyunassservice.service.sensitivedataprocessv2.plugins.*; /** * 敏感数据处理类工厂 * * @Author hgw * @Date 2021-11-01 * 有以下解密模式: * ----------------------------- * 淘系(oaid):http://192.168.88.47/web/#/5?page_id=14225 * 非淘系(非oaid、拼多多打码解密):http://192.168.88.47/web/#/5?page_id=14251 * 京东代理:http://showdoc.happylife.ren/web/#/5?page_id=10825 * 拼多多代理(仅明文解密):http://showdoc.happylife.ren/web/#/5?page_id=10825 * 明文解密(明文解密、淘系部分平台打码输出走明文模式):直接从数据库获取明文(或打码)输出;淘系部分平打过码输出只需从数据库获取数据后掐头去尾 */ public class SensitiveDataProcessFactoryV2 { /** * 根据条件创建ISensitiveDataProcess对象。 * * @param sensitiveDataMode 解密模式 * @return ISensitiveDataProcess对象 */ public static ISensitiveDataProcessV2 create(SensitiveDataModeEnum sensitiveDataMode) { switch (sensitiveDataMode) { case OAID: return SpringResolveManager.resolve(OaIdSensitiveDataProcess.class); case CIPHERTEXT: return SpringResolveManager.resolve(CiphertextSensitiveDataProcess.class); case CLEARTEXT: return SpringResolveManager.resolve(CleartextSensitiveDataProcess.class); case JD_PROXY: return SpringResolveManager.resolve(JdProxySensitiveDataProcess.class); case PDD_PROXY: return SpringResolveManager.resolve(PddProxySensitiveDataProcess.class); case ORIGINALCIPHERTEXT: return SpringResolveManager.resolve(OriginalTextProxySensitiveDataProcess.class); default: throw new AppException(ErrorCodes.LOGICERROR, "未实现解密模式为“" + sensitiveDataMode.name() + "”处理方案"); } } }
辅助类部分代码

//region 数据脱敏解密 /** * 数据脱敏解密。 * * @param contextInfo 上下文环境信息 * @param queryOption 业务数据(敏感数据脱敏) * @return 输出业务数据(敏感数据脱敏) */ public static DecryptingDataQueryResult decrypt(BaseContextInfo contextInfo, DecryptingDataQueryOption queryOption) { //region 构建相关对象 //创建返回结果对象。 DecryptingDataQueryResult queryResult = new DecryptingDataQueryResult(); List<DecryptingDataQueryResult.Item> queryResultItemList = new ArrayList<>(); queryResult.setItems(queryResultItemList); queryResult.setContextId(contextInfo.getContextID()); //根据请求参数集构建所有待解密项集合 List<BeSensitiveDataItem> allBeSensitiveDataItemList = new ArrayList<>(queryOption.getItems().size()); queryOption.getItems().forEach(g -> { //构建对象加入集合并映射。 BeSensitiveDataItem beSensitiveDataItem = new BeSensitiveDataItem(); MapperUtils.map(g, beSensitiveDataItem); beSensitiveDataItem.setField(queryOption.getField()); allBeSensitiveDataItemList.add(beSensitiveDataItem); //初始化解密结果对象 DecryptingDataResult decryptedResult = new DecryptingDataResult(); beSensitiveDataItem.setDecryptedResult(decryptedResult); Map<SensitiveDataColumnConfigEnumV2, String> decryptedDataMap = new HashMap<>(CollectionsUtil.getHashCapacity(20)); decryptedResult.setDecryptedDataMap(decryptedDataMap); }); //表示已处理的业务主键集。 List<String> processedBusinessKeyList = new ArrayList<>(); //是否为打码解密。 boolean hasFuzzy = Boolean.TRUE.equals(queryOption.getbHasFuzzy()); //endregion if (SensitiveDataSceneEnum.ORIGINALTEXT.equals(queryOption.getScene())) { //region 获取原始密文解密 /** * 直接从api数据库里查询原始密文数据 */ decryptProfile(contextInfo, queryOption, processedBusinessKeyList, allBeSensitiveDataItemList, SensitiveDataModeEnum.ORIGINALCIPHERTEXT, (g) -> { return true; } ); //endregion } //region 京东代理解密 /** * 过滤条件: * 1. 除排已处理项 * 2. 京东平台解密 */ decryptProfile(contextInfo, queryOption, processedBusinessKeyList, allBeSensitiveDataItemList, SensitiveDataModeEnum.JD_PROXY, (g) -> { return !processedBusinessKeyList.contains(g.getBusinessKey()) && PolyAPIPlatEnum.isJd(g.getPolyAPIPlat()); } ); //endregion //region 拼多多代理解密 /** * 过滤条件: * 1. 除排已处理项 * 2. 拼多多明文解密 * 注:拼多多打码解密走密文模式数据脱敏 */ decryptProfile(contextInfo, queryOption, processedBusinessKeyList, allBeSensitiveDataItemList, SensitiveDataModeEnum.PDD_PROXY, (g) -> { return !processedBusinessKeyList.contains(g.getBusinessKey()) && PolyAPIPlatEnum.isPdd(g.getPolyAPIPlat()) && !hasFuzzy; } ); //endregion //region oaid模式数据脱敏 /** * 过滤条件: * 1. 除排已处理项 * 2. 有密文数据 * 3. 且 通过oaid解密。 * 4. 且 非(打码输出 且 平台密文数据为带掩码格式(淘系平台))。 * 注:打码输出 且 平台密文数据为带掩码格式(淘系平台),走明文数据脱敏。 */ decryptProfile(contextInfo, queryOption, processedBusinessKeyList, allBeSensitiveDataItemList, SensitiveDataModeEnum.OAID, (g) -> { return !processedBusinessKeyList.contains(g.getBusinessKey()) && Boolean.TRUE.equals(g.getHasCipherText()) && SensitiveDataPlatFeatures.needOaid(g.getPolyAPIPlat()) && !(hasFuzzy && SensitiveDataPlatFeatures.isMaskData(g.getPolyAPIPlat())); } ); //endregion //region 密文模式数据脱敏 /** * 过滤条件: * 1. 除排已处理项 * 2. 有密文数据 * 3. 且 不通过oaid解密。 */ decryptProfile(contextInfo, queryOption, processedBusinessKeyList, allBeSensitiveDataItemList, SensitiveDataModeEnum.CIPHERTEXT, (g) -> { return !processedBusinessKeyList.contains(g.getBusinessKey()) && Boolean.TRUE.equals(g.getHasCipherText()) && !SensitiveDataPlatFeatures.needOaid(g.getPolyAPIPlat()); } ); //endregion //region 明文模式数据脱敏 /** * 过滤条件: * 1. 非销售单解密(销售单数据在OMS,不存在售后明文解密) * 2. 且 (有明文数据 或 打码输出且平台密文数据为带掩码格式(淘系平台),打码解密直接从数据库取出数据掐头去尾即可) * * 特别说明: * 1. 明文解密模式不除排已处理项 * 2. 明文模式数据脱敏要放到最后,因为数据里有可能既有明文又有密文。 * 3. 明文解密用数据库中的明文替换相应的结果集字段,以数据库中的明文为准。 * 4. 对于售后单中的敏感信息,最初从网店订单中引用(为密文),但是后期客户可能会修改这些敏感数据(为明文),故一个售后单中的敏感信息既有密文、也有明文。 */ decryptProfile(contextInfo, queryOption, processedBusinessKeyList, allBeSensitiveDataItemList, SensitiveDataModeEnum.CLEARTEXT, (g) -> { return !queryOption.getModule().equals(SensitiveDataModuleEnumV2.TRADE) && (Boolean.TRUE.equals(g.getHasClearText()) || (hasFuzzy && SensitiveDataPlatFeatures.isMaskData(g.getPolyAPIPlat()))); } ); //endregion //region 填充返回结果 allBeSensitiveDataItemList.forEach(g -> { DecryptingDataQueryResult.Item queryResultItem = new DecryptingDataQueryResult.Item(); queryResultItemList.add(queryResultItem); MapperUtils.map(g, queryResultItem); }); //endregion return queryResult; } //endregion
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述