SpringBoot+使用过滤器链执行风控决策

风控流程

image

下单前进行风控校验

 // 1.begin---风控处理---前置处理{黑白名单校验}
        RiskControlRuleEnum controlRuleEnum = riskControlHandlerService.preHandle(mappingObj.getMerchantGoodsType(), thatUser);
        if (controlRuleEnum != null) {
            logger.error("风控处理进入--->{}", controlRuleEnum.getDesc());
            Result error = Result.error(controlRuleEnum.getDesc());
            error.setCode("WEB_RISK_CONTROL_" + controlRuleEnum.getCode());
            return error;
        }

下单后进行风控判断是否会进入

  // 2.ending---风控限制后置处理|处理{黑白名单校验}
 taskExecutor.execute(() -> riskControlHandlerService.afterBuyingTicketsHandle(mappingObj.getMerchantGoodsType(), user));

风控前置校验

    /**
     * 风控---前置校验
     *
     * @param user user
     * @return
     * @throws Exception
     */
    public RiskControlRuleEnum preHandle(String merchantGoodsType, User user) {
        // 风控规则校验---拒绝购买票的号码校验
        List<RiskControlManager> managerList = riskControlManagerService.getByMerchantGoodsType(merchantGoodsType);
        if (CollectionUtils.isNotEmpty(managerList)) {
            for (RiskControlManager manager : managerList) {
                // 拒绝号码购买----风控校验
                String riskControlDesc = manager.getRiskControlDesc();
                if (StringUtils.isNotBlank(riskControlDesc)) {
                    String[] splitPhone = riskControlDesc.split(",");
                    for (String thatLimitPhone : splitPhone) {
                        if (StringUtils.isNotBlank(user.getMobile()) && user.getMobile().startsWith(thatLimitPhone)) {
                            return RiskControlRuleEnum.TicketPurchaseProhibited;
                        }
                    }
                }
            }
        }
        RiskControlUsers riskControlUsers = new RiskControlUsers();
        riskControlUsers.setPayerId(user.getMid());
        riskControlUsers.setMerchantGoodsType(merchantGoodsType);
        List<RiskControlUsers> riskControlUsers1 = riskControlUsersService.listAll(riskControlUsers);
        if (CollectionUtils.isEmpty(riskControlUsers1)) {
            return null;
        }
        // 如果有黑名单限制--黑名单限制
        for (RiskControlUsers controlUsers : riskControlUsers1) {
            if (controlUsers.getRiskControlLimitType().equals(RiskControlRuleEnum.TicketPurchaseProhibited.getCode())) {
                return RiskControlRuleEnum.TicketPurchaseProhibited;
            }
        }
        // 如果没有黑名单限制--灰名单限制
        Integer riskControlLimitType = riskControlUsers1.get(0).getRiskControlLimitType();
        RiskControlRuleEnum[] values = RiskControlRuleEnum.values();
        for (RiskControlRuleEnum ruleEnum : values) {
            if (ruleEnum.getCode().equals(riskControlLimitType)) {
                return ruleEnum;
            }
        }
        return null;
    }

