From eaca8dc8cc66edde436987a821f66d1318d3e4e5 Mon Sep 17 00:00:00 2001 From: Aska Date: Mon, 7 Sep 2026 16:21:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(gateway):=20adminListChannels=20=E6=8C=89?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E8=81=9A=E5=90=88=E2=80=94=E2=80=94bare+kook?= =?UTF-8?q?=E5=A4=9A=E4=B8=AAadapter=E4=B8=8D=E5=86=8D=E6=8B=86=E6=88=90?= =?UTF-8?q?=E5=A4=9A=E8=A1=8C=E5=AF=BC=E8=87=B4=E9=87=8D=E5=A4=8D=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 根因: caps循环把 kook(bare)+kook:fc2048(多账号) 分别append, 每行Accounts都是完整platform账号集→前端显示两个kook且fc2048重复(主人'只点一次创建出两个kook') - 修: 按platform聚合(hasChannelSummary检查), 同platform只一行(Name=platform), Accounts为整个platform账号集; 保留agent-121删除同步(平台有账号才显示) - 测试断言: kook:3fc8/conf0 → kook(聚合行) 更新 - 全仓 go build/vet/test绿; 前端无涉 --- internal/services/gateway/admin.go | 8 +++++++- .../gateway/admin_write_channel_config_test.go | 10 +++++----- internal/services/gateway/extra_test.go | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/internal/services/gateway/admin.go b/internal/services/gateway/admin.go index 86ca7d2..a1bc601 100644 --- a/internal/services/gateway/admin.go +++ b/internal/services/gateway/admin.go @@ -161,7 +161,13 @@ func (s *Server) adminListChannels(w http.ResponseWriter, r *http.Request) { continue } } - sum := ChannelSummary{Name: ch.Name(), Connected: ch.IsConnected()} + // Aggregate by platform: a bare adapter ("kook") and the multi-account + // ones ("kook:fc2048", "kook:conf1") are ONE platform row, so the account + // list is not duplicated into a separate row per in-registry adapter. + if s.hasChannelSummary(out, platform) { + continue + } + sum := ChannelSummary{Name: platform, Connected: ch.IsConnected()} if accts, ok := accountsByPlatform[platform]; ok && len(accts) > 0 { sum.Accounts = enrichAccountsWithBot(accts, botByPlatform[platform]) } diff --git a/internal/services/gateway/admin_write_channel_config_test.go b/internal/services/gateway/admin_write_channel_config_test.go index 08ec2d9..b4d881a 100644 --- a/internal/services/gateway/admin_write_channel_config_test.go +++ b/internal/services/gateway/admin_write_channel_config_test.go @@ -202,10 +202,10 @@ func TestAdminDeleteChannelAccountRemovesFromList(t *testing.T) { _, ts, jwt := buildEnv(t, cfgDefault(), Deps{Registry: caps, Channels: store}) tok := signAny(t, jwt, "acct", auth.RoleOwner) - // Before the delete the account shows up. + // Before the delete the account shows up (aggregated into a single "kook" row). items, _ := adminChannelsList(t, ts, tok) - if len(items) != 1 || items[0].Name != "kook:3fc8" { - t.Fatalf("before delete items = %+v, want [kook:3fc8]", items) + if len(items) != 1 || items[0].Name != "kook" || len(items[0].Accounts) != 1 || items[0].Accounts[0].ID != "3fc8" { + t.Fatalf("before delete items = %+v, want one kook row with account 3fc8", items) } resp, body := doReq(t, http.MethodDelete, ts.URL+"/api/v1/admin/channels/kook/config?id=3fc8", nil, tok) @@ -252,8 +252,8 @@ func TestAdminDeleteChannelAccountKeepsSibling(t *testing.T) { } items, _ := adminChannelsList(t, ts, tok) - if len(items) != 1 || items[0].Name != "kook:conf1" { - t.Fatalf("items = %+v, want only kook:conf1 (deleted 3fc8 must vanish)", items) + if len(items) != 1 || items[0].Name != "kook" { + t.Fatalf("items = %+v, want one kook row (deleted 3fc8 must vanish)", items) } if len(items[0].Accounts) != 1 || items[0].Accounts[0].ID != "conf1" { t.Fatalf("accounts = %+v, want only conf1", items[0].Accounts) diff --git a/internal/services/gateway/extra_test.go b/internal/services/gateway/extra_test.go index 649a9c2..95c9091 100644 --- a/internal/services/gateway/extra_test.go +++ b/internal/services/gateway/extra_test.go @@ -597,8 +597,8 @@ func TestAdminChannels_SurfacesBotIdentity(t *testing.T) { if err := json.Unmarshal(decodeBody(t, body)["data"], &items); err != nil { t.Fatalf("decode: %v", err) } - if len(items) != 1 || items[0].Name != "kook:conf0" { - t.Fatalf("items = %+v, want single kook:conf0", items) + if len(items) != 1 || items[0].Name != "kook" { + t.Fatalf("items = %+v, want single kook row", items) } if len(items[0].Accounts) != 1 { t.Fatalf("accounts = %+v, want one", items[0].Accounts)