spark-server/internal/module/group/logic/update.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

61 lines
1.5 KiB
Go

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"`
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.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.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.Role), nil
}