feat(ECR-011): 昵称、首页贴士与档案 Self 唯一/合盘交叉校验
每账号仅一条 self(migration 40902);合盘只选 TA;账号昵称可改;首页穿衣/颜色/养生贴士。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/jackc/pgx/v5"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
nickgen "github.com/yuxingu/digital-psychology/apps/api/internal/nickname"
|
||||
"github.com/yuxingu/digital-psychology/apps/api/internal/repository"
|
||||
)
|
||||
|
||||
@@ -46,12 +47,12 @@ func (s *Service) Login(ctx context.Context, userID uuid.UUID, deviceKey, phone,
|
||||
}
|
||||
|
||||
// OpenLogin: any phone+password accepted; persist account; issue session.
|
||||
func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceKey, phone, password, nickname string) (*SessionResult, error) {
|
||||
func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceKey, phone, password, nickIn string) (*SessionResult, error) {
|
||||
phone = strings.TrimSpace(phone)
|
||||
if phone == "" {
|
||||
return nil, errors.New("请填写手机号")
|
||||
}
|
||||
nickname = strings.TrimSpace(nickname)
|
||||
nickIn = nickgen.Normalize(nickIn)
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -65,8 +66,12 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK
|
||||
_ = s.Repo.BindDevice(ctx, deviceKey, acc.ID)
|
||||
}
|
||||
nick := acc.Nickname
|
||||
if nickname != "" {
|
||||
nick = nickname
|
||||
if nickIn != "" {
|
||||
nick = nickIn
|
||||
_ = s.Repo.UpdateNickname(ctx, acc.ID, nick)
|
||||
} else if nick == "" {
|
||||
nick = nickgen.Random()
|
||||
_ = s.Repo.UpdateNickname(ctx, acc.ID, nick)
|
||||
}
|
||||
return s.issue(ctx, acc.ID, acc.Phone, nick)
|
||||
}
|
||||
@@ -74,15 +79,19 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// New phone: prefer upgrading anonymous device user.
|
||||
nick := nickIn
|
||||
if nick == "" {
|
||||
nick = nickgen.Random()
|
||||
}
|
||||
|
||||
cur, curErr := s.Repo.GetAccount(ctx, deviceUserID)
|
||||
uid := deviceUserID
|
||||
if curErr == nil && cur.Phone == "" {
|
||||
if err := s.Repo.RegisterOnUser(ctx, deviceUserID, phone, hashStr, nickname); err != nil {
|
||||
if err := s.Repo.RegisterOnUser(ctx, deviceUserID, phone, hashStr, nick); err != nil {
|
||||
return nil, errors.New("登录失败,请重试")
|
||||
}
|
||||
} else {
|
||||
uid, err = s.Repo.CreateUserWithPhone(ctx, phone, hashStr, nickname)
|
||||
uid, err = s.Repo.CreateUserWithPhone(ctx, phone, hashStr, nick)
|
||||
if err != nil {
|
||||
return nil, errors.New("登录失败,请重试")
|
||||
}
|
||||
@@ -90,7 +99,26 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK
|
||||
if deviceKey != "" {
|
||||
_ = s.Repo.BindDevice(ctx, deviceKey, uid)
|
||||
}
|
||||
return s.issue(ctx, uid, phone, nickname)
|
||||
return s.issue(ctx, uid, phone, nick)
|
||||
}
|
||||
|
||||
// UpdateNickname changes account display nickname (1–16 chars).
|
||||
func (s *Service) UpdateNickname(ctx context.Context, userID uuid.UUID, nick string) (*Me, error) {
|
||||
nick = nickgen.Normalize(nick)
|
||||
if nick == "" {
|
||||
return nil, errors.New("请填写昵称")
|
||||
}
|
||||
if err := s.Repo.UpdateNickname(ctx, userID, nick); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acc, err := s.Repo.GetAccount(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if acc.Phone == "" {
|
||||
return nil, errors.New("未登录")
|
||||
}
|
||||
return &Me{ID: acc.ID.String(), Phone: maskPhone(acc.Phone), Nickname: acc.Nickname}, nil
|
||||
}
|
||||
|
||||
// Logout revokes the current bearer session and unbinds the device from the account
|
||||
|
||||
Reference in New Issue
Block a user