spark-server/internal/module/user/logic/avatar.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

62 lines
1.4 KiB
Go

package logic
import (
"context"
"strings"
"time"
uploadentity "spark-server/internal/module/upload/entity"
"spark-server/internal/module/user/entity"
)
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 || s.ids == nil || u == nil || u.ID <= 0 {
return ""
}
raw, err := entity.LetterAvatarPNG(u.Nickname)
if err != nil || len(raw) == 0 {
return ""
}
objectID, err := s.ids.NextID()
if err != nil {
return ""
}
key := uploadentity.BuildObjectKey(uploadentity.PurposeAvatar, u.ID, objectID, time.Now().Format("20060102"), "png")
if err := s.objects.Put(ctx, key, raw, defaultAvatarMIME); err != nil {
return ""
}
return key
}