package controllers import ( "fmt" "strings" "server/models" "server/pkg/jwtutil" "server/services" beego "github.com/beego/beego/v2/server/web" ) // tenantModuleItem 模块列表返回项:在模块基础信息上补充套餐开通状态, // locked=true 表示该模块不在当前租户已购套餐内(前端置灰并提示购买套餐)。 type tenantModuleItem struct { models.SystemModules Locked bool `json:"locked"` } // BackendModulesController backend 模块接口(yz_system_modules) type BackendModulesController struct { beego.Controller } func (c *BackendModulesController) backendModulesClaims() (*jwtutil.Claims, error) { auth := c.Ctx.Request.Header.Get("Authorization") if auth == "" { return nil, fmt.Errorf("未登录") } parts := strings.SplitN(auth, " ", 2) if len(parts) != 2 || parts[0] != "Bearer" { return nil, fmt.Errorf("认证信息格式错误") } claims, err := jwtutil.ParseToken(parts[1]) if err != nil { return nil, fmt.Errorf("无效的token") } if claims.UserType != "backend" { return nil, fmt.Errorf("无权访问") } return claims, nil } func (c *BackendModulesController) jsonErr(httpStatus, bizCode int, msg string) { c.Ctx.Output.SetStatus(httpStatus) c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg} _ = c.ServeJSON() } // GetTenantList GET /backend/modules/getTenantList // 返回当前 backend 账号可见的模块(status=1 且 is_show=1)。 // 同时按当前租户已购套餐标记 locked:未开通的功能模块前端置灰、禁止跳转并提示购买套餐。 func (c *BackendModulesController) GetTenantList() { claims, err := c.backendModulesClaims() if err != nil { c.jsonErr(401, 401, err.Error()) return } var rows []models.SystemModules _, err = models.Orm.QueryTable(new(models.SystemModules)). Filter("delete_time__isnull", true). Filter("status", 1). Filter("is_show", 1). OrderBy("sort", "id"). All(&rows) if err != nil { c.jsonErr(500, 500, "获取失败:"+err.Error()) return } // 租户已开通的模块编码集合(来自租户绑定/生效套餐) allowed := map[string]bool{} packageName := "" if tid := uint64(claims.TenantId); tid > 0 { allowed = services.GetTenantModuleCodes(tid) if pkg, e := services.GetTenantPackage(tid); e == nil && pkg != nil { packageName = pkg.Name } } list := make([]tenantModuleItem, 0, len(rows)) for _, m := range rows { // 安全兜底:租户未绑定套餐或套餐未配置任何功能模块时不做锁定, // 避免套餐数据缺失导致全部功能不可用。 locked := len(allowed) > 0 && !allowed[strings.TrimSpace(m.Code)] list = append(list, tenantModuleItem{SystemModules: m, Locked: locked}) } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "获取成功", "data": map[string]interface{}{ "list": list, "total": len(list), "package_name": packageName, "purchase_url": services.GetPackagePurchaseURL(), }, } _ = c.ServeJSON() }