package dao import ( "database/sql" "fmt" "time" "dd_fiber_api/internal/admin_auth" "dd_fiber_api/pkg/database" "dd_fiber_api/pkg/snowflake" "github.com/didi/gendry/builder" ) // AdminUserDAO 管理员用户数据访问对象 type AdminUserDAO struct { client *database.MySQLClient } // NewAdminUserDAO 创建管理员用户DAO func NewAdminUserDAO(client *database.MySQLClient) *AdminUserDAO { return &AdminUserDAO{ client: client, } } // GetByPhone 根据手机号码获取管理员 func (d *AdminUserDAO) GetByPhone(phone string) (*admin_auth.AdminUser, error) { query := `SELECT id, username, phone, password, nickname, avatar, status, is_super_admin, last_login_at, last_login_ip, created_at, updated_at FROM admin_users WHERE phone = ? AND status = 1` var user admin_auth.AdminUser var usernameField, phoneField, nicknameField, avatarField, lastLoginIPField sql.NullString var lastLoginAt sql.NullTime err := d.client.DB.QueryRow(query, phone).Scan( &user.ID, &usernameField, &phoneField, &user.Password, &nicknameField, &avatarField, &user.Status, &user.IsSuperAdmin, &lastLoginAt, &lastLoginIPField, &user.CreatedAt, &user.UpdatedAt, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("查询管理员失败: %v", err) } if usernameField.Valid { user.Username = usernameField.String } if phoneField.Valid { user.Phone = phoneField.String } if nicknameField.Valid { user.Nickname = nicknameField.String } if avatarField.Valid { user.Avatar = avatarField.String } if lastLoginIPField.Valid { user.LastLoginIP = lastLoginIPField.String } if lastLoginAt.Valid { user.LastLoginAt = admin_auth.NewDateTimePtr(lastLoginAt.Time) } return &user, nil } // GetByUsername 根据用户名获取管理员 func (d *AdminUserDAO) GetByUsername(username string) (*admin_auth.AdminUser, error) { query := `SELECT id, username, phone, password, nickname, avatar, status, is_super_admin, last_login_at, last_login_ip, created_at, updated_at FROM admin_users WHERE username = ? AND status = 1` var user admin_auth.AdminUser var usernameField, phoneField, nicknameField, avatarField, lastLoginIPField sql.NullString var lastLoginAt sql.NullTime err := d.client.DB.QueryRow(query, username).Scan( &user.ID, &usernameField, &phoneField, &user.Password, &nicknameField, &avatarField, &user.Status, &user.IsSuperAdmin, &lastLoginAt, &lastLoginIPField, &user.CreatedAt, &user.UpdatedAt, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("查询管理员失败: %v", err) } if usernameField.Valid { user.Username = usernameField.String } if phoneField.Valid { user.Phone = phoneField.String } if nicknameField.Valid { user.Nickname = nicknameField.String } if avatarField.Valid { user.Avatar = avatarField.String } if lastLoginIPField.Valid { user.LastLoginIP = lastLoginIPField.String } if lastLoginAt.Valid { user.LastLoginAt = admin_auth.NewDateTimePtr(lastLoginAt.Time) } return &user, nil } // GetByID 根据ID获取管理员 func (d *AdminUserDAO) GetByID(id string) (*admin_auth.AdminUser, error) { query := `SELECT id, username, phone, password, nickname, avatar, status, is_super_admin, last_login_at, last_login_ip, created_at, updated_at FROM admin_users WHERE id = ?` var user admin_auth.AdminUser var usernameField, phoneField, nicknameField, avatarField, lastLoginIPField sql.NullString var lastLoginAt sql.NullTime err := d.client.DB.QueryRow(query, id).Scan( &user.ID, &usernameField, &phoneField, &user.Password, &nicknameField, &avatarField, &user.Status, &user.IsSuperAdmin, &lastLoginAt, &lastLoginIPField, &user.CreatedAt, &user.UpdatedAt, ) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, fmt.Errorf("查询管理员失败: %v", err) } if usernameField.Valid { user.Username = usernameField.String } if phoneField.Valid { user.Phone = phoneField.String } if nicknameField.Valid { user.Nickname = nicknameField.String } if avatarField.Valid { user.Avatar = avatarField.String } if lastLoginIPField.Valid { user.LastLoginIP = lastLoginIPField.String } if lastLoginAt.Valid { user.LastLoginAt = admin_auth.NewDateTimePtr(lastLoginAt.Time) } return &user, nil } // UpdateLastLogin 更新最后登录时间和IP func (d *AdminUserDAO) UpdateLastLogin(id, ip string) error { query := `UPDATE admin_users SET last_login_at = ?, last_login_ip = ? WHERE id = ?` _, err := d.client.DB.Exec(query, time.Now(), ip, id) if err != nil { return fmt.Errorf("更新最后登录信息失败: %v", err) } return nil } // GetUserRoles 获取用户的角色代码列表 func (d *AdminUserDAO) GetUserRoles(userID string) ([]string, error) { query := `SELECT r.code FROM admin_roles r INNER JOIN admin_user_roles ur ON r.id = ur.role_id WHERE ur.user_id = ? AND r.status = 1` rows, err := d.client.DB.Query(query, userID) if err != nil { return nil, fmt.Errorf("查询用户角色失败: %v", err) } defer rows.Close() var roles []string for rows.Next() { var code string if err := rows.Scan(&code); err != nil { return nil, fmt.Errorf("扫描角色代码失败: %v", err) } roles = append(roles, code) } return roles, nil } // GetUserPermissions 获取用户的权限代码列表(包括角色权限) func (d *AdminUserDAO) GetUserPermissions(userID string) ([]string, error) { // 如果是超级管理员,返回所有权限(这里简化处理,实际应该从权限表查询) query := `SELECT DISTINCT p.code FROM admin_permissions p INNER JOIN admin_role_permissions rp ON p.id = rp.permission_id INNER JOIN admin_user_roles ur ON rp.role_id = ur.role_id WHERE ur.user_id = ?` rows, err := d.client.DB.Query(query, userID) if err != nil { return nil, fmt.Errorf("查询用户权限失败: %v", err) } defer rows.Close() var permissions []string for rows.Next() { var code string if err := rows.Scan(&code); err != nil { return nil, fmt.Errorf("扫描权限代码失败: %v", err) } permissions = append(permissions, code) } return permissions, nil } // GetUserRoleIDs 获取用户的角色ID列表 func (d *AdminUserDAO) GetUserRoleIDs(userID string) ([]string, error) { query := `SELECT role_id FROM admin_user_roles WHERE user_id = ?` rows, err := d.client.DB.Query(query, userID) if err != nil { return nil, fmt.Errorf("查询用户角色失败: %v", err) } defer rows.Close() var roleIDs []string for rows.Next() { var roleID string if err := rows.Scan(&roleID); err != nil { continue } roleIDs = append(roleIDs, roleID) } return roleIDs, nil } // SetUserRoles 设置用户的角色 func (d *AdminUserDAO) SetUserRoles(userID string, roleIDs []string) error { // 先删除原有角色 deleteQuery := `DELETE FROM admin_user_roles WHERE user_id = ?` _, err := d.client.DB.Exec(deleteQuery, userID) if err != nil { return fmt.Errorf("删除用户角色失败: %v", err) } // 插入新角色 if len(roleIDs) > 0 { table := "admin_user_roles" data := make([]map[string]any, 0, len(roleIDs)) for _, roleID := range roleIDs { // 生成关联ID id := snowflake.GenerateID() data = append(data, map[string]any{ "id": id, "user_id": userID, "role_id": roleID, }) } cond, vals, err := builder.BuildInsert(table, data) if err != nil { return fmt.Errorf("构建插入语句失败: %v", err) } _, err = d.client.DB.Exec(cond, vals...) if err != nil { return fmt.Errorf("设置用户角色失败: %v", err) } } return nil } // List 列出管理员用户(支持分页和搜索) func (d *AdminUserDAO) List(keyword string, page, pageSize int) ([]*admin_auth.AdminUser, int, error) { table := "admin_users" // 构建查询条件 where := map[string]any{} if keyword != "" { where["_or"] = []map[string]any{ {"username like": "%" + keyword + "%"}, {"phone like": "%" + keyword + "%"}, {"nickname like": "%" + keyword + "%"}, } } // 查询总数 countFields := []string{"COUNT(*) as total"} countCond, countVals, err := builder.BuildSelect(table, where, countFields) if err != nil { return nil, 0, fmt.Errorf("构建统计查询失败: %v", err) } var total int err = d.client.DB.QueryRow(countCond, countVals...).Scan(&total) if err != nil { return nil, 0, fmt.Errorf("查询管理员总数失败: %v", err) } // 查询数据 selectFields := []string{"id", "username", "phone", "nickname", "avatar", "status", "is_super_admin", "last_login_at", "last_login_ip", "created_at", "updated_at"} cond, vals, err := builder.BuildSelect(table, where, selectFields) if err != nil { return nil, 0, fmt.Errorf("构建查询失败: %v", err) } // 添加排序和分页 offset := (page - 1) * pageSize cond += " ORDER BY created_at DESC LIMIT ? OFFSET ?" vals = append(vals, pageSize, offset) rows, err := d.client.DB.Query(cond, vals...) if err != nil { return nil, 0, fmt.Errorf("查询管理员列表失败: %v", err) } defer rows.Close() var users []*admin_auth.AdminUser for rows.Next() { var user admin_auth.AdminUser var usernameField, phoneField, nicknameField, avatarField, lastLoginIPField sql.NullString var lastLoginAt sql.NullTime err := rows.Scan( &user.ID, &usernameField, &phoneField, &nicknameField, &avatarField, &user.Status, &user.IsSuperAdmin, &lastLoginAt, &lastLoginIPField, &user.CreatedAt, &user.UpdatedAt, ) if err != nil { continue } if usernameField.Valid { user.Username = usernameField.String } if phoneField.Valid { user.Phone = phoneField.String } if nicknameField.Valid { user.Nickname = nicknameField.String } if avatarField.Valid { user.Avatar = avatarField.String } if lastLoginIPField.Valid { user.LastLoginIP = lastLoginIPField.String } if lastLoginAt.Valid { user.LastLoginAt = admin_auth.NewDateTimePtr(lastLoginAt.Time) } users = append(users, &user) } return users, total, nil } // Create 创建管理员用户 func (d *AdminUserDAO) Create(user *admin_auth.AdminUser) error { table := "admin_users" data := []map[string]any{ { "id": user.ID, "username": user.Username, "phone": user.Phone, "password": user.Password, "nickname": user.Nickname, "avatar": user.Avatar, "status": user.Status, "is_super_admin": user.IsSuperAdmin, }, } cond, vals, err := builder.BuildInsert(table, data) if err != nil { return fmt.Errorf("构建插入语句失败: %v", err) } _, err = d.client.DB.Exec(cond, vals...) if err != nil { return fmt.Errorf("创建管理员失败: %v", err) } return nil } // Update 更新管理员用户 func (d *AdminUserDAO) Update(user *admin_auth.AdminUser) error { table := "admin_users" where := map[string]any{ "id": user.ID, } data := map[string]any{ "username": user.Username, "phone": user.Phone, "nickname": user.Nickname, "avatar": user.Avatar, "status": user.Status, "is_super_admin": user.IsSuperAdmin, } // 如果密码不为空,则更新密码 if user.Password != "" { data["password"] = user.Password } cond, vals, err := builder.BuildUpdate(table, where, data) if err != nil { return fmt.Errorf("构建更新语句失败: %v", err) } _, err = d.client.DB.Exec(cond, vals...) if err != nil { return fmt.Errorf("更新管理员失败: %v", err) } return nil } // Delete 删除管理员用户(软删除,更新状态为禁用) func (d *AdminUserDAO) Delete(id string) error { where := map[string]any{ "id": id, } data := map[string]any{ "status": 0, // 禁用状态 } cond, vals, err := builder.BuildUpdate("admin_users", where, data) if err != nil { return fmt.Errorf("构建更新语句失败: %v", err) } _, err = d.client.DB.Exec(cond, vals...) if err != nil { return fmt.Errorf("删除管理员失败: %v", err) } return nil }