spark-server/internal/module/square/model/query.go
DESKTOP-L8OUL9F\gfl0034 715ace7ac6 feat(square): 广场 Bot/RSS 发布与媒体校验
支持广场机器人发帖与媒体类型检查,并补充相关迁移与 i18n。
2026-09-24 23:07:06 +08:00

192 lines
4.9 KiB
Go

package model
import (
"context"
"errors"
"time"
"gorm.io/gorm"
"spark-server/internal/module/square/entity"
)
// notExpiredSQL keeps user posts and unexpired bot posts.
const notExpiredSQL = "(expires_at IS NULL OR expires_at > ?)"
func (m *Repo) GetPost(ctx context.Context, id int64) (*entity.Post, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var row Post
if err := db.Where("id = ?", id).Take(&row).Error; err != nil {
return nil, mapDBErr(err)
}
return row.Entity(), nil
}
func (m *Repo) ListByAuthors(ctx context.Context, authorIDs []int64, cursor int64, limit int) ([]*entity.Post, error) {
if len(authorIDs) == 0 {
return []*entity.Post{}, nil
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
q := db.Where("user_id IN ? AND status = ? AND "+notExpiredSQL, authorIDs, entity.StatusNormal, time.Now())
if cursor > 0 {
q = q.Where("id < ?", cursor)
}
var rows []Post
if err := q.Order("id DESC").Limit(limit).Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
return collectPosts(rows), nil
}
func (m *Repo) ListByAuthor(ctx context.Context, authorID, cursor int64, limit int) ([]*entity.Post, error) {
return m.ListByAuthors(ctx, []int64{authorID}, cursor, limit)
}
func (m *Repo) ListPublicFeed(ctx context.Context, cursor int64, limit int) ([]*entity.Post, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
q := db.Where(
"audit_status = ? AND status = ? AND visibility IN ? AND "+notExpiredSQL,
entity.AuditApproved, entity.StatusNormal,
[]int16{int16(entity.VisibilityPublic), int16(entity.VisibilityExclude)},
time.Now(),
)
if cursor > 0 {
q = q.Where("id < ?", cursor)
}
var rows []Post
if err := q.Order("id DESC").Limit(limit).Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
return collectPosts(rows), nil
}
func (m *Repo) ListAudience(ctx context.Context, postIDs []int64) (map[int64][]int64, error) {
out := make(map[int64][]int64)
if len(postIDs) == 0 {
return out, nil
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var rows []Audience
if err := db.Where("post_id IN ?", postIDs).Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
for _, row := range rows {
out[row.PostID] = append(out[row.PostID], row.PeerID)
}
return out, nil
}
func (m *Repo) ListLikes(ctx context.Context, postIDs []int64) (map[int64][]*entity.Like, error) {
out := make(map[int64][]*entity.Like)
if len(postIDs) == 0 {
return out, nil
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var rows []Like
if err := db.Where("post_id IN ?", postIDs).Order("created_at ASC").Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
for i := range rows {
like := rows[i].Entity()
out[like.PostID] = append(out[like.PostID], like)
}
return out, nil
}
func (m *Repo) ListComments(ctx context.Context, postIDs []int64) (map[int64][]*entity.Comment, error) {
out := make(map[int64][]*entity.Comment)
if len(postIDs) == 0 {
return out, nil
}
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var rows []Comment
if err := db.Where("post_id IN ?", postIDs).Order("id ASC").Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
for i := range rows {
c := rows[i].Entity()
out[c.PostID] = append(out[c.PostID], c)
}
return out, nil
}
func (m *Repo) GetComment(ctx context.Context, id int64) (*entity.Comment, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var row Comment
if err := db.Where("id = ?", id).Take(&row).Error; err != nil {
return nil, mapDBErr(err)
}
return row.Entity(), nil
}
func (m *Repo) GetNoticeState(ctx context.Context, userID int64) (*entity.NoticeState, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var row NoticeState
if err := db.Where("user_id = ?", userID).Take(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return entity.DefaultNoticeState(userID), nil
}
return nil, mapDBErr(err)
}
return row.Entity(), nil
}
func (m *Repo) LatestNoticeID(ctx context.Context, userID int64) (int64, error) {
db, err := m.session(ctx)
if err != nil {
return 0, err
}
var row Notice
if err := db.Where("to_user_id = ?", userID).Order("id DESC").Limit(1).Take(&row).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return 0, nil
}
return 0, mapDBErr(err)
}
return row.ID, nil
}
func (m *Repo) ListNotices(ctx context.Context, userID, cursor int64, limit int) ([]*entity.Notice, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
q := db.Where("to_user_id = ?", userID)
if cursor > 0 {
q = q.Where("id < ?", cursor)
}
var rows []Notice
if err := q.Order("id DESC").Limit(limit).Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
out := make([]*entity.Notice, 0, len(rows))
for i := range rows {
out = append(out, rows[i].Entity())
}
return out, nil
}