From 2346983d6799afa9667b829310f8b650a452f84d Mon Sep 17 00:00:00 2001 From: yanghao05 Date: Wed, 9 Apr 2025 20:32:31 +0800 Subject: [PATCH] fix: create post --- backend/app/http/admin/posts.go | 42 +++++++++- backend/app/http/admin/routes.gen.go | 2 +- backend/app/models/medias.go | 78 +++++++++++------- backend/database/fields/posts.gen.go | 5 ++ backend/database/fields/posts.go | 1 + frontend/admin/src/api/httpClient.js | 2 +- frontend/admin/src/api/postService.js | 12 ++- frontend/admin/src/pages/MediaPage.vue | 90 +++++++++++---------- frontend/admin/src/pages/PostCreatePage.vue | 51 ++++++++---- frontend/admin/src/pages/PostPage.vue | 4 +- 10 files changed, 192 insertions(+), 95 deletions(-) diff --git a/backend/app/http/admin/posts.go b/backend/app/http/admin/posts.go index 9923db0..0961043 100644 --- a/backend/app/http/admin/posts.go +++ b/backend/app/http/admin/posts.go @@ -3,9 +3,11 @@ package admin import ( "quyun/app/models" "quyun/app/requests" + "quyun/database/fields" "quyun/database/schemas/public/model" "github.com/gofiber/fiber/v3" + "github.com/samber/lo" ) type ListQuery struct { @@ -24,10 +26,48 @@ func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *Li return models.Posts.List(ctx.Context(), pagination, cond) } +type PostForm struct { + Title string `json:"title"` + Price int64 `json:"price"` + Discount int16 `json:"discount"` + Introduction string `json:"introduction"` + Medias []int64 `json:"medias"` + Status fields.PostStatus `json:"status"` +} + // Create // @Router /v1/admin/posts [post] // @Bind form body -func (ctl *posts) Create(ctx fiber.Ctx, form *model.Posts) error { +func (ctl *posts) Create(ctx fiber.Ctx, form *PostForm) error { + post := model.Posts{ + Title: form.Title, + Price: form.Price, + Discount: form.Discount, + Description: form.Introduction, + Status: form.Status, + Content: "", + Tags: fields.Json[[]string]{}, + Assets: fields.Json[[]fields.MediaAsset]{}, + } + + if form.Medias != nil { + medias, err := models.Medias.GetByIds(ctx.Context(), form.Medias) + if err != nil { + return err + } + assets := lo.Map(medias, func(media *model.Medias, _ int) fields.MediaAsset { + return fields.MediaAsset{ + Type: models.Medias.ConvertFileTypeByMimeType(media.MimeType), + Media: media.ID, + Mark: nil, + } + }) + post.Assets = fields.ToJson(assets) + } + + if err := models.Posts.Create(ctx.Context(), &post); err != nil { + return err + } return nil } diff --git a/backend/app/http/admin/routes.gen.go b/backend/app/http/admin/routes.gen.go index e7006ca..88b62ab 100644 --- a/backend/app/http/admin/routes.gen.go +++ b/backend/app/http/admin/routes.gen.go @@ -47,7 +47,7 @@ func (r *Routes) Register(router fiber.Router) { router.Post("/v1/admin/posts", Func1( r.posts.Create, - Body[model.Posts]("form"), + Body[PostForm]("form"), )) router.Put("/v1/admin/posts/:id", Func2( diff --git a/backend/app/models/medias.go b/backend/app/models/medias.go index 986956e..4397e39 100644 --- a/backend/app/models/medias.go +++ b/backend/app/models/medias.go @@ -4,6 +4,7 @@ import ( "context" "quyun/app/requests" + "quyun/database/fields" "quyun/database/schemas/public/model" "quyun/database/schemas/public/table" @@ -12,26 +13,14 @@ import ( "github.com/sirupsen/logrus" ) -type MediaType string - -const ( - MediaTypeUnknown MediaType = "unknown" - MediaTypeArchive MediaType = "archive" - MediaTypeImage MediaType = "image" - MediaTypeVideo MediaType = "video" - MediaTypeDocument MediaType = "document" - MediaTypeAudio MediaType = "audio" - MediaTypePDF MediaType = "pdf" -) - type MediaItem struct { - ID int64 `json:"id"` - Name string `json:"name"` - UploadTime string `json:"upload_time"` - FileSize int64 `json:"file_size"` - MimeType string `json:"media_type"` - FileType MediaType `json:"file_type"` - ThumbnailUrl string `json:"thumbnail_url"` + ID int64 `json:"id"` + Name string `json:"name"` + UploadTime string `json:"upload_time"` + FileSize int64 `json:"file_size"` + MimeType string `json:"media_type"` + FileType fields.MediaAssetType `json:"file_type"` + ThumbnailUrl string `json:"thumbnail_url"` } // @provider @@ -150,30 +139,57 @@ func (m *mediasModel) Create(ctx context.Context, model *model.Medias) error { return nil } -func (m *mediasModel) ConvertFileTypeByMimeType(mimeType string) MediaType { +func (m *mediasModel) ConvertFileTypeByMimeType(mimeType string) fields.MediaAssetType { switch mimeType { - case "image/jpeg", "image/jpg", "image/png": - return MediaTypeImage - case "video/mp4": - return MediaTypeVideo + case "image/jpeg", "image/jpg", "image/png", "image/gif": + return fields.MediaAssetTypeImage + case "video/mp4", "video/x-m4v": + return fields.MediaAssetTypeVideo case "audio/mpeg": - return MediaTypeAudio - case "application/pdf": - return MediaTypePDF - case "application/msword", + return fields.MediaAssetTypeAudio + case "application/pdf", + "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation": - return MediaTypeDocument + return fields.MediaAssetTypeDocument case "application/rar", "application/x-rar-compressed", "application/x-zip-compressed", "application/x-zip", "application/zip", "application/x-7z-compressed": - return MediaTypeArchive + return fields.MediaAssetTypeArchive } - return MediaTypeUnknown + return fields.MediaAssetTypeUnknown +} + +// GetByIds +func (m *mediasModel) GetByIds(ctx context.Context, ids []int64) ([]*model.Medias, error) { + if len(ids) == 0 { + return nil, nil + } + + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + tbl := table.Medias + stmt := tbl. + SELECT(tbl.AllColumns). + WHERE(tbl.ID.IN(condIds...)) + m.log.Infof("sql: %s", stmt.DebugSql()) + + var medias []model.Medias + err := stmt.QueryContext(ctx, db, &medias) + if err != nil { + m.log.Errorf("error querying media items: %v", err) + return nil, err + } + + return lo.Map(medias, func(media model.Medias, _ int) *model.Medias { + return &media + }), nil } diff --git a/backend/database/fields/posts.gen.go b/backend/database/fields/posts.gen.go index 4f9cefc..05204fa 100644 --- a/backend/database/fields/posts.gen.go +++ b/backend/database/fields/posts.gen.go @@ -27,6 +27,8 @@ const ( MediaAssetTypeAudio MediaAssetType = "audio" // MediaAssetTypeDocument is a MediaAssetType of type Document. MediaAssetTypeDocument MediaAssetType = "document" + // MediaAssetTypeArchive is a MediaAssetType of type Archive. + MediaAssetTypeArchive MediaAssetType = "archive" // MediaAssetTypeOther is a MediaAssetType of type Other. MediaAssetTypeOther MediaAssetType = "other" ) @@ -40,6 +42,7 @@ var _MediaAssetTypeNames = []string{ string(MediaAssetTypeVideo), string(MediaAssetTypeAudio), string(MediaAssetTypeDocument), + string(MediaAssetTypeArchive), string(MediaAssetTypeOther), } @@ -59,6 +62,7 @@ func MediaAssetTypeValues() []MediaAssetType { MediaAssetTypeVideo, MediaAssetTypeAudio, MediaAssetTypeDocument, + MediaAssetTypeArchive, MediaAssetTypeOther, } } @@ -82,6 +86,7 @@ var _MediaAssetTypeValue = map[string]MediaAssetType{ "video": MediaAssetTypeVideo, "audio": MediaAssetTypeAudio, "document": MediaAssetTypeDocument, + "archive": MediaAssetTypeArchive, "other": MediaAssetTypeOther, } diff --git a/backend/database/fields/posts.go b/backend/database/fields/posts.go index 2cd9246..24a6526 100644 --- a/backend/database/fields/posts.go +++ b/backend/database/fields/posts.go @@ -14,6 +14,7 @@ type MediaAsset struct { // Video = "video", // Audio = "audio", // Document = "document", +// Archive = "archive", // Other = "other" // ) type MediaAssetType string diff --git a/frontend/admin/src/api/httpClient.js b/frontend/admin/src/api/httpClient.js index 2942dbe..2545fb6 100644 --- a/frontend/admin/src/api/httpClient.js +++ b/frontend/admin/src/api/httpClient.js @@ -27,7 +27,7 @@ httpClient.interceptors.request.use( // Response interceptor httpClient.interceptors.response.use( response => { - return response.data; + return response }, error => { // Handle HTTP errors here diff --git a/frontend/admin/src/api/postService.js b/frontend/admin/src/api/postService.js index e33ca39..9bb009f 100644 --- a/frontend/admin/src/api/postService.js +++ b/frontend/admin/src/api/postService.js @@ -13,4 +13,14 @@ export const postService = { getPost(id) { return httpClient.get(`/admin/posts/${id}`); }, -}; \ No newline at end of file + createPost(post) { + return httpClient.post('/admin/posts', post); + }, + + updatePost(id, post) { + return httpClient.put(`/admin/posts/${id}`, post); + }, + deletePost(id) { + return httpClient.delete(`/admin/posts/${id}`); + }, +} \ No newline at end of file diff --git a/frontend/admin/src/pages/MediaPage.vue b/frontend/admin/src/pages/MediaPage.vue index 3534b8a..ca839a2 100644 --- a/frontend/admin/src/pages/MediaPage.vue +++ b/frontend/admin/src/pages/MediaPage.vue @@ -1,18 +1,18 @@ @@ -153,9 +158,7 @@ const formatFileSize = (bytes) => { current-page-report-template="第 {first} 到 {last} 条,共 {totalRecords} 条" :lazy="true" :show-current-page-report="true"> @@ -176,7 +179,8 @@ const formatFileSize = (bytes) => { - +