Files
quyun-v2/backend/app/services/tenant.go

137 lines
3.7 KiB
Go

package services
import (
"context"
"errors"
"quyun/v2/app/errorx"
"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) (*dto.TenantProfile, error) {
tid := cast.ToInt64(id)
t, err := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.ID.Eq(tid)).First()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errorx.ErrRecordNotFound
}
return nil, errorx.ErrDatabaseError.WithCause(err)
}
// Stats
followers, _ := models.TenantUserQuery.WithContext(ctx).Where(models.TenantUserQuery.TenantID.Eq(tid)).Count()
contents, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.TenantID.Eq(tid), models.ContentQuery.Status.Eq(consts.ContentStatusPublished)).Count()
// Following status
isFollowing := false
if userID := ctx.Value(consts.CtxKeyUser); userID != nil {
uid := cast.ToInt64(userID)
isFollowing, _ = models.TenantUserQuery.WithContext(ctx).
Where(models.TenantUserQuery.TenantID.Eq(tid), models.TenantUserQuery.UserID.Eq(uid)).
Exists()
}
return &dto.TenantProfile{
ID: cast.ToString(t.ID),
Name: t.Name,
Avatar: "", // Extract from config if available
Stats: dto.Stats{
Followers: int(followers),
Contents: int(contents),
},
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
if _, err := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.ID.Eq(tid)).First(); err != nil {
return errorx.ErrRecordNotFound
}
tu := &models.TenantUser{
TenantID: tid,
UserID: uid,
Role: types.Array[consts.TenantUserRole]{consts.TenantUserRoleMember},
Status: consts.UserStatusVerified,
}
if err := models.TenantUserQuery.WithContext(ctx).Save(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
}
func (s *tenant) ListFollowed(ctx context.Context) ([]dto.TenantProfile, error) {
userID := ctx.Value(consts.CtxKeyUser)
if userID == nil {
return nil, errorx.ErrUnauthorized
}
uid := cast.ToInt64(userID)
tbl, q := models.TenantUserQuery.QueryContext(ctx)
list, err := q.Where(tbl.UserID.Eq(uid)).Find()
if err != nil {
return nil, errorx.ErrDatabaseError.WithCause(err)
}
var data []dto.TenantProfile
for _, tu := range list {
// Fetch Tenant
t, err := models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.ID.Eq(tu.TenantID)).First()
if err != nil {
continue
}
// Stats
followers, _ := models.TenantUserQuery.WithContext(ctx).Where(models.TenantUserQuery.TenantID.Eq(tu.TenantID)).Count()
contents, _ := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.TenantID.Eq(tu.TenantID), models.ContentQuery.Status.Eq(consts.ContentStatusPublished)).Count()
data = append(data, dto.TenantProfile{
ID: cast.ToString(t.ID),
Name: t.Name,
Avatar: "",
Stats: dto.Stats{
Followers: int(followers),
Contents: int(contents),
},
IsFollowing: true,
})
}
return data, nil
}