风控后置--决策

 /**
     * 风控----后置校验
     *
     * @param user user
     * @return
     * @throws Exception
     */
    public void afterBuyingTicketsHandle(String merchantGoodsType, User user) {
        // 商品维度的风控策略加载||已启用的加商品类型过滤+优先级排序
        List<RiskControlManager> managerList = riskControlManagerService.getByMerchantGoodsType(merchantGoodsType);
        if (CollectionUtils.isEmpty(managerList)) {
            return;
        }
        RiskControlDecisionsFilterChain filterChain = RiskControlDecisionsFilterChain.getInstance();
        // 获取用户风控信息{已经SQL的排序修改按照序列的--优先级排序}
        for (RiskControlManager manager : managerList) {
            Long mid = manager.getMid();
            // 获取风控惩罚机制
            RiskControlRestrictive riskControlRestrictive = new RiskControlRestrictive();
            riskControlRestrictive.setRiskControlRuleId(mid);
            List<RiskControlRestrictive> restrictives = riskControlRestrictiveService.listAll(riskControlRestrictive);
            if (CollectionUtils.isEmpty(restrictives)) {
                // 如果没有--风控策略
                continue;
            }
            // 风控排序 -----最小条件满足优先{天--小时---分钟}
            Comparator<RiskControlRestrictive> comparator = new Comparator<RiskControlRestrictive>() {
                @Override
                public int compare(RiskControlRestrictive o1, RiskControlRestrictive o2) {
                    // 时间间隔单位
                    Integer timeIntervalUnitV1 = o1.getTimeIntervalUnit();
                    Integer timeIntervalUnitV2 = o2.getTimeIntervalUnit();
                    return timeIntervalUnitV1 - timeIntervalUnitV2;
                }
            };
            restrictives.sort(comparator);
            // 校验用户风控策略满足条件{过滤器链路使用---用户封印{无法根据IP、身份证、电话号码封印}}
            for (RiskControlRestrictive restrictive : restrictives) {
                // 获取限制类型---下单的限定
                if (restrictive.getOperationType().equals(RiskControlRestrictiveOperationEnum.PlaceAnOrder.getCode())) {
                    // 风控决策引擎--启动{决策目标风控行为:开启所有的风控链决策--使用 execute 方法}
                    boolean execute = filterChain.executeDefaultHandler(user, manager, restrictive, riskControlLimitAccountFilterChain);
                    if (execute) {
                        // 满足风控条件任意一项:黑白名单入库成功---------风控过滤链释放
                        return;
                    }
                } else if (restrictive.getOperationType().equals(RiskControlRestrictiveOperationEnum.Refund.getCode())) {
                    // 获取限制类型---退款的限定--todo

                }
            }
        }
    }

风控决策引擎管理--总线

/**
 * packageName com.cztech.platform.transaction.common.riskControl
 *
 * @author GuoTong
 * @version JDK 8
 * @className RiskControlDecisionsFilterChain
 * @date 2024/5/9
 * @description 风控决策引擎
 */
public class RiskControlDecisionsFilterChain {

    private Logger log = LoggerFactory.getLogger(RiskControlDecisionsFilterChain.class);

    /**
     * 标识===过滤器所属限制类型
     * 子类必须重写
     *
     * @return int
     */
    protected int getThisRestrictiveType() {
        return 0;
    }

    /**
     * 风控决策过滤器链
     */
    public static List<RiskControlDecisionsFilterChain> filterChains = new ArrayList<>();


    private static RiskControlDecisionsFilterChain chain = null;

    public static RiskControlDecisionsFilterChain getInstance() {
        if (chain == null) {
            synchronized (RiskControlDecisionsFilterChain.class) {
                if (chain == null) {
                    chain = new RiskControlDecisionsFilterChain();
                }
            }
        }
        return chain;
    }

