Commit a16693a8 authored by 郑建's avatar 郑建

Merge remote-tracking branch 'origin/zj-niwodai' into zj-niwodai

# Conflicts:
#	src/main/java/com/quantgroup/asset/distribution/controller/FundModuleController.java
#	src/test/java/com/quantgroup/asset/distribution/niwodai/NiwodaiTest.java
parents 3869dd56 210a7969
...@@ -21,9 +21,12 @@ import com.alibaba.druid.pool.DruidDataSource; ...@@ -21,9 +21,12 @@ import com.alibaba.druid.pool.DruidDataSource;
@Configuration @Configuration
public class DataSourceConfig { public class DataSourceConfig {
private String dbUrl = "jdbc:mysql://172.17.5.9:31024/asset_distribution?useUnicode=true&characterEncoding=utf-8"; @Value("${spring.datasource.primary.url}")
private String username = "qa"; private String dbUrl;
private String password = "qatest"; @Value("${spring.datasource.primary.username}")
private String username;
@Value("${spring.datasource.primary.password}")
private String password;
@Value("${spring.datasource.primary.driver-class-name}") @Value("${spring.datasource.primary.driver-class-name}")
private String driverClassName; private String driverClassName;
......
...@@ -125,11 +125,11 @@ public class HttpClientConfig { ...@@ -125,11 +125,11 @@ public class HttpClientConfig {
return null; return null;
} }
}; };
String classesPath= ClassUtils.getDefaultClassLoader().getResource("").getPath(); String classesPath = this.getClass().getClassLoader().getResource("niwodai/").getPath();
KeyStore keyStore = KeyStore.getInstance("PKCS12"); KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(new File(classesPath + "/niwodai/" + "qg-keystore.jks")), "password".toCharArray()); keyStore.load(new FileInputStream(new File(classesPath + "qg-keystore.jks")), "password".toCharArray());
SSLContext sslcontext = SSLContexts.custom() SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File(classesPath + "/niwodai/" + "qg-truststore.jks"), "password".toCharArray(), new TrustSelfSignedStrategy()) .loadTrustMaterial(new File(classesPath + "qg-truststore.jks"), "password".toCharArray(), new TrustSelfSignedStrategy())
.loadKeyMaterial(keyStore, "password".toCharArray()) .loadKeyMaterial(keyStore, "password".toCharArray())
.build(); .build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory( SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
......
...@@ -77,7 +77,7 @@ public class ConsumerConfig implements RabbitListenerConfigurer { ...@@ -77,7 +77,7 @@ public class ConsumerConfig implements RabbitListenerConfigurer {
log.info("资金路由有效MQ消息接收, 消息内容 : {} ",ms); log.info("资金路由有效MQ消息接收, 消息内容 : {} ",ms);
String applyNo = jo.getJSONObject("data").getString("applyNo"); String applyNo = jo.getJSONObject("data").getString("applyNo");
String nextOperateDate = getNextOperateDate(jo, noticeType); String nextOperateDate = getNextOperateDate(jo, noticeType);
iAidFundRouteRecordService.fundingResultNotity(applyNo,FundingResult.fromCode(noticeType)); // iAidFundRouteRecordService.fundingResultNotity(applyNo,FundingResult.fromCode(noticeType));
distributeService.receiveFundingResult(applyNo, FundingResult.fromCode(noticeType), nextOperateDate); distributeService.receiveFundingResult(applyNo, FundingResult.fromCode(noticeType), nextOperateDate);
log.info("资金路由有效MQ消息处理结束, bizNo : {} ,noticeType : {} , 耗时 : {} ",applyNo,noticeType,stopwatch.stop().elapsed(TimeUnit.MILLISECONDS)); log.info("资金路由有效MQ消息处理结束, bizNo : {} ,noticeType : {} , 耗时 : {} ",applyNo,noticeType,stopwatch.stop().elapsed(TimeUnit.MILLISECONDS));
} }
......
package com.quantgroup.asset.distribution.constant;
/**
* @author : Hyuk
* @description : AidFundConstants
* @date : 2020/3/27 5:09 下午
*/
public class AidFundConstants {
public static class FundId {
/**
* 你我贷
*/
public static final String NIWODAI = "970";
}
}
package com.quantgroup.asset.distribution.constant;
/**
* @author : Hyuk
* @description : AidFundIncomingStatus
* @date : 2020/3/30 11:04 上午
*/
public class AidFundStatus {
/**
* 进件状态
*/
public static class Incoming {
public static int REJECT = 0;
public static int PASS = 1;
// 资方审核中
public static int WAIT = 2;
// 保留状态,如果资方进件成功改为WAIT
public static int PRE = 3;
}
/**
* 路由状态
*/
public static class Route {
// 1-准入成功
public static int PRE_PASS = 1;
// 2-准入失败
public static int PRE_REJECT = 2;
// 3-进件完成
public static int INCOMING_COMPLETE = 3;
}
}
...@@ -29,10 +29,15 @@ public class RedisKeyConstants { ...@@ -29,10 +29,15 @@ public class RedisKeyConstants {
/** /**
* 你我贷token * 你我贷token
*/ */
public static final String NI_WO_DAI_TOKEN_KEY = "DATA_EXPORT_PLATFORM:NIWODAI:TOKEN:YHABEA"; public static final String NI_WO_DAI_TOKEN_KEY = "ASSET.DISTRIBUTE:NIWODAI:TOKEN:YHABEA";
/** /**
* 完成路由的资方缓存KEY * 完成路由的资方缓存KEY
*/ */
public static final String FINISH_ROUTE_AID_FUND_KEY="FINISH.ROUTE.AID.FUND.KEY.IJN9_"; public static final String FINISH_ROUTE_AID_FUND_KEY="ASSET.DISTRIBUTE:FINISH.ROUTE.AID.FUND.KEY.IJN9_";
/**
* 助贷资方审核订单缓存KEY
*/
public static final String AID_FUND_AUDIT_ORDER_KEY = "ASSET.DISTRIBUTE:AID_FUND_AUDIT_ORDER:BY_BIZ_NO_AND_FUND_ID:AKVVS3:";
} }
package com.quantgroup.asset.distribution.controller; package com.quantgroup.asset.distribution.controller;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.quantgroup.asset.distribution.model.entity.fund.FundConfigCondition;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.quantgroup.asset.distribution.constant.FundModuleConstants; import com.quantgroup.asset.distribution.constant.FundModuleConstants;
import com.quantgroup.asset.distribution.enums.response.FundModuleResponse; import com.quantgroup.asset.distribution.enums.response.FundModuleResponse;
import com.quantgroup.asset.distribution.model.response.GlobalResponse; import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import com.quantgroup.asset.distribution.service.approval.IApprovalLogService;
import com.quantgroup.asset.distribution.service.funding.IFundModuleService; import com.quantgroup.asset.distribution.service.funding.IFundModuleService;
import com.quantgroup.asset.distribution.util.fund.module.ChannelFundConfigUtil; import com.quantgroup.asset.distribution.util.fund.module.ChannelFundConfigUtil;
...@@ -112,11 +106,6 @@ public class FundModuleController { ...@@ -112,11 +106,6 @@ public class FundModuleController {
return findChannelFundConfigCommon(configId, 2); return findChannelFundConfigCommon(configId, 2);
} }
@RequestMapping("/simulation/conditions")
public GlobalResponse allConditions(Long configId){
return fundConfigConditions(configId);
}
private GlobalResponse saveChannelFundsConfigCommon(Integer type, Long id, String bizChannel, String funds, String remarks, private GlobalResponse saveChannelFundsConfigCommon(Integer type, Long id, String bizChannel, String funds, String remarks,
String auditor, String proposer, int oldOrNew) { String auditor, String proposer, int oldOrNew) {
log.info("资方模块接口, 新增或修改资方配置开始, type : {}, id : {}, bizChannel : {}, funds : {}, remarks : {}, auditor : {}, proposer : {}", type, id, bizChannel, funds, remarks, auditor, proposer); log.info("资方模块接口, 新增或修改资方配置开始, type : {}, id : {}, bizChannel : {}, funds : {}, remarks : {}, auditor : {}, proposer : {}", type, id, bizChannel, funds, remarks, auditor, proposer);
...@@ -190,25 +179,4 @@ public class FundModuleController { ...@@ -190,25 +179,4 @@ public class FundModuleController {
return response; return response;
} }
private GlobalResponse fundConfigConditions(Long configId){
log.info("资方模块接口,根据id获取所有案例, configId : {}", configId);
if (configId == null) {
return GlobalResponse.create(FundModuleResponse.ID_IS_EMPTY);
}
Stopwatch stopwatch = Stopwatch.createStarted();
GlobalResponse response = fundModuleService.getAllConditionsOfFundConfig(configId);
log.info("资方模块接口,根据id获取所有案例, configId : {} 耗时 : {}, response : {}", configId, stopwatch.stop().elapsed(TimeUnit.MILLISECONDS), JSON.toJSONString(response));
return response;
}
private GlobalResponse simulation(List<FundConfigCondition> configConditions,Long configId){
log.info("资方模块接口,根据案例进行空跑, configConditions : {}", configConditions);
if (CollectionUtils.isEmpty(configConditions)) {
return GlobalResponse.create(FundModuleResponse.ID_IS_EMPTY);
}
Stopwatch stopwatch = Stopwatch.createStarted();
GlobalResponse response = fundModuleService.simulationCases(configConditions,configId);
log.info("资方模块接口,根据id获取所有案例, configConditions : {} 耗时 : {}, response : {}", configConditions, stopwatch.stop().elapsed(TimeUnit.MILLISECONDS), JSON.toJSONString(response));
return response;
}
} }
package com.quantgroup.asset.distribution.controller;
import com.alibaba.fastjson.JSON;
import com.quantgroup.asset.distribution.constant.AidFundConstants;
import com.quantgroup.asset.distribution.constant.AidFundStatus;
import com.quantgroup.asset.distribution.constant.StatusConstants;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import com.quantgroup.asset.distribution.service.alarm.IAlarmService;
import com.quantgroup.asset.distribution.service.distribute.IAssetDistributeRecordService;
import com.quantgroup.asset.distribution.service.distribute.IAssetDistributeService;
import com.quantgroup.asset.distribution.service.funding.IAidFundAuditOrderService;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundAuditOrder;
import com.quantgroup.asset.distribution.service.jpa.entity.Asset;
import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiCostant;
import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiIncomingResultResponseVO;
import com.quantgroup.asset.distribution.service.notify.INotifyService;
import com.quantgroup.asset.distribution.service.product.IFinanceProductService;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import com.quantgroup.asset.distribution.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author : Hyuk
* @description : NiWoDaiContraoller
* @date : 2020/3/27 2:12 下午
*/
@RestController
@Slf4j
@RequestMapping("/niwodai")
public class NiWoDaiController {
@Autowired
private IAidFundAuditOrderService aidFundAuditOrderService;
@Autowired
private IAlarmService alarmService;
@Autowired
private IAssetDistributeService assetDistributeService;
@Autowired
private IAssetDistributeRecordService assetDistributeRecordService;
@Autowired
private IFinanceProductService financeProductService;
@Autowired
private INotifyService notifyService;
@RequestMapping("/incoming/callback")
public GlobalResponse auditResultCallback(String orderId, String type, Integer code, Long timestamp, String data) {
log.info("你我贷审核进件回调收到结果, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId,
type, code, timestamp, data);
AidLoanFundAuditOrder aidLoanFundAuditOrder = aidFundAuditOrderService.findByBizNoAndFundId(orderId, AidFundConstants.FundId.NIWODAI);
if (aidLoanFundAuditOrder == null) {
log.info("你我贷审核进件回调结果未找到订单, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId, type, code, timestamp, data);
alarmService.dingtalkAlarm("Error", "你我贷资方审核回调结果未找到订单", "bizNo : " + orderId + " , type : " + type + " , code : " + code + " , timestamp : " + timestamp + " , data : " + data);
return GlobalResponse.success();
}
if (aidLoanFundAuditOrder.getAuditResult().intValue() != AidFundStatus.Incoming.WAIT && aidLoanFundAuditOrder.getAuditResult().intValue() != AidFundStatus.Incoming.PRE) {
log.info("你我贷进件回调结果订单重复通知结果, 请查看, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId, type, code, timestamp, data);
return GlobalResponse.success();
}
if (!"APPLY".equals(type)) {
log.info("你我贷审核进件回调结果type出现错误, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId, type, code, timestamp , data);
alarmService.dingtalkAlarm("Error", "你我贷审核结果回调type错误", "bizNo : " + orderId + " , type : " + type + " , code : " + code + " , timestamp : " + timestamp + " , data : " + data);
return GlobalResponse.success();
}
if (code == null || (code != 300005 && code != 300006)) {
log.info("你我贷审核进件回调结果code出现错误, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId, type, code, timestamp , data);
alarmService.dingtalkAlarm("Error", "你我贷审核结果回调code出现错误", "bizNo : " + orderId + " , type : " + type + " , code : " + code + " , timestamp : " + timestamp + " , data : " + data);
return GlobalResponse.success();
}
AssetForm assetForm = JSON.parseObject(aidLoanFundAuditOrder.getAssetFormText(), AssetForm.class);
Asset asset = JSON.parseObject(aidLoanFundAuditOrder.getAssetText(), Asset.class);
Map<String, Object> dataMap = JSON.parseObject(aidLoanFundAuditOrder.getDataText(), Map.class);
if (300005 == code) {
// 将助贷审核订单状态改为拒绝
aidFundAuditOrderService.updateOrderStatus(aidLoanFundAuditOrder, AidFundStatus.Incoming.REJECT);
// 将分发记录改为失败
assetDistributeRecordService.updateAssetDistributeStatus(orderId, StatusConstants.FAIL);
// 重新进行分发
assetDistributeService.distribute(assetForm, asset, dataMap);
} else {
NiwodaiIncomingResultResponseVO vo = JSON.parseObject(data, NiwodaiIncomingResultResponseVO.class);
if (!checkIncomingResult(vo)) {
log.info("你我贷审核进件回调结果data出现错误, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId, type, code, timestamp, JSON.toJSONString(vo));
alarmService.dingtalkAlarm("Error", "你我贷审核结果回调data出现错误", "bizNo : " + orderId + " , type : " + type + " , code : " + code + " , timestamp : " + timestamp + " , data : " + data);
return GlobalResponse.success();
}
// 通过了直接通知资金系统
String finance = financeProductService.createSingletonFinanceProduct(vo.getApprovedAmount().toString(), NiwodaiCostant.AUDIT_TERM, AidFundConstants.FundId.NIWODAI, null);
assetForm = financeProductService.checkFundResult(assetForm, finance, Long.parseLong(vo.getValidBefore()));
notifyService.notifyFundServer(assetForm, dataMap);
}
log.info("你我贷审核进件回调结果处理完成, orderId : {}, type : {}, code : {}, timestamp : {}, data : {}", orderId,
type, code, timestamp, data);
return GlobalResponse.success();
}
/**
* 审核通过,检验参数
* @param vo
* @return
*/
private boolean checkIncomingResult(NiwodaiIncomingResultResponseVO vo) {
if (vo == null || vo.getApprovedAmount() == null || vo.getValidBefore() == null) {
return false;
}
return true;
}
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
}
}
...@@ -43,8 +43,4 @@ public enum RuleOperator { ...@@ -43,8 +43,4 @@ public enum RuleOperator {
log.error("枚举不存在,code={}", code); log.error("枚举不存在,code={}", code);
throw new QGException(QGExceptionType.COMMON_ILLEGAL_PARAM); throw new QGException(QGExceptionType.COMMON_ILLEGAL_PARAM);
} }
public String getCode() {
return this.code;
}
} }
package com.quantgroup.asset.distribution.enums;
import lombok.Getter;
/**
* @author : Hyuk
* @description : UserLoanType
* @date : 2020/3/26 7:10 下午
*/
public enum UserLoanType {
FIRST_APPLY(0, "首申"),
RE_APPLY(1, "复申"),
RE_LOAN(2, "复贷");
@Getter
private Integer code;
@Getter
private String title;
UserLoanType(Integer code, String title) {
this.code = code;
this.title = title;
}
}
...@@ -53,8 +53,19 @@ public enum QGExceptionType { ...@@ -53,8 +53,19 @@ public enum QGExceptionType {
NO_FUND_INFO_BEEN_HIT(3002, "未命中任何资方, bizChannel : %s, amount : %s, term : %s"), NO_FUND_INFO_BEEN_HIT(3002, "未命中任何资方, bizChannel : %s, amount : %s, term : %s"),
FUND_PRIORITY_IS_ERROR(3003, "资方优先级不符合要求, bizChannel : %s, amount : %s, term : %s"), FUND_PRIORITY_IS_ERROR(3003, "资方优先级不符合要求, bizChannel : %s, amount : %s, term : %s"),
NOT_FOUNT_CHANNEL_FUNDS_INFO(3004, "未找到渠道资方配置, 请检查; bizChannel : %s"), NOT_FOUNT_CHANNEL_FUNDS_INFO(3004, "未找到渠道资方配置, 请检查; bizChannel : %s"),
CHANNEL_FUND_CONFIG_GREATER_THAN_TOW(3005, "渠道资方有效配置大于2条,请检查; bizChannel : % s"), CHANNEL_FUND_CONFIG_GREATER_THAN_TOW(3005, "渠道资方有效配置大于2条,请检查; bizChannel : %s"),
HIT_FUND_BUT_AMOUNT_OR_TERM_IS_EMPTY(3006, "命中资方但额度或期数为空, 请检查!"); HIT_FUND_BUT_AMOUNT_OR_TERM_IS_EMPTY(3006, "命中资方但额度或期数为空, 请检查!"),
GET_USER_INFO_ERROR(3007, "用户中心获取用户信息异常!"),
USER_PHONE_NO_EMPTY(3008, "用户手机号为空"),
USER_ID_NO_EMPTY(3009, "用户身份证为空"),
USER_NAME_EMPTY(3010, "用户姓名为空"),
GET_NIWODAI_TOKEN_ERROR(3011, "获取你我贷token异常"),
NIWODAI_PRE_AUDIT_RESULAT_ERROR(3012, "你我贷准入接口返回结果异常, resposne : %s"),
NIWODAI_INCOMING_RESULT_ERROR(3013, "你我贷进件返回结果异常, resposne : % s"),
NIWODAI_INCOMING_AUDIT_RESULT_ERROR(3014, "你我贷进件审核返回结果异常, response : %s"),
OCR_DATA_MISS(3015,"OCR信息数据缺失,请核查"),
UNKNOW_AID_FUND_ID(3016, "未知的助贷资方, fundId : %s");
......
package com.quantgroup.asset.distribution.model.entity.fund;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class FundConfigCondition implements Serializable {
private static final long serialVersionUID = 1L;
private String conditionTempId;
private List<Condition> condition;
private Result result;
@Data
public static class Condition{
private String conditionCode;
private String conditionName;
private String conditionValue;
}
@Data
public static class Result{
private Boolean success;
private String fundInfo;
}
}
...@@ -25,8 +25,8 @@ public class AlarmServiceImpl implements IAlarmService{ ...@@ -25,8 +25,8 @@ public class AlarmServiceImpl implements IAlarmService{
private static final String ALARM_HTTP_URL = "http://alertserv-dataservice.quantgroup.cn/common/alert/dingtalk"; private static final String ALARM_HTTP_URL = "http://alertserv-dataservice.quantgroup.cn/common/alert/dingtalk";
private static final String ROBOT_WEB_HOOK = "https://oapi.dingtalk.com/robot/send?access_token=53a55ffe3d4a5398a7ba44e4fcee1a3ac006edcba9cfdc4b1f9f692ffc18a5b8"; private static final String ROBOT_WEB_HOOK = "https://oapi.dingtalk.com/robot/send?access_token=53a55ffe3d4a5398a7ba44e4fcee1a3ac006edcba9cfdc4b1f9f692ffc18a5b8";
@Value("${isDebug}") @Value("${alarmOpen}")
private Boolean isDebug; private Boolean alarmOpen;
@Autowired @Autowired
private IHttpService httpService; private IHttpService httpService;
...@@ -34,7 +34,7 @@ public class AlarmServiceImpl implements IAlarmService{ ...@@ -34,7 +34,7 @@ public class AlarmServiceImpl implements IAlarmService{
@Override @Override
public void dingtalkAlarm(String alarmLevel, String msgTitle, String msgContent) { public void dingtalkAlarm(String alarmLevel, String msgTitle, String msgContent) {
try { try {
if (isDebug) { return; } if (!alarmOpen) { return; }
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put("webhook", ROBOT_WEB_HOOK); params.put("webhook", ROBOT_WEB_HOOK);
params.put("alarmLevel", alarmLevel); params.put("alarmLevel", alarmLevel);
......
...@@ -74,8 +74,8 @@ public class AssetDistributeRecordServiceImpl implements IAssetDistributeRecordS ...@@ -74,8 +74,8 @@ public class AssetDistributeRecordServiceImpl implements IAssetDistributeRecordS
public void updateAssetDistributeStatus(String bizNo, int status) { public void updateAssetDistributeStatus(String bizNo, int status) {
AssetDistributeRecord assetDistributeRecord = assetDistributeRecordRepository.findByBizNoOrderByCreatedAtDescLimitOne(bizNo); AssetDistributeRecord assetDistributeRecord = assetDistributeRecordRepository.findByBizNoOrderByCreatedAtDescLimitOne(bizNo);
if (assetDistributeRecord == null) { if (assetDistributeRecord == null) {
if (isDebug) { return; }
log.info("资产分发记录更改状态未找到订单, bizNo : {}, status : {}", bizNo, status); log.info("资产分发记录更改状态未找到订单, bizNo : {}, status : {}", bizNo, status);
if (isDebug) { return; }
throw new QGException(QGExceptionType.NOT_FOUND_FUND_SERVER_RESULT_BIZNO, bizNo, status); throw new QGException(QGExceptionType.NOT_FOUND_FUND_SERVER_RESULT_BIZNO, bizNo, status);
} else { } else {
assetDistributeRecord.setAssetDistributeStatus(status); assetDistributeRecord.setAssetDistributeStatus(status);
......
...@@ -28,6 +28,7 @@ import com.quantgroup.asset.distribution.service.jpa.entity.AssetDistributeRuleC ...@@ -28,6 +28,7 @@ import com.quantgroup.asset.distribution.service.jpa.entity.AssetDistributeRuleC
import com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew; import com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew;
import com.quantgroup.asset.distribution.service.notify.INotifyService; import com.quantgroup.asset.distribution.service.notify.INotifyService;
import com.quantgroup.asset.distribution.service.product.IFinanceProductHitLogService; import com.quantgroup.asset.distribution.service.product.IFinanceProductHitLogService;
import com.quantgroup.asset.distribution.service.product.IFinanceProductService;
import com.quantgroup.asset.distribution.service.redis.IRedisService; import com.quantgroup.asset.distribution.service.redis.IRedisService;
import com.quantgroup.asset.distribution.service.rule.IRuleService; import com.quantgroup.asset.distribution.service.rule.IRuleService;
import com.quantgroup.asset.distribution.service.rule.vo.IRuleVO; import com.quantgroup.asset.distribution.service.rule.vo.IRuleVO;
...@@ -74,6 +75,8 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{ ...@@ -74,6 +75,8 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
@Autowired @Autowired
private IRuleService ruleService; private IRuleService ruleService;
@Autowired @Autowired
private IFinanceProductService financeProductService;
@Autowired
private IFinanceProductHitLogService financeProductHitLogService; private IFinanceProductHitLogService financeProductHitLogService;
private static final ExecutorService executorPool = Executors.newFixedThreadPool(4); private static final ExecutorService executorPool = Executors.newFixedThreadPool(4);
...@@ -108,6 +111,10 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{ ...@@ -108,6 +111,10 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
assetForm.getUuid(), assetForm.getBizNo(), assetForm.getAssetNo(), assetForm.getBizChannel(), ruleConfig.getId(), ruleConfig.getAssetDistributeRuleName(), assetForm.getUuid(), assetForm.getBizNo(), assetForm.getAssetNo(), assetForm.getBizChannel(), ruleConfig.getId(), ruleConfig.getAssetDistributeRuleName(),
distributeStatus); distributeStatus);
success = true; success = true;
} else if (distributeStatus == StatusConstants.FAIL) {
// 如果分发失败,直接更改状态
assetDistributeRecord.setAssetDistributeStatus(StatusConstants.FAIL);
assetDistributeRecordService.updateAssetDistribute(assetDistributeRecord);
} }
} }
// 保存节点尝试记录 // 保存节点尝试记录
...@@ -135,28 +142,22 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{ ...@@ -135,28 +142,22 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
try { try {
switch (ruleType) { switch (ruleType) {
case DistributeConstants.RuleType.FUND_ROUTE: case DistributeConstants.RuleType.FUND_ROUTE:
// 资方配置空跑 // 资方配置空跑,这里的目的是深度拷贝一个新对象,避免发生错乱
doTestExecute(JSON.parseObject(JSON.toJSONString(assetForm), AssetForm.class), data); doTestExecute(JSON.parseObject(JSON.toJSONString(assetForm), AssetForm.class), data);
// 如果使用资方模块则去命中资方,创建金融产品集 // 如果使用资方模块则去命中资方,创建金融产品集
String hitFinanceProduct = hitFundIfUseFundModule(assetForm, data, ExecuteType.ONLINE); String hitFinanceProduct = hitFundIfUseFundModule(assetForm, data, ExecuteType.ONLINE);
// 资方模块结果处理 // 资方模块结果处理
checkFundResult(assetForm, hitFinanceProduct); financeProductService.checkFundResult(assetForm, hitFinanceProduct);
if(StringUtils.isNotEmpty(hitFinanceProduct)) { if(StringUtils.isNotEmpty(hitFinanceProduct)) {
notifyService.notifyFundServer(assetForm, data); notifyService.notifyFundServer(assetForm, data);
return StatusConstants.WAIT; return StatusConstants.WAIT;
} }
return StatusConstants.FAIL; return StatusConstants.FAIL;
case DistributeConstants.RuleType.AID_FUND_ROUTE: { case DistributeConstants.RuleType.AID_FUND_ROUTE: {
GlobalResponse response = aidFundRouteService.aidFundRoute(assetForm, asset.getUserLoanType(), data); boolean response = aidFundRouteService.aidFundRoute(assetForm, asset, data);
int status = response.getCode() == 0 ? StatusConstants.WAIT : StatusConstants.FAIL; return response ? StatusConstants.WAIT : StatusConstants.FAIL;
//助贷资金路由 分配失败没有 mq消息 成功有
if(status==0){
// 助贷资金路由目前不从mq里接受终态
assetDistributeRecord.setAssetDistributeStatus(status);
assetDistributeRecordService.updateAssetDistribute(assetDistributeRecord);
} }
return status; case DistributeConstants.RuleType.DIVERSION:
}case DistributeConstants.RuleType.DIVERSION:
notifyService.notifyFundServer(assetForm, data); notifyService.notifyFundServer(assetForm, data);
return StatusConstants.WAIT; return StatusConstants.WAIT;
default: default:
...@@ -230,7 +231,10 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{ ...@@ -230,7 +231,10 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
try { try {
Stopwatch stopwatch = Stopwatch.createStarted(); Stopwatch stopwatch = Stopwatch.createStarted();
// 1、更改分配记录状态 // 1、更改分配记录状态
if (fundingResult != FundingResult.HANG_UP) {
// HANG_UP不更改,
assetDistributeRecordService.updateAssetDistributeStatus(bizNo, fundingResult == FundingResult.FUAD_ASSIGN_SUCC ? StatusConstants.SUCCESS : StatusConstants.FAIL); assetDistributeRecordService.updateAssetDistributeStatus(bizNo, fundingResult == FundingResult.FUAD_ASSIGN_SUCC ? StatusConstants.SUCCESS : StatusConstants.FAIL);
}
// 2、通知业务流系统 // 2、通知业务流系统
notifyService.notifyBusinessFlow(bizNo, fundingResult, nextOperateDate); notifyService.notifyBusinessFlow(bizNo, fundingResult, nextOperateDate);
// 3、重新进行分发, 目前还没有,等接了助贷资金路由以后再增加 // 3、重新进行分发, 目前还没有,等接了助贷资金路由以后再增加
...@@ -329,38 +333,6 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{ ...@@ -329,38 +333,6 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
return hitFinanceProduct; return hitFinanceProduct;
} }
/**
* 资方模块命中后结果处理
* @param assetForm
* @param hitFinanceProduct
* @return
*/
private AssetForm checkFundResult(AssetForm assetForm, String hitFinanceProduct) {
if (hitFinanceProduct == null) {
if ("false".equals(assetForm.getAuditResult())) {
// 把传过来的额度和期数处理为null
assetForm.setAmount(null);
assetForm.setTerm(null);
}
return assetForm;
}
// 金融产品集替换
String oldFinanceProduct = assetForm.getFinanceProducts();
assetForm.setFinanceProducts(hitFinanceProduct);
// 审核结果替换
String oldAuditResult = assetForm.getAuditResult();
if ("false".equals(oldAuditResult)) {
assetForm.setAuditResult("true");
}
// 保存日志
financeProductHitLogService.saveLog(assetForm, oldFinanceProduct, hitFinanceProduct, oldAuditResult, assetForm.getAuditResult(), ExecuteType.ONLINE);
log.info("资方命中后,审核最终结果, assetForm : {}", JSON.toJSONString(assetForm));
return assetForm;
}
/** /**
* 组建金融产品集 * 组建金融产品集
* @param assetForm * @param assetForm
......
package com.quantgroup.asset.distribution.service.funding;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import java.util.Map;
/**
* @author : Hyuk
* @description : IAidFundAssetService
* @date : 2020/3/27 5:07 下午
*/
public interface IAidFundAssetService {
/**
* 准入审核,预审
* @param assetForm
* @return
*/
public boolean preAudit(AssetForm assetForm, String fundId);
/**
* 进件审核
* @param assetForm
* @param data
* @param userLoanType
* @return true:进件成功 false:进件失败
*/
public boolean audit(AssetForm assetForm, Map<String, Object> data, Integer userLoanType, String fundId);
}
package com.quantgroup.asset.distribution.service.funding;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundAuditOrder;
/**
* @author : Hyuk
* @description : IAidFundAuditOrderService
* @date : 2020/3/30 10:31 上午
*/
public interface IAidFundAuditOrderService {
public AidLoanFundAuditOrder saveAidFundAuditOrder(AidLoanFundAuditOrder aidLoanFundAuditOrder);
/**
* 更改助贷资金路由审核订单状态
* @param aidLoanFundAuditOrder
* @param status
* @return
*/
public AidLoanFundAuditOrder updateOrderStatus(AidLoanFundAuditOrder aidLoanFundAuditOrder, Integer status);
/**
* 根据三元素查找审核订单
* @param bizNo
* @param fundId
* @param auditResult
* @return
*/
public AidLoanFundAuditOrder findByBizNoAndFundId(String bizNo, String fundId);
}
...@@ -3,6 +3,10 @@ package com.quantgroup.asset.distribution.service.funding; ...@@ -3,6 +3,10 @@ package com.quantgroup.asset.distribution.service.funding;
import com.quantgroup.asset.distribution.enums.funding.FundingResult; import com.quantgroup.asset.distribution.enums.funding.FundingResult;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundRouteRecord; import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundRouteRecord;
import java.util.concurrent.TimeUnit;
import static com.quantgroup.asset.distribution.constant.RedisKeyConstants.FINISH_ROUTE_AID_FUND_KEY;
/** /**
* Created by renfeng on 2019/7/17. * Created by renfeng on 2019/7/17.
*/ */
...@@ -11,20 +15,37 @@ public interface IAidFundRouteRecordService { ...@@ -11,20 +15,37 @@ public interface IAidFundRouteRecordService {
/** /**
* 资金分配结果通知 * 资金分配结果通知
*
* @param bizNo * @param bizNo
* @param fundingResult * @param fundingResult
*/ */
void fundingResultNotity(String bizNo,FundingResult fundingResult); void fundingResultNotity(String bizNo, FundingResult fundingResult);
/** /**
* 保存主贷资金路由记录 * 保存主贷资金路由记录
*
* @param aidLoanFundRouteRecord * @param aidLoanFundRouteRecord
*/ */
void saveAidLoanFundRouteRecord(AidLoanFundRouteRecord aidLoanFundRouteRecord); AidLoanFundRouteRecord saveAidLoanFundRouteRecord(AidLoanFundRouteRecord aidLoanFundRouteRecord);
/**
* 根据bizNo和fundId找路由记录
*
* @param bizNo
* @param fundId
* @return
*/
AidLoanFundRouteRecord findByBizNoAndFundId(String bizNo, String fundId);
/**
* 更改助贷资金路由记录状态
*
* @param aidLoanFundRouteRecord
* @param status
* @return
*/
AidLoanFundRouteRecord updateAidLoanFundRouteRecordStatus(AidLoanFundRouteRecord aidLoanFundRouteRecord, Integer status);
} }
...@@ -4,6 +4,7 @@ import java.util.Map; ...@@ -4,6 +4,7 @@ import java.util.Map;
import com.quantgroup.asset.distribution.model.form.AssetForm; import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.model.response.GlobalResponse; import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import com.quantgroup.asset.distribution.service.jpa.entity.Asset;
/** /**
* Created by renfeng on 2019/7/17. * Created by renfeng on 2019/7/17.
...@@ -17,6 +18,6 @@ public interface IAidFundRouteService { ...@@ -17,6 +18,6 @@ public interface IAidFundRouteService {
* @param userLoanType * @param userLoanType
* @return * @return
*/ */
GlobalResponse aidFundRoute(AssetForm assetForm,Integer userLoanType, Map<String, Object> data); boolean aidFundRoute(AssetForm assetForm, Asset asset, Map<String, Object> data);
} }
package com.quantgroup.asset.distribution.service.funding; package com.quantgroup.asset.distribution.service.funding;
import com.quantgroup.asset.distribution.config.annotation.HandleException;
import com.quantgroup.asset.distribution.model.entity.fund.FundConfigCondition;
import com.quantgroup.asset.distribution.model.response.GlobalResponse; import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import java.util.List;
/** /**
* 资方模块Service * 资方模块Service
* @author liwenbin * @author liwenbin
...@@ -103,8 +99,4 @@ public interface IFundModuleService { ...@@ -103,8 +99,4 @@ public interface IFundModuleService {
* @return * @return
*/ */
public GlobalResponse audit(Long id, Integer auditStatus); public GlobalResponse audit(Long id, Integer auditStatus);
GlobalResponse getAllConditionsOfFundConfig(Long configId);
GlobalResponse simulationCases(List<FundConfigCondition> configConditions,Long configId);
} }
package com.quantgroup.asset.distribution.service.funding.impl;
import com.quantgroup.asset.distribution.constant.AidFundConstants;
import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.exception.QGExceptionType;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.service.funding.IAidFundAssetService;
import com.quantgroup.asset.distribution.service.niwodai.INiwodaiAssetService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @author : Hyuk
* @description : AidFundAssetServiceIMpl
* @date : 2020/3/27 5:22 下午
*/
@Slf4j
@Service
public class AidFundAssetServiceImpl implements IAidFundAssetService {
@Autowired
private INiwodaiAssetService niwodaiAssetService;
@Override
public boolean preAudit(AssetForm assetForm, String fundId) {
switch (fundId) {
case AidFundConstants.FundId.NIWODAI : {
return niwodaiAssetService.preAudit(assetForm.getUuid()).getPass().booleanValue();
}
default :
throw new QGException(QGExceptionType.UNKNOW_AID_FUND_ID);
}
}
@Override
public boolean audit(AssetForm assetForm, Map<String, Object> data, Integer userLoanType, String fundId) {
switch (fundId) {
case AidFundConstants.FundId.NIWODAI : {
return niwodaiAssetService.incoming(assetForm, data, userLoanType).getCode().equals(300007);
}
default :
throw new QGException(QGExceptionType.UNKNOW_AID_FUND_ID);
}
}
}
package com.quantgroup.asset.distribution.service.funding.impl;
import com.quantgroup.asset.distribution.constant.RedisKeyConstants;
import com.quantgroup.asset.distribution.service.funding.IAidFundAuditOrderService;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundAuditOrder;
import com.quantgroup.asset.distribution.service.jpa.repository.IAidLoanFundAuditOrderRepository;
import com.quantgroup.asset.distribution.service.redis.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* @author : Hyuk
* @description : AidFundAuditOrderServiceIMpl
* @date : 2020/3/30 11:14 上午
*/
@Service
public class AidFundAuditOrderServiceImpl implements IAidFundAuditOrderService {
@Autowired
private IAidLoanFundAuditOrderRepository aidLoanFundAuditOrderRepository;
@Autowired
private IRedisService<AidLoanFundAuditOrder> redisService;
@Override
public AidLoanFundAuditOrder saveAidFundAuditOrder(AidLoanFundAuditOrder aidLoanFundAuditOrder) {
aidLoanFundAuditOrder = aidLoanFundAuditOrderRepository.save(aidLoanFundAuditOrder);
String key = RedisKeyConstants.AID_FUND_AUDIT_ORDER_KEY + aidLoanFundAuditOrder.getBizNo() + "_" + aidLoanFundAuditOrder.getFundId();
redisService.setEntityEx(key, aidLoanFundAuditOrder, 30, TimeUnit.MINUTES);
return aidLoanFundAuditOrder;
}
@Override
public AidLoanFundAuditOrder updateOrderStatus(AidLoanFundAuditOrder aidLoanFundAuditOrder, Integer status) {
aidLoanFundAuditOrder.setAuditResult(status);
return saveAidFundAuditOrder(aidLoanFundAuditOrder);
}
@Override
public AidLoanFundAuditOrder findByBizNoAndFundId(String bizNo, String fundId) {
String key = RedisKeyConstants.AID_FUND_AUDIT_ORDER_KEY + bizNo + "_" + fundId;
AidLoanFundAuditOrder aidLoanFundAuditOrder = redisService.getEntity(key);
if (aidLoanFundAuditOrder == null) {
aidLoanFundAuditOrder = aidLoanFundAuditOrderRepository.findByBizNoAndFundIdAndEnableIsTrue(bizNo, fundId);
if (aidLoanFundAuditOrder != null) {
redisService.setEntityEx(key, aidLoanFundAuditOrder, 30, TimeUnit.MINUTES);
}
}
return aidLoanFundAuditOrder;
}
}
...@@ -13,6 +13,7 @@ import org.springframework.stereotype.Service; ...@@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static com.quantgroup.asset.distribution.constant.RedisKeyConstants.AID_LOAN_COUNT_LIMIT_KEY; import static com.quantgroup.asset.distribution.constant.RedisKeyConstants.AID_LOAN_COUNT_LIMIT_KEY;
import static com.quantgroup.asset.distribution.constant.RedisKeyConstants.FINISH_ROUTE_AID_FUND_KEY;
/** /**
* Created by renfeng on 2019/7/19. * Created by renfeng on 2019/7/19.
...@@ -26,9 +27,8 @@ public class AidFundRouteRecordServiceImpl implements IAidFundRouteRecordService ...@@ -26,9 +27,8 @@ public class AidFundRouteRecordServiceImpl implements IAidFundRouteRecordService
@Autowired @Autowired
private IAidLoanFundRouteRecordRepository iAidLoanFundRouteRecordRepository; private IAidLoanFundRouteRecordRepository iAidLoanFundRouteRecordRepository;
@Autowired @Autowired
private IRedisService<String> redisService; private IRedisService<AidLoanFundRouteRecord> redisService;
/** /**
* 资金分配结果通知 * 资金分配结果通知
...@@ -59,9 +59,29 @@ public class AidFundRouteRecordServiceImpl implements IAidFundRouteRecordService ...@@ -59,9 +59,29 @@ public class AidFundRouteRecordServiceImpl implements IAidFundRouteRecordService
* @param aidLoanFundRouteRecord * @param aidLoanFundRouteRecord
*/ */
@Override @Override
public void saveAidLoanFundRouteRecord(AidLoanFundRouteRecord aidLoanFundRouteRecord) { public AidLoanFundRouteRecord saveAidLoanFundRouteRecord(AidLoanFundRouteRecord aidLoanFundRouteRecord) {
iAidLoanFundRouteRecordRepository.save(aidLoanFundRouteRecord); AidLoanFundRouteRecord record = iAidLoanFundRouteRecordRepository.save(aidLoanFundRouteRecord);
redisService.setEntityEx(FINISH_ROUTE_AID_FUND_KEY + record.getBizNo() + "_" + record.getFundId(),
record, 30, TimeUnit.MINUTES);
return record;
} }
@Override
public AidLoanFundRouteRecord findByBizNoAndFundId(String bizNo, String fundId) {
String key = FINISH_ROUTE_AID_FUND_KEY + bizNo + "_" + fundId;
AidLoanFundRouteRecord record = redisService.getEntity(key);
if (record == null) {
record = iAidLoanFundRouteRecordRepository.findByBizNoAndFundId(bizNo, fundId);
if (record != null) {
redisService.setEntityEx(key, record, 30, TimeUnit.MINUTES);
}
}
return record;
}
@Override
public AidLoanFundRouteRecord updateAidLoanFundRouteRecordStatus(AidLoanFundRouteRecord aidLoanFundRouteRecord, Integer status) {
aidLoanFundRouteRecord.setAidFundRouteStatus(status);
return saveAidLoanFundRouteRecord(aidLoanFundRouteRecord);
}
} }
...@@ -2,14 +2,16 @@ package com.quantgroup.asset.distribution.service.funding.impl; ...@@ -2,14 +2,16 @@ package com.quantgroup.asset.distribution.service.funding.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.quantgroup.asset.distribution.constant.AidFundStatus;
import com.quantgroup.asset.distribution.model.form.AssetForm; import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.model.response.GlobalResponse; import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import com.quantgroup.asset.distribution.service.funding.IAidFundRouteRecordService; import com.quantgroup.asset.distribution.service.funding.*;
import com.quantgroup.asset.distribution.service.funding.IAidFundRouteService; import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundAuditOrder;
import com.quantgroup.asset.distribution.service.funding.IAidLoanFundConfigService;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundConfig; import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundConfig;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundRouteRecord; import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundRouteRecord;
import com.quantgroup.asset.distribution.service.jpa.entity.Asset;
import com.quantgroup.asset.distribution.service.jpa.repository.ICustomerTypeRuleConfigRepository; import com.quantgroup.asset.distribution.service.jpa.repository.ICustomerTypeRuleConfigRepository;
import com.quantgroup.asset.distribution.service.niwodai.INiwodaiAssetService;
import com.quantgroup.asset.distribution.service.redis.IRedisService; import com.quantgroup.asset.distribution.service.redis.IRedisService;
import com.quantgroup.asset.distribution.service.rule.IRuleService; import com.quantgroup.asset.distribution.service.rule.IRuleService;
import com.quantgroup.asset.distribution.util.DateUtil; import com.quantgroup.asset.distribution.util.DateUtil;
...@@ -43,14 +45,16 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService { ...@@ -43,14 +45,16 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService {
private IAidFundRouteRecordService iAidFundRouteRecordService; private IAidFundRouteRecordService iAidFundRouteRecordService;
@Autowired @Autowired
private IRedisService<String> redisService; private IRedisService<String> redisService;
@Autowired @Autowired
private IRedisService<AssetForm> redisServiceAssetForm; private IRedisService<AidLoanFundRouteRecord> redisRouteRecord;
@Autowired @Autowired
private IRuleService ruleService; private IRuleService ruleService;
@Autowired @Autowired
private ICustomerTypeRuleConfigRepository iCustomerTypeRuleConfigRepository; private ICustomerTypeRuleConfigRepository iCustomerTypeRuleConfigRepository;
@Autowired
private IAidFundAssetService aidFundAssetService;
@Autowired
private IAidFundAuditOrderService aidFundAuditOrderService;
/** /**
* 助贷资金路由 * 助贷资金路由
...@@ -60,7 +64,7 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService { ...@@ -60,7 +64,7 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService {
* @return * @return
*/ */
@Override @Override
public GlobalResponse aidFundRoute(AssetForm assetForm,Integer userLoanType, Map<String, Object> data) { public boolean aidFundRoute(AssetForm assetForm, Asset asset, Map<String, Object> data) {
Stopwatch started = Stopwatch.createStarted(); Stopwatch started = Stopwatch.createStarted();
...@@ -97,29 +101,36 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService { ...@@ -97,29 +101,36 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService {
for(AidLoanFundConfig aidLoanFundConfig : aidLoanFundConfigSet){ for(AidLoanFundConfig aidLoanFundConfig : aidLoanFundConfigSet){
//此助贷资方如果已经被这笔订单路由过 就跳过 //此助贷资方如果已经被这笔订单路由过 就跳过
if(String.valueOf(aidLoanFundConfig.getFundId()) AidLoanFundRouteRecord aidLoanFundRouteRecord = iAidFundRouteRecordService.findByBizNoAndFundId(assetForm.getBizNo(), aidLoanFundConfig.getFundId());
.equals(redisServiceAssetForm.getString(FINISH_ROUTE_AID_FUND_KEY + assetForm.getBizNo()))) int status = aidLoanFundRouteRecord == null ? -1 : aidLoanFundRouteRecord.getAidFundRouteStatus().intValue();
if (status == AidFundStatus.Route.INCOMING_COMPLETE || status == AidFundStatus.Route.PRE_REJECT) {
// 进件完成和准入拒绝的直接跳过
continue; continue;
}
//助贷资金分配规则校验 //助贷资金分配规则校验
if(ruleService.valid(aidLoanFundConfig.getFundRuleEl(), data)){ if(ruleService.valid(aidLoanFundConfig.getFundRuleEl(), data)){
//助贷资金准入接口调用 // 助贷资金准入接口调用
boolean accessResult = false;//todo 调用真实的准入接口 boolean accessResult = false;
if (status == AidFundStatus.Route.PRE_PASS) {
//保存主贷资金路由记录 accessResult = true;
AidLoanFundRouteRecord aidLoanFundRouteRecord = new AidLoanFundRouteRecord(); } else {
aidLoanFundRouteRecord.setAidFundRouteStatus(accessResult?1:2);//1-准入成功 2-准入失败 3-进件成功 4-进件失败 accessResult = aidFundAssetService.preAudit(assetForm, aidLoanFundConfig.getFundId());
// 保存主贷资金路由记录
aidLoanFundRouteRecord = new AidLoanFundRouteRecord();
aidLoanFundRouteRecord.setAidFundRouteStatus(accessResult ? AidFundStatus.Route.PRE_PASS : AidFundStatus.Route.PRE_REJECT);//1-准入成功 2-准入失败 3-进件完成
aidLoanFundRouteRecord.setAssetNo(assetForm.getAssetNo()); aidLoanFundRouteRecord.setAssetNo(assetForm.getAssetNo());
aidLoanFundRouteRecord.setUuid(assetForm.getUuid()); aidLoanFundRouteRecord.setUuid(assetForm.getUuid());
aidLoanFundRouteRecord.setBizChannel(assetForm.getBizChannel()); aidLoanFundRouteRecord.setBizChannel(assetForm.getBizChannel());
aidLoanFundRouteRecord.setBizNo(assetForm.getBizNo()); aidLoanFundRouteRecord.setBizNo(assetForm.getBizNo());
aidLoanFundRouteRecord.setFinanceProductType(Integer.parseInt(assetForm.getBizType())); aidLoanFundRouteRecord.setFinanceProductType(Integer.parseInt(assetForm.getBizType()));
aidLoanFundRouteRecord.setUserLoanType(userLoanType); aidLoanFundRouteRecord.setUserLoanType(asset.getUserLoanType());
aidLoanFundRouteRecord.setFundNo(aidLoanFundConfig.getFundNo()); aidLoanFundRouteRecord.setFundNo(aidLoanFundConfig.getFundNo());
aidLoanFundRouteRecord.setFundId(aidLoanFundConfig.getFundId()); aidLoanFundRouteRecord.setFundId(aidLoanFundConfig.getFundId());
aidLoanFundRouteRecord.setEnable(true); aidLoanFundRouteRecord.setEnable(true);
iAidFundRouteRecordService.saveAidLoanFundRouteRecord(aidLoanFundRouteRecord); aidLoanFundRouteRecord = iAidFundRouteRecordService.saveAidLoanFundRouteRecord(aidLoanFundRouteRecord);
log.info("主贷资金路由-准入完成, bizChannel : {} , uuid : {} , bizNo : {} , fundId : {} , 准入结果: {} , 耗时 : {}",assetForm.getBizChannel(),assetForm.getUuid(),assetForm.getBizNo(),aidLoanFundRouteRecord.getFundId(),accessResult,started.stop().elapsed(TimeUnit.MILLISECONDS)); log.info("助贷资金路由-准入完成, bizChannel : {} , uuid : {} , bizNo : {} , fundId : {} , 准入结果 : {} , 耗时 : {}",assetForm.getBizChannel(),assetForm.getUuid(),assetForm.getBizNo(),aidLoanFundRouteRecord.getFundId(),accessResult,started.elapsed(TimeUnit.MILLISECONDS));
}
if(accessResult){ if(accessResult){
//客户类别区分 1-自然流量 2-拒绝流量 留在这里 你我贷暂时不用 等以后要用时 随时可用 //客户类别区分 1-自然流量 2-拒绝流量 留在这里 你我贷暂时不用 等以后要用时 随时可用
...@@ -132,14 +143,52 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService { ...@@ -132,14 +143,52 @@ public class AidFundRouteServiceImpl implements IAidFundRouteService {
// } // }
// } // }
// } // }
//todo 调用助贷资方进件接口 异步 // 先创建进件订单记录
AidLoanFundAuditOrder aidLoanFundAuditOrder = createAidFundAuditOrder(aidLoanFundRouteRecord, assetForm, asset, data);
log.info("主贷资金路由-进件完成, bizChannel : {} , uuid : {} , bizNo : {} , fundId : {} , 耗时 : {} ",assetForm.getBizChannel(),assetForm.getUuid(),assetForm.getBizNo(),aidLoanFundRouteRecord.getFundId(),started.stop().elapsed(TimeUnit.MILLISECONDS)); // 调用助贷资方进件接口 异步
return GlobalResponse.success(); boolean incomingResult = aidFundAssetService.audit(assetForm, data, asset.getUserLoanType(), aidLoanFundConfig.getFundId());
// 将助贷路由记录状态改为进件完成
iAidFundRouteRecordService.updateAidLoanFundRouteRecordStatus(aidLoanFundRouteRecord, AidFundStatus.Route.INCOMING_COMPLETE);
log.info("助贷资金路由-进件完成, bizChannel : {} , uuid : {} , bizNo : {} , fundId : {} , 进件结果 : {}, 耗时 : {} ",assetForm.getBizChannel(),assetForm.getUuid(),assetForm.getBizNo(),aidLoanFundRouteRecord.getFundId(),incomingResult,started.stop().elapsed(TimeUnit.MILLISECONDS));
if (incomingResult) {
aidFundAuditOrderService.updateOrderStatus(aidLoanFundAuditOrder, AidFundStatus.Incoming.WAIT);
return true;
} else {
aidFundAuditOrderService.updateOrderStatus(aidLoanFundAuditOrder, AidFundStatus.Incoming.REJECT);
} }
} }
} }
} }
return GlobalResponse.error("未匹配到助贷资金"); }
return false;
}
/**
* 创建资方审核订单
* @param aidLoanFundRouteRecord
* @param assetForm
* @param asset
* @param data
*/
private AidLoanFundAuditOrder createAidFundAuditOrder(AidLoanFundRouteRecord aidLoanFundRouteRecord, AssetForm assetForm, Asset asset, Map<String, Object> data) {
AidLoanFundAuditOrder aidLoanFundAuditOrder = aidFundAuditOrderService.findByBizNoAndFundId(assetForm.getBizNo(), aidLoanFundRouteRecord.getFundId());
if (aidLoanFundAuditOrder != null) {
log.info("助贷资方审核订单已存在, 直接返回订单, uuid : {}, bizNo : {}, assetNo : {}, bizChannel : {}, orderStatus : {}", assetForm.getUuid(), assetForm.getBizNo(),
assetForm.getAssetNo(), assetForm.getBizChannel(), aidLoanFundAuditOrder.getAuditResult());
return aidLoanFundAuditOrder;
}
aidLoanFundAuditOrder = new AidLoanFundAuditOrder();
aidLoanFundAuditOrder.setAssetNo(asset.getAssetNo());
aidLoanFundAuditOrder.setFundNo(aidLoanFundRouteRecord.getFundNo());
aidLoanFundAuditOrder.setUuid(assetForm.getUuid());
aidLoanFundAuditOrder.setBizNo(assetForm.getBizNo());
aidLoanFundAuditOrder.setFundId(aidLoanFundRouteRecord.getFundId());
aidLoanFundAuditOrder.setAssetFormText(JSON.toJSONString(assetForm));
aidLoanFundAuditOrder.setAssetText(JSON.toJSONString(asset));
aidLoanFundAuditOrder.setDataText(JSON.toJSONString(data));
aidLoanFundAuditOrder.setAuditResult(AidFundStatus.Incoming.PRE);
aidLoanFundAuditOrder.setEnable(true);
return aidFundAuditOrderService.saveAidFundAuditOrder(aidLoanFundAuditOrder);
} }
} }
package com.quantgroup.asset.distribution.service.funding.impl; package com.quantgroup.asset.distribution.service.funding.impl;
import java.math.BigDecimal; import java.util.ArrayList;
import java.math.RoundingMode; import java.util.List;
import java.util.*; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSON;
import com.quantgroup.asset.distribution.enums.RuleOperator;
import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfigNew;
import com.quantgroup.asset.distribution.model.entity.fund.FundConfigCondition;
import com.quantgroup.asset.distribution.model.entity.fund.FundConfigSimulationVO;
import com.quantgroup.asset.distribution.service.funding.IFundModuleChannelFundConfigNewService; import com.quantgroup.asset.distribution.service.funding.IFundModuleChannelFundConfigNewService;
import com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew; import com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew;
import com.quantgroup.asset.distribution.service.rule.IRuleService;
import com.quantgroup.asset.distribution.service.rule.vo.BaseRuleVO;
import com.quantgroup.asset.distribution.service.rule.vo.IRuleVO;
import com.quantgroup.asset.distribution.service.rule.vo.UnionRuleVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -66,8 +53,6 @@ public class FundModuleServiceImpl implements IFundModuleService{ ...@@ -66,8 +53,6 @@ public class FundModuleServiceImpl implements IFundModuleService{
private IFundModuleChannelFundConfigNewService fundModuleChannelFundConfigNewService; private IFundModuleChannelFundConfigNewService fundModuleChannelFundConfigNewService;
@Autowired @Autowired
private IApprovalLogService approvalLogService; private IApprovalLogService approvalLogService;
@Autowired
private IRuleService ruleService;
@Value("${clotho.url}") @Value("${clotho.url}")
private String clothoURL; private String clothoURL;
...@@ -191,311 +176,4 @@ public class FundModuleServiceImpl implements IFundModuleService{ ...@@ -191,311 +176,4 @@ public class FundModuleServiceImpl implements IFundModuleService{
return GlobalResponse.create(FundModuleResponse.UKNOW_AUDIT_STATUS); return GlobalResponse.create(FundModuleResponse.UKNOW_AUDIT_STATUS);
} }
} }
@HandleException
@Override
public GlobalResponse getAllConditionsOfFundConfig(Long configId){
FundModuleChannelFundConfigNew config = fundModuleChannelFundConfigNewService.findById(configId);
// 未找到资方渠道配置直接通知
if (config == null) {
return GlobalResponse.error("未找到相关配置");
}
List<ChannelFundConfigNew> fundConfigList = JSONArray.parseArray(config.getFunds(), ChannelFundConfigNew.class);
List<FundModuleLimitTypeConfig> typeConfigs = fundModuleLimitTypeService.getAllLimitType();
Map<String,String> codeToNameMap = new HashMap<>();
for (FundModuleLimitTypeConfig typeConfig : typeConfigs){
codeToNameMap.put(typeConfig.getCode(),typeConfig.getName());
}
List<BaseRuleVO> baseRuleList = new ArrayList<>();
for (ChannelFundConfigNew channelFundConfig : fundConfigList) {
IRuleVO ruleVO = ruleService.getIRuleVo(channelFundConfig.getLimits());
baseRuleList.addAll(getAllBaseRule(ruleVO));
}
Map<String,List<String>> keyValueMap = collectValueMap(baseRuleList);
//去掉相同的值 例如 amount>3000 和amount>=3000在生成案例时 3001都可以满足 此时会有两个3001
for (Map.Entry<String,List<String>> entry : keyValueMap.entrySet()){
entry.setValue(new ArrayList<>(new LinkedHashSet<>(entry.getValue())));
}
List<FundConfigCondition> configConditions = createCondition(keyValueMap,codeToNameMap);
FundConfigSimulationVO vo = new FundConfigSimulationVO();
vo.setConditionsCase(configConditions);
List<FundConfigCondition.Condition> type = new ArrayList<>();
for (String key : keyValueMap.keySet()){
FundConfigCondition.Condition condition = new FundConfigCondition.Condition();
condition.setConditionCode(key);
condition.setConditionName(codeToNameMap.get(key));
type.add(condition);
}
vo.setConditionsType(type);
return GlobalResponse.success(vo);
}
@Override
public GlobalResponse simulationCases(List<FundConfigCondition> configConditions,Long configId) {
FundModuleChannelFundConfigNew config = fundModuleChannelFundConfigNewService.findById(configId);
if (config == null) {
return GlobalResponse.error("未找到相关配置");
}
List<ChannelFundConfigNew> fundConfigList = JSONArray.parseArray(config.getFunds(), ChannelFundConfigNew.class);
B:for (FundConfigCondition configCondition : configConditions){
Map<String,Object> data = new HashMap<>();
for (FundConfigCondition.Condition condition : configCondition.getCondition()){
String value = condition.getConditionValue();
Class<?> clazz = getType(value);
if (clazz.isAssignableFrom(BigDecimal.class)){
data.put(condition.getConditionCode(),new BigDecimal(value));
}else{
data.put(condition.getConditionCode(),value);
}
}
// 资方去重, 可能存在多条件同一个资方
Set<String> fundSet = new HashSet<>();
JSONArray fundArray = new JSONArray();
A:for (ChannelFundConfigNew channelFundConfig : fundConfigList) {
IRuleVO ruleVO = ruleService.getIRuleVo(channelFundConfig.getLimits());
if (ruleVO == null) { throw new QGException(QGExceptionType.CRATE_RULE_VO_ERROR); }
Set<String> params = ruleVO.getParamNames();
for (String key : params) {
if (!data.containsKey(key)) {
continue A;
}
}
if (!ruleVO.valid(data)) {
continue;
}
String key = channelFundConfig.getFundId() + "_" + channelFundConfig.getFundProductId() + "_" + channelFundConfig.getPriority();
if (!fundSet.contains(key)) {
// 创建并增加资方配置
JSONObject fundInfoJSON = new JSONObject();
fundInfoJSON.put("fundId", channelFundConfig.getFundId());
fundInfoJSON.put("fundProductId", channelFundConfig.getFundProductId());
fundInfoJSON.put("priority", channelFundConfig.getPriority());
fundArray.add(fundInfoJSON);
fundSet.add(key);
}
}
FundConfigCondition.Result result = new FundConfigCondition.Result();
if (CollectionUtils.isEmpty(fundArray)){
result.setSuccess(false);
configCondition.setResult(result);
continue;
}
QGPreconditions.checkArgument(fundArray.size() != 0, QGExceptionType.NO_FUND_INFO_BEEN_HIT);
// 看命中优先级是否符合要求
boolean[] bucket = new boolean[fundArray.size() + 1];
for (int i = 0, len = fundArray.size(); i < len; i++) {
int priority = fundArray.getJSONObject(i).getIntValue("priority");
if (!(priority > 0 && priority <= len)) {
throw new QGException(QGExceptionType.FUND_PRIORITY_IS_ERROR);
}
if (bucket[priority]) {
// 多个相同的优先级
throw new QGException(QGExceptionType.FUND_PRIORITY_IS_ERROR);
}
bucket[priority] = true;
}
result.setSuccess(true);
fundArray = JSONArray.parseArray(JSON.toJSONString(fundArray.stream().sorted(Comparator.comparingInt(o -> ((JSONObject) o).getInteger("priority"))).collect(Collectors.toList())));
String fundProductId = fundArray.getJSONObject(0).getString("fundProductId");
String fundId = fundArray.getJSONObject(0).getString("fundId");
result.setFundInfo(("null".equals(fundProductId) || StringUtils.isEmpty(fundProductId))?fundId:fundId+"_"+fundProductId);
configCondition.setResult(result);
}
FundConfigSimulationVO vo = new FundConfigSimulationVO();
vo.setConditionsCase(configConditions);
return GlobalResponse.success(vo);
}
private static List<BaseRuleVO> getAllBaseRule(IRuleVO ruleVO){
List<BaseRuleVO> baseRuleList = new ArrayList<>();
if (ruleVO.getClass().isAssignableFrom(UnionRuleVO.class)){
UnionRuleVO uRuleVo = (UnionRuleVO)ruleVO;
baseRuleList= uRuleVo.getBaseRules();
}else {
baseRuleList.add((BaseRuleVO)ruleVO);
}
return baseRuleList;
}
private static List<String> createValue(String operator,String value){
List<String> list = new ArrayList<>();
switch (RuleOperator.fromCode(operator)) {
case Equal:
case NotEqual:
list.add(getValue(RuleOperator.Equal.getCode(),value));
list.add(getValue(RuleOperator.NotEqual.getCode(),value));
return list;
case In:
case NotIn:
list.add(getValue(RuleOperator.In.getCode(),value));
list.add(getValue(RuleOperator.NotIn.getCode(),value));
return list;
case LessThan:
case GreaterThanOrEqual:
list.add(getValue(RuleOperator.LessThan.getCode(),value));
list.add(getValue(RuleOperator.GreaterThanOrEqual.getCode(),value));
return list;
case GreaterThan:
case LessThanOrEqual:
list.add(getValue(RuleOperator.GreaterThan.getCode(),value));
list.add(getValue(RuleOperator.LessThanOrEqual.getCode(),value));
return list;
default:
throw new QGException(QGExceptionType.RULE_OPERATOR_NOT_EXIST);
}
}
private static String getValue(String operator,String value){
Class<?> clazz = getType(value);
switch (RuleOperator.fromCode(operator)) {
case Equal:
return value;
case NotEqual:
if (clazz.isAssignableFrom(BigDecimal.class)) {
return new BigDecimal(value).add(new BigDecimal(1)).toString();
}else if (clazz.isAssignableFrom(Boolean.class)){
return Boolean.toString(!Boolean.valueOf(value));
}else {
if (value.length() == 1){
return String.valueOf((char) (value.charAt(0) + 1));
}else {
return value.substring(0,value.length() - 1) + String.valueOf((char) (value.charAt(value.length() -1 ) + 1));
}
}
case In:
if (value.contains(",")){
List<String> list = Arrays.asList(value.split(","));
return list.get(RandomUtils.nextInt(0,list.size()-1));
}else {
return value;
}
case NotIn:
if (value.contains(",")){
List<String> list = Arrays.asList(value.split(","));
if (BigDecimal.class.isAssignableFrom(list.get(0).getClass())){
Integer num = 1;
while (list.contains(String.valueOf(num))){
num ++;
}
return num.toString();
}else {
String start = getValue(operator,list.get(0));
while (list.contains(start)){
start = getValue(operator,start);
}
return start;
}
}else {
return value;
}
case LessThan:
if (BigDecimal.class.isAssignableFrom(clazz)){
if (new BigDecimal(value).doubleValue() < 1 && new BigDecimal(value).doubleValue() > 0){
return new BigDecimal(value).divide(new BigDecimal(10),value.split(".")[1].length(), RoundingMode.HALF_UP).toString();
}else {
return new BigDecimal(value).subtract(new BigDecimal(1)).toString();
}
}else {
throw new QGException(QGExceptionType.CRATE_RULE_VO_ERROR);
}
case GreaterThan:
if (BigDecimal.class.isAssignableFrom(clazz)){
return new BigDecimal(value).add(new BigDecimal(1)).toString();
}else {
throw new QGException(QGExceptionType.CRATE_RULE_VO_ERROR);
}
case LessThanOrEqual:
return getValue("<",value);
case GreaterThanOrEqual:
return getValue(">",value);
default:
throw new QGException(QGExceptionType.RULE_OPERATOR_NOT_EXIST);
}
}
private static Class<?> getType(String value){
if (StringUtils.isNumeric(value)){
return BigDecimal.class;
}
if ("true".equals(value) || "false".equals(value)){
return Boolean.class;
}
return String.class;
}
private static Map<String,List<String>> collectValueMap(List<BaseRuleVO> vos){
Map<String,List<String>> keyValueMap = new HashMap<>();
for (BaseRuleVO vo : vos){
if (keyValueMap.containsKey(vo.getKey())){
keyValueMap.get(vo.getKey()).addAll(createValue(vo.getOperator(),vo.getValue()));
}else {
keyValueMap.put(vo.getKey(),new ArrayList<>(createValue(vo.getOperator(),vo.getValue())));
}
}
return keyValueMap;
}
/**
* 对map中的每个key的list做笛卡儿积
* @param map
* @return
*/
private static List<FundConfigCondition> createCondition(Map<String,List<String>> map,Map<String,String> codeToNameMap){
List<FundConfigCondition> configConditions = new ArrayList<>();
List<String> keyList = new ArrayList<>(map.keySet());
List<List<String>> dimensionValue = new ArrayList<>();
for (String key:keyList){
dimensionValue.add(map.get(key));
}
List<List<String>> results = new ArrayList<>();
descartes(dimensionValue,results,0,new ArrayList<>());
for (int i = 0;i<results.size();i++){
FundConfigCondition configCondition = new FundConfigCondition();
List<FundConfigCondition.Condition> conditions = new ArrayList<>();
for (int j = 0;j<results.get(i).size();j++){
FundConfigCondition.Condition condition = new FundConfigCondition.Condition();
condition.setConditionCode(keyList.get(j));
condition.setConditionValue(results.get(i).get(j));
condition.setConditionName(codeToNameMap.get(keyList.get(j)));
conditions.add(condition);
}
configCondition.setConditionTempId(String.valueOf(i));
configCondition.setCondition(conditions);
configConditions.add(configCondition);
}
return configConditions;
}
/**
* 笛卡尔积演算
* @param dimensionValue
* @param result
* @param layer
* @param currentList
* @param <T>
*/
private static <T> void descartes(List<List<T>> dimensionValue, List<List<T>> result, int layer, List<T> currentList) {
if (layer < dimensionValue.size() - 1) {
if (dimensionValue.get(layer).size() == 0) {
descartes(dimensionValue, result, layer + 1, currentList);
} else {
for (int i = 0; i < dimensionValue.get(layer).size(); i++) {
List<T> list = new ArrayList<>(currentList);
list.add(dimensionValue.get(layer).get(i));
descartes(dimensionValue, result, layer + 1, list);
}
}
} else if (layer == dimensionValue.size() - 1) {
if (dimensionValue.get(layer).size() == 0) {
result.add(currentList);
} else {
for (int i = 0; i < dimensionValue.get(layer).size(); i++) {
List<T> list = new ArrayList<>(currentList);
list.add(dimensionValue.get(layer).get(i));
result.add(list);
}
}
}
}
} }
package com.quantgroup.asset.distribution.service.jpa.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @author : Hyuk
* @description : AidLoanFundAuditOrder
* @date : 2020/3/30 1:28 上午
*/
@Entity
@Table(name="aid_loan_fund_audit_order")
@Data
public class AidLoanFundAuditOrder implements Serializable {
private static final long serialVersionUID = -1L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "asset_no")
private String assetNo;
@Column(name = "fund_no")
private String fundNo;
@Column(name = "uuid")
private String uuid;
@Column(name = "biz_no")
private String bizNo;
@Column(name = "fund_id")
private String fundId;
@Column(name = "asset_form_text")
private String assetFormText;
@Column(name = "asset_text")
private String assetText;
@Column(name = "data_text")
private String dataText;
// 1-通过,2-拒绝,3-审核中
@Column(name = "audit_result")
private Integer auditResult;
@Column(name = "audit_context")
private String auditContext;
@Column(name = "enable")
private Boolean enable;
@Column(name = "created_at")
private Timestamp createdAt;
@Column(name = "updated_at")
private Timestamp updatedAt;
@PrePersist
public void prePersist() {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
createdAt = timestamp;
updatedAt = timestamp;
}
@PreUpdate
public void preUpdate() {
updatedAt = new Timestamp(System.currentTimeMillis());
}
}
package com.quantgroup.asset.distribution.service.jpa.repository;
import com.quantgroup.asset.distribution.service.jpa.entity.AidLoanFundAuditOrder;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author : Hyuk
* @description : IAidLoanFundAuditOrderRepository
* @date : 2020/3/30 1:34 上午
*/
public interface IAidLoanFundAuditOrderRepository extends JpaRepository<AidLoanFundAuditOrder, Long> {
/**
* 根据三元素查找订单
* @param bizNo
* @param fundId
* @param auditResult
* @return
*/
public AidLoanFundAuditOrder findByBizNoAndFundIdAndEnableIsTrue(String bizNo, String fundId);
}
...@@ -13,5 +13,5 @@ public interface IAidLoanFundRouteRecordRepository extends JpaRepository<AidLoan ...@@ -13,5 +13,5 @@ public interface IAidLoanFundRouteRecordRepository extends JpaRepository<AidLoan
AidLoanFundRouteRecord findByBizNoAndAidFundRouteStatus(String bizNo,Integer aidFundRouteStatus); AidLoanFundRouteRecord findByBizNoAndAidFundRouteStatus(String bizNo,Integer aidFundRouteStatus);
AidLoanFundRouteRecord findByBizNoAndFundId(String bizNo, String fundId);
} }
package com.quantgroup.asset.distribution.service.niwodai; package com.quantgroup.asset.distribution.service.niwodai;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.service.jpa.entity.Asset;
import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiDataImportCheckResponseVO; import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiDataImportCheckResponseVO;
import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiIncomingResponseVO; import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiIncomingResponseVO;
import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiIncomingResultResponseVO; import com.quantgroup.asset.distribution.service.niwodai.vo.NiwodaiIncomingResultResponseVO;
...@@ -11,9 +13,9 @@ public interface INiwodaiAssetService { ...@@ -11,9 +13,9 @@ public interface INiwodaiAssetService {
NiwodaiIncomingResultResponseVO incomingResult(String orderId); NiwodaiIncomingResultResponseVO incomingResult(String orderId);
NiwodaiDataImportCheckResponseVO dataCheck(String uuid); NiwodaiDataImportCheckResponseVO preAudit(String uuid);
NiwodaiIncomingResponseVO incoming(String uuid, String orderId, String amount, Integer term); NiwodaiIncomingResponseVO incoming(AssetForm assetForm, Map<String, Object> data, Integer userLoanType);
Map<String,Object> queryUserBasic2Info(String userId, String phoneNo, boolean isQuery); Map<String,Object> queryUserBasic2Info(String userId, String phoneNo, boolean isQuery);
} }
...@@ -5,10 +5,9 @@ import com.quantgroup.asset.distribution.service.niwodai.vo.*; ...@@ -5,10 +5,9 @@ import com.quantgroup.asset.distribution.service.niwodai.vo.*;
public interface INiwodaiService { public interface INiwodaiService {
NiwodaiDataImportCheckResponseVO dataImportCheck(NiwodaiDataImportCheckRequestVO requestVO); NiwodaiDataImportCheckResponseVO dataImportCheck(NiwodaiDataImportCheckRequestVO requestVO, String uuid);
NiwodaiIncomingResponseVO incoming(NiwodaiIncomingRequestVO niwodaiIncomingRequestVO, String uuid);
NiwodaiIncomingResponseVO incoming(NiwodaiIncomingRequestVO niwodaiIncomingRequestVO);
NiwodaiIncomingResultResponseVO incoingResult(NiwodaiIncomingResultRequestVO requestVO); NiwodaiIncomingResultResponseVO incoingResult(NiwodaiIncomingResultRequestVO requestVO);
} }
...@@ -6,16 +6,20 @@ import cn.quantgroup.user.IUserSdkService; ...@@ -6,16 +6,20 @@ import cn.quantgroup.user.IUserSdkService;
import cn.quantgroup.user.UserSdkServiceFactory; import cn.quantgroup.user.UserSdkServiceFactory;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Stopwatch;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.lkb.data.hbase.dataservice.verify.OCRIdCardDataService; import com.lkb.data.hbase.dataservice.verify.OCRIdCardDataService;
import com.lkb.data.hbase.row.verify.OCRIdCardRow; import com.lkb.data.hbase.row.verify.OCRIdCardRow;
import com.quantgroup.asset.distribution.enums.UserLoanType;
import com.quantgroup.asset.distribution.exception.QGException; import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.exception.QGExceptionType; import com.quantgroup.asset.distribution.exception.QGExceptionType;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.service.httpclient.IHttpService; import com.quantgroup.asset.distribution.service.httpclient.IHttpService;
import com.quantgroup.asset.distribution.service.niwodai.INiwodaiAssetService; import com.quantgroup.asset.distribution.service.niwodai.INiwodaiAssetService;
import com.quantgroup.asset.distribution.service.niwodai.INiwodaiService; import com.quantgroup.asset.distribution.service.niwodai.INiwodaiService;
import com.quantgroup.asset.distribution.service.niwodai.vo.*; import com.quantgroup.asset.distribution.service.niwodai.vo.*;
import javafx.scene.paint.Stop;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -31,6 +35,7 @@ import java.math.BigDecimal; ...@@ -31,6 +35,7 @@ import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@Service @Service
...@@ -64,49 +69,44 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService { ...@@ -64,49 +69,44 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService {
} }
@Override @Override
public NiwodaiDataImportCheckResponseVO dataCheck(String uuid){ public NiwodaiDataImportCheckResponseVO preAudit(String uuid) {
NiwodaiDataImportCheckRequestVO requestVO = new NiwodaiDataImportCheckRequestVO(); NiwodaiDataImportCheckRequestVO requestVO = new NiwodaiDataImportCheckRequestVO();
requestVO.setExternalUserId(uuid);
UserSysResult<UserInfo> userInfoByUuid = userSdkService.findUserInfoByUuid(uuid); UserSysResult<UserInfo> userInfoByUuid = userSdkService.findUserInfoByUuid(uuid);
if (!userInfoByUuid.isSuccess()){ if (!userInfoByUuid.isSuccess()){
log.error("准入检查获取用户中心信息失败 uuid : {}",uuid); log.error("你我贷准入检查获取用户中心信息失败 uuid : {}",uuid);
throw new QGException("获取用户中心信息失败", QGExceptionType.COMMON_ILLEGAL_PARAM); throw new QGException(QGExceptionType.GET_USER_INFO_ERROR);
} }
requestVO.setPhone(userInfoByUuid.getData().getPhoneNo()); requestVO.setPhone(getPhoneNoMask(userInfoByUuid.getData().getPhoneNo()));
List<OCRIdCardRow> list = OCRIdCardDataService.get(uuid); requestVO.setIdcardNumber(getIdNoMask(userInfoByUuid.getData().getIdNo()));
if (CollectionUtils.isEmpty(list)) { requestVO.setRealName(userInfoByUuid.getData().getName());
log.error("准入检查获取用户OCR信息失败 uuid : {}",uuid); Stopwatch stopwatch = Stopwatch.createStarted();
throw new QGException("没有相关用户信息", QGExceptionType.COMMON_ILLEGAL_PARAM); NiwodaiDataImportCheckResponseVO responseVO = niwodaiService.dataImportCheck(requestVO, uuid);
} log.info("你我贷进件接口调用完成, uuid : {}, requestVo : {}, responseVo : {}, 耗时 : {}", uuid, JSON.toJSONString(requestVO), JSON.toJSONString(responseVO), stopwatch.stop().elapsed(TimeUnit.SECONDS));
OCRIdCardRow ocrIdCardRow = list.get(0); return responseVO;
IdCardA idCardFront = JSON.parseObject(ocrIdCardRow.getIdCardContentA(), IdCardA.class);
requestVO.setIdcardNumber(idCardFront.getCitizen_id());
requestVO.setRealName(idCardFront.getName());
return niwodaiService.dataImportCheck(requestVO);
} }
@Override @Override
public NiwodaiIncomingResponseVO incoming(String uuid, String orderId, String amount, Integer term) { public NiwodaiIncomingResponseVO incoming(AssetForm assetForm, Map<String, Object> data, Integer userLoanType) {
List<OCRIdCardRow> list = OCRIdCardDataService.get(uuid); List<OCRIdCardRow> list = OCRIdCardDataService.get(assetForm.getUuid());
if (CollectionUtils.isEmpty(list)) { if (CollectionUtils.isEmpty(list)) {
log.error("进件申请获取用户OCR信息失败 uuid : {}",uuid); log.error("你我贷进件申请获取用户OCR信息失败 uuid : {}, orderId : {}",assetForm.getUuid(), assetForm.getBizNo());
throw new QGException("没有相关用户信息", QGExceptionType.COMMON_ILLEGAL_PARAM); throw new QGException(QGExceptionType.OCR_DATA_MISS);
} }
OCRIdCardRow ocrIdCardRow = list.get(0); OCRIdCardRow ocrIdCardRow = list.get(0);
UserSysResult<UserInfo> userInfoByUuid = userSdkService.findUserInfoByUuid(uuid); UserSysResult<UserInfo> userInfoByUuid = userSdkService.findUserInfoByUuid(assetForm.getUuid());
if (!userInfoByUuid.isSuccess()){ if (!userInfoByUuid.isSuccess()){
log.error("进件申请获取用户中心信息失败 uuid : {}",uuid); log.error("你我贷进件申请获取用户中心信息失败, uuid : {}, orderId : {}", assetForm.getUuid(), assetForm.getBizNo());
throw new QGException("获取用户中心信息失败", QGExceptionType.COMMON_ILLEGAL_PARAM); throw new QGException(QGExceptionType.GET_USER_INFO_ERROR);
} }
IdCardA idCardFront = JSON.parseObject(ocrIdCardRow.getIdCardContentA(), IdCardA.class); IdCardA idCardFront = JSON.parseObject(ocrIdCardRow.getIdCardContentA(), IdCardA.class);
IdCardB idCardBack = JSON.parseObject(ocrIdCardRow.getIdCardContentB(), IdCardB.class); IdCardB idCardBack = JSON.parseObject(ocrIdCardRow.getIdCardContentB(), IdCardB.class);
Map<String,Object> infoMap = queryUserBasic2Info(uuid,userInfoByUuid.getData().getPhoneNo(),true); Map<String,Object> infoMap = (Map<String,Object>)queryUserBasic2Info(assetForm.getUuid(), userInfoByUuid.getData().getPhoneNo(),true).get("info");
NiwodaiIncomingRequestVO vo = new NiwodaiIncomingRequestVO(); NiwodaiIncomingRequestVO vo = new NiwodaiIncomingRequestVO();
vo.setOrderId(orderId); vo.setOrderId(assetForm.getBizNo());
NiwodaiCostant.UserInfo userInfo = new NiwodaiCostant.UserInfo(); NiwodaiCostant.UserInfo userInfo = new NiwodaiCostant.UserInfo();
userInfo.setRealName(idCardFront.getName()); userInfo.setRealName(idCardFront.getName());
userInfo.setIdcardNumber(idCardFront.getCitizen_id()); userInfo.setIdcardNumber(idCardFront.getCitizen_id().replaceAll("x", "X"));
userInfo.setPhone(userInfoByUuid.getData().getPhoneNo()); userInfo.setPhone(userInfoByUuid.getData().getPhoneNo());
userInfo.setMaritalStatus(conversMarryStatus((String) infoMap.get("marryStatus")).name()); userInfo.setMaritalStatus(conversMarryStatus((String) infoMap.get("marryStatus")).name());
userInfo.setGender("男".equals(idCardFront.getGender()) ? NiwodaiCostant.Gender.MALE.name() : NiwodaiCostant.Gender.FEMALE.name()); userInfo.setGender("男".equals(idCardFront.getGender()) ? NiwodaiCostant.Gender.MALE.name() : NiwodaiCostant.Gender.FEMALE.name());
...@@ -121,15 +121,16 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService { ...@@ -121,15 +121,16 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService {
userInfo.setCity((String) infoMap.get("city")); userInfo.setCity((String) infoMap.get("city"));
userInfo.setDistrict((String) infoMap.get("district")); userInfo.setDistrict((String) infoMap.get("district"));
userInfo.setAddress(idCardFront.getAddress()); userInfo.setAddress(idCardFront.getAddress());
userInfo.setIndustry(random(NiwodaiCostant.Industry.values()).name()); userInfo.setIndustry(conversIndustry((String) infoMap.get("vocation")).name());
userInfo.setIncome(conversIncome((String) infoMap.get("salary")).name()); userInfo.setIncome(conversIncome((String) infoMap.get("salary")).name());
userInfo.setIncomeType(random(NiwodaiCostant.IncomeType.values()).name()); // userInfo.setIncomeType(random(NiwodaiCostant.IncomeType.values()).name());
userInfo.setDebt(NiwodaiCostant.Debt.ZERO.name()); userInfo.setDebt(NiwodaiCostant.Debt.ZERO.name());
vo.setUserInfo(userInfo); vo.setUserInfo(userInfo);
NiwodaiCostant.LoanInfo loanInfo = new NiwodaiCostant.LoanInfo(); NiwodaiCostant.LoanInfo loanInfo = new NiwodaiCostant.LoanInfo();
loanInfo.setAmount(new BigDecimal(amount)); // 写死
loanInfo.setTerm(term); loanInfo.setAmount(new BigDecimal(12000));
loanInfo.setPurpose(random(NiwodaiCostant.Purpose.values()).name()); loanInfo.setTerm(12);
loanInfo.setPurpose(NiwodaiCostant.Purpose.CONSUMPTION.name());
vo.setLoanInfo(loanInfo); vo.setLoanInfo(loanInfo);
NiwodaiCostant.Contacts contacts = new NiwodaiCostant.Contacts(); NiwodaiCostant.Contacts contacts = new NiwodaiCostant.Contacts();
contacts.setNameA((String) infoMap.get("firstName")); contacts.setNameA((String) infoMap.get("firstName"));
...@@ -140,21 +141,17 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService { ...@@ -140,21 +141,17 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService {
contacts.setRelationshipB(conversRelationship((String)infoMap.get("secondRelation")).name()); contacts.setRelationshipB(conversRelationship((String)infoMap.get("secondRelation")).name());
vo.setContacts(contacts); vo.setContacts(contacts);
NiwodaiCostant.CompnayInfo compnayInfo = new NiwodaiCostant.CompnayInfo(); NiwodaiCostant.CompnayInfo compnayInfo = new NiwodaiCostant.CompnayInfo();
compnayInfo.setName(randomCompanyName()); compnayInfo.setName(random(NiwodaiCostant.COMPANY_NAMES));
compnayInfo.setAddress(userInfo.getProvince()+userInfo.getCity()+compnayInfo.getName()); compnayInfo.setAddress(userInfo.getProvince() + userInfo.getCity() + compnayInfo.getName());
compnayInfo.setCity(userInfo.getCity()); compnayInfo.setCity(userInfo.getCity());
compnayInfo.setProvince(userInfo.getProvince()); compnayInfo.setProvince(userInfo.getProvince());
vo.setCompanyInfo(compnayInfo); vo.setCompanyInfo(compnayInfo);
vo.setMnoData(new NiwodaiCostant.MnoData()); vo.setMnoData(new NiwodaiCostant.MnoData());
return niwodaiService.incoming(vo); vo.setChannelRiskData(getUserTag(userLoanType, data));
return niwodaiService.incoming(vo, assetForm.getUuid());
} }
private static String randomCompanyName(){
int index = (int) (Math.random() * companyNames.length);
return companyNames[index];
}
private static <T> T random(T[] objects){ private static <T> T random(T[] objects){
int index = (int) (Math.random() * objects.length); int index = (int) (Math.random() * objects.length);
return objects[index]; return objects[index];
...@@ -315,22 +312,39 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService { ...@@ -315,22 +312,39 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService {
} }
} }
private static NiwodaiCostant.Industry conversIndustry(String occupation) {
switch (occupation) {
case ("工人") : return NiwodaiCostant.Industry.AGRICULTURE;
case ("教师") : return NiwodaiCostant.Industry.EDUCATION;
case ("白领") : return NiwodaiCostant.Industry.INFORMATION_TECHNOLOGY_SERVICES;
case ("学生") : return NiwodaiCostant.Industry.EDUCATION;
case ("创业者") : return NiwodaiCostant.Industry.TECHNOLOGICAL_SERVICES;
case ("个体户") : return NiwodaiCostant.Industry.RETAIL;
case ("公司职员") : return NiwodaiCostant.Industry.FINANCE;
case ("企业法人") : return NiwodaiCostant.Industry.ESTATE;
case ("网店店主") : return NiwodaiCostant.Industry.ENTERTAINMENT;
case ("暂无职业") :
case ("其他") :
default : return NiwodaiCostant.Industry.UNKNOWN;
}
}
private static NiwodaiCostant.Occupation conversOccupation(String occupation){ private static NiwodaiCostant.Occupation conversOccupation(String occupation){
switch (occupation){ switch (occupation){
case ("工人") : case ("工人") :
case ("公司职员") :
case ("白领") :
case ("教师") : case ("教师") :
case ("白领") :
case ("公司职员") :
return NiwodaiCostant.Occupation.WORKER; return NiwodaiCostant.Occupation.WORKER;
case ("学生") : return NiwodaiCostant.Occupation.STUDENT; case ("学生") : return NiwodaiCostant.Occupation.STUDENT;
case ("创业者") : return NiwodaiCostant.Occupation.PROFESSIONAL; case ("创业者") :
case ("企业法人") : return NiwodaiCostant.Occupation.PRIVATE_OWNERS;
case ("个体户") : case ("个体户") :
return NiwodaiCostant.Occupation.BUSINESSMEN;
case ("网店店主") : case ("网店店主") :
return NiwodaiCostant.Occupation.PRIVATE_OWNERS; case ("其他") : return NiwodaiCostant.Occupation.PROFESSIONAL;
case ("企业法人") : return NiwodaiCostant.Occupation.BUSINESSMEN;
case ("暂无职业") : case ("暂无职业") :
case ("其他") : default : return NiwodaiCostant.Occupation.BE_UNEMPLOYED;
default:return NiwodaiCostant.Occupation.BE_UNEMPLOYED;
} }
} }
private static NiwodaiCostant.EducationalBackground conversEducation(String education){ private static NiwodaiCostant.EducationalBackground conversEducation(String education){
...@@ -387,5 +401,42 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService { ...@@ -387,5 +401,42 @@ public class NiwodaiAssetServiceImpl implements INiwodaiAssetService {
} }
} }
/**
* 获取手机号掩码,后4位掩码
* @param phoneNo
* @return
*/
private static String getPhoneNoMask(String phoneNo) {
// if (StringUtils.isEmpty(phoneNo)) { throw new QGException(QGExceptionType.USER_PHONE_NO_EMPTY); }
// return phoneNo.substring(0, phoneNo.length() - 4) + "****";
return phoneNo;
}
/**
* 身份证号掩码,后5位掩码
* @param idNo
* @return
*/
private static String getIdNoMask(String idNo) {
// if (StringUtils.isEmpty(idNo)) { throw new QGException(QGExceptionType.USER_ID_NO_EMPTY); }
// return idNo.substring(0, idNo.length() - 5) + "*****";
return idNo;
}
/**
* 获取用户标签
* @param data
* @return
*/
private Integer getUserTag(int userLoanType, Map<String, Object> data) {
if (userLoanType == UserLoanType.FIRST_APPLY.getCode() || userLoanType == UserLoanType.RE_APPLY.getCode()) {
return NiwodaiCostant.Tag.NATURE;
} else {
if (data.get("model_exec_data_source#xinyan_v5") != null && data.get("third_data_source#tencent_md5_risk_new_riskScore") != null) {
return NiwodaiCostant.Tag.REJECT;
} else {
return NiwodaiCostant.Tag.NATURE;
}
}
}
} }
package com.quantgroup.asset.distribution.service.niwodai.impl; package com.quantgroup.asset.distribution.service.niwodai.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.quantgroup.asset.distribution.constant.RedisKeyConstants; import com.quantgroup.asset.distribution.constant.RedisKeyConstants;
import com.quantgroup.asset.distribution.exception.QGException; import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.exception.QGExceptionType;
import com.quantgroup.asset.distribution.service.httpclient.IHttpService; import com.quantgroup.asset.distribution.service.httpclient.IHttpService;
import com.quantgroup.asset.distribution.service.niwodai.INiwodaiService; import com.quantgroup.asset.distribution.service.niwodai.INiwodaiService;
import com.quantgroup.asset.distribution.service.niwodai.vo.*; import com.quantgroup.asset.distribution.service.niwodai.vo.*;
...@@ -18,9 +20,6 @@ import java.util.Base64; ...@@ -18,9 +20,6 @@ import java.util.Base64;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static com.quantgroup.asset.distribution.exception.QGExceptionType.COMMON_THIRD_PARTY_TIMEOUT;
@Slf4j @Slf4j
@Service @Service
public class NiwodaiServiceImpl implements INiwodaiService { public class NiwodaiServiceImpl implements INiwodaiService {
...@@ -46,47 +45,57 @@ public class NiwodaiServiceImpl implements INiwodaiService { ...@@ -46,47 +45,57 @@ public class NiwodaiServiceImpl implements INiwodaiService {
IHttpService iHttpService; IHttpService iHttpService;
@Override @Override
public NiwodaiDataImportCheckResponseVO dataImportCheck(NiwodaiDataImportCheckRequestVO requestVO) { public NiwodaiDataImportCheckResponseVO dataImportCheck(NiwodaiDataImportCheckRequestVO requestVO, String uuid) {
String token = getToken(); String token = getToken();
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
log.error("你我贷准入检查时获取token失败,requestVO : {}", JSON.toJSONString(requestVO)); log.error("你我贷准入检查时获取token失败, uuid : {}", uuid);
throw new QGException("你我贷准入检查时获取token失败", COMMON_THIRD_PARTY_TIMEOUT); throw new QGException(QGExceptionType.GET_NIWODAI_TOKEN_ERROR);
} }
String result = iHttpService.postNiwodaiJson(domain2 + dataImportCheckUrl, commonHeader(token), JSON.toJSONString(requestVO), true); String result = iHttpService.postNiwodaiJson(domain2 + dataImportCheckUrl, commonHeader(token), JSON.toJSONString(requestVO), false);
log.info("你我贷准入检查接口调用结束, uuid : {}, requestVo : {}, response : {}", uuid, JSON.toJSONString(requestVO), result);
if (StringUtils.isNotEmpty(result)) { if (StringUtils.isNotEmpty(result)) {
NiwodaiDataImportCheckResponseVO vo = JSON.parseObject(result, NiwodaiDataImportCheckResponseVO.class);
if (vo != null && vo.getPass() != null) {
return JSON.parseObject(result, NiwodaiDataImportCheckResponseVO.class); return JSON.parseObject(result, NiwodaiDataImportCheckResponseVO.class);
} }
return null; }
throw new QGException(QGExceptionType.NIWODAI_PRE_AUDIT_RESULAT_ERROR, result);
} }
@Override @Override
public NiwodaiIncomingResponseVO incoming(NiwodaiIncomingRequestVO requestVO) { public NiwodaiIncomingResponseVO incoming(NiwodaiIncomingRequestVO requestVO, String uuid) {
String token = getToken(); String token = getToken();
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
log.error("你我贷进件时获取token失败,requestVO : {}", JSON.toJSONString(requestVO)); log.error("你我贷进件时获取token失败, uuid : {}, bizNo : {}", uuid, requestVO.getOrderId());
throw new QGException("你我贷进件时获取token失败", COMMON_THIRD_PARTY_TIMEOUT); throw new QGException(QGExceptionType.GET_NIWODAI_TOKEN_ERROR);
} }
String result = iHttpService.postNiwodaiJson(domain2 + incomingUrl, commonHeader(token), JSON.toJSONString(requestVO),true); String result = iHttpService.postNiwodaiJson(domain2 + incomingUrl, commonHeader(token), JSON.toJSONString(requestVO),false);
log.info("你我贷进件接口审核接口结束, uuid : {}, bizNo : {}, response : {}", uuid, requestVO.getOrderId(), result);
if (StringUtils.isNotEmpty(result)) { if (StringUtils.isNotEmpty(result)) {
return JSON.parseObject(result, NiwodaiIncomingResponseVO.class); NiwodaiIncomingResponseVO vo = JSON.parseObject(result, NiwodaiIncomingResponseVO.class);
if (vo != null && vo.getCode() != null) {
return vo;
} }
return null; }
throw new QGException(QGExceptionType.NIWODAI_INCOMING_RESULT_ERROR);
} }
@Override @Override
public NiwodaiIncomingResultResponseVO incoingResult(NiwodaiIncomingResultRequestVO requestVO){ public NiwodaiIncomingResultResponseVO incoingResult(NiwodaiIncomingResultRequestVO requestVO){
String token = getToken(); String token = getToken();
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
log.error("你我贷获取进件结果时获取token失败,requestVO : {}", JSON.toJSONString(requestVO)); log.error("你我贷获取进件结果时获取token失败, requestVO : {}", JSON.toJSONString(requestVO));
throw new QGException("你我贷获取进件结果时获取token失败", COMMON_THIRD_PARTY_TIMEOUT); throw new QGException(QGExceptionType.GET_NIWODAI_TOKEN_ERROR);
} }
String result = iHttpService.postNiwodaiJson(domain2 + getIncomingResult, commonHeader(token), JSON.toJSONString(requestVO),true); String result = iHttpService.postNiwodaiJson(domain2 + getIncomingResult, commonHeader(token), JSON.toJSONString(requestVO),true);
if (StringUtils.isNotEmpty(result)){ if (StringUtils.isNotEmpty(result)){
return JSON.parseObject(result, NiwodaiIncomingResultResponseVO.class); NiwodaiIncomingResultResponseVO vo = JSON.parseObject(result, NiwodaiIncomingResultResponseVO.class);
if (vo != null && vo.getCode() != null) {
return vo;
} }
return null;
} }
throw new QGException(QGExceptionType.NIWODAI_INCOMING_AUDIT_RESULT_ERROR);
}
public String getToken() { public String getToken() {
String token = iRedisService.getString(RedisKeyConstants.NI_WO_DAI_TOKEN_KEY); String token = iRedisService.getString(RedisKeyConstants.NI_WO_DAI_TOKEN_KEY);
......
...@@ -5,6 +5,10 @@ import lombok.Data; ...@@ -5,6 +5,10 @@ import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
public class NiwodaiCostant { public class NiwodaiCostant {
// 你我贷审核期数固定为12期
public static final String AUDIT_TERM = "12";
@Data @Data
public static class UserInfo { public static class UserInfo {
/** /**
...@@ -642,4 +646,21 @@ public class NiwodaiCostant { ...@@ -642,4 +646,21 @@ public class NiwodaiCostant {
UNKNOWN; UNKNOWN;
} }
/**
* 公司名称固定几个
*/
public static final String[] COMPANY_NAMES = {"外企人力资源公司", "中智人力资源公司", "新绿人力资源公司", "东浩人力资源公司"};
public static class Tag {
/**
* 自然流量标签
*/
public static final Integer NATURE = 1;
/**
* 拒绝流量标签
*/
public static final Integer REJECT = 2;
}
} }
...@@ -48,6 +48,12 @@ public class NiwodaiIncomingRequestVO implements Serializable { ...@@ -48,6 +48,12 @@ public class NiwodaiIncomingRequestVO implements Serializable {
*/ */
private NiwodaiCostant.CreditRefData creditRefData; private NiwodaiCostant.CreditRefData creditRefData;
/**
* 渠道风控信息,用与联合建模
* 1-自然流量,2-拒绝流量
*/
private Integer channelRiskData;
public Map<String,Object> toMap(){ public Map<String,Object> toMap(){
return JSONObject.parseObject(JSON.toJSONString(this)); return JSONObject.parseObject(JSON.toJSONString(this));
} }
......
...@@ -32,5 +32,5 @@ public class NiwodaiIncomingResultResponseVO implements Serializable { ...@@ -32,5 +32,5 @@ public class NiwodaiIncomingResultResponseVO implements Serializable {
/** /**
* 额度有效期 * 额度有效期
*/ */
private Date validBefore; private String validBefore;
} }
package com.quantgroup.asset.distribution.service.product;
import com.quantgroup.asset.distribution.model.form.AssetForm;
/**
* @author : Hyuk
* @description : IFinanceProductService
* @date : 2020/3/30 5:10 下午
*/
public interface IFinanceProductService {
/**
* 创建单个资方金融产品集
* @param amount
* @param term
* @param fundId
* @return
*/
public String createSingletonFinanceProduct(String amount, String term, String fundId, String fundProId);
/**
* 结果处理
* @param assetForm
* @param hitFinanceProduct
* @return
*/
public AssetForm checkFundResult(AssetForm assetForm, String hitFinanceProduct, Long deadLine);
public AssetForm checkFundResult(AssetForm assetForm, String hitFinanceProduct);
}
package com.quantgroup.asset.distribution.service.product.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.quantgroup.asset.distribution.enums.ExecuteType;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.service.product.IFinanceProductHitLogService;
import com.quantgroup.asset.distribution.service.product.IFinanceProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author : Hyuk
* @description : FInanceProdcutServiceIMpl
* @date : 2020/3/30 5:11 下午
*/
@Slf4j
@Service
public class FinanceProductServiceImpl implements IFinanceProductService {
@Autowired
private IFinanceProductHitLogService financeProductHitLogService;
@Override
public String createSingletonFinanceProduct(String amount, String term, String fundId, String fundProId) {
JSONArray fundArray = createSingletonFundArr(fundId, null);
JSONArray financeProductArray = new JSONArray();
JSONObject amountJSON = new JSONObject();
financeProductArray.add(amountJSON);
amountJSON.put("min", amount);
amountJSON.put("max", amount);
JSONArray termArray = new JSONArray();
amountJSON.put("terms", termArray);
JSONObject termJSON = new JSONObject();
termArray.add(termJSON);
try {
// 不能是string,否则资方那边会报错
termJSON.put("term", Integer.parseInt(term));
} catch (Exception e) {
termJSON.put("term", Double.parseDouble(term));
}
termJSON.put("fundInfo", fundArray);
return JSON.toJSONString(financeProductArray);
}
@Override
public AssetForm checkFundResult(AssetForm assetForm, String hitFinanceProduct, Long deadLine) {
if (hitFinanceProduct == null) {
if ("false".equals(assetForm.getAuditResult())) {
// 把传过来的额度和期数处理为null
assetForm.setAmount(null);
assetForm.setTerm(null);
}
return assetForm;
}
// 金融产品集替换
String oldFinanceProduct = assetForm.getFinanceProducts();
assetForm.setFinanceProducts(hitFinanceProduct);
// 审核结果替换
String oldAuditResult = assetForm.getAuditResult();
if ("false".equals(oldAuditResult)) {
assetForm.setAuditResult("true");
}
// 截止时间替换
if (deadLine != null) { assetForm.setDeadLine(String.valueOf(deadLine)); }
// 保存日志
financeProductHitLogService.saveLog(assetForm, oldFinanceProduct, hitFinanceProduct, oldAuditResult, assetForm.getAuditResult(), ExecuteType.ONLINE);
log.info("资方命中后,审核最终结果, assetForm : {}", JSON.toJSONString(assetForm));
return assetForm;
}
@Override
public AssetForm checkFundResult(AssetForm assetForm, String hitFinanceProduct) {
return checkFundResult(assetForm, hitFinanceProduct, null);
}
private JSONArray createSingletonFundArr(String fundId, String fundProductId) {
JSONArray fundArray = new JSONArray();
JSONObject fundInfoJSON = new JSONObject();
fundInfoJSON.put("fundId", fundId);
fundInfoJSON.put("fundProductId", fundProductId);
fundInfoJSON.put("priority", 1);
fundInfoJSON.put("feeType", 1);
fundInfoJSON.put("rateType", 1);
fundInfoJSON.put("rate", 0);
fundArray.add(fundInfoJSON);
return fundArray;
}
}
package com.quantgroup.asset.distribution.util; package com.quantgroup.asset.distribution.util;
import java.sql.Timestamp;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
...@@ -27,4 +28,14 @@ public class DateUtil { ...@@ -27,4 +28,14 @@ public class DateUtil {
public static String getCurDateTime() { public static String getCurDateTime() {
return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()); return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
} }
/**
* 将时间类型字符串转换为Long类型
* @param dateTime
* @param pattern
* @return
*/
public static Long transStringToLong(String dateTime, String pattern) {
return Timestamp.valueOf(LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern(pattern))).getTime();
}
} }
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} --- [%thread] [%file:%line] %logger - %msg%n}"/> value="${FILE_LOG_PATTERN:-%d{yyyy-MM-dd HH:mm:ss.SSS} ${LOG_LEVEL_PATTERN:-%5p} --- [%thread] [%file:%line] %logger - %msg%n}"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/vpants/shaun/asset-distribution-9051/logs/rule-engine.log</file> <file>/vpants/shaun/asset-distribution-9051/logs/asset-distribution.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern> <fileNamePattern>
/vpants/shaun/asset-distribution-9051/logs/rule-engine.log.%d{yyyy-MM-dd} /vpants/shaun/asset-distribution-9051/logs/asset-distribution.log.%d{yyyy-MM-dd}
</fileNamePattern> </fileNamePattern>
<maxHistory>7</maxHistory> <maxHistory>7</maxHistory>
</rollingPolicy> </rollingPolicy>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment