485 lines
12 KiB
Go
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
|
|
}
|