    /**
     * 风控决策引擎执行入口
     *
     * @param user        用户ID
     * @param manager     风控管理器
     * @param restrictive 风控限制
     * @author GuoTong
     */
    public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
        log.error("风控决策引擎执行-----进入执行---------");
        for (RiskControlDecisionsFilterChain filterChain : filterChains) {
            // 获取限制类型----只运行当前限制的决策事件
            if (restrictive.getRestrictiveType().equals(filterChain.getThisRestrictiveType())) {
                // 获取执行链路的结果
                boolean respWasSuccess = filterChain.execute(user, manager, restrictive);
                // 已经执行成功,则过滤器链终止
                if (respWasSuccess) {
                    return true;
                }
            }

        }
        log.error("风控决策引擎执行-----执行结束---------");
        return false;
    }

    protected int countRiskControlLimit(String startTime, String endTime, User user) {
        return 0;
    }

    /**
     * 保存用户--进入限制桶
     * 子类必须重写
     *
     * @param riskControlUsers riskControlUsers
     */
    protected void saveLimitUser(RiskControlUsers riskControlUsers) {
    }

    protected ReleaseTimeSetting getReleaseTimeSetting() {
        return null;
    }

    /**
     * 限制名单限定--决策----通用业务逻辑
     *
     * @param user        userId
     * @param manager     manager
     * @param restrictive restrictive
     */
    protected boolean executeDefaultHandler(User user, RiskControlManager manager, RiskControlRestrictive restrictive, RiskControlDecisionsFilterChain targetFilterChain) {
        // 获取时间间隔
        Long timeInterval = restrictive.getTimeInterval();
        // 获取时间间隔单位
        Integer timeIntervalUnit = restrictive.getTimeIntervalUnit();
        // 获取限制次数
        Long quantity = restrictive.getQuantity();
        // 计算限制区间:当前时间  -- 开始时间
        LocalDateTime now = LocalDateTime.now();
        String endTime = LocalDateTimeUtil.format(now, RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
        String startTime = null;
        if (timeIntervalUnit.equals(RiskControlRestrictiveTimeEnum.Minute.getCode())) {
            // 如果是分钟
            startTime = LocalDateTimeUtil.format(now.minusMinutes(timeInterval), RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
        } else if (timeIntervalUnit.equals(RiskControlRestrictiveTimeEnum.Hours.getCode())) {
            // 如果是小时
            startTime = LocalDateTimeUtil.format(now.minusHours(timeInterval), RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
        } else {
            // 天
            startTime = LocalDateTimeUtil.format(now.minusDays(timeInterval), RuleCommonUtils.YYYY_MM_DD_HH_MM_SS);
        }
        // 查询当前情况下的下单数量
        int thatOrderNum = targetFilterChain.countRiskControlLimit(startTime, endTime, user);
        if (thatOrderNum >= quantity) {
            log.error("用户{}在{}到{}期间下单次数超过限制次数{}", user.getMid(), startTime, endTime, quantity);
            // 封印该用户--todo{惩罚机制}
            RiskControlUsers riskControlUsers = new RiskControlUsers();
            riskControlUsers.setStateId(1);
            riskControlUsers.setCreateTime(new Date());
            riskControlUsers.setMerchantGoodsType(manager.getMerchantGoodsType());
            riskControlUsers.setRiskControlDetailLimit(manager.getRiskControlDetailLimit());
            riskControlUsers.setRiskControlLimitType(manager.getRiskControlRule());
            ReleaseTimeSetting releaseTimeSetting = targetFilterChain.getReleaseTimeSetting();
            if (releaseTimeSetting != null) {
                riskControlUsers.setReleaseTimeDay(releaseTimeSetting.getNowDay());
            } else {
                riskControlUsers.setReleaseTimeDay(7);
            }
            riskControlUsers.setRiskControlCardType("身份证");
            riskControlUsers.setIdCard(user.getIdentityNumber());
            // 黑名单|白名单
            riskControlUsers.setRiskControlTypeName(manager.getRiskControlRestrictive());
            riskControlUsers.setUserName(user.getName());
            riskControlUsers.setPhone(user.getMobile());
            riskControlUsers.setIpAddres(user.getLastLoginIP());
            riskControlUsers.setLimitTime(new Date());
            riskControlUsers.setDescLimit(manager.getRiskControlName());
            riskControlUsers.setPayerId(user.getMid());
            log.error("风控----管控---用户信息------>:" + JSONObject.toJSONString(riskControlUsers));
            targetFilterChain.saveLimitUser(riskControlUsers);
            return true;
        }
        return false;
    }

}

风控链----01风控决策引擎---限制账户

/**
 * packageName com.cztech.platform.transaction.common.riskControl
 *
 * @author GuoTong
 * @version JDK 8
 * @className RiskControlDecisionsFilterChain
 * @date 2024/5/9
 * @description 风控决策引擎---限制账户
 */
@Component
public class RiskControlLimitAccountFilterChain extends RiskControlDecisionsFilterChain {

    private Logger log = LoggerFactory.getLogger(RiskControlLimitAccountFilterChain.class);

    @Autowired
    private RiskControlUsersService riskControlUsersService;

    @Autowired
    private OrderService orderService;


    /**
     * 标识===过滤器所属限制类型
     * @return int
     */
    @Override
    protected int getThisRestrictiveType() {
        return RiskControlRestrictiveEnum.LimitAccount.getCode();
    }

    /**
     * 保存用户--进入限制桶
     * 子类必须重写
     * @param riskControlUsers riskControlUsers
     */
    protected void saveLimitUser(RiskControlUsers riskControlUsers) {
        riskControlUsersService.save(riskControlUsers);
    }

    /**
     * 构造函数---注册到过滤器链
     */
    public RiskControlLimitAccountFilterChain() {
        filterChains.add(this);
    }

    /**
     * 风控决策引擎执行入口--限制账户
     *
     * @param user,       用户ID
     * @param manager     风控管理器
     * @param restrictive 风控限制
     * @author GuoTong
     */
    @Override
    public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
        boolean restrictiveFlag = false;
        try {
            restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
        } catch (Exception e) {
            log.error("RiskControlLimitAccountFilterChain execute error:", e);
        }
        return restrictiveFlag;
    }

    @Override
    protected int countRiskControlLimit(String startTime, String endTime, User user) {
       return orderService.countRiskControlLimit(startTime, endTime, user.getMid());
    }

    @Override
    protected ReleaseTimeSetting getReleaseTimeSetting() {
        return riskControlUsersService.selectReleaseTimeData();
    }

}

风控链----02风控决策引擎---限制身份证

/**
 * packageName com.cztech.platform.transaction.common.riskControl
 *
 * @author GuoTong
 * @version JDK 8
 * @className RiskControlDecisionsFilterChain
 * @date 2024/5/9
 * @description 风控决策引擎---限制身份证
 */
@Component
public class RiskControlLimitIdCardFilterChain extends RiskControlDecisionsFilterChain {

    private Logger log = LoggerFactory.getLogger(RiskControlLimitIdCardFilterChain.class);


    @Autowired
    private RiskControlUsersService riskControlUsersService;

    @Autowired
    private OrderService orderService;

    /**
     * 标识===过滤器所属限制类型
     * @return int
     */
    @Override
    protected int getThisRestrictiveType() {
        return RiskControlRestrictiveEnum.LimitIdCard.getCode();
    }

    /**
     * 构造函数---注册到过滤器链
     */
    public RiskControlLimitIdCardFilterChain() {
        filterChains.add(this);
    }

    /**
     * 风控决策引擎执行入口--限制身份证
     *
     * @param user,       用户ID
     * @param manager     风控管理器
     * @param restrictive 风控限制
     * @author GuoTong
     */
    @Override
    public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
        boolean restrictiveFlag = false;
        try {
            restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
        } catch (Exception e) {
            log.error("RiskControlLimitAccountFilterChain execute error:", e);
        }
        return restrictiveFlag;
    }

    @Override
    protected int countRiskControlLimit(String startTime, String endTime, User user) {
        String identityNumber = user.getIdentityNumber();
        if (StringUtils.isBlank(identityNumber)) {
            return 0;
        }
        return orderService.countRiskControlFiledLimit(startTime, endTime, identityNumber);
    }


    /**
     * 保存用户--进入限制桶
     * 子类必须重写
     * @param riskControlUsers riskControlUsers
     */
    protected void saveLimitUser(RiskControlUsers riskControlUsers) {
        riskControlUsersService.save(riskControlUsers);
    }

    @Override
    protected ReleaseTimeSetting getReleaseTimeSetting() {
        return riskControlUsersService.selectReleaseTimeData();
    }


}

