spark-server/internal/module/friend/model/friend_request.go
2026-09-23 17:11:56 +08:00

133 lines
4.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"context"
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"spark-server/internal/module/friend/entity"
"spark-server/internal/pkg/errs"
)
// FriendRequest maps table friend_requests.
type FriendRequest struct {
ID int64 `gorm:"column:id;primaryKey;comment:Snowflake 申请 id"`
FromUser int64 `gorm:"column:from_user;comment:申请人 user_id"`
ToUser int64 `gorm:"column:to_user;comment:被申请人 user_id"`
Source int `gorm:"column:source;comment:来源:1=二维码 2=邮箱 3=spark_id"`
Reason string `gorm:"column:reason;comment:申请理由"`
Remark string `gorm:"column:remark;comment:申请人对对方的备注,同意后写入自己的好友边"`
Status int `gorm:"column:status;comment:1=待处理 2=已同意 3=已拒绝"`
CreatedAt time.Time `gorm:"column:created_at;comment:首次申请时间"`
UpdatedAt time.Time `gorm:"column:updated_at;comment:最近一次申请或处理时间"`
}
func (FriendRequest) TableName() string { return "t_friend_requests" }
func (r *FriendRequest) entity() *entity.Request {
if r == nil {
return nil
}
return &entity.Request{
ID: r.ID, FromUser: r.FromUser, ToUser: r.ToUser, Source: entity.Source(r.Source),
Reason: r.Reason, Remark: r.Remark, Status: entity.RequestStatus(r.Status),
CreatedAt: r.CreatedAt, UpdatedAt: r.UpdatedAt,
}
}
func requestFromEntity(r *entity.Request) FriendRequest {
return FriendRequest{
ID: r.ID, FromUser: r.FromUser, ToUser: r.ToUser, Source: int(r.Source),
Reason: r.Reason, Remark: r.Remark, Status: int(r.Status),
CreatedAt: r.CreatedAt, UpdatedAt: r.UpdatedAt,
}
}
func (m *Repo) GetRequest(ctx context.Context, id int64) (*entity.Request, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var row FriendRequest
if err := db.Where("id = ?", id).Take(&row).Error; err != nil {
return nil, mapDBErr(err)
}
return row.entity(), nil
}
func (m *Repo) GetRequestByPair(ctx context.Context, from, to int64) (*entity.Request, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
var row FriendRequest
if err := db.Where("from_user = ? AND to_user = ?", from, to).Take(&row).Error; err != nil {
return nil, mapDBErr(err)
}
return row.entity(), nil
}
func (m *Repo) UpsertRequest(ctx context.Context, req *entity.Request) error {
if req == nil || req.FromUser <= 0 || req.ToUser <= 0 {
return errs.ErrInvalidArgument
}
db, err := m.session(ctx)
if err != nil {
return err
}
row := requestFromEntity(req)
err = db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "from_user"}, {Name: "to_user"}},
DoUpdates: clause.AssignmentColumns([]string{"source", "reason", "remark", "status", "updated_at"}),
}).Create(&row).Error
if err != nil {
return mapDBErr(err)
}
saved, err := m.GetRequestByPair(ctx, req.FromUser, req.ToUser)
if err != nil {
return err
}
*req = *saved
return nil
}
func (m *Repo) ListIncoming(ctx context.Context, toUserID int64, status entity.RequestStatus, limit int) ([]*entity.Request, error) {
db, err := m.session(ctx)
if err != nil {
return nil, err
}
limit = entity.ClampLimit(limit)
var rows []FriendRequest
q := db.Where("to_user = ?", toUserID)
if status > 0 {
q = q.Where("status = ?", status)
}
if err := q.Order("updated_at DESC").Limit(limit).Find(&rows).Error; err != nil {
return nil, mapDBErr(err)
}
out := make([]*entity.Request, 0, len(rows))
for i := range rows {
out = append(out, rows[i].entity())
}
return out, nil
}
func markRequestsAccepted(tx *gorm.DB, ids []int64, at time.Time) error {
if len(ids) == 0 {
return nil
}
return mapDBErr(tx.Model(&FriendRequest{}).Where("id IN ?", ids).Updates(map[string]any{
"status": entity.RequestAccepted,
"updated_at": at,
}).Error)
}
func rejectPairRequests(tx *gorm.DB, a, b int64, at time.Time) error {
return mapDBErr(tx.Model(&FriendRequest{}).
Where("(from_user = ? AND to_user = ?) OR (from_user = ? AND to_user = ?)", a, b, b, a).
Where("status = ?", entity.RequestPending).
Updates(map[string]any{"status": entity.RequestRejected, "updated_at": at}).Error)
}