@@ -16,14 +16,19 @@ package repo
1616
1717import (
1818 "context"
19+ "time"
1920
2021 "github.com/Boyuan-IT-Club/Meowpick-Backend/application/dto"
22+ "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/cache"
2123 "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/config"
2224 "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/model"
2325 "github.com/Boyuan-IT-Club/Meowpick-Backend/infra/util/page"
2426 "github.com/Boyuan-IT-Club/Meowpick-Backend/types/consts"
2527 "github.com/zeromicro/go-zero/core/stores/monc"
2628 "go.mongodb.org/mongo-driver/bson"
29+ "go.mongodb.org/mongo-driver/bson/primitive"
30+ "go.mongodb.org/mongo-driver/mongo"
31+ "go.mongodb.org/mongo-driver/mongo/options"
2732)
2833
2934var _ IProposalRepo = (* ProposalRepo )(nil )
@@ -34,10 +39,14 @@ const (
3439
3540type IProposalRepo interface {
3641 FindMany (ctx context.Context , param * dto.PageParam ) ([]* model.Proposal , int64 , error )
42+ Toggle (ctx context.Context , userId , targetId string , targetType int32 ) (bool , error )
43+ IsProposal (ctx context.Context , userId , targetId string , targetType int32 ) (bool , error )
44+ CountProposalByTarget (ctx context.Context , targetId string , targetType int32 ) (int64 , error )
3745}
3846
3947type ProposalRepo struct {
40- conn * monc.Model
48+ conn * monc.Model
49+ cache * cache.ProposalCache
4150}
4251
4352func NewProposalRepo (cfg * config.Config ) * ProposalRepo {
@@ -66,3 +75,54 @@ func (r *ProposalRepo) FindMany(ctx context.Context, param *dto.PageParam) ([]*m
6675
6776 return proposals , total , nil
6877}
78+
79+ // Toggle 翻转投票状态
80+ func (r * ProposalRepo ) Toggle (ctx context.Context , userId , targetId string , targetType int32 ) (bool , error ) {
81+ now := time .Now ()
82+ pipeline := mongo.Pipeline {
83+ {{"$set" , bson.M {
84+ consts .ID : bson.M {"$ifNull" : bson.A {"$" + consts .ID , primitive .NewObjectID ().Hex ()}},
85+
86+ consts .UserID : bson.M {"$ifNull" : bson.A {"$" + consts .UserID , userId }},
87+ consts .TargetID : bson.M {"$ifNull" : bson.A {"$" + consts .TargetID , targetId }},
88+
89+ consts .CreatedAt : bson.M {"$ifNull" : bson.A {"$" + consts .CreatedAt , now }},
90+ consts .UpdatedAt : now ,
91+
92+ consts .Active : bson.M {"$cond" : bson.A {
93+ bson.M {"$not" : bson.M {"$ifNull" : bson.A {"$" + consts .ID , nil }}},
94+ true ,
95+ bson.M {"$not" : "$active" },
96+ }},
97+ }}},
98+ }
99+ var proposal struct {
100+ Active bool `bson:"active"`
101+ }
102+
103+ err := r .conn .FindOneAndUpdateNoCache (ctx ,
104+ & proposal ,
105+ bson.M {consts .UserID : userId , consts .TargetID : targetId },
106+ pipeline ,
107+ options .FindOneAndUpdate ().SetUpsert (true ).SetReturnDocument (options .After ),
108+ )
109+ return proposal .Active , err
110+ }
111+
112+ // IsProposal 获取一个用户对一个目标的当前投票状态
113+ func (r * ProposalRepo ) IsProposal (ctx context.Context , userId , targetId string , targetType int32 ) (bool , error ) {
114+ cnt , err := r .conn .CountDocuments (ctx , bson.M {
115+ consts .UserID : userId ,
116+ consts .TargetID : targetId ,
117+ consts .Active : bson.M {"$ne" : false },
118+ })
119+ return cnt > 0 , err
120+ }
121+
122+ // CountProposalByTarget 获得目标的总投票数
123+ func (r * ProposalRepo ) CountProposalByTarget (ctx context.Context , targetId string , targetType int32 ) (int64 , error ) {
124+ return r .conn .CountDocuments (ctx , bson.M {
125+ consts .TargetID : targetId ,
126+ consts .Active : bson.M {"$ne" : false },
127+ })
128+ }
0 commit comments