From d2e3388a0859054735de28cb00126dfdb25e772d Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Tue, 24 Mar 2026 09:05:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BE=81=E4=BF=A1=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=BB=93=E6=9E=9C=E8=A3=85=E9=85=8D=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../support/CreditInfoPayloadAssembler.java | 124 ++++++++++++++++++ .../CreditInfoPayloadAssemblerTest.java | 61 +++++++++ 2 files changed, 185 insertions(+) create mode 100644 ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssembler.java create mode 100644 ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssemblerTest.java diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssembler.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssembler.java new file mode 100644 index 00000000..607c932a --- /dev/null +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssembler.java @@ -0,0 +1,124 @@ +package com.ruoyi.info.collection.service.support; + +import com.ruoyi.info.collection.domain.CcdiCreditNegativeInfo; +import com.ruoyi.info.collection.domain.CcdiDebtsInfo; +import com.ruoyi.lsfx.domain.response.CreditParsePayload; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.sql.Date; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 征信解析结果装配器 + */ +@Component +public class CreditInfoPayloadAssembler { + + private static final List DEBT_MAPPINGS = List.of( + new DebtMapping("uncle_bank_house", "银行", "住房贷款", "银行", "未结清银行住房贷款"), + new DebtMapping("uncle_bank_car", "银行", "汽车贷款", "银行", "未结清银行汽车贷款"), + new DebtMapping("uncle_bank_manage", "银行", "经营贷款", "银行", "未结清银行经营贷款"), + new DebtMapping("uncle_bank_consume", "银行", "消费贷款", "银行", "未结清银行消费贷款"), + new DebtMapping("uncle_bank_other", "银行", "其他贷款", "银行", "未结清银行其他贷款"), + new DebtMapping("uncle_not_bank", "非银", "非银行贷款", "非银", "未结清非银行贷款"), + new DebtMapping("uncle_credit_cart", "银行", "信用卡", "银行", "未结清信用卡") + ); + + public List buildDebts(String personId, String personName, LocalDate queryDate, CreditParsePayload payload) { + Map source = payload == null ? null : payload.getLxDebt(); + if (source == null || source.isEmpty()) { + return List.of(); + } + List rows = new ArrayList<>(); + for (DebtMapping mapping : DEBT_MAPPINGS) { + CcdiDebtsInfo row = buildDebtRow(personId, personName, queryDate, source, mapping); + if (row != null) { + rows.add(row); + } + } + return rows; + } + + public CcdiCreditNegativeInfo buildNegative(String personId, String personName, LocalDate queryDate, CreditParsePayload payload) { + Map source = payload == null ? null : payload.getLxPublictype(); + CcdiCreditNegativeInfo info = new CcdiCreditNegativeInfo(); + info.setPersonId(personId); + info.setPersonName(personName); + info.setQueryDate(queryDate == null ? null : Date.valueOf(queryDate)); + info.setCivilCnt(toInteger(source == null ? null : source.get("civil_cnt"))); + info.setEnforceCnt(toInteger(source == null ? null : source.get("enforce_cnt"))); + info.setAdmCnt(toInteger(source == null ? null : source.get("adm_cnt"))); + info.setCivilLmt(toBigDecimal(source == null ? null : source.get("civil_lmt"))); + info.setEnforceLmt(toBigDecimal(source == null ? null : source.get("enforce_lmt"))); + info.setAdmLmt(toBigDecimal(source == null ? null : source.get("adm_lmt"))); + return info; + } + + private CcdiDebtsInfo buildDebtRow(String personId, String personName, LocalDate queryDate, + Map source, DebtMapping mapping) { + BigDecimal principalBalance = toBigDecimal(source.get(mapping.prefix() + "_bal")); + BigDecimal debtTotalAmount = toBigDecimal(source.get(mapping.prefix() + "_lmt")); + String debtStatus = toStringValue(source.get(mapping.prefix() + "_state")); + if (isEmptyMetrics(principalBalance, debtTotalAmount, debtStatus)) { + return null; + } + + CcdiDebtsInfo row = new CcdiDebtsInfo(); + row.setPersonId(personId); + row.setPersonName(personName); + row.setQueryDate(queryDate == null ? null : Date.valueOf(queryDate)); + row.setDebtMainType(mapping.debtMainType()); + row.setDebtSubType(mapping.debtSubType()); + row.setCreditorType(mapping.creditorType()); + row.setDebtName(mapping.debtName()); + row.setPrincipalBalance(principalBalance); + row.setDebtTotalAmount(debtTotalAmount); + row.setDebtStatus(debtStatus); + return row; + } + + private boolean isEmptyMetrics(BigDecimal principalBalance, BigDecimal debtTotalAmount, String debtStatus) { + boolean principalEmpty = principalBalance == null || BigDecimal.ZERO.compareTo(principalBalance) == 0; + boolean totalEmpty = debtTotalAmount == null || BigDecimal.ZERO.compareTo(debtTotalAmount) == 0; + return principalEmpty && totalEmpty && isBlank(debtStatus); + } + + private Integer toInteger(Object value) { + BigDecimal decimal = toBigDecimal(value); + return decimal == null ? 0 : decimal.intValue(); + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return null; + } + if (value instanceof BigDecimal decimal) { + return decimal; + } + String text = Objects.toString(value, "").trim(); + if (text.isEmpty()) { + return null; + } + return new BigDecimal(text); + } + + private String toStringValue(Object value) { + if (value == null) { + return null; + } + String text = Objects.toString(value, "").trim(); + return text.isEmpty() ? null : text; + } + + private boolean isBlank(String value) { + return value == null || value.trim().isEmpty(); + } + + private record DebtMapping(String prefix, String debtMainType, String debtSubType, String creditorType, String debtName) { + } +} diff --git a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssemblerTest.java b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssemblerTest.java new file mode 100644 index 00000000..e0316190 --- /dev/null +++ b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssemblerTest.java @@ -0,0 +1,61 @@ +package com.ruoyi.info.collection.service.support; + +import com.ruoyi.info.collection.domain.CcdiCreditNegativeInfo; +import com.ruoyi.info.collection.domain.CcdiDebtsInfo; +import com.ruoyi.lsfx.domain.response.CreditParsePayload; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CreditInfoPayloadAssemblerTest { + + private final CreditInfoPayloadAssembler assembler = new CreditInfoPayloadAssembler(); + + @Test + void shouldConvertDebtPayloadToSevenTypedRows() { + CreditParsePayload payload = new CreditParsePayload(); + Map debt = new HashMap<>(); + debt.put("uncle_bank_house_bal", "50000"); + debt.put("uncle_bank_house_lmt", "100000"); + debt.put("uncle_bank_house_state", "正常"); + debt.put("uncle_not_bank_bal", "2000"); + debt.put("uncle_not_bank_lmt", "3000"); + debt.put("uncle_not_bank_state", "逾期"); + payload.setLxDebt(debt); + + List rows = assembler.buildDebts("330101199001010011", "张三", LocalDate.parse("2026-03-01"), payload); + + assertEquals(2, rows.size()); + assertEquals("住房贷款", rows.get(0).getDebtSubType()); + assertEquals("非银", rows.get(1).getCreditorType()); + } + + @Test + void shouldBuildNegativeInfoFromPublicTypePayload() { + CreditParsePayload payload = new CreditParsePayload(); + Map publictype = new HashMap<>(); + publictype.put("civil_cnt", 2); + publictype.put("civil_lmt", "9800"); + payload.setLxPublictype(publictype); + + CcdiCreditNegativeInfo info = assembler.buildNegative("330101199001010011", "张三", LocalDate.parse("2026-03-01"), payload); + + assertEquals(2, info.getCivilCnt()); + assertEquals(new BigDecimal("9800"), info.getCivilLmt()); + } + + @Test + void shouldSkipDebtRowWhenAllMetricsAreEmpty() { + CreditParsePayload payload = new CreditParsePayload(); + payload.setLxDebt(new HashMap<>()); + + assertTrue(assembler.buildDebts("3301", "张三", LocalDate.parse("2026-03-01"), payload).isEmpty()); + } +}