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 }