Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
asset-distribution
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
data-spider
asset-distribution
Commits
88cc84b5
Commit
88cc84b5
authored
Mar 23, 2020
by
data-爬虫-任锋
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
资产分发添加助贷资金导流
parent
05628c06
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
246 additions
and
255 deletions
+246
-255
AssetServiceImpl.java
...set/distribution/service/asset/impl/AssetServiceImpl.java
+12
-234
AssetDistributeServiceImpl.java
...n/service/distribute/impl/AssetDistributeServiceImpl.java
+234
-21
No files found.
src/main/java/com/quantgroup/asset/distribution/service/asset/impl/AssetServiceImpl.java
View file @
88cc84b5
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
asset
.
impl
;
import
java.lang.reflect.Field
;
import
java.math.BigDecimal
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.funding.IFundModuleChannelFundConfigNewService
;
import
com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.rule.vo.IRuleVO
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.google.common.base.Stopwatch
;
import
com.quantgroup.asset.distribution.config.annotation.Attribute
;
import
com.quantgroup.asset.distribution.enums.ExecuteType
;
import
com.quantgroup.asset.distribution.enums.response.AssetResponse
;
import
com.quantgroup.asset.distribution.exception.QGException
;
import
com.quantgroup.asset.distribution.exception.QGExceptionType
;
import
com.quantgroup.asset.distribution.exception.QGPreconditions
;
import
com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfig
;
import
com.quantgroup.asset.distribution.model.form.AssetForm
;
import
com.quantgroup.asset.distribution.model.response.GlobalResponse
;
import
com.quantgroup.asset.distribution.service.alarm.IAlarmService
;
...
...
@@ -39,14 +16,19 @@ import com.quantgroup.asset.distribution.service.asset.IAssetAttributeService;
import
com.quantgroup.asset.distribution.service.asset.IAssetService
;
import
com.quantgroup.asset.distribution.service.distribute.IAssetDistributeService
;
import
com.quantgroup.asset.distribution.service.distribute.IDistributeFailLogService
;
import
com.quantgroup.asset.distribution.service.funding.IFundModuleChannelFundConfigService
;
import
com.quantgroup.asset.distribution.service.jpa.entity.Asset
;
import
com.quantgroup.asset.distribution.service.jpa.entity.AssetAttributeExtendConfig
;
import
com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfig
;
import
com.quantgroup.asset.distribution.service.product.IFinanceProductHitLogService
;
import
com.quantgroup.asset.distribution.service.rule.IRuleService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
java.lang.reflect.Field
;
import
java.math.BigDecimal
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.TimeUnit
;
/**
* 资产Service
...
...
@@ -67,14 +49,6 @@ public class AssetServiceImpl implements IAssetService{
private
IAlarmService
alarmService
;
@Autowired
private
IDistributeFailLogService
distributeFailLogService
;
@Autowired
private
IFundModuleChannelFundConfigNewService
fundModuleChannelFundConfigNewService
;
@Autowired
private
IRuleService
ruleService
;
@Autowired
private
IFinanceProductHitLogService
financeProductHitLogService
;
private
static
final
ExecutorService
executorPool
=
Executors
.
newFixedThreadPool
(
100
);
@Async
...
...
@@ -92,12 +66,6 @@ public class AssetServiceImpl implements IAssetService{
assetAttributeService
.
saveAssetAttrubite
(
asset
,
assetAttributeExtendConfigList
,
data
);
// 把资产基础属性值放入data
data
=
addAssetAttributeToData
(
asset
,
data
);
// 资方配置空跑
doTestExecute
(
JSON
.
parseObject
(
JSON
.
toJSONString
(
assetForm
),
AssetForm
.
class
),
data
);
// 如果使用资方模块则去命中资方,创建金融产品集
String
hitFinanceProduct
=
hitFundIfUseFundModule
(
assetForm
,
data
,
ExecuteType
.
ONLINE
);
// 资方模块结果处理
checkFundResult
(
assetForm
,
hitFinanceProduct
);
// 资产分发
assetDistributeService
.
distribute
(
assetForm
,
asset
,
data
);
log
.
info
(
"资产分发完成, uuid : {}, bizNo : {}, assetNo : {}, bizChannel : {}, 耗时 : {}"
,
assetForm
.
getUuid
(),
...
...
@@ -222,194 +190,4 @@ public class AssetServiceImpl implements IAssetService{
return
sb
.
toString
();
}
/**
* 如果使用资方模块,需要去命中资方
* @param assetForm
*/
public
String
hitFundIfUseFundModule
(
AssetForm
assetForm
,
Map
<
String
,
Object
>
data
,
ExecuteType
executeType
)
{
// 如果auditResult为true, amount或term有一个为空, 那就不管是否是测试,都不能使用资方模块了
// 同时兼容量子魔方白名单,白名单的没有期数直接返回
if
(
"true"
.
equals
(
assetForm
.
getAuditResult
())
&&
(
StringUtils
.
isEmpty
(
assetForm
.
getAmount
())
||
StringUtils
.
isEmpty
(
assetForm
.
getTerm
())))
{
return
null
;
}
FundModuleChannelFundConfigNew
config
=
fundModuleChannelFundConfigNewService
.
findByBizChannel
(
assetForm
.
getBizChannel
());
// 未找到资方渠道配置直接通知
if
(
config
==
null
)
{
return
null
;
}
QGPreconditions
.
checkArgument
(
config
!=
null
,
QGExceptionType
.
NOT_FOUNT_CHANNEL_FUNDS_INFO
,
assetForm
.
getBizChannel
());
JSONArray
fundArray
=
new
JSONArray
();
// 资方去重, 可能存在多条件同一个资方
Set
<
String
>
fundSet
=
new
HashSet
<>();
List
<
ChannelFundConfigNew
>
fundConfigList
=
JSONArray
.
parseArray
(
config
.
getFunds
(),
ChannelFundConfigNew
.
class
);
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
A
;
}
// 是否配了审核条件
boolean
hasAuditResultLimit
=
params
.
contains
(
"audit_result"
);
if
(!
hasAuditResultLimit
)
{
// 如果没配,自动过一层auditResult@true的条件
if
(!
ruleService
.
valid
(
"audit_result==true"
,
data
))
{
continue
A
;
}
}
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
());
fundInfoJSON
.
put
(
"feeType"
,
channelFundConfig
.
getFeeType
());
fundInfoJSON
.
put
(
"rateType"
,
channelFundConfig
.
getRateType
());
fundInfoJSON
.
put
(
"rate"
,
channelFundConfig
.
getRate
());
fundArray
.
add
(
fundInfoJSON
);
log
.
info
(
"资方模块用户命中资方条件, uuid : {}, assetNo : {}, bizNo : {}, bizChannel : {}, fundId : {}, fundProductId : {}"
,
assetForm
.
getUuid
(),
assetForm
.
getAssetNo
(),
assetForm
.
getBizNo
(),
assetForm
.
getBizChannel
(),
channelFundConfig
.
getFundId
(),
channelFundConfig
.
getFundProductId
());
fundSet
.
add
(
key
);
}
}
// 如果审核拒绝,也没命中任何资方, 直接返回
if
(
"false"
.
equals
(
assetForm
.
getAuditResult
())
&&
fundArray
.
size
()
==
0
)
{
return
null
;
}
QGPreconditions
.
checkArgument
(
fundArray
.
size
()
!=
0
,
QGExceptionType
.
NO_FUND_INFO_BEEN_HIT
,
assetForm
.
getBizChannel
(),
assetForm
.
getAmount
(),
assetForm
.
getTerm
());
// 看命中优先级是否符合要求
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
,
assetForm
.
getBizChannel
(),
assetForm
.
getAmount
(),
assetForm
.
getTerm
());
}
if
(
bucket
[
priority
])
{
// 多个相同的优先级
throw
new
QGException
(
QGExceptionType
.
FUND_PRIORITY_IS_ERROR
,
assetForm
.
getBizChannel
(),
assetForm
.
getAmount
(),
assetForm
.
getTerm
());
}
bucket
[
priority
]
=
true
;
}
String
hitFinanceProduct
=
createFinancePro
(
assetForm
,
fundArray
);
log
.
info
(
"资方模块组成金融产品集完成, uuid : {}, assetNo : {}, bizNo : {}, bizChannel : {}, financeProduct : {}, executeType : {}"
,
assetForm
.
getUuid
(),
assetForm
.
getAssetNo
(),
assetForm
.
getBizNo
(),
assetForm
.
getBizChannel
(),
hitFinanceProduct
,
executeType
.
name
());
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 fundArray
* @return
*/
private
String
createFinancePro
(
AssetForm
assetForm
,
JSONArray
fundArray
)
{
// 首先判断是否有额度期数
QGPreconditions
.
checkArgument
(
StringUtils
.
isNotEmpty
(
assetForm
.
getAmount
())
&&
StringUtils
.
isNotEmpty
(
assetForm
.
getTerm
()),
QGExceptionType
.
HIT_FUND_BUT_AMOUNT_OR_TERM_IS_EMPTY
);
JSONArray
financeProductArray
=
new
JSONArray
();
JSONObject
amountJSON
=
new
JSONObject
();
financeProductArray
.
add
(
amountJSON
);
amountJSON
.
put
(
"min"
,
assetForm
.
getAmount
());
amountJSON
.
put
(
"max"
,
assetForm
.
getAmount
());
JSONArray
termArray
=
new
JSONArray
();
amountJSON
.
put
(
"terms"
,
termArray
);
JSONObject
termJSON
=
new
JSONObject
();
termArray
.
add
(
termJSON
);
try
{
// 不能是string,否则资方那边会报错
termJSON
.
put
(
"term"
,
Integer
.
parseInt
(
assetForm
.
getTerm
()));
}
catch
(
Exception
e
)
{
termJSON
.
put
(
"term"
,
Double
.
parseDouble
(
assetForm
.
getTerm
()));
}
termJSON
.
put
(
"fundInfo"
,
fundArray
);
return
JSON
.
toJSONString
(
financeProductArray
);
}
/**
* 资方配置空跑
* @param testAssetForm
* @param data
*/
private
void
doTestExecute
(
AssetForm
assetForm
,
Map
<
String
,
Object
>
data
)
{
executorPool
.
execute
(()
->
{
try
{
assetForm
.
setBizChannel
(
"88888_"
+
assetForm
.
getBizChannel
());
String
hitFundPro
=
hitFundIfUseFundModule
(
assetForm
,
data
,
ExecuteType
.
TEST
);
if
(
hitFundPro
!=
null
)
{
// 如果命中了记录一下,并且如果审核状态为false改为true
String
oldFundPro
=
assetForm
.
getFinanceProducts
();
String
oldAuditResult
=
assetForm
.
getAuditResult
();
assetForm
.
setFinanceProducts
(
hitFundPro
);
assetForm
.
setAuditResult
(
"true"
);
financeProductHitLogService
.
saveLog
(
assetForm
,
oldFundPro
,
hitFundPro
,
oldAuditResult
,
assetForm
.
getAuditResult
(),
ExecuteType
.
TEST
);
}
else
{
// 如果没命中,且审核结果未false
if
(
"false"
.
equals
(
assetForm
.
getAuditResult
()))
{
// 把传过来的额度和期数处理为null
assetForm
.
setAmount
(
null
);
assetForm
.
setTerm
(
null
);
}
}
log
.
info
(
"空跑审核最终结果, assetForm : {}"
,
JSON
.
toJSONString
(
assetForm
));
}
catch
(
QGException
qe
)
{
log
.
error
(
"资方配置执行空跑出现错误 : {}, uuid : {}, bizChannel : {}, bizType : {}, bizNo : {}, assetNo : {} "
,
qe
.
qgExceptionType
.
code
+
"->"
+
qe
.
detail
,
assetForm
.
getUuid
(),
assetForm
.
getBizChannel
(),
assetForm
.
getBizType
(),
assetForm
.
getBizNo
(),
assetForm
.
getAssetNo
());
alarmService
.
dingtalkAlarm
(
"Warn"
,
"资方配置执行空跑出现错误"
,
"bizChannel : "
+
assetForm
.
getBizChannel
()
+
" , bizType : "
+
assetForm
.
getBizType
()
+
" , bizNo : "
+
assetForm
.
getBizNo
()
+
" , assetNo : "
+
assetForm
.
getAssetNo
()
+
" , uuid : "
+
assetForm
.
getUuid
()
+
" , 错误信息 : "
+
qe
.
qgExceptionType
.
code
+
"->"
+
qe
.
detail
);
}
catch
(
Exception
ex
)
{
log
.
error
(
"资方配置执行空跑出现异常, uuid : {}, bizChannel : {}, bizType : {}, bizNo : {}, assetNo : {} "
,
assetForm
.
getUuid
(),
assetForm
.
getBizChannel
(),
assetForm
.
getBizType
(),
assetForm
.
getBizNo
(),
assetForm
.
getAssetNo
(),
ex
);
alarmService
.
dingtalkAlarm
(
"Warn"
,
"资方配置执行空跑出现异常"
,
"bizChannel : "
+
assetForm
.
getBizChannel
()
+
" , bizType : "
+
assetForm
.
getBizType
()
+
" , bizNo : "
+
assetForm
.
getBizNo
()
+
" , assetNo : "
+
assetForm
.
getAssetNo
()
+
" , uuid : "
+
assetForm
.
getUuid
()
+
" , 错误信息 : 未知错误."
);
}
});
}
}
src/main/java/com/quantgroup/asset/distribution/service/distribute/impl/AssetDistributeServiceImpl.java
View file @
88cc84b5
package
com
.
quantgroup
.
asset
.
distribution
.
service
.
distribute
.
impl
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
...
...
@@ -20,10 +7,13 @@ import com.google.common.base.Stopwatch;
import
com.quantgroup.asset.distribution.constant.DistributeConstants
;
import
com.quantgroup.asset.distribution.constant.RedisKeyConstants
;
import
com.quantgroup.asset.distribution.constant.StatusConstants
;
import
com.quantgroup.asset.distribution.enums.ExecuteType
;
import
com.quantgroup.asset.distribution.enums.funding.FundingResult
;
import
com.quantgroup.asset.distribution.exception.QGException
;
import
com.quantgroup.asset.distribution.exception.QGExceptionType
;
import
com.quantgroup.asset.distribution.exception.QGPreconditions
;
import
com.quantgroup.asset.distribution.model.entity.DistributeRecord
;
import
com.quantgroup.asset.distribution.model.entity.fund.ChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.model.form.AssetForm
;
import
com.quantgroup.asset.distribution.model.response.GlobalResponse
;
import
com.quantgroup.asset.distribution.service.alarm.IAlarmService
;
...
...
@@ -31,14 +21,27 @@ import com.quantgroup.asset.distribution.service.distribute.IAssetDistributeReco
import
com.quantgroup.asset.distribution.service.distribute.IAssetDistributeRuleConfigService
;
import
com.quantgroup.asset.distribution.service.distribute.IAssetDistributeService
;
import
com.quantgroup.asset.distribution.service.funding.IAidFundRouteService
;
import
com.quantgroup.asset.distribution.service.funding.IFundModuleChannelFundConfigNewService
;
import
com.quantgroup.asset.distribution.service.jpa.entity.Asset
;
import
com.quantgroup.asset.distribution.service.jpa.entity.AssetDistributeRecord
;
import
com.quantgroup.asset.distribution.service.jpa.entity.AssetDistributeRuleConfig
;
import
com.quantgroup.asset.distribution.service.jpa.entity.FundModuleChannelFundConfigNew
;
import
com.quantgroup.asset.distribution.service.notify.INotifyService
;
import
com.quantgroup.asset.distribution.service.product.IFinanceProductHitLogService
;
import
com.quantgroup.asset.distribution.service.redis.IRedisService
;
import
com.quantgroup.asset.distribution.service.rule.IRuleService
;
import
com.quantgroup.asset.distribution.service.rule.vo.IRuleVO
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
java.util.*
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
/**
* 资产分发Service
...
...
@@ -59,8 +62,6 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
@Autowired
private
IRedisService
<
Integer
>
redisService
;
@Autowired
private
IRuleService
ruleService
;
@Autowired
private
IAidFundRouteService
aidFundRouteService
;
@Autowired
private
INotifyService
notifyService
;
...
...
@@ -68,6 +69,14 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
private
IAssetDistributeRecordService
assetDistributeRecordService
;
@Autowired
private
IAlarmService
alarmService
;
@Autowired
private
IFundModuleChannelFundConfigNewService
fundModuleChannelFundConfigNewService
;
@Autowired
private
IRuleService
ruleService
;
@Autowired
private
IFinanceProductHitLogService
financeProductHitLogService
;
private
static
final
ExecutorService
executorPool
=
Executors
.
newFixedThreadPool
(
4
);
/**
* 分发
...
...
@@ -126,14 +135,26 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
try
{
switch
(
ruleType
)
{
case
DistributeConstants
.
RuleType
.
FUND_ROUTE
:
// 资方配置空跑
doTestExecute
(
JSON
.
parseObject
(
JSON
.
toJSONString
(
assetForm
),
AssetForm
.
class
),
data
);
// 如果使用资方模块则去命中资方,创建金融产品集
String
hitFinanceProduct
=
hitFundIfUseFundModule
(
assetForm
,
data
,
ExecuteType
.
ONLINE
);
// 资方模块结果处理
checkFundResult
(
assetForm
,
hitFinanceProduct
);
if
(
StringUtils
.
isNotEmpty
(
hitFinanceProduct
))
{
notifyService
.
notifyFundServer
(
assetForm
,
data
);
return
StatusConstants
.
WAIT
;
}
return
StatusConstants
.
FAIL
;
case
DistributeConstants
.
RuleType
.
AID_FUND_ROUTE
:
{
GlobalResponse
response
=
aidFundRouteService
.
aidFundRoute
(
assetForm
,
asset
.
getUserLoanType
(),
data
);
int
status
=
response
.
getCode
()
==
0
?
StatusConstants
.
SUCCESS
:
StatusConstants
.
FAIL
;
//助贷资金路由 分配失败没有 mq消息 成功有
if
(
status
==
0
){
// 助贷资金路由目前不从mq里接受终态
assetDistributeRecord
.
setAssetDistributeStatus
(
status
);
assetDistributeRecordService
.
updateAssetDistribute
(
assetDistributeRecord
);
}
return
status
;
}
case
DistributeConstants
.
RuleType
.
DIVERSION
:
...
...
@@ -225,4 +246,196 @@ public class AssetDistributeServiceImpl implements IAssetDistributeService{
" , 错误信息 : 未知错误"
);
}
}
/**
* 如果使用资方模块,需要去命中资方
* @param assetForm
*/
public
String
hitFundIfUseFundModule
(
AssetForm
assetForm
,
Map
<
String
,
Object
>
data
,
ExecuteType
executeType
)
{
// 如果auditResult为true, amount或term有一个为空, 那就不管是否是测试,都不能使用资方模块了
// 同时兼容量子魔方白名单,白名单的没有期数直接返回
if
(
"true"
.
equals
(
assetForm
.
getAuditResult
())
&&
(
StringUtils
.
isEmpty
(
assetForm
.
getAmount
())
||
StringUtils
.
isEmpty
(
assetForm
.
getTerm
())))
{
return
null
;
}
FundModuleChannelFundConfigNew
config
=
fundModuleChannelFundConfigNewService
.
findByBizChannel
(
assetForm
.
getBizChannel
());
// 未找到资方渠道配置直接通知
if
(
config
==
null
)
{
return
null
;
}
JSONArray
fundArray
=
new
JSONArray
();
// 资方去重, 可能存在多条件同一个资方
Set
<
String
>
fundSet
=
new
HashSet
<>();
List
<
ChannelFundConfigNew
>
fundConfigList
=
JSONArray
.
parseArray
(
config
.
getFunds
(),
ChannelFundConfigNew
.
class
);
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
A
;
}
// 是否配了审核条件
boolean
hasAuditResultLimit
=
params
.
contains
(
"audit_result"
);
if
(!
hasAuditResultLimit
)
{
// 如果没配,自动过一层auditResult@true的条件
if
(!
ruleService
.
valid
(
"audit_result==true"
,
data
))
{
continue
A
;
}
}
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
());
fundInfoJSON
.
put
(
"feeType"
,
channelFundConfig
.
getFeeType
());
fundInfoJSON
.
put
(
"rateType"
,
channelFundConfig
.
getRateType
());
fundInfoJSON
.
put
(
"rate"
,
channelFundConfig
.
getRate
());
fundArray
.
add
(
fundInfoJSON
);
log
.
info
(
"资方模块用户命中资方条件, uuid : {}, assetNo : {}, bizNo : {}, bizChannel : {}, fundId : {}, fundProductId : {}"
,
assetForm
.
getUuid
(),
assetForm
.
getAssetNo
(),
assetForm
.
getBizNo
(),
assetForm
.
getBizChannel
(),
channelFundConfig
.
getFundId
(),
channelFundConfig
.
getFundProductId
());
fundSet
.
add
(
key
);
}
}
// 如果审核拒绝,也没命中任何资方, 直接返回
if
(
"false"
.
equals
(
assetForm
.
getAuditResult
())
&&
fundArray
.
size
()
==
0
)
{
return
null
;
}
QGPreconditions
.
checkArgument
(
fundArray
.
size
()
!=
0
,
QGExceptionType
.
NO_FUND_INFO_BEEN_HIT
,
assetForm
.
getBizChannel
(),
assetForm
.
getAmount
(),
assetForm
.
getTerm
());
// 看命中优先级是否符合要求
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
,
assetForm
.
getBizChannel
(),
assetForm
.
getAmount
(),
assetForm
.
getTerm
());
}
if
(
bucket
[
priority
])
{
// 多个相同的优先级
throw
new
QGException
(
QGExceptionType
.
FUND_PRIORITY_IS_ERROR
,
assetForm
.
getBizChannel
(),
assetForm
.
getAmount
(),
assetForm
.
getTerm
());
}
bucket
[
priority
]
=
true
;
}
String
hitFinanceProduct
=
createFinancePro
(
assetForm
,
fundArray
);
log
.
info
(
"资方模块组成金融产品集完成, uuid : {}, assetNo : {}, bizNo : {}, bizChannel : {}, financeProduct : {}, executeType : {}"
,
assetForm
.
getUuid
(),
assetForm
.
getAssetNo
(),
assetForm
.
getBizNo
(),
assetForm
.
getBizChannel
(),
hitFinanceProduct
,
executeType
.
name
());
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 fundArray
* @return
*/
private
String
createFinancePro
(
AssetForm
assetForm
,
JSONArray
fundArray
)
{
// 首先判断是否有额度期数
QGPreconditions
.
checkArgument
(
StringUtils
.
isNotEmpty
(
assetForm
.
getAmount
())
&&
StringUtils
.
isNotEmpty
(
assetForm
.
getTerm
()),
QGExceptionType
.
HIT_FUND_BUT_AMOUNT_OR_TERM_IS_EMPTY
);
JSONArray
financeProductArray
=
new
JSONArray
();
JSONObject
amountJSON
=
new
JSONObject
();
financeProductArray
.
add
(
amountJSON
);
amountJSON
.
put
(
"min"
,
assetForm
.
getAmount
());
amountJSON
.
put
(
"max"
,
assetForm
.
getAmount
());
JSONArray
termArray
=
new
JSONArray
();
amountJSON
.
put
(
"terms"
,
termArray
);
JSONObject
termJSON
=
new
JSONObject
();
termArray
.
add
(
termJSON
);
try
{
// 不能是string,否则资方那边会报错
termJSON
.
put
(
"term"
,
Integer
.
parseInt
(
assetForm
.
getTerm
()));
}
catch
(
Exception
e
)
{
termJSON
.
put
(
"term"
,
Double
.
parseDouble
(
assetForm
.
getTerm
()));
}
termJSON
.
put
(
"fundInfo"
,
fundArray
);
return
JSON
.
toJSONString
(
financeProductArray
);
}
/**
* 资方配置空跑
* @param assetForm
* @param data
*/
private
void
doTestExecute
(
AssetForm
assetForm
,
Map
<
String
,
Object
>
data
)
{
executorPool
.
execute
(()
->
{
try
{
assetForm
.
setBizChannel
(
"88888_"
+
assetForm
.
getBizChannel
());
String
hitFundPro
=
hitFundIfUseFundModule
(
assetForm
,
data
,
ExecuteType
.
TEST
);
if
(
hitFundPro
!=
null
)
{
// 如果命中了记录一下,并且如果审核状态为false改为true
String
oldFundPro
=
assetForm
.
getFinanceProducts
();
String
oldAuditResult
=
assetForm
.
getAuditResult
();
assetForm
.
setFinanceProducts
(
hitFundPro
);
assetForm
.
setAuditResult
(
"true"
);
financeProductHitLogService
.
saveLog
(
assetForm
,
oldFundPro
,
hitFundPro
,
oldAuditResult
,
assetForm
.
getAuditResult
(),
ExecuteType
.
TEST
);
}
else
{
// 如果没命中,且审核结果未false
if
(
"false"
.
equals
(
assetForm
.
getAuditResult
()))
{
// 把传过来的额度和期数处理为null
assetForm
.
setAmount
(
null
);
assetForm
.
setTerm
(
null
);
}
}
log
.
info
(
"空跑审核最终结果, assetForm : {}"
,
JSON
.
toJSONString
(
assetForm
));
}
catch
(
QGException
qe
)
{
log
.
error
(
"资方配置执行空跑出现错误 : {}, uuid : {}, bizChannel : {}, bizType : {}, bizNo : {}, assetNo : {} "
,
qe
.
qgExceptionType
.
code
+
"->"
+
qe
.
detail
,
assetForm
.
getUuid
(),
assetForm
.
getBizChannel
(),
assetForm
.
getBizType
(),
assetForm
.
getBizNo
(),
assetForm
.
getAssetNo
());
alarmService
.
dingtalkAlarm
(
"Warn"
,
"资方配置执行空跑出现错误"
,
"bizChannel : "
+
assetForm
.
getBizChannel
()
+
" , bizType : "
+
assetForm
.
getBizType
()
+
" , bizNo : "
+
assetForm
.
getBizNo
()
+
" , assetNo : "
+
assetForm
.
getAssetNo
()
+
" , uuid : "
+
assetForm
.
getUuid
()
+
" , 错误信息 : "
+
qe
.
qgExceptionType
.
code
+
"->"
+
qe
.
detail
);
}
catch
(
Exception
ex
)
{
log
.
error
(
"资方配置执行空跑出现异常, uuid : {}, bizChannel : {}, bizType : {}, bizNo : {}, assetNo : {} "
,
assetForm
.
getUuid
(),
assetForm
.
getBizChannel
(),
assetForm
.
getBizType
(),
assetForm
.
getBizNo
(),
assetForm
.
getAssetNo
(),
ex
);
alarmService
.
dingtalkAlarm
(
"Warn"
,
"资方配置执行空跑出现异常"
,
"bizChannel : "
+
assetForm
.
getBizChannel
()
+
" , bizType : "
+
assetForm
.
getBizType
()
+
" , bizNo : "
+
assetForm
.
getBizNo
()
+
" , assetNo : "
+
assetForm
.
getAssetNo
()
+
" , uuid : "
+
assetForm
.
getUuid
()
+
" , 错误信息 : 未知错误."
);
}
});
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment