77 lines
1.7 KiB
PHP
77 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\admin\model\split\Link;
|
|
use think\Exception;
|
|
|
|
/**
|
|
* 分流链接码生成服务
|
|
*/
|
|
class SplitLinkCodeService
|
|
{
|
|
private const CODE_LENGTH = 9;
|
|
|
|
private const CHARSET = 'abcdefghijklmnopqrstuvwxyz';
|
|
|
|
private const MAX_ATTEMPTS = 50;
|
|
|
|
/**
|
|
* 规范化链接码(小写、去空格)
|
|
*/
|
|
public static function normalize(string $code): string
|
|
{
|
|
return strtolower(trim($code));
|
|
}
|
|
|
|
/**
|
|
* 是否为合法 9 位小写字母链接码
|
|
*/
|
|
public static function isValidFormat(string $code): bool
|
|
{
|
|
return (bool) preg_match('/^[a-z]{9}$/', $code);
|
|
}
|
|
|
|
/**
|
|
* 链接码是否未被占用
|
|
*/
|
|
public static function isAvailable(string $code, int $excludeId = 0): bool
|
|
{
|
|
$code = self::normalize($code);
|
|
$query = Link::where('link_code', $code);
|
|
if ($excludeId > 0) {
|
|
$query->where('id', '<>', $excludeId);
|
|
}
|
|
return !$query->find();
|
|
}
|
|
|
|
/**
|
|
* 生成唯一 9 位小写字母链接码
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function generateUnique(): string
|
|
{
|
|
for ($i = 0; $i < self::MAX_ATTEMPTS; $i++) {
|
|
$code = $this->generateRandom();
|
|
if (!Link::where('link_code', $code)->find()) {
|
|
return $code;
|
|
}
|
|
}
|
|
throw new Exception('分流链接生成失败,请稍后重试');
|
|
}
|
|
|
|
private function generateRandom(): string
|
|
{
|
|
$chars = self::CHARSET;
|
|
$max = strlen($chars) - 1;
|
|
$code = '';
|
|
for ($i = 0; $i < self::CODE_LENGTH; $i++) {
|
|
$code .= $chars[random_int(0, $max)];
|
|
}
|
|
return $code;
|
|
}
|
|
}
|