分类 默认分类 下的文章

卡点完美的男人

昨天晚上和一位从上海来的朋友吃饭,该朋友是之前在上海的同事;时隔一年左右的时间再次相见,他还是那个少年;不禁让我想起他刚进入公司的情景;

也就是前年,他刚毕业,从实习的单位出来进入公司;当时我刚开始带项目,也算有缘,划到了我这边;记得来公司头几天的一个中午,leader叫上我和两个刚入职的小伙子上公司附近的小饭店吃个饭,大家彼此熟悉下;按理说,上饭店吃饭,也不需要干啥,可小伙子那是忙前忙后,上菜了,把好点的菜都移到我们这,又给这个倒茶水,那个倒饮料的,那时天还很热,吃的也是川菜;就见他那汗从头顶往下流,衬衣都快湿透了;而另一个小伙子是南方这边的人;傻愣愣的支棱在那,就一个劲的傻吃;当时给我的感觉就是北方的小伙子确实会来事儿;

因他是新人,刚毕业,虽说在实习单位有点底子,但还是个新手,好在人比较实在、上进、好学;和团队成员也融合的很好;因为我那时也是刚带项目;手底下就他一个兵;所以我们相处的时间是比较长的;因为我刚毕业找工作的时候比较艰辛,第一位老大对我挺好的(后面了解,其实也不是这么回事儿),我认为它是一种可传承的东西;加上小伙子综合能力是很优秀的;所以在做项目的过程中,把自己针对问题,是怎么去思考它的,怎么去设计,为什么这么设计等等都与他分享;还有人生阶段所需要注意的事项;这些都是我走过的坑和后知后觉的东西,都和他进行交流;我想,对于刚毕业那会儿的他应该算是一笔财富;于我而言,也是完成了内心坚守的一份传承;一直到去年四月份,公司上海区大量裁员,我因个人原因,来到了杭州,他则继续留在了上海,去了OTA的头部公司;薪资double;

时间总是过的很快,我们在推杯换盏的时候思绪拉了回来,他带着他的媳妇和他的小舅子上杭州来玩;我们就约在西湖那逛了会儿;然后来唰火锅了;在言谈间,小伙子还是透着那股实在劲儿;这种劲儿真的是太招人喜欢了;人也比刚毕业那会儿成熟了;眉宇间也多了份自信;像这种时间的跳跃再重逢的场景,总是让人感触良多;像他的人生规划中,已经很清晰了;在ota头部公司再待个两年左右,就可以拿到阿里的p7了;然后到我现在这个岁数;p8就差不多了;那个时候将开启他真正的人生;所以就现在看来,这位小伙子前途无量;

在饭桌上也认识了他的媳妇;同样是非常优秀的;交谈间感觉他们都有个很好的人生底色,就是家风;给人极其踏实信赖的感觉;努力、上进;我记得和他们说过一句还不错的话,这句话不仅是对他们说的,也是对我自己说的:但凡优秀的人都会尊重一直努力的人;所以只需要努力就好了;我很开心、也很荣幸,在他人生道路中扮演了一次传递正能量的小角色;而我们在将来的任何时刻只要相遇,都能把酒言欢;

单身老男人的自白

这两天回了趟南昌,主要做了两件事情,

  • 和大学的老同学和老师在一起吃了个饭
  • 参加好朋友的小孩周岁宴

这次南昌之旅对我影响挺大,夸张点说,冲击了我的三观;此时此刻正听着《The sound of silence》舒缓的旋律,记录着这次行程的心得;

自己已经到了而立之年,但无论以心智、成就和人生阶段来说,早已被同龄人甩的远远的了;车子、房子、票子、老婆、孩子到现在这个阶段,几乎是什么都没有;本来一个人躲在杭州的角落里已经被这种失败给麻痹了;但当同龄人在一起叙旧的时候;这种失败感迅速的笼罩着自身,难以言明;当然,我并不想以名利场来定义现在状态,却让我加深了之前长辈常讲的

什么阶段应该做什么事儿

对于这句话,更多了份赞同

能见到这么多老同学,还是非常开心的;很多同学现在都是刚有小孩脱不开身的时候;在百忙中抽出空来大家聚一聚,这份同学之情,大家都还是很珍惜的;看见他们,格外的透着份亲切:laughing: :laughing: :laughing:

第二天就去参加老朋友小孩的周岁宴了;朋友是医药行业的,其实按真实感受来说,这次吃饭并没有给我带来太多的欢快;他宴请的多半是在医药行业的朋友,和我跨着行业,还有这些人也都是生面孔;所以对我来说是挺无聊的;吃完饭后又到他新买的房子去看看了;然后他们就在聊着房子、车子、票子、老婆、小孩;这些话题基本都让我闭上了嘴,我假借有几分醉意,闷声不吭;

不过正是这顿饭,才真正的让我三观受着强大的冲击;从我朋友的状态我能感受的到,他是真的在这座城市扎下了根,正是有了老婆之后,选择了买房,整个人都是稳定的状态;紧接着和周边的同事、朋友形成着盘根错节的关系网;在他们的聊天中我能感受到他们的这份从容和自信;再一回头想下头天一起吃饭的同学们;其实他们也是如此;他们过的才是生活,踏踏实实,稳步向前的生活;

自视我现在的状态,实在是大相径庭;我这哪是生活啊,我犹如四处逃窜者,一直处于打一枪换一炮的状态;永远不会形成比较稳定的、相对社会上的这种人际关系;公司就是同事的关系,到家后就是自己一个人苦闷的世界;

所以,这是很明确且强意识的东西在警示着我,审视当下,尽快的改变现有的状态;加强自身的能力,解决紧迫性的问题;于我而言,这是紧要的!

这次南昌之旅,对我来说是有收获的,还有一点做的也是还不错的,没有把大学同学聚会搞成名利场;一直在谨防着给大家这样的感觉;永远保持着纯真的同学情!

系统流程

风控系统(risk-admittance)介绍

系统流程

系统中含有许多流程,如公司牌流程、续租流程、个人牌流程、前置三期流程等,根据进件入参RiskAdmittanceQueryParams中的 riskScene 值进行判断该进件走哪个场景

   ...
   "riskScene":[
       {
           "riskFlowScene":"PRE_RISK"
       }
   ],
   ...

当时该值设计为list数据结构,riskFlowScene值为RiskFlowSceneEnum.name值

