package model import ( "app-cloudep-tweeting-service/internal/domain" "context" "errors" "github.com/zeromicro/go-zero/core/stores/mon" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "time" ) var _ Post_likesModel = (*customPost_likesModel)(nil) type ( // Post_likesModel is an interface to be customized, add more methods here, // and implement the added methods in customPost_likesModel. Post_likesModel interface { post_likesModel LikeDislike(ctx context.Context, postLike *PostLikes) error FindLikeUsers(ctx context.Context, param *QueryPostLikeReq) ([]*PostLikes, int64, error) FindUIDPostLikeStatus(ctx context.Context, param *QueryUIDPostLikeStatusReq) ([]UIDPostLikeStatusResp, error) } QueryPostLikeReq struct { Target string `bson:"target"` LikeType domain.LikeType `bson:"like_type"` PageIndex int64 `bson:"page_index"` PageSize int64 `bson:"page_size"` } QueryUIDPostLikeStatusReq struct { Targets []string `bson:"target"` LikeType domain.LikeType `bson:"like_type"` UID string } UIDPostLikeStatusResp struct { TargetID string `json:"target_id"` LikeStatus bool `json:"like_status"` } customPost_likesModel struct { *defaultPost_likesModel } ) // NewPost_likesModel returns a model for the mongo. func NewPost_likesModel(url, db, collection string) Post_likesModel { conn := mon.MustNewModel(url, db, collection) return &customPost_likesModel{ defaultPost_likesModel: newDefaultPost_likesModel(conn), } } func (m *defaultPost_likesModel) LikeDislike(ctx context.Context, postLike *PostLikes) error { // 使用 target_id、uid、type 來查詢資料是否存在 filter := bson.M{ "target_id": postLike.TargetID, "uid": postLike.UID, "type": postLike.Type, } // 查詢資料是否存在 var existingPostLike PostLikes err := m.conn.FindOne(ctx, &existingPostLike, filter) if err == nil { // 資料存在,進行刪除操作 _, err = m.conn.DeleteOne(ctx, filter) if err != nil { return err // 刪除失敗 } return nil // 刪除成功 } else if errors.Is(mongo.ErrNoDocuments, err) { // 資料不存在,進行插入操作 postLike.ID = primitive.NewObjectID() // 設置新的 ObjectID postLike.CreateAt = time.Now().UTC().UnixNano() _, err = m.conn.InsertOne(ctx, postLike) if err != nil { return err // 插入失敗 } return nil // 插入成功 } else { // 其他錯誤 return err } } func (m *defaultPost_likesModel) FindLikeUsers(ctx context.Context, param *QueryPostLikeReq) ([]*PostLikes, int64, error) { // 建立篩選條件 filter := bson.M{} // 如果指定了 Target 條件,將其添加到篩選條件中 if param.Target != "" { filter["target_id"] = param.Target } // 如果指定了 LikeType 條件,將其添加到篩選條件中 if param.LikeType != 0 { filter["type"] = param.LikeType } // 計算符合條件的文檔總數 totalCount, err := m.conn.CountDocuments(ctx, filter) if err != nil { return nil, 0, err } // 設置分頁和排序選項 opts := options.Find() opts.SetSort(bson.D{{"createAt", -1}}) // 按照創建時間倒序排序 if param.PageSize > 0 { opts.SetLimit(param.PageSize) } if param.PageIndex > 0 && param.PageSize > 0 { opts.SetSkip((param.PageIndex - 1) * param.PageSize) } // 查詢符合條件的文檔 var results []*PostLikes err = m.conn.Find(ctx, &results, filter, opts) if err != nil { return nil, 0, err } // 返回結果集、總數和錯誤信息 return results, totalCount, nil } func (m *defaultPost_likesModel) FindUIDPostLikeStatus(ctx context.Context, param *QueryUIDPostLikeStatusReq) ([]UIDPostLikeStatusResp, error) { // 初始化返回結果的切片 var results []UIDPostLikeStatusResp // 建立篩選條件 filter := bson.M{ "uid": param.UID, // 篩選指定的 UID "target_id": bson.M{"$in": param.Targets}, // 篩選多個目標 ID "type": param.LikeType, // 篩選指定的 LikeType } // 查詢符合條件的點讚記錄 var postLikes []PostLikes err := m.conn.Find(ctx, &postLikes, filter) if err != nil { return nil, err } // 構建一個 map 來保存查詢到的點讚記錄 targetLikeMap := make(map[string]bool) for _, like := range postLikes { targetLikeMap[like.TargetID] = true } // 構建每個目標的點讚狀態 for _, targetID := range param.Targets { likeStatus := UIDPostLikeStatusResp{ TargetID: targetID, LikeStatus: targetLikeMap[targetID], // 如果 map 中有該 targetID,返回 true,否則返回 false } // 如果該 targetID 沒有點讚記錄,默認 LikeStatus 為 false if _, found := targetLikeMap[targetID]; !found { likeStatus.LikeStatus = false } results = append(results, likeStatus) } return results, nil }