package model import ( "context" "fmt" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/cache" "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" "time" ) var _ PostModel = (*customPostModel)(nil) type ( // PostModel is an interface to be customized, add more methods here, // and implement the added methods in customPostModel. PostModel interface { postModel DeleteMany(ctx context.Context, id ...string) (int64, error) UpdateOptional(ctx context.Context, data *Post) (*mongo.UpdateResult, error) } customPostModel struct { *defaultPostModel } ) // NewPostModel returns a model for the mongo. func NewPostModel(url, db, collection string, c cache.CacheConf) PostModel { conn := monc.MustNewModel(url, db, collection, c) return &customPostModel{ defaultPostModel: newDefaultPostModel(conn), } } func (m *defaultPostModel) DeleteMany(ctx context.Context, id ...string) (int64, error) { objectIDs := make([]primitive.ObjectID, 0, len(id)) key := make([]string, 0, len(id)) // prepare for _, item := range id { oid, err := primitive.ObjectIDFromHex(item) if err != nil { logx.WithCallerSkip(1).WithFields( logx.Field("func", "defaultPostModel.DeleteMany"), logx.Field("id", item), ).Error(err.Error()) continue } objectIDs = append(objectIDs, oid) key = append(key, prefixPostCacheKey+item) } // 檢查是否有有效的 ObjectIDs if len(objectIDs) == 0 { return 0, ErrNotFound } // 刪除文檔 res, err := m.conn.DeleteMany(ctx, bson.M{"_id": bson.M{"$in": objectIDs}}) if err != nil { return 0, err } err = m.conn.DelCache(ctx, key...) if err != nil { return 0, err } return res, err } func (m *defaultPostModel) UpdateOptional(ctx context.Context, data *Post) (*mongo.UpdateResult, error) { update := bson.M{"$set": bson.M{}} if data.UID != "" { update["$set"].(bson.M)["uid"] = data.UID } if data.Content != "" { update["$set"].(bson.M)["content"] = data.Content } if data.Status != 0 { update["$set"].(bson.M)["status"] = data.Status } if data.IsAd { update["$set"].(bson.M)["is_ad"] = data.IsAd } if len(data.Tags) > 0 { update["$set"].(bson.M)["tags"] = data.Tags } if len(data.Media) > 0 { update["$set"].(bson.M)["media_url"] = data.Media } if data.Like != 0 { update["$set"].(bson.M)["like"] = data.Like } if data.DisLike != 0 { update["$set"].(bson.M)["dislike"] = data.DisLike } // UpdateAt 是每次都需要更新的,不用檢查 update["$set"].(bson.M)["updateAt"] = time.Now().UTC().UnixNano() fmt.Println("update map", update) key := prefixPostCacheKey + data.ID.Hex() res, err := m.conn.UpdateOne(ctx, key, bson.M{"_id": data.ID}, update) return res, err }