description riskFlowScene 流程类型 授信额度(期数) 金融额度(期数)
风控SAAS_A流程1+3 SAAS_RISK_FLOW_A_SCENE_12 guaranteeFlow CreditType.FIANACE_PLATFORM_12 LoanType.TWELVE
风控SAAS_A流程4+0 SAAS_RISK_FLOW_A_SCENE_48 guaranteeFlow CreditType.FIANACE_PLATFORM_48 LoanType.FORTY_EIGHT
风控SAAS_B流程1+3 SAAS_RISK_FLOW_B_SCENE_12 guaranteeFlow CreditType.FIANACE_PLATFORM_12 LoanType.TWELVE
个人牌流程4+0 CENTRALIZED_NEW_CAR_SCENE_48 personalFlow CreditType.PERSSONAL_48 LoanType.FORTY_EIGHT
公司牌流程1+3 COMPANY_NEW_CAR_SCENE_48 companyFlow CreditType.COMPANY_48 LoanType.FORTY_EIGHT
续租策略流程 TGC_RELE releFlow CreditType.NULL LoanType.NULL
中小企业流程 COMPANY_RISK merchFlow CreditType.NULL LoanType.NULL
前置流程 PRE_RISK preFLow CreditType.NULL LoanType.FORTY_EIGHT
前置三期流程
(入参中含有多个金融方案)
PRE_RISK preFLow CreditType.NULL LoanType.FORTY_EIGHT

前置流程和前置三期区别:

  • 进件入参,前置流程只有一个金融产品id,前置三期有多个金融产品id
  • 匹配40000后,前置流程直接将消息发出,前置三期会继续走x策略、银行推荐策略等
  • 高首付逻辑处理只针对前置三期流程
  • 发送mq消息的tag,前置:pre_risk_for_tgc, 前置三期:pre_risk_v3_for_tgc

每个流程由不同的功能处理器拼接而成,以实现该流程的需求,接下来介绍每个流程的工作流


流程类型

guaranteeFlow(担保流程):

graph TB subgraph guaranteeFlow start-->fraudQuery fraudQuery -. 异步请求反欺诈策略 .-> fraudReceiver fraudReceiver-->|反欺诈拒绝|mqSend fraudReceiver-->|反欺诈通过|historyQuery historyQuery-->|没有历史进件记录|pbcQuery historyQuery-->|有历史进件记录|quotaMatch pbcQuery-->|人行通过|paymentQuery pbcQuery-->|人行拒绝|guaranteeQuery paymentQuery-->|查询到额度|quotaMatch paymentQuery-. 异步请求基础风控策略 .-> quotaMatch quotaMatch-->allSceneFinished allSceneFinished-->|所有业务场景都为已评估状态|tenantRiskQuery allSceneFinished-->|有业务场景为未评估状态|线程结束 tenantRiskQuery-->|不需要请求外部资方|guaranteeQuery tenantRiskQuery-. 异步请求资方风控.需要请求外部资方 .->guaranteeQuery guaranteeQuery-. 异步请求可担保策略 .->guaranteeReceive guaranteeReceive-->recordCredit recordCredit-->mqSend mqSend-->terminate end subgraph 反欺诈策略 NewKnoxFraudReceiver-->FraudAccess FraudAccess-->fraudReceiver end subgraph 电审策略mq接收 NewAuditResultMessageReciver-->AuditAccess AuditAccess-->|电审通过|quotaMatch AuditAccess-->|电审拒绝|allSceneFinished AuditAccess-. 电审未补充资料 .-> NewAuditResultMessageReciver end subgraph 基础风控策略mq接收 NewKnoxRunResultMessageReciver-->KnoxAccess KnoxAccess-->|基础风控策略通过|quotaMatch KnoxAccess-->|基础风控策略拒绝|allSceneFinished KnoxAccess-. 基础风控策略命中电审 .-> NewAuditResultMessageReciver end subgraph 资方风控策略mq接收 NewTenantPlatformRiskResultMessageReciver-->tenantAccess tenantAccess-->|资方风控通过|guaranteeQuery end subgraph 担保策略mq接收 NewKnoxGuaranteeRuleReciver-->guaPolicyAccess guaPolicyAccess-->guaranteeReceive end fraudQuery -x NewKnoxFraudReceiver paymentQuery -x NewKnoxRunResultMessageReciver tenantRiskQuery -x NewTenantPlatformRiskResultMessageReciver guaranteeQuery -x NewKnoxGuaranteeRuleReciver

personFlow(个人牌流程):

graph TB subgraph personFlow start-->paymentQuery paymentQuery-->|查询到额度|quotaMatch paymentQuery-. 异步请求基础风控策略 .-> quotaMatch quotaMatch-->allSceneFinished allSceneFinished-->|所有业务场景都为已评估状态|tenantRiskQuery allSceneFinished-->|有业务场景为未评估状态|线程结束 tenantRiskQuery-. 异步请求资方风控.需要请求外部资方 .->mqSend mqSend-->terminate end subgraph 电审策略mq接收 NewAuditResultMessageReciver-->AuditAccess AuditAccess-->|电审通过|quotaMatch AuditAccess-->|电审拒绝|allSceneFinished AuditAccess-. 电审未补充资料 .-> NewAuditResultMessageReciver end subgraph 基础风控策略mq接收 NewKnoxRunResultMessageReciver-->KnoxAccess KnoxAccess-->|基础风控策略通过|quotaMatch KnoxAccess-->|基础风控策略拒绝|allSceneFinished KnoxAccess-. 基础风控策略命中电审 .-> NewAuditResultMessageReciver end subgraph 资方风控策略mq接收 NewTenantPlatformRiskResultMessageReciver-->tenantAccess tenantAccess-->|资方风控通过|mqSend end paymentQuery -x NewKnoxRunResultMessageReciver tenantRiskQuery -x NewTenantPlatformRiskResultMessageReciver

companyFlow(公司牌流程):

graph TB subgraph companyFlow start-->paymentQuery paymentQuery-->|查询到额度|quotaMatch paymentQuery-. 异步请求基础风控策略 .-> quotaMatch quotaMatch-->allSceneFinished allSceneFinished-->|所有业务场景都为已评估状态|mqSend allSceneFinished-->|有业务场景为未评估状态|线程结束 mqSend-->terminate end subgraph 电审策略mq接收 NewAuditResultMessageReciver-->AuditAccess AuditAccess-->|电审通过|quotaMatch AuditAccess-->|电审拒绝|allSceneFinished AuditAccess-. 电审未补充资料 .-> NewAuditResultMessageReciver end subgraph 基础风控策略mq接收 NewKnoxRunResultMessageReciver-->KnoxAccess KnoxAccess-->|基础风控策略通过|quotaMatch KnoxAccess-->|基础风控策略拒绝|allSceneFinished KnoxAccess-. 基础风控策略命中电审 .-> NewAuditResultMessageReciver end paymentQuery -x NewKnoxRunResultMessageReciver

releFlow(续租流程):

graph TB subgraph releFlow start-->releQuery releQuery-->releMqSend releMqSend-->terminate end

merchFlow(中小企业流程):

