package services import ( "context" "errors" "quyun/v2/app/errorx" tenant_dto "quyun/v2/app/http/v1/dto" "quyun/v2/database/models" "quyun/v2/pkg/consts" "github.com/spf13/cast" "go.ipao.vip/gen/types" "gorm.io/gorm" ) // @provider type tenant struct{} func (s *tenant) GetPublicProfile(ctx context.Context, id string) (*tenant_dto.TenantProfile, error) { // id could be Code or ID. Try Code first, then ID. tbl, q := models.TenantQuery.QueryContext(ctx) // Try to find by code or ID var t *models.Tenant var err error // Assume id is ID for simplicity if numeric, or try both. if cast.ToInt64(id) > 0 { t, err = q.Where(tbl.ID.Eq(cast.ToInt64(id))).First() } else { t, err = q.Where(tbl.Code.Eq(id)).First() } if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errorx.ErrRecordNotFound } return nil, errorx.ErrDatabaseError.WithCause(err) } // Stats // Followers followers, _ := models.TenantUserQuery.WithContext(ctx).Where(models.TenantUserQuery.TenantID.Eq(t.ID)).Count() // Contents contentsCount, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.TenantID.Eq(t.ID), models.ContentQuery.Status.Eq(consts.ContentStatusPublished)).Count() // Likes var likes int64 // Sum content likes // Mock likes for now or fetch // IsFollowing isFollowing := false userID := ctx.Value(consts.CtxKeyUser) if userID != nil { uid := cast.ToInt64(userID) count, _ := models.TenantUserQuery.WithContext(ctx).Where(models.TenantUserQuery.TenantID.Eq(t.ID), models.TenantUserQuery.UserID.Eq(uid)).Count() isFollowing = count > 0 } // Config parsing (Unused for now as we don't map to bio yet) // config := t.Config.Data() return &tenant_dto.TenantProfile{ ID: cast.ToString(t.ID), Name: t.Name, Avatar: "", // From config Cover: "", // From config Bio: "", // From config Description: "", // From config CertType: "personal", // Mock Stats: tenant_dto.Stats{ Followers: int(followers), Contents: int(contentsCount), Likes: int(likes), }, IsFollowing: isFollowing, }, nil } func (s *tenant) Follow(ctx context.Context, id string) error { userID := ctx.Value(consts.CtxKeyUser) if userID == nil { return errorx.ErrUnauthorized } uid := cast.ToInt64(userID) tid := cast.ToInt64(id) // Check if tenant exists _, err := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.ID.Eq(tid)).First() if err != nil { return errorx.ErrRecordNotFound } // Add to tenant_users tu := &models.TenantUser{ TenantID: tid, UserID: uid, Role: types.Array[consts.TenantUserRole]{consts.TenantUserRoleMember}, Status: consts.UserStatusVerified, } count, _ := models.TenantUserQuery.WithContext(ctx).Where(models.TenantUserQuery.TenantID.Eq(tid), models.TenantUserQuery.UserID.Eq(uid)).Count() if count > 0 { return nil // Already following } if err := models.TenantUserQuery.WithContext(ctx).Create(tu); err != nil { return errorx.ErrDatabaseError.WithCause(err) } return nil } func (s *tenant) Unfollow(ctx context.Context, id string) error { userID := ctx.Value(consts.CtxKeyUser) if userID == nil { return errorx.ErrUnauthorized } uid := cast.ToInt64(userID) tid := cast.ToInt64(id) _, err := models.TenantUserQuery.WithContext(ctx).Where(models.TenantUserQuery.TenantID.Eq(tid), models.TenantUserQuery.UserID.Eq(uid)).Delete() if err != nil { return errorx.ErrDatabaseError.WithCause(err) } return nil }