用户管理指南
本文档介绍如何管理 Vibany 平台的用户,包括用户查看、权限管理和黑名单功能。
用户系统概述
Vibany 使用 Clerk 处理认证,用户数据自动同步到本地 PostgreSQL 数据库。
用户数据结构
// lib/db/schema.ts
users {
clerkId: string; // Clerk 用户 ID(主键)
email: string; // 邮箱
username: string; // 用户名
avatarUrl: string; // 头像 URL
extra: object; // 扩展字段
createdAt: Date; // 创建时间
updatedAt: Date; // 更新时间
}
extra 字段包含:
isBlocklisted: 是否在黑名单blocklistedAt: 加入黑名单时间isSuspended: 是否被暂停
查看用户列表
通过 Admin 后台
- 访问
/admin/users - 查看所有用户列表
- 支持搜索(按邮箱、用户名)
- 支持分页浏览
通过数据库查询
-- 查看所有用户
SELECT * FROM users ORDER BY created_at DESC LIMIT 20;
-- 查看特定用户
SELECT * FROM users WHERE email = 'user@example.com';
-- 查看黑名单用户
SELECT * FROM users
WHERE extra->>'isBlocklisted' = 'true';
管理员权限
设置管理员
在 .env.local 中配置:
# 使用 Clerk User ID
ADMIN_USER_IDS=user_abc123,user_def456
# 或使用邮箱
ADMIN_USER_EMAILS=admin@yourdomain.com,operator@yourdomain.com
验证管理员身份
代码中检查:
const adminIds = process.env.ADMIN_USER_IDS?.split(',') || [];
const adminEmails = process.env.ADMIN_USER_EMAILS?.split(',') || [];
const isAdmin = adminIds.includes(userId) || adminEmails.includes(email);
黑名单管理
什么是黑名单
黑名单用于阻止特定用户或邮箱注册/登录。
黑名单类型
| 类型 | 匹配方式 | 示例 |
|---|---|---|
| 完整邮箱匹配 | spammer@example.com | |
| domain | 域名匹配 | example.com |
| ip | IP 地址匹配 | 192.168.1.1 |
添加黑名单
通过 Admin 后台:
- 访问
/admin/blocklists - 点击 "添加黑名单"
- 选择类型(email/domain/ip)
- 输入匹配模式
- 添加描述(可选)
通过数据库:
INSERT INTO blocklists (id, type, pattern, enabled, description, created_at, updated_at)
VALUES (
gen_random_uuid(),
'email',
'spammer@example.com',
true,
'垃圾邮件发送者',
NOW(),
NOW()
);
黑名单效果
- 新用户注册:匹配黑名单的邮箱无法注册
- 已有用户:匹配黑名单的用户会被限制功能
- 积分发放:黑名单用户获得较少初始积分
用户钱包管理
查看用户积分
SELECT
u.email,
u.username,
w.permanent_points
FROM users u
JOIN wallets w ON u.clerk_id = w.user_id
WHERE u.email = 'user@example.com';
手动调整积分
通过 Admin 后台:
- 找到用户
- 点击 "调整积分"
- 输入积分数量(正数为增加,负数为扣除)
- 添加调整原因
通过 API:
// 增加积分
await rechargeUserPoints({
userId: 'user_xxx',
points: 100,
description: '手动补偿',
metadata: { adminId: 'admin_xxx', reason: '系统故障补偿' }
});
// 扣除积分
await deductPoints({
userId: 'user_xxx',
points: 50,
description: '违规处理'
});
用户邀请管理
查看邀请码
SELECT
i.invite_code,
u.username as referrer,
i.invite_type,
i.ref_ratio,
i.max_uses,
i.expires_at
FROM invitations i
JOIN users u ON i.referrer_id = u.clerk_id
ORDER BY i.created_at DESC;
禁用邀请码
UPDATE invitations
SET extra = jsonb_set(extra, '{disabled}', 'true')
WHERE invite_code = 'ABC123';
用户数据分析
统计用户增长
-- 每日新增用户
SELECT
DATE(created_at) as date,
COUNT(*) as new_users
FROM users
GROUP BY DATE(created_at)
ORDER BY date DESC;
-- 总用户数
SELECT COUNT(*) FROM users;
-- 活跃用户(最近 7 天有操作)
SELECT COUNT(DISTINCT user_id)
FROM histories
WHERE created_at > NOW() - INTERVAL '7 days';
用户画像
-- 积分分布
SELECT
CASE
WHEN permanent_points < 100 THEN '0-100'
WHEN permanent_points < 500 THEN '100-500'
WHEN permanent_points < 1000 THEN '500-1000'
ELSE '1000+'
END as points_range,
COUNT(*) as user_count
FROM wallets
GROUP BY 1;
常见问题
用户无法登录
检查清单:
- 用户邮箱是否在黑名单
- Clerk 配置是否正确
- 用户账号是否被暂停
管理员权限不生效
解决方案:
- 检查
.env.local中的ADMIN_USER_IDS或ADMIN_USER_EMAILS - 确认使用正确的 User ID(不是邮箱)
- 重启应用以加载新配置
用户数据不同步
原因:
- Clerk webhook 未触发
- 数据库连接问题
解决方案:
- 检查数据库连接
- 手动触发同步
- 检查 Clerk 日志