From 93d757764c23a9de920d90ee369ca3ed8b12e50b Mon Sep 17 00:00:00 2001 From: Cbgogogog <1293543528@qq.com> Date: Wed, 16 Aug 2023 21:56:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=B0=8F=E9=B1=BC?= =?UTF-8?q?=E5=B9=B2=E9=83=A8=E5=88=86=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- biz/adaptor/server.go | 20 ++++ biz/application/service/plan.go | 111 +++++++++++++++++- biz/infrastructure/consts/field.go | 2 + biz/infrastructure/mapper/donate/mongo.go | 131 ++++++++++++++++++++++ biz/infrastructure/mapper/fish/mongo.go | 88 +++++++++++++++ biz/infrastructure/mapper/plan/mongo.go | 2 + go.mod | 2 +- go.sum | 4 +- provider/provider.go | 4 + provider/wire_gen.go | 10 +- 10 files changed, 366 insertions(+), 8 deletions(-) create mode 100644 biz/infrastructure/mapper/donate/mongo.go create mode 100644 biz/infrastructure/mapper/fish/mongo.go diff --git a/biz/adaptor/server.go b/biz/adaptor/server.go index 2785668..7c6e8dd 100644 --- a/biz/adaptor/server.go +++ b/biz/adaptor/server.go @@ -17,6 +17,26 @@ type ContentServerImpl struct { PlanService service.IPlanService } +func (s *ContentServerImpl) DonateFish(ctx context.Context, req *content.DonateFishReq) (res *content.DonateFishResp, err error) { + return s.PlanService.DonateFish(ctx, req) + +} + +func (s *ContentServerImpl) AddUserFish(ctx context.Context, req *content.AddUserFishReq) (res *content.AddUserFishResp, err error) { + return s.PlanService.AddUserFish(ctx, req) + +} + +func (s *ContentServerImpl) ListFishByPlan(ctx context.Context, req *content.ListFishByPlanReq) (res *content.ListFishByPlanResp, err error) { + return s.PlanService.ListFishByPlan(ctx, req) + +} + +func (s *ContentServerImpl) RetrieveUserFish(ctx context.Context, req *content.RetrieveUserFishReq) (res *content.RetrieveUserFishResp, err error) { + return s.PlanService.RetrieveUserFish(ctx, req) + +} + func (s *ContentServerImpl) ListPlan(ctx context.Context, req *content.ListPlanReq) (res *content.ListPlanResp, err error) { return s.PlanService.ListPlan(ctx, req) diff --git a/biz/application/service/plan.go b/biz/application/service/plan.go index 193e3e7..bd27372 100644 --- a/biz/application/service/plan.go +++ b/biz/application/service/plan.go @@ -6,10 +6,13 @@ import ( "github.com/xh-polaris/gopkg/pagination/esp" "github.com/xh-polaris/gopkg/pagination/mongop" "github.com/xh-polaris/meowchat-content/biz/infrastructure/consts" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/donate" + Fish "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/fish" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/plan" "github.com/xh-polaris/meowchat-content/biz/infrastructure/util/convertor" "github.com/xh-polaris/service-idl-gen-go/kitex_gen/meowchat/content" "go.mongodb.org/mongo-driver/bson/primitive" + "sort" "time" ) @@ -20,11 +23,17 @@ type IPlanService interface { CreatePlan(ctx context.Context, req *content.CreatePlanReq) (*content.CreatePlanResp, error) UpdatePlan(ctx context.Context, req *content.UpdatePlanReq) (*content.UpdatePlanResp, error) DeletePlan(ctx context.Context, req *content.DeletePlanReq) (*content.DeletePlanResp, error) + DonateFish(ctx context.Context, req *content.DonateFishReq) (*content.DonateFishResp, error) + AddUserFish(ctx context.Context, req *content.AddUserFishReq) (*content.AddUserFishResp, error) + ListFishByPlan(ctx context.Context, req *content.ListFishByPlanReq) (*content.ListFishByPlanResp, error) + RetrieveUserFish(ctx context.Context, req *content.RetrieveUserFishReq) (*content.RetrieveUserFishResp, error) } type PlanService struct { - PlanMongoMapper plan.IMongoMapper - PlanEsMapper plan.IEsMapper + PlanMongoMapper plan.IMongoMapper + PlanEsMapper plan.IEsMapper + DonateMongoMapper donate.IMongoMapper + FishMongoMapper Fish.IMongoMapper } var PlanSet = wire.NewSet( @@ -42,7 +51,6 @@ func (s *PlanService) ListPlan(ctx context.Context, req *content.ListPlanReq) (* p := convertor.ParsePagination(req.PaginationOptions) if req.SearchOptions == nil { plans, total, err = s.PlanMongoMapper.FindManyAndCount(ctx, filter, p, mongop.IdCursorType) - print(plans) if err != nil { return nil, err } @@ -155,3 +163,100 @@ func (s *PlanService) DeletePlan(ctx context.Context, req *content.DeletePlanReq } return &content.DeletePlanResp{}, nil } + +func (s *PlanService) DonateFish(ctx context.Context, req *content.DonateFishReq) (*content.DonateFishResp, error) { + data, err := s.FishMongoMapper.FindOne(ctx, req.UserId) + if err != nil { + return nil, err + } + data.FishNum = data.FishNum - req.Fish + err = s.FishMongoMapper.Update(ctx, data) + if err != nil { + return nil, err + } + + err = s.DonateMongoMapper.Insert(ctx, &donate.Donate{ + UserId: req.UserId, + PlanId: req.PlanId, + FishNum: req.Fish, + }) + if err != nil { + return nil, err + } + res, err := s.PlanMongoMapper.FindOne(ctx, req.PlanId) + if err != nil { + return nil, err + } + res.NowFish = res.NowFish + req.Fish + err = s.PlanMongoMapper.Update(ctx, res) + if err != nil { + return nil, err + } + + return &content.DonateFishResp{}, nil +} + +func (s *PlanService) AddUserFish(ctx context.Context, req *content.AddUserFishReq) (*content.AddUserFishResp, error) { + data, err := s.FishMongoMapper.FindOne(ctx, req.UserId) + switch err { + case nil: + data.FishNum = data.FishNum + req.Fish + err = s.FishMongoMapper.Update(ctx, data) + if err != nil { + return nil, err + } + return &content.AddUserFishResp{}, nil + case consts.ErrNotFound: + oid, err := primitive.ObjectIDFromHex(req.UserId) + if err != nil { + return nil, err + } + err = s.FishMongoMapper.Insert(ctx, &Fish.Fish{ + UserId: oid, + FishNum: req.Fish, + }) + if err != nil { + return nil, err + } + return &content.AddUserFishResp{}, nil + default: + return nil, err + } +} + +func (s *PlanService) ListFishByPlan(ctx context.Context, req *content.ListFishByPlanReq) (*content.ListFishByPlanResp, error) { + data, err := s.DonateMongoMapper.ListDonateByPlan(ctx, req.PlanId) + if err != nil { + return nil, err + } + fishMap := make(map[string]int64, len(data)) + userIds := make([]string, 0, len(data)) + for _, value := range data { + i, ok := fishMap[value.UserId] + if ok == true { + fishMap[value.UserId] = value.FishNum + i + } else { + fishMap[value.UserId] = value.FishNum + userIds = append(userIds, value.UserId) + } + } + sort.Slice(userIds, func(i, j int) bool { + return fishMap[userIds[i]] > fishMap[userIds[j]] + }) + return &content.ListFishByPlanResp{ + UserIds: userIds, + FishMap: fishMap, + }, nil +} + +func (s *PlanService) RetrieveUserFish(ctx context.Context, req *content.RetrieveUserFishReq) (*content.RetrieveUserFishResp, error) { + data, err := s.FishMongoMapper.FindOne(ctx, req.UserId) + switch err { + case nil: + return &content.RetrieveUserFishResp{Fish: data.FishNum}, nil + case consts.ErrNotFound: + return &content.RetrieveUserFishResp{Fish: 0}, nil + default: + return nil, err + } +} diff --git a/biz/infrastructure/consts/field.go b/biz/infrastructure/consts/field.go index 3fb2aa4..d15f7df 100644 --- a/biz/infrastructure/consts/field.go +++ b/biz/infrastructure/consts/field.go @@ -20,4 +20,6 @@ const ( StartTime = "startTime" EndTime = "endTime" InitiatorIds = "initiatorIds" + PlanId = "planId" + FishNum = "fishNum" ) diff --git a/biz/infrastructure/mapper/donate/mongo.go b/biz/infrastructure/mapper/donate/mongo.go new file mode 100644 index 0000000..419945b --- /dev/null +++ b/biz/infrastructure/mapper/donate/mongo.go @@ -0,0 +1,131 @@ +package donate + +import ( + "context" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/consts" + "time" + + "github.com/xh-polaris/meowchat-content/biz/infrastructure/config" + "github.com/zeromicro/go-zero/core/stores/monc" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo/options" +) + +var _ IMongoMapper = (*MongoMapper)(nil) + +const prefixDonateCacheKey = "cache:donate:" +const CollectionName = "donate" + +type ( + IMongoMapper interface { + Insert(ctx context.Context, data *Donate) error + FindOne(ctx context.Context, id string) (*Donate, error) + Update(ctx context.Context, data *Donate) error + Delete(ctx context.Context, id string) error + ListDonateByPlan(ctx context.Context, planId string) ([]*Donate, error) + ListDonateByUser(ctx context.Context, userId string) ([]*Donate, error) + } + + MongoMapper struct { + conn *monc.Model + } + + Donate struct { + ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` + UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"` + CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"` + UserId string `bson:"userId,omitempty" json:"userId,omitempty"` + PlanId string `bson:"planId,omitempty" json:"planId,omitempty"` + FishNum int64 `bson:"fishNum,omitempty" json:"fishNum,omitempty"` + } +) + +func NewMongoMapper(config *config.Config) IMongoMapper { + conn := monc.MustNewModel(config.Mongo.URL, config.Mongo.DB, CollectionName, config.Cache) + return &MongoMapper{ + conn: conn, + } +} + +func (m *MongoMapper) Insert(ctx context.Context, data *Donate) error { + if data.ID.IsZero() { + data.ID = primitive.NewObjectID() + data.CreateAt = time.Now() + data.UpdateAt = time.Now() + } + + key := prefixDonateCacheKey + data.ID.Hex() + _, err := m.conn.InsertOne(ctx, key, data) + return err +} + +func (m *MongoMapper) FindOne(ctx context.Context, id string) (*Donate, error) { + oid, err := primitive.ObjectIDFromHex(id) + if err != nil { + return nil, consts.ErrInvalidObjectId + } + + var data Donate + key := prefixDonateCacheKey + id + err = m.conn.FindOne(ctx, key, &data, bson.M{consts.ID: oid}) + switch err { + case nil: + return &data, nil + case monc.ErrNotFound: + return nil, consts.ErrNotFound + default: + return nil, err + } +} + +func (m *MongoMapper) Update(ctx context.Context, data *Donate) error { + data.UpdateAt = time.Now() + key := prefixDonateCacheKey + data.ID.Hex() + _, err := m.conn.ReplaceOne(ctx, key, bson.M{consts.ID: data.ID}, data) + return err +} + +func (m *MongoMapper) Delete(ctx context.Context, id string) error { + oid, err := primitive.ObjectIDFromHex(id) + if err != nil { + return consts.ErrInvalidObjectId + } + key := prefixDonateCacheKey + id + _, err = m.conn.DeleteOne(ctx, key, bson.M{consts.ID: oid}) + return err +} + +func (m *MongoMapper) ListDonateByPlan(ctx context.Context, planId string) ([]*Donate, error) { + var data []*Donate + var err error + + opts := options.FindOptions{ + Sort: bson.M{consts.FishNum: -1}, + } + filter := bson.M{consts.PlanId: planId} + + err = m.conn.Find(ctx, &data, filter, &opts) + if err != nil { + return nil, err + } else { + return data, nil + } +} + +func (m *MongoMapper) ListDonateByUser(ctx context.Context, userId string) ([]*Donate, error) { + var data []*Donate + var err error + + opts := options.FindOptions{ + Sort: bson.M{consts.FishNum: -1}, + } + filter := bson.M{consts.UserId: userId} + + err = m.conn.Find(ctx, &data, filter, &opts) + if err != nil { + return nil, err + } else { + return data, nil + } +} diff --git a/biz/infrastructure/mapper/fish/mongo.go b/biz/infrastructure/mapper/fish/mongo.go new file mode 100644 index 0000000..1c40931 --- /dev/null +++ b/biz/infrastructure/mapper/fish/mongo.go @@ -0,0 +1,88 @@ +package fish + +import ( + "context" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/consts" + "time" + + "github.com/xh-polaris/meowchat-content/biz/infrastructure/config" + "github.com/zeromicro/go-zero/core/stores/monc" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +var _ IMongoMapper = (*MongoMapper)(nil) + +const prefixFishCacheKey = "cache:fish:" +const CollectionName = "fish" + +type ( + IMongoMapper interface { + Insert(ctx context.Context, data *Fish) error + FindOne(ctx context.Context, id string) (*Fish, error) + Update(ctx context.Context, data *Fish) error + Delete(ctx context.Context, id string) error + } + + MongoMapper struct { + conn *monc.Model + } + + Fish struct { + UserId primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` + UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"` + CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"` + FishNum int64 `bson:"fishNum,omitempty" json:"fishNum,omitempty"` + } +) + +func NewMongoMapper(config *config.Config) IMongoMapper { + conn := monc.MustNewModel(config.Mongo.URL, config.Mongo.DB, CollectionName, config.Cache) + return &MongoMapper{ + conn: conn, + } +} + +func (m *MongoMapper) Insert(ctx context.Context, data *Fish) error { + data.CreateAt = time.Now() + data.UpdateAt = time.Now() + key := prefixFishCacheKey + data.UserId.Hex() + _, err := m.conn.InsertOne(ctx, key, data) + return err +} + +func (m *MongoMapper) FindOne(ctx context.Context, id string) (*Fish, error) { + oid, err := primitive.ObjectIDFromHex(id) + if err != nil { + return nil, consts.ErrInvalidObjectId + } + + var data Fish + key := prefixFishCacheKey + id + err = m.conn.FindOne(ctx, key, &data, bson.M{consts.ID: oid}) + switch err { + case nil: + return &data, nil + case monc.ErrNotFound: + return nil, consts.ErrNotFound + default: + return nil, err + } +} + +func (m *MongoMapper) Update(ctx context.Context, data *Fish) error { + data.UpdateAt = time.Now() + key := prefixFishCacheKey + data.UserId.Hex() + _, err := m.conn.ReplaceOne(ctx, key, bson.M{consts.ID: data.UserId}, data) + return err +} + +func (m *MongoMapper) Delete(ctx context.Context, id string) error { + oid, err := primitive.ObjectIDFromHex(id) + if err != nil { + return consts.ErrInvalidObjectId + } + key := prefixFishCacheKey + id + _, err = m.conn.DeleteOne(ctx, key, bson.M{consts.ID: oid}) + return err +} diff --git a/biz/infrastructure/mapper/plan/mongo.go b/biz/infrastructure/mapper/plan/mongo.go index f90e584..20989f2 100644 --- a/biz/infrastructure/mapper/plan/mongo.go +++ b/biz/infrastructure/mapper/plan/mongo.go @@ -43,6 +43,8 @@ type ( InitiatorIds []string `bson:"initiatorIds,omitempty"` StartTime time.Time `bson:"startTime,omitempty" json:"startTime,omitempty"` EndTime time.Time `bson:"endTime,omitempty" json:"endTime,omitempty"` + MaxFish int64 `bson:"maxFish,omitempty" json:"maxFish,omitempty"` + NowFish int64 `bson:"nowFish,omitempty" json:"nowFish,omitempty"` UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"` CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"` diff --git a/go.mod b/go.mod index f4ac56f..2ef6a0e 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/kitex-contrib/obs-opentelemetry v0.2.3 github.com/mitchellh/mapstructure v1.1.2 github.com/xh-polaris/gopkg v0.0.0-20230805125627-ce41556a654d - github.com/xh-polaris/service-idl-gen-go v0.0.0-20230809180852-d28727be21d4 + github.com/xh-polaris/service-idl-gen-go v0.0.0-20230813101042-26c6385e25a8 github.com/zeromicro/go-zero v1.5.4 go.mongodb.org/mongo-driver v1.12.0 google.golang.org/grpc v1.56.2 diff --git a/go.sum b/go.sum index ac78824..7e9b178 100644 --- a/go.sum +++ b/go.sum @@ -386,8 +386,8 @@ github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6 github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xh-polaris/gopkg v0.0.0-20230805125627-ce41556a654d h1:xAbXPYbhcqB9/NOnmwsGcjhTVQzRd0xP7jJpGTXmOHM= github.com/xh-polaris/gopkg v0.0.0-20230805125627-ce41556a654d/go.mod h1:eFkuwj6uq1k4hbDa66TijCWGL4PrNeWaNmAnxfWDeU0= -github.com/xh-polaris/service-idl-gen-go v0.0.0-20230809180852-d28727be21d4 h1:LWAehgXERkNumf49QaExpINwEPbW9j0RN8xsK5DSkvQ= -github.com/xh-polaris/service-idl-gen-go v0.0.0-20230809180852-d28727be21d4/go.mod h1:KjBt4ZOfugCsdAbFlrniKMDrpJAJobm8KEezTvKVnJM= +github.com/xh-polaris/service-idl-gen-go v0.0.0-20230813101042-26c6385e25a8 h1:us6cv8ashLDusy5qj4/9rS9E/pP3lFfpcFtdE22G+9Y= +github.com/xh-polaris/service-idl-gen-go v0.0.0-20230813101042-26c6385e25a8/go.mod h1:KjBt4ZOfugCsdAbFlrniKMDrpJAJobm8KEezTvKVnJM= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/provider/provider.go b/provider/provider.go index 5db57c7..c64b78c 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -4,6 +4,8 @@ import ( "github.com/google/wire" "github.com/xh-polaris/meowchat-content/biz/infrastructure/config" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/cat" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/donate" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/fish" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/image" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/moment" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/plan" @@ -40,4 +42,6 @@ var MapperSet = wire.NewSet( post.NewEsMapper, plan.NewMongoMapper, plan.NewEsMapper, + fish.NewMongoMapper, + donate.NewMongoMapper, ) diff --git a/provider/wire_gen.go b/provider/wire_gen.go index 4533d10..65f20b3 100644 --- a/provider/wire_gen.go +++ b/provider/wire_gen.go @@ -11,6 +11,8 @@ import ( "github.com/xh-polaris/meowchat-content/biz/application/service" "github.com/xh-polaris/meowchat-content/biz/infrastructure/config" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/cat" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/donate" + "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/fish" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/image" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/moment" "github.com/xh-polaris/meowchat-content/biz/infrastructure/mapper/plan" @@ -48,9 +50,13 @@ func NewContentServerImpl() (*adaptor.ContentServerImpl, error) { } planIMongoMapper := plan.NewMongoMapper(configConfig) planIEsMapper := plan.NewEsMapper(configConfig) + donateIMongoMapper := donate.NewMongoMapper(configConfig) + fishIMongoMapper := fish.NewMongoMapper(configConfig) planService := &service.PlanService{ - PlanMongoMapper: planIMongoMapper, - PlanEsMapper: planIEsMapper, + PlanMongoMapper: planIMongoMapper, + PlanEsMapper: planIEsMapper, + DonateMongoMapper: donateIMongoMapper, + FishMongoMapper: fishIMongoMapper, } contentServerImpl := &adaptor.ContentServerImpl{ Config: configConfig,