package middleware import ( "context" "encoding/json" "fmt" "gitea.com/red-future/common/beans" "gitea.com/red-future/common/message" "gitea.com/red-future/common/redis" "gitea.com/red-future/common/utils" "github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" "net/http" "time" ) func ModuleTenantCheck(r *ghttp.Request) { // 检查是否是超级管理员 isSuperAdmin := false if err := message.CallRPC(r.Context(), "userService.IsSuperAdmin", nil, &isSuperAdmin); err != nil { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, err) } // 如果是超级管理员,则不进行模块租户检查 if isSuperAdmin || r.Request.RequestURI == "/asset/getAssetAndSku?assetId=696b4acd1be1c8b76c4b4c15" { r.Middleware.Next() return } getUserInfo, err := utils.GetUserInfo(r.Context()) if err != nil { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, err) } exit := gconv.Int64(time.Minute * 1) getEX, err := redis.GetRedisClientTest("test").GetEX(r.Context(), fmt.Sprintf("module_tenant:tenantId-%v", getUserInfo.TenantId), gredis.GetEXOption{ TTLOption: gredis.TTLOption{ EX: &exit, }, }) if err != nil { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, err) } // 获取模块key moduleKey := g.Cfg().MustGet(context.Background(), "server.name").String() if !g.IsEmpty(getEX.String()) { list := new(beans.ModuleTenant) if err = json.Unmarshal(getEX.Bytes(), &list); err != nil { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, err) } // 缓存中有数据,检查是否过期 if !g.IsEmpty(list.ExpireAt) { gt1 := gtime.New(time.Now()) gt2 := gtime.New(list.ExpireAt) if !gt1.Before(gt2) { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, "功能模块已到期,请续期后再使用") } else { if list.CertificationStatus != 2 { SetResponseInfo(r.Context(), r, http.StatusPreconditionRequired, "功能模块未认证通过,请认证后再使用") } } } else { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, "您未开通此功能模块,请开通后再使用") } } else { checkRes := new(beans.ModuleTenantCheckRes) checkReq := beans.ModuleTenantCheckReq{ ModuleKey: moduleKey, TenantId: gconv.Uint64(getUserInfo.TenantId), } err = message.CallRPC(r.Context(), "moduleService.Check", &checkReq, checkRes) if err != nil { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, err) } // 根据检查结果判断是否允许访问 if !checkRes.Status { SetResponseInfo(r.Context(), r, http.StatusPaymentRequired, checkRes.Message) } else { if !checkRes.CertificationStatus { SetResponseInfo(r.Context(), r, http.StatusPreconditionRequired, checkRes.Message) } } } r.Middleware.Next() // 继续执行后续中间件和路由处理 } // SetResponseInfo 设置响应信息 func SetResponseInfo(ctx context.Context, r *ghttp.Request, code int, message any) { _ = ctx r.Response.WriteJsonExit(map[string]interface{}{ "success": false, "code": code, "message": fmt.Sprintf("服务不可用:%s", message), }) r.Exit() }