實作管理者用戶管理、邀請註冊功能

This commit is contained in:
2025-09-09 15:15:26 +08:00
parent 32b19e9a0f
commit 46bd9db2e3
11 changed files with 1297 additions and 214 deletions

View File

@@ -3,6 +3,73 @@ import { UserService } from '@/lib/services/database-service'
const userService = new UserService()
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const { email, role } = body
if (!email || !role) {
return NextResponse.json(
{ success: false, error: '請提供電子郵件和角色' },
{ status: 400 }
)
}
// 驗證電子郵件格式
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(email)) {
return NextResponse.json(
{ success: false, error: '請輸入有效的電子郵件格式' },
{ status: 400 }
)
}
// 驗證角色
const validRoles = ['user', 'developer', 'admin']
if (!validRoles.includes(role)) {
return NextResponse.json(
{ success: false, error: '無效的角色值' },
{ status: 400 }
)
}
// 檢查電子郵件是否已存在
const existingUser = await userService.findByEmail(email)
if (existingUser) {
return NextResponse.json(
{ success: false, error: '此電子郵件已被使用' },
{ status: 400 }
)
}
// 創建邀請用戶
const result = await userService.createInvitedUser(email, role)
if (result.success) {
return NextResponse.json({
success: true,
message: '邀請用戶創建成功',
data: {
user: result.user,
invitationLink: result.invitationLink
}
})
} else {
return NextResponse.json(
{ success: false, error: result.error },
{ status: 400 }
)
}
} catch (error) {
console.error('創建邀請用戶錯誤:', error)
return NextResponse.json(
{ success: false, error: '創建邀請用戶時發生錯誤' },
{ status: 500 }
)
}
}
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url)
@@ -14,7 +81,7 @@ export async function GET(request: NextRequest) {
const status = searchParams.get('status') || ''
// 構建查詢條件
let whereConditions = ['is_active = TRUE']
let whereConditions = ['status IN ("active", "inactive", "invited")']
let params: any[] = []
if (search) {
@@ -34,9 +101,11 @@ export async function GET(request: NextRequest) {
if (status && status !== 'all') {
if (status === 'active') {
whereConditions.push('last_login IS NOT NULL AND last_login >= DATE_SUB(NOW(), INTERVAL 30 DAY)')
whereConditions.push('status = "active"')
} else if (status === 'inactive') {
whereConditions.push('last_login IS NULL OR last_login < DATE_SUB(NOW(), INTERVAL 30 DAY)')
whereConditions.push('status = "inactive"')
} else if (status === 'invited') {
whereConditions.push('status = "invited"')
}
}
@@ -54,10 +123,21 @@ export async function GET(request: NextRequest) {
const stats = await userService.getUserStats()
// 映射用戶數據欄位,將資料庫欄位轉換為前端期望的欄位
const mappedUsers = users.map(user => ({
...user,
joinDate: user.join_date ? new Date(user.join_date).toLocaleDateString('zh-TW') : '-',
lastLogin: user.last_login ? new Date(user.last_login).toLocaleString('zh-TW') : '-',
status: user.status, // 直接使用資料庫的 status 欄位
totalApps: 0, // 暫時設為 0後續可以從統計數據中獲取
totalReviews: 0, // 暫時設為 0後續可以從統計數據中獲取
totalLikes: user.total_likes || 0
}))
return NextResponse.json({
success: true,
data: {
users,
users: mappedUsers,
pagination: {
page,
limit,
@@ -65,12 +145,12 @@ export async function GET(request: NextRequest) {
totalPages: Math.ceil(total / limit)
},
stats: {
totalUsers: stats?.total_users || 0,
activeUsers: stats?.active_users || 0,
adminCount: stats?.admin_count || 0,
developerCount: stats?.developer_count || 0,
inactiveUsers: stats?.inactive_users || 0,
newThisMonth: stats?.new_this_month || 0
totalUsers: stats?.totalUsers || 0,
activeUsers: stats?.activeUsers || 0,
adminCount: stats?.adminCount || 0,
developerCount: stats?.developerCount || 0,
inactiveUsers: stats?.invitedUsers || 0, // 將 invitedUsers 映射為 inactiveUsers待註冊
newThisMonth: stats?.newThisMonth || 0
}
}
})
@@ -84,51 +164,3 @@ export async function GET(request: NextRequest) {
}
}
export async function POST(request: NextRequest) {
try {
const { email, role } = await request.json()
if (!email || !role) {
return NextResponse.json(
{ error: '請提供電子郵件和角色' },
{ status: 400 }
)
}
// 檢查郵箱是否已存在
const existingUser = await userService.findByEmail(email)
if (existingUser) {
return NextResponse.json(
{ error: '該電子郵件地址已被使用' },
{ status: 400 }
)
}
// 生成邀請 token
const { v4: uuidv4 } = require('uuid')
const invitationToken = uuidv4()
// 創建邀請記錄(這裡可以存儲到邀請表或臨時表)
// 暫時返回邀請連結
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
const invitationLink = `${baseUrl}/register?token=${invitationToken}&email=${encodeURIComponent(email)}&role=${encodeURIComponent(role)}`
return NextResponse.json({
success: true,
message: '用戶邀請已創建',
data: {
invitationLink,
token: invitationToken,
email,
role
}
})
} catch (error) {
console.error('創建用戶邀請錯誤:', error)
return NextResponse.json(
{ error: '創建用戶邀請時發生錯誤' },
{ status: 500 }
)
}
}