diff --git a/backend/app/http/v1/dto/content.go b/backend/app/http/v1/dto/content.go index aa0a3b4..72f3afd 100644 --- a/backend/app/http/v1/dto/content.go +++ b/backend/app/http/v1/dto/content.go @@ -23,6 +23,7 @@ type ContentItem struct { AuthorAvatar string `json:"author_avatar"` Views int `json:"views"` Likes int `json:"likes"` + CreatedAt string `json:"created_at"` IsPurchased bool `json:"is_purchased"` } diff --git a/backend/app/http/v1/routes.gen.go b/backend/app/http/v1/routes.gen.go index 5a37540..de4ec74 100644 --- a/backend/app/http/v1/routes.gen.go +++ b/backend/app/http/v1/routes.gen.go @@ -50,6 +50,18 @@ 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 -> common.DeleteMediaAsset") + router.Delete("/v1/media-assets/:id"[len(r.Path()):], Func2( + r.common.DeleteMediaAsset, + Local[*models.User]("__ctx_user"), + PathParam[string]("id"), + )) + r.log.Debugf("Registering route: Delete /v1/upload/:uploadId -> common.AbortUpload") + router.Delete("/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.common.GetOptions, @@ -60,6 +72,19 @@ func (r *Routes) Register(router fiber.Router) { 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.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.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.common.InitUpload, @@ -73,31 +98,6 @@ func (r *Routes) Register(router fiber.Router) { File[multipart.FileHeader]("file"), Body[dto.UploadPartForm]("form"), )) - r.log.Debugf("Registering route: Post /v1/upload/complete -> common.CompleteUpload") - router.Post("/v1/upload/complete"[len(r.Path()):], DataFunc2( - r.common.CompleteUpload, - Local[*models.User]("__ctx_user"), - Body[dto.UploadCompleteForm]("form"), - )) - r.log.Debugf("Registering route: Delete /v1/upload/:uploadId -> common.AbortUpload") - router.Delete("/v1/upload/:uploadId"[len(r.Path()):], Func2( - r.common.AbortUpload, - Local[*models.User]("__ctx_user"), - PathParam[string]("uploadId"), - )) - r.log.Debugf("Registering route: Delete /v1/media-assets/:id -> common.DeleteMediaAsset") - router.Delete("/v1/media-assets/:id"[len(r.Path()):], Func2( - r.common.DeleteMediaAsset, - Local[*models.User]("__ctx_user"), - PathParam[string]("id"), - )) - r.log.Debugf("Registering route: Post /v1/upload -> common.Upload") - router.Post("/v1/upload"[len(r.Path()):], DataFunc3( - r.common.Upload, - Local[*models.User]("__ctx_user"), - File[multipart.FileHeader]("file"), - Body[dto.UploadForm]("form"), - )) // Register routes for controller: Content r.log.Debugf("Registering route: Get /v1/contents -> content.List") router.Get("/v1/contents"[len(r.Path()):], DataFunc1( @@ -242,6 +242,12 @@ func (r *Routes) Register(router fiber.Router) { Local[*models.User]("__ctx_user"), PathParam[string]("id"), )) + r.log.Debugf("Registering route: Get /v1/creators/:id/contents -> tenant.ListContents") + router.Get("/v1/creators/:id/contents"[len(r.Path()):], DataFunc2( + r.tenant.ListContents, + PathParam[string]("id"), + Query[dto.ContentListFilter]("filter"), + )) r.log.Debugf("Registering route: Get /v1/tenants/:id -> tenant.Get") router.Get("/v1/tenants/:id"[len(r.Path()):], DataFunc2( r.tenant.Get, diff --git a/backend/app/http/v1/tenant.go b/backend/app/http/v1/tenant.go index 77579fa..4b96015 100644 --- a/backend/app/http/v1/tenant.go +++ b/backend/app/http/v1/tenant.go @@ -2,6 +2,7 @@ package v1 import ( "quyun/v2/app/http/v1/dto" + "quyun/v2/app/requests" "quyun/v2/app/services" "quyun/v2/database/models" @@ -11,6 +12,28 @@ import ( // @provider type Tenant struct{} +// List creator contents +// +// @Router /v1/creators/:id/contents [get] +// @Summary List creator contents +// @Description List contents of a specific creator +// @Tags TenantPublic +// @Accept json +// @Produce json +// @Param id path string true "Tenant ID" +// @Param page query int false "Page" +// @Param limit query int false "Limit" +// @Success 200 {object} requests.Pager +// @Bind id path +// @Bind filter query +func (t *Tenant) ListContents(ctx fiber.Ctx, id string, filter *dto.ContentListFilter) (*requests.Pager, error) { + if filter == nil { + filter = &dto.ContentListFilter{} + } + filter.TenantID = &id + return services.Content.List(ctx, filter) +} + // Get tenant public profile // // @Router /v1/tenants/:id [get] diff --git a/backend/app/services/content.go b/backend/app/services/content.go index b4550b8..4274917 100644 --- a/backend/app/services/content.go +++ b/backend/app/services/content.go @@ -50,7 +50,7 @@ func (s *content) List(ctx context.Context, filter *content_dto.ContentListFilte case "price_asc": q = q.Order(tbl.ID.Desc()) default: // latest - q = q.Order(tbl.PublishedAt.Desc()) + q = q.Order(tbl.ID.Desc()) } // Pagination @@ -443,13 +443,14 @@ func (s *content) ListTopics(ctx context.Context) ([]content_dto.Topic, error) { func (s *content) toContentItemDTO(item *models.Content, price float64) content_dto.ContentItem { dto := content_dto.ContentItem{ - ID: cast.ToString(item.ID), - Title: item.Title, - Genre: item.Genre, - AuthorID: cast.ToString(item.UserID), - Views: int(item.Views), - Likes: int(item.Likes), - Price: price, + ID: cast.ToString(item.ID), + Title: item.Title, + Genre: item.Genre, + AuthorID: cast.ToString(item.UserID), + Views: int(item.Views), + Likes: int(item.Likes), + CreatedAt: item.CreatedAt.Format("2006-01-02"), + Price: price, } if item.Author != nil { dto.AuthorName = item.Author.Nickname diff --git a/backend/app/services/creator.go b/backend/app/services/creator.go index 87c4b31..9d85a12 100644 --- a/backend/app/services/creator.go +++ b/backend/app/services/creator.go @@ -252,6 +252,7 @@ func (s *creator) ListContents( Items: data, }, nil } + func (s *creator) CreateContent(ctx context.Context, userID int64, form *creator_dto.ContentCreateForm) error { tid, err := s.getTenantID(ctx, userID) if err != nil { diff --git a/frontend/portal/src/api/content.js b/frontend/portal/src/api/content.js index e269041..c554f7a 100644 --- a/frontend/portal/src/api/content.js +++ b/frontend/portal/src/api/content.js @@ -2,6 +2,11 @@ import { request } from '../utils/request'; export const contentApi = { list: (params) => { + if (params.tenantId) { + const { tenantId, ...rest } = params; + const qs = new URLSearchParams(rest).toString(); + return request(`/creators/${tenantId}/contents?${qs}`); + } const qs = new URLSearchParams(params).toString(); return request(`/contents?${qs}`); }, diff --git a/frontend/portal/src/views/tenant/HomeView.vue b/frontend/portal/src/views/tenant/HomeView.vue index f32395f..33c91f4 100644 --- a/frontend/portal/src/views/tenant/HomeView.vue +++ b/frontend/portal/src/views/tenant/HomeView.vue @@ -34,15 +34,22 @@
{{ item.created_at }}