graph TB subgraph merchFlow MerchMessageReciver-->merchMsgAccess merchMsgAccess-->merchMsgReceiver merchMsgReceiver-->|审核拒绝<br>auditStatus==REJECT |merchMqSend merchMsgReceiver-->|额度不足<br>auditStatus==CREDIT_REJECT|merchMqSend merchMsgReceiver-->|人工审核驳回<br>auditStatus==REFUSE |merchMqSend merchMsgReceiver-->|额度审核驳回<br>auditStatus==LACK_OF_MATERIAL |merchMqSend merchMsgReceiver-->|额度通过<br>auditStatus==CREDIT_PASS |fraudQuery fraudQuery -. 异步请求反欺诈策略 .-> fraudReceiver fraudReceiver-->|反欺诈拒绝|merchMqSend fraudReceiver-->|反欺诈通过|prePaymentQuery prePaymentQuery-->|查询到额度|merchMatch prePaymentQuery-. 异步请求企业基础风控策略 .-> merchMatch merchMatch-->|匹配40000|xQuery xQuery-. 异步请求x策略 .->xReceiver xReceiver-->merchMqSend merchMatch-->|匹配结果非40000|merchMqSend merchMqSend-->terminate end subgraph 反欺诈策略 NewKnoxFraudReceiver-->FraudAccess FraudAccess-->fraudReceiver end subgraph 企业信审系统 MerchAuditReceiver-->merchAuditAccess merchAuditAccess-->|电审通过|merchMatch merchAuditAccess-->|电审拒绝|merchMqSend merchAuditAccess-. 电审未补充资料 .-> MerchAuditReceiver end subgraph 企业基础风控策略 MerchKnoxReceiver-->merchKnoxAccess merchKnoxAccess-->|基础风控策略通过|merchMatch merchKnoxAccess-->|基础风控策略拒绝|merchMqSend merchKnoxAccess-. 基础风控策略命中电审 .-> MerchAuditReceiver end subgraph X策略mq接收 XRuleReciver-->xPolicyAccess xPolicyAccess-->xReceiver end fraudQuery -x NewKnoxFraudReceiver prePaymentQuery -x MerchKnoxReceiver xQuery -x XRuleReciver

preflow(前置流程):

graph TB subgraph preflow start-->inTransitOrder inTransitOrder-->|有在途订单|preMqSend inTransitOrder-->|没有在途订单|fraudQuery fraudQuery -. 异步请求反欺诈策略 .-> fraudReceiver fraudReceiver-->|反欺诈拒绝|preMqSend fraudReceiver-->|反欺诈通过|prePaymentQuery prePaymentQuery-->|前置额度缓存有记录|quotaMatch prePaymentQuery-. 异步请求基础风控策略 .->quotaMatch quotaMatch-->discriOver discriOver-->|低首付通过|preMqSend discriOver-->|非低首付通过|guaranteeQuery guaranteeQuery-. 异步请求可担保策略 .->guaranteeReceive guaranteeReceive-->discriOver discriOver-->preMqSend preMqSend-->terminate end subgraph 反欺诈策略 NewKnoxFraudReceiver-->FraudAccess FraudAccess-->fraudReceiver end subgraph 电审策略mq接收 NewAuditResultMessageReciver-->AuditAccess AuditAccess-->|电审通过|quotaMatch AuditAccess-->|电审拒绝|discriOver AuditAccess-. 电审未补充资料 .-> NewAuditResultMessageReciver end subgraph 基础风控策略mq接收 NewKnoxRunResultMessageReciver-->KnoxAccess KnoxAccess-->|基础风控策略通过|quotaMatch KnoxAccess-->|基础风控策略拒绝|discriOver KnoxAccess-. 基础风控策略命中电审 .-> NewAuditResultMessageReciver end subgraph 担保策略mq接收 NewKnoxGuaranteeRuleReciver-->guaPolicyAccess guaPolicyAccess-->guaranteeReceive end subgraph 提额流程 提额流程-->quotaAccess quotaAccess-->|提额通过|quotaMatch quotaAccess-->|提额取消|discriOver quotaAccess-->|提额拒绝|discriOver end subgraph 担保流程 担保流程-->guaAccess guaAccess-->|担保通过|quotaMatch guaAccess-->|担保取消|discriOver guaAccess-->|担保拒绝|discriOver end subgraph 担保复用流程 担保复用流程-->guaReuseAccess guaReuseAccess-->|担保复用通过|quotaMatch guaReuseAccess-->|担保复用取消|discriOver end fraudQuery -x NewKnoxFraudReceiver prePaymentQuery -x NewKnoxRunResultMessageReciver guaranteeQuery -x NewKnoxGuaranteeRuleReciver
graph TB subgraph 第一次匹配 discriOver-->|第一次匹配<br>&低首付通过|preMqSend discriOver-->|第一次匹配<br>&A<br>&从未提额|提额流程 discriOver-->|第一次匹配<br>&A<br>&已提过额<br>&可担保|担保流程 discriOver-->|第一次匹配<br>&A<br>&已提过额<br>&可担保复用|担保复用流程 discriOver-->|第一次匹配<br>&A<br>&已提过额<br>&不可担保|preMqSend discriOver-->|第一次匹配<br>&B<br>&可担保|担保流程 discriOver-->|第一次匹配<br>&B<br>&可担保复用|担保复用流程 discriOver-->|第一次匹配<br>&B<br>&不可担保|preMqSend end
graph TB subgraph 提额流程接入 discriOver-->|提额匹配<br>&低首付通过|preMqSend discriOver-->|提额匹配<br>&A<br>&可担保|担保流程 discriOver-->|提额匹配<br>&A<br>&可担保复用|担保复用流程 discriOver-->|提额匹配<br>&A<br>&不可担保|preMqSend discriOver-->|提额匹配<br>&B<br>&可担保|担保流程 discriOver-->|提额匹配<br>&B<br>&可担保复用|担保复用流程 discriOver-->|提额匹配<br>&B<br>&不可担保|preMqSend discriOver-->|提额取消<br>&可担保|担保流程 discriOver-->|提额取消<br>&可担保复用|担保复用流程 discriOver-->|提额取消<br>&不可担保|preMqSend discriOver-->|提额拒绝<br>&可担保|担保流程 discriOver-->|提额拒绝<br>&可担保复用|担保复用流程 discriOver-->|提额拒绝<br>&不可担保|preMqSend end
graph TB subgraph 担保复用流程接入 discriOver-->|担保复用匹配<br>&低首付通过|preMqSend discriOver-->|担保复用取消<br>|担保流程 end
graph TB subgraph 担保流程接入 discriOver-->|担保匹配<br>&低首付通过|preMqSend discriOver-->|担保匹配<br>&A<br>|preMqSend discriOver-->|担保匹配<br>&B|preMqSend discriOver-->|担保取消<br>|preMqSend discriOver-->|担保拒绝<br>|preMqSend end

