thread-master/apps/backend/internal/module/radar/repository/watch_mongo.go

129 lines
3.6 KiB
Go
Raw Permalink Normal View History

2026-08-03 05:52:02 +00:00
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 {
2026-08-13 02:22:24 +00:00
if w == nil {
return domain.ErrValidation
}
if err := w.NormalizeContext(); err != nil {
return err
}
var old domain.RadarWatch
if err := s.watches.FindOne(ctx, &old, bson.M{"_id": w.ID}); err == nil {
if old.ContextMode == domain.WatchContextProduct && (old.BrandID != w.BrandID || old.ProductID != w.ProductID) {
return domain.ErrValidation
}
} else if err != mon.ErrNotFound {
return err
}
2026-08-03 05:52:02 +00:00
_, 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
}
2026-08-13 02:22:24 +00:00
func (s *MonStore) DeleteWatch(ctx context.Context, id string) error {
res, err := s.watches.DeleteOne(ctx, bson.M{"_id": id})
if err != nil {
return err
}
if res == 0 {
return domain.ErrNotFound
}
return nil
}
2026-08-03 05:52:02 +00:00
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
}
2026-08-13 02:22:24 +00:00
if f.ContextMode == domain.WatchContextGeneric {
q["$or"] = bson.A{bson.M{"context_mode": domain.WatchContextGeneric}, bson.M{"context_mode": bson.M{"$exists": false}}, bson.M{"context_mode": ""}}
} else if f.ContextMode != "" {
q["context_mode"] = f.ContextMode
}
if f.BrandID != "" {
q["brand_id"] = f.BrandID
}
if f.ProductID != "" {
q["product_id"] = f.ProductID
}
2026-08-03 05:52:02 +00:00
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)))
2026-08-13 02:22:24 +00:00
for _, w := range list {
if w != nil && w.ContextMode == "" {
w.ContextMode = domain.WatchContextGeneric
}
}
2026-08-03 05:52:02 +00:00
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
}