From 1166a5c949a33675849c86793faef6805e4a0f02 Mon Sep 17 00:00:00 2001 From: Rogee Date: Fri, 23 May 2025 23:42:27 +0800 Subject: [PATCH] feat: update --- backend/app/http/admin/medias.go | 5 +- backend/app/http/admin/posts.go | 7 +- backend/app/http/admin/statistics.go | 8 +- backend/app/http/posts.go | 30 ++--- backend/app/model/medias.funcs.gen.go | 137 ++++++++++++++++++++ backend/app/model/medias.go | 148 ++-------------------- backend/app/model/medias_test.go | 6 +- backend/app/model/orders.funcs.gen.go | 140 ++++++++++++++++++++ backend/app/model/orders.go | 80 ++---------- backend/app/model/posts.funcs.gen.go | 176 ++++++++++++++++++++++++++ backend/app/model/posts.go | 145 ++++++--------------- backend/app/model/provider.gen.go | 21 +++ backend/app/model/users.funcs.gen.go | 176 ++++++++++++++++++++++++++ backend/app/model/users.go | 128 ++----------------- backend/app/model/users_test.go | 6 +- backend/database/conds/conds.go | 11 -- backend/database/conds/posts.go | 41 ------ 17 files changed, 751 insertions(+), 514 deletions(-) create mode 100644 backend/app/model/medias.funcs.gen.go create mode 100644 backend/app/model/orders.funcs.gen.go create mode 100644 backend/app/model/posts.funcs.gen.go create mode 100644 backend/app/model/users.funcs.gen.go delete mode 100644 backend/database/conds/conds.go delete mode 100644 backend/database/conds/posts.go diff --git a/backend/app/http/admin/medias.go b/backend/app/http/admin/medias.go index e072b4f..f0762d8 100644 --- a/backend/app/http/admin/medias.go +++ b/backend/app/http/admin/medias.go @@ -19,8 +19,7 @@ type medias struct { // @Bind pagination query // @Bind query query func (ctl *medias) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) { - cond := model.MediasModel().BuildConditionWithKey(query.Keyword) - return model.MediasModel().List(ctx.Context(), pagination, cond) + return model.MediasModel().List(ctx.Context(), pagination, model.MediasModel().Like(query.Keyword)) } // Show media @@ -55,7 +54,7 @@ func (ctl *medias) Delete(ctx fiber.Ctx, id int64) error { return err } - if err := model.MediasModel().Delete(ctx.Context(), id); err != nil { + if err := media.ForceDelete(ctx.Context()); err != nil { return err } return ctx.SendStatus(fiber.StatusNoContent) diff --git a/backend/app/http/admin/posts.go b/backend/app/http/admin/posts.go index 780f106..a5475b3 100644 --- a/backend/app/http/admin/posts.go +++ b/backend/app/http/admin/posts.go @@ -3,7 +3,6 @@ package admin import ( "quyun/app/model" "quyun/app/requests" - "quyun/database/conds" "quyun/database/fields" "github.com/gofiber/fiber/v3" @@ -23,10 +22,10 @@ type posts struct{} // @Bind pagination query // @Bind query query func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) { - conds := []conds.Cond{ + conds := []model.Cond{ // conds.Post_NotDeleted(), // conds.Post_Status(fields.PostStatusPublished), - conds.Post_Like(query.Keyword), + model.PostsModel().CondLike(query.Keyword), } pager, err := model.PostsModel().List(ctx.Context(), pagination, conds...) if err != nil { @@ -158,7 +157,7 @@ func (ctl *posts) Delete(ctx fiber.Ctx, id int64) error { return fiber.ErrNotFound } - if err := post.Delete(ctx.Context()); err != nil { + if err := post.ForceDelete(ctx.Context()); err != nil { return err } return nil diff --git a/backend/app/http/admin/statistics.go b/backend/app/http/admin/statistics.go index 12a7be6..cf71bc4 100644 --- a/backend/app/http/admin/statistics.go +++ b/backend/app/http/admin/statistics.go @@ -29,11 +29,11 @@ func (s *statistics) statistics(ctx fiber.Ctx) (*StatisticsResponse, error) { var err error - statistics.PostDraft, err = model.PostsModel().Count(ctx.Context(), table.Posts.Status.EQ(Int(int64(fields.PostStatusDraft)))) + statistics.PostDraft, err = model.PostsModel().Count(ctx.Context(), model.ExprCond(table.Posts.Status.EQ(Int(int64(fields.PostStatusDraft))))) if err != nil { return nil, err } - statistics.PostPublished, err = model.PostsModel().Count(ctx.Context(), table.Posts.Status.EQ(Int(int64(fields.PostStatusPublished)))) + statistics.PostPublished, err = model.PostsModel().Count(ctx.Context(), model.ExprCond(table.Posts.Status.EQ(Int(int64(fields.PostStatusPublished))))) if err != nil { return nil, err } @@ -43,12 +43,12 @@ func (s *statistics) statistics(ctx fiber.Ctx) (*StatisticsResponse, error) { return nil, err } - statistics.Order, err = model.OrdersModel().Count(ctx.Context(), table.Orders.Status.EQ(Int(int64(fields.OrderStatusCompleted)))) + statistics.Order, err = model.OrdersModel().Count(ctx.Context(), model.ExprCond(table.Orders.Status.EQ(Int(int64(fields.OrderStatusCompleted))))) if err != nil { return nil, err } - statistics.User, err = model.UsersModel().Count(ctx.Context(), BoolExp(Bool(true))) + statistics.User, err = model.UsersModel().Count(ctx.Context()) if err != nil { return nil, err } diff --git a/backend/app/http/posts.go b/backend/app/http/posts.go index 5af0f70..921d62a 100644 --- a/backend/app/http/posts.go +++ b/backend/app/http/posts.go @@ -8,7 +8,6 @@ import ( "quyun/app/jobs" "quyun/app/model" "quyun/app/requests" - "quyun/database/conds" "quyun/database/fields" "quyun/providers/ali" "quyun/providers/job" @@ -39,10 +38,10 @@ type posts struct { // @Bind query query // @Bind user local func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery, user *model.Users) (*requests.Pager, error) { - conds := []conds.Cond{ - conds.Post_NotDeleted(), - conds.Post_Status(fields.PostStatusPublished), - conds.Post_Like(query.Keyword), + conds := []model.Cond{ + model.PostsModel().CondNotDeleted(), + model.PostsModel().CondStatus(fields.PostStatusPublished), + model.PostsModel().CondLike(query.Keyword), } pager, err := model.PostsModel().List(ctx.Context(), pagination, conds...) @@ -118,7 +117,7 @@ type PostItem struct { func (ctl *posts) Show(ctx fiber.Ctx, id int64, user *model.Users) (*PostItem, error) { log.Infof("Fetching post with ID: %d", id) - post, err := model.PostsModel().GetByID(ctx.Context(), id, conds.Post_NotDeleted(), conds.Post_Status(fields.PostStatusPublished)) + post, err := model.PostsModel().GetByID(ctx.Context(), id, model.PostsModel().CondNotDeleted(), model.PostsModel().CondStatus(fields.PostStatusPublished)) if err != nil { log.WithError(err).Errorf("GetByID err: %v", err) return nil, err @@ -217,11 +216,12 @@ func (ctl *posts) Play(ctx fiber.Ctx, id int64, user *model.Users) (*PlayUrl, er func (ctl *posts) Mine(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery, user *model.Users) (*requests.Pager, error) { log.Infof("Fetching posts for user with pagination: %+v and keyword: %v", pagination, query.Keyword) - conds := []conds.Cond{ - conds.Post_NotDeleted(), - conds.Post_Status(fields.PostStatusPublished), - conds.Post_Like(query.Keyword), + conds := []model.Cond{ + model.PostsModel().CondNotDeleted(), + model.PostsModel().CondStatus(fields.PostStatusPublished), + model.PostsModel().CondLike(query.Keyword), } + pager, err := model.UsersModel().PostList(ctx.Context(), user.ID, pagination, conds...) if err != nil { log.WithError(err).Errorf("post list err: %v", err) @@ -283,16 +283,16 @@ func (ctl *posts) Buy(ctx fiber.Ctx, id int64, user *model.Users) (*wechat.JSAPI if err != nil { return nil, errors.Wrapf(err, " failed to get post: %d", id) } - payPrice := post.Price * int64(post.Discount) / 100 + // payPrice := post.PayPrice() - order, err := model.OrdersModel().Create(ctx.Context(), user.ID, post.ID) + order, err := model.OrdersModel().CreateFromUserPostID(ctx.Context(), user.ID, post.ID) if err != nil { return nil, errors.Wrap(err, "订单创建失败") } - if user.Balance >= payPrice { + if user.Balance >= post.PayPrice() { if err := order.SetMeta(ctx.Context(), func(om fields.OrderMeta) fields.OrderMeta { - om.CostBalance = payPrice + om.CostBalance = post.PayPrice() return om }); err != nil { return nil, errors.Wrap(err, "订单创建失败") @@ -308,7 +308,7 @@ func (ctl *posts) Buy(ctx fiber.Ctx, id int64, user *model.Users) (*wechat.JSAPI }, nil } - payPrice = payPrice - user.Balance + payPrice := post.PayPrice() - user.Balance if err := order.SetMeta(ctx.Context(), func(om fields.OrderMeta) fields.OrderMeta { om.CostBalance = user.Balance return om diff --git a/backend/app/model/medias.funcs.gen.go b/backend/app/model/medias.funcs.gen.go new file mode 100644 index 0000000..8f0f9cb --- /dev/null +++ b/backend/app/model/medias.funcs.gen.go @@ -0,0 +1,137 @@ +package model + +import ( + "context" + "time" + + "quyun/database/table" + + . "github.com/go-jet/jet/v2/postgres" + "github.com/samber/lo" + log "github.com/sirupsen/logrus" +) + +// conds + +func (m *Medias) CondID(id int64) Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Medias.ID.EQ(Int(id))) + } +} + +// funcs +func (m *Medias) log() *log.Entry { + return log.WithField("model", "Medias") +} + +func (m *Medias) Create(ctx context.Context) error { + m.CreatedAt = time.Now() + + stmt := table.Medias.INSERT(table.Medias.MutableColumns).MODEL(m).RETURNING(table.Medias.AllColumns) + m.log().WithField("func", "Create").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Medias item: %v", err) + return err + } + + m.log().WithField("func", "Create").Infof("Medias item created successfully") + return nil +} + +func (m *Medias) BatchCreate(ctx context.Context, models []*Medias) error { + stmt := table.Medias.INSERT(table.Medias.MutableColumns).MODELS(models) + m.log().WithField("func", "BatchCreate").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Medias item: %v", err) + return err + } + + m.log().WithField("func", "BatchCreate").Infof("Medias items created successfully") + return nil +} + +func (m *Medias) ForceDelete(ctx context.Context) error { + stmt := table.Medias.DELETE().WHERE(table.Medias.ID.EQ(Int(m.ID))) + m.log().WithField("func", "Delete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Delete").Errorf("error deleting Medias item: %v", err) + return err + } + + m.log().WithField("func", "Delete").Infof("Medias item deleted successfully") + return nil +} + +func (m *Medias) BatchForceDelete(ctx context.Context, ids []int64) error { + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + stmt := table.Medias.DELETE().WHERE(table.Medias.ID.IN(condIds...)) + m.log().WithField("func", "BatchDelete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "BatchDelete").Errorf("error deleting Medias items: %v", err) + return err + } + + m.log().WithField("func", "BatchDelete").Infof("Medias items deleted successfully") + return nil +} + +func (m *Medias) Update(ctx context.Context) error { + stmt := table.Medias.UPDATE(table.Medias.MutableColumns.Except(mediasUpdateExcludeColumns...)).SET(m).WHERE(table.Medias.ID.EQ(Int(m.ID))).RETURNING(table.Medias.AllColumns) + m.log().WithField("func", "Update").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Update").Errorf("error updating Medias item: %v", err) + return err + } + + m.log().WithField("func", "Update").Infof("Medias item updated successfully") + return nil +} + +// GetByCond +func (m *Medias) GetByCond(ctx context.Context, conds ...Cond) (*Medias, error) { + cond := CondTrue(conds...) + + stmt := table.Medias.SELECT(table.Medias.AllColumns).WHERE(cond) + m.log().WithField("func", "GetByCond").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "GetByCond").Errorf("error getting Medias item by ID: %v", err) + return nil, err + } + + m.log().WithField("func", "GetByCond").Infof("Medias item retrieved successfully") + return m, nil +} + +// GetByID +func (m *Medias) GetByID(ctx context.Context, id int64, conds ...Cond) (*Medias, error) { + return m.GetByCond(ctx, CondJoin(m.CondID(id), conds...)...) +} + +// Count +func (m *Medias) Count(ctx context.Context, conds ...Cond) (int64, error) { + cond := CondTrue(conds...) + + tbl := table.Medias + stmt := tbl.SELECT(COUNT(tbl.ID).AS("count")).WHERE(cond) + m.log().Infof("sql: %s", stmt.DebugSql()) + + var count struct { + Count int64 + } + + if err := stmt.QueryContext(ctx, db, &count); err != nil { + m.log().Errorf("error counting Medias items: %v", err) + return 0, err + } + + return count.Count, nil +} diff --git a/backend/app/model/medias.go b/backend/app/model/medias.go index a95b1a4..3e4a14f 100644 --- a/backend/app/model/medias.go +++ b/backend/app/model/medias.go @@ -2,7 +2,6 @@ package model import ( "context" - "time" "quyun/app/requests" "quyun/database/fields" @@ -10,55 +9,34 @@ import ( . "github.com/go-jet/jet/v2/postgres" "github.com/samber/lo" - log "github.com/sirupsen/logrus" ) -func (m *Medias) log() *log.Entry { - return log.WithField("model", "MediasModel") +var mediasUpdateExcludeColumns = []Column{ + table.Medias.CreatedAt, } -func (m *Medias) BuildConditionWithKey(key *string) BoolExpression { - tbl := table.Medias +func (m *Medias) Like(key *string) Cond { + return func(cond BoolExpression) BoolExpression { + tbl := table.Medias + if key == nil || *key == "" { + return cond + } - cond := Bool(true) + cond = cond.AND( + tbl.Name.LIKE(String("%" + *key + "%")), + ) - if key == nil || *key == "" { return cond } - - cond = cond.AND( - tbl.Name.LIKE(String("%" + *key + "%")), - ) - - return cond } -// countByCond -func (m *Medias) countByCondition(ctx context.Context, expr BoolExpression) (int64, error) { - var cnt struct { - Cnt int64 - } - - tbl := table.Medias - stmt := SELECT(COUNT(tbl.ID).AS("cnt")).FROM(tbl).WHERE(expr) - m.log().Infof("sql: %s", stmt.DebugSql()) - - err := stmt.QueryContext(ctx, db, &cnt) - if err != nil { - m.log().Errorf("error counting media items: %v", err) - return 0, err - } - - return cnt.Cnt, nil -} - -func (m *Medias) List(ctx context.Context, pagination *requests.Pagination, expr BoolExpression) (*requests.Pager, error) { +func (m *Medias) List(ctx context.Context, pagination *requests.Pagination, conds ...Cond) (*requests.Pager, error) { pagination.Format() tbl := table.Medias stmt := tbl. SELECT(tbl.AllColumns). - WHERE(expr). + WHERE(CondTrue(conds...)). ORDER_BY(tbl.ID.DESC()). LIMIT(pagination.Limit). OFFSET(pagination.Offset) @@ -71,7 +49,7 @@ func (m *Medias) List(ctx context.Context, pagination *requests.Pagination, expr return nil, err } - count, err := m.countByCondition(ctx, expr) + count, err := m.Count(ctx, conds...) if err != nil { m.log().Errorf("error getting media count: %v", err) return nil, err @@ -84,33 +62,6 @@ func (m *Medias) List(ctx context.Context, pagination *requests.Pagination, expr }, nil } -func (m *Medias) BatchCreate(ctx context.Context, models []*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 *Medias) Create(ctx context.Context) error { - m.CreatedAt = time.Now() - stmt := table.Medias.INSERT(table.Medias.MutableColumns).MODEL(m).RETURNING(table.Medias.AllColumns) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if err := stmt.QueryContext(ctx, db, m); err != nil { - m.log().Errorf("error creating media item: %v", err) - return err - } - - m.log().Infof("media item created successfully") - return nil -} - // GetByIds func (m *Medias) GetByIds(ctx context.Context, ids []int64) ([]*Medias, error) { if len(ids) == 0 { @@ -157,59 +108,6 @@ func (m *Medias) GetByHash(ctx context.Context, hash string) (*Medias, error) { return &media, nil } -// Update -func (m *Medias) Update(ctx context.Context, hash string, model *Medias) error { - tbl := table.Medias - stmt := tbl. - UPDATE(tbl.MutableColumns.Except(tbl.CreatedAt)). - MODEL(model). - WHERE(table.Medias.Hash.EQ(String(hash))) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if _, err := stmt.ExecContext(ctx, db); err != nil { - m.log().WithField("hash", hash).Errorf("error updating media item: %v", err) - return err - } - - m.log().Infof("media item updated successfully") - return nil -} - -// GetByID -func (m *Medias) GetByID(ctx context.Context, id int64) (*Medias, error) { - tbl := table.Medias - stmt := tbl. - SELECT(tbl.AllColumns). - WHERE(tbl.ID.EQ(Int64(id))) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var media Medias - - if err := stmt.QueryContext(ctx, db, &media); err != nil { - m.log().Errorf("error querying media item by ID: %v", err) - return nil, err - } - - return &media, nil -} - -// Delete -func (m *Medias) Delete(ctx context.Context, id int64) error { - tbl := table.Medias - stmt := tbl. - DELETE(). - WHERE(tbl.ID.EQ(Int64(id))) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if _, err := stmt.ExecContext(ctx, db); err != nil { - m.log().Errorf("error deleting media item: %v", err) - return err - } - - m.log().Infof("media item deleted successfully") - return nil -} - // UpdateMetas func (m *Medias) UpdateMetas(ctx context.Context, id int64, metas fields.MediaMetas) error { meta := fields.ToJson(metas) @@ -250,21 +148,3 @@ func (m *Medias) GetRelations(ctx context.Context, hash string) ([]*Medias, erro return &media }), nil } - -// Count -func (m *Medias) Count(ctx context.Context) (int64, error) { - tbl := table.Medias - stmt := tbl.SELECT(COUNT(tbl.ID).AS("count")) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var count struct { - Count int64 - } - - if err := stmt.QueryContext(ctx, db, &count); err != nil { - m.log().Errorf("error counting media items: %v", err) - return 0, err - } - - return count.Count, nil -} diff --git a/backend/app/model/medias_test.go b/backend/app/model/medias_test.go index 1e02994..2923c51 100644 --- a/backend/app/model/medias_test.go +++ b/backend/app/model/medias_test.go @@ -52,7 +52,7 @@ func (s *MediasTestSuite) Test_countByCondition() { Convey("no cond", func() { database.Truncate(context.Background(), db, table.Medias.TableName()) - cnt, err := MediasModel().countByCondition(context.Background(), nil) + cnt, err := MediasModel().Count(context.Background()) Convey("should not return an error", func() { So(err, ShouldBeNil) }) @@ -137,7 +137,7 @@ func (s *MediasTestSuite) Test_Create() { So(err, ShouldBeNil) }) - cnt, err := MediasModel().countByCondition(context.Background(), nil) + cnt, err := MediasModel().Count(context.Background()) Convey("Count should not return an error", func() { So(err, ShouldBeNil) }) @@ -169,7 +169,7 @@ func (s *MediasTestSuite) Test_Page() { So(err, ShouldBeNil) } - cnt, err := MediasModel().countByCondition(context.Background(), nil) + cnt, err := MediasModel().Count(context.Background()) So(err, ShouldBeNil) So(cnt, ShouldEqual, 20) }) diff --git a/backend/app/model/orders.funcs.gen.go b/backend/app/model/orders.funcs.gen.go new file mode 100644 index 0000000..80f355c --- /dev/null +++ b/backend/app/model/orders.funcs.gen.go @@ -0,0 +1,140 @@ +package model + +import ( + "context" + "time" + + "quyun/database/table" + + . "github.com/go-jet/jet/v2/postgres" + "github.com/samber/lo" + log "github.com/sirupsen/logrus" +) + +// conds + +func (m *Orders) CondID(id int64) Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Orders.ID.EQ(Int(id))) + } +} + +// funcs +func (m *Orders) log() *log.Entry { + return log.WithField("model", "Orders") +} + +func (m *Orders) Create(ctx context.Context) error { + m.CreatedAt = time.Now() + m.UpdatedAt = time.Now() + + stmt := table.Medias.INSERT(table.Orders.MutableColumns).MODEL(m).RETURNING(table.Medias.AllColumns) + m.log().WithField("func", "Create").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Orders item: %v", err) + return err + } + + m.log().WithField("func", "Create").Infof("Orders item created successfully") + return nil +} + +func (m *Orders) BatchCreate(ctx context.Context, models []*Orders) error { + stmt := table.Orders.INSERT(table.Orders.MutableColumns).MODELS(models) + m.log().WithField("func", "BatchCreate").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Orders item: %v", err) + return err + } + + m.log().WithField("func", "BatchCreate").Infof("Orders items created successfully") + return nil +} + +func (m *Orders) ForceDelete(ctx context.Context) error { + stmt := table.Orders.DELETE().WHERE(table.Orders.ID.EQ(Int(m.ID))) + m.log().WithField("func", "Delete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Delete").Errorf("error deleting Orders item: %v", err) + return err + } + + m.log().WithField("func", "Delete").Infof("Orders item deleted successfully") + return nil +} + +func (m *Orders) BatchForceDelete(ctx context.Context, ids []int64) error { + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + stmt := table.Orders.DELETE().WHERE(table.Orders.ID.IN(condIds...)) + m.log().WithField("func", "BatchDelete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "BatchDelete").Errorf("error deleting Orders items: %v", err) + return err + } + + m.log().WithField("func", "BatchDelete").Infof("Orders items deleted successfully") + return nil +} + +func (m *Orders) Update(ctx context.Context) error { + m.UpdatedAt = time.Now() + + stmt := table.Orders.UPDATE(table.Orders.MutableColumns.Except(ordersUpdateExcludeColumns...)).SET(m).WHERE(table.Orders.ID.EQ(Int(m.ID))).RETURNING(table.Orders.AllColumns) + m.log().WithField("func", "Update").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Update").Errorf("error updating Orders item: %v", err) + return err + } + + m.log().WithField("func", "Update").Infof("Orders item updated successfully") + return nil +} + +// GetByCond +func (m *Orders) GetByCond(ctx context.Context, conds ...Cond) (*Orders, error) { + cond := CondTrue(conds...) + + stmt := table.Orders.SELECT(table.Orders.AllColumns).WHERE(cond) + m.log().WithField("func", "GetByCond").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "GetByCond").Errorf("error getting Orders item by ID: %v", err) + return nil, err + } + + m.log().WithField("func", "GetByCond").Infof("Orders item retrieved successfully") + return m, nil +} + +// GetByID +func (m *Orders) GetByID(ctx context.Context, id int64, conds ...Cond) (*Orders, error) { + return m.GetByCond(ctx, CondJoin(m.CondID(id), conds...)...) +} + +// Count +func (m *Orders) Count(ctx context.Context, conds ...Cond) (int64, error) { + cond := CondTrue(conds...) + + tbl := table.Orders + stmt := tbl.SELECT(COUNT(tbl.ID).AS("count")).WHERE(cond) + m.log().Infof("sql: %s", stmt.DebugSql()) + + var count struct { + Count int64 + } + + if err := stmt.QueryContext(ctx, db, &count); err != nil { + m.log().Errorf("error counting Orders items: %v", err) + return 0, err + } + + return count.Count, nil +} diff --git a/backend/app/model/orders.go b/backend/app/model/orders.go index 411ac8f..7382cfe 100644 --- a/backend/app/model/orders.go +++ b/backend/app/model/orders.go @@ -12,32 +12,15 @@ import ( . "github.com/go-jet/jet/v2/postgres" "github.com/pkg/errors" "github.com/samber/lo" - log "github.com/sirupsen/logrus" ) -func (m *Orders) log() *log.Entry { - return log.WithField("model", "OrdersModel") -} - -// GetByID returns an order by ID -func (m *Orders) GetByID(ctx context.Context, id int64) (*Orders, error) { - tbl := table.Orders - - stmt := tbl. - SELECT(tbl.AllColumns). - WHERE( - tbl.ID.EQ(Int64(id)), - ) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var order Orders - err := stmt.QueryContext(ctx, db, &order) - if err != nil { - m.log().Errorf("error querying order by ID: %v", err) - return nil, err - } - - return &order, nil +var ordersUpdateExcludeColumns = []Column{ + table.Orders.OrderNo, + table.Orders.Price, + table.Orders.Discount, + table.Orders.SubOrderNo, + table.Orders.PostID, + table.Orders.UserID, } // BuildConditionWithKey builds the WHERE clause for order queries @@ -150,7 +133,7 @@ func (m *Orders) List(ctx context.Context, pagination *requests.Pagination, cond } // Create creates a new order -func (o *Orders) Create(ctx context.Context, userId, postId int64) (*Orders, error) { +func (o *Orders) CreateFromUserPostID(ctx context.Context, userId, postId int64) (*Orders, error) { post, err := PostsModel().GetByID(ctx, postId) if err != nil { return nil, errors.Wrap(err, "failed to get post") @@ -215,25 +198,6 @@ func (m *Orders) SetStatus(ctx context.Context, status fields.OrderStatus) error return nil } -// Count -func (m *Orders) Count(ctx context.Context, cond BoolExpression) (int64, error) { - tbl := table.Orders - stmt := SELECT(COUNT(tbl.ID).AS("cnt")).FROM(tbl).WHERE(cond) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var cnt struct { - Cnt int64 - } - - err := stmt.QueryContext(ctx, db, &cnt) - if err != nil { - m.log().Errorf("error counting orders: %v", err) - return 0, err - } - - return cnt.Cnt, nil -} - // SumAmount func (m *Orders) SumAmount(ctx context.Context) (int64, error) { tbl := table.Orders @@ -292,31 +256,3 @@ func (m *Orders) SetTransactionID(ctx context.Context, transactionID string) err } return nil } - -// Update -func (m *Orders) Update(ctx context.Context) error { - tbl := table.Orders - stmt := tbl. - UPDATE( - tbl.MutableColumns.Except( - tbl.OrderNo, - tbl.Price, - tbl.Discount, - tbl.SubOrderNo, - tbl.PostID, - tbl.UserID, - ), - ). - MODEL(m). - WHERE( - tbl.ID.EQ(Int64(m.ID)), - ). - RETURNING(tbl.AllColumns) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if err := stmt.QueryContext(ctx, db, m); err != nil { - m.log().Errorf("error updating order: %v", err) - return err - } - return nil -} diff --git a/backend/app/model/posts.funcs.gen.go b/backend/app/model/posts.funcs.gen.go new file mode 100644 index 0000000..72f869d --- /dev/null +++ b/backend/app/model/posts.funcs.gen.go @@ -0,0 +1,176 @@ +package model + +import ( + "context" + "time" + + "quyun/database/table" + + . "github.com/go-jet/jet/v2/postgres" + "github.com/samber/lo" + log "github.com/sirupsen/logrus" +) + +// conds +func (m *Posts) CondNotDeleted() Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Posts.DeletedAt.IS_NULL()) + } +} + +func (m *Posts) CondID(id int64) Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Posts.ID.EQ(Int(id))) + } +} + +// funcs +func (m *Posts) log() *log.Entry { + return log.WithField("model", "Posts") +} + +func (m *Posts) Create(ctx context.Context) error { + m.CreatedAt = time.Now() + m.UpdatedAt = time.Now() + + stmt := table.Medias.INSERT(table.Posts.MutableColumns).MODEL(m).RETURNING(table.Medias.AllColumns) + m.log().WithField("func", "Create").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Posts item: %v", err) + return err + } + + m.log().WithField("func", "Create").Infof("Posts item created successfully") + return nil +} + +func (m *Posts) BatchCreate(ctx context.Context, models []*Posts) error { + stmt := table.Posts.INSERT(table.Posts.MutableColumns).MODELS(models) + m.log().WithField("func", "BatchCreate").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Posts item: %v", err) + return err + } + + m.log().WithField("func", "BatchCreate").Infof("Posts items created successfully") + return nil +} + +func (m *Posts) Delete(ctx context.Context) error { + stmt := table.Posts.UPDATE().SET(table.Posts.DeletedAt.SET(TimestampT(time.Now()))).WHERE(table.Posts.ID.EQ(Int(m.ID))) + m.log().WithField("func", "SoftDelete").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "SoftDelete").Errorf("error soft deleting Posts item: %v", err) + return err + } + + m.log().WithField("func", "SoftDelete").Infof("Posts item soft deleted successfully") + return nil +} + +// BatchDelete +func (m *Posts) BatchDelete(ctx context.Context, ids []int64) error { + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + stmt := table.Posts.UPDATE().SET(table.Posts.DeletedAt.SET(TimestampT(time.Now()))).WHERE(table.Posts.ID.IN(condIds...)) + m.log().WithField("func", "BatchSoftDelete").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "BatchSoftDelete").Errorf("error soft deleting Posts items: %v", err) + return err + } + + m.log().WithField("func", "BatchSoftDelete").Infof("Posts items soft deleted successfully") + return nil +} + +func (m *Posts) ForceDelete(ctx context.Context) error { + stmt := table.Posts.DELETE().WHERE(table.Posts.ID.EQ(Int(m.ID))) + m.log().WithField("func", "Delete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Delete").Errorf("error deleting Posts item: %v", err) + return err + } + + m.log().WithField("func", "Delete").Infof("Posts item deleted successfully") + return nil +} + +func (m *Posts) BatchForceDelete(ctx context.Context, ids []int64) error { + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + stmt := table.Posts.DELETE().WHERE(table.Posts.ID.IN(condIds...)) + m.log().WithField("func", "BatchDelete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "BatchDelete").Errorf("error deleting Posts items: %v", err) + return err + } + + m.log().WithField("func", "BatchDelete").Infof("Posts items deleted successfully") + return nil +} + +func (m *Posts) Update(ctx context.Context) error { + m.UpdatedAt = time.Now() + + stmt := table.Posts.UPDATE(table.Posts.MutableColumns.Except(postsUpdateExcludeColumns...)).SET(m).WHERE(table.Posts.ID.EQ(Int(m.ID))).RETURNING(table.Posts.AllColumns) + m.log().WithField("func", "Update").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Update").Errorf("error updating Posts item: %v", err) + return err + } + + m.log().WithField("func", "Update").Infof("Posts item updated successfully") + return nil +} + +// GetByCond +func (m *Posts) GetByCond(ctx context.Context, conds ...Cond) (*Posts, error) { + cond := CondTrue(conds...) + + stmt := table.Posts.SELECT(table.Posts.AllColumns).WHERE(cond) + m.log().WithField("func", "GetByCond").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "GetByCond").Errorf("error getting Posts item by ID: %v", err) + return nil, err + } + + m.log().WithField("func", "GetByCond").Infof("Posts item retrieved successfully") + return m, nil +} + +// GetByID +func (m *Posts) GetByID(ctx context.Context, id int64, conds ...Cond) (*Posts, error) { + return m.GetByCond(ctx, CondJoin(m.CondID(id), conds...)...) +} + +// Count +func (m *Posts) Count(ctx context.Context, conds ...Cond) (int64, error) { + cond := CondTrue(conds...) + + tbl := table.Posts + stmt := tbl.SELECT(COUNT(tbl.ID).AS("count")).WHERE(cond) + m.log().Infof("sql: %s", stmt.DebugSql()) + + var count struct { + Count int64 + } + + if err := stmt.QueryContext(ctx, db, &count); err != nil { + m.log().Errorf("error counting Posts items: %v", err) + return 0, err + } + + return count.Count, nil +} diff --git a/backend/app/model/posts.go b/backend/app/model/posts.go index f233a5a..8205ec3 100644 --- a/backend/app/model/posts.go +++ b/backend/app/model/posts.go @@ -5,16 +5,45 @@ import ( "time" "quyun/app/requests" - "quyun/database/conds" + "quyun/database/fields" "quyun/database/table" . "github.com/go-jet/jet/v2/postgres" "github.com/samber/lo" - log "github.com/sirupsen/logrus" ) -func (m *Posts) log() *log.Entry { - return log.WithField("model", "PostsModel") +var postsUpdateExcludeColumns = []Column{ + table.Posts.CreatedAt, + table.Posts.DeletedAt, + table.Posts.Views, + table.Posts.Likes, +} + +func (m *Posts) CondStatus(s fields.PostStatus) Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Posts.Status.EQ(Int(int64(s)))) + } +} + +func (m *Posts) CondLike(key *string) Cond { + return func(cond BoolExpression) BoolExpression { + tbl := table.Posts + if key == nil || *key == "" { + return cond + } + + cond = cond.AND( + tbl.Title.LIKE(String("%" + *key + "%")). + OR( + tbl.Content.LIKE(String("%" + *key + "%")), + ). + OR( + tbl.Description.LIKE(String("%" + *key + "%")), + ), + ) + + return cond + } } func (m *Posts) IncrViewCount(ctx context.Context) error { @@ -32,67 +61,6 @@ func (m *Posts) IncrViewCount(ctx context.Context) error { return nil } -// GetByID -func (m *Posts) GetByID(ctx context.Context, id int64, cond ...conds.Cond) (*Posts, error) { - tbl := table.Posts - - var combinedCond BoolExpression = tbl.ID.EQ(Int64(id)) - for _, c := range cond { - combinedCond = c(combinedCond) - } - stmt := tbl.SELECT(tbl.AllColumns).WHERE(combinedCond) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var post Posts - err := stmt.QueryContext(ctx, db, &post) - if err != nil { - m.log().Errorf("error getting post: %v", err) - return nil, err - } - return &post, nil -} - -// Create -func (m *Posts) Create(ctx context.Context) error { - m.CreatedAt = time.Now() - m.UpdatedAt = time.Now() - - tbl := table.Posts - stmt := tbl.INSERT(tbl.MutableColumns).MODEL(m).RETURNING(tbl.AllColumns) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if err := stmt.QueryContext(ctx, db, m); err != nil { - m.log().Errorf("error creating post: %v", err) - return err - } - return nil -} - -// Update -func (m *Posts) Update(ctx context.Context) error { - m.UpdatedAt = time.Now() - - tbl := table.Posts - stmt := tbl. - UPDATE( - tbl.MutableColumns.Except( - tbl.CreatedAt, - tbl.DeletedAt, - tbl.Views, - tbl.Likes, - ), - ). - MODEL(m). - WHERE(tbl.ID.EQ(Int64(m.ID))) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if _, err := stmt.ExecContext(ctx, db); err != nil { - m.log().Errorf("error updating post: %v", err) - return err - } - return nil -} - // countByCond func (m *Posts) countByCondition(ctx context.Context, expr BoolExpression) (int64, error) { var cnt struct { @@ -112,18 +80,15 @@ func (m *Posts) countByCondition(ctx context.Context, expr BoolExpression) (int6 return cnt.Cnt, nil } -func (m *Posts) List(ctx context.Context, pagination *requests.Pagination, cond ...conds.Cond) (*requests.Pager, error) { +func (m *Posts) List(ctx context.Context, pagination *requests.Pagination, conds ...Cond) (*requests.Pager, error) { pagination.Format() - combinedCond := table.Posts.DeletedAt.IS_NULL() - for _, c := range cond { - combinedCond = c(combinedCond) - } + cond := CondJoin(m.CondNotDeleted(), conds...) tbl := table.Posts stmt := tbl. SELECT(tbl.AllColumns). - WHERE(combinedCond). + WHERE(CondTrue(cond...)). ORDER_BY(tbl.ID.DESC()). LIMIT(pagination.Limit). OFFSET(pagination.Offset) @@ -136,7 +101,7 @@ func (m *Posts) List(ctx context.Context, pagination *requests.Pagination, cond return nil, err } - count, err := m.countByCondition(ctx, combinedCond) + count, err := m.Count(ctx, CondJoin(m.CondNotDeleted(), conds...)...) if err != nil { m.log().Errorf("error getting post count: %v", err) return nil, err @@ -149,24 +114,6 @@ func (m *Posts) List(ctx context.Context, pagination *requests.Pagination, cond }, nil } -// DeleteByID soft delete item -func (m *Posts) Delete(ctx context.Context) error { - tbl := table.Posts - stmt := tbl. - UPDATE(tbl.DeletedAt). - SET(TimestampT(time.Now())). - WHERE( - tbl.ID.EQ(Int64(m.ID)), - ) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if _, err := stmt.ExecContext(ctx, db); err != nil { - m.log().Errorf("error deleting post: %v", err) - return err - } - return nil -} - // SendTo func (m *Posts) SendTo(ctx context.Context, userId int64) error { // add record to user_posts @@ -332,20 +279,6 @@ func (m *Posts) GetMediaByIds(ctx context.Context, ids []int64) ([]Medias, error return medias, nil } -// Count -func (m *Posts) Count(ctx context.Context, cond BoolExpression) (int64, error) { - tbl := table.Posts - stmt := tbl. - SELECT(COUNT(tbl.ID).AS("count")). - WHERE(cond) - - var count struct { - Count int64 - } - if err := stmt.QueryContext(ctx, db, &count); err != nil { - m.log().Errorf("error counting posts: %v", err) - return 0, err - } - - return count.Count, nil +func (m *Posts) PayPrice() int64 { + return m.Price * int64(m.Discount) / 100 } diff --git a/backend/app/model/provider.gen.go b/backend/app/model/provider.gen.go index 3ec7ba8..3c52685 100644 --- a/backend/app/model/provider.gen.go +++ b/backend/app/model/provider.gen.go @@ -7,12 +7,33 @@ import ( "context" "database/sql" + . "github.com/go-jet/jet/v2/postgres" "go.ipao.vip/atom" "go.ipao.vip/atom/container" "go.ipao.vip/atom/contracts" "go.ipao.vip/atom/opt" ) +type Cond func(BoolExpression) BoolExpression + +func ExprCond(expr BoolExpression) Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(expr) + } +} + +func CondTrue(conds ...Cond) BoolExpression { + cond := BoolExp(Bool(true)) + for _, c := range conds { + cond = c(cond) + } + return cond +} + +func CondJoin(cond Cond, conds ...Cond) []Cond { + return append([]Cond{cond}, conds...) +} + var db *sql.DB func MediasModel() *Medias { return &Medias{} } diff --git a/backend/app/model/users.funcs.gen.go b/backend/app/model/users.funcs.gen.go new file mode 100644 index 0000000..7dc2902 --- /dev/null +++ b/backend/app/model/users.funcs.gen.go @@ -0,0 +1,176 @@ +package model + +import ( + "context" + "time" + + "quyun/database/table" + + . "github.com/go-jet/jet/v2/postgres" + "github.com/samber/lo" + log "github.com/sirupsen/logrus" +) + +// conds +func (m *Users) CondNotDeleted() Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Users.DeletedAt.IS_NULL()) + } +} + +func (m *Users) CondID(id int64) Cond { + return func(cond BoolExpression) BoolExpression { + return cond.AND(table.Users.ID.EQ(Int(id))) + } +} + +// funcs +func (m *Users) log() *log.Entry { + return log.WithField("model", "Users") +} + +func (m *Users) Create(ctx context.Context) error { + m.CreatedAt = time.Now() + m.UpdatedAt = time.Now() + + stmt := table.Medias.INSERT(table.Users.MutableColumns).MODEL(m).RETURNING(table.Medias.AllColumns) + m.log().WithField("func", "Create").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Users item: %v", err) + return err + } + + m.log().WithField("func", "Create").Infof("Users item created successfully") + return nil +} + +func (m *Users) BatchCreate(ctx context.Context, models []*Users) error { + stmt := table.Users.INSERT(table.Users.MutableColumns).MODELS(models) + m.log().WithField("func", "BatchCreate").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Create").Errorf("error creating Users item: %v", err) + return err + } + + m.log().WithField("func", "BatchCreate").Infof("Users items created successfully") + return nil +} + +func (m *Users) Delete(ctx context.Context) error { + stmt := table.Users.UPDATE().SET(table.Users.DeletedAt.SET(TimestampT(time.Now()))).WHERE(table.Users.ID.EQ(Int(m.ID))) + m.log().WithField("func", "SoftDelete").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "SoftDelete").Errorf("error soft deleting Users item: %v", err) + return err + } + + m.log().WithField("func", "SoftDelete").Infof("Users item soft deleted successfully") + return nil +} + +// BatchDelete +func (m *Users) BatchDelete(ctx context.Context, ids []int64) error { + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + stmt := table.Users.UPDATE().SET(table.Users.DeletedAt.SET(TimestampT(time.Now()))).WHERE(table.Users.ID.IN(condIds...)) + m.log().WithField("func", "BatchSoftDelete").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "BatchSoftDelete").Errorf("error soft deleting Users items: %v", err) + return err + } + + m.log().WithField("func", "BatchSoftDelete").Infof("Users items soft deleted successfully") + return nil +} + +func (m *Users) ForceDelete(ctx context.Context) error { + stmt := table.Users.DELETE().WHERE(table.Users.ID.EQ(Int(m.ID))) + m.log().WithField("func", "Delete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "Delete").Errorf("error deleting Users item: %v", err) + return err + } + + m.log().WithField("func", "Delete").Infof("Users item deleted successfully") + return nil +} + +func (m *Users) BatchForceDelete(ctx context.Context, ids []int64) error { + condIds := lo.Map(ids, func(id int64, _ int) Expression { + return Int64(id) + }) + + stmt := table.Users.DELETE().WHERE(table.Users.ID.IN(condIds...)) + m.log().WithField("func", "BatchDelete").Info(stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log().WithField("func", "BatchDelete").Errorf("error deleting Users items: %v", err) + return err + } + + m.log().WithField("func", "BatchDelete").Infof("Users items deleted successfully") + return nil +} + +func (m *Users) Update(ctx context.Context) error { + m.UpdatedAt = time.Now() + + stmt := table.Users.UPDATE(table.Users.MutableColumns.Except(usersUpdateExcludeColumns...)).SET(m).WHERE(table.Users.ID.EQ(Int(m.ID))).RETURNING(table.Users.AllColumns) + m.log().WithField("func", "Update").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "Update").Errorf("error updating Users item: %v", err) + return err + } + + m.log().WithField("func", "Update").Infof("Users item updated successfully") + return nil +} + +// GetByCond +func (m *Users) GetByCond(ctx context.Context, conds ...Cond) (*Users, error) { + cond := CondTrue(conds...) + + stmt := table.Users.SELECT(table.Users.AllColumns).WHERE(cond) + m.log().WithField("func", "GetByCond").Info(stmt.DebugSql()) + + if err := stmt.QueryContext(ctx, db, m); err != nil { + m.log().WithField("func", "GetByCond").Errorf("error getting Users item by ID: %v", err) + return nil, err + } + + m.log().WithField("func", "GetByCond").Infof("Users item retrieved successfully") + return m, nil +} + +// GetByID +func (m *Users) GetByID(ctx context.Context, id int64, conds ...Cond) (*Users, error) { + return m.GetByCond(ctx, CondJoin(m.CondID(id), conds...)...) +} + +// Count +func (m *Users) Count(ctx context.Context, conds ...Cond) (int64, error) { + cond := CondTrue(conds...) + + tbl := table.Users + stmt := tbl.SELECT(COUNT(tbl.ID).AS("count")).WHERE(cond) + m.log().Infof("sql: %s", stmt.DebugSql()) + + var count struct { + Count int64 + } + + if err := stmt.QueryContext(ctx, db, &count); err != nil { + m.log().Errorf("error counting Users items: %v", err) + return 0, err + } + + return count.Count, nil +} diff --git a/backend/app/model/users.go b/backend/app/model/users.go index e39741a..52f9661 100644 --- a/backend/app/model/users.go +++ b/backend/app/model/users.go @@ -5,7 +5,6 @@ import ( "time" "quyun/app/requests" - "quyun/database/conds" "quyun/database/fields" "quyun/database/table" @@ -13,31 +12,13 @@ import ( "github.com/go-jet/jet/v2/qrm" "github.com/pkg/errors" "github.com/samber/lo" - log "github.com/sirupsen/logrus" ) -func (m *Users) log() *log.Entry { - return log.WithField("model", "UsersModel") -} - -// GetByID -func (m *Users) GetByID(ctx context.Context, id int64) (*Users, error) { - tbl := table.Users - - stmt := tbl. - SELECT(tbl.AllColumns). - WHERE( - tbl.ID.EQ(Int64(id)), - ) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var user Users - if err := stmt.QueryContext(ctx, db, &user); err != nil { - m.log().Errorf("error querying user by ID(%d), err: %v", id, err) - return nil, err - } - - return &user, nil +var usersUpdateExcludeColumns = []Column{ + table.Users.OpenID, + table.Users.Balance, + table.Users.CreatedAt, + table.Users.DeletedAt, } // BuildConditionWithKey builds the WHERE clause for user queries @@ -109,79 +90,13 @@ func (m *Users) List(ctx context.Context, pagination *requests.Pagination, cond }, nil } -// Create creates a new user -func (m *Users) Create(ctx context.Context) (*Users, error) { - m.CreatedAt = time.Now() - m.UpdatedAt = time.Now() - - tbl := table.Users - stmt := tbl.INSERT(tbl.MutableColumns).MODEL(m).RETURNING(tbl.AllColumns) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var createdUser Users - err := stmt.QueryContext(ctx, db, &createdUser) - if err != nil { - m.log().Errorf("error creating user: %v", err) - return nil, err - } - return &createdUser, nil -} - -// Update updates an existing user -func (m *Users) Update(ctx context.Context) (*Users, error) { - m.UpdatedAt = time.Now() - - tbl := table.Users - stmt := tbl. - UPDATE( - tbl.MutableColumns.Except( - tbl.OpenID, - tbl.Balance, - tbl.CreatedAt, - tbl.DeletedAt, - ), - ). - MODEL(m). - WHERE(tbl.ID.EQ(Int64(m.ID))). - RETURNING(tbl.AllColumns) - m.log().Infof("sql: %s", stmt.DebugSql()) - - var user Users - if err := stmt.QueryContext(ctx, db, &user); err != nil { - m.log().Errorf("error updating user: %v", err) - return nil, err - } - return &user, nil -} - -// DeleteByID soft deletes a user by ID -func (m *Users) DeleteByID(ctx context.Context, id int64) error { - tbl := table.Users - stmt := tbl. - UPDATE(tbl.DeletedAt). - SET(TimestampT(time.Now())). - WHERE( - tbl.ID.EQ(Int64(id)), - ) - m.log().Infof("sql: %s", stmt.DebugSql()) - - if _, err := stmt.ExecContext(ctx, db); err != nil { - m.log().Errorf("error deleting user: %v", err) - return err - } - return nil -} - // PostList returns a paginated list of posts for a user -func (m *Users) PostList(ctx context.Context, userId int64, pagination *requests.Pagination, conds ...conds.Cond) (*requests.Pager, error) { +func (m *Users) PostList(ctx context.Context, userId int64, pagination *requests.Pagination, conds ...Cond) (*requests.Pager, error) { pagination.Format() tblUserPosts := table.UserPosts - combineConds := tblUserPosts.UserID.EQ(Int64(userId)) - for _, c := range conds { - combineConds = c(combineConds) - } + cond := CondJoin(ExprCond(tblUserPosts.UserID.EQ(Int64(userId))), conds...) tbl := table.Posts stmt := SELECT(tbl.AllColumns). @@ -191,7 +106,7 @@ func (m *Users) PostList(ctx context.Context, userId int64, pagination *requests tblUserPosts.PostID.EQ(tbl.ID), ), ). - WHERE(combineConds). + WHERE(CondTrue(cond...)). ORDER_BY(tblUserPosts.ID.DESC()). LIMIT(pagination.Limit). OFFSET(pagination.Offset) @@ -256,8 +171,7 @@ func (m *Users) GetUserByOpenIDOrCreate(ctx context.Context, openID string, user user, err := m.GetUserByOpenID(ctx, openID) if err != nil { if errors.Is(err, qrm.ErrNoRows) { - user, err = userModel.Create(ctx) - if err != nil { + if err = userModel.Create(ctx); err != nil { return nil, errors.Wrap(err, "failed to create user") } } else { @@ -271,8 +185,7 @@ func (m *Users) GetUserByOpenIDOrCreate(ctx context.Context, openID string, user user.Metas = userModel.Metas user.AuthToken = userModel.AuthToken - user, err = user.Update(ctx) - if err != nil { + if err := user.Update(ctx); err != nil { return nil, errors.Wrap(err, "failed to update user") } } @@ -354,27 +267,6 @@ func (m *Users) HasBought(ctx context.Context, postID int64) (bool, error) { return userPost.ID > 0, nil } -// Count -func (m *Users) Count(ctx context.Context, cond BoolExpression) (int64, error) { - tbl := table.Users - stmt := tbl. - SELECT(COUNT(tbl.ID).AS("cnt")). - WHERE(cond) - - m.log().Infof("sql: %s", stmt.DebugSql()) - - var cnt struct { - Cnt int64 - } - - if err := stmt.QueryContext(ctx, db, &cnt); err != nil { - m.log().Errorf("error counting users: %v", err) - return 0, err - } - - return cnt.Cnt, nil -} - // SetUsername func (m *Users) SetUsername(ctx context.Context, username string) error { tbl := table.Users diff --git a/backend/app/model/users_test.go b/backend/app/model/users_test.go index 9ceb294..94adff8 100644 --- a/backend/app/model/users_test.go +++ b/backend/app/model/users_test.go @@ -51,9 +51,9 @@ func (s *UsersTestSuite) Test_Create() { Balance: 1000, } - u, err := user.Create(context.TODO()) + err := user.Create(context.TODO()) So(err, ShouldBeNil) - So(u, ShouldNotBeNil) - So(u.ID, ShouldNotBeZeroValue) + So(user, ShouldNotBeNil) + So(user.ID, ShouldNotBeZeroValue) }) } diff --git a/backend/database/conds/conds.go b/backend/database/conds/conds.go deleted file mode 100644 index dc56265..0000000 --- a/backend/database/conds/conds.go +++ /dev/null @@ -1,11 +0,0 @@ -package conds - -import ( - . "github.com/go-jet/jet/v2/postgres" -) - -type Cond func(BoolExpression) BoolExpression - -func Default() BoolExpression { - return BoolExp(Bool(true)) -} diff --git a/backend/database/conds/posts.go b/backend/database/conds/posts.go deleted file mode 100644 index 3efb6f4..0000000 --- a/backend/database/conds/posts.go +++ /dev/null @@ -1,41 +0,0 @@ -package conds - -import ( - "quyun/database/fields" - "quyun/database/table" - - . "github.com/go-jet/jet/v2/postgres" -) - -func Post_NotDeleted() Cond { - return func(cond BoolExpression) BoolExpression { - return cond.AND(table.Posts.DeletedAt.IS_NULL()) - } -} - -func Post_Status(s fields.PostStatus) Cond { - return func(cond BoolExpression) BoolExpression { - return cond.AND(table.Posts.Status.EQ(Int(int64(s)))) - } -} - -func Post_Like(key *string) Cond { - return func(cond BoolExpression) BoolExpression { - tbl := table.Posts - if key == nil || *key == "" { - return cond - } - - cond = cond.AND( - tbl.Title.LIKE(String("%" + *key + "%")). - OR( - tbl.Content.LIKE(String("%" + *key + "%")), - ). - OR( - tbl.Description.LIKE(String("%" + *key + "%")), - ), - ) - - return cond - } -}