package logic import ( "context" "errors" "strings" "time" "spark-server/internal/module/friend/entity" "spark-server/internal/pkg/errs" "spark-server/internal/pkg/i18n" "spark-server/internal/pkg/reqctx" "spark-server/internal/pkg/validate" ) // AcceptInput creates a bidirectional friendship from a pending incoming request. type AcceptInput struct { RequestID int64 `json:"request_id" validate:"required,gt=0" label:"field.request_id" errmsg:"required:validate.friend.request_required"` Remark string `json:"remark" validate:"omitempty,max=64" label:"field.remark" errmsg:"max:validate.friend.remark_invalid"` } type AcceptResult struct { UID int64 `json:"uid"` } func (s *Service) Accept(ctx context.Context, userID int64, in AcceptInput) (*AcceptResult, error) { if !s.ready() || userID <= 0 { return nil, errs.ErrUnauthorized } if err := validate.StructLang(reqctx.Lang(ctx), in); err != nil { return nil, err } req, err := s.repo.GetRequest(ctx, in.RequestID) if err != nil { return nil, err } lang := reqctx.Lang(ctx) if req.ToUser != userID || req.Status != entity.RequestPending { return nil, errs.ErrForbidden.WithMsg(i18n.T(lang, i18n.KeyFriendRequestInvalid, nil)) } if err := s.canApply(ctx, userID, req.FromUser); err != nil { if !errors.Is(err, errs.ErrDuplicate) { return nil, err } } if err := s.becomeFriends(ctx, req, userID, strings.TrimSpace(in.Remark)); err != nil { return nil, err } return &AcceptResult{UID: req.FromUser}, nil } func (s *Service) becomeFriends(ctx context.Context, req *entity.Request, accepter int64, accepterRemark string) error { now := time.Now() fromRemark := strings.TrimSpace(req.Remark) edges := []*entity.Relation{ entity.NewFriendEdge(req.FromUser, req.ToUser, fromRemark, req.Source, now), entity.NewFriendEdge(accepter, req.FromUser, accepterRemark, req.Source, now), } ids := []int64{req.ID} if reverse, err := s.repo.GetRequestByPair(ctx, accepter, req.FromUser); err == nil && reverse.ID != req.ID { ids = append(ids, reverse.ID) } if err := s.repo.AcceptFriend(ctx, entity.AcceptParams{Edges: edges, Requests: ids}); err != nil { return err } if s.greeter != nil { _ = s.greeter.BecameFriends(ctx, req.FromUser, req.ToUser) } return nil }