fix(admin-frontend): 修复节点权限组保存与协议默认值

统一将节点编辑和批量修改的 group_ids、route_ids
序列化为字符串 ID,避免保存权限组后订阅侧无法命中节点

后端新增 whereGroupId 兼容历史字符串与数字 JSON 值,
并补齐 TUIC 版本、ALPN 选项及 AnyTLS 默认 Padding 配置

docs: 新增 HelloAGENTS 通用与工作流避坑指南
This commit is contained in:
yinjianm
2026-04-27 23:03:57 +08:00
parent c64badfc23
commit 30c2f655e7
16 changed files with 1096 additions and 33 deletions
@@ -43,7 +43,7 @@ class CheckTrafficExceeded extends Command
}
$userIdsInGroup = $users->pluck('id')->toArray();
$servers = Server::whereJsonContains('group_ids', (string) $groupId)->get();
$servers = Server::whereGroupId($groupId)->get();
foreach ($servers as $server) {
if (!NodeSyncService::isNodeOnline($server->id)) {
@@ -51,7 +51,7 @@ class GroupController extends Controller
if (!$serverGroup) {
return $this->fail([400202, '组不存在']);
}
if (Server::whereJsonContains('group_ids', $groupId)->exists()) {
if (Server::whereGroupId($groupId)->exists()) {
return $this->fail([400, '该组已被节点所使用,无法删除']);
}
+40
View File
@@ -135,6 +135,46 @@ class Server extends Model
'machine_id' => 'integer',
];
private function normalizeJsonIdList($value): array
{
if (is_string($value)) {
$decoded = json_decode($value, true);
$value = json_last_error() === JSON_ERROR_NONE ? $decoded : [$value];
}
if (!is_array($value)) {
return [];
}
return array_values(array_unique(array_filter(array_map(
fn ($item) => trim((string) $item),
$value
), fn ($item) => $item !== '')));
}
public function setGroupIdsAttribute($value): void
{
$this->attributes['group_ids'] = json_encode($this->normalizeJsonIdList($value));
}
public function setRouteIdsAttribute($value): void
{
$this->attributes['route_ids'] = json_encode($this->normalizeJsonIdList($value));
}
public function scopeWhereGroupId($query, $groupId)
{
$normalized = trim((string) $groupId);
return $query->where(function ($query) use ($normalized) {
$query->whereJsonContains('group_ids', $normalized);
if (ctype_digit($normalized)) {
$query->orWhereJsonContains('group_ids', (int) $normalized);
}
});
}
private const MULTIPLEX_CONFIGURATION = [
'multiplex' => [
'type' => 'object',
+2 -2
View File
@@ -31,7 +31,7 @@ class ServerGroup extends Model
public function servers()
{
return Server::whereJsonContains('group_ids', (string) $this->id)->get();
return Server::whereGroupId($this->id)->get();
}
/**
@@ -40,7 +40,7 @@ class ServerGroup extends Model
protected function serverCount(): Attribute
{
return Attribute::make(
get: fn () => Server::whereJsonContains('group_ids', (string) $this->id)->count(),
get: fn () => Server::whereGroupId($this->id)->count(),
);
}
}
+3 -3
View File
@@ -39,7 +39,7 @@ class NodeSyncService
*/
public static function notifyUsersUpdatedByGroup(int $groupId): void
{
$servers = Server::whereJsonContains('group_ids', (string) $groupId)
$servers = Server::whereGroupId($groupId)
->get();
foreach ($servers as $server) {
@@ -59,7 +59,7 @@ class NodeSyncService
if (!$user->group_id)
return;
$servers = Server::whereJsonContains('group_ids', (string) $user->group_id)->get();
$servers = Server::whereGroupId($user->group_id)->get();
foreach ($servers as $server) {
if (!self::isNodeOnline($server->id))
continue;
@@ -90,7 +90,7 @@ class NodeSyncService
*/
public static function notifyUserRemovedFromGroup(int $userId, int $groupId): void
{
$servers = Server::whereJsonContains('group_ids', (string) $groupId)
$servers = Server::whereGroupId($groupId)
->get();
foreach ($servers as $server) {
+1 -1
View File
@@ -54,7 +54,7 @@ class ServerService
*/
public static function getAvailableServers(User $user): array
{
$servers = Server::whereJsonContains('group_ids', (string) $user->group_id)
$servers = Server::whereGroupId($user->group_id)
->where('show', true)
->where(function ($query) {
$query->whereNull('transfer_enable')