虚线代表异步处理
额度不足 -> 满足可提额的先决条件, 流程图中指定为A
基础风控策略拒绝|电审拒绝|首付比例无匹配 -> 只满足进担保的先决条件, 流程图中指定为B


preflow V3(前置三期流程):

graph TB subgraph preflow v3 start-->inTransitOrder inTransitOrder-->|有在途订单|preMqSendV3 inTransitOrder-->|没有在途订单|fraudQuery fraudQuery -. 异步请求反欺诈策略 .-> fraudReceiver fraudReceiver-->|反欺诈拒绝|preMqSendV3 fraudReceiver-->|反欺诈通过|prePaymentQuery prePaymentQuery-->|前置额度缓存有记录|quotaMatchOfProList prePaymentQuery-. 异步请求基础风控策略 .->quotaMatchOfProList quotaMatchOfProList-->discriOver discriOver-->|低首付通过|xQuery xQuery-. 异步请求x策略 .->xReceiver xReceiver-->recommendBankQuery recommendBankQuery-. 异步请求银行推荐策略 .->recommendBankReceiver discriOver-->|非低首付通过|guaranteeQuery guaranteeQuery-. 异步请求可担保策略 .->guaranteeReceive guaranteeReceive-->discriOver discriOver-->preMqSendV3 recommendBankReceiver-->preMqSendV3 preMqSendV3-->terminate end subgraph 反欺诈策略 NewKnoxFraudReceiver-->FraudAccess FraudAccess-->fraudReceiver end subgraph 电审策略mq接收 NewAuditResultMessageReciver-->AuditAccess AuditAccess-->|电审通过|quotaMatchOfProList AuditAccess-->|电审拒绝|discriOver AuditAccess-. 电审未补充资料 .-> NewAuditResultMessageReciver end subgraph 基础风控策略mq接收 NewKnoxRunResultMessageReciver-->KnoxAccess KnoxAccess-->|基础风控策略通过|quotaMatchOfProList KnoxAccess-->|基础风控策略拒绝|discriOver KnoxAccess-. 基础风控策略命中电审 .-> NewAuditResultMessageReciver end subgraph 担保策略mq接收 NewKnoxGuaranteeRuleReciver-->guaPolicyAccess guaPolicyAccess-->guaranteeReceive end subgraph X策略mq接收 XRuleReciver-->xPolicyAccess xPolicyAccess-->xReceiver end subgraph 银行推荐策略mq接收 RecommendBankRuleReciver-->recommendBankAccess recommendBankAccess-->recommendBankReceiver end subgraph 提额流程 提额流程-->quotaAccess quotaAccess-->|提额通过|quotaMatchOfProList quotaAccess-->|提额取消|discriOver quotaAccess-->|提额拒绝|discriOver end subgraph 担保流程 担保流程-->guaAccess guaAccess-->|担保通过|quotaMatchOfProList guaAccess-->|担保取消|discriOver guaAccess-->|担保拒绝|discriOver end subgraph 担保复用流程 担保复用流程-->guaReuseAccess guaReuseAccess-->|担保复用通过|quotaMatchOfProList guaReuseAccess-->|担保复用取消|discriOver end subgraph 高首付流程 高首付流程-->downPayAccess downPayAccess-->|使用高首付流程|xQuery end fraudQuery -x NewKnoxFraudReceiver prePaymentQuery -x NewKnoxRunResultMessageReciver guaranteeQuery -x NewKnoxGuaranteeRuleReciver xQuery -x XRuleReciver recommendBankQuery -x RecommendBankRuleReciver
graph TB subgraph 第一次匹配 discriOver-->|第一次匹配<br>&低首付通过|X策略 discriOver-->|第一次匹配<br>&A<br>&从未提额|提额流程 discriOver-->|第一次匹配<br>&A<br>&已提过额<br>&可担保|担保流程 discriOver-->|第一次匹配<br>&A<br>&已提过额<br>&可担保复用|担保复用流程 discriOver-->|第一次匹配<br>&A<br>&已提过额<br>&不可担保|preMqSendV3 discriOver-->|第一次匹配<br>&D<br>&从未提额|提额流程 discriOver-->|第一次匹配<br>&D<br>&已提过额<br>&可担保|担保流程 discriOver-->|第一次匹配<br>&D<br>&已提过额<br>&可担保复用|担保复用流程 discriOver-->|第一次匹配<br>&D<br>&已提过额<br>&不可担保|高首付流程 discriOver-->|第一次匹配<br>&B<br>&可担保|担保流程 discriOver-->|第一次匹配<br>&B<br>&可担保复用|担保复用流程 discriOver-->|第一次匹配<br>&B<br>&不可担保|preMqSendV3 discriOver-->|第一次匹配<br>&C<br>&可担保|担保流程 discriOver-->|第一次匹配<br>&C<br>&可担保复用|担保复用流程 discriOver-->|第一次匹配<br>&C<br>&不可担保|高首付流程 end
graph TB subgraph 提额流程接入 discriOver-->|提额匹配<br>&低首付通过|X策略 discriOver-->|提额匹配<br>&A<br>&可担保|担保流程 discriOver-->|提额匹配<br>&A<br>&可担保复用|担保复用流程 discriOver-->|提额匹配<br>&A<br>&不可担保<br>&可高首付|高首付流程 discriOver-->|提额匹配<br>&A<br>&不可担保<br>&不可高首付|preMqSendV3 discriOver-->|提额匹配<br>&D<br>&可担保|担保流程 discriOver-->|提额匹配<br>&D<br>&可担保复用|担保复用流程 discriOver-->|提额匹配<br>&D<br>&不可担保<br>&可高首付|高首付流程 discriOver-->|提额匹配<br>&D<br>&不可担保<br>&不可高首付|preMqSendV3 discriOver-->|提额匹配<br>&B<br>&可担保|担保流程 discriOver-->|提额匹配<br>&B<br>&可担保复用|担保复用流程 discriOver-->|提额匹配<br>&B<br>&不可担保<br>&可高首付|高首付流程 discriOver-->|提额匹配<br>&B<br>&不可担保<br>&不可高首付|preMqSendV3 discriOver-->|提额匹配<br>&C<br>&可担保|担保流程 discriOver-->|提额匹配<br>&C<br>&可担保复用|担保复用流程 discriOver-->|提额匹配<br>&C<br>&不可担保<br>&可高首付|高首付流程 discriOver-->|提额匹配<br>&C<br>&不可担保<br>&不可高首付|preMqSendV3 discriOver-->|提额取消<br>&可高首付|高首付流程 discriOver-->|提额取消<br>&不可高首付<br>&可担保|担保流程 discriOver-->|提额取消<br>&不可高首付<br>&可担保复用|担保复用流程 discriOver-->|提额取消<br>&不可高首付<br>&不可担保|preMqSendV3 discriOver-->|提额拒绝<br>&可担保|担保流程 discriOver-->|提额拒绝<br>&可担保复用|担保复用流程 discriOver-->|提额拒绝<br>&不可担保<br>&可高首付|高首付流程 discriOver-->|提额拒绝<br>&不可担保<br>&不可高首付|preMqSendV3 end
graph TB subgraph 担保复用流程接入 discriOver-->|担保复用匹配<br>&低首付通过|X策略 discriOver-->|担保复用取消<br>|担保流程 end
graph TB subgraph 担保流程接入 discriOver-->|担保匹配<br>&低首付通过|X策略 discriOver-->|担保匹配<br>&A<br>&可高首付|高首付流程 discriOver-->|担保匹配<br>&A<br>&不可高首付|preMqSendV3 discriOver-->|担保匹配<br>&D<br>&可高首付|高首付流程 discriOver-->|担保匹配<br>&D<br>&不可高首付|preMqSendV3 discriOver-->|担保匹配<br>&B<br>&可高首付|高首付流程 discriOver-->|担保匹配<br>&B<br>&不可高首付|preMqSendV3 discriOver-->|担保匹配<br>&C<br>&可高首付|高首付流程 discriOver-->|担保匹配<br>&C<br>&不可高首付|preMqSendV3 discriOver-->|担保取消<br>可高首付|高首付流程 discriOver-->|担保取消<br>不可高首付|preMqSendV3 discriOver-->|担保拒绝<br>可高首付|高首付流程 discriOver-->|担保拒绝<br>不可高首付|preMqSendV3 end
graph TB subgraph 高首付流程接入 高首付流程== 将第一次匹配的高首付比例结果覆盖进件中的匹配结果 ==>X策略 end
  • 虚线代表异步处理
  • 额度不足 -> 满足可提额的先决条件, 流程图中指定为A
  • 基础风控策略拒绝|电审拒绝|首付比例无匹配 -> 只满足进担保的先决条件, 流程图中指定为B
  • 指在与金融方案匹配完的结果为40000的首付比例不含有小于35,且基础首付比例大于35 -> 满足可提额的先决条件, 流程图中指定为C
  • 指在与金融方案匹配完的结果为40000的首付比例不含有小于35,且基础首付比例含有小于35 -> 只满足进担保的先决条件, 流程图中指定为D
  • 指在与金融方案匹配完的结果为40000的首付比例含有小于35,统称为低首付通过 -> 低首付比例通过
  • 额度缓存/基础风控策略/电审的匹配结果 -> 第一次匹配
  • 进件中有高首付标记 -> 可高首付,反之为不可高首付

