From cf8bb5f192c183dec952aa11a0f8bfcbcb048fb8 Mon Sep 17 00:00:00 2001 From: yanghao05 Date: Tue, 8 Apr 2025 15:35:58 +0800 Subject: [PATCH] feat: update page list show --- backend/app/models/medias.go | 49 +++++--- backend/app/models/medias_test.go | 79 ++++++++++++ backend/app/models/posts.go | 4 +- backend/app/requests/pagination.go | 9 +- backend/app/service/http/http.go | 4 +- backend/test.http | 4 + frontend/admin/index.html | 2 +- frontend/admin/src/App.vue | 2 +- frontend/admin/src/api/get_medias.json | 52 ++++++++ frontend/admin/src/api/httpClient.js | 2 +- frontend/admin/src/api/mediaService.js | 9 ++ frontend/admin/src/pages/MediaPage.vue | 161 +++++++++++++------------ frontend/admin/vite.config.js | 5 +- 13 files changed, 280 insertions(+), 102 deletions(-) create mode 100644 frontend/admin/src/api/get_medias.json create mode 100644 frontend/admin/src/api/mediaService.js diff --git a/backend/app/models/medias.go b/backend/app/models/medias.go index d577188..1e09014 100644 --- a/backend/app/models/medias.go +++ b/backend/app/models/medias.go @@ -64,8 +64,8 @@ func (m *mediasModel) countByCondition(ctx context.Context, expr BoolExpression) } func (m *mediasModel) List(ctx context.Context, pagination *requests.Pagination) (*requests.Pager, error) { - limit := pagination.Limit - offset := pagination.Offset() + limit := pagination.GetLimit() + offset := pagination.GetOffset() tbl := table.Medias stmt := tbl. @@ -89,8 +89,8 @@ func (m *mediasModel) List(ctx context.Context, pagination *requests.Pagination) } // Convert model.Medias to MediaItem - mediaItems := lo.Map(medias, func(media model.Medias, _ int) MediaItem { - return MediaItem{ + mediaItems := lo.Map(medias, func(media model.Medias, _ int) *MediaItem { + return &MediaItem{ ID: media.ID, Name: media.Name, UploadTime: media.CreatedAt.Format("2006-01-02 15:04:05"), @@ -108,6 +108,19 @@ func (m *mediasModel) List(ctx context.Context, pagination *requests.Pagination) }, nil } +func (m *mediasModel) BatchCreate(ctx context.Context, models []*model.Medias) error { + stmt := table.Medias.INSERT(table.Medias.MutableColumns).MODELS(models) + m.log.Infof("sql: %s", stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log.Errorf("error creating media item: %v", err) + return err + } + + m.log.Infof("media item created successfully") + return nil +} + func (m *mediasModel) Create(ctx context.Context, model *model.Medias) error { stmt := table.Medias.INSERT(table.Medias.MutableColumns).MODEL(model) m.log.Infof("sql: %s", stmt.DebugSql()) @@ -123,9 +136,7 @@ func (m *mediasModel) Create(ctx context.Context, model *model.Medias) error { func (m *mediasModel) ConvertFileTypeByMimeType(mimeType string) MediaType { switch mimeType { - case "image/jpeg": - case "image/jpg": - case "image/png": + case "image/jpeg", "image/jpg", "image/png": return MediaTypeImage case "video/mp4": return MediaTypeVideo @@ -133,19 +144,19 @@ func (m *mediasModel) ConvertFileTypeByMimeType(mimeType string) MediaType { return MediaTypeAudio case "application/pdf": return MediaTypePDF - case "application/msword": - case "application/vnd.openxmlformats-officedocument.wordprocessingml.document": - case "application/vnd.ms-excel": - case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": - case "application/vnd.ms-powerpoint": - case "application/vnd.openxmlformats-officedocument.presentationml.presentation": + case "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 - case "application/rar": - case "application/x-rar-compressed": - case "application/x-zip-compressed": - case "application/x-zip": - case "application/zip": - case "application/x-7z-compressed": + case "application/rar", + "application/x-rar-compressed", + "application/x-zip-compressed", + "application/x-zip", + "application/zip", + "application/x-7z-compressed": return MediaTypeArchive } return MediaTypeUnknown diff --git a/backend/app/models/medias_test.go b/backend/app/models/medias_test.go index 7302dd3..27acacd 100644 --- a/backend/app/models/medias_test.go +++ b/backend/app/models/medias_test.go @@ -3,6 +3,8 @@ package models import ( "context" "fmt" + "math" + "math/rand" "testing" "time" @@ -54,6 +56,60 @@ func (s *MediasTestSuite) Test_countByCondition() { }) } +func (s *MediasTestSuite) Test_BatchCreate() { + Convey("Create", s.T(), func() { + Convey("valid media", func() { + database.Truncate(context.Background(), db, table.Medias.TableName()) + + models := []*model.Medias{ + { + Name: "test 01", + CreatedAt: time.Now(), + MimeType: "video/mp4", + Size: rand.Int63n(math.MaxInt64), // Random size + Path: "path/to/media.mp4", + }, + { + Name: "test 02", + CreatedAt: time.Now(), + MimeType: "audio/mp3", + Size: rand.Int63n(math.MaxInt64), // Random size + Path: "path/to/media.mp3", + }, + { + Name: "test 03", + CreatedAt: time.Now(), + MimeType: "application/pdf", + Size: rand.Int63n(math.MaxInt64), // Random size + Path: "path/to/media.pdf", + }, + { + Name: "test 04", + CreatedAt: time.Now(), + MimeType: "image/jpeg", + Size: rand.Int63n(math.MaxInt64), // Random size + Path: "path/to/media.jpeg", + }, + { + Name: "test 05", + CreatedAt: time.Now(), + MimeType: "application/zip", + Size: rand.Int63n(math.MaxInt64), // Random size + Path: "path/to/media.zip", + }, + } + + count := 10 + for i := 0; i < count; i++ { + err := Medias.BatchCreate(context.Background(), models) + Convey("Create should not return an error: "+fmt.Sprintf("%d", i), func() { + So(err, ShouldBeNil) + }) + } + }) + }) +} + func (s *MediasTestSuite) Test_Create() { Convey("Create", s.T(), func() { Convey("valid media", func() { @@ -132,3 +188,26 @@ func (s *MediasTestSuite) Test_Page() { }) }) } + +// Test ConvertFileTypeByMimeType +func (s *MediasTestSuite) Test_ConvertFileTypeByMimeType() { + Convey("ConvertFileTypeByMimeType", s.T(), func() { + Convey("image", func() { + mimeType := "image/jpeg" + fileType := Medias.ConvertFileTypeByMimeType(mimeType) + So(fileType, ShouldEqual, MediaTypeImage) + }) + + Convey("video", func() { + mimeType := "video/mp4" + fileType := Medias.ConvertFileTypeByMimeType(mimeType) + So(fileType, ShouldEqual, MediaTypeVideo) + }) + + Convey("invalid mime type", func() { + mimeType := "invalid/type" + fileType := Medias.ConvertFileTypeByMimeType(mimeType) + So(fileType, ShouldEqual, MediaTypeUnknown) + }) + }) +} diff --git a/backend/app/models/posts.go b/backend/app/models/posts.go index bce1d7d..5d31feb 100644 --- a/backend/app/models/posts.go +++ b/backend/app/models/posts.go @@ -118,8 +118,8 @@ func (m *postsModel) countByCondition(ctx context.Context, expr BoolExpression) } func (m *postsModel) List(ctx context.Context, pagination *requests.Pagination, cond BoolExpression) (*requests.Pager, error) { - limit := pagination.Limit - offset := pagination.Offset() + limit := pagination.GetLimit() + offset := pagination.GetOffset() tbl := table.Posts stmt := tbl. diff --git a/backend/app/requests/pagination.go b/backend/app/requests/pagination.go index e98528d..c626318 100644 --- a/backend/app/requests/pagination.go +++ b/backend/app/requests/pagination.go @@ -13,10 +13,17 @@ type Pagination struct { Limit int64 `json:"limit" form:"limit" query:"limit"` } -func (filter *Pagination) Offset() int64 { +func (filter *Pagination) GetOffset() int64 { return (filter.Page - 1) * filter.Limit } +func (filter *Pagination) GetLimit() int64 { + if filter.Limit <= 0 { + return 10 + } + return filter.Limit +} + func (filter *Pagination) Format() *Pagination { if filter.Page <= 0 { filter.Page = 1 diff --git a/backend/app/service/http/http.go b/backend/app/service/http/http.go index 6233cc6..80b402f 100644 --- a/backend/app/service/http/http.go +++ b/backend/app/service/http/http.go @@ -6,6 +6,7 @@ import ( "quyun/app/errorx" appHttp "quyun/app/http" "quyun/app/jobs" + "quyun/app/models" "quyun/app/service" _ "quyun/docs" "quyun/providers/ali" @@ -47,6 +48,7 @@ func Command() atom.Option { defaultProviders(). With( jobs.Provide, + models.Provide, ). WithProviders( appHttp.Providers(), @@ -68,7 +70,7 @@ type Service struct { func Serve(cmd *cobra.Command, args []string) error { return container.Container.Invoke(func(ctx context.Context, svc Service) error { - log.SetFormatter(&log.JSONFormatter{}) + log.SetFormatter(&log.TextFormatter{}) if svc.App.Mode == app.AppModeDevelopment { log.SetLevel(log.DebugLevel) diff --git a/backend/test.http b/backend/test.http index c3c3e92..a5a3f4a 100644 --- a/backend/test.http +++ b/backend/test.http @@ -31,4 +31,8 @@ Content-Type: application/json ### get oss token GET {{host}}/v1/admin/uploads/token HTTP/1.1 +Content-Type: application/json + +### get medias +GET {{host}}/v1/admin/medias HTTP/1.1 Content-Type: application/json \ No newline at end of file diff --git a/frontend/admin/index.html b/frontend/admin/index.html index 3afa212..c203166 100644 --- a/frontend/admin/index.html +++ b/frontend/admin/index.html @@ -4,7 +4,7 @@ - 趣云管理后台 + Hello diff --git a/frontend/admin/src/App.vue b/frontend/admin/src/App.vue index 14e7ded..38ee0db 100644 --- a/frontend/admin/src/App.vue +++ b/frontend/admin/src/App.vue @@ -37,7 +37,7 @@ const navItems = ref([