spark-server/internal/module/group/logic/transfer.go
zhr ae9a71034d feat: implement Spark IM V3 modular monolith
Add HTTP /v1 MVC, TCP send path, groups with server-side member-avatar collage, object-storage upload, and friends/favorites around the architecture-v3 layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 19:52:11 +08:00

67 lines
1.8 KiB
Go

package logic
import (
"context"
"spark-server/internal/module/group/entity"
"spark-server/internal/pkg/errs"
"spark-server/internal/pkg/reqctx"
"spark-server/internal/pkg/validate"
)
type TransferInput struct {
UID int64 `json:"uid" validate:"required,gt=0" label:"field.uid" errmsg:"required:validate.group.uid_required;gt:validate.group.uid_required"`
}
func (s *Service) Transfer(ctx context.Context, ownerID, groupID int64, in *TransferInput) (*View, error) {
if !s.ready() || ownerID <= 0 {
return nil, errs.ErrUnauthorized
}
if in == nil {
return nil, errs.ErrInvalidArgument
}
if err := validate.StructLang(reqctx.Lang(ctx), in); err != nil {
return nil, err
}
g, err := s.loadActive(ctx, groupID)
if err != nil {
return nil, err
}
if err := s.requireOwner(ctx, g, ownerID); err != nil {
return nil, err
}
if in.UID == ownerID {
return nil, errs.ErrInvalidArgument
}
if _, err := s.requireMember(ctx, groupID, in.UID); err != nil {
return nil, err
}
if err := s.repo.TransferOwner(ctx, groupID, ownerID, in.UID); err != nil {
return nil, err
}
g.OwnerID = in.UID
s.invalidateMembers(g.ConversationID)
_ = s.notice(ctx, g, ownerID, entity.SystemKindTransfer, []int64{in.UID})
return viewOf(g, entity.RoleMember), nil
}
func (s *Service) Dissolve(ctx context.Context, ownerID, groupID int64) error {
if !s.ready() || ownerID <= 0 {
return errs.ErrUnauthorized
}
g, err := s.loadActive(ctx, groupID)
if err != nil {
return err
}
if err := s.requireOwner(ctx, g, ownerID); err != nil {
return err
}
ids, _ := s.repo.ListMemberIDs(ctx, groupID)
if err := s.repo.Dissolve(ctx, groupID); err != nil {
return err
}
s.invalidateMembers(g.ConversationID)
_ = s.notice(ctx, g, ownerID, entity.SystemKindDissolve, ids)
return nil
}