功能处理器介绍

bean name 描述 bean name 描述
start 开始处理器 terminate 结束处理器
inTransitOrder 判断在途订单处理器 fraudQuery 反欺诈请求处理器
fraudReceiver 反欺诈接收处理器 prePaymentQuery 前置(包含三期)判断额度缓存处理器
paymentQuery 非前置判断额度缓存处理器 quotaMatch 额度匹配处理器
discriOver 调度处理器 quotaMatchOfProList 前置三期额度匹配处理器
xQuery X策略请求处理器 xReceiver X策略接收处理器
recommendBankQuery 银行推荐策略请求处理器 recommendBankReceiver 银行推荐策略接收处理器
guaranteeQuery 可担保策略请求处理器 guaranteeReceive 可担保策略接收处理器
preMqSend 前置发送mq消息处理器 preMqSendV3 前置三期发送mq消息处理器
historyQuery 查询历史进件缓存处理器 pbcQuery 判断人行拒绝处理器
allSceneFinished 判断所有业务场景是否结束 tenantRiskQuery 外部资方策略请求处理器
recordCredit 存取额度缓存处理器 mqSend 非前置流程发送mq消息处理器
fraudAccess 反欺诈接入流程处理器 AuditAccess 电审接入流程处理器
DownPayAccess 高首付接入流程处理器 GuaAccess 担保接入流程处理器
GuaPolicyAccess 担保策略接入流程处理器 GuaReuseAccess 担保复用接入流程处理器
KnoxAccess 基础风控策略接入流程处理器 MerchKnoxAccess 中小企业基础风控策略接入流程
MerchMsgAccess 中小企业审核结果接入流程 QuotaAccess 提额流程接入流程
RecommendBankAccess 银行推荐策略接入流程 TenantAccess 外部资方接入流程
XPolicyAccess X策略接入流程

业务框架

风控系统(risk-admittance)业务框架

流程介绍

根据系统流程介绍可知,系统核心是由多条流程组成,下图为流程类的类图

classDiagram Flow <|.. BaseFlow : implements Flow: + void main(bizNo, params) Flow: + void access(access, type, reqParam) Flow: + void access(beanName, reqParam) BaseFlow <|-- CompanyFlow : Inheritance BaseFlow <|-- GuaranteeFlow : Inheritance BaseFlow <|-- MerchFlow : Inheritance BaseFlow <|-- PersonalFlow : Inheritance BaseFlow <|-- PreFlow : Inheritance BaseFlow <|-- ReleFlow : Inheritance BaseFlow: +ProcessHandler start BaseFlow: +ProcessHandler terminate BaseFlow: +HandlerContextPipeLine pipeLine BaseFlow: +Map<String, Map<String, ConditionFunc>> accessMap BaseFlow: + void main(bizNo, params) BaseFlow: + void access(access, type, reqParam) BaseFlow: + void access(beanName, reqParam) BaseFlow: + abstract void init() BaseFlow: + void afterPropertiesSet() CompanyFlow:+void init() GuaranteeFlow:+void init() MerchFlow:+void init() PersonalFlow:+void init() PreFlow:+void init() ReleFlow:+void init()

Flow

  • main: 从starthandler开始执行整个流程
  • access(access, type, reqParam): 从mq接入流程内
    • access:接入节点对象
    • type:是pass|cancel|reject
    • reqParam:进件大对象
  • access(beanName, reqParam): 从测试接口接入流程内,只测某个或某些处理器
    • access:开始节点beanName
    • reqParam:进件大对象

BaseFlow

  • start: 开始处理器
  • terminate: 结束处理器
  • pipeLine: 流程中的所有功能处理器都是由pipeLine进行串联的
  • accessMap: 所有接入节点的集合,以接入节点对象的beanName为key,ConditionFunc对象为value的map结构体
  • main: 实现接口
  • access(access, type, reqParam): 实现接口
  • access(beanName, reqParam): 实现接口
  • init(): 抽象方法,子类实现
  • afterPropertiesSet: 初始化HandlerContextPipeLine

CompanyFlow和所有子流程

  • init: 添加该流程所需的功能处理器

