Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.
Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)
Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
(dropped 3 stale entries, added the 17 missing ones)
Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
when it is empty
Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.
Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
52 lines
2.1 KiB
PHP
52 lines
2.1 KiB
PHP
<?php
|
|
/**
|
|
* @package Jio
|
|
*/
|
|
|
|
namespace Jio\Finance;
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
/**
|
|
* 统一业务流水号分配器。
|
|
*
|
|
* 订单号、资金流水号、提现单号共用同一套号码规则,不再按业务类型区分,
|
|
* 也不再存在任何可配置前缀:{YmdHis}{8 位随机数},共 22 字符。
|
|
* 该长度同时满足数据库 VARCHAR(32) 列与各网关 out_trade_no ≤32 字符的限制。
|
|
*
|
|
* 后缀为什么是 8 位纯数字(而不是等长的 base36):
|
|
* - 同一秒内的取值空间从 10^6 提升到 10^8(+6.6 bit),撞号频率随之下降
|
|
* 两个数量级,规避高并发下单时的重试噪音;
|
|
* - 保持「纯数字、定长」形态,号码仍可被运营从截图或邮件里整段复制、
|
|
* 电话口述,不引入 0/O、1/I 之类的大小写与字形歧义;
|
|
* - 表默认排序规则是 utf8mb4_*_ci(大小写不敏感),一旦混入大小写字母,
|
|
* 唯一索引会把 aB 与 Ab 判为重复行,反而凭空制造冲突;
|
|
* - 22 字符拼上重试后缀(P999)后 26 字符,仍远低于 32 的上限。
|
|
* 碰撞最终由调用侧的重试循环兜底(FinancialFlowService::record 与
|
|
* OrderRepositoryCore::create 均为 5 次),此处只负责把概率压低。
|
|
*/
|
|
final class BusinessNumber {
|
|
|
|
/** 随机后缀的位数。 */
|
|
private const SUFFIX_DIGITS = 8;
|
|
|
|
/** 随机后缀的上界,等于 10^SUFFIX_DIGITS - 1。 */
|
|
private const SUFFIX_MAX = 99999999;
|
|
|
|
/**
|
|
* 生成一个统一流水号。
|
|
*
|
|
* @param \DateTimeInterface|null $now 分配时刻,默认取站内时区的当前时间。
|
|
* @param int|null $random 0-99999999 的随机后缀,默认随机取值。
|
|
*/
|
|
public static function allocate(?\DateTimeInterface $now = null, ?int $random = null): string {
|
|
if ($now === null) {
|
|
$now = new \DateTimeImmutable('now', wp_timezone());
|
|
}
|
|
$random = $random ?? random_int(0, self::SUFFIX_MAX);
|
|
$random = max(0, min(self::SUFFIX_MAX, $random));
|
|
|
|
return $now->format('YmdHis') . str_pad((string) $random, self::SUFFIX_DIGITS, '0', STR_PAD_LEFT);
|
|
}
|
|
}
|