feat: tenant-scoped routing and portal navigation

This commit is contained in:
2026-01-08 21:30:46 +08:00
parent f3aa92078a
commit 3e095c57f3
52 changed files with 1111 additions and 670 deletions

View File

@@ -3,6 +3,8 @@ package auth
import (
"quyun/v2/app/http/v1/dto"
"quyun/v2/app/services"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"github.com/gofiber/fiber/v3"
)
@@ -12,7 +14,7 @@ type Auth struct{}
// SendOTP sends an OTP to the provided phone number.
//
// @Router /v1/auth/otp [post]
// @Router /t/:tenantCode/v1/auth/otp [post]
// @Summary Send OTP
// @Description Send OTP to phone number
// @Tags Auth
@@ -27,7 +29,7 @@ func (a *Auth) SendOTP(ctx fiber.Ctx, form *dto.SendOTPForm) error {
// Login logs in or registers a user with OTP.
//
// @Router /v1/auth/login [post]
// @Router /t/:tenantCode/v1/auth/login [post]
// @Summary Login or Register with OTP
// @Description Login or register user using phone number and OTP
// @Tags Auth
@@ -37,5 +39,11 @@ func (a *Auth) SendOTP(ctx fiber.Ctx, form *dto.SendOTPForm) error {
// @Success 200 {object} dto.LoginResponse
// @Bind form body
func (a *Auth) Login(ctx fiber.Ctx, form *dto.LoginForm) (*dto.LoginResponse, error) {
return services.User.LoginWithOTP(ctx, form.Phone, form.OTP)
tenantID := int64(0)
if t := ctx.Locals(consts.CtxKeyTenant); t != nil {
if tenant, ok := t.(*models.Tenant); ok {
tenantID = tenant.ID
}
}
return services.User.LoginWithOTP(ctx, tenantID, form.Phone, form.OTP)
}

View File

@@ -42,13 +42,13 @@ func (r *Routes) Name() string {
// Each route is registered with its corresponding controller action and parameter bindings.
func (r *Routes) Register(router fiber.Router) {
// Register routes for controller: Auth
r.log.Debugf("Registering route: Post /v1/auth/login -> auth.Login")
router.Post("/v1/auth/login"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/auth/login -> auth.Login")
router.Post("/t/:tenantCode/v1/auth/login"[len(r.Path()):], DataFunc1(
r.auth.Login,
Body[dto.LoginForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/auth/otp -> auth.SendOTP")
router.Post("/v1/auth/otp"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/auth/otp -> auth.SendOTP")
router.Post("/t/:tenantCode/v1/auth/otp"[len(r.Path()):], Func1(
r.auth.SendOTP,
Body[dto.SendOTPForm]("form"),
))

View File

@@ -13,7 +13,7 @@ import (
// @provider
type Common struct{}
// @Router /v1/upload [post]
// @Router /t/:tenantCode/v1/upload [post]
// @Summary Upload file
// @Description Upload file
// @Tags Common
@@ -31,16 +31,17 @@ func (c *Common) Upload(
file *multipart.FileHeader,
form *dto.UploadForm,
) (*dto.UploadResult, error) {
tenantID := getTenantID(ctx)
val := ""
if form != nil {
val = form.Type
}
return services.Common.Upload(ctx, user.ID, file, val)
return services.Common.Upload(ctx, tenantID, user.ID, file, val)
}
// Get options (enums)
//
// @Router /v1/common/options [get]
// @Router /t/:tenantCode/v1/common/options [get]
// @Summary Get options
// @Description Get global options (enums)
// @Tags Common
@@ -53,7 +54,7 @@ func (c *Common) GetOptions(ctx fiber.Ctx) (*dto.OptionsResponse, error) {
// Check file hash for deduplication
//
// @Router /v1/upload/check [get]
// @Router /t/:tenantCode/v1/upload/check [get]
// @Summary Check hash
// @Description Check if file hash exists
// @Tags Common
@@ -64,10 +65,11 @@ func (c *Common) GetOptions(ctx fiber.Ctx) (*dto.OptionsResponse, error) {
// @Bind user local key(__ctx_user)
// @Bind hash query
func (c *Common) CheckHash(ctx fiber.Ctx, user *models.User, hash string) (*dto.UploadResult, error) {
return services.Common.CheckHash(ctx, user.ID, hash)
tenantID := getTenantID(ctx)
return services.Common.CheckHash(ctx, tenantID, user.ID, hash)
}
// @Router /v1/upload/init [post]
// @Router /t/:tenantCode/v1/upload/init [post]
// @Summary Init multipart upload
// @Description Initialize multipart upload
// @Tags Common
@@ -78,10 +80,11 @@ func (c *Common) CheckHash(ctx fiber.Ctx, user *models.User, hash string) (*dto.
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Common) InitUpload(ctx fiber.Ctx, user *models.User, form *dto.UploadInitForm) (*dto.UploadInitResponse, error) {
return services.Common.InitUpload(ctx.Context(), user.ID, form)
tenantID := getTenantID(ctx)
return services.Common.InitUpload(ctx.Context(), tenantID, user.ID, form)
}
// @Router /v1/upload/part [post]
// @Router /t/:tenantCode/v1/upload/part [post]
// @Summary Upload part
// @Description Upload a part
// @Tags Common
@@ -94,10 +97,11 @@ func (c *Common) InitUpload(ctx fiber.Ctx, user *models.User, form *dto.UploadIn
// @Bind file file
// @Bind form body
func (c *Common) UploadPart(ctx fiber.Ctx, user *models.User, file *multipart.FileHeader, form *dto.UploadPartForm) error {
return services.Common.UploadPart(ctx.Context(), user.ID, file, form)
tenantID := getTenantID(ctx)
return services.Common.UploadPart(ctx.Context(), tenantID, user.ID, file, form)
}
// @Router /v1/upload/complete [post]
// @Router /t/:tenantCode/v1/upload/complete [post]
// @Summary Complete upload
// @Description Complete multipart upload
// @Tags Common
@@ -108,10 +112,11 @@ func (c *Common) UploadPart(ctx fiber.Ctx, user *models.User, file *multipart.Fi
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Common) CompleteUpload(ctx fiber.Ctx, user *models.User, form *dto.UploadCompleteForm) (*dto.UploadResult, error) {
return services.Common.CompleteUpload(ctx.Context(), user.ID, form)
tenantID := getTenantID(ctx)
return services.Common.CompleteUpload(ctx.Context(), tenantID, user.ID, form)
}
// @Router /v1/upload/:uploadId [delete]
// @Router /t/:tenantCode/v1/upload/:uploadId [delete]
// @Summary Abort upload
// @Description Abort multipart upload
// @Tags Common
@@ -122,10 +127,11 @@ func (c *Common) CompleteUpload(ctx fiber.Ctx, user *models.User, form *dto.Uplo
// @Bind user local key(__ctx_user)
// @Bind uploadId path
func (c *Common) AbortUpload(ctx fiber.Ctx, user *models.User, uploadId string) error {
return services.Common.AbortUpload(ctx.Context(), user.ID, uploadId)
tenantID := getTenantID(ctx)
return services.Common.AbortUpload(ctx.Context(), tenantID, user.ID, uploadId)
}
// @Router /v1/media-assets/:id<int> [delete]
// @Router /t/:tenantCode/v1/media-assets/:id<int> [delete]
// @Summary Delete media asset
// @Description Delete media asset
// @Tags Common
@@ -136,7 +142,8 @@ func (c *Common) AbortUpload(ctx fiber.Ctx, user *models.User, uploadId string)
// @Bind user local key(__ctx_user)
// @Bind id path
func (c *Common) DeleteMediaAsset(ctx fiber.Ctx, user *models.User, id int64) error {
return services.Common.DeleteMediaAsset(ctx.Context(), user.ID, id)
tenantID := getTenantID(ctx)
return services.Common.DeleteMediaAsset(ctx.Context(), tenantID, user.ID, id)
}
// Upload file

View File

@@ -1,11 +1,10 @@
package v1
import (
"quyun/v2/app/errorx"
"quyun/v2/app/http/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"github.com/gofiber/fiber/v3"
)
@@ -15,7 +14,7 @@ type Content struct{}
// List contents (Explore / Search)
//
// @Router /v1/contents [get]
// @Router /t/:tenantCode/v1/contents [get]
// @Summary List contents
// @Description List contents with filtering and pagination
// @Tags Content
@@ -32,12 +31,19 @@ func (c *Content) List(
ctx fiber.Ctx,
filter *dto.ContentListFilter,
) (*requests.Pager, error) {
return services.Content.List(ctx, filter)
tenantID := getTenantID(ctx)
if tenantID > 0 {
if filter.TenantID != nil && *filter.TenantID != tenantID {
return nil, errorx.ErrForbidden.WithMsg("租户不匹配")
}
filter.TenantID = &tenantID
}
return services.Content.List(ctx, tenantID, filter)
}
// Get content detail
//
// @Router /v1/contents/:id<int> [get]
// @Router /t/:tenantCode/v1/contents/:id<int> [get]
// @Summary Get content detail
// @Description Get content detail by ID
// @Tags Content
@@ -47,13 +53,14 @@ func (c *Content) List(
// @Success 200 {object} dto.ContentDetail
// @Bind id path
func (c *Content) Get(ctx fiber.Ctx, id int64) (*dto.ContentDetail, error) {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.Get(ctx, uid, id)
return services.Content.Get(ctx, tenantID, uid, id)
}
// Get comments for a content
//
// @Router /v1/contents/:id<int>/comments [get]
// @Router /t/:tenantCode/v1/contents/:id<int>/comments [get]
// @Summary Get comments
// @Description Get comments for a content
// @Tags Content
@@ -65,13 +72,14 @@ func (c *Content) Get(ctx fiber.Ctx, id int64) (*dto.ContentDetail, error) {
// @Bind id path
// @Bind page query
func (c *Content) ListComments(ctx fiber.Ctx, id int64, page int) (*requests.Pager, error) {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.ListComments(ctx, uid, id, page)
return services.Content.ListComments(ctx, tenantID, uid, id, page)
}
// Post a comment
//
// @Router /v1/contents/:id<int>/comments [post]
// @Router /t/:tenantCode/v1/contents/:id<int>/comments [post]
// @Summary Post comment
// @Description Post a comment to a content
// @Tags Content
@@ -83,13 +91,14 @@ func (c *Content) ListComments(ctx fiber.Ctx, id int64, page int) (*requests.Pag
// @Bind id path
// @Bind form body
func (c *Content) CreateComment(ctx fiber.Ctx, id int64, form *dto.CommentCreateForm) error {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.CreateComment(ctx, uid, id, form)
return services.Content.CreateComment(ctx, tenantID, uid, id, form)
}
// Like a comment
//
// @Router /v1/comments/:id<int>/like [post]
// @Router /t/:tenantCode/v1/comments/:id<int>/like [post]
// @Summary Like comment
// @Description Like a comment
// @Tags Content
@@ -99,65 +108,70 @@ func (c *Content) CreateComment(ctx fiber.Ctx, id int64, form *dto.CommentCreate
// @Success 200 {string} string "Liked"
// @Bind id path
func (c *Content) LikeComment(ctx fiber.Ctx, id int64) error {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.LikeComment(ctx, uid, id)
return services.Content.LikeComment(ctx, tenantID, uid, id)
}
// Add like
//
// @Router /v1/contents/:id<int>/like [post]
// @Router /t/:tenantCode/v1/contents/:id<int>/like [post]
// @Summary Add like
// @Tags Content
// @Param id path int64 true "Content ID"
// @Success 200 {string} string "Liked"
// @Bind id path
func (c *Content) AddLike(ctx fiber.Ctx, id int64) error {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.AddLike(ctx, uid, id)
return services.Content.AddLike(ctx, tenantID, uid, id)
}
// Remove like
//
// @Router /v1/contents/:id<int>/like [delete]
// @Router /t/:tenantCode/v1/contents/:id<int>/like [delete]
// @Summary Remove like
// @Tags Content
// @Param id path int64 true "Content ID"
// @Success 200 {string} string "Unliked"
// @Bind id path
func (c *Content) RemoveLike(ctx fiber.Ctx, id int64) error {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.RemoveLike(ctx, uid, id)
return services.Content.RemoveLike(ctx, tenantID, uid, id)
}
// Add favorite
//
// @Router /v1/contents/:id<int>/favorite [post]
// @Router /t/:tenantCode/v1/contents/:id<int>/favorite [post]
// @Summary Add favorite
// @Tags Content
// @Param id path int64 true "Content ID"
// @Success 200 {string} string "Favorited"
// @Bind id path
func (c *Content) AddFavorite(ctx fiber.Ctx, id int64) error {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.AddFavorite(ctx, uid, id)
return services.Content.AddFavorite(ctx, tenantID, uid, id)
}
// Remove favorite
//
// @Router /v1/contents/:id<int>/favorite [delete]
// @Router /t/:tenantCode/v1/contents/:id<int>/favorite [delete]
// @Summary Remove favorite
// @Tags Content
// @Param id path int64 true "Content ID"
// @Success 200 {string} string "Unfavorited"
// @Bind id path
func (c *Content) RemoveFavorite(ctx fiber.Ctx, id int64) error {
tenantID := getTenantID(ctx)
uid := getUserID(ctx)
return services.Content.RemoveFavorite(ctx, uid, id)
return services.Content.RemoveFavorite(ctx, tenantID, uid, id)
}
// List curated topics
//
// @Router /v1/topics [get]
// @Router /t/:tenantCode/v1/topics [get]
// @Summary List topics
// @Description List curated topics
// @Tags Content
@@ -165,14 +179,6 @@ func (c *Content) RemoveFavorite(ctx fiber.Ctx, id int64) error {
// @Produce json
// @Success 200 {array} dto.Topic
func (c *Content) ListTopics(ctx fiber.Ctx) ([]dto.Topic, error) {
return services.Content.ListTopics(ctx)
}
func getUserID(ctx fiber.Ctx) int64 {
if u := ctx.Locals(consts.CtxKeyUser); u != nil {
if user, ok := u.(*models.User); ok {
return user.ID
}
}
return 0
tenantID := getTenantID(ctx)
return services.Content.ListTopics(ctx, tenantID)
}

View File

@@ -14,7 +14,7 @@ type Creator struct{}
// Apply to become a creator
//
// @Router /v1/creator/apply [post]
// @Router /t/:tenantCode/v1/creator/apply [post]
// @Summary Apply creator
// @Description Apply to become a creator
// @Tags CreatorCenter
@@ -25,12 +25,13 @@ type Creator struct{}
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Creator) Apply(ctx fiber.Ctx, user *models.User, form *dto.ApplyForm) error {
return services.Creator.Apply(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Creator.Apply(ctx, tenantID, user.ID, form)
}
// Get creator dashboard stats
//
// @Router /v1/creator/dashboard [get]
// @Router /t/:tenantCode/v1/creator/dashboard [get]
// @Summary Dashboard stats
// @Description Get creator dashboard stats
// @Tags CreatorCenter
@@ -39,12 +40,13 @@ func (c *Creator) Apply(ctx fiber.Ctx, user *models.User, form *dto.ApplyForm) e
// @Success 200 {object} dto.DashboardStats
// @Bind user local key(__ctx_user)
func (c *Creator) Dashboard(ctx fiber.Ctx, user *models.User) (*dto.DashboardStats, error) {
return services.Creator.Dashboard(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Creator.Dashboard(ctx, tenantID, user.ID)
}
// Get content details for edit
//
// @Router /v1/creator/contents/:id<int> [get]
// @Router /t/:tenantCode/v1/creator/contents/:id<int> [get]
// @Summary Get content
// @Description Get content details for edit
// @Tags CreatorCenter
@@ -55,12 +57,13 @@ func (c *Creator) Dashboard(ctx fiber.Ctx, user *models.User) (*dto.DashboardSta
// @Bind user local key(__ctx_user)
// @Bind id path
func (c *Creator) GetContent(ctx fiber.Ctx, user *models.User, id int64) (*dto.ContentEditDTO, error) {
return services.Creator.GetContent(ctx, user.ID, id)
tenantID := getTenantID(ctx)
return services.Creator.GetContent(ctx, tenantID, user.ID, id)
}
// List creator contents
//
// @Router /v1/creator/contents [get]
// @Router /t/:tenantCode/v1/creator/contents [get]
// @Summary List contents
// @Description List creator contents
// @Tags CreatorCenter
@@ -77,12 +80,13 @@ func (c *Creator) ListContents(
user *models.User,
filter *dto.CreatorContentListFilter,
) (*requests.Pager, error) {
return services.Creator.ListContents(ctx, user.ID, filter)
tenantID := getTenantID(ctx)
return services.Creator.ListContents(ctx, tenantID, user.ID, filter)
}
// Create/Publish content
//
// @Router /v1/creator/contents [post]
// @Router /t/:tenantCode/v1/creator/contents [post]
// @Summary Create content
// @Description Create/Publish content
// @Tags CreatorCenter
@@ -93,12 +97,13 @@ func (c *Creator) ListContents(
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Creator) CreateContent(ctx fiber.Ctx, user *models.User, form *dto.ContentCreateForm) error {
return services.Creator.CreateContent(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Creator.CreateContent(ctx, tenantID, user.ID, form)
}
// Update content
//
// @Router /v1/creator/contents/:id<int> [put]
// @Router /t/:tenantCode/v1/creator/contents/:id<int> [put]
// @Summary Update content
// @Description Update content
// @Tags CreatorCenter
@@ -111,12 +116,13 @@ func (c *Creator) CreateContent(ctx fiber.Ctx, user *models.User, form *dto.Cont
// @Bind id path
// @Bind form body
func (c *Creator) UpdateContent(ctx fiber.Ctx, user *models.User, id int64, form *dto.ContentUpdateForm) error {
return services.Creator.UpdateContent(ctx, user.ID, id, form)
tenantID := getTenantID(ctx)
return services.Creator.UpdateContent(ctx, tenantID, user.ID, id, form)
}
// Delete content
//
// @Router /v1/creator/contents/:id<int> [delete]
// @Router /t/:tenantCode/v1/creator/contents/:id<int> [delete]
// @Summary Delete content
// @Description Delete content
// @Tags CreatorCenter
@@ -127,12 +133,13 @@ func (c *Creator) UpdateContent(ctx fiber.Ctx, user *models.User, id int64, form
// @Bind user local key(__ctx_user)
// @Bind id path
func (c *Creator) DeleteContent(ctx fiber.Ctx, user *models.User, id int64) error {
return services.Creator.DeleteContent(ctx, user.ID, id)
tenantID := getTenantID(ctx)
return services.Creator.DeleteContent(ctx, tenantID, user.ID, id)
}
// List sales orders
//
// @Router /v1/creator/orders [get]
// @Router /t/:tenantCode/v1/creator/orders [get]
// @Summary List sales orders
// @Description List sales orders
// @Tags CreatorCenter
@@ -148,12 +155,13 @@ func (c *Creator) ListOrders(
user *models.User,
filter *dto.CreatorOrderListFilter,
) ([]dto.Order, error) {
return services.Creator.ListOrders(ctx, user.ID, filter)
tenantID := getTenantID(ctx)
return services.Creator.ListOrders(ctx, tenantID, user.ID, filter)
}
// Process refund
//
// @Router /v1/creator/orders/:id<int>/refund [post]
// @Router /t/:tenantCode/v1/creator/orders/:id<int>/refund [post]
// @Summary Process refund
// @Description Process refund
// @Tags CreatorCenter
@@ -166,12 +174,13 @@ func (c *Creator) ListOrders(
// @Bind id path
// @Bind form body
func (c *Creator) Refund(ctx fiber.Ctx, user *models.User, id int64, form *dto.RefundForm) error {
return services.Creator.ProcessRefund(ctx, user.ID, id, form)
tenantID := getTenantID(ctx)
return services.Creator.ProcessRefund(ctx, tenantID, user.ID, id, form)
}
// Get channel settings
//
// @Router /v1/creator/settings [get]
// @Router /t/:tenantCode/v1/creator/settings [get]
// @Summary Get settings
// @Description Get channel settings
// @Tags CreatorCenter
@@ -180,12 +189,13 @@ func (c *Creator) Refund(ctx fiber.Ctx, user *models.User, id int64, form *dto.R
// @Success 200 {object} dto.Settings
// @Bind user local key(__ctx_user)
func (c *Creator) GetSettings(ctx fiber.Ctx, user *models.User) (*dto.Settings, error) {
return services.Creator.GetSettings(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Creator.GetSettings(ctx, tenantID, user.ID)
}
// Update channel settings
//
// @Router /v1/creator/settings [put]
// @Router /t/:tenantCode/v1/creator/settings [put]
// @Summary Update settings
// @Description Update channel settings
// @Tags CreatorCenter
@@ -196,12 +206,13 @@ func (c *Creator) GetSettings(ctx fiber.Ctx, user *models.User) (*dto.Settings,
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Creator) UpdateSettings(ctx fiber.Ctx, user *models.User, form *dto.Settings) error {
return services.Creator.UpdateSettings(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Creator.UpdateSettings(ctx, tenantID, user.ID, form)
}
// List payout accounts
//
// @Router /v1/creator/payout-accounts [get]
// @Router /t/:tenantCode/v1/creator/payout-accounts [get]
// @Summary List payout accounts
// @Description List payout accounts
// @Tags CreatorCenter
@@ -210,12 +221,13 @@ func (c *Creator) UpdateSettings(ctx fiber.Ctx, user *models.User, form *dto.Set
// @Success 200 {array} dto.PayoutAccount
// @Bind user local key(__ctx_user)
func (c *Creator) ListPayoutAccounts(ctx fiber.Ctx, user *models.User) ([]dto.PayoutAccount, error) {
return services.Creator.ListPayoutAccounts(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Creator.ListPayoutAccounts(ctx, tenantID, user.ID)
}
// Add payout account
//
// @Router /v1/creator/payout-accounts [post]
// @Router /t/:tenantCode/v1/creator/payout-accounts [post]
// @Summary Add payout account
// @Description Add payout account
// @Tags CreatorCenter
@@ -226,12 +238,13 @@ func (c *Creator) ListPayoutAccounts(ctx fiber.Ctx, user *models.User) ([]dto.Pa
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Creator) AddPayoutAccount(ctx fiber.Ctx, user *models.User, form *dto.PayoutAccount) error {
return services.Creator.AddPayoutAccount(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Creator.AddPayoutAccount(ctx, tenantID, user.ID, form)
}
// Remove payout account
//
// @Router /v1/creator/payout-accounts [delete]
// @Router /t/:tenantCode/v1/creator/payout-accounts [delete]
// @Summary Remove payout account
// @Description Remove payout account
// @Tags CreatorCenter
@@ -242,12 +255,13 @@ func (c *Creator) AddPayoutAccount(ctx fiber.Ctx, user *models.User, form *dto.P
// @Bind user local key(__ctx_user)
// @Bind id query
func (c *Creator) RemovePayoutAccount(ctx fiber.Ctx, user *models.User, id int64) error {
return services.Creator.RemovePayoutAccount(ctx, user.ID, id)
tenantID := getTenantID(ctx)
return services.Creator.RemovePayoutAccount(ctx, tenantID, user.ID, id)
}
// Request withdrawal
//
// @Router /v1/creator/withdraw [post]
// @Router /t/:tenantCode/v1/creator/withdraw [post]
// @Summary Request withdrawal
// @Description Request withdrawal
// @Tags CreatorCenter
@@ -258,5 +272,6 @@ func (c *Creator) RemovePayoutAccount(ctx fiber.Ctx, user *models.User, id int64
// @Bind user local key(__ctx_user)
// @Bind form body
func (c *Creator) Withdraw(ctx fiber.Ctx, user *models.User, form *dto.WithdrawForm) error {
return services.Creator.Withdraw(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Creator.Withdraw(ctx, tenantID, user.ID, form)
}

View File

@@ -0,0 +1,26 @@
package v1
import (
"quyun/v2/database/models"
"quyun/v2/pkg/consts"
"github.com/gofiber/fiber/v3"
)
func getUserID(ctx fiber.Ctx) int64 {
if u := ctx.Locals(consts.CtxKeyUser); u != nil {
if user, ok := u.(*models.User); ok {
return user.ID
}
}
return 0
}
func getTenantID(ctx fiber.Ctx) int64 {
if t := ctx.Locals(consts.CtxKeyTenant); t != nil {
if tenant, ok := t.(*models.Tenant); ok {
return tenant.ID
}
}
return 0
}

View File

@@ -50,368 +50,368 @@ func (r *Routes) Name() string {
// Each route is registered with its corresponding controller action and parameter bindings.
func (r *Routes) Register(router fiber.Router) {
// Register routes for controller: Common
r.log.Debugf("Registering route: Delete /v1/media-assets/:id<int> -> common.DeleteMediaAsset")
router.Delete("/v1/media-assets/:id<int>"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/media-assets/:id<int> -> common.DeleteMediaAsset")
router.Delete("/t/:tenantCode/v1/media-assets/:id<int>"[len(r.Path()):], Func2(
r.common.DeleteMediaAsset,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Delete /v1/upload/:uploadId -> common.AbortUpload")
router.Delete("/v1/upload/:uploadId"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/upload/:uploadId -> common.AbortUpload")
router.Delete("/t/:tenantCode/v1/upload/:uploadId"[len(r.Path()):], Func2(
r.common.AbortUpload,
Local[*models.User]("__ctx_user"),
PathParam[string]("uploadId"),
))
r.log.Debugf("Registering route: Get /v1/common/options -> common.GetOptions")
router.Get("/v1/common/options"[len(r.Path()):], DataFunc0(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/common/options -> common.GetOptions")
router.Get("/t/:tenantCode/v1/common/options"[len(r.Path()):], DataFunc0(
r.common.GetOptions,
))
r.log.Debugf("Registering route: Get /v1/upload/check -> common.CheckHash")
router.Get("/v1/upload/check"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/upload/check -> common.CheckHash")
router.Get("/t/:tenantCode/v1/upload/check"[len(r.Path()):], DataFunc2(
r.common.CheckHash,
Local[*models.User]("__ctx_user"),
QueryParam[string]("hash"),
))
r.log.Debugf("Registering route: Post /v1/upload -> common.Upload")
router.Post("/v1/upload"[len(r.Path()):], DataFunc3(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/upload -> common.Upload")
router.Post("/t/:tenantCode/v1/upload"[len(r.Path()):], DataFunc3(
r.common.Upload,
Local[*models.User]("__ctx_user"),
File[multipart.FileHeader]("file"),
Body[dto.UploadForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/upload/complete -> common.CompleteUpload")
router.Post("/v1/upload/complete"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/upload/complete -> common.CompleteUpload")
router.Post("/t/:tenantCode/v1/upload/complete"[len(r.Path()):], DataFunc2(
r.common.CompleteUpload,
Local[*models.User]("__ctx_user"),
Body[dto.UploadCompleteForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/upload/init -> common.InitUpload")
router.Post("/v1/upload/init"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/upload/init -> common.InitUpload")
router.Post("/t/:tenantCode/v1/upload/init"[len(r.Path()):], DataFunc2(
r.common.InitUpload,
Local[*models.User]("__ctx_user"),
Body[dto.UploadInitForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/upload/part -> common.UploadPart")
router.Post("/v1/upload/part"[len(r.Path()):], Func3(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/upload/part -> common.UploadPart")
router.Post("/t/:tenantCode/v1/upload/part"[len(r.Path()):], Func3(
r.common.UploadPart,
Local[*models.User]("__ctx_user"),
File[multipart.FileHeader]("file"),
Body[dto.UploadPartForm]("form"),
))
// Register routes for controller: Content
r.log.Debugf("Registering route: Delete /v1/contents/:id<int>/favorite -> content.RemoveFavorite")
router.Delete("/v1/contents/:id<int>/favorite"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/contents/:id<int>/favorite -> content.RemoveFavorite")
router.Delete("/t/:tenantCode/v1/contents/:id<int>/favorite"[len(r.Path()):], Func1(
r.content.RemoveFavorite,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Delete /v1/contents/:id<int>/like -> content.RemoveLike")
router.Delete("/v1/contents/:id<int>/like"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/contents/:id<int>/like -> content.RemoveLike")
router.Delete("/t/:tenantCode/v1/contents/:id<int>/like"[len(r.Path()):], Func1(
r.content.RemoveLike,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /v1/contents -> content.List")
router.Get("/v1/contents"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/contents -> content.List")
router.Get("/t/:tenantCode/v1/contents"[len(r.Path()):], DataFunc1(
r.content.List,
Query[dto.ContentListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /v1/contents/:id<int> -> content.Get")
router.Get("/v1/contents/:id<int>"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/contents/:id<int> -> content.Get")
router.Get("/t/:tenantCode/v1/contents/:id<int>"[len(r.Path()):], DataFunc1(
r.content.Get,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /v1/contents/:id<int>/comments -> content.ListComments")
router.Get("/v1/contents/:id<int>/comments"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/contents/:id<int>/comments -> content.ListComments")
router.Get("/t/:tenantCode/v1/contents/:id<int>/comments"[len(r.Path()):], DataFunc2(
r.content.ListComments,
PathParam[int64]("id"),
QueryParam[int]("page"),
))
r.log.Debugf("Registering route: Get /v1/topics -> content.ListTopics")
router.Get("/v1/topics"[len(r.Path()):], DataFunc0(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/topics -> content.ListTopics")
router.Get("/t/:tenantCode/v1/topics"[len(r.Path()):], DataFunc0(
r.content.ListTopics,
))
r.log.Debugf("Registering route: Post /v1/comments/:id<int>/like -> content.LikeComment")
router.Post("/v1/comments/:id<int>/like"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/comments/:id<int>/like -> content.LikeComment")
router.Post("/t/:tenantCode/v1/comments/:id<int>/like"[len(r.Path()):], Func1(
r.content.LikeComment,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Post /v1/contents/:id<int>/comments -> content.CreateComment")
router.Post("/v1/contents/:id<int>/comments"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/contents/:id<int>/comments -> content.CreateComment")
router.Post("/t/:tenantCode/v1/contents/:id<int>/comments"[len(r.Path()):], Func2(
r.content.CreateComment,
PathParam[int64]("id"),
Body[dto.CommentCreateForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/contents/:id<int>/favorite -> content.AddFavorite")
router.Post("/v1/contents/:id<int>/favorite"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/contents/:id<int>/favorite -> content.AddFavorite")
router.Post("/t/:tenantCode/v1/contents/:id<int>/favorite"[len(r.Path()):], Func1(
r.content.AddFavorite,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Post /v1/contents/:id<int>/like -> content.AddLike")
router.Post("/v1/contents/:id<int>/like"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/contents/:id<int>/like -> content.AddLike")
router.Post("/t/:tenantCode/v1/contents/:id<int>/like"[len(r.Path()):], Func1(
r.content.AddLike,
PathParam[int64]("id"),
))
// Register routes for controller: Creator
r.log.Debugf("Registering route: Delete /v1/creator/contents/:id<int> -> creator.DeleteContent")
router.Delete("/v1/creator/contents/:id<int>"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/creator/contents/:id<int> -> creator.DeleteContent")
router.Delete("/t/:tenantCode/v1/creator/contents/:id<int>"[len(r.Path()):], Func2(
r.creator.DeleteContent,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Delete /v1/creator/payout-accounts -> creator.RemovePayoutAccount")
router.Delete("/v1/creator/payout-accounts"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/creator/payout-accounts -> creator.RemovePayoutAccount")
router.Delete("/t/:tenantCode/v1/creator/payout-accounts"[len(r.Path()):], Func2(
r.creator.RemovePayoutAccount,
Local[*models.User]("__ctx_user"),
QueryParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /v1/creator/contents -> creator.ListContents")
router.Get("/v1/creator/contents"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creator/contents -> creator.ListContents")
router.Get("/t/:tenantCode/v1/creator/contents"[len(r.Path()):], DataFunc2(
r.creator.ListContents,
Local[*models.User]("__ctx_user"),
Query[dto.CreatorContentListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /v1/creator/contents/:id<int> -> creator.GetContent")
router.Get("/v1/creator/contents/:id<int>"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creator/contents/:id<int> -> creator.GetContent")
router.Get("/t/:tenantCode/v1/creator/contents/:id<int>"[len(r.Path()):], DataFunc2(
r.creator.GetContent,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /v1/creator/dashboard -> creator.Dashboard")
router.Get("/v1/creator/dashboard"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creator/dashboard -> creator.Dashboard")
router.Get("/t/:tenantCode/v1/creator/dashboard"[len(r.Path()):], DataFunc1(
r.creator.Dashboard,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/creator/orders -> creator.ListOrders")
router.Get("/v1/creator/orders"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creator/orders -> creator.ListOrders")
router.Get("/t/:tenantCode/v1/creator/orders"[len(r.Path()):], DataFunc2(
r.creator.ListOrders,
Local[*models.User]("__ctx_user"),
Query[dto.CreatorOrderListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /v1/creator/payout-accounts -> creator.ListPayoutAccounts")
router.Get("/v1/creator/payout-accounts"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creator/payout-accounts -> creator.ListPayoutAccounts")
router.Get("/t/:tenantCode/v1/creator/payout-accounts"[len(r.Path()):], DataFunc1(
r.creator.ListPayoutAccounts,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/creator/settings -> creator.GetSettings")
router.Get("/v1/creator/settings"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creator/settings -> creator.GetSettings")
router.Get("/t/:tenantCode/v1/creator/settings"[len(r.Path()):], DataFunc1(
r.creator.GetSettings,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Post /v1/creator/apply -> creator.Apply")
router.Post("/v1/creator/apply"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/creator/apply -> creator.Apply")
router.Post("/t/:tenantCode/v1/creator/apply"[len(r.Path()):], Func2(
r.creator.Apply,
Local[*models.User]("__ctx_user"),
Body[dto.ApplyForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/creator/contents -> creator.CreateContent")
router.Post("/v1/creator/contents"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/creator/contents -> creator.CreateContent")
router.Post("/t/:tenantCode/v1/creator/contents"[len(r.Path()):], Func2(
r.creator.CreateContent,
Local[*models.User]("__ctx_user"),
Body[dto.ContentCreateForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/creator/orders/:id<int>/refund -> creator.Refund")
router.Post("/v1/creator/orders/:id<int>/refund"[len(r.Path()):], Func3(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/creator/orders/:id<int>/refund -> creator.Refund")
router.Post("/t/:tenantCode/v1/creator/orders/:id<int>/refund"[len(r.Path()):], Func3(
r.creator.Refund,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.RefundForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/creator/payout-accounts -> creator.AddPayoutAccount")
router.Post("/v1/creator/payout-accounts"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/creator/payout-accounts -> creator.AddPayoutAccount")
router.Post("/t/:tenantCode/v1/creator/payout-accounts"[len(r.Path()):], Func2(
r.creator.AddPayoutAccount,
Local[*models.User]("__ctx_user"),
Body[dto.PayoutAccount]("form"),
))
r.log.Debugf("Registering route: Post /v1/creator/withdraw -> creator.Withdraw")
router.Post("/v1/creator/withdraw"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/creator/withdraw -> creator.Withdraw")
router.Post("/t/:tenantCode/v1/creator/withdraw"[len(r.Path()):], Func2(
r.creator.Withdraw,
Local[*models.User]("__ctx_user"),
Body[dto.WithdrawForm]("form"),
))
r.log.Debugf("Registering route: Put /v1/creator/contents/:id<int> -> creator.UpdateContent")
router.Put("/v1/creator/contents/:id<int>"[len(r.Path()):], Func3(
r.log.Debugf("Registering route: Put /t/:tenantCode/v1/creator/contents/:id<int> -> creator.UpdateContent")
router.Put("/t/:tenantCode/v1/creator/contents/:id<int>"[len(r.Path()):], Func3(
r.creator.UpdateContent,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.ContentUpdateForm]("form"),
))
r.log.Debugf("Registering route: Put /v1/creator/settings -> creator.UpdateSettings")
router.Put("/v1/creator/settings"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Put /t/:tenantCode/v1/creator/settings -> creator.UpdateSettings")
router.Put("/t/:tenantCode/v1/creator/settings"[len(r.Path()):], Func2(
r.creator.UpdateSettings,
Local[*models.User]("__ctx_user"),
Body[dto.Settings]("form"),
))
// Register routes for controller: Storage
r.log.Debugf("Registering route: Get /v1/storage/* -> storage.Download")
router.Get("/v1/storage/*"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/storage/* -> storage.Download")
router.Get("/t/:tenantCode/v1/storage/*"[len(r.Path()):], Func2(
r.storage.Download,
QueryParam[string]("expires"),
QueryParam[string]("sign"),
))
r.log.Debugf("Registering route: Put /v1/storage/* -> storage.Upload")
router.Put("/v1/storage/*"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Put /t/:tenantCode/v1/storage/* -> storage.Upload")
router.Put("/t/:tenantCode/v1/storage/*"[len(r.Path()):], DataFunc2(
r.storage.Upload,
QueryParam[string]("expires"),
QueryParam[string]("sign"),
))
// Register routes for controller: Tenant
r.log.Debugf("Registering route: Delete /v1/tenants/:id<int>/follow -> tenant.Unfollow")
router.Delete("/v1/tenants/:id<int>/follow"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/tenants/:id<int>/follow -> tenant.Unfollow")
router.Delete("/t/:tenantCode/v1/tenants/:id<int>/follow"[len(r.Path()):], Func2(
r.tenant.Unfollow,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /v1/creators/:id<int>/contents -> tenant.ListContents")
router.Get("/v1/creators/:id<int>/contents"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/creators/:id<int>/contents -> tenant.ListContents")
router.Get("/t/:tenantCode/v1/creators/:id<int>/contents"[len(r.Path()):], DataFunc2(
r.tenant.ListContents,
PathParam[int64]("id"),
Query[dto.ContentListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /v1/tenants -> tenant.List")
router.Get("/v1/tenants"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/tenants -> tenant.List")
router.Get("/t/:tenantCode/v1/tenants"[len(r.Path()):], DataFunc1(
r.tenant.List,
Query[dto.TenantListFilter]("filter"),
))
r.log.Debugf("Registering route: Get /v1/tenants/:id<int> -> tenant.Get")
router.Get("/v1/tenants/:id<int>"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/tenants/:id<int> -> tenant.Get")
router.Get("/t/:tenantCode/v1/tenants/:id<int>"[len(r.Path()):], DataFunc2(
r.tenant.Get,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Post /v1/tenants/:id<int>/follow -> tenant.Follow")
router.Post("/v1/tenants/:id<int>/follow"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/tenants/:id<int>/follow -> tenant.Follow")
router.Post("/t/:tenantCode/v1/tenants/:id<int>/follow"[len(r.Path()):], Func2(
r.tenant.Follow,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
// Register routes for controller: Transaction
r.log.Debugf("Registering route: Get /v1/orders/:id<int>/status -> transaction.Status")
router.Get("/v1/orders/:id<int>/status"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/orders/:id<int>/status -> transaction.Status")
router.Get("/t/:tenantCode/v1/orders/:id<int>/status"[len(r.Path()):], DataFunc1(
r.transaction.Status,
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Post /v1/orders -> transaction.Create")
router.Post("/v1/orders"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/orders -> transaction.Create")
router.Post("/t/:tenantCode/v1/orders"[len(r.Path()):], DataFunc2(
r.transaction.Create,
Local[*models.User]("__ctx_user"),
Body[dto.OrderCreateForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/orders/:id<int>/pay -> transaction.Pay")
router.Post("/v1/orders/:id<int>/pay"[len(r.Path()):], DataFunc3(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/orders/:id<int>/pay -> transaction.Pay")
router.Post("/t/:tenantCode/v1/orders/:id<int>/pay"[len(r.Path()):], DataFunc3(
r.transaction.Pay,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.OrderPayForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/webhook/payment/notify -> transaction.Webhook")
router.Post("/v1/webhook/payment/notify"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/webhook/payment/notify -> transaction.Webhook")
router.Post("/t/:tenantCode/v1/webhook/payment/notify"[len(r.Path()):], DataFunc1(
r.transaction.Webhook,
Body[WebhookForm]("form"),
))
// Register routes for controller: User
r.log.Debugf("Registering route: Delete /v1/me/favorites/:contentId<int> -> user.RemoveFavorite")
router.Delete("/v1/me/favorites/:contentId<int>"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/me/favorites/:contentId<int> -> user.RemoveFavorite")
router.Delete("/t/:tenantCode/v1/me/favorites/:contentId<int>"[len(r.Path()):], Func2(
r.user.RemoveFavorite,
Local[*models.User]("__ctx_user"),
PathParam[int64]("contentId"),
))
r.log.Debugf("Registering route: Delete /v1/me/likes/:contentId<int> -> user.RemoveLike")
router.Delete("/v1/me/likes/:contentId<int>"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Delete /t/:tenantCode/v1/me/likes/:contentId<int> -> user.RemoveLike")
router.Delete("/t/:tenantCode/v1/me/likes/:contentId<int>"[len(r.Path()):], Func2(
r.user.RemoveLike,
Local[*models.User]("__ctx_user"),
PathParam[int64]("contentId"),
))
r.log.Debugf("Registering route: Get /v1/me -> user.Me")
router.Get("/v1/me"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me -> user.Me")
router.Get("/t/:tenantCode/v1/me"[len(r.Path()):], DataFunc1(
r.user.Me,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/me/coupons -> user.MyCoupons")
router.Get("/v1/me/coupons"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/coupons -> user.MyCoupons")
router.Get("/t/:tenantCode/v1/me/coupons"[len(r.Path()):], DataFunc2(
r.user.MyCoupons,
Local[*models.User]("__ctx_user"),
QueryParam[string]("status"),
))
r.log.Debugf("Registering route: Get /v1/me/favorites -> user.Favorites")
router.Get("/v1/me/favorites"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/favorites -> user.Favorites")
router.Get("/t/:tenantCode/v1/me/favorites"[len(r.Path()):], DataFunc1(
r.user.Favorites,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/me/following -> user.Following")
router.Get("/v1/me/following"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/following -> user.Following")
router.Get("/t/:tenantCode/v1/me/following"[len(r.Path()):], DataFunc1(
r.user.Following,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/me/library -> user.Library")
router.Get("/v1/me/library"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/library -> user.Library")
router.Get("/t/:tenantCode/v1/me/library"[len(r.Path()):], DataFunc1(
r.user.Library,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/me/likes -> user.Likes")
router.Get("/v1/me/likes"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/likes -> user.Likes")
router.Get("/t/:tenantCode/v1/me/likes"[len(r.Path()):], DataFunc1(
r.user.Likes,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Get /v1/me/notifications -> user.Notifications")
router.Get("/v1/me/notifications"[len(r.Path()):], DataFunc3(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/notifications -> user.Notifications")
router.Get("/t/:tenantCode/v1/me/notifications"[len(r.Path()):], DataFunc3(
r.user.Notifications,
Local[*models.User]("__ctx_user"),
QueryParam[string]("type"),
QueryParam[int]("page"),
))
r.log.Debugf("Registering route: Get /v1/me/orders -> user.ListOrders")
router.Get("/v1/me/orders"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/orders -> user.ListOrders")
router.Get("/t/:tenantCode/v1/me/orders"[len(r.Path()):], DataFunc2(
r.user.ListOrders,
Local[*models.User]("__ctx_user"),
QueryParam[string]("status"),
))
r.log.Debugf("Registering route: Get /v1/me/orders/:id<int> -> user.GetOrder")
router.Get("/v1/me/orders/:id<int>"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/orders/:id<int> -> user.GetOrder")
router.Get("/t/:tenantCode/v1/me/orders/:id<int>"[len(r.Path()):], DataFunc2(
r.user.GetOrder,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Get /v1/me/wallet -> user.Wallet")
router.Get("/v1/me/wallet"[len(r.Path()):], DataFunc1(
r.log.Debugf("Registering route: Get /t/:tenantCode/v1/me/wallet -> user.Wallet")
router.Get("/t/:tenantCode/v1/me/wallet"[len(r.Path()):], DataFunc1(
r.user.Wallet,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Post /v1/me/favorites -> user.AddFavorite")
router.Post("/v1/me/favorites"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/me/favorites -> user.AddFavorite")
router.Post("/t/:tenantCode/v1/me/favorites"[len(r.Path()):], Func2(
r.user.AddFavorite,
Local[*models.User]("__ctx_user"),
QueryParam[int64]("contentId"),
))
r.log.Debugf("Registering route: Post /v1/me/likes -> user.AddLike")
router.Post("/v1/me/likes"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/me/likes -> user.AddLike")
router.Post("/t/:tenantCode/v1/me/likes"[len(r.Path()):], Func2(
r.user.AddLike,
Local[*models.User]("__ctx_user"),
QueryParam[int64]("contentId"),
))
r.log.Debugf("Registering route: Post /v1/me/notifications/:id<int>/read -> user.MarkNotificationRead")
router.Post("/v1/me/notifications/:id<int>/read"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/me/notifications/:id<int>/read -> user.MarkNotificationRead")
router.Post("/t/:tenantCode/v1/me/notifications/:id<int>/read"[len(r.Path()):], Func2(
r.user.MarkNotificationRead,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
))
r.log.Debugf("Registering route: Post /v1/me/notifications/read-all -> user.MarkAllNotificationsRead")
router.Post("/v1/me/notifications/read-all"[len(r.Path()):], Func1(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/me/notifications/read-all -> user.MarkAllNotificationsRead")
router.Post("/t/:tenantCode/v1/me/notifications/read-all"[len(r.Path()):], Func1(
r.user.MarkAllNotificationsRead,
Local[*models.User]("__ctx_user"),
))
r.log.Debugf("Registering route: Post /v1/me/realname -> user.RealName")
router.Post("/v1/me/realname"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/me/realname -> user.RealName")
router.Post("/t/:tenantCode/v1/me/realname"[len(r.Path()):], Func2(
r.user.RealName,
Local[*models.User]("__ctx_user"),
Body[dto.RealNameForm]("form"),
))
r.log.Debugf("Registering route: Post /v1/me/wallet/recharge -> user.Recharge")
router.Post("/v1/me/wallet/recharge"[len(r.Path()):], DataFunc2(
r.log.Debugf("Registering route: Post /t/:tenantCode/v1/me/wallet/recharge -> user.Recharge")
router.Post("/t/:tenantCode/v1/me/wallet/recharge"[len(r.Path()):], DataFunc2(
r.user.Recharge,
Local[*models.User]("__ctx_user"),
Body[dto.RechargeForm]("form"),
))
r.log.Debugf("Registering route: Put /v1/me -> user.Update")
router.Put("/v1/me"[len(r.Path()):], Func2(
r.log.Debugf("Registering route: Put /t/:tenantCode/v1/me -> user.Update")
router.Put("/t/:tenantCode/v1/me"[len(r.Path()):], Func2(
r.user.Update,
Local[*models.User]("__ctx_user"),
Body[dto.UserUpdate]("form"),

View File

@@ -1,11 +1,12 @@
package v1
func (r *Routes) Path() string {
return "/v1"
return "/t/:tenantCode/v1"
}
func (r *Routes) Middlewares() []any {
return []any{
r.middlewares.TenantResolver,
r.middlewares.Auth,
}
}

View File

@@ -17,7 +17,7 @@ type Storage struct {
// Upload file
//
// @Router /v1/storage/* [put]
// @Router /t/:tenantCode/v1/storage/* [put]
// @Summary Upload file
// @Tags Storage
// @Accept octet-stream
@@ -58,7 +58,7 @@ func (s *Storage) Upload(ctx fiber.Ctx, expires, sign string) (string, error) {
// Download file
//
// @Router /v1/storage/* [get]
// @Router /t/:tenantCode/v1/storage/* [get]
// @Summary Download file
// @Tags Storage
// @Accept json

View File

@@ -1,6 +1,7 @@
package v1
import (
"quyun/v2/app/errorx"
"quyun/v2/app/http/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
@@ -14,7 +15,7 @@ type Tenant struct{}
// List creator contents
//
// @Router /v1/creators/:id<int>/contents [get]
// @Router /t/:tenantCode/v1/creators/:id<int>/contents [get]
// @Summary List creator contents
// @Description List contents of a specific creator
// @Tags TenantPublic
@@ -27,16 +28,20 @@ type Tenant struct{}
// @Bind id path
// @Bind filter query
func (t *Tenant) ListContents(ctx fiber.Ctx, id int64, filter *dto.ContentListFilter) (*requests.Pager, error) {
tenantID := getTenantID(ctx)
if tenantID > 0 && id != tenantID {
return nil, errorx.ErrForbidden.WithMsg("租户不匹配")
}
if filter == nil {
filter = &dto.ContentListFilter{}
}
filter.TenantID = &id
return services.Content.List(ctx, filter)
filter.TenantID = &tenantID
return services.Content.List(ctx, tenantID, filter)
}
// List tenants (search)
//
// @Router /v1/tenants [get]
// @Router /t/:tenantCode/v1/tenants [get]
// @Summary List tenants
// @Description Search tenants
// @Tags TenantPublic
@@ -48,12 +53,13 @@ func (t *Tenant) ListContents(ctx fiber.Ctx, id int64, filter *dto.ContentListFi
// @Success 200 {object} requests.Pager
// @Bind filter query
func (t *Tenant) List(ctx fiber.Ctx, filter *dto.TenantListFilter) (*requests.Pager, error) {
return services.Tenant.List(ctx, filter)
tenantID := getTenantID(ctx)
return services.Tenant.List(ctx, tenantID, filter)
}
// Get tenant public profile
//
// @Router /v1/tenants/:id<int> [get]
// @Router /t/:tenantCode/v1/tenants/:id<int> [get]
// @Summary Get tenant profile
// @Description Get tenant public profile
// @Tags TenantPublic
@@ -68,12 +74,16 @@ func (t *Tenant) Get(ctx fiber.Ctx, user *models.User, id int64) (*dto.TenantPro
if user != nil {
uid = user.ID
}
return services.Tenant.GetPublicProfile(ctx, uid, id)
tenantID := getTenantID(ctx)
if tenantID > 0 && id != tenantID {
return nil, errorx.ErrForbidden.WithMsg("租户不匹配")
}
return services.Tenant.GetPublicProfile(ctx, tenantID, uid)
}
// Follow a tenant
//
// @Router /v1/tenants/:id<int>/follow [post]
// @Router /t/:tenantCode/v1/tenants/:id<int>/follow [post]
// @Summary Follow tenant
// @Description Follow a tenant
// @Tags TenantPublic
@@ -84,12 +94,16 @@ func (t *Tenant) Get(ctx fiber.Ctx, user *models.User, id int64) (*dto.TenantPro
// @Bind user local key(__ctx_user)
// @Bind id path
func (t *Tenant) Follow(ctx fiber.Ctx, user *models.User, id int64) error {
return services.Tenant.Follow(ctx, user.ID, id)
tenantID := getTenantID(ctx)
if tenantID > 0 && id != tenantID {
return errorx.ErrForbidden.WithMsg("租户不匹配")
}
return services.Tenant.Follow(ctx, tenantID, user.ID)
}
// Unfollow a tenant
//
// @Router /v1/tenants/:id<int>/follow [delete]
// @Router /t/:tenantCode/v1/tenants/:id<int>/follow [delete]
// @Summary Unfollow tenant
// @Description Unfollow a tenant
// @Tags TenantPublic
@@ -100,5 +114,9 @@ func (t *Tenant) Follow(ctx fiber.Ctx, user *models.User, id int64) error {
// @Bind user local key(__ctx_user)
// @Bind id path
func (t *Tenant) Unfollow(ctx fiber.Ctx, user *models.User, id int64) error {
return services.Tenant.Unfollow(ctx, user.ID, id)
tenantID := getTenantID(ctx)
if tenantID > 0 && id != tenantID {
return errorx.ErrForbidden.WithMsg("租户不匹配")
}
return services.Tenant.Unfollow(ctx, tenantID, user.ID)
}

View File

@@ -13,7 +13,7 @@ type Transaction struct{}
// Create Order
//
// @Router /v1/orders [post]
// @Router /t/:tenantCode/v1/orders [post]
// @Summary Create Order
// @Description Create Order
// @Tags Transaction
@@ -28,12 +28,13 @@ func (t *Transaction) Create(
user *models.User,
form *dto.OrderCreateForm,
) (*dto.OrderCreateResponse, error) {
return services.Order.Create(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Order.Create(ctx, tenantID, user.ID, form)
}
// Pay for order
//
// @Router /v1/orders/:id<int>/pay [post]
// @Router /t/:tenantCode/v1/orders/:id<int>/pay [post]
// @Summary Pay for order
// @Description Pay for order
// @Tags Transaction
@@ -51,12 +52,13 @@ func (t *Transaction) Pay(
id int64,
form *dto.OrderPayForm,
) (*dto.OrderPayResponse, error) {
return services.Order.Pay(ctx, user.ID, id, form)
tenantID := getTenantID(ctx)
return services.Order.Pay(ctx, tenantID, user.ID, id, form)
}
// Check order payment status
//
// @Router /v1/orders/:id<int>/status [get]
// @Router /t/:tenantCode/v1/orders/:id<int>/status [get]
// @Summary Check order status
// @Description Check order payment status
// @Tags Transaction
@@ -66,7 +68,8 @@ func (t *Transaction) Pay(
// @Success 200 {object} dto.OrderStatusResponse
// @Bind id path
func (t *Transaction) Status(ctx fiber.Ctx, id int64) (*dto.OrderStatusResponse, error) {
return services.Order.Status(ctx, id)
tenantID := getTenantID(ctx)
return services.Order.Status(ctx, tenantID, id)
}
type WebhookForm struct {
@@ -76,7 +79,7 @@ type WebhookForm struct {
// Payment Webhook
//
// @Router /v1/webhook/payment/notify [post]
// @Router /t/:tenantCode/v1/webhook/payment/notify [post]
// @Summary Payment Webhook
// @Description Payment Webhook
// @Tags Transaction
@@ -86,7 +89,8 @@ type WebhookForm struct {
// @Success 200 {string} string "success"
// @Bind form body
func (t *Transaction) Webhook(ctx fiber.Ctx, form *WebhookForm) (string, error) {
err := services.Order.ProcessExternalPayment(ctx, form.OrderID, form.ExternalID)
tenantID := getTenantID(ctx)
err := services.Order.ProcessExternalPayment(ctx, tenantID, form.OrderID, form.ExternalID)
if err != nil {
return "fail", err
}

View File

@@ -15,7 +15,7 @@ type User struct{}
// Get current user profile
//
// @Router /v1/me [get]
// @Router /t/:tenantCode/v1/me [get]
// @Summary Get user profile
// @Description Get current user profile
// @Tags UserCenter
@@ -30,7 +30,7 @@ func (u *User) Me(ctx fiber.Ctx, user *models.User) (*auth_dto.User, error) {
// Update user profile
//
// @Router /v1/me [put]
// @Router /t/:tenantCode/v1/me [put]
// @Summary Update user profile
// @Description Update user profile
// @Tags UserCenter
@@ -46,7 +46,7 @@ func (u *User) Update(ctx fiber.Ctx, user *models.User, form *dto.UserUpdate) er
// Submit real-name authentication
//
// @Router /v1/me/realname [post]
// @Router /t/:tenantCode/v1/me/realname [post]
// @Summary Realname auth
// @Description Submit real-name authentication
// @Tags UserCenter
@@ -62,7 +62,7 @@ func (u *User) RealName(ctx fiber.Ctx, user *models.User, form *dto.RealNameForm
// Get wallet balance and transactions
//
// @Router /v1/me/wallet [get]
// @Router /t/:tenantCode/v1/me/wallet [get]
// @Summary Get wallet
// @Description Get wallet balance and transactions
// @Tags UserCenter
@@ -71,12 +71,13 @@ func (u *User) RealName(ctx fiber.Ctx, user *models.User, form *dto.RealNameForm
// @Success 200 {object} dto.WalletResponse
// @Bind user local key(__ctx_user)
func (u *User) Wallet(ctx fiber.Ctx, user *models.User) (*dto.WalletResponse, error) {
return services.Wallet.GetWallet(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Wallet.GetWallet(ctx, tenantID, user.ID)
}
// Recharge wallet
//
// @Router /v1/me/wallet/recharge [post]
// @Router /t/:tenantCode/v1/me/wallet/recharge [post]
// @Summary Recharge wallet
// @Description Recharge wallet
// @Tags UserCenter
@@ -87,12 +88,13 @@ func (u *User) Wallet(ctx fiber.Ctx, user *models.User) (*dto.WalletResponse, er
// @Bind user local key(__ctx_user)
// @Bind form body
func (u *User) Recharge(ctx fiber.Ctx, user *models.User, form *dto.RechargeForm) (*dto.RechargeResponse, error) {
return services.Wallet.Recharge(ctx, user.ID, form)
tenantID := getTenantID(ctx)
return services.Wallet.Recharge(ctx, tenantID, user.ID, form)
}
// List user orders
//
// @Router /v1/me/orders [get]
// @Router /t/:tenantCode/v1/me/orders [get]
// @Summary List orders
// @Description List user orders
// @Tags UserCenter
@@ -103,12 +105,13 @@ func (u *User) Recharge(ctx fiber.Ctx, user *models.User, form *dto.RechargeForm
// @Bind user local key(__ctx_user)
// @Bind status query
func (u *User) ListOrders(ctx fiber.Ctx, user *models.User, status string) ([]dto.Order, error) {
return services.Order.ListUserOrders(ctx, user.ID, status)
tenantID := getTenantID(ctx)
return services.Order.ListUserOrders(ctx, tenantID, user.ID, status)
}
// Get user order detail
//
// @Router /v1/me/orders/:id<int> [get]
// @Router /t/:tenantCode/v1/me/orders/:id<int> [get]
// @Summary Get order detail
// @Description Get user order detail
// @Tags UserCenter
@@ -119,12 +122,13 @@ func (u *User) ListOrders(ctx fiber.Ctx, user *models.User, status string) ([]dt
// @Bind user local key(__ctx_user)
// @Bind id path
func (u *User) GetOrder(ctx fiber.Ctx, user *models.User, id int64) (*dto.Order, error) {
return services.Order.GetUserOrder(ctx, user.ID, id)
tenantID := getTenantID(ctx)
return services.Order.GetUserOrder(ctx, tenantID, user.ID, id)
}
// Get purchased content
//
// @Router /v1/me/library [get]
// @Router /t/:tenantCode/v1/me/library [get]
// @Summary Get library
// @Description Get purchased content
// @Tags UserCenter
@@ -133,12 +137,13 @@ func (u *User) GetOrder(ctx fiber.Ctx, user *models.User, id int64) (*dto.Order,
// @Success 200 {array} dto.ContentItem
// @Bind user local key(__ctx_user)
func (u *User) Library(ctx fiber.Ctx, user *models.User) ([]dto.ContentItem, error) {
return services.Content.GetLibrary(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Content.GetLibrary(ctx, tenantID, user.ID)
}
// Get favorites
//
// @Router /v1/me/favorites [get]
// @Router /t/:tenantCode/v1/me/favorites [get]
// @Summary Get favorites
// @Description Get favorites
// @Tags UserCenter
@@ -147,12 +152,13 @@ func (u *User) Library(ctx fiber.Ctx, user *models.User) ([]dto.ContentItem, err
// @Success 200 {array} dto.ContentItem
// @Bind user local key(__ctx_user)
func (u *User) Favorites(ctx fiber.Ctx, user *models.User) ([]dto.ContentItem, error) {
return services.Content.GetFavorites(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Content.GetFavorites(ctx, tenantID, user.ID)
}
// Add to favorites
//
// @Router /v1/me/favorites [post]
// @Router /t/:tenantCode/v1/me/favorites [post]
// @Summary Add favorite
// @Description Add to favorites
// @Tags UserCenter
@@ -163,12 +169,13 @@ func (u *User) Favorites(ctx fiber.Ctx, user *models.User) ([]dto.ContentItem, e
// @Bind user local key(__ctx_user)
// @Bind contentId query
func (u *User) AddFavorite(ctx fiber.Ctx, user *models.User, contentId int64) error {
return services.Content.AddFavorite(ctx, user.ID, contentId)
tenantID := getTenantID(ctx)
return services.Content.AddFavorite(ctx, tenantID, user.ID, contentId)
}
// Remove from favorites
//
// @Router /v1/me/favorites/:contentId<int> [delete]
// @Router /t/:tenantCode/v1/me/favorites/:contentId<int> [delete]
// @Summary Remove favorite
// @Description Remove from favorites
// @Tags UserCenter
@@ -179,12 +186,13 @@ func (u *User) AddFavorite(ctx fiber.Ctx, user *models.User, contentId int64) er
// @Bind user local key(__ctx_user)
// @Bind contentId path
func (u *User) RemoveFavorite(ctx fiber.Ctx, user *models.User, contentId int64) error {
return services.Content.RemoveFavorite(ctx, user.ID, contentId)
tenantID := getTenantID(ctx)
return services.Content.RemoveFavorite(ctx, tenantID, user.ID, contentId)
}
// Get liked contents
//
// @Router /v1/me/likes [get]
// @Router /t/:tenantCode/v1/me/likes [get]
// @Summary Get likes
// @Description Get liked contents
// @Tags UserCenter
@@ -193,12 +201,13 @@ func (u *User) RemoveFavorite(ctx fiber.Ctx, user *models.User, contentId int64)
// @Success 200 {array} dto.ContentItem
// @Bind user local key(__ctx_user)
func (u *User) Likes(ctx fiber.Ctx, user *models.User) ([]dto.ContentItem, error) {
return services.Content.GetLikes(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Content.GetLikes(ctx, tenantID, user.ID)
}
// Like content
//
// @Router /v1/me/likes [post]
// @Router /t/:tenantCode/v1/me/likes [post]
// @Summary Like content
// @Description Like content
// @Tags UserCenter
@@ -209,12 +218,13 @@ func (u *User) Likes(ctx fiber.Ctx, user *models.User) ([]dto.ContentItem, error
// @Bind user local key(__ctx_user)
// @Bind contentId query
func (u *User) AddLike(ctx fiber.Ctx, user *models.User, contentId int64) error {
return services.Content.AddLike(ctx, user.ID, contentId)
tenantID := getTenantID(ctx)
return services.Content.AddLike(ctx, tenantID, user.ID, contentId)
}
// Unlike content
//
// @Router /v1/me/likes/:contentId<int> [delete]
// @Router /t/:tenantCode/v1/me/likes/:contentId<int> [delete]
// @Summary Unlike content
// @Description Unlike content
// @Tags UserCenter
@@ -225,12 +235,13 @@ func (u *User) AddLike(ctx fiber.Ctx, user *models.User, contentId int64) error
// @Bind user local key(__ctx_user)
// @Bind contentId path
func (u *User) RemoveLike(ctx fiber.Ctx, user *models.User, contentId int64) error {
return services.Content.RemoveLike(ctx, user.ID, contentId)
tenantID := getTenantID(ctx)
return services.Content.RemoveLike(ctx, tenantID, user.ID, contentId)
}
// Get following tenants
//
// @Router /v1/me/following [get]
// @Router /t/:tenantCode/v1/me/following [get]
// @Summary Get following
// @Description Get following tenants
// @Tags UserCenter
@@ -239,12 +250,13 @@ func (u *User) RemoveLike(ctx fiber.Ctx, user *models.User, contentId int64) err
// @Success 200 {array} dto.TenantProfile
// @Bind user local key(__ctx_user)
func (u *User) Following(ctx fiber.Ctx, user *models.User) ([]dto.TenantProfile, error) {
return services.Tenant.ListFollowed(ctx, user.ID)
tenantID := getTenantID(ctx)
return services.Tenant.ListFollowed(ctx, tenantID, user.ID)
}
// Get notifications
//
// @Router /v1/me/notifications [get]
// @Router /t/:tenantCode/v1/me/notifications [get]
// @Summary Get notifications
// @Description Get notifications
// @Tags UserCenter
@@ -262,7 +274,7 @@ func (u *User) Notifications(ctx fiber.Ctx, user *models.User, typeArg string, p
// Mark notification as read
//
// @Router /v1/me/notifications/:id<int>/read [post]
// @Router /t/:tenantCode/v1/me/notifications/:id<int>/read [post]
// @Summary Mark as read
// @Tags UserCenter
// @Accept json
@@ -277,7 +289,7 @@ func (u *User) MarkNotificationRead(ctx fiber.Ctx, user *models.User, id int64)
// Mark all notifications as read
//
// @Router /v1/me/notifications/read-all [post]
// @Router /t/:tenantCode/v1/me/notifications/read-all [post]
// @Summary Mark all as read
// @Tags UserCenter
// @Accept json
@@ -290,7 +302,7 @@ func (u *User) MarkAllNotificationsRead(ctx fiber.Ctx, user *models.User) error
// List my coupons
//
// @Router /v1/me/coupons [get]
// @Router /t/:tenantCode/v1/me/coupons [get]
// @Summary List coupons
// @Description List my coupons
// @Tags UserCenter