风控链----03风控决策引擎---限制账IP

/**
 * packageName com.cztech.platform.transaction.common.riskControl
 *
 * @author GuoTong
 * @version JDK 8
 * @className RiskControlDecisionsFilterChain
 * @date 2024/5/9
 * @description 风控决策引擎---限制IP
 */
@Component
public class RiskControlLimitIpFilterChain extends RiskControlDecisionsFilterChain {

    private Logger log = LoggerFactory.getLogger(RiskControlLimitIpFilterChain.class);


    @Autowired
    private RiskControlUsersService riskControlUsersService;

    @Autowired
    private OrderService orderService;

    /**
     * 构造函数---注册到过滤器链
     */
    public RiskControlLimitIpFilterChain() {
        filterChains.add(this);
    }
    /**
     * 标识===过滤器所属限制类型
     * @return int
     */
    @Override
    protected int getThisRestrictiveType() {
        return RiskControlRestrictiveEnum.LimitIp.getCode();
    }

    /**
     * 风控决策引擎执行入口--限制IP
     *
     * @param user,       用户ID
     * @param manager     风控管理器
     * @param restrictive 风控限制
     * @author GuoTong
     */
    @Override
    public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
        boolean restrictiveFlag = false;
        try {
            restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
        } catch (Exception e) {
            log.error("RiskControlLimitAccountFilterChain execute error:", e);
        }
        return restrictiveFlag;
    }

    @Override
    protected int countRiskControlLimit(String startTime, String endTime, User user) {
        String lastLoginIP = user.getLastLoginIP();
        if (StringUtils.isBlank(lastLoginIP)) {
            return 0;
        }
        return orderService.countRiskControlIPLimit(startTime, endTime, lastLoginIP);
    }

    /**
     * 保存用户--进入限制桶
     * 子类必须重写
     * @param riskControlUsers riskControlUsers
     */
    protected void saveLimitUser(RiskControlUsers riskControlUsers) {
        riskControlUsersService.save(riskControlUsers);
    }
    @Override
    protected ReleaseTimeSetting getReleaseTimeSetting() {
        return riskControlUsersService.selectReleaseTimeData();
    }

}

