| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- <?php
- declare(strict_types=1);
- use SixShop\Payment\Enum\NumberBizEnum;
- if (!function_exists('generate_number')) {
- /**
- * 生成20位数字编号
- * 格式:14位日期时间(YmdHis) + 2位业务码(00-99) + 3位随机数 + 1位校验位
- *
- * @param NumberBizEnum $bizCode 业务编码(0-99),1 订单号 2 订单支付
- * @return string 20位数字编号
- * @throws InvalidArgumentException 当业务码不在0-99范围时抛出
- */
- function generate_number(NumberBizEnum $bizCode): string
- {
- $bizCode = $bizCode->value;
- // 1. 校验业务码范围
- if ($bizCode < 0 || $bizCode > 99) {
- throw new InvalidArgumentException('业务码必须是0-99之间的整数');
- }
- // 2. 14位日期时间(年月日时分秒)
- $datetime = date('YmdHis');
- // 3. 2位业务码(自动补零)
- $bizPart = str_pad((string)$bizCode, 2, '0', STR_PAD_LEFT);
- // 4. 3位安全随机数
- $random = str_pad((string)random_int(0, 999), 3, '0', STR_PAD_LEFT);
- // 5. 组合前19位
- $prefix = $datetime . $bizPart . $random;
- // 6. 计算校验位(简单加权求和)
- $sum = 0;
- for ($i = 0; $i < 19; $i++) {
- $sum += $prefix[$i] * (($i % 2) ? 3 : 1);
- }
- $checkDigit = (10 - ($sum % 10)) % 10;
- return $prefix . $checkDigit;
- }
- }
- if (!function_exists('validate_order_number')) {
- /**
- * 验证订单号有效性
- */
- function validate_order_number(string $orderNo): bool
- {
- // 基础格式检查
- if (!preg_match('/^\d{20}$/', $orderNo)) {
- return false;
- }
- // 校验位验证
- $prefix = substr($orderNo, 0, 19);
- $check = substr($orderNo, -1);
- $sum = 0;
- for ($i = 0; $i < 19; $i++) {
- $sum += $prefix[$i] * (($i % 2) ? 3 : 1);
- }
- return ((10 - ($sum % 10)) % 10) == $check;
- }
- }
|