0.11.1: 旗舰版完善(资源权限等级/个人环境变量/收藏/企业报表/租户概览/ARM64发布/多渠道接入)
- 迁移 000035-000037(权限等级/环境变量/渠道) - 新增 internal/channel 渠道抽象层(webhook/企微/钉钉/飞书) - 全部功能端到端验证通过(25 包单测)
This commit is contained in:
@@ -24,6 +24,7 @@ func NewAdminHTTPHandler(pool *pgxpool.Pool, identityService *identity.Service,
|
||||
h := &AdminHTTPHandler{pool: pool, identity: identityService, version: version, startedAt: startedAt, reload: reload, mux: http.NewServeMux()}
|
||||
h.mux.HandleFunc("GET /api/v1/admin/system-info", h.systemInfo)
|
||||
h.mux.HandleFunc("GET /api/v1/admin/monitoring/overview", h.overview)
|
||||
h.mux.HandleFunc("GET /api/v1/admin/tenants/overview", h.tenantsOverview)
|
||||
h.mux.HandleFunc("POST /api/v1/admin/reload", h.reloadSnapshots)
|
||||
return h
|
||||
}
|
||||
@@ -82,3 +83,44 @@ func (h *AdminHTTPHandler) reloadSnapshots(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
apiresponse.OK(w, map[string]bool{"reloaded": true})
|
||||
}
|
||||
|
||||
|
||||
// tenantsOverview 以部门为租户维度,汇总各租户的账号/Key/用量。
|
||||
func (h *AdminHTTPHandler) tenantsOverview(w http.ResponseWriter, r *http.Request) {
|
||||
if _, ok := h.account(w, r); !ok {
|
||||
return
|
||||
}
|
||||
rows, err := h.pool.Query(r.Context(), `SELECT d.id::text,d.name,
|
||||
(SELECT count(*) FROM gateway.portal_users u WHERE u.department_id=d.id),
|
||||
(SELECT count(*) FROM gateway.api_keys k WHERE k.tenant_id=d.id AND k.enabled),
|
||||
(SELECT count(*) FROM gateway.audit_events a WHERE a.tenant_id=d.id AND a.recorded_at>=date_trunc('day',now())),
|
||||
(SELECT COALESCE(sum(a.prompt_tokens+a.completion_tokens),0) FROM gateway.audit_events a WHERE a.tenant_id=d.id AND a.recorded_at>=date_trunc('day',now()))
|
||||
FROM gateway.departments d WHERE d.active ORDER BY d.name`)
|
||||
if err != nil {
|
||||
apiresponse.Error(w, http.StatusServiceUnavailable, "租户概览查询失败")
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
type tenantRow struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
PortalUsers int64 `json:"portal_users"`
|
||||
EnabledKeys int64 `json:"enabled_api_keys"`
|
||||
TodayRequests int64 `json:"today_requests"`
|
||||
TodayTokens int64 `json:"today_tokens"`
|
||||
}
|
||||
items := []tenantRow{}
|
||||
for rows.Next() {
|
||||
var item tenantRow
|
||||
if err := rows.Scan(&item.ID, &item.Name, &item.PortalUsers, &item.EnabledKeys, &item.TodayRequests, &item.TodayTokens); err != nil {
|
||||
apiresponse.Error(w, http.StatusServiceUnavailable, "租户概览查询失败")
|
||||
return
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
apiresponse.Error(w, http.StatusServiceUnavailable, "租户概览查询失败")
|
||||
return
|
||||
}
|
||||
apiresponse.OK(w, map[string]any{"tenants": items})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user