详解Magento2订单号生成机制
Magento2里的订单号,由 Quote 对象的reserveOrderId方法生成:
Magento\Quote\Model\Quote::reserveOrderId()
/** * Generate new increment order id and associate it with current quote * * @return $this */ public function reserveOrderId() { if (!$this->getReservedOrderId()) { $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this)); } else { //checking if reserved order id was already used for some order //if yes reserving new one if not using old one if ($this->orderIncrementIdChecker->isIncrementIdUsed($this->getReservedOrderId())) { $this->setReservedOrderId($this->_getResource()->getReservedOrderId($this)); } } return $this; }
在用户提交订单时,会调用该方法。具体会存在三种情况:
-
如果 Quote 对象的 reserved_order_id 字段存在, 未被其他订单使用,则 reserved_order_id 字段保持不变
-
如果 Quote 对象的 reserved_order_id 字段存在,但是已经被别的订单使用了,则重新生成新的订单号
-
如果 Quote 对象的 reserved_order_id 字段为空,则生成新的订单号
如论哪种情况,在生成订单号的时候,都会调用 Magento\Quote\Model\ResourceModel\Quote::getReservedOrderId() 方法:
1 /** 2 * Get reserved order id 3 * 4 * @param \Magento\Quote\Model\Quote $quote 5 * @return string 6 */ 7 public function getReservedOrderId($quote) 8 { 9 return $this->sequenceManager->getSequence( 10 \Magento\Sales\Model\Order::ENTITY, 11 $quote->getStoreId() 12 ) 13 ->getNextValue(); 14 }
该方法会根据 entity_type 和 store_id, 查询 sales_sequence_meta 表中记录的序号表表名:
对于 Default Store View, Store Id = 1:
select * from sales_sequence_meta where entity_type = "order" and store_id = 1;
查询结果如下:
可以看到订单序号表是 sequence_order_1
每次需要生成订单号时,会先在该表插入一条记录,再获取最新插入的值, 我们称这个值为序号
获得序号后,需要将该序号乘以递增步长再格式化为9位数字(不足9位用0补全)
还需要获取订单号递增步长、前缀和后缀:
select * from sales_sequence_profile where meta_id = 5;
查询结果如下:
递增步长 为 sales_sequence_profile 表中 step 的值,默认值为 1,也就是说默认情况下,新订单号每次递增1
前缀 为 sales_sequence_profile 表中 prefix 的值, 默认值为当前的 store id
后缀 为 sales_sequence_profile 表中 suffix 的值, 默认为空
如果想要修改订单号前缀、后缀,修改该表中对应记录即可
最后,在得到了订单序号、前缀、后缀后,通过公式
完整订单号 = 前缀 + 订单序号 + 后缀
就可以获得最终的订单号了
原文链接:详解Magento2订单号生成机制