From 85871e138042cc754aa9f5f57aecb7076535d949 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Mon, 30 Mar 2026 10:56:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E6=B5=81=E7=A8=8B=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E8=84=B1=E6=95=8F=E4=B8=8E=E6=A8=A1=E5=9E=8B=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=A7=A3=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/dto/ModelInvokeDTO.java | 5 ++ .../service/LoanPricingModelService.java | 13 ++++ .../impl/LoanPricingWorkflowServiceImpl.java | 4 ++ .../service/LoanPricingModelServiceTest.java | 66 +++++++++++++++++++ .../LoanPricingWorkflowServiceImplTest.java | 21 ++++++ 5 files changed, 109 insertions(+) create mode 100644 ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java index 9a0348c..37fdb51 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java @@ -150,4 +150,9 @@ public class ModelInvokeDTO { */ private String idType; + /** + * 证件号码(非必填) + */ + private String idNum; + } diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java index a2b96c6..471531a 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java @@ -39,12 +39,25 @@ public class LoanPricingModelService { @Resource private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper; + @Resource + private SensitiveFieldCryptoService sensitiveFieldCryptoService; + public void invokeModelAsync(Long workflowId) { LoanPricingWorkflow loanPricingWorkflow = loanPricingWorkflowMapper.selectById(workflowId); if (Objects.isNull(loanPricingWorkflow)){ log.error("未找到对应的流程信息,未调用模型服务"); return; } + try + { + loanPricingWorkflow.setCustName(sensitiveFieldCryptoService.decrypt(loanPricingWorkflow.getCustName())); + loanPricingWorkflow.setIdNum(sensitiveFieldCryptoService.decrypt(loanPricingWorkflow.getIdNum())); + } + catch (RuntimeException ex) + { + log.error("贷款定价模型调用前敏感字段解密失败", ex); + throw ex; + } ModelInvokeDTO modelInvokeDTO = new ModelInvokeDTO(); BeanUtils.copyProperties(loanPricingWorkflow, modelInvokeDTO); JSONObject response = modelService.invokeModel(modelInvokeDTO); diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java index 88a98f0..6bf51e1 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java @@ -160,6 +160,10 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(LoanPricingWorkflow::getSerialNum, serialNum); LoanPricingWorkflow loanPricingWorkflow = loanPricingWorkflowMapper.selectOne(wrapper); + String plainCustName = sensitiveFieldCryptoService.decrypt(loanPricingWorkflow.getCustName()); + String plainIdNum = sensitiveFieldCryptoService.decrypt(loanPricingWorkflow.getIdNum()); + loanPricingWorkflow.setCustName(loanPricingSensitiveDisplayService.maskCustName(plainCustName)); + loanPricingWorkflow.setIdNum(loanPricingSensitiveDisplayService.maskIdNum(plainIdNum)); loanPricingWorkflowVO.setLoanPricingWorkflow(loanPricingWorkflow); if (Objects.nonNull(loanPricingWorkflow.getModelOutputId())){ diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java new file mode 100644 index 0000000..bd2ef6d --- /dev/null +++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java @@ -0,0 +1,66 @@ +package com.ruoyi.loanpricing.service; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.loanpricing.domain.dto.ModelInvokeDTO; +import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow; +import com.ruoyi.loanpricing.mapper.LoanPricingWorkflowMapper; +import com.ruoyi.loanpricing.mapper.ModelCorpOutputFieldsMapper; +import com.ruoyi.loanpricing.mapper.ModelRetailOutputFieldsMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Objects; + +@ExtendWith(MockitoExtension.class) +class LoanPricingModelServiceTest +{ + @Mock + private ModelService modelService; + + @Mock + private LoanPricingWorkflowMapper loanPricingWorkflowMapper; + + @Mock + private ModelRetailOutputFieldsMapper modelRetailOutputFieldsMapper; + + @Mock + private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper; + + @Mock + private SensitiveFieldCryptoService sensitiveFieldCryptoService; + + @InjectMocks + private LoanPricingModelService loanPricingModelService; + + @Test + void shouldDecryptCustNameAndIdNumBeforeInvokeModel() + { + LoanPricingWorkflow workflow = new LoanPricingWorkflow(); + workflow.setId(1L); + workflow.setCustType("个人"); + workflow.setCustName("cipher-name"); + workflow.setIdNum("cipher-id"); + + JSONObject response = new JSONObject(); + response.put("calculateRate", "6.15"); + + when(loanPricingWorkflowMapper.selectById(1L)).thenReturn(workflow); + when(sensitiveFieldCryptoService.decrypt("cipher-name")).thenReturn("张三"); + when(sensitiveFieldCryptoService.decrypt("cipher-id")).thenReturn("110101199001011234"); + when(modelService.invokeModel(any())).thenReturn(response); + + loanPricingModelService.invokeModelAsync(1L); + + verify(modelService).invokeModel(argThat((ModelInvokeDTO dto) -> + Objects.equals("张三", dto.getCustName()) + && Objects.equals("110101199001011234", dto.getIdNum()))); + } +} diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java index 8933b81..f8c9a34 100644 --- a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java +++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java @@ -154,6 +154,27 @@ class LoanPricingWorkflowServiceImplTest assertEquals("6.15", result.getModelRetailOutputFields().getCalculateRate()); } + @Test + void shouldMaskCustNameAndIdNumWhenReturningWorkflowDetail() + { + LoanPricingWorkflow workflow = new LoanPricingWorkflow(); + workflow.setSerialNum("P20260328001"); + workflow.setCustType("个人"); + workflow.setCustName("cipher-name"); + workflow.setIdNum("cipher-id"); + + when(loanPricingWorkflowMapper.selectOne(any())).thenReturn(workflow); + when(sensitiveFieldCryptoService.decrypt("cipher-name")).thenReturn("张三"); + when(sensitiveFieldCryptoService.decrypt("cipher-id")).thenReturn("110101199001011234"); + when(loanPricingSensitiveDisplayService.maskCustName("张三")).thenReturn("张*"); + when(loanPricingSensitiveDisplayService.maskIdNum("110101199001011234")).thenReturn("1101********1234"); + + LoanPricingWorkflowVO result = loanPricingWorkflowService.selectLoanPricingBySerialNum("P20260328001"); + + assertEquals("张*", result.getLoanPricingWorkflow().getCustName()); + assertEquals("1101********1234", result.getLoanPricingWorkflow().getIdNum()); + } + @Test void shouldUseCorporateModelOutputCalculateRateForWorkflowDetail() {