web
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -63,6 +64,102 @@ func (s *UserService) WeChatLogin(code string) (*model.User, string, error) {
|
||||
return user, token, nil
|
||||
}
|
||||
|
||||
// EmailLogin 邮箱登录
|
||||
func (s *UserService) EmailLogin(email, password, clientIP, userAgent string) (*model.User, string, error) {
|
||||
// 查找用户
|
||||
user, err := s.userRepo.GetByEmail(email)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, "", errors.New("邮箱或密码错误")
|
||||
}
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
|
||||
return nil, "", errors.New("邮箱或密码错误")
|
||||
}
|
||||
|
||||
// 检查用户状态
|
||||
if user.Status == 0 {
|
||||
return nil, "", errors.New("用户已被禁用")
|
||||
}
|
||||
|
||||
// 生成JWT token (7天有效期)
|
||||
tokenExpiry := 7 * 24 * 3600
|
||||
token, err := jwt.GenerateToken(user.ID, "user", tokenExpiry)
|
||||
if err != nil {
|
||||
return nil, "", errors.New("生成token失败")
|
||||
}
|
||||
|
||||
// 记录登录日志
|
||||
s.logUserLogin(user.ID, "email", true, "", clientIP, userAgent)
|
||||
|
||||
return user, token, nil
|
||||
}
|
||||
|
||||
// EmailRegister 邮箱注册
|
||||
func (s *UserService) EmailRegister(email, password, nickname string) (*model.User, error) {
|
||||
// 检查邮箱是否已注册
|
||||
_, err := s.userRepo.GetByEmail(email)
|
||||
if err == nil {
|
||||
// 找到了用户,说明邮箱已注册
|
||||
return nil, errors.New("该邮箱已被注册")
|
||||
}
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// 其他数据库错误
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 加密密码
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, errors.New("密码加密失败")
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
// 为邮箱用户生成唯一的 OpenID(使用 email: 前缀避免与微信 OpenID 冲突)
|
||||
user := &model.User{
|
||||
OpenID: "email:" + email, // 使用邮箱作为 OpenID,避免唯一索引冲突
|
||||
Email: email,
|
||||
Password: string(hashedPassword),
|
||||
Nickname: nickname,
|
||||
Status: 1,
|
||||
}
|
||||
|
||||
if err := s.userRepo.Create(user); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// logUserLogin 记录用户登录日志
|
||||
func (s *UserService) logUserLogin(userID uint, loginType string, success bool, errorMsg, ip, userAgent string) {
|
||||
status := 1
|
||||
if !success {
|
||||
status = 0
|
||||
}
|
||||
|
||||
remark := loginType + " 登录"
|
||||
if errorMsg != "" {
|
||||
remark = errorMsg
|
||||
}
|
||||
|
||||
log := &model.UserLoginLog{
|
||||
UserID: userID,
|
||||
LoginIP: ip,
|
||||
UserAgent: userAgent,
|
||||
LoginTime: time.Now(),
|
||||
Status: status,
|
||||
Remark: remark,
|
||||
}
|
||||
|
||||
if err := s.db.Create(log).Error; err != nil {
|
||||
fmt.Printf("记录登录日志失败: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateUser 创建用户
|
||||
func (s *UserService) CreateUser(user *model.User) error {
|
||||
// 检查用户是否已存在
|
||||
|
||||
Reference in New Issue
Block a user