功能处理器

每个流程是由多个功能处理器组成

特性介绍

我们通过两个纬度对每个功能处理器赋予特性:

  1. 流程节点 | 接入节点
    
    public enum HandlerType {
    /**
     * 异步接收外部系统mq,将其接入到流程的节点定义为接入节点
     */
    ACCESS("接入节点", 1),
    /**
     * 每个flow初始化时定义的handler节点
     */
    PROCESS("流程节点", 2);
    }
2. 静态特性 | 动态特性
- 静态特性:该功能处理器在初始化时已知前驱节点和后驱节点
- 动态特性:该功能处理器根据运行过程中的数据判断是否有后驱节点和后驱节点的beanName  
由以上两种特性可衍生出三种节点类型

public enum FeatureType {
/**

  • 根据初始化的顺序已经指定前驱节点和后驱节点
    */
    NORMAL("普通节点", 1),

/**

  • 该节点为结束节点,有两种节点会是结束节点
    1. 请求外部系统,等待异步接收mq消息返回
    1. 最后一个节点
      */
      OVER("结束节点", 2),

/**

  • 根据运行时的数据判断该节点为以下三种状态
    1. 该节点为结束节点
    1. 该节点下个节点为初始化默认的后驱节点
    1. 该节点的后驱节点为计算后的节点
      */
      CONDITION("条件节点", 3);
      }
      
      一个流程中的所有节点,主要分为流程节点和接入节点,其次根据每个节点的动静特性分为普通节点/结束节点/条件节点
      但是无论是流程节点还是接入节点,都会被封装为DefaultHandlerContext对象
public class DefaultHandlerContext<T> extends AbstractHandlerContext {
    /**
     * 空节点,next节点等于该节点,表示当前节点为结束节点
     */
    public static final DefaultHandlerContext NULL_OBJECT = new DefaultHandlerContext();

    /**
     * 业务处理handler
     */
    private ProcessHandler<T> handler;

    /**
     * handler的beanName
     */
    private String beanName;

    ...
}

public abstract class AbstractHandlerContext<T> implements ProcessHandler<T> {

    /**
     * 默认为普通节点
     */
    protected FeatureType featureType = FeatureType.NORMAL;

    /**
     * 默认为流程节点
     */
    protected HandlerType handlerType = HandlerType.PROCESS;

    /**
     * 当前节点的前驱节点
     */
    protected DefaultHandlerContext prev;

    /**
     * 当前节点的后驱节点
     */
    protected DefaultHandlerContext next;

    /**
     * 当前节点为条件节点时的执行语句,以判断当前节点是否是结束节点,如果不是,获取下个节点的handler beanName
     */
    protected ConditionFunc<T> conditionFun;

    ...

}

流程节点介绍

DefaultHandlerContext中的handler类图如下:

classDiagram ProcessHandler <|.. AbstractProcessHandler : implements ProcessHandler: + String process(reqParam) ProcessHandler: + String getBeanName() ProcessHandler: + interface Internal<T> AbstractProcessHandler <|-- inTransitOrder : Inheritance AbstractProcessHandler <|-- fraudQuery : Inheritance AbstractProcessHandler <|-- fraudReceiver : Inheritance AbstractProcessHandler <|-- 其它子类功能处理器 : Inheritance AbstractProcessHandler: +String beanName AbstractProcessHandler: +Internal<T> internal AbstractProcessHandler: + T process(reqParam) AbstractProcessHandler: + void doBefore(reqParam) AbstractProcessHandler: + void doAfter(reqParam, result) AbstractProcessHandler: + T abstract doProcess(reqParam) AbstractProcessHandler: + Invoker<T> getInvoker() AbstractProcessHandler: + final class InternalImpl implements Internal<T> inTransitOrder:+Invoker invoker inTransitOrder:+Void doProcess(ReqParam reqParam) fraudQuery:+Invoker invoker fraudQuery:+Void doProcess(ReqParam reqParam) fraudReceiver:+Invoker invoker fraudReceiver:+Void doProcess(ReqParam reqParam) 其它子类功能处理器:+Invoker invoker 其它子类功能处理器:+Void doProcess(ReqParam reqParam)

ProcessHandler

  • process: 处理业务方法
  • getBeanName: 获取该handler beanName
  • interface Internal: 内部接口 收集该handler处理器的返回值和需要更新的表数据等

AbstractProcessHandler

  • process 处理业务组合方法

      public T process(ReqParam reqParam) {
         doBefore(reqParam);
         T result = doProcess(reqParam);
         doAfter(reqParam, result);
         internal.intern(reqParam, result);
    
         return result;
     }
  • doBefore: 调用业务处理器的前置方法, 默认实现

  • doProcess: 抽象方法,供子类处理器实现,真正业务处理方法

  • doAfter: 调用业务处理器的后置方法,默认实现

  • InternalImpl: 实现接口Internal,完成对业务处理运行时的数据收集,可供前端展示和问题定位分析使用

子类功能处理器(inTransitOrder、fraudQuery、fraudReceiver等)

  • invoker: 处理非业务的数据处理执行器,如根据返回值判断该节点是否需要操作数据库、操作哪些表、返回值的存储等
  • doProcess: 处理该功能处理器的业务方法,如在途订单:调用第三方接口,获取数据以判断是否含有在途订单等业务逻辑

流程内的节点可以是普通节点、结束节点、条件节点;
举例分析:

  • 结束节点:
    • fraudQuery:反欺诈异步请求节点,流程在执行该节点后,线程已结束,等待策略mq消息返回
  • 普通节点:
    • quotaMatchOfProList:多金融方案进行匹配完后,默认next节点就是discriOver调度节点
  • 条件节点:
    • prePaymentQuery:额度缓存判断处理器,额度缓存存在则下个节点是quotaMatchOfProList(多金融方案匹配节点),不存在则异步请求基础风控策略,当前节点为结束节点
    • fraudReceiver:反欺诈策略接收处理器,反欺诈通过则下个节点是prePaymentQuery(额度缓存处理器节点),反欺诈拒绝则下个节点为preMqSendV3(发送mq消息)

接入节点介绍

Access类图如下:

classDiagram FlowAccess <|.. BaseAccess : implements FlowAccess: + String getBeanName() BaseAccess <|-- FraudAccess : Inheritance BaseAccess <|-- KnoxAccess : Inheritance BaseAccess <|-- AuditAccess : Inheritance BaseAccess <|-- 其它子类接入流程处理器 : Inheritance BaseAccess: +String beanName BaseAccess: + void pass(reqParam) BaseAccess: + void reject(reqParam) BaseAccess: + void cancel(reqParam)

FlowAccess:

  • getBeanName: 获取该Access beanName

