package logic import ( "context" "strings" "spark-server/internal/pkg/errs" "spark-server/internal/pkg/reqctx" "spark-server/internal/pkg/validate" ) type UpdateInput struct { Name *string `json:"name" validate:"omitempty,min=1,max=32" label:"field.group_name" errmsg:"min:validate.group.name_invalid;max:validate.group.name_invalid"` Avatar *string `json:"avatar" validate:"omitempty,max=512" label:"field.avatar"` Announcement *string `json:"announcement" validate:"omitempty,max=1024" label:"field.group_announcement" errmsg:"max:validate.group.announcement_invalid"` MutedAll *bool `json:"muted_all"` } func (s *Service) Update(ctx context.Context, userID, groupID int64, in *UpdateInput) (*View, error) { if !s.ready() || userID <= 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 } if in.Name == nil && in.Avatar == nil && in.Announcement == nil && in.MutedAll == nil { return nil, errs.ErrInvalidArgument } g, err := s.loadActive(ctx, groupID) if err != nil { return nil, err } if _, err := s.requireManage(ctx, groupID, userID); err != nil { return nil, err } if in.Name != nil { g.Name = strings.TrimSpace(*in.Name) } if in.Avatar != nil { av := strings.TrimSpace(*in.Avatar) if !validGroupAvatar(groupID, av) { return nil, errs.ErrInvalidArgument } g.Avatar = av } if in.Announcement != nil { ann, err := s.gateText(ctx, userID, strings.TrimSpace(*in.Announcement)) if err != nil { return nil, err } g.Announcement = ann } if in.MutedAll != nil { g.MutedAll = *in.MutedAll } g.UpdatedAtMS = nowMS() if err := s.repo.UpdateProfile(ctx, g); err != nil { return nil, err } mem, err := s.requireMember(ctx, groupID, userID) if err != nil { return nil, err } return viewOf(g, mem), nil }