feat: heal dead sync channels and block deleting system default (Z12h)

Ensure default channel and rebind Agent/Binding on list, ticket, agents/me, and ensure-binding so SyncPage does not stay on deleted-channel errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
whm
2026-08-06 08:57:30 +08:00
parent 2a7da53769
commit 362dcee242
8 changed files with 309 additions and 85 deletions

View File

@@ -9,6 +9,7 @@ import (
"aijianzhan/platform/internal/audit"
"aijianzhan/platform/internal/authx"
"aijianzhan/platform/internal/dbsync"
"aijianzhan/platform/internal/logic/applogic"
"aijianzhan/platform/internal/svc"
"github.com/zeromicro/go-zero/rest/httpx"
@@ -41,7 +42,12 @@ func syncListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
if !requireDBSync(svcCtx, w) {
return
}
list, err := svcCtx.DBSync.Store().ListChannelsByTenant(syncTenantID(r))
tid := syncTenantID(r)
if _, err := applogic.HealTenantSyncBind(r.Context(), svcCtx, tid); err != nil {
// 列表仍继续,避免自愈失败挡运维
_ = err
}
list, err := svcCtx.DBSync.Store().ListChannelsByTenant(tid)
if err != nil {
authx.WriteError(w, http.StatusBadRequest, err.Error())
return
@@ -109,15 +115,26 @@ func syncDeleteHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
id := pathvar.Vars(r)["id"]
if _, err := svcCtx.DBSync.Store().GetChannelForTenant(id, syncTenantID(r)); err != nil {
tid := syncTenantID(r)
ch, err := svcCtx.DBSync.Store().GetChannelForTenant(id, tid)
if err != nil {
authx.WriteError(w, http.StatusNotFound, err.Error())
return
}
// Z12h-1公司默认同步通道禁止删除账号落点依赖它
if ch.IsSystemDefault {
authx.WriteError(w, http.StatusBadRequest, "公司默认同步通道不可删除;账号绑定落点依赖此通道。若异常请刷新页面自动修复")
return
}
svcCtx.DBSync.StopChannel(id)
if err := svcCtx.DBSync.Store().DeleteChannel(id); err != nil {
authx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
// 若误删后仍有 Binding 挂死heal 会挂回默认通道
if _, hErr := applogic.HealTenantSyncBind(r.Context(), svcCtx, tid); hErr != nil {
_ = hErr
}
httpx.OkJson(w, map[string]any{"ok": true})
}
}