优先级退金额 小算法

发布时间 2023-09-14 15:10:53作者: 川流不息&

优先级退金额 小算法

背景 :用户需要 退钱 按照对应的规则优先级 退,例如 用户最大要退 50 ,这个时候 让优先级 现金 福利卡 礼包 这几个优先退 其他次之。例如 用户 混合支付 用了 20 现金 20 福利卡 20 礼包,这个时候要退 50,应该是 依次 退 现金 20 福利卡 20 礼包 10

思路
  1. 首先获取 用户每种 类型的最大 退款数据。

  2. 让优先级 获取最大 退款数据,获取到 存在新的 List 里面 (这样就保证顺序) ,在把 其他的数据 不相关的数据 排除 优先级的 加入。

  3. 遍历 新的List 依次 相减,并且记录到 对应的相减的结果,并且判断 是不是已经足够了,把结果加入到新的List 。

showcode
/**
 * 运费优先级计算
 * @param workOrderMaximumRefundTO
 */
private void setUserFreightCostInfoList(WorkOrderMaximumRefundTO workOrderMaximumRefundTO) {
    BigDecimal maxUserFreight = workOrderMaximumRefundTO.getMaxUserFreight();
    List<CostInfoTO> maxCostInfoTOList = workOrderMaximumRefundTO.getMaxCostInfoTOList();
    // 默认优先退现金、其次礼品余额、最后福利卡券
    // CASH GIFT_BALANCE WELFARE_CARD
    Map<String, CostInfoTO> costInfoTOMap = maxCostInfoTOList
            .stream()
            .collect(Collectors.toMap(e -> e.getType(), t -> t));

    CostInfoTO cashCostInfoTO = costInfoTOMap.get(CostTypeEnum.CASH.getCode());
    CostInfoTO giftCostInfoTO = costInfoTOMap.get(CostTypeEnum.GIFT_BALANCE.getCode());
    CostInfoTO cardCostInfoTO = costInfoTOMap.get(CostTypeEnum.WELFARE_CARD.getCode());
    List<String> exists = Lists.newArrayList(CostTypeEnum.CASH.getCode(),CostTypeEnum.GIFT_BALANCE.getCode(),CostTypeEnum.WELFARE_CARD.getCode());

    List<CostInfoTO> costInfoTOList = Lists.newArrayList();
    if(null != cashCostInfoTO){
        costInfoTOList.add(cashCostInfoTO);
    }
    if(null != giftCostInfoTO){
        costInfoTOList.add(giftCostInfoTO);
    }
    if(null != cardCostInfoTO){
        costInfoTOList.add(cardCostInfoTO);
    }
    costInfoTOMap.forEach((k,v)->{
        if(!exists.contains(k)){
            costInfoTOList.add(v);
        }
    });

    if(CollectionUtils.isEmpty(costInfoTOList)) {
        List<CostInfoTO> costInfoTOS = maxCostInfoTOList.stream().map(e -> {
            CostInfoTO costInfo = new CostInfoTO();
            costInfo.setName(e.getName());
            String type = e.getType();
            costInfo.setType(type);
            costInfo.setUseNum(BigDecimal.ZERO);
            return costInfo;
        }).collect(Collectors.toList());
        workOrderMaximumRefundTO.setUserFreightCostInfoList(costInfoTOS);
        return;
    }
    boolean flag = false;
    List<CostInfoTO> costInfoTOS = new ArrayList<>();

    for (int i = 0; i < costInfoTOList.size(); i++) {
        CostInfoTO newCostInfoTO = new CostInfoTO();
        CostInfoTO costInfoTO = costInfoTOList.get(i);

        newCostInfoTO.setName(costInfoTO.getName());
        newCostInfoTO.setType(costInfoTO.getType());
        BigDecimal useNum = costInfoTO.getUseNum();
        //是否已经有足够
        if(flag){
            newCostInfoTO.setUseNum(BigDecimal.ZERO);
            costInfoTOS.add(newCostInfoTO);
            continue;
        }
        // 如果现金足够
        if(useNum.compareTo(maxUserFreight) >= CommonConstants.ZERO){
            flag = true;
            newCostInfoTO.setUseNum(maxUserFreight);
        }else {
            // 减去现金 剩余多少
            newCostInfoTO.setUseNum(useNum);
            maxUserFreight = NumberUtil.sub(maxUserFreight, useNum);
        }
        costInfoTOS.add(newCostInfoTO);
    }
    workOrderMaximumRefundTO.setUserFreightCostInfoList(costInfoTOS);

}

测试结果

用户运费信息[CostInfoTO(name=现金, type=CASH, useNum=12), CostInfoTO(name=福利卡, type=WELFARE_CARD, useNum=10), CostInfoTO(name=福利礼包, type=WELFARE_PACKAGE, useNum=10), CostInfoTO(name=能量, type=POWER, useNum=8)]

换成 15 算

用户运费信息[CostInfoTO(name=现金, type=CASH, useNum=12), CostInfoTO(name=福利卡, type=WELFARE_CARD, useNum=3), CostInfoTO(name=福利礼包, type=WELFARE_PACKAGE, useNum=0), CostInfoTO(name=能量, type=POWER, useNum=0)]

总结:有一点难度。