经过前面一段时间的学习,相信你对类目、属性、商品、促销、库存、购物车的业务和设计有了一定的了解。上一章节我们还讨论了一些订单设计的秘密。
下单之前的阻碍终于扫清了,相信你对订单整个业务模型已经有了比较深刻的认知。今天是订单的第四个章节,猿人工厂君打算和你聊一聊订单流程的一些事情。
提及订单下单流程的话题,不少朋友会觉得似乎之前已经讲过了,毕竟结算页面的生成,从某种程度上来看,就是生成订单数据的一个过程。
然而这个说法正确与否,我们暂时不做讨论,订单接单和结算页生成数据,或许还是有些区别。从职责上讲,结算页展现了订单的清单,但是还有很多信息并没有完全展示出来。而且结算页生成的数据,难道订单就可以直接使用吗?
我们就分析一个简单的场景吧。比如某个用户在购物车勾选了一些商品,然后选择结算,结算页经过一系列复杂的业务计算之后,展示出了订单结算的信息。但是用户并没有提交订单,而是玩耍了好一会儿再点提交按钮。在玩耍的过程中,订单中的各种信息都会发生变化,按照这些错误的信息下单,那么订单的信息就是错误的。
这种场景如果成功了可以引发很多纠纷——比如,有促销优惠时价格页面显示很低,但是到下单时却没有促销了,价格升高,竞争对手可以利用这一点分分钟玩耍掉你的站点。再比如说,库存发生了变化,如果不做一些检查,恶意的用户利用这个漏洞,多开页面,也能恶意下单成功,导致订单超卖。
所以,订单下单的一个业务内部的职责,就很清晰了——确保订单数据准确有效。
那怎样才能确保订单数据准确有效呢?我们可以先画个图来分析一下。
看上去很复杂吧?确实如此噢结算页的数据必须重新计算,不能以页面提交的为准,尤其是金额。简单的来讲,基础验证主要是验证结算页提交的金额数据之间的关系是否一致,订单级数据和sku级数据的汇总是否能对齐。然后就是数据合法性校验了,比如长度,比如特殊字符。
剩余的校验,都需要经过业务系统的查询,用户、商家、类目、商品、SKU、价格、运费、优惠券都必须经过数据查询、重新计算得出。因为用户在结算页填写订单的时候,以上数据均可能发生变化,以上有任一一项数据不合法,都是不可以下单的。
也许你会问,为什么不校验库存状态了?没库存下单,不是会发生超卖现象吗?这个问题问得很好,但是对于下单来讲,不会再校验库存了,直接预占就好。因为有库存才能预占成功,没有库存自然会预占失败,再次使用库存查询,是多此一举的。
接下来要做的就是一些扣减工作了,比如库存预占、促销的次数扣减、优惠券的扣减。我们继续完善下流程图吧。
数据校验和次数扣减做完了,剩余的流程自然是订单入库保存数据了。不过大家可以再看看,上面的流程是否就是正确的呢?我们说假如啊,促销扣次成功了,优惠券扣次失败了,怎么处理呢?促销扣减的次数,不应该回退用户呢?
再比如一切成功了,最后数据库发生问题了,又怎么来处理呢?前边儿的扣减操作是否需要回退呢?所以呀,问题没有那么简单。从流程图上来看,下单流程已经很复杂了,而且那些流程都可能面临数据的查询工作,可能在性能上导致一些问题,有没有办法优化一下呢?办法还是有的,我们可以把这些流程大致归类为一个粗浅的模型。
从订单下单的整体业务流程来说,主要可以抽象为基本数据校验,业务数据校验,订单扣次、订单入库,和失败回退业务几个方便。这几个业务流程其实是相互独立的,而且每个流程内部是可以同时进行的,只要一个最终结果去决定下一步要做什么就好了。
嗯……同时进行的事情怎么来做呢,自然是异步去做就好了,为了性能的保障这也是没办法的事情。有了模型自然好办事情了。重新画一个清晰一点的图相信你就明白了。
以上就是订单下单流程的设计了,到目前为止,猿设计系列算是大功告成了。猿设计系列主要针对电商系统的黄金业务流程,做了一些设计。猿设计系列的目的,在于帮助大家提高挖掘需求和设计流程的能力,相对来说和详细设计是由很大距离的。
当然,还有一些比较重要的业务设计没有讲到,比如支付,比如售后,比如生产流程。这些在设计阶段暂时不做讲授了,不过在后续的coding系列中,会给出对应的详细设计以及实现。
从下一个章节开始,我们将进入实战阶段,猿人君将手把手带你来实现之前的设计。