added ability to change user info

This commit is contained in:
onysd 2026-08-05 21:19:50 +03:00
parent cddd341bb2
commit 40d49d5e97
22 changed files with 799 additions and 26 deletions

View file

@ -140,6 +140,28 @@ func (s *Service) GetDocument(ctx context.Context, id int64) (domain.Document, b
return s.media.GetDocument(ctx, id)
}
// ValidateAvatarUpload is a pure check (decodes only the image header) so a
// dry-run preview can validate bytes before SetAccountAvatar/CreateAvatarFromBytes
// actually renders and stores the avatar's s/a/c size set.
func (s *Service) ValidateAvatarUpload(data []byte) bool {
if len(data) == 0 {
return false
}
cfg, _, err := image.DecodeConfig(bytes.NewReader(data))
return err == nil && cfg.Width > 0 && cfg.Height > 0
}
// CreateAvatarFromBytes stores already-in-hand image bytes as an avatar Photo
// ('s'/'a'/'c' sizes), for callers that skip the chunked upload.saveFilePart
// transfer regular clients use (e.g. the admin console, which already has the
// full file from a browser upload).
func (s *Service) CreateAvatarFromBytes(ctx context.Context, data []byte, ownerUserID int64) (domain.Photo, error) {
if len(data) == 0 {
return domain.Photo{}, domain.ErrPhotoInvalid
}
return s.createAvatarPhoto(ctx, data, ownerUserID)
}
// CreateAvatarFromUpload 把已上传文件组装成头像 Photo('s'/'a'/'c' 尺寸,'a'/'c' 匹配
// InputPeerPhotoFileLocation big/small 与 channelFull 下载路径),不绑定 profile_photos。用于频道 editPhoto。
func (s *Service) CreateAvatarFromUpload(ctx context.Context, file domain.UploadedFileRef) (domain.Photo, error) {

View file

@ -253,6 +253,35 @@ func (s *Service) UpdateUsername(ctx context.Context, userID int64, username str
return s.projectOne(ctx, self.ID, u)
}
// SetPhone force-sets a user's phone number (admin use -- no code
// verification, unlike the user-facing verified change-phone flow in
// internal/app/account). Pre-checks availability via ByPhone before writing,
// on top of the store's own unique-constraint backstop.
func (s *Service) SetPhone(ctx context.Context, userID int64, phone string) (domain.User, error) {
self, err := s.loadSelf(ctx, userID)
if err != nil {
return domain.User{}, err
}
phone = domain.NormalizePhone(strings.TrimSpace(phone))
if !domain.ValidPhone(phone) {
return domain.User{}, domain.ErrPhoneNumberInvalid
}
if phone == self.Phone {
return s.projectOne(ctx, self.ID, self)
}
if existing, found, err := s.users.ByPhone(ctx, phone); err != nil {
return domain.User{}, err
} else if found && existing.ID != self.ID {
return domain.User{}, domain.ErrPhoneNumberOccupied
}
u, err := s.users.UpdatePhone(ctx, self.ID, phone)
if err != nil {
return domain.User{}, err
}
s.refreshCachedUsers(ctx, u)
return s.projectOne(ctx, self.ID, u)
}
// UpdateProfile 修改当前用户的基础资料。未设置的字段保持原值。
func (s *Service) UpdateProfile(ctx context.Context, userID int64, update domain.UserProfileUpdate) (domain.User, error) {
self, err := s.loadSelf(ctx, userID)