BaseAccess

  • getBeanName: 获取该Access beanName
  • pass: 通过(基础风控通过、电审通过、提额通过、担保通过等)
  • reject: 拒绝(基础风控拒绝、电审拒绝、提额拒绝、担保拒绝等)
  • cancel: 取消(提额拒绝、担保拒绝等)

子类接入流程处理器

  • 复写父类的pass/reject/cancel方法

执行流程分析:

以前置三期流程为例

类图如下:

classDiagram Flow接口 <|.. BaseFlow基础实现类 : 实现 Flow接口: + String getBeanName() BaseFlow基础实现类 <|-- PreFLow : 继承 BaseFlow基础实现类: +String beanName BaseFlow基础实现类: + void pass(reqParam) BaseFlow基础实现类: + void reject(reqParam) BaseFlow基础实现类: + void cancel(reqParam) PreFLow --* HandlerContextPipeLine : Contains 1:1 HandlerContextPipeLine --> "many" DefaultHandlerContext流程内节点 : Contains 1:many AbstractHandlerContext <|-- DefaultHandlerContext流程内节点 : 继承 DefaultHandlerContext流程内节点 "1" --> "1..*" ProcessHandler实现类处理器: handler属性 AbstractProcessHandler基础实现类 <|-- ProcessHandler实现类处理器: 继承 ProcessHandler业务处理器接口 <|.. AbstractProcessHandler基础实现类 : 实现 ProcessHandler业务处理器接口 <|.. AbstractHandlerContext : 实现 AbstractHandlerContext <|-- DefaultHandlerContext接入节点 : 继承 FlowAccess接入接口 <|.. BaseAccess基础实现类 : 实现 FlowAccess接入接口: + String getBeanName() BaseAccess基础实现类 <|-- 接入节点实现类 : 继承 BaseAccess基础实现类: +String beanName BaseAccess基础实现类: + void pass(reqParam) BaseAccess基础实现类: + void reject(reqParam) BaseAccess基础实现类: + void cancel(reqParam) DefaultHandlerContext接入节点 --* 接入节点实现类 : 包含access BeanName和ConditionFunc执行器

流程图:参考系统流程.md文件

所用到的功能处理器归纳如下:

beanName 描述 流程/接入节点 静态/动态特性 beanName 描述 流程/接入节点 静态/动态特性
start 开始节点 流程节点 普通节点
inTransitOrder 判断在途订单节点 流程节点 条件节点
fraudQuery 反欺诈异步请求节点 流程节点 结束节点 fraudAccess 反欺诈mq接收节点 接入节点 条件节点
fraudReceiver 反欺诈接收节点 流程节点 条件节点 KnoxAccess 基础风控策略接入节点 接入节点 条件节点
prePaymentQuery 额度缓存节点 流程节点 条件节点 AuditAccess 电审策略接入节点 接入节点 条件节点
quotaMatch 金融方案匹配节点 流程节点 条件节点 QuotaAccess 提额接入节点 接入节点 条件节点
quotaMatchOfProList 多金融方案匹配节点 流程节点 普通节点 GuaAccess 担保接入节点 接入节点 条件节点
discriOver 调度节点 流程节点 条件节点 GuaReuseAccess 担保复用接入节点 接入节点 条件节点
xQuery X策略异步请求节点 流程节点 结束节点 DownPayAccess 高首付接入节点 接入节点 条件节点
xReceiver X策略接收节点 流程节点 普通节点 xPolicyAccess x策略mq接收节点 接入节点 条件节点
recommendBankQuery 银行推荐策略异步请求节点 流程节点 结束节点 recommendBankAccess 银行推荐策略mq接收节点 接入节点 条件节点
recommendBankReceiver 银行推荐策略接收节点 流程节点 条件节点
guaranteeQuery 可担保策略异步请求节点 流程节点 结束节点 guaPolicyAccess 可担保策略mq接收节点 接入节点 条件节点
guaranteeReceive 可担保策略接收节点 流程节点 条件节点
preMqSend 前置发送mq消息节点 流程节点 条件节点
preMqSendV3 前置三期发送mq消息节点 流程节点 普通节点
terminate 结束处理器 流程节点 结束节点

初始化流程

BaseFlow#

    public void afterPropertiesSet() throws Exception {
        pipeLine = new HandlerContextPipeLine(new DefaultHandlerContext(start), new DefaultHandlerContext(terminate, FeatureType.OVER));
        init();
    }

HandlerContextPipeLine#

    // 当前flow流程的所有DefaultHandlerContext
    private Map<String, DefaultHandlerContext> contextMap = new HashMap<String, DefaultHandlerContext>() {{
        // 包含NULL_OBJECT
        put(null, DefaultHandlerContext.NULL_OBJECT);
    }};

    /**
     * HandlerContextPipeLine 构造函数
     * @param head
     * @param end
     */
    public HandlerContextPipeLine(DefaultHandlerContext head, DefaultHandlerContext end) {
        this.head = head;
        this.end = end;

        contextMap.put(head.getBeanName(), head);
        contextMap.put(end.getBeanName(), end);
        head.setNext(end);
        end.setPrev(head);
    }
  • 先初始化流程中的pipeLine,每个HandlerContextPipeLine初始化都有start和terminate节点
  • pipeLine中的每个节点都有前驱节点和后驱节点属性
  • contextMap:该流程中所包含的所有功能处理器
    
    preflow#
/**
 * 流程节点初始化
 */
@Override
@SuppressWarnings("unchecked")
public void init() {
    pipeLine
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("inTransitOrder"), inTransitFun))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("fraudQuery"), FeatureType.OVER))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("fraudReceiver"), fraudReceiverFun))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("prePaymentQuery"), prePaymentFun))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("quotaMatch"), quotaMatchFun))
            .add(new DefaultHandlerContext(HandlerUtil.getHandler("quotaMatchOfProList")))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("discriOver"), discrFun))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("xQuery"), FeatureType.OVER))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("xReceiver")))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("recommendBankQuery"), recommendBankQryFun))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("recommendBankReceiver"), recommendBankRecFun))
            .add(new DefaultHandlerContext(HandlerUtil.getHandler("guaranteeQuery"), FeatureType.OVER))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("guaranteeReceive"), guaFun))
            .add(new DefaultHandlerContext<>(HandlerUtil.getHandler("preMqSend"), preMqSendFun))
            .add(new DefaultHandlerContext(HandlerUtil.getHandler("preMqSendV3")));

}

