177 lines
5.3 KiB
PHP
177 lines
5.3 KiB
PHP
<?php
|
||
|
||
/**
|
||
* @author Any
|
||
* @description KISS
|
||
* @date 2021年6月9日
|
||
* @version 1.0.0
|
||
*
|
||
* _____LOG_____
|
||
*
|
||
*/
|
||
|
||
namespace app\models;
|
||
|
||
use app\components\FlashStorage;
|
||
|
||
class UniqueOrderNo
|
||
{
|
||
const ORDER_TYPE_DEFAULT = '000';
|
||
|
||
const ORDER_TYPE_CASH_USER_WALLET = '010';
|
||
|
||
const ORDER_TYPE_TRANSFER = '020';
|
||
const ORDER_TYPE_PAYMENT_ORDER_UNION = '030';
|
||
const ORDER_TYPE_PAYMENT_ORDER = '031';
|
||
|
||
const ORDER_TYPE_MANUAL_RECHARGE_ORDER = '108';
|
||
|
||
const ORDER_TYPE_MANUAL_RECHARGE_INTEGRAL_ORDER = '208';
|
||
const ORDER_TYPE_INTEGRAL_MALL_ORDER = '300';
|
||
const ORDER_TYPE_BINDING_CARD_ORDER = '701'; //此值在商户侧唯一,用于【4.7分账接收方进件查询】查询申请单的信息
|
||
const ORDER_TYPE_PS_MER_ORDER = '702'; //商户分账单号
|
||
|
||
const ORDER_TYPE_BOOK_BOX = '801'; //预定包厢
|
||
const ORDER_TYPE_AUTO_RECHARGE_ORDER = '109'; //充值订单
|
||
const ORDER_TYPE_GOODS = '802'; //商品订单
|
||
|
||
|
||
/**
|
||
* 根据订单号获取订单类型Key
|
||
* @param string $order_no 订单号
|
||
*/
|
||
public static function getOrderTypeByOrderNo($order_no)
|
||
{
|
||
if (empty($order_no) || strlen($order_no) < 19)
|
||
return 0;
|
||
$order_type = substr($order_no, 14, 3);
|
||
switch ($order_type) {
|
||
case "010":
|
||
return 1;
|
||
break;
|
||
case "020":
|
||
return 2;
|
||
case "108":
|
||
return 10;
|
||
case "109":
|
||
return 11;
|
||
break;
|
||
case "208":
|
||
return 12;
|
||
case "300":
|
||
return 13;
|
||
case "601":
|
||
return 16;
|
||
case "602":
|
||
return 21;
|
||
case "603":
|
||
return 22;
|
||
case "604":
|
||
return 18;
|
||
case "701":
|
||
return 17;
|
||
case "801":
|
||
return 33;
|
||
case "802":
|
||
return 19;
|
||
break;
|
||
//@TODO 其他
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
public static function orderTypeLabels()
|
||
{
|
||
return [
|
||
'1' => '钱包提现',
|
||
'2' => '平台转账',
|
||
'10' => '余额充值',
|
||
'11' => '余额充值',
|
||
'12' => '积分充值',
|
||
'13' => '积分兑换',
|
||
'16' => '球杆检测',
|
||
'21' => '球杆检测',
|
||
'22' => '球杆检测',
|
||
'33' => '预定包厢',
|
||
'19' => '商品下单',
|
||
'99' => '店长入账记录',
|
||
];
|
||
}
|
||
|
||
public static function getOrderType($type)
|
||
{
|
||
$labels = self::orderTypeLabels();
|
||
return isset($labels[$type]) ? $labels[$type] : "未知";
|
||
}
|
||
|
||
|
||
/**
|
||
* 生成唯一订单号,YYYYMMDDHHIISS+订单类型+随机数+校验码(2位)
|
||
* @param string $order_type 订单类型,识别码三位数字
|
||
* @param Model $class Model
|
||
* @param integer $len 订单号长度,最小值为20
|
||
* retrun string|null
|
||
* throw Exception
|
||
*/
|
||
public static function generate($order_type, $class = null, $len = 24, $retry = 1, $retry_max = 3, $unique_field = 'order_no')
|
||
{
|
||
$cache_key = "u_o_n_g_{$order_type}";
|
||
$cache_val = FlashStorage::getCache($cache_key);
|
||
if ($cache_val !== false) {
|
||
sleep(1);
|
||
$retry += 1;
|
||
return $retry <= $retry_max ? self::generate($order_type, $class, $len, $retry, $retry_max, $unique_field) : null;
|
||
}
|
||
FlashStorage::setCache($cache_key, $cache_key);
|
||
$order_no = null;
|
||
if ($class == null) {
|
||
$order_no = self::_generate($order_type, $len);
|
||
FlashStorage::deleteCache($cache_key);
|
||
return $order_no;
|
||
}
|
||
if (!class_exists($class)) {
|
||
throw new \Exception("{$class}不存在");
|
||
}
|
||
while (true) {
|
||
$order_no = self::_generate($order_type, $len);
|
||
$exists = $class::find()->where([$unique_field => $order_no])->exists();
|
||
if (!$exists) {
|
||
FlashStorage::deleteCache($cache_key);
|
||
break;
|
||
}
|
||
}
|
||
return $order_no;
|
||
}
|
||
|
||
public static function _generate($order_type, $len = 32)
|
||
{
|
||
$order_no_main = date('YmdHis', time()) . $order_type;
|
||
$rand_str_len = $len - strlen($order_no_main) - 2;
|
||
$rand_str = "";
|
||
if ($rand_str_len > 0) {
|
||
$rand_min = pow(10, $rand_str_len - 1);
|
||
$rand_max = pow(10, $rand_str_len) - 1;
|
||
$rand_str = mt_rand($rand_min, $rand_max);
|
||
}
|
||
$order_no_main .= $rand_str;
|
||
$order_no_mian_len = strlen($order_no_main);
|
||
$order_no_main_sum = 0;
|
||
for ($i = 0; $i < $order_no_mian_len; $i++) {
|
||
$order_no_main_sum += (int)(substr($order_no_main, $i, 1));
|
||
}
|
||
$order_no = $order_no_main . str_pad((100 - $order_no_main_sum % 100) % 100, 2, '0', STR_PAD_LEFT);
|
||
//并发情况生成唯一订单号
|
||
$cache_key = "u_o_n_g_{$order_type}_{$order_no}";
|
||
$cache_val = FlashStorage::getCache($cache_key);
|
||
if ($cache_val !== false) {
|
||
usleep(500);
|
||
return self::_generate($order_type, $len);
|
||
}
|
||
FlashStorage::setCache($cache_key, $cache_key, 60);
|
||
|
||
return $order_no;
|
||
}
|
||
|
||
}
|