二级制的巧用-签角的等级校验

353 阅读2分钟

需求简述

对于一次授信的尽职调查操作,需要选择多个签角人员进行签角确认。根据授信的金额不同,选择的签角人员等级需要满足对应的规则才能进行签角操作,所以我们需要对选择的签角人员和对应金额进行一个校验。签角人员最低等级为10,数字越小代表等级越高.

  1. 以下是对不同金额范围的具体签角规则.
金额(单位:亿)级别(签角人员级别)
6<X3级及以上
3<X≤64级及以上
1<X≤35级及以上
0.5<X≤16级及以上
0.3<X≤0.57级及以上
X≤0.38级及以上
  1. 两个相同的低级别人员的权限可以组合成一个高一级的人员权限.如:两个7级人员签角,等于一个6级人员签角

  2. 详细例子

组成情形享有的权限
7级+7级6级权限
6级+2个7级5级权限
2个7级+2个7级5级权限

需求分析

这个需求的实现有两个点需要解决:

  1. 多个人员的等级如何组合换算
  2. 判断换算后的等级权限是否满足对应金额的签角权限.

显然,第一个点是重难点.只要第一个换算出来了,第二点按部就班判断即可.

设计思路

两个相同的等级相加可以当做一个高一级的等级。根据这个特性,可以用2进制的加法去模拟这个过程和结构。因为二级制就是1+1=2,但是满2进1就类似两个低位相加变成一个高位.例如二进制数的01+01=10.需求中等级由低到高,代表的数字是由大到小。共有10个等级,所以以一个10位的二进制数0B1000000000为基础,向右移位,移动(level-1)位,获得对应等级的二级制数.

公式:F(level)=0B1000000000>>(level-1);

下面的表格就是等级映射到一个二进制数的过程和结果

等级(level)操作过程F(level)=0B1000000000>>(level-1);二级制数
10B1000000000>>0;0B1000000000
20B1000000000>>1;0B0100000000
30B1000000000>>2;0B0010000000
40B1000000000>>3;0B0001000000
50B1000000000>>4;0B0000100000
60B1000000000>>5;0B0000010000
70B1000000000>>6;0B0000001000
80B1000000000>>7;0B0000000100
90B1000000000>>8;0B0000000010
100B1000000000>>9;0B0000000001

举例,判断3个6级和2个7级的签角人员是否有一个4级的权限。

0B0000001000(7级)+0B0000001000(7级)+0B0000010000(6级)+0B0000010000(6级)+0B0000010000(6级)=0B0001000000(四级)

核心代码

private boolean checkLevel(Long amount,List<Integer> signLevelList) {
    LOGGER.info("开始检查A角的签角等级");
    Integer maxLevel = 0B1000000000;
    Integer totalLevel = 0;
    for (int i = 0; i < signLevelList.size(); i++) {
        Integer signUserLevel = signLevelList.get(i);
        Integer refLevel = maxLevel >> (signUserLevel - 1);
        totalLevel += refLevel;
    }
    Long W = 10000*100L;//单位分
    LOGGER.info("签角项目金额:{}", amount);
    if (amount <= 3000 * W) {
        return totalLevel >= (maxLevel >> (8 - 1));//小于0.3亿 8级以上
    } else if (amount <= 5000 * W) {
        return totalLevel >= (maxLevel >> (7 - 1));//小于0.5亿 7级以上
    } else if (amount <= 10000 * W) {
        return totalLevel >= (maxLevel >> (6 - 1));//小于1.0亿 6级以上
    } else if (amount <= 30000 * W) {
        return totalLevel >= (maxLevel >> (5 - 1));//小于3.0亿 5级以上
    } else if (amount <= 60000 * W) {
        return totalLevel >= (maxLevel >> (4 - 1));//小于5.0亿 4级以上
    } else if (amount > 60000 * W) {
        return totalLevel >= (maxLevel >> (3 - 1));//小于6.0亿 3级以上
    }
    return false;
}

扩展思考

假如规则变成了3个低等级可以换算成一个高等级的,是不是也可以用同样的思路呢?