feat(admin): upgrade admin console UI widgets, add plan & status management, and redesign system status dashboard
This commit is contained in:
@@ -339,6 +339,43 @@ func (h *Handler) AdminSetSharedBilling(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
||||
}
|
||||
|
||||
// AdminSetTenantPlan: PUT /api/v1/admin/tenants/:id/plan {plan} —— 改方案等级。
|
||||
func (h *Handler) AdminSetTenantPlan(c *gin.Context) {
|
||||
var b struct {
|
||||
Plan string `json:"plan"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&b); err != nil || strings.TrimSpace(b.Plan) == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "plan 必填"})
|
||||
return
|
||||
}
|
||||
if err := h.db.SetTenantPlan(c.Request.Context(), c.Param("id"), b.Plan); err != nil {
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
||||
}
|
||||
|
||||
// AdminSetTenantStatus: PUT /api/v1/admin/tenants/:id/status {status} —— 改租户状态(暂停/恢复)。
|
||||
func (h *Handler) AdminSetTenantStatus(c *gin.Context) {
|
||||
var b struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&b); err != nil || strings.TrimSpace(b.Status) == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "status 必填"})
|
||||
return
|
||||
}
|
||||
if b.Status != "active" && b.Status != "suspended" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 status,仅支持 active/suspended"})
|
||||
return
|
||||
}
|
||||
if err := h.db.SetTenantStatus(c.Request.Context(), c.Param("id"), b.Status); err != nil {
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
||||
}
|
||||
|
||||
|
||||
// AdminMembers: GET /api/v1/admin/tenants/:id/members —— 某租户成员列表。
|
||||
func (h *Handler) AdminMembers(c *gin.Context) {
|
||||
rows, err := h.db.ListMembers(c.Request.Context(), c.Param("id"))
|
||||
|
||||
@@ -152,6 +152,9 @@ func New(db *store.Postgres, cache *store.Redis, bus *nats.Bus, blobStore *blob.
|
||||
admin.GET("/tenants", h.AdminTenants) // 租户目录(成员数+余额)
|
||||
admin.POST("/tenants", h.AdminCreateTenant) // 新建租户(可选指定 owner)
|
||||
admin.PUT("/tenants/:id/shared-billing", h.AdminSetSharedBilling) // 共享计费开关
|
||||
admin.PUT("/tenants/:id/plan", h.AdminSetTenantPlan) // 方案等级
|
||||
admin.PUT("/tenants/:id/status", h.AdminSetTenantStatus) // 租户状态
|
||||
|
||||
admin.GET("/tenants/:id/members", h.AdminMembers) // 成员列表
|
||||
admin.POST("/tenants/:id/members", h.AdminAddMember) // 按邮箱加成员
|
||||
admin.PUT("/tenants/:id/members/:uid", h.AdminSetMemberRole) // 改角色
|
||||
|
||||
@@ -386,3 +386,20 @@ func (p *Postgres) ResolveBillingTenantID(ctx context.Context, userID, activeTen
|
||||
}
|
||||
return activeTenantID
|
||||
}
|
||||
|
||||
// SetTenantPlan 更改租户方案等级。
|
||||
func (p *Postgres) SetTenantPlan(ctx context.Context, tenantID string, plan string) error {
|
||||
if p.db == nil {
|
||||
return errStoreDisabled
|
||||
}
|
||||
return p.db.WithContext(ctx).Model(&Tenant{}).Where("id = ?", tenantID).Update("plan", plan).Error
|
||||
}
|
||||
|
||||
// SetTenantStatus 更改租户状态(active / suspended)。
|
||||
func (p *Postgres) SetTenantStatus(ctx context.Context, tenantID string, status string) error {
|
||||
if p.db == nil {
|
||||
return errStoreDisabled
|
||||
}
|
||||
return p.db.WithContext(ctx).Model(&Tenant{}).Where("id = ?", tenantID).Update("status", status).Error
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user