.gitignore
New file @@ -0,0 +1,6 @@ *.iml *.class target/ .idea/ *.prefs *.log cmci-pfcs-gateway/pom.xml
New file @@ -0,0 +1,87 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jttech.zxmx.plat</groupId> <artifactId>zxmx-plat-gateway</artifactId> <version>0.0.1-SNAPSHOT</version> <name>cmci-pfcs-gateway</name> <description>Jwssw Simple Service</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties> <dependencies> <!-- 节选 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-log4j2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <dependency> <groupId>org.jdom</groupId> <artifactId>jdom</artifactId> <version>2.0.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.60</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build> </project> cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/Application.java
New file @@ -0,0 +1,24 @@ package com.jttech.cmci.pfcs; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 启动类 * * @author carsonwang * @version 1.0 * @date 2022/4/6 18:00 * @since JDK 1.8 */ @SpringBootApplication public class Application { /** * simple service 启动入口 * * @param args 参数集 */ public static void main(String[] args) { SpringApplication.run(Application.class, args); } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/content/ZxmxContent.java
New file @@ -0,0 +1,45 @@ package com.jttech.cmci.pfcs.content; /** * @Description:常量 * @Author:carsonwang * @Date:Created in 2022-04-06 16:16 * @Version: 1.0 */ public class ZxmxContent { /** * "" */ public static final String EMPTY_STR = ""; /** * 逗号 */ public final static String SIGN_COMMA = ","; /** * 竖线 */ public final static String VERTICAL_LINE = "\\|"; public final static String reportMessage = "ReportMessage"; public final static String QueryInfo = "QueryInfo"; public final static String QueryDate = "QueryDate"; public final static String creditTranDetailsInfo = "CreditTranDetailsInfo"; public final static String beRecoveryDetailsInfo = "BeRecoveryDetailsInfo"; public final static String baseInfo = "BaseInfo"; public final static String money = "Money"; public final static String nonrevolvingLoanDetInfo = "NonrevolvingLoanDetInfo"; public final static String latestMonPerfmInfo = "LatestMonPerfmInfo"; public final static String currentOverdueTotal = "CurrentOverdueTotal"; public final static String avgUsedOfSixMonth = "AvgUsedOfSixMonth"; public final static String LoopQuotaSubAct = "LoopQuotaSubAct"; public final static String RevolvinLoanAct = "RevolvinLoanAct"; public final static String CreditCardAct = "CreditCardAct"; public final static String SemiCreditCardAct = "SemiCreditCardAct"; public final static String Lines = "Lines"; public final static String Last5YearsHisPerFmInfo = "Last5YearsHisPerFmInfo"; public final static String Content = "Content"; public final static String ReportHead = "ReportHead"; public final static String ThisQueryReqInfo = "ThisQueryReqInfo"; public final static String QueryName = "QueryName"; public final static String QueryCredNum = "QueryCredNum"; } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/controller/ZxmxManagerController.java
New file @@ -0,0 +1,39 @@ package com.jttech.cmci.pfcs.controller; import com.jttech.cmci.pfcs.service.ZxmxManagerService; import com.jttech.cmci.pfcs.vo.req.ZxmxGetScoreReqVo; import com.jttech.cmci.pfcs.vo.resp.ZxmxGetScoreRespVo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * 征信模型 * * @author carsonwang * @version 1.0 * @date 2022/4/6 18:00 * @since JDK 1.8 */ @RestController @RequestMapping("/zxmx") public class ZxmxManagerController { private Logger mLogger = LoggerFactory.getLogger(getClass()); @Autowired private ZxmxManagerService mZxmxManagerService; /** * 获取分数 * * @return 当前环境 */ @PostMapping("/getScore") public @ResponseBody ZxmxGetScoreRespVo getScore(@RequestBody ZxmxGetScoreReqVo creditInfo) { mLogger.info("请求参数:{}", creditInfo); return mZxmxManagerService.getScore(creditInfo); } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/service/ZxmxManagerService.java
New file @@ -0,0 +1,700 @@ package com.jttech.cmci.pfcs.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.jttech.cmci.pfcs.util.DateUtil; import com.jttech.cmci.pfcs.vo.UserInfoVo; import com.jttech.cmci.pfcs.vo.req.ZxmxGetScoreReqVo; import com.jttech.cmci.pfcs.vo.resp.ZxmxGetScoreRespVo; import com.jttech.cmci.pfcs.content.ZxmxContent; import com.jttech.cmci.pfcs.util.XmlUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.util.Date; /** * @Description:征信模型加工 * @Author:carsonwang * @Date:Created in 2022-04-06 14:39 * @Version: 1.0 */ @Service public class ZxmxManagerService { private Logger mLogger = LoggerFactory.getLogger(getClass()); public ZxmxGetScoreRespVo getScore(ZxmxGetScoreReqVo pReqVo) { mLogger.info("请求报文:{}", pReqVo); JSONObject creditInfo = XmlUtils.xml2Json(pReqVo.getZxData()); creditInfo = creditInfo.getJSONObject(ZxmxContent.reportMessage); // 获取用户信息 UserInfoVo userInfo = getUserInfo(creditInfo); mLogger.info("=================征信模型加工开始,当前用户为:{}=================", userInfo); // 获取逾期总金额(被追偿信息债权金额+非循环贷账户当前逾期总额+循环额度下分账户当前逾期总额+循环贷账户当前逾期总额+贷记卡账户当前逾期总额) Integer overdueTotal = getOverdueTotal(userInfo, creditInfo); // 获取贷记卡授信总额度(所有贷记卡授信金额求和) Integer creditLines = getCreditLines(userInfo, creditInfo); // 获取近六个月平均应还款额 Integer avgUsedOfSixMonth = getAvgUsedOfSixMonth(userInfo, creditInfo); // 获取近一年逾期次数 Integer overdueNumOfYear = getOverdueNumOfYear(userInfo, creditInfo); // 获取近一年查征次数 Integer queryNumOfYear = getQueryNumOfYear(userInfo, creditInfo); ZxmxGetScoreRespVo respVo = new ZxmxGetScoreRespVo(overdueTotal, creditLines, avgUsedOfSixMonth, overdueNumOfYear, queryNumOfYear); mLogger.info("=================征信模型加工结束,当前用户为:{},加工结果为:{}=================", userInfo, respVo); return respVo; } /** * 获取用户信息 * * @param pCreditInfo * @return */ private UserInfoVo getUserInfo(JSONObject pCreditInfo) { JSONObject reportHead = getJsonObject(pCreditInfo, ZxmxContent.ReportHead); JSONObject thisQueryReqInfo = getJsonObject(reportHead, ZxmxContent.ThisQueryReqInfo); String username = thisQueryReqInfo.getString(ZxmxContent.QueryName); String idNo = thisQueryReqInfo.getString(ZxmxContent.QueryCredNum); UserInfoVo userInfo = new UserInfoVo(username, idNo); return userInfo; } /** * 近一年查征次数(根据查征记录中近一年查询次数计算) * * @param pCreditInfo * @return */ private Integer getQueryNumOfYear(UserInfoVo userInfo, JSONObject pCreditInfo) { Integer totalQueryNumOfYear = 0; JSONArray queryInfos = pCreditInfo.getJSONArray(ZxmxContent.QueryInfo); if (!CollectionUtils.isEmpty(queryInfos)) { Date currTime = DateUtil.getDayEndTime(new Date()); Date yearTime = DateUtil.addYear(currTime, -1); for (Object obj : queryInfos) { if (obj != null) { JSONObject queryInfo = (JSONObject) obj; String queryDateStr = queryInfo.getString(ZxmxContent.QueryDate); if (!StringUtils.isEmpty(queryDateStr)) { Date queryDate = DateUtil.parseDate(DateUtil.pattern[2], queryDateStr); if (queryDate.after(yearTime) && queryDate.before(currTime)) { totalQueryNumOfYear++; } } } } } // 获取近一年查征次数 Integer queryNumOfYear = getQueryNumOfYear(totalQueryNumOfYear); mLogger.info("==========================用户:{},近一年查询征信总数为:{},评级为:{}=======================", userInfo, totalQueryNumOfYear, queryNumOfYear); return queryNumOfYear; } /** * 获取近一年查征次数 评级 0 0 1 (0,5] 2 (5,10] 3 (10,15] 4 (15,20] 5 (20,25] 6 (25,30] * 7 (30,35] 8 (35,40] 9 >40 * * @param pTotalQueryNumOfYear * @return */ private Integer getQueryNumOfYear(Integer pTotalQueryNumOfYear) { Integer queryNumOfYear = 0; if (pTotalQueryNumOfYear == 0) { queryNumOfYear = 0; } else if (pTotalQueryNumOfYear > 0 && pTotalQueryNumOfYear <= 5) { queryNumOfYear = 1; } else if (pTotalQueryNumOfYear > 5 && pTotalQueryNumOfYear <= 10) { queryNumOfYear = 2; } else if (pTotalQueryNumOfYear > 10 && pTotalQueryNumOfYear <= 15) { queryNumOfYear = 3; } else if (pTotalQueryNumOfYear > 15 && pTotalQueryNumOfYear <= 20) { queryNumOfYear = 4; } else if (pTotalQueryNumOfYear > 20 && pTotalQueryNumOfYear <= 25) { queryNumOfYear = 5; } else if (pTotalQueryNumOfYear > 25 && pTotalQueryNumOfYear <= 30) { queryNumOfYear = 6; } else if (pTotalQueryNumOfYear > 30 && pTotalQueryNumOfYear <= 35) { queryNumOfYear = 7; } else if (pTotalQueryNumOfYear > 35 && pTotalQueryNumOfYear <= 40) { queryNumOfYear = 8; } else if (pTotalQueryNumOfYear > 40) { queryNumOfYear = 9; } return queryNumOfYear; } /** * 近一年逾期次数("非循环贷账户/循环额度下分账户/循环贷账户/贷记卡账户/准贷记卡账户 账户中近一年还款月中为逾期的总次数") * * @param pCreditInfo * @return */ private Integer getOverdueNumOfYear(UserInfoVo userInfo, JSONObject pCreditInfo) { JSONObject creditTranDetailsInfo = getJsonObject(pCreditInfo, ZxmxContent.creditTranDetailsInfo); if (creditTranDetailsInfo == null) { return -1; } // 6.4.2 非循环贷账户 D1【NonrevolvingLoanDetInfo】 JSONArray nonrevolvingLoanDetInfos = creditTranDetailsInfo.getJSONArray(ZxmxContent.nonrevolvingLoanDetInfo); // 6.4.2.4 最近五年内历史表现信息【Last5YearsHisPerFmInfo】 content Integer nonrevolvingOverdueNum = 0; if (!CollectionUtils.isEmpty(nonrevolvingLoanDetInfos)) { for (Object obj : nonrevolvingLoanDetInfos) { if (obj != null) { JSONObject nonrevolvingLoanDetInfo = (JSONObject) obj; JSONObject last5YearsHisPerFmInfo = getJsonObject(nonrevolvingLoanDetInfo, ZxmxContent.Last5YearsHisPerFmInfo); if (last5YearsHisPerFmInfo != null) { nonrevolvingOverdueNum = nonrevolvingOverdueNum + getOverdueNum(last5YearsHisPerFmInfo); } } } } mLogger.info("非循环贷账户,最近五年内历史表现信息,逾期次数:{}", nonrevolvingOverdueNum); // 6.4.3 循环额度下分账户 R4【LoopQuotaSubAct】 JSONArray loopQuotaSubActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.LoopQuotaSubAct); // 6.4.3.4最近五年内历史表现信息【Last5YearsHisPerfmInfo】 content Integer loopOverdueNum = 0; if (!CollectionUtils.isEmpty(loopQuotaSubActs)) { for (Object obj : loopQuotaSubActs) { if (obj != null) { JSONObject loopQuotaSubAct = (JSONObject) obj; JSONObject last5YearsHisPerFmInfo = getJsonObject(loopQuotaSubAct, ZxmxContent.Last5YearsHisPerFmInfo); if (last5YearsHisPerFmInfo != null) { loopOverdueNum = loopOverdueNum + getOverdueNum(last5YearsHisPerFmInfo); } } } } mLogger.info("循环额度下分账户,最近五年内历史表现信息,逾期次数:{}", loopOverdueNum); // 6.4.4 循环贷账户 R1【RevolvinLoanAct】 JSONArray revolvinLoanActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.RevolvinLoanAct); // 6.4.4.4最近五年内历史表现信息【Last5YearsHisPerfmInfo】 content Integer revolvinOverdueNum = 0; if (!CollectionUtils.isEmpty(revolvinLoanActs)) { for (Object obj : revolvinLoanActs) { if (obj != null) { JSONObject revolvinLoanAct = (JSONObject) obj; JSONObject last5YearsHisPerFmInfo = getJsonObject(revolvinLoanAct, ZxmxContent.Last5YearsHisPerFmInfo); if (last5YearsHisPerFmInfo != null) { revolvinOverdueNum = revolvinOverdueNum + getOverdueNum(last5YearsHisPerFmInfo); } } } } mLogger.info("循环贷账户,最近五年内历史表现信息,逾期次数:{}", revolvinOverdueNum); // 6.4.5 贷记卡账户 R2【CreditCardAct】 JSONArray creditCardActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.CreditCardAct); // 6.4.5.5最近五年内历史表现信息【Last5YearsHisPerfmInfo】 content Integer creditCardOverdueNum = 0; if (!CollectionUtils.isEmpty(creditCardActs)) { for (Object obj : creditCardActs) { if (obj != null) { JSONObject creditCardAct = (JSONObject) obj; JSONObject last5YearsHisPerFmInfo = getJsonObject(creditCardAct, ZxmxContent.Last5YearsHisPerFmInfo); if (last5YearsHisPerFmInfo != null) { creditCardOverdueNum = creditCardOverdueNum + getOverdueNum(last5YearsHisPerFmInfo); } } } } mLogger.info("贷记卡账户,最近五年内历史表现信息,逾期次数:{}", creditCardOverdueNum); // 6.4.6 准贷记卡账户 R3【SemiCreditCardAct】 JSONArray semiCreditCardActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.SemiCreditCardAct); // 6.4.6.4最近五年内历史表现信息【Last5YearsHisPerfmInfo】 content Integer semiCreditCardOverdueNum = 0; if (!CollectionUtils.isEmpty(semiCreditCardActs)) { for (Object obj : semiCreditCardActs) { if (obj != null) { JSONObject semiCreditCardAct = (JSONObject) obj; JSONObject last5YearsHisPerFmInfo = getJsonObject(semiCreditCardAct, ZxmxContent.Last5YearsHisPerFmInfo); if (last5YearsHisPerFmInfo != null) { semiCreditCardOverdueNum = semiCreditCardOverdueNum + getOverdueNum(last5YearsHisPerFmInfo); } } } } mLogger.info("准贷记卡账户,最近五年内历史表现信息,逾期次数:{}", semiCreditCardOverdueNum); Integer totalOverdueNum = nonrevolvingOverdueNum + loopOverdueNum + revolvinOverdueNum + creditCardOverdueNum + semiCreditCardOverdueNum; Integer overdueNumOfYear = getOverdueNumOfYear(totalOverdueNum); mLogger.info("==========================用户:{},近一年逾期次数总数:{},评级为:{}=======================", userInfo, totalOverdueNum, overdueNumOfYear); return overdueNumOfYear; } /** * 近一年逾期次数 评级 0 0 1 (0,5] 2 (5,10] 3 (10,15] 4 (15,20] 5 (20,25] 6 (25,30] 7 * (30,35] 8 (35,40] 9 >40 * * @param pTotalOverdueNum * @return */ private Integer getOverdueNumOfYear(Integer pTotalOverdueNum) { Integer overdueNumOfYear = 0; if (pTotalOverdueNum == 0) { overdueNumOfYear = 0; } else if (pTotalOverdueNum > 0 && pTotalOverdueNum <= 5) { overdueNumOfYear = 1; } else if (pTotalOverdueNum > 5 && pTotalOverdueNum <= 10) { overdueNumOfYear = 2; } else if (pTotalOverdueNum > 10 && pTotalOverdueNum <= 15) { overdueNumOfYear = 3; } else if (pTotalOverdueNum > 15 && pTotalOverdueNum <= 20) { overdueNumOfYear = 4; } else if (pTotalOverdueNum > 20 && pTotalOverdueNum <= 25) { overdueNumOfYear = 5; } else if (pTotalOverdueNum > 25 && pTotalOverdueNum <= 30) { overdueNumOfYear = 6; } else if (pTotalOverdueNum > 30 && pTotalOverdueNum <= 35) { overdueNumOfYear = 7; } else if (pTotalOverdueNum > 35 && pTotalOverdueNum <= 40) { overdueNumOfYear = 8; } else if (pTotalOverdueNum > 40) { overdueNumOfYear = 9; } return overdueNumOfYear; } /** * 各个账户明细还款记录,从最后一个还款日往前推12个还款日,还款记录 近一年非*且非n且非m且非c次数之和 * * @param pLast5YearsHisPerFmInfo * @return */ private Integer getOverdueNum(JSONObject pLast5YearsHisPerFmInfo) { Integer overdueNum = 0; String content = pLast5YearsHisPerFmInfo.getString(ZxmxContent.Content); if (!StringUtils.isEmpty(content)) { String[] repayInfos = content.split(ZxmxContent.VERTICAL_LINE); for (int i = 0; i < 12; i++) { // 如果索引大于长度,直接跳出循环 if (i > repayInfos.length - 1) { break; } String repayInfo = repayInfos[i]; if (!(repayInfo.startsWith("*") || repayInfo.startsWith("N") || repayInfo.startsWith("M") || repayInfo.startsWith("C"))) { overdueNum++; } } } return overdueNum; } /** * 近六个月平均应还款额(信贷交易授信及负债信息概要 * :非循环贷账户信息汇总-最近6个月平均应还款+循环额度下分账户信息汇总-最近6个月平均应还款+循环贷账户信息汇总-最近6个月平均应还+ * 贷记卡账户信息汇总-最近6个月平均使用额度+准贷记卡账户信息汇总-最近6个月平均透支余额) * * @param pCreditInfo * @return */ private Integer getAvgUsedOfSixMonth(UserInfoVo userInfo, JSONObject pCreditInfo) { JSONObject creditTranDetailsInfo = getJsonObject(pCreditInfo, ZxmxContent.creditTranDetailsInfo); if (creditTranDetailsInfo == null) { return -1; } // 非循环贷账户信息汇总 - 6.4.2.3 最近一次月度表现信息 最近 6 个月平均使用额度 BigDecimal nonrevolvingAvgUsedOfSixMonth = BigDecimal.ZERO; JSONArray nonrevolvingLoanDetInfos = creditTranDetailsInfo.getJSONArray(ZxmxContent.nonrevolvingLoanDetInfo); if (!CollectionUtils.isEmpty(nonrevolvingLoanDetInfos)) { for (Object obj : nonrevolvingLoanDetInfos) { if (obj != null) { JSONObject nonrevolvingLoanDetInfo = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(nonrevolvingLoanDetInfo, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { nonrevolvingAvgUsedOfSixMonth = nonrevolvingAvgUsedOfSixMonth .add(getAmount(latestMonPerfmInfo, ZxmxContent.avgUsedOfSixMonth)); } } } } mLogger.info("非循环贷账户信息汇总 - 最近一次月度表现信息 最近 6 个月平均使用额度:{}", nonrevolvingAvgUsedOfSixMonth); // 循环额度下分账户信息汇总 - 6.4.3.3 最近一次月度表现信息 最近 6 个月平均使用额度 BigDecimal loopAvgUsedOfSixMonth = BigDecimal.ZERO; JSONArray loopQuotaSubActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.LoopQuotaSubAct); if (!CollectionUtils.isEmpty(loopQuotaSubActs)) { for (Object obj : loopQuotaSubActs) { if (obj != null) { JSONObject loopQuotaSubAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(loopQuotaSubAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { loopAvgUsedOfSixMonth = loopAvgUsedOfSixMonth .add(getAmount(latestMonPerfmInfo, ZxmxContent.avgUsedOfSixMonth)); } } } } mLogger.info("循环额度下分账户信息汇总 - 最近一次月度表现信息 最近 6 个月平均使用额度:{}", loopAvgUsedOfSixMonth); // 循环贷账户信息汇总 - 6.4.4.3 最近一次月度表现信息 最近 6 个月平均使用额度 BigDecimal revolvinAvgUsedOfSixMonth = BigDecimal.ZERO; JSONArray revolvinLoanActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.RevolvinLoanAct); if (!CollectionUtils.isEmpty(revolvinLoanActs)) { for (Object obj : revolvinLoanActs) { if (obj != null) { JSONObject revolvinLoanAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(revolvinLoanAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { revolvinAvgUsedOfSixMonth = revolvinAvgUsedOfSixMonth .add(getAmount(latestMonPerfmInfo, ZxmxContent.avgUsedOfSixMonth)); } } } } mLogger.info("循环贷账户信息汇总 - 最近一次月度表现信息 最近 6 个月平均使用额度:{}", revolvinAvgUsedOfSixMonth); // 贷记卡账户信息汇总 - 6.4.5.3 最近一次月度表现信息 最近 6 个月平均使用额度 BigDecimal creditCardAvgUsedOfSixMonth = BigDecimal.ZERO; JSONArray creditCardActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.CreditCardAct); if (!CollectionUtils.isEmpty(creditCardActs)) { for (Object obj : creditCardActs) { if (obj != null) { JSONObject creditCardAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(creditCardAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { creditCardAvgUsedOfSixMonth = creditCardAvgUsedOfSixMonth .add(getAmount(latestMonPerfmInfo, ZxmxContent.avgUsedOfSixMonth)); } } } } mLogger.info("贷记卡账户信息汇总 - 最近一次月度表现信息 最近 6 个月平均使用额度:{}", creditCardAvgUsedOfSixMonth); // 准贷记卡账户信息汇总 - 6.4.6.3 最近一次月度表现信息 最近 6 个月平均使用额度 BigDecimal semiCreditCardAvgUsedOfSixMonth = BigDecimal.ZERO; JSONArray semiCreditCardActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.SemiCreditCardAct); if (!CollectionUtils.isEmpty(semiCreditCardActs)) { for (Object obj : semiCreditCardActs) { if (obj != null) { JSONObject semiCreditCardAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(semiCreditCardAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { semiCreditCardAvgUsedOfSixMonth = semiCreditCardAvgUsedOfSixMonth .add(getAmount(latestMonPerfmInfo, ZxmxContent.avgUsedOfSixMonth)); } } } } mLogger.info("准贷记卡账户信息汇总 - 最近一次月度表现信息 最近 6 个月平均使用额度:{}", semiCreditCardAvgUsedOfSixMonth); BigDecimal totalAvgUsedOfSixMonth = nonrevolvingAvgUsedOfSixMonth.add(loopAvgUsedOfSixMonth) .add(revolvinAvgUsedOfSixMonth).add(creditCardAvgUsedOfSixMonth).add(semiCreditCardAvgUsedOfSixMonth); // 获取近六个月平均应还款额 Integer avgUsedOfSixMonth = getAvgUsedOfSixMonth(totalAvgUsedOfSixMonth); mLogger.info("==========================用户:{},近六个月平均应还款总额:{},评级为:{}======================", userInfo, totalAvgUsedOfSixMonth, avgUsedOfSixMonth); return avgUsedOfSixMonth; } /** * 获取近六个月平均应还款额评级 0 0 1 (0,10000) 2 (10000,20000] 3 (20000,30000] 4 * (30000,40000] 5 (40000,50000] 6 (50000,60000] 7 (60000,70000] 8 * (70000,80000] 9 >80000 * * @param pTotalAvgUsedOfSixMonth * @return */ private Integer getAvgUsedOfSixMonth(BigDecimal pTotalAvgUsedOfSixMonth) { Integer avgUsedOfSixMonth = 0; if (pTotalAvgUsedOfSixMonth.compareTo(BigDecimal.ZERO) == 0) { avgUsedOfSixMonth = 0; } else if (pTotalAvgUsedOfSixMonth.compareTo(BigDecimal.ZERO) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("10000")) <= 0) { avgUsedOfSixMonth = 1; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("10000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("20000")) <= 0) { avgUsedOfSixMonth = 2; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("20000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("30000")) <= 0) { avgUsedOfSixMonth = 3; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("30000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("40000")) <= 0) { avgUsedOfSixMonth = 4; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("40000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("50000")) <= 0) { avgUsedOfSixMonth = 5; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("50000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("60000")) <= 0) { avgUsedOfSixMonth = 6; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("60000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("70000")) <= 0) { avgUsedOfSixMonth = 7; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("70000")) > 0 && pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("80000")) <= 0) { avgUsedOfSixMonth = 8; } else if (pTotalAvgUsedOfSixMonth.compareTo(new BigDecimal("80000")) > 0) { avgUsedOfSixMonth = 9; } return avgUsedOfSixMonth; } /** * 所有贷记卡授信金额求和 * * @param pCreditInfo * @return */ private Integer getCreditLines(UserInfoVo userInfo, JSONObject pCreditInfo) { JSONObject creditTranDetailsInfo = getJsonObject(pCreditInfo, ZxmxContent.creditTranDetailsInfo); if (creditTranDetailsInfo == null) { return -1; } BigDecimal lines = BigDecimal.ZERO; JSONArray creditCardActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.CreditCardAct); if (!CollectionUtils.isEmpty(creditCardActs)) { for (Object obj : creditCardActs) { JSONObject creditCardAct = (JSONObject) obj; JSONObject baseInfo = getJsonObject(creditCardAct, ZxmxContent.baseInfo); if (baseInfo != null) { lines = lines.add(getAmount(baseInfo, ZxmxContent.Lines)); } } } Integer creditLines = getCreditLines(lines); mLogger.info("==========================用户:{},所有贷记卡授信金额:{},评级为:{}========================", userInfo, lines, creditLines); return creditLines; } /** * 授信额度分级 0 0 1 (0,30000] 2 (30000,50000] 3 (50000,70000] 4 (70000,90000] 5 * (90000,110000] 6 (110000,130000] 7 (130000,150000] 8 (150000,200000] 9 * >200000 * * @param lines * @return */ private Integer getCreditLines(BigDecimal lines) { Integer overdueTotal = 0; if (lines.compareTo(BigDecimal.ZERO) == 0) { overdueTotal = 0; } else if (lines.compareTo(BigDecimal.ZERO) > 0 && lines.compareTo(new BigDecimal("30000")) <= 0) { overdueTotal = 1; } else if (lines.compareTo(new BigDecimal("30000")) > 0 && lines.compareTo(new BigDecimal("50000")) <= 0) { overdueTotal = 2; } else if (lines.compareTo(new BigDecimal("50000")) > 0 && lines.compareTo(new BigDecimal("70000")) <= 0) { overdueTotal = 3; } else if (lines.compareTo(new BigDecimal("70000")) > 0 && lines.compareTo(new BigDecimal("90000")) <= 0) { overdueTotal = 4; } else if (lines.compareTo(new BigDecimal("90000")) > 0 && lines.compareTo(new BigDecimal("110000")) <= 0) { overdueTotal = 5; } else if (lines.compareTo(new BigDecimal("110000")) > 0 && lines.compareTo(new BigDecimal("130000")) <= 0) { overdueTotal = 6; } else if (lines.compareTo(new BigDecimal("130000")) > 0 && lines.compareTo(new BigDecimal("150000")) <= 0) { overdueTotal = 7; } else if (lines.compareTo(new BigDecimal("150000")) > 0 && lines.compareTo(new BigDecimal("200000")) <= 0) { overdueTotal = 8; } else if (lines.compareTo(new BigDecimal("200000")) > 0) { overdueTotal = 9; } return overdueTotal; } /** * 获取逾期总金额(被追偿信息债权金额+非循环贷账户当前逾期总额+循环额度下分账户当前逾期总额+循环贷账户当前逾期总额+贷记卡账户当前逾期总额) * * @param pCreditInfo * @return */ private Integer getOverdueTotal(UserInfoVo userInfo, JSONObject pCreditInfo) { JSONObject creditTranDetailsInfo = getJsonObject(pCreditInfo, ZxmxContent.creditTranDetailsInfo); if (creditTranDetailsInfo == null) { return -1; } // 6.4.1.1 基本信息【BaseInfo】 Money 债权金额 BigDecimal money = BigDecimal.ZERO; JSONObject beRecoveryDetailsInfo = getJsonObject(creditTranDetailsInfo, ZxmxContent.beRecoveryDetailsInfo); if (beRecoveryDetailsInfo != null) { JSONObject baseInfo = getJsonObject(beRecoveryDetailsInfo, ZxmxContent.baseInfo); if (baseInfo != null) { money = getAmount(baseInfo, ZxmxContent.money); } } mLogger.info("被追偿信息债权金额,基本信息,债权金额:{}", money); // 6.4.2.3 最近一次月度表现信息 CurrentOverdueTotal BigDecimal nonrevolvingOverdueTotal = BigDecimal.ZERO; JSONArray nonrevolvingLoanDetInfos = creditTranDetailsInfo.getJSONArray(ZxmxContent.nonrevolvingLoanDetInfo); if (!CollectionUtils.isEmpty(nonrevolvingLoanDetInfos)) { for (Object obj : nonrevolvingLoanDetInfos) { if (obj != null) { JSONObject nonrevolvingLoanDetInfo = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(nonrevolvingLoanDetInfo, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { nonrevolvingOverdueTotal = nonrevolvingOverdueTotal .add(getAmount(latestMonPerfmInfo, ZxmxContent.currentOverdueTotal)); } } } } mLogger.info("非循环贷账户,最近一次月度表现信息,当前逾期总额:{}", nonrevolvingOverdueTotal); // 6.4.3.3 最近一次月度表现信息 CurrentOverdueTotal BigDecimal loopOverdueTotal = BigDecimal.ZERO; JSONArray loopQuotaSubActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.LoopQuotaSubAct); if (!CollectionUtils.isEmpty(loopQuotaSubActs)) { for (Object obj : loopQuotaSubActs) { if (obj != null) { JSONObject loopQuotaSubAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(loopQuotaSubAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { loopOverdueTotal = loopOverdueTotal .add(getAmount(latestMonPerfmInfo, ZxmxContent.currentOverdueTotal)); } } } } mLogger.info("循环额度下分账户,最近一次月度表现信息,当前逾期总额:{}", loopOverdueTotal); // 6.4.4.3 最近一次月度表现信息 CurrentOverdueTotal BigDecimal revolvinOverdueTotal = BigDecimal.ZERO; JSONArray revolvinLoanActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.RevolvinLoanAct); if (!CollectionUtils.isEmpty(revolvinLoanActs)) { for (Object obj : revolvinLoanActs) { if (obj != null) { JSONObject revolvinLoanAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(revolvinLoanAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { revolvinOverdueTotal = revolvinOverdueTotal .add(getAmount(latestMonPerfmInfo, ZxmxContent.currentOverdueTotal)); } } } } mLogger.info("循环贷账户,最近一次月度表现信息,当前逾期总额:{}", revolvinOverdueTotal); // 6.4.5.3 最近一次月度表现信息 CurrentOverdueTotal BigDecimal creditCardOverdueTotal = BigDecimal.ZERO; JSONArray creditCardActs = creditTranDetailsInfo.getJSONArray(ZxmxContent.CreditCardAct); if (!CollectionUtils.isEmpty(creditCardActs)) { for (Object obj : creditCardActs) { if (obj != null) { JSONObject creditCardAct = (JSONObject) obj; JSONObject latestMonPerfmInfo = getJsonObject(creditCardAct, ZxmxContent.latestMonPerfmInfo); if (latestMonPerfmInfo != null) { creditCardOverdueTotal = creditCardOverdueTotal .add(getAmount(latestMonPerfmInfo, ZxmxContent.currentOverdueTotal)); } } } } mLogger.info("贷记卡账户,最近一次月度表现信息,当前逾期总额:{}", creditCardOverdueTotal); BigDecimal totalOverdueTotal = money.add(nonrevolvingOverdueTotal).add(loopOverdueTotal) .add(revolvinOverdueTotal).add(creditCardOverdueTotal); Integer overdueTotal = getOverdueTotal(totalOverdueTotal); mLogger.info("==========================用户:{},获取逾期总金额:{},评级:{}==========================", userInfo, totalOverdueTotal, overdueTotal); return overdueTotal; } /** * 0 0 1 (0,10000) 2 (10000,20000] 3 (20000,30000] 4 (30000,40000] 5 * (40000,50000] 6 (50000,60000] 7 (60000,70000] 8 (70000,80000] 9 >80000 * * @param totalOverdueTotal * @return */ private Integer getOverdueTotal(BigDecimal totalOverdueTotal) { Integer overdueTotal = 0; if (totalOverdueTotal.compareTo(BigDecimal.ZERO) == 0) { overdueTotal = 0; } else if (totalOverdueTotal.compareTo(BigDecimal.ZERO) > 0 && totalOverdueTotal.compareTo(new BigDecimal("10000")) <= 0) { overdueTotal = 1; } else if (totalOverdueTotal.compareTo(new BigDecimal("10000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("20000")) <= 0) { overdueTotal = 2; } else if (totalOverdueTotal.compareTo(new BigDecimal("20000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("30000")) <= 0) { overdueTotal = 3; } else if (totalOverdueTotal.compareTo(new BigDecimal("30000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("40000")) <= 0) { overdueTotal = 4; } else if (totalOverdueTotal.compareTo(new BigDecimal("40000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("50000")) <= 0) { overdueTotal = 5; } else if (totalOverdueTotal.compareTo(new BigDecimal("50000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("60000")) <= 0) { overdueTotal = 6; } else if (totalOverdueTotal.compareTo(new BigDecimal("60000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("70000")) <= 0) { overdueTotal = 7; } else if (totalOverdueTotal.compareTo(new BigDecimal("70000")) > 0 && totalOverdueTotal.compareTo(new BigDecimal("80000")) <= 0) { overdueTotal = 8; } else if (totalOverdueTotal.compareTo(new BigDecimal("80000")) > 0) { overdueTotal = 9; } return overdueTotal; } /** * 获取金额 * * @param pJsonObject * @param pKeyName * @return */ private BigDecimal getAmount(JSONObject pJsonObject, String pKeyName) { mLogger.info("获取参数:{},在对象:{}的值", pKeyName, pJsonObject); String num = pJsonObject.getString(pKeyName); if (StringUtils.isEmpty(num)) { return BigDecimal.ZERO; } return new BigDecimal(num.replaceAll(ZxmxContent.SIGN_COMMA, ZxmxContent.EMPTY_STR)); } /** * 获取json对象 * * @param pJsonObject * @param pKeyName * @return */ private JSONObject getJsonObject(JSONObject pJsonObject, String pKeyName) { mLogger.info("获取参数:{},在对象:{}的值", pKeyName, pJsonObject); JSONArray jsonArray = pJsonObject.getJSONArray(pKeyName); if (CollectionUtils.isEmpty(jsonArray)) { return null; } return (JSONObject) jsonArray.get(0); } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/DateUtil.java
New file @@ -0,0 +1,955 @@ package com.jttech.cmci.pfcs.util; import org.springframework.util.StringUtils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; public class DateUtil { public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd"); private static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; public static String[] pattern = new String[] { "yyyyMMdd", "yyyy-MM-dd", "yyyy.MM.dd", "yyyy/MM/dd", "yyyy-MM", "yyyyMM", "yyyy/MM", "yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyyMMddHHmmssSSS", "HH:mm", "HHmmss", "MM-dd HH:mm", "YYYY-MM-dd HH:mm", "MM-dd HH:mm:ss" }; public static Date previous(int days) { return new Date(System.currentTimeMillis() - days * 3600000L * 24L); } public static Date addDay(Date date, int days) { return new Date(date.getTime() + days * 3600000L * 24L); } public static Date addMin(Date date, int mins) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MINUTE, mins); // System.out.println(c.getTime()); return c.getTime(); } public static Date addHour(Date date, int hours) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.HOUR_OF_DAY, hours); // System.out.println(c.getTime()); return c.getTime(); } public static String formatDateTime(String format, long d) { return new SimpleDateFormat(format).format(d); } public static String formatDate(String format, Date d) { return StringUtils.isEmpty(format) || null == d ? "" : new SimpleDateFormat(format).format(d); } public static String formatDate(Date d) { return formatDate(pattern[7], d); } public static Date parseDate(String format, String d) { try { return new SimpleDateFormat(format).parse(d); } catch (Exception e) { throw new RuntimeException("需要时间格式为:" + format); } } public static Date getNextWeekDay(int weekDay) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); int addDateNumber = 0; if (Calendar.SUNDAY == calendar.get(Calendar.DAY_OF_WEEK)) { if (Calendar.SUNDAY == weekDay) { addDateNumber = 7; } } else { addDateNumber = 7; if (Calendar.SUNDAY == weekDay) { addDateNumber = 14; } } calendar.add(Calendar.DATE, addDateNumber); calendar.set(Calendar.DAY_OF_WEEK, weekDay); return calendar.getTime(); } public static Date getThisWeekMonday() { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); int min = calendar.getActualMinimum(Calendar.DAY_OF_WEEK); // 获取周开始基准 int current = calendar.get(Calendar.DAY_OF_WEEK); // 获取当天周内天数 calendar.add(Calendar.DAY_OF_WEEK, min - current + 1); // 当天-基准,获取周开始日期 return calendar.getTime(); } /** * 获取所在日期周的星期一(周一到周日为一周) * * @return 日期所在周的星期一 */ public static Date getWeekMonday(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); int min = calendar.getActualMinimum(Calendar.DAY_OF_WEEK); // 获取周开始基准 int current = calendar.get(Calendar.DAY_OF_WEEK); // 获取当天周内天数 calendar.add(Calendar.DAY_OF_WEEK, min - current + 1 + (current == Calendar.SUNDAY ? -7 : 0)); // 当天-基准,获取周开始日期 return calendar.getTime(); } public static Date parse(String str) { try { return threadLocal.get().parse(str); } catch (ParseException e) { e.printStackTrace(); return null; } } /** * 获取字符串当月第一天,需要date(yyyy-MM-dd) * * @param date * @return */ public static String getFirstDayOfMonth(String date) { return getFirstDayOfMonth(parse(date)); } /** * 获取字符串当月最后一天 * * @param date * @return */ public static String getFirstDayOfMonth(String format, String date) { return getFirstDayOfMonth(parseDate(format, date)); } /** * 获取字符串当月第一天,需要date(yyyy-MM-dd) * * @param date * @return */ public static String getEndDayOfMonth(String date) { return getEndDayOfMonth(parse(date)); } /** * 获取字符串当月最后一天 * * @param date * @return */ public static String getEndDayOfMonth(String format, String date) { return getEndDayOfMonth(parseDate(format, date)); } /** * 获取字符串当月最后一天 * * @param date * @return */ public static Date getFirstDayDateOfMonth(String format, String date) { return getFirstDayDateOfMonth(parseDate(format, date)); } /** * 获取字符串当月最后一天 * * @param date * @return */ public static Date getEndDayDateOfMonth(String format, String date) { return getEndDayDateOfMonth(parseDate(format, date)); } public static String getFirstDayOfMonth(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.DATE, 1); return threadLocal.get().format(cal.getTime()); } public static String getEndDayOfMonth(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); return threadLocal.get().format(cal.getTime()); } public static Date getFirstDayDateOfMonth(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.DATE, 1); return cal.getTime(); } public static Date getEndDayDateOfMonth(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); return cal.getTime(); } public static Date addMonth(Date date, int count) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(2, count); return c.getTime(); } public static Date addYear(Date date, int count) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.YEAR, count); return c.getTime(); } public static String getCurrentDate() { return threadLocal.get().format(new Date()); } public static Date getTodayDate() { try { return threadLocal.get().parse(getCurrentDate()); } catch (ParseException e) { throw new RuntimeException(); } } public static int getDayOfWeek() { Calendar cal = Calendar.getInstance(); return cal.get(7); } public static int getDayOfWeek(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.get(7); } public static int getDayOfWeek(String date) { Calendar cal = Calendar.getInstance(); cal.setTime(parse(date)); return cal.get(7); } public static int getMaxDayOfMonth(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.getActualMaximum(5); } public static String toString(Date date) { if (date == null) return ""; else return threadLocal.get().format(date); } public static String toString(Date date, String format) { SimpleDateFormat t = new SimpleDateFormat(format); return t.format(date); } // 获取当前年 public static String getYear() { SimpleDateFormat formatter = new SimpleDateFormat("yyyy"); return formatter.format(new Date()); } // 获取年 public static String getYear(Date date) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy"); return formatter.format(date); } // 获取当年月 public static String getMonth() { SimpleDateFormat formatter = new SimpleDateFormat("MM"); return formatter.format(new Date()); } // 获取当年月 public static String getYearMonth() { SimpleDateFormat formatter = new SimpleDateFormat("yyyyMM"); return formatter.format(new Date()); } // 获取月 public static String getMonth(Date date) { SimpleDateFormat formatter = new SimpleDateFormat("MM"); return formatter.format(date); } // 获取当日 public static String getDay() { SimpleDateFormat formatter = new SimpleDateFormat("dd"); return formatter.format(new Date()); } // 获取日 public static String getDay(Date date) { SimpleDateFormat formatter = new SimpleDateFormat("dd"); return formatter.format(date); } /** * 月 * * @return */ public static List<String> getMonthList() { List<String> list = new ArrayList<String>(); list.add("01"); list.add("02"); list.add("03"); list.add("04"); list.add("05"); list.add("06"); list.add("07"); list.add("08"); list.add("09"); list.add("10"); list.add("11"); list.add("12"); return list; } // 计算相差时间 public static double dateDiff(String startTime, String endTime, String format) { SimpleDateFormat sd = new SimpleDateFormat(format); long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数 long nh = 1000 * 60 * 60;// 一小时的毫秒数 long diff; double hour = 0; try { // 获得两个时间的毫秒时间差异 diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime(); hour = (diff % nd) * 1.0f / nh;// 计算差多少小时 } catch (ParseException e) { e.printStackTrace(); } // DecimalFormat df = new DecimalFormat("#.00"); System.out.println(new Double(String.format("%.2f", hour))); return new Double(String.format("%.2f", hour)); } // 计算相差天数时间 public static int dateDayDiff(String startTime, String endTime, String format) { SimpleDateFormat sd = new SimpleDateFormat(format); long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数 long diff; int day = 0; try { // 获得两个时间的毫秒时间差异 diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime(); day = (int) (diff / nd);// 计算差多少天 } catch (ParseException e) { e.printStackTrace(); } return day; } public static List<WeekDay> getDisplayWeekDays(Date startTime, Date endTime) { List<WeekDay> weekDays = new ArrayList<WeekDay>(); Date date = startTime; long endTimeLong = endTime.getTime(); while (date.getTime() <= endTimeLong) { weekDays.add(new WeekDay(date)); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DATE, 1); date = calendar.getTime(); } return weekDays; } public static class WeekDay { private Date date; private static final String[] WEEK_DAY_NAME = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; public WeekDay() { } public WeekDay(Date date) { this.setDate(date); } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @SuppressWarnings("deprecation") @Override public String toString() { return threadLocal.get().format(date) + "(" + WEEK_DAY_NAME[date.getDay()] + ")"; } @SuppressWarnings("deprecation") public String getDay() { return WEEK_DAY_NAME[date.getDay()]; } } // 指定日期所在月的第一天日期 public static Date getBeginDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.DATE, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); } // 获取指定日期的下个月的日期 public static Date getNextBeginDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.DATE, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.add(Calendar.MONTH, +1); return calendar.getTime(); } // 指定日期所在年的第一天日期 public static Date getBeginDayOfYear(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.MONTH, 0); calendar.set(Calendar.DATE, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); } public static Date getEndDayOfYear(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH)); calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE)); calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY)); calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); return calendar.getTime(); } // 获取指定日期的下年的日期 public static Date getNextBeginDayOfYear(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.MONTH, 1); calendar.set(Calendar.DATE, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.add(Calendar.YEAR, +1); return calendar.getTime(); } /** * @param startDate * @param endDate * @return * @功能描述: * <p> * 获取两个时间相差秒 * </p> * @创建作者: lance * @创建日期: 2016年12月12日 下午12:02:30 */ public static Integer getTimeSecond(Date startDate, Date endDate) { long start = startDate.getTime(); long end = endDate.getTime(); int second = (int) ((end - start) / 1000); return second; } /** * @param beginDate * @param endDate * @return * @功能描述: * <p> * 获取两个日期之间的天数 * </p> * @创建作者: lance * @创建日期: 2017年1月6日 上午10:52:47 */ public static Integer getDays(String beginDate, String endDate) { SimpleDateFormat sd = new SimpleDateFormat(DateUtil.pattern[1]); try { return (int) ((sd.parse(endDate).getTime() - sd.parse(beginDate).getTime()) / 86400000); } catch (ParseException e) { e.printStackTrace(); } return null; } /** * @param beginDate * @param endDate * @return * @功能描述: * <p> * 获取两个日期之间的天数 * </p> * @创建作者: lance * @创建日期: 2017年1月6日 上午10:52:47 */ public static Integer getDays(Date beginDate, Date endDate) { return (int) ((getDayBeginTime(endDate).getTime() - getDayBeginTime(beginDate).getTime()) / 86400000); } /** * @param date * @return * @功能描述: * <p> * 获取两个日期之间的天数 * </p> * @创建作者: lance * @创建日期: 2017年1月6日 上午10:52:47 */ public static Date getDayBeginTime(Date date) { try { String dateStr = threadLocal.get().format(date); return threadLocal.get().parse(dateStr); } catch (ParseException e) { e.printStackTrace(); } return null; } public static Integer getDayOfHour(Date date) { String hour = new SimpleDateFormat("HH").format(date); return Integer.valueOf(hour); } public static Integer getDayOfMinute(Date date) { String hour = new SimpleDateFormat("mm").format(date); return Integer.valueOf(hour); } public static Date getDayEndTime(Date date) { try { return new Date(getDayBeginTime(date).getTime() + 0x5265BFFL); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 获取当前时间距离当天结束的分钟数 * * @param date * @return */ public static Integer getDayEndMinute(Date date) { Date dayEndTime = getDayEndTime(date); Integer timeSecond = getTimeSecond(date, dayEndTime); return timeSecond / 60; } /** * 计算两点时间间隔年 * * @param startTime * @param endTime * @param format * @return */ public static int betweenTimesYear(String startTime, String endTime, String format) { SimpleDateFormat sd = new SimpleDateFormat(format); int year = 0; try { long end = sd.parse(endTime).getTime(); long start = sd.parse(startTime).getTime(); long oneYear = 1000l * 60 * 60 * 24 * 365; year = (int) ((end - start) / oneYear); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return year; } public static int getAgeByBirth(Date birthday) { int age = 0; try { Calendar now = Calendar.getInstance(); now.setTime(new Date());// 当前时间 Calendar birth = Calendar.getInstance(); birth.setTime(birthday); if (birth.after(now)) {// 如果传入的时间,在当前时间的后面,返回0岁 age = 0; } else { age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR); if (now.get(Calendar.DAY_OF_YEAR) < birth.get(Calendar.DAY_OF_YEAR)) { age -= 1; } } return age; } catch (Exception e) { throw new RuntimeException("身份证号异常"); } } /** * 获取精确到秒的时间戳 * * @param pDate * @return */ public static int getSecondTimestamp(Date pDate) { if (null == pDate) { return 0; } String timestamp = String.valueOf(pDate.getTime() / 1000); return Integer.valueOf(timestamp); } /** * 秒时间戳转成时间 * * @param pSecondTimestamp * @return */ public static Date parseSecondTimestamp(int pSecondTimestamp) { Date date = null; if (pSecondTimestamp != 0) { date = new Date(pSecondTimestamp * 1000L); } return date; } public static Date getLastQuarterStartTime() { Calendar startCalendar = Calendar.getInstance(); startCalendar.set(Calendar.MONTH, (startCalendar.get(Calendar.MONTH) / 3 - 1) * 3); startCalendar.set(Calendar.DAY_OF_MONTH, 1); setMinTime(startCalendar); return startCalendar.getTime(); } public static Date getLastQuarterEndTime() { Calendar endCalendar = Calendar.getInstance(); endCalendar.set(Calendar.MONTH, (endCalendar.get(Calendar.MONTH) / 3 - 1) * 3 + 2); endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); setMaxTime(endCalendar); return endCalendar.getTime(); } public static Date getQuarterStartTime(Integer year, Integer quarter) { Calendar quarterCalendar = Calendar.getInstance(); quarterCalendar.set(Calendar.YEAR, year); switch (quarter) { case 1: quarterCalendar.set(Calendar.MONTH, 0); break; case 2: quarterCalendar.set(Calendar.MONTH, 3); break; case 3: quarterCalendar.set(Calendar.MONTH, 6); break; case 4: quarterCalendar.set(Calendar.MONTH, 9); break; default: } quarterCalendar.set(Calendar.DAY_OF_MONTH, 1); setMinTime(quarterCalendar); return quarterCalendar.getTime(); } public static Date getQuarterEndTime(Integer year, Integer quarter) { Calendar quarterCalendar = Calendar.getInstance(); quarterCalendar.set(Calendar.YEAR, year); switch (quarter) { case 1: quarterCalendar.set(Calendar.MONTH, 2); break; case 2: quarterCalendar.set(Calendar.MONTH, 5); break; case 3: quarterCalendar.set(Calendar.MONTH, 8); break; case 4: quarterCalendar.set(Calendar.MONTH, 11); break; default: } quarterCalendar.set(Calendar.DAY_OF_MONTH, quarterCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); setMaxTime(quarterCalendar); return quarterCalendar.getTime(); } public static Date getMonthStartTime(Integer year, Integer month) { Calendar monthCalendar = Calendar.getInstance(); monthCalendar.set(Calendar.YEAR, year); monthCalendar.set(Calendar.MONTH, month - 1); monthCalendar.set(Calendar.DAY_OF_MONTH, 1); setMinTime(monthCalendar); return monthCalendar.getTime(); } public static Date getMonthEndTime(Integer year, Integer month) { Calendar monthCalendar = Calendar.getInstance(); monthCalendar.set(Calendar.YEAR, year); monthCalendar.set(Calendar.MONTH, month - 1); monthCalendar.set(Calendar.DAY_OF_MONTH, monthCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); setMaxTime(monthCalendar); return monthCalendar.getTime(); } public static Date getYearStartTime(Integer year) { Calendar quarterCalendar = Calendar.getInstance(); quarterCalendar.set(Calendar.YEAR, year); quarterCalendar.set(Calendar.MONTH, 0); quarterCalendar.set(Calendar.DAY_OF_MONTH, 1); setMinTime(quarterCalendar); return quarterCalendar.getTime(); } public static Date getYearEndTime(Integer year) { Calendar quarterCalendar = Calendar.getInstance(); quarterCalendar.set(Calendar.YEAR, year); quarterCalendar.set(Calendar.MONTH, 11); quarterCalendar.set(Calendar.DAY_OF_MONTH, quarterCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); setMaxTime(quarterCalendar); return quarterCalendar.getTime(); } public static Date getDayEndTimeWithoutMillisecond(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); } private static void setMinTime(Calendar calendar) { calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); } private static void setMaxTime(Calendar calendar) { calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY)); calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/XmlUtils.java
New file @@ -0,0 +1,95 @@ package com.jttech.cmci.pfcs.util; import com.alibaba.fastjson.JSONObject; import com.jttech.cmci.pfcs.vo.req.ZxmxGetScoreReqVo; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; import org.springframework.util.StringUtils; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.LinkedList; import java.util.List; /** * @author Skaði the Corrupting Heart * @version 1.0.0 * @ClassName xml.java * @Description TODO * @createTime 2022年04月02日 17:12 */ public class XmlUtils { public static JSONObject xml2Json(String xmlStr) { try { if (StringUtils.isEmpty(xmlStr)) { return null; } xmlStr = xmlStr.replaceAll("\\\n", ""); byte[] xml = xmlStr.getBytes("UTF-8"); JSONObject json = new JSONObject(); InputStream is = new ByteArrayInputStream(xml); SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(is); Element root = doc.getRootElement(); json.put(root.getName(), iterateElement(root)); return json; } catch (Exception pE) { throw new RuntimeException("xml文件解析失败", pE); } } private static JSONObject iterateElement(Element element) { List<Element> node = element.getChildren(); JSONObject obj = new JSONObject(); List list = null; for (Element child : node) { list = new LinkedList(); String text = child.getTextTrim(); if (StringUtils.isEmpty(text)) { if (child.getChildren().size() == 0) { continue; } if (obj.containsKey(child.getName())) { list = (List) obj.get(child.getName()); } list.add(iterateElement(child)); // 遍历child的子节点 obj.put(child.getName(), list); } else { if (obj.containsKey(child.getName())) { Object value = obj.get(child.getName()); try { list = (List) value; } catch (ClassCastException e) { list.add(value); } } if (child.getChildren().size() == 0) { // child无子节点时直接设置text obj.put(child.getName(), text); } else { list.add(text); obj.put(child.getName(), list); } } } return obj; } public static void main(String[] args) { String a = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ReportMessage><ReportHead><ReportIdentInfo><ReportId>2022051909455761166981</ReportId><ReportTime>2022.05.19 09:45:57</ReportTime></ReportIdentInfo><ThisQueryReqInfo><QueryName>罗玉林</QueryName><QueryCertType>身份证</QueryCertType><QueryCredNum>522424200009281017</QueryCredNum><QueryOrg>深圳市中裔信息工程融资担保有限公司</QueryOrg><QueryReasonCode>担保资格审查</QueryReasonCode></ThisQueryReqInfo><ObjPromptMsg><Info>信息主体对信用报告内容提出了0笔异议且正在处理中,请浏览时注意阅读相关内容。</Info></ObjPromptMsg></ReportHead><BaseInfo><IdentityInfo><SurveyInfo><Gender>男</Gender><DateOfBirth>2000.09.28</DateOfBirth><MaritalStatus>未婚</MaritalStatus><Education>初中及以下</Education><Degree>其他</Degree><WorkStatus>--</WorkStatus><Citizenship>--</Citizenship><Email>--</Email><ContactAddress>广东揭阳揭东区磐东镇河中村新世纪商场附近</ContactAddress><ResidenceAddress>--</ResidenceAddress></SurveyInfo><PhoneInfo><No>1</No><Phone>17685170689</Phone><InfoUpdateDate>2018.10.04</InfoUpdateDate></PhoneInfo></IdentityInfo><ResideInfo><No>1</No><ResideAddr>广东揭阳揭东区磐东镇河中村新世纪商场附近</ResideAddr><ResidePhone>--</ResidePhone><ResideStatus>--</ResideStatus><InfoUpdateDate>2018.10.04</InfoUpdateDate></ResideInfo></BaseInfo><ReportSumamry><CreditTranPromptInfo><No>1</No><BusinessType>个人住房贷款</BusinessType><AccountNum>--</AccountNum><FirstBusinessReleaseMonth>--</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditTranPromptInfo><No>2</No><BusinessType>个人商用房贷款(包括商住两用房)</BusinessType><AccountNum>--</AccountNum><FirstBusinessReleaseMonth>--</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditTranPromptInfo><No>3</No><BusinessType>其他类贷款</BusinessType><AccountNum>1</AccountNum><FirstBusinessReleaseMonth>2018.10</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditTranPromptInfo><No>4</No><BusinessType>贷记卡</BusinessType><AccountNum>--</AccountNum><FirstBusinessReleaseMonth>--</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditTranPromptInfo><No>5</No><BusinessType>准贷记卡</BusinessType><AccountNum>--</AccountNum><FirstBusinessReleaseMonth>--</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditTranPromptInfo><No>6</No><BusinessType>--</BusinessType><AccountNum>--</AccountNum><FirstBusinessReleaseMonth>--</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditTranPromptInfo><No>7</No><BusinessType>合计</BusinessType><AccountNum>1</AccountNum><FirstBusinessReleaseMonth>--</FirstBusinessReleaseMonth></CreditTranPromptInfo><CreditDefaultSumInfo><BadDebtsSummInfo><AccountNum>1</AccountNum><Balance>1,919</Balance></BadDebtsSummInfo></CreditDefaultSumInfo><CreditTranAndDebtSummInfo><NonrevolvingLoanSummInfo><OrgNum>1</OrgNum><AccountNum>1</AccountNum><AuthorizationTotal>2,665</AuthorizationTotal><Balance>1,919</Balance><AvgRepaymentLastSixMonth>2,170</AvgRepaymentLastSixMonth></NonrevolvingLoanSummInfo><RevolvingLoanAccountSummInfo/></CreditTranAndDebtSummInfo><QueryRecordSummary><LastQueryRecordInfo><LastQueryDate>2022.04.12</LastQueryDate><LastQueryOrg>商业银行\"CW\"</LastQueryOrg><LastQueryReason>信用卡审批</LastQueryReason></LastQueryRecordInfo><QueryRecordSummInfo><NumQueryOrgLoanApprovalLastOneMonth>0</NumQueryOrgLoanApprovalLastOneMonth><NumQueryOrgCreditCardApprovalLastOneMonth>0</NumQueryOrgCreditCardApprovalLastOneMonth><NumQueryLoanApprovalLastOneMonth>0</NumQueryLoanApprovalLastOneMonth><NumQueryCreditCardApprovalLastOneMonth>0</NumQueryCreditCardApprovalLastOneMonth><NumQuerySelfQueryLastOneMonth>0</NumQuerySelfQueryLastOneMonth><NumQueryPostLoanManagementLastTwoYear>3</NumQueryPostLoanManagementLastTwoYear><NumQueryGuaranteeQualificationReviewLastTwoYear>0</NumQueryGuaranteeQualificationReviewLastTwoYear><NumQuerySpecialMerchantRealNameReviewLastTwoYear>0</NumQuerySpecialMerchantRealNameReviewLastTwoYear></QueryRecordSummInfo></QueryRecordSummary></ReportSumamry><CreditTranDetailsInfo><NonrevolvingLoanDetInfo><BaseInfo><CreditPrtlIdent>账户</CreditPrtlIdent><ManagmtOrg>消费金融公司\"YY\"</ManagmtOrg><AccountId>******</AccountId><IssuanceDate>2018.10.04</IssuanceDate><DueDate>2019.08.31</DueDate><Money>2,665</Money><Currency>人民币元</Currency><Type>其他个人消费贷款</Type><GuratMode>信用/免担保</GuratMode><RepayPerid>10</RepayPerid><RepayFrequency>月</RepayFrequency><RepayType>--</RepayType><CommonBwMark>无</CommonBwMark></BaseInfo><LatestPerformanceInfo><Title>截至2022年04月30日</Title><AccountStatus>呆账</AccountStatus><Balance>1,919</Balance><LastRepayDate>2019.02.20</LastRepayDate></LatestPerformanceInfo><Last5YearsHisPerFmInfo><Title>2018年10月 —2022年04月的还款记录</Title><Content>7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|7_2,170|6_1,856|5_0|4_1,232|3_920|2_608|1_296|N_0|N_0|N_0|*_0|</Content></Last5YearsHisPerFmInfo></NonrevolvingLoanDetInfo></CreditTranDetailsInfo><NonCreditTranDetailsInfo/><PublicInfo/><OpenInfo/><QueryInfo><No>1</No><QueryDate>2022.04.12</QueryDate><QueryOrg>商业银行\"CW\"</QueryOrg><Reason>信用卡审批</Reason></QueryInfo><QueryInfo><No>2</No><QueryDate>2020.10.29</QueryDate><QueryOrg>商业银行\"AV\"</QueryOrg><Reason>信用卡审批</Reason></QueryInfo><QueryInfo><No>3</No><QueryDate>2020.10.23</QueryDate><QueryOrg>小额贷款公司\"KU\"</QueryOrg><Reason>贷款审批</Reason></QueryInfo><QueryInfo><No>4</No><QueryDate>2020.10.07</QueryDate><QueryOrg>消费金融公司\"QY\"</QueryOrg><Reason>贷款审批</Reason></QueryInfo><RptExplain><Title>报告说明</Title><Content>1. 本报告中的“数字解读”仅供使用本信用报告的银行等授信机构参考,授信机构应自行承担使用“数字解读”的相关法律责任。2. “数字解读”将信用报告内容解读为一个数值,是对信用主体未来信贷违约可能性的预测,其取值范围为 0 到 1000,分值越高,违约可能性越低;“相对位置”是信用主体的数字解读值在全部人群中的百分比排序位置,比如“>50%”代表该数字解读值高于 50%的信用主体;“说明”中的“影响因素”是影响信用主体获得更高数字解读值的原因,根据当前信用报告的实际情况给出,最多有两条。“数字解读”显示为“--”的,仅代表无法根据当前信用报告内容给出数字解读值,并无其他含义。无法给出数字解读值的具体原因见“说明” 。3. 本报告的信贷交易信息提示中,“业务类型”为“其他” 的汇总信息不包含“资产处置” 和“垫款” 业务。4. 本报告中如果没有“信贷交易违约信息概要”信息,说明信用主体最近 5 年内没有连续逾期。5. 对于存在授信限额的协议信息,信息主体的可用额度需结合“授信协议信息” 中的授信额度、 授信限额信息和余额进行估算。6. 本报告中的信贷交易授信及负债信息概要展示的信息是指未结清/未销户的授信及负债信息。7. 本报告的借贷交易明细信息中,循环贷账户的到期日期是指账户授信额度的到期日期。8. 本报告的借贷交易明细信息中,借贷账户展示最近 5 年的还款情况,包括当前还款状态和当前逾期总额。9.对于通过自助渠道办理的“小额、 高频” 业务,金融机构将合并报送相关账户,展示在本报告的借贷交易明细信息中; 此时账户的还款方式为“不区分还款方式”,该账户的还款频率统一约定为“月”,“还款期数”按月计算, 其还款信息按月进行观测和更新。10.本报告中的逾期准贷记卡账户是指该账户 60 天以上的透支行为。11.本报告中的还款期数为“--”是指该账户是非分期还款。12.本报告不展示 5 年前已经结束的违约行为,以及 5 年前的欠税记录、强制执行记录、民事判决记录、行政处罚记录、电信欠费记录。13.机构说明是数据提供机构对具体业务添加的特别说明信息。14.本人声明是信息主体对信用报告中的信息所附注的简要说明,信用主体对本人声明的真实性负责。15.异议标注是征信中心添加的,用于说明信用主体对信用报告中的哪些信息有异议。16.本报告内容涉及个人隐私,查询者应依法使用、妥善保管。因使用不当造成个人信息泄露的,征信中心将不承担相关责任。17.本报告中所有金额(除“有相关还款责任的企业借款”中的金额外)均为人民币金额,参照查询日前一天的汇。18.本报告整合了数据提供机构以信息主体不同证件报送的信息。</Content></RptExplain></ReportMessage>"; // System.out.println(xml2Json(a)); ZxmxGetScoreReqVo zxmxGetScoreReqVo = new ZxmxGetScoreReqVo(); zxmxGetScoreReqVo.setZxData(a); System.out.println(JSONObject.toJSONString(zxmxGetScoreReqVo)); } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/UserInfoVo.java
New file @@ -0,0 +1,62 @@ package com.jttech.cmci.pfcs.vo; /** * @Description:用户信息 * @Author:carsonwang * @Date:Created in 2022-04-07 10:52 * @Version: 1.0 */ public class UserInfoVo { /** * 用户名 */ private String username; /** * 身份证号码 */ private String idNo; public String getUsername() { return username; } public void setUsername(String pUsername) { username = pUsername; } public String getIdNo() { return idNo; } public void setIdNo(String pIdNo) { idNo = pIdNo; } public UserInfoVo() { } public UserInfoVo(String pUsername, String pIdNo) { username = pUsername; idNo = pIdNo; } @Override public String toString() { return "{\"UserInfoVo\":{" + "\"username\":\"" + username + '\"' + ",\"idNo\":\"" + idNo + '\"' + "}}"; } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/req/ZxmxGetScoreReqVo.java
New file @@ -0,0 +1,69 @@ package com.jttech.cmci.pfcs.vo.req; import java.io.Serializable; /** * @Description:征信信息请求VO * @Author:carsonwang * @Date:Created in 2022-04-06 15:27 * @Version: 1.0 */ public class ZxmxGetScoreReqVo implements Serializable { /** * 征信数据 */ private String zxData; /** * 流水号 */ private String serialNum; /** * 请求编号 */ private String requestId; public String getZxData() { return zxData; } public void setZxData(String pZxData) { zxData = pZxData; } public String getSerialNum() { return serialNum; } public void setSerialNum(String pSerialNum) { serialNum = pSerialNum; } public String getRequestId() { return requestId; } public void setRequestId(String pRequestId) { requestId = pRequestId; } @Override public String toString() { return "{\"ZxmxGetScoreReqVo\":{" + "\"zxData\":\"" + zxData + '\"' + ",\"serialNum\":\"" + serialNum + '\"' + ",\"requestId\":\"" + requestId + '\"' + "}}"; } } cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/resp/ZxmxGetScoreRespVo.java
New file @@ -0,0 +1,125 @@ package com.jttech.cmci.pfcs.vo.resp; import java.io.Serializable; /** * @Description:征信信息请求VO * @Author:carsonwang * @Date:Created in 2022-04-06 15:27 * @Version: 1.0 */ public class ZxmxGetScoreRespVo implements Serializable { /** * 逾期总金额(被追偿信息债权金额+非循环贷账户当前逾期总额+循环额度下分账户当前逾期总额+循环贷账户当前逾期总额+贷记卡账户当前逾期总额) */ private Integer overdueTotal = 0; /** * 贷记卡授信总额度(所有贷记卡授信金额求和) */ private Integer creditLines = 0; /** * 近六个月平均应还款额(信贷交易授信及负债信息概要 * :非循环贷账户信息汇总-最近6个月平均应还款+循环额度下分账户信息汇总-最近6个月平均应还款+循环贷账户信息汇总-最近6个月平均应还+ * 贷记卡账户信息汇总-最近6个月平均使用额度+准贷记卡账户信息汇总-最近6个月平均透支余额) */ private Integer avgUsedOfSixMonth = 0; /** * 近一年逾期次数("非循环贷账户/循环额度下分账户/循环贷账户/贷记卡账户/准贷记卡账户 账户中近一年还款月中为逾期的总次数") */ private Integer overdueNumOfYear = 0; /** * 近一年查征次数(根据查征记录中近一年查询次数计算) */ private Integer queryNumOfYear = 0; public Integer getOverdueTotal() { return overdueTotal; } public void setOverdueTotal(Integer pOverdueTotal) { overdueTotal = pOverdueTotal; } public Integer getCreditLines() { return creditLines; } public void setCreditLines(Integer pCreditLines) { creditLines = pCreditLines; } public Integer getAvgUsedOfSixMonth() { return avgUsedOfSixMonth; } public void setAvgUsedOfSixMonth(Integer pAvgUsedOfSixMonth) { avgUsedOfSixMonth = pAvgUsedOfSixMonth; } public Integer getOverdueNumOfYear() { return overdueNumOfYear; } public void setOverdueNumOfYear(Integer pOverdueNumOfYear) { overdueNumOfYear = pOverdueNumOfYear; } public Integer getQueryNumOfYear() { return queryNumOfYear; } public void setQueryNumOfYear(Integer pQueryNumOfYear) { queryNumOfYear = pQueryNumOfYear; } public ZxmxGetScoreRespVo() { } public ZxmxGetScoreRespVo(Integer pOverdueTotal, Integer pCreditLines, Integer pAvgUsedOfSixMonth, Integer pOverdueNumOfYear, Integer pQueryNumOfYear) { overdueTotal = pOverdueTotal; creditLines = pCreditLines; avgUsedOfSixMonth = pAvgUsedOfSixMonth; overdueNumOfYear = pOverdueNumOfYear; queryNumOfYear = pQueryNumOfYear; } @Override public String toString() { return "{\"ZxmxGetScoreRespVo\":{" + "\"overdueTotal\":" + overdueTotal + ",\"creditLines\":" + creditLines + ",\"avgUsedOfSixMonth\":" + avgUsedOfSixMonth + ",\"overdueNumOfYear\":" + overdueNumOfYear + ",\"queryNumOfYear\":" + queryNumOfYear + "}}"; } } cmci-pfcs-gateway/src/main/resources/application.properties
New file @@ -0,0 +1,2 @@ server.port=8400 logging.config=classpath:logback.xml cmci-pfcs-gateway/src/main/resources/logback.xml
New file @@ -0,0 +1,72 @@ <?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> <configuration status="WARN" monitorInterval="1800"> <Properties> <!-- 日志默认存放的位置,这里设置为项目根路径下,也可指定绝对路径 --> <!-- ${web:rootDir}是web项目根路径,java项目没有这个变量,需要删掉,否则会报异常 --> <!--<property name="basePath">D://log4j2Logs</property>--> <!-- <property name="basePath">/home/log/zxmx-plat</property>--> <property name="basePath">logs</property> <!-- 控制台默认输出格式,"%-5level":日志级别,"%l":输出完整的错误位置,是小写的L,因为有行号显示,所以影响日志输出的性能 --> <property name="console_log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %l - %m%n</property> <!-- 日志文件默认输出格式,不带行号输出(行号显示会影响日志输出性能);%C:大写,类名;%M:方法名;%m:错误信息;%n:换行 --> <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %C.%M - %m%n</property> <!-- 日志默认切割的最小单位 --> <property name="every_file_size">20MB</property> <!-- 日志默认输出级别 --> <property name="output_log_level">INFO</property> <!-- 日志默认存放路径(所有级别日志) --> <property name="rolling_fileName">${basePath}/log/zxmx-plat-gateway.log</property> <!-- 日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 --> <property name="rolling_filePattern">${basePath}/back/%d{yyyy-MM}/zxmx-plat-gateway-%d{yyyy-MM-dd}-%i.log.gz</property> <!-- 日志默认同类型日志,同一文件夹下可以存放的数量,不设置此属性则默认为7个 --> <property name="rolling_max">50</property> <!-- 控制台显示的日志最低级别 --> <property name="console_print_level">INFO</property> </Properties> <!--定义appender --> <appenders> <!-- 用来定义输出到控制台的配置 --> <Console name="Console" target="SYSTEM_OUT"> <!-- 设置控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> <ThresholdFilter level="${console_print_level}" onMatch="ACCEPT" onMismatch="DENY"/> <!-- 设置输出格式,不设置默认为:%m%n --> <PatternLayout pattern="${console_log_pattern}"/> </Console> <!-- 打印root中指定的level级别以上的日志到文件 --> <RollingFile name="RollingFile" fileName="${rolling_fileName}" filePattern="${rolling_filePattern}"> <PatternLayout pattern="${log_pattern}"/> <Policies> <SizeBasedTriggeringPolicy size="${every_file_size}"/> </Policies> <!-- 设置同类型日志,同一文件夹下可以存放的数量,如果不设置此属性则默认存放7个文件 --> <DefaultRolloverStrategy max="${rolling_max}" /> <!-- 匹配INFO以及以上级别 --> <Filters> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> </RollingFile> </appenders> <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <loggers> <!-- 设置对打印sql语句的支持 --> <logger name="java.sql" level="info" additivity="false"> <appender-ref ref="Console"/> </logger> <!--建立一个默认的root的logger--> <root level="${output_log_level}"> <appender-ref ref="RollingFile"/> <appender-ref ref="Console"/> </root> </loggers> </configuration>