HandlerContextPipeLine#
/**

  • 新增节点时: 当前节点是普通节点时,设置当前节点的next节点为end

  • --------- 上游节点是普通节点时,设置当前节点为上游节点的next节点

  • @param handlerContext

  • @return
    */
    public HandlerContextPipeLine add(DefaultHandlerContext handlerContext) {
    DefaultHandlerContext preContext = end.getPrev();
    end.setPrev(handlerContext);
    if (handlerContext.getFeatureType() == FeatureType.NORMAL) {
    handlerContext.setNext(end);
    }

    handlerContext.setPrev(preContext);
    if (preContext.getFeatureType() == FeatureType.NORMAL) {
    preContext.setNext(handlerContext);
    }

    contextMap.put(handlerContext.getBeanName(), handlerContext);
    return this;
    }

DefaultHandlerContext#

public DefaultHandlerContext(ProcessHandler handler, FeatureType type) {
    this(handler);
    this.featureType = type;
    if (featureType == FeatureType.OVER) {
        next = NULL_OBJECT;
    }
}
> - 当前节点为普通节点时,会初始化前驱节点和后驱节点
> - 当前节点为条件节点时,初始化不会设置next节点
> - 当前节点为结束节点时,初始化next节点为NULL_OBJECT

---
#### 进件流程
初始化结束后,进件执行流程如下:
根据进件选择执行具体流程

RiskExecutor#

public void execute(String bizNo, RiskAdmittanceQueryParams params) {
    Flow flow = getFlow(params);
    flow.main(bizNo, params);
}
执行flow的main方法:

BaseFlow#

/**
 * 从starthandler开始流程
 *
 * @param bizNo
 * @param params
 */
@Override
public void main(String bizNo, RiskAdmittanceQueryParams params) {
    pipeLine.start(getDataUtil().initReqParam(bizNo, params), getDataUtil());
}
执行HandlerContextPipeLine的start方法:

HandlerContextPipeLine#

/**
 * 流程的开始节点
 *
 * @param reqParam
 * @param dataUtil
 */
public void start(ReqParam reqParam, DataUtil dataUtil) {
    head.execute(reqParam, dataUtil, handlerFun);
}
执行AbstractHandlerContext的execute方法:

AbstractHandlerContext#

void execute(ReqParam reqParam, DataUtil dataUtil, Function<String, DefaultHandlerContext> handlerFun) {
    log.info(" === bizNo: {} - execute {} handler start", reqParam.getBizNo(), this.getBeanName());

    DefaultHandlerContext temp;
    if (FeatureType.CONDITION == featureType) {
        temp = handlerFun.apply(conditionFun.invoke(reqParam, this.process(reqParam)));
    } else {
        this.process(reqParam);
        temp = next;
    }

    // 对数据进行落库操作
    updateData(reqParam, dataUtil);

    // 判断该handler处理完是否终结
    if (temp == NULL_OBJECT) {
        log.info("=== bizNo: {} - execute {} handler end,当前流程已结束,数据:{}", reqParam.getBizNo(), this.getBeanName(), JSON.toJSONString(reqParam));
        return;
    }

    log.info("=== bizNo: {} - execute {} handler end, 当前handler处理后的数据:{},下个handlerName:{}", reqParam.getBizNo(), this.getBeanName(), JSON.toJSONString(reqParam.getCurrentInfo()), temp.getBeanName());
    temp.execute(reqParam, dataUtil, handlerFun);
}
> - 判断当前节点是否是条件节点
>   - 是,执行当前节点process方法,将返回值传入条件对象ConditFunc中,获取next节点
>   - 否,执行当前节点process方法,获取当前节点的默认next节点
> - 根据当前节点的HandlerInfo数据进行落库操作
> - 判断下个节点是否是NULL_OBJECT
>   - 是,当前线程结束,打印数据
>   - 否,执行下个节点的execute方法
---
#### 接入流程


> 接入节点通常都是条件节点

以反欺诈接入节点为例:

@Component
@Slf4j
@Data
public class FraudAccess extends BaseAccess {
}

@Access
@Data
@Slf4j
public abstract class BaseAccess implements FlowAccess {
...
/**

  • 通过
  • @param reqParam
    */
    public void pass(ReqParam reqParam) {
    log.info("进入接入{}类内,调用pass方法", this.getBeanName());
    // 额度匹配
    reqParam.getFlow().access(this, "pass", reqParam);
    }
    ...

}

> FraudAccess是空实现,直接调用父类方法  
> 通过reqParam可知当前接入节点所接入的流程,从而调用BaseFlow中的access方法

BaseFlow#

Map<String, Map<String, ConditionFunc>> accessMap = new HashMap<String, Map<String, ConditionFunc>>() {{
    // 反欺诈
    put("fraudAccess",
            new HashMap<String, ConditionFunc>() {{
                put("pass", (reqParam, o) -> "fraudReceiver");
            }});
            ...
}};

/**
 * 从mq接入流程内
 *
 * @param access
 * @param reqParam
 * @param type
 */
@Override
public void access(FlowAccess access, String type, ReqParam reqParam) {
    log.info("access:{}, type:{} 接入流程内", access.getBeanName(), type);
    String funcKey = access.getBeanName();
    ConditionFunc func = null;
    if (accessMap.containsKey(funcKey)) {
        func = accessMap.get(funcKey).get(type);
    } else if (access instanceof MatchQuotaAccess) {
        func = accessMap.get("matchAccess").get(type);
    }

    Assert.notNull(func, access.getBeanName() + "func should not null");
    pipeLine.access(funcKey, func, reqParam, getDataUtil());
}
...

}

> accessMap: 流程初始化时,以access beanName为key,ConditionFunc(确认下个节点的beanName)对象为value的map数据  
> access: 通过access beanName获取条件对象ConditionFunc, 调用HandlerContextPipeLine#access方法

HandlerContextPipeLine#

/**
 * mq接收数据接入流程
 *
 * @param beanName access name
 * @param func     要执行的func
 * @param reqParam
 * @param dataUtil
 */
public void access(String beanName, ConditionFunc<ReqParam> func, ReqParam reqParam, DataUtil dataUtil) {
    log.info("mq接收数据节点接入HandlerContextPipeLine内,beanName:{}", beanName);
    DefaultHandlerContext<ReqParam> handlerContext = new DefaultHandlerContext<>(func, beanName);
    handlerContext.execute(reqParam, dataUtil, handlerFun);
}
> 1. 通过beanName和ConditionFunc对象初始化DefaultHandlerContext对象
> 2. 执行AbstractContext.execute方法,由上述进件流程可知,因1创建的DefaultHandlerContext是条件节点,执行ConditionFunc执行器获取下个节点(流程中的节点),从而进入流程节点

ConditionFunc执行器接口定义:

@FunctionalInterface
public interface ConditionFunc {
String invoke(ReqParam reqParam, T t);
}



---
总结:该篇主要介绍系统业务架构的思想
1. 首先根据业务性质区分功能处理器特性
2. 用HandlerContextPipeLine将流程内的节点进行串接
3. 每个节点设置prev(前驱节点)和next(后驱节点),以达到系统灵活的扩展性