feat: 添加内容创建时间字段,优化内容列表和详情视图;添加创作者内容列表接口;优化上传和删除功能

This commit is contained in:
2026-01-06 17:03:11 +08:00
parent 1723802722
commit ab5bc8d41a
7 changed files with 177 additions and 62 deletions

View File

@@ -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"`
}

View File

@@ -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,

View File

@@ -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]

View File

@@ -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

View File

@@ -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 {