feat: new channel
This commit is contained in:
+32
-21
@@ -14,10 +14,11 @@ class Channel extends Model
|
||||
|
||||
public const BUILDER_NEW = 'new';
|
||||
|
||||
public const NEW_CHANNEL_ID_LENGTH = 8;
|
||||
/** New-builder channel id / core ver·sdkv patch string: exactly 6 chars like 2.2.66 (alnum + dots). */
|
||||
public const NEW_CHANNEL_ID_PATTERN = '/^[0-9A-Z]\.[0-9A-Z]\.[0-9A-Z]{2}$/';
|
||||
|
||||
/**
|
||||
* Public-root path prefixes that must not be used as 8-char channel IDs.
|
||||
* Public-root path prefixes that must not be used as old 32-hex channel IDs.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
@@ -39,6 +40,25 @@ class Channel extends Model
|
||||
'builder_type' => self::BUILDER_OLD,
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
$bust = static function (Channel $channel): void {
|
||||
$svc = app(\App\Services\FilterOptionsService::class);
|
||||
$svc->forgetChannels();
|
||||
$uids = array_unique(array_filter([
|
||||
(int) $channel->user_id,
|
||||
(int) $channel->getOriginal('user_id'),
|
||||
]));
|
||||
foreach ($uids as $uid) {
|
||||
if ($uid > 0) {
|
||||
$svc->forgetChannels($uid);
|
||||
}
|
||||
}
|
||||
};
|
||||
static::saved($bust);
|
||||
static::deleted($bust);
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
@@ -124,7 +144,7 @@ class Channel extends Model
|
||||
public function landingPath(): string
|
||||
{
|
||||
if ($this->isNewBuilder()) {
|
||||
return '/weifile/weifile.html';
|
||||
return '/channel/'.$this->channel_id.'/weifile/weifile.html';
|
||||
}
|
||||
|
||||
return '/web/'.$this->channel_id.'/support.html';
|
||||
@@ -135,10 +155,6 @@ class Channel extends Model
|
||||
*/
|
||||
public function supportLinks(): array
|
||||
{
|
||||
if ($this->isNewBuilder()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$links = [];
|
||||
$path = $this->landingPath();
|
||||
$scheme = trim((string) config('coruna.static_site.scheme', 'https')) ?: 'https';
|
||||
@@ -164,10 +180,7 @@ class Channel extends Model
|
||||
public static function normalizeNewChannelId(string $channelId): ?string
|
||||
{
|
||||
$channelId = strtoupper(trim($channelId));
|
||||
if (! preg_match('/^[A-Z0-9]{'.self::NEW_CHANNEL_ID_LENGTH.'}$/', $channelId)) {
|
||||
return null;
|
||||
}
|
||||
if (self::isReservedChannelName($channelId)) {
|
||||
if (! preg_match(self::NEW_CHANNEL_ID_PATTERN, $channelId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -176,12 +189,12 @@ class Channel extends Model
|
||||
|
||||
public static function randomNewChannelId(): string
|
||||
{
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$code = strtoupper(substr(bin2hex(random_bytes(5)), 0, self::NEW_CHANNEL_ID_LENGTH));
|
||||
if (self::normalizeNewChannelId($code) === null) {
|
||||
continue;
|
||||
}
|
||||
if (self::query()->whereRaw('upper(channel_id) = ?', [$code])->exists()) {
|
||||
$chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$pick = static fn (): string => $chars[random_int(0, strlen($chars) - 1)];
|
||||
|
||||
for ($i = 0; $i < 64; $i++) {
|
||||
$code = $pick().'.'.$pick().'.'.$pick().$pick();
|
||||
if (self::query()->where('channel_id', $code)->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -191,11 +204,9 @@ class Channel extends Model
|
||||
throw new RuntimeException('无法生成唯一渠道 ID');
|
||||
}
|
||||
|
||||
public function sourceZipRelativePath(): string
|
||||
public function channelPublicRelativeDir(): string
|
||||
{
|
||||
$dir = trim((string) config('coruna.channel_builder_new.source_dir', 'channel-source-new'), '/');
|
||||
|
||||
return $dir.'/'.$this->channel_id.'.zip';
|
||||
return 'channel/'.$this->channel_id;
|
||||
}
|
||||
|
||||
public static function isReservedChannelName(string $name): bool
|
||||
|
||||
@@ -15,6 +15,15 @@ class User extends Authenticatable
|
||||
'password', 'remember_token', 'bot_token',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
$bust = static function (): void {
|
||||
app(\App\Services\FilterOptionsService::class)->forgetAgents();
|
||||
};
|
||||
static::saved($bust);
|
||||
static::deleted($bust);
|
||||
}
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
|
||||
Reference in New Issue
Block a user