Files
ai-showcase-platform/app/api/admin/users/route.ts

167 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextRequest, NextResponse } from 'next/server'
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)
const page = parseInt(searchParams.get('page') || '1')
const limit = parseInt(searchParams.get('limit') || '10')
const search = searchParams.get('search') || ''
const department = searchParams.get('department') || ''
const role = searchParams.get('role') || ''
const status = searchParams.get('status') || ''
// 構建查詢條件
let whereConditions = ['status IN ("active", "inactive", "invited")']
let params: any[] = []
if (search) {
whereConditions.push('(name LIKE ? OR email LIKE ?)')
params.push(`%${search}%`, `%${search}%`)
}
if (department && department !== 'all') {
whereConditions.push('department = ?')
params.push(department)
}
if (role && role !== 'all') {
whereConditions.push('role = ?')
params.push(role)
}
if (status && status !== 'all') {
if (status === 'active') {
whereConditions.push('status = "active"')
} else if (status === 'inactive') {
whereConditions.push('status = "inactive"')
} else if (status === 'invited') {
whereConditions.push('status = "invited"')
}
}
const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : ''
// 使用 UserService 的方法
const { users, total } = await userService.findAll({
search,
department,
role,
status,
page,
limit
})
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: mappedUsers,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit)
},
stats: {
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
}
}
})
} catch (error) {
console.error('獲取用戶列表錯誤:', error)
return NextResponse.json(
{ error: '獲取用戶列表時發生錯誤' },
{ status: 500 }
)
}
}