package logic import ( "context" "strings" "time" uploadentity "spark-server/internal/module/upload/entity" "spark-server/internal/module/user/entity" "spark-server/internal/pkg/reqctx" ) const defaultAvatarMIME = "image/png" func (s *Service) ensureDefaultAvatar(ctx context.Context, u *entity.User) { if u == nil || strings.TrimSpace(u.Avatar) != "" { return } s.stampDefaultAvatar(ctx, u) } func (s *Service) stampDefaultAvatar(ctx context.Context, u *entity.User) { if u == nil || u.ID <= 0 { return } fallback := entity.LetterAvatarDataURI(u.Nickname) avatar := fallback if key := s.putLetterPNG(ctx, u); key != "" { avatar = key } prev := u.Avatar u.Avatar = avatar if s.repo == nil || prev == avatar { return } if err := s.repo.UpdateProfile(ctx, u); err == nil { return } u.Avatar = fallback if prev != fallback { _ = s.repo.UpdateProfile(ctx, u) } } func (s *Service) putLetterPNG(ctx context.Context, u *entity.User) string { if s == nil || s.objects == nil || u == nil || u.ID <= 0 { return "" } raw, err := entity.LetterAvatarPNG(u.Nickname) if err != nil || len(raw) == 0 { return "" } key := uploadentity.BuildObjectKey(uploadentity.PurposeAvatar, u.ID, reqctx.NewObjectName(), time.Now().UTC().Format("20060102"), "png") if err := s.objects.Put(ctx, key, raw, defaultAvatarMIME); err != nil { return "" } return key }