Files
EchoChat/backend/go-service/app/auth/dao/user_dao.go
bujinyuan 8a6576a2f7 feat(auth): 用户/角色模型与数据访问层
- constants: 用户状态、性别、角色代码常量定义
- model: User/Role/UserRole GORM 模型
- dao: UserDAO (CRUD + 账号查询) + RoleDAO (角色分配/查询/检查)
- provider: Auth 模块 Wire Provider Set

Made-with: Cursor
2026-02-28 10:42:34 +08:00

132 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package dao 提供 auth 模块的数据库访问操作
package dao
import (
"context"
"github.com/echochat/backend/app/auth/model"
"github.com/echochat/backend/pkg/logs"
"go.uber.org/zap"
"gorm.io/gorm"
)
// UserDAO 用户数据访问对象
type UserDAO struct {
db *gorm.DB
}
// NewUserDAO 创建 UserDAO 实例
func NewUserDAO(db *gorm.DB) *UserDAO {
return &UserDAO{db: db}
}
// Create 创建用户
// 插入一条新用户记录username 和 email 有唯一索引
func (d *UserDAO) Create(ctx context.Context, user *model.User) error {
funcName := "dao.user_dao.Create"
logs.Info(ctx, funcName, "创建用户",
zap.String("username", user.Username),
zap.String("email", logs.MaskEmail(user.Email)),
)
var err error
defer func() {
if err != nil {
logs.Error(ctx, funcName, "创建用户失败", zap.Error(err))
} else {
logs.Info(ctx, funcName, "创建用户成功", zap.Int64("user_id", user.ID))
}
}()
err = d.db.WithContext(ctx).Create(user).Error
return err
}
// FindByEmail 按邮箱查询用户
// 精确匹配邮箱地址,利用 email 唯一索引
func (d *UserDAO) FindByEmail(ctx context.Context, email string) (*model.User, error) {
funcName := "dao.user_dao.FindByEmail"
logs.Debug(ctx, funcName, "按邮箱查询用户", zap.String("email", logs.MaskEmail(email)))
var user model.User
err := d.db.WithContext(ctx).Where("email = ?", email).First(&user).Error
if err != nil {
return nil, err
}
return &user, nil
}
// FindByUsername 按用户名查询用户
// 精确匹配用户名,利用 username 唯一索引
func (d *UserDAO) FindByUsername(ctx context.Context, username string) (*model.User, error) {
funcName := "dao.user_dao.FindByUsername"
logs.Debug(ctx, funcName, "按用户名查询用户", zap.String("username", username))
var user model.User
err := d.db.WithContext(ctx).Where("username = ?", username).First(&user).Error
if err != nil {
return nil, err
}
return &user, nil
}
// FindByID 按 ID 查询用户
func (d *UserDAO) FindByID(ctx context.Context, id int64) (*model.User, error) {
funcName := "dao.user_dao.FindByID"
logs.Debug(ctx, funcName, "按ID查询用户", zap.Int64("id", id))
var user model.User
err := d.db.WithContext(ctx).First(&user, id).Error
if err != nil {
return nil, err
}
return &user, nil
}
// Update 更新用户信息
// 仅更新非零值字段
func (d *UserDAO) Update(ctx context.Context, user *model.User) error {
funcName := "dao.user_dao.Update"
logs.Info(ctx, funcName, "更新用户信息", zap.Int64("user_id", user.ID))
var err error
defer func() {
if err != nil {
logs.Error(ctx, funcName, "更新用户失败", zap.Int64("user_id", user.ID), zap.Error(err))
}
}()
err = d.db.WithContext(ctx).Save(user).Error
return err
}
// UpdateLastLogin 更新最后登录信息
func (d *UserDAO) UpdateLastLogin(ctx context.Context, userID int64, ip string) error {
funcName := "dao.user_dao.UpdateLastLogin"
logs.Debug(ctx, funcName, "更新登录信息", zap.Int64("user_id", userID))
err := d.db.WithContext(ctx).
Model(&model.User{}).
Where("id = ?", userID).
Updates(map[string]interface{}{
"last_login_at": gorm.Expr("NOW()"),
"last_login_ip": ip,
}).Error
return err
}
// FindByAccount 按用户名或邮箱查找用户(登录时使用)
func (d *UserDAO) FindByAccount(ctx context.Context, account string) (*model.User, error) {
funcName := "dao.user_dao.FindByAccount"
logs.Debug(ctx, funcName, "按账号查询用户", zap.String("account", account))
var user model.User
err := d.db.WithContext(ctx).
Where("username = ? OR email = ?", account, account).
First(&user).Error
if err != nil {
return nil, err
}
return &user, nil
}