138 lines
4.2 KiB
TypeScript
138 lines
4.2 KiB
TypeScript
import { NextResponse } from 'next/server'
|
||
import { prisma } from '@/lib/prisma'
|
||
import { createServerSupabaseClient } from '@/lib/supabase-server'
|
||
import { addCredit } from '@/lib/services/credit'
|
||
|
||
// POST /api/users/sync - 同步Supabase用户到Prisma数据库
|
||
export async function POST() {
|
||
try {
|
||
const supabase = await createServerSupabaseClient()
|
||
const { data: { user: supabaseUser }, error: authError } = await supabase.auth.getUser()
|
||
|
||
if (authError || !supabaseUser) {
|
||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||
}
|
||
|
||
// 先检查用户是否存在
|
||
let user = await prisma.user.findUnique({
|
||
where: { id: supabaseUser.id }
|
||
})
|
||
|
||
let isNewUser = false
|
||
|
||
if (user) {
|
||
// 用户已存在,更新信息
|
||
user = await prisma.user.update({
|
||
where: { id: supabaseUser.id },
|
||
data: {
|
||
email: supabaseUser.email!,
|
||
username: supabaseUser.user_metadata?.username || supabaseUser.user_metadata?.full_name || null,
|
||
avatar: supabaseUser.user_metadata?.avatar_url || null,
|
||
bio: supabaseUser.user_metadata?.bio || null,
|
||
language: supabaseUser.user_metadata?.language || 'en',
|
||
updatedAt: new Date()
|
||
}
|
||
})
|
||
} else {
|
||
// 用户不存在,需要创建
|
||
try {
|
||
user = await prisma.user.create({
|
||
data: {
|
||
id: supabaseUser.id,
|
||
email: supabaseUser.email!,
|
||
username: supabaseUser.user_metadata?.username || supabaseUser.user_metadata?.full_name || null,
|
||
avatar: supabaseUser.user_metadata?.avatar_url || null,
|
||
bio: supabaseUser.user_metadata?.bio || null,
|
||
language: supabaseUser.user_metadata?.language || 'en',
|
||
subscriptionPlanId: 'free'
|
||
}
|
||
})
|
||
isNewUser = true
|
||
} catch (createError: unknown) {
|
||
// 如果是唯一约束错误,可能是并发创建导致的
|
||
const prismaError = createError as { code?: string }
|
||
if (prismaError.code === 'P2002') {
|
||
console.warn(`Concurrent user creation detected for ${supabaseUser.id}, fetching existing user`)
|
||
user = await prisma.user.findUnique({
|
||
where: { id: supabaseUser.id }
|
||
})
|
||
if (!user) {
|
||
throw createError // 如果还是找不到用户,重新抛出错误
|
||
}
|
||
} else {
|
||
throw createError
|
||
}
|
||
}
|
||
}
|
||
|
||
// isNewUser 变量已经在上面定义了
|
||
|
||
if (isNewUser) {
|
||
// 为新用户添加系统赠送的5USD信用额度(1个月后过期)
|
||
const expiresAt = new Date()
|
||
expiresAt.setMonth(expiresAt.getMonth() + 1)
|
||
|
||
try {
|
||
await addCredit(
|
||
user.id,
|
||
5.0,
|
||
'system_gift',
|
||
'系统赠送 - 新用户礼包',
|
||
expiresAt
|
||
)
|
||
console.log(`Added welcome credit for new user: ${user.id}`)
|
||
} catch (creditError) {
|
||
console.error('Failed to add welcome credit:', creditError)
|
||
// 不影响用户创建流程
|
||
}
|
||
|
||
return NextResponse.json({
|
||
message: 'User created successfully',
|
||
user
|
||
}, { status: 201 })
|
||
} else {
|
||
return NextResponse.json({
|
||
message: 'User updated successfully',
|
||
user
|
||
})
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('Error syncing user:', error)
|
||
return NextResponse.json(
|
||
{ error: 'Failed to sync user' },
|
||
{ status: 500 }
|
||
)
|
||
}
|
||
}
|
||
|
||
// GET /api/users/sync - 获取当前用户信息
|
||
export async function GET() {
|
||
try {
|
||
const supabase = await createServerSupabaseClient()
|
||
const { data: { user: supabaseUser }, error: authError } = await supabase.auth.getUser()
|
||
|
||
if (authError || !supabaseUser) {
|
||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||
}
|
||
|
||
// 从Prisma数据库获取用户信息
|
||
const user = await prisma.user.findUnique({
|
||
where: { id: supabaseUser.id }
|
||
})
|
||
|
||
if (!user) {
|
||
return NextResponse.json({ error: 'User not found in database' }, { status: 404 })
|
||
}
|
||
|
||
return NextResponse.json({ user })
|
||
|
||
} catch (error) {
|
||
console.error('Error fetching user:', error)
|
||
return NextResponse.json(
|
||
{ error: 'Failed to fetch user' },
|
||
{ status: 500 }
|
||
)
|
||
}
|
||
}
|