duidui_fiber/internal/admin_auth/dao/admin_user_dao.go
2026-03-27 10:34:03 +08:00

485 lines
12 KiB
Go

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
}