package repository import ( "context" "apps/backend/internal/module/radar/domain" "github.com/zeromicro/go-zero/core/stores/mon" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) func (s *MonStore) SaveWatch(ctx context.Context, w *domain.RadarWatch) error { _, err := s.watches.ReplaceOne(ctx, bson.M{"_id": w.ID}, w, options.Replace().SetUpsert(true)) return err } func (s *MonStore) GetWatch(ctx context.Context, id string) (*domain.RadarWatch, error) { var w domain.RadarWatch err := s.watches.FindOne(ctx, &w, bson.M{"_id": id}) if err == mon.ErrNotFound { return nil, domain.ErrNotFound } if err != nil { return nil, err } return &w, nil } func (s *MonStore) ListWatches(ctx context.Context, ownerUID int64, f domain.WatchListFilter) ([]*domain.RadarWatch, int64, error) { q := bson.M{"owner_uid": ownerUID} if f.Status != "" { q["status"] = f.Status } total, err := s.watches.CountDocuments(ctx, q) if err != nil { return nil, 0, err } page, ps := f.Page, f.PageSize if page < 1 { page = 1 } if ps < 1 { ps = 20 } var list []*domain.RadarWatch err = s.watches.Find(ctx, &list, q, options.Find(). SetSort(bson.D{{Key: "created_at", Value: -1}}). SetSkip(int64((page-1)*ps)). SetLimit(int64(ps))) return list, total, err } func (s *MonStore) ListActiveWatches(ctx context.Context, ownerUID int64) ([]*domain.RadarWatch, error) { var list []*domain.RadarWatch err := s.watches.Find(ctx, &list, bson.M{"owner_uid": ownerUID, "status": domain.WatchActive}, options.Find().SetSort(bson.D{{Key: "created_at", Value: 1}})) return list, err } func (s *MonStore) ListAllActiveWatches(ctx context.Context) ([]*domain.RadarWatch, error) { var list []*domain.RadarWatch err := s.watches.Find(ctx, &list, bson.M{"status": domain.WatchActive}, options.Find().SetSort(bson.D{ {Key: "owner_uid", Value: 1}, {Key: "created_at", Value: 1}, })) return list, err } func (s *MonStore) CountActiveWatches(ctx context.Context, ownerUID int64) (int64, error) { return s.watches.CountDocuments(ctx, bson.M{"owner_uid": ownerUID, "status": domain.WatchActive}) } // TouchWatchSweptAt 只動 last_swept_at,避免與使用者同時編輯關鍵字互相覆蓋。 func (s *MonStore) TouchWatchSweptAt(ctx context.Context, id string, at int64) error { res, err := s.watches.UpdateOne(ctx, bson.M{"_id": id}, bson.M{"$set": bson.M{"last_swept_at": at}}) if err != nil { return err } if res.MatchedCount == 0 { return domain.ErrNotFound } return nil }