cxfoot/models/UniqueOrderNo.php
2023-10-27 14:25:12 +08:00

175 lines
5.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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_AUTO_RECHARGE_ORDER = '109';
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_BALL_ARM = '601'; //球杆检测
const ORDER_TYPE_HIT_BALL = '602'; //击球检测
const ORDER_TYPE_MEMBER = '603'; //购买会员
const ORDER_TYPE_BALL_CART = '801'; //球车租赁
const ORDER_TYPE_RETURN_ORDER = '901'; //用户申请退款
const ORDER_TYPE_DEPOSIT = '604'; //交纳押金
/**
* 根据订单号获取订单类型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;
break;
//@TODO 其他
default:
return 0;
}
}
public static function orderTypeLabels()
{
return [
'1' => '钱包提现',
'2' => '平台转账',
'10' => '余额充值',
'11' => '余额充值',
'12' => '积分充值',
'13' => '积分兑换',
'16' => '球杆检测',
'21' => '球杆检测',
'22' => '球杆检测',
];
}
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;
}
}