96 lines
2.3 KiB
Go
96 lines
2.3 KiB
Go
package services
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/inchstep/server/internal/models"
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type UserService struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewUserService(db *gorm.DB) *UserService {
|
|
return &UserService{db: db}
|
|
}
|
|
|
|
func generateID() string {
|
|
b := make([]byte, 16)
|
|
rand.Read(b)
|
|
return hex.EncodeToString(b)
|
|
}
|
|
|
|
func (s *UserService) RegisterByPhone(phone string) (*models.User, error) {
|
|
var existing models.User
|
|
if err := s.db.Where("phone = ?", phone).First(&existing).Error; err == nil {
|
|
return nil, errors.New("该手机号已注册")
|
|
}
|
|
user := &models.User{
|
|
ID: generateID(),
|
|
Phone: &phone,
|
|
Privacy: models.PrivacyFriendsOnly,
|
|
Points: 0,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
if err := s.db.Create(user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
func (s *UserService) GetByPhone(phone string) (*models.User, error) {
|
|
var user models.User
|
|
if err := s.db.Where("phone = ?", phone).First(&user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &user, nil
|
|
}
|
|
|
|
func (s *UserService) GetByID(id string) (*models.User, error) {
|
|
var user models.User
|
|
if err := s.db.First(&user, "id = ?", id).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &user, nil
|
|
}
|
|
|
|
func (s *UserService) UpdateProfile(id string, updates map[string]interface{}) (*models.User, error) {
|
|
allowed := map[string]bool{"nickname": true, "avatar": true, "bio": true, "motto": true, "privacy": true}
|
|
filtered := make(map[string]interface{})
|
|
for k, v := range updates {
|
|
if allowed[k] {
|
|
filtered[k] = v
|
|
}
|
|
}
|
|
if err := s.db.Model(&models.User{}).Where("id = ?", id).Updates(filtered).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return s.GetByID(id)
|
|
}
|
|
|
|
func (s *UserService) DeleteAccount(id string) error {
|
|
return s.db.Model(&models.User{}).Where("id = ?", id).Updates(map[string]interface{}{
|
|
"phone": nil,
|
|
"nickname": nil,
|
|
"avatar": nil,
|
|
"bio": nil,
|
|
"motto": nil,
|
|
"privacy": models.PrivacyPrivate,
|
|
}).Error
|
|
}
|
|
|
|
func HashPassword(password string) (string, error) {
|
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 12)
|
|
return string(bytes), err
|
|
}
|
|
|
|
func CheckPassword(hash, password string) bool {
|
|
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
|
|
}
|