From a1db88e4c746fa3c267d887bec99a4fe626a93c6 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Mon, 30 Mar 2026 10:54:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E6=B5=81=E7=A8=8B=E6=95=8F?= =?UTF-8?q?=E6=84=9F=E5=AD=97=E6=AE=B5=E5=8A=A0=E5=AF=86=E4=B8=8E=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E8=84=B1=E6=95=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/LoanPricingWorkflowServiceImpl.java | 22 +++++- .../loanpricing/LoanPricingWorkflowMapper.xml | 4 +- .../LoanPricingWorkflowServiceImplTest.java | 78 +++++++++++++++++++ 3 files changed, 98 insertions(+), 6 deletions(-) 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 e559c05..88a98f0 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 @@ -14,7 +14,9 @@ import com.ruoyi.loanpricing.mapper.LoanPricingWorkflowMapper; import com.ruoyi.loanpricing.mapper.ModelCorpOutputFieldsMapper; import com.ruoyi.loanpricing.mapper.ModelRetailOutputFieldsMapper; import com.ruoyi.loanpricing.service.ILoanPricingWorkflowService; +import com.ruoyi.loanpricing.service.LoanPricingSensitiveDisplayService; import com.ruoyi.loanpricing.service.LoanPricingModelService; +import com.ruoyi.loanpricing.service.SensitiveFieldCryptoService; import com.ruoyi.loanpricing.util.LoanPricingConverter; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -47,6 +49,12 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi @Resource private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper; + @Resource + private SensitiveFieldCryptoService sensitiveFieldCryptoService; + + @Resource + private LoanPricingSensitiveDisplayService loanPricingSensitiveDisplayService; + /** * 发起利率定价流程 @@ -72,6 +80,8 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi loanPricingWorkflow.setRunType("1"); } + loanPricingWorkflow.setCustName(sensitiveFieldCryptoService.encrypt(loanPricingWorkflow.getCustName())); + loanPricingWorkflow.setIdNum(sensitiveFieldCryptoService.encrypt(loanPricingWorkflow.getIdNum())); loanPricingWorkflowMapper.insert(loanPricingWorkflow); loanPricingModelService.invokeModelAsync(loanPricingWorkflow.getId()); @@ -129,7 +139,11 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi @Override public IPage selectLoanPricingPage(Page page, LoanPricingWorkflow loanPricingWorkflow) { - return loanPricingWorkflowMapper.selectWorkflowPageWithRates(page, loanPricingWorkflow); + IPage pageResult = loanPricingWorkflowMapper.selectWorkflowPageWithRates(page, loanPricingWorkflow); + pageResult.getRecords().forEach(row -> row.setCustName( + loanPricingSensitiveDisplayService.maskCustName( + sensitiveFieldCryptoService.decrypt(row.getCustName())))); + return pageResult; } /** @@ -187,10 +201,10 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi wrapper.like(LoanPricingWorkflow::getCreateBy, loanPricingWorkflow.getCreateBy()); } - // 按客户名称模糊查询 - if (StringUtils.hasText(loanPricingWorkflow.getCustName())) + // 按客户内码模糊查询 + if (StringUtils.hasText(loanPricingWorkflow.getCustIsn())) { - wrapper.like(LoanPricingWorkflow::getCustName, loanPricingWorkflow.getCustName()); + wrapper.like(LoanPricingWorkflow::getCustIsn, loanPricingWorkflow.getCustIsn()); } // 按机构号筛选 diff --git a/ruoyi-loan-pricing/src/main/resources/mapper/loanpricing/LoanPricingWorkflowMapper.xml b/ruoyi-loan-pricing/src/main/resources/mapper/loanpricing/LoanPricingWorkflowMapper.xml index d3e66c2..21a1727 100644 --- a/ruoyi-loan-pricing/src/main/resources/mapper/loanpricing/LoanPricingWorkflowMapper.xml +++ b/ruoyi-loan-pricing/src/main/resources/mapper/loanpricing/LoanPricingWorkflowMapper.xml @@ -26,8 +26,8 @@ AND lpw.create_by LIKE CONCAT('%', #{query.createBy}, '%') - - AND lpw.cust_name LIKE CONCAT('%', #{query.custName}, '%') + + AND lpw.cust_isn LIKE CONCAT('%', #{query.custIsn}, '%') AND lpw.org_code LIKE CONCAT('%', #{query.orgCode}, '%') 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 b39f6f1..8933b81 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 @@ -1,10 +1,16 @@ package com.ruoyi.loanpricing.service.impl; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; 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.baomidou.mybatisplus.core.MybatisConfiguration; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow; import com.ruoyi.loanpricing.domain.entity.ModelCorpOutputFields; @@ -14,13 +20,20 @@ import com.ruoyi.loanpricing.domain.vo.LoanPricingWorkflowVO; import com.ruoyi.loanpricing.mapper.LoanPricingWorkflowMapper; import com.ruoyi.loanpricing.mapper.ModelCorpOutputFieldsMapper; import com.ruoyi.loanpricing.mapper.ModelRetailOutputFieldsMapper; +import com.ruoyi.loanpricing.service.LoanPricingSensitiveDisplayService; import com.ruoyi.loanpricing.service.LoanPricingModelService; +import com.ruoyi.loanpricing.service.SensitiveFieldCryptoService; +import org.apache.ibatis.builder.MapperBuilderAssistant; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Collections; +import java.util.Objects; + @ExtendWith(MockitoExtension.class) class LoanPricingWorkflowServiceImplTest { @@ -36,9 +49,34 @@ class LoanPricingWorkflowServiceImplTest @Mock private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper; + @Mock + private SensitiveFieldCryptoService sensitiveFieldCryptoService; + + @Mock + private LoanPricingSensitiveDisplayService loanPricingSensitiveDisplayService; + @InjectMocks private LoanPricingWorkflowServiceImpl loanPricingWorkflowService; + @Test + void shouldEncryptCustNameAndIdNumBeforeInsert() + { + LoanPricingWorkflow workflow = new LoanPricingWorkflow(); + workflow.setCustName("张三"); + workflow.setIdNum("110101199001011234"); + workflow.setCustIsn("CUST001"); + + when(sensitiveFieldCryptoService.encrypt("张三")).thenReturn("cipher-name"); + when(sensitiveFieldCryptoService.encrypt("110101199001011234")).thenReturn("cipher-id"); + + loanPricingWorkflowService.createLoanPricing(workflow); + + verify(loanPricingWorkflowMapper).insert(argThat((LoanPricingWorkflow entity) -> + Objects.equals("cipher-name", entity.getCustName()) + && Objects.equals("cipher-id", entity.getIdNum()) + && Objects.equals("CUST001", entity.getCustIsn()))); + } + @Test void shouldReturnPagedWorkflowListWithCalculateRate() { @@ -55,6 +93,46 @@ class LoanPricingWorkflowServiceImplTest assertEquals("6.15", result.getRecords().get(0).getCalculateRate()); } + @Test + void shouldMaskCustNameWhenReturningPagedWorkflowList() + { + LoanPricingWorkflowListVO row = new LoanPricingWorkflowListVO(); + row.setCustName("cipher-name"); + + Page pageResult = new Page<>(1, 10); + pageResult.setRecords(Collections.singletonList(row)); + + when(loanPricingWorkflowMapper.selectWorkflowPageWithRates(any(), any())).thenReturn(pageResult); + when(sensitiveFieldCryptoService.decrypt("cipher-name")).thenReturn("张三"); + when(loanPricingSensitiveDisplayService.maskCustName("张三")).thenReturn("张*"); + + IPage result = loanPricingWorkflowService.selectLoanPricingPage(new Page<>(1, 10), new LoanPricingWorkflow()); + + assertEquals("张*", result.getRecords().get(0).getCustName()); + } + + @Test + void shouldUseCustIsnInsteadOfCustNameAsQueryCondition() + { + LoanPricingWorkflow query = new LoanPricingWorkflow(); + query.setCustIsn("CUST001"); + query.setCustName("张三"); + + when(loanPricingWorkflowMapper.selectList(any())).thenReturn(Collections.emptyList()); + + loanPricingWorkflowService.selectLoanPricingList(query); + + ArgumentCaptor> wrapperCaptor = ArgumentCaptor.forClass(LambdaQueryWrapper.class); + verify(loanPricingWorkflowMapper).selectList(wrapperCaptor.capture()); + + LambdaQueryWrapper wrapper = wrapperCaptor.getValue(); + TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), LoanPricingWorkflow.class); + String sqlSegment = wrapper.getSqlSegment(); + + assertTrue(sqlSegment.contains("cust_isn"), sqlSegment); + assertTrue(!sqlSegment.contains("cust_name"), sqlSegment); + } + @Test void shouldUseRetailModelOutputCalculateRateForWorkflowDetail() {