风控链----04风控决策引擎---限制手机

/**
 * packageName com.cztech.platform.transaction.common.riskControl
 *
 * @author GuoTong
 * @version JDK 8
 * @className RiskControlDecisionsFilterChain
 * @date 2024/5/9
 * @description 风控决策引擎---限制手机号
 */
@Component
public class RiskControlLimitPhoneFilterChain extends RiskControlDecisionsFilterChain {

    private Logger log = LoggerFactory.getLogger(RiskControlLimitPhoneFilterChain.class);


    @Autowired
    private RiskControlUsersService riskControlUsersService;

    @Autowired
    private OrderService orderService;

    /**
     * 标识===过滤器所属限制类型
     * @return int
     */
    @Override
    protected int getThisRestrictiveType() {
        return RiskControlRestrictiveEnum.LimitPhone.getCode();
    }

    /**
     * 构造函数---注册到过滤器链
     */
    public RiskControlLimitPhoneFilterChain() {
        filterChains.add(this);
    }

    /**
     * 风控决策引擎执行入口--限制手机号
     *
     * @param user,       用户ID
     * @param manager     风控管理器
     * @param restrictive 风控限制
     * @author GuoTong
     */
    @Override
    public boolean execute(User user, RiskControlManager manager, RiskControlRestrictive restrictive) {
        boolean restrictiveFlag = false;
        try {
            restrictiveFlag = super.executeDefaultHandler(user, manager, restrictive,this);
        } catch (Exception e) {
            log.error("RiskControlLimitAccountFilterChain execute error:", e);
        }
        return restrictiveFlag;
    }

    @Override
    protected int countRiskControlLimit(String startTime, String endTime, User user) {
        String mobile = user.getMobile();
        if (StringUtils.isBlank(mobile)) {
            return 0;
        }
        return orderService.countRiskControlPhoneLimit(startTime, endTime, mobile);
    }

    /**
     * 保存用户--进入限制桶
     * 子类必须重写
     * @param riskControlUsers riskControlUsers
     */
    protected void saveLimitUser(RiskControlUsers riskControlUsers) {
        riskControlUsersService.save(riskControlUsers);
    }

    @Override
    protected ReleaseTimeSetting getReleaseTimeSetting() {
        return riskControlUsersService.selectReleaseTimeData();
    }

}

posted on 2024-05-10 11:30  白嫖老郭  阅读(51)  评论(0编辑  收藏  举报

导航