From 5378165da6ad9f748a8a3e4599743d0bfbb4835b Mon Sep 17 00:00:00 2001 From: wanghc <2466022993@qq.com> Date: Fri, 03 Mar 2023 14:55:38 +0800 Subject: [PATCH] 浦发分行小系统 --- cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/resp/ZxmxGetScoreRespVo.java | 125 +++ .gitignore | 6 cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/controller/ZxmxManagerController.java | 39 + cmci-pfcs-gateway/pom.xml | 87 ++ cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/Application.java | 24 cmci-pfcs-gateway/src/main/resources/logback.xml | 72 + cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/DateUtil.java | 955 ++++++++++++++++++++++++ cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/content/ZxmxContent.java | 45 + cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/XmlUtils.java | 95 ++ cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/req/ZxmxGetScoreReqVo.java | 69 + cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/UserInfoVo.java | 62 + cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/service/ZxmxManagerService.java | 700 +++++++++++++++++ cmci-pfcs-gateway/src/main/resources/application.properties | 2 13 files changed, 2,281 insertions(+), 0 deletions(-) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b3503f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.iml +*.class +target/ +.idea/ +*.prefs +*.log diff --git a/cmci-pfcs-gateway/pom.xml b/cmci-pfcs-gateway/pom.xml new file mode 100644 index 0000000..bceeca7 --- /dev/null +++ b/cmci-pfcs-gateway/pom.xml @@ -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> diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/Application.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/Application.java new file mode 100644 index 0000000..6ddb573 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/Application.java @@ -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); + } +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/content/ZxmxContent.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/content/ZxmxContent.java new file mode 100644 index 0000000..ee00568 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/content/ZxmxContent.java @@ -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"; + +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/controller/ZxmxManagerController.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/controller/ZxmxManagerController.java new file mode 100644 index 0000000..2eb51b3 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/controller/ZxmxManagerController.java @@ -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); + } +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/service/ZxmxManagerService.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/service/ZxmxManagerService.java new file mode 100644 index 0000000..0e990ca --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/service/ZxmxManagerService.java @@ -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); + } +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/DateUtil.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/DateUtil.java new file mode 100644 index 0000000..08c2626 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/DateUtil.java @@ -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)); + } + +} \ No newline at end of file diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/XmlUtils.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/XmlUtils.java new file mode 100644 index 0000000..d1807d6 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/util/XmlUtils.java @@ -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)); + } +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/UserInfoVo.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/UserInfoVo.java new file mode 100644 index 0000000..2a97319 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/UserInfoVo.java @@ -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 + '\"' + "}}"; + + } +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/req/ZxmxGetScoreReqVo.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/req/ZxmxGetScoreReqVo.java new file mode 100644 index 0000000..e4414c6 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/req/ZxmxGetScoreReqVo.java @@ -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 + '\"' + "}}"; + + } +} diff --git a/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/resp/ZxmxGetScoreRespVo.java b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/resp/ZxmxGetScoreRespVo.java new file mode 100644 index 0000000..0e17fe6 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/java/com/jttech/cmci/pfcs/vo/resp/ZxmxGetScoreRespVo.java @@ -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 + "}}"; + + } +} diff --git a/cmci-pfcs-gateway/src/main/resources/application.properties b/cmci-pfcs-gateway/src/main/resources/application.properties new file mode 100644 index 0000000..d9f4f96 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/resources/application.properties @@ -0,0 +1,2 @@ +server.port=8400 +logging.config=classpath:logback.xml \ No newline at end of file diff --git a/cmci-pfcs-gateway/src/main/resources/logback.xml b/cmci-pfcs-gateway/src/main/resources/logback.xml new file mode 100644 index 0000000..c8aa4a7 --- /dev/null +++ b/cmci-pfcs-gateway/src/main/resources/logback.xml @@ -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> -- Gitblit v1.8.0