feat: xxbb
This commit is contained in:
+78
-2
@@ -4,13 +4,39 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use RuntimeException;
|
||||
|
||||
class Channel extends Model
|
||||
{
|
||||
public const OFFICIAL_USER_ID = 0;
|
||||
|
||||
public const BUILDER_OLD = 'old';
|
||||
|
||||
public const BUILDER_NEW = 'new';
|
||||
|
||||
public const CHANNEL_NAME_LENGTH = 8;
|
||||
|
||||
/**
|
||||
* Public-root path prefixes that must not be used as channel_name.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public const RESERVED_CHANNEL_NAMES = [
|
||||
'admin', 'user', 'api', 'web', 'sync', 'details', 'weifile', 'hooks',
|
||||
'link', 'statistic', 'vhx', 'event', 'log', 'storage', 'build', 'hot',
|
||||
'vendor', 'css', 'js', 'up', 'index', 'assets', 'static', 'source', 'channel',
|
||||
'out', 't', 'a', 'u', 'uj', 'us', 'ub', 'ba', 'result', 'favicon',
|
||||
'robots', 'sitemap', 'public', 'app', 'bootstrap', 'config',
|
||||
'database', 'resources', 'routes', 'tests', 'artisan', 'livewire',
|
||||
'sanctum', 'telescope', 'horizon', 'pulse',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'channel_id', 'user_id', 'domains', 'status', 'remark',
|
||||
'channel_id', 'builder_type', 'channel_name', 'user_id', 'domains', 'status', 'remark',
|
||||
];
|
||||
|
||||
protected $attributes = [
|
||||
'builder_type' => self::BUILDER_OLD,
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
@@ -37,6 +63,18 @@ class Channel extends Model
|
||||
return (int) $this->user_id === self::OFFICIAL_USER_ID;
|
||||
}
|
||||
|
||||
public function isNewBuilder(): bool
|
||||
{
|
||||
return $this->builderType() === self::BUILDER_NEW;
|
||||
}
|
||||
|
||||
public function builderType(): string
|
||||
{
|
||||
$type = strtolower(trim((string) ($this->builder_type ?? '')));
|
||||
|
||||
return $type === self::BUILDER_NEW ? self::BUILDER_NEW : self::BUILDER_OLD;
|
||||
}
|
||||
|
||||
public function agentLabel(): string
|
||||
{
|
||||
if ($this->isOfficial()) {
|
||||
@@ -83,13 +121,25 @@ class Channel extends Model
|
||||
}, $domains))));
|
||||
}
|
||||
|
||||
public function landingPath(): string
|
||||
{
|
||||
if ($this->isNewBuilder()) {
|
||||
$name = strtolower(trim((string) ($this->channel_name ?? '')));
|
||||
if ($name !== '') {
|
||||
return '/source/'.$name.'/index.html';
|
||||
}
|
||||
}
|
||||
|
||||
return '/web/'.$this->channel_id.'/support.html';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
public function supportLinks(): array
|
||||
{
|
||||
$links = [];
|
||||
$path = '/web/'.$this->channel_id.'/support.html';
|
||||
$path = $this->landingPath();
|
||||
$scheme = trim((string) config('coruna.static_site.scheme', 'https')) ?: 'https';
|
||||
foreach ($this->resolvedDomains() as $domain) {
|
||||
$origin = rtrim($domain, '/');
|
||||
@@ -110,6 +160,32 @@ class Channel extends Model
|
||||
return bin2hex(random_bytes(16));
|
||||
}
|
||||
|
||||
public static function isReservedChannelName(string $name): bool
|
||||
{
|
||||
return in_array(strtolower($name), self::RESERVED_CHANNEL_NAMES, true);
|
||||
}
|
||||
|
||||
public static function randomChannelName(): string
|
||||
{
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$name = substr(bin2hex(random_bytes(5)), 0, self::CHANNEL_NAME_LENGTH);
|
||||
if (self::isReservedChannelName($name)) {
|
||||
continue;
|
||||
}
|
||||
if (self::query()->where('channel_name', $name)->exists()) {
|
||||
continue;
|
||||
}
|
||||
$public = public_path('source/'.$name);
|
||||
if (is_dir($public) || is_file($public)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
throw new RuntimeException('无法生成唯一 channel_name');
|
||||
}
|
||||
|
||||
public static function maxPerAgent(): int
|
||||
{
|
||||
$n = (int) config('coruna.channels.max_per_agent', 5);
|
||||
|
||||
Reference in New Issue
Block a user