2019年7月2日16:43:41
订单号设计,这个功能说复杂也复杂,简单也简单
先说一下比较基础的做法,
例如
$orderKey = uniqid(date('Ymd'));
pp($orderKey);
201907205d32de71e6002
利用php自带的生成唯一ID 方法,生成带日期的唯一订单号,并发情况下不会重复,经过测试过,连续写10000次不会重复
请不要使用随机数函数,因为会重复
设计思路的话有几种:
1,有意义的位数的订单号
日期+订单来源+支付类型+业务标记+用户ID+自递增数
这样就比较一目了然,也是很常见的 设计方案
2,可以反解的订单号,本身一眼是看不出你订单的意义
可以通过反解订单知道此订单的情况,这不是和方案1一样吗?方案一会暴露系统的订单设计意义,方案可能会涉及到加密等问题,为了数据安全考虑
3,无意义的订单号为了处理并发,有些情况下,为了巨大的并发量会设计一个算法来生产订单号的接口,直接使用
4,使用redis,mysql锁机制做自增数,一个内部调用的一个服务这样然后可以配合任意的前缀
使用mysql做计数器的一个demo
public static function counter($shop_id = 0, $type = null, $need_transaction = 1, $pad_length = 15, $now = null) {
if (empty($type)) {
throw new \Exception('type标签不能为空');
}
if (empty($now)) {
$now = time();
}
/*
* 合同生产需要短一点,根据20190703XXXX的格式,长度为12,再短的话,就会出现一天之内生产333个,可能后期业务会不够用
*/
if ($type == 5) {
$time = date('Ymd', $now);
$pad_length = 11;
} else {
$time = date('Ym', $now);
}
$length = $pad_length - mb_strlen($time);
$tag = self::counter_array($type);
$name = $time . '_' . $tag;
$need_transaction == 1 && DB::beginTransaction();
try {
$Counter = Counter::where('name', $name)->first(['value', 'id']);
if (empty($Counter)) {
//没有就插入
$Counter = new Counter;
$Counter->name = $name;
$Counter->type = $type;
$Counter->tag = $tag;
// $Counter->shop_id = $shop_id;
$Counter->save();
$Counter = Counter::where('name', $name)->first(['value', 'id']);
}
$Counter = $Counter->toArray();
//加锁 防止生成的订单号出错,没有在name上加索引
Counter::where('id', $Counter['id'])->lockForUpdate()->first();
$new_count = (float) $Counter['value'] + 3;
Counter::where('name', $name)->update(['value' => $new_count]);
$string = $time . str_pad($new_count, $length, '0', STR_PAD_LEFT);
$need_transaction == 1 && DB::commit();
return $string;
} catch (\Exception $e) {
$need_transaction == 1 && DB::rollBack();
throw new \Exception($e->getMessage());
}
}
//订单计数器映射数组
public static function counter_array($type = null) {
$array['5'] = 'contract';
$array['10'] = 'sales_order_number';
$array['20'] = 'purchase_order_number';
$array['30'] = 'logistics_order_number';
$array['40'] = 'inbound_order_number';
$array['50'] = 'outbound_order_number';
$array['60'] = 'purchase_point_number';
$array['70'] = 'express_number';
$array['75'] = 'return_express_number';
$array['80'] = 'sale_voucher_number';
$array['90'] = 'batch_number';
$array['100'] = 'purchase_settle_number';
$array['110'] = 'sales_settle_number';
$array['120'] = 'sales_point_number';
$array['130'] = 'k3_pay_number';
if (empty($type)) {
return $array;
}
return $array[$type];
}
标签:name,Counter,订单号,number,设计,array,电商,type
来源: https://www.cnblogs.com/zx-admin/p/11121604.html