thread-master/apps/backend/internal/module/appnotif/repository/mongo.go

128 lines
3.0 KiB
Go
Raw Normal View History

2026-07-13 01:15:30 +00:00
package repository
import (
"context"
libmongo "apps/backend/internal/lib/mongo"
"apps/backend/internal/module/appnotif/domain"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
const col = "notifications"
type MonStore struct {
n *mon.Model
}
func NewMonStore(uri, database string) *MonStore {
uri = libmongo.MustMongoURI(uri)
return &MonStore{n: mon.MustNewModel(uri, database, col)}
}
func (s *MonStore) Insert(ctx context.Context, n *domain.Notification) error {
_, err := s.n.InsertOne(ctx, n)
return err
}
func (s *MonStore) ListByOwner(ctx context.Context, ownerUID int64) ([]*domain.Notification, error) {
var list []*domain.Notification
err := s.n.Find(ctx, &list, bson.M{"owner_uid": ownerUID},
options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}))
return list, err
}
func (s *MonStore) UnreadCount(ctx context.Context, ownerUID int64) (int64, error) {
var list2 []*domain.Notification
if err := s.n.Find(ctx, &list2, bson.M{"owner_uid": ownerUID}); err != nil {
return 0, err
}
var c int64
for _, n := range list2 {
if n.ReadAt == 0 {
c++
}
}
return c, nil
}
func (s *MonStore) FindByID(ctx context.Context, id string) (*domain.Notification, error) {
var n domain.Notification
err := s.n.FindOne(ctx, &n, bson.M{"_id": id})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
return &n, nil
}
func (s *MonStore) MarkRead(ctx context.Context, ownerUID int64, id string) error {
n, err := s.FindByID(ctx, id)
if err != nil {
return err
}
if n.OwnerUID != ownerUID {
return domain.ErrForbidden
}
if n.ReadAt == 0 {
n.ReadAt = domain.NowNano()
_, err = s.n.ReplaceOne(ctx, bson.M{"_id": id}, n)
}
return err
}
func (s *MonStore) MarkAllRead(ctx context.Context, ownerUID int64) error {
list, err := s.ListByOwner(ctx, ownerUID)
if err != nil {
return err
}
now := domain.NowNano()
for _, n := range list {
if n.ReadAt == 0 {
n.ReadAt = now
_, _ = s.n.ReplaceOne(ctx, bson.M{"_id": n.ID}, n)
}
}
return nil
}
func (s *MonStore) FindLatestByJobRef(ctx context.Context, ownerUID int64, jobID string) (*domain.Notification, error) {
if jobID == "" {
return nil, domain.ErrNotFound
}
var list []*domain.Notification
err := s.n.Find(ctx, &list, bson.M{
"owner_uid": ownerUID,
"kind": domain.KindJob,
"ref_type": domain.RefJob,
"ref_id": jobID,
}, options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}).SetLimit(1))
if err != nil {
return nil, err
}
if len(list) == 0 {
return nil, domain.ErrNotFound
}
return list[0], nil
}
func (s *MonStore) Replace(ctx context.Context, n *domain.Notification) error {
if n == nil || n.ID == "" {
return domain.ErrNotFound
}
res, err := s.n.ReplaceOne(ctx, bson.M{"_id": n.ID}, n)
if err != nil {
return err
}
if res.MatchedCount == 0 {
return domain.ErrNotFound
}
return nil
}
var _ domain.Repository = (*MonStore)(nil)