多订单多支付方式分配金额问题

算是个面试题吧,问题描述是这样:多个业务订单,对应一个支付单进行支付,支付时使用了组合支付。那么没个订单分配到的支付方式及金额如何计算。 一共三个支付方式组合A,B,C金额分辨占100,100,80. 一共两个订单1订单金额80,2订单金额200. 分配后,产生4份订单和支付方式不同的数据。 画个图明了一点: 多订单多支付方式分配金额问题
文章图片
问题抽象: 我们发现图一和图二重叠一下不就是图三的分配结果嘛。 可是代码似乎没这么简单就可以操作。 又将问题拟物化,便于理解,将支付方式组合可以想象成不通种类的杯子,而订单组合是不同种类的酒,现在要把酒放到辈子里去。每倒一次算一个订单和支付方式组合的数据。 第一次:1号酒开始到,在A杯子里都倒不满,直接全部倒光。数据为1+A+80 第二次:2号酒倒入A剩下的20雨量满了。数据为2+A+20 第三次:2号酒倒入B杯子,倒满100,2号酒还剩80。数据为2+B+100 第四次:2号酒倒入C杯子,倒满也到光了。数据为2+C+80 我们发现这四次操作就是遍历订单组合的数据,依次去占有剩余支付金额的数据。而2,3,4次是一个迭代的代码过程。 如果你刚好有时间,可以自己用熟悉的代码实现一下,贴出来讨论讨论。

所以一种实现如下:

public class ItemDistribution {private List cupList = new ArrayList<>(); /** * 初始化 * @param list */ public ItemDistribution(List list) { if(list == null || list.size()<=0){ return; } Integer start = 0; Integer end = 0; for(Item item : list){ end = start + item.amount; Entry entry = new Entry(start, end, item.payMethod); start = end; cupList.add(entry); } }/** * 分配 * @param orderIdAmountMap * @return */ public List getOrderInfoItemList(Map orderIdAmountMap){ if(cupList == null){ return null; } List cupTransferList = cupList; List returnItems = new ArrayList<>(); for (Map.Entry orderIdAmountEntry : orderIdAmountMap.entrySet()) { Integer orderId = orderIdAmountEntry.getKey(); Integer orderAmount = orderIdAmountEntry.getValue(); buildItem(orderId, orderAmount, cupTransferList, returnItems); } return returnItems; }/** * 单个cup分配 * @param orderId * @param orderAmount * @param cupList * @param returnItems */ private void buildItem(Integer orderId, Integer orderAmount, List cupList, List returnItems) { if(IntegerUtil.isZero(orderAmount) || orderId == null){ return; }Entry cup = getLatestCup(cupList); if(cup == null){ return; } Integer remain = cup.end - cup.index; Item item = null; if(remain > orderAmount){ cup.index = cup.start + orderAmount; item = new Item(orderId, orderAmount, cup.payMethod); returnItems.add(item); return; }else{ cup.index = cup.end; item = new Item(orderId, remain, cup.payMethod); returnItems.add(item); orderAmount = orderAmount - remain; }buildItem(orderId, orderAmount, cupList, returnItems); }/** * 获得可用的cup * @param cupTransferList * @return */ private Entry getLatestCup(List cupTransferList){ for(Entry cup : cupTransferList){ if(!IntegerUtil.isEquals(cup.index, cup.end)){ return cup; } } return null; }public class Entry{ private Integer start; private Integer end; private Integer index = 0; private Integer payMethod; public Entry(Integer start, Integer end, Integer payMethod) { this.start = start; this.index = start; this.end = end; this.payMethod = payMethod; } }public static void main(String[] args) { List list = new ArrayList(); Item OrderPayInfoItem1 = new Item(100,1); Item OrderPayInfoItem2 = new Item(100,2); Item OrderPayInfoItem3 = new Item(80,3); list.add(OrderPayInfoItem1); list.add(OrderPayInfoItem2); list.add(OrderPayInfoItem3); ItemDistribution itemDistribution = new ItemDistribution(list); Map map = new HashMap<>(); map.put(1001, 80); map.put(1002, 200); List returnList = itemDistribution.getOrderInfoItemList(map); } }

【多订单多支付方式分配金额问题】

    推荐阅读