92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
|
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||
|
|
import { auth } from '../../../lib/supabase'
|
||
|
|
import { getUserProfile, handleApiError, validateEmail } from '../../../lib/api-utils'
|
||
|
|
|
||
|
|
interface LoginRequest {
|
||
|
|
email: string
|
||
|
|
password: string
|
||
|
|
}
|
||
|
|
|
||
|
|
export default async function handler(
|
||
|
|
req: NextApiRequest,
|
||
|
|
res: NextApiResponse
|
||
|
|
) {
|
||
|
|
if (req.method !== 'POST') {
|
||
|
|
return res.status(405).json({ success: false, error: '方法不允许' })
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const { email, password }: LoginRequest = req.body
|
||
|
|
|
||
|
|
// 验证必填字段
|
||
|
|
if (!email || !password) {
|
||
|
|
return res.status(400).json({
|
||
|
|
success: false,
|
||
|
|
error: '缺少必填字段',
|
||
|
|
details: '邮箱和密码为必填项'
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// 验证邮箱格式
|
||
|
|
if (!validateEmail(email)) {
|
||
|
|
return res.status(400).json({
|
||
|
|
success: false,
|
||
|
|
error: '邮箱格式不正确'
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// 登录用户
|
||
|
|
const authData = await auth.signIn(email, password)
|
||
|
|
|
||
|
|
if (!authData?.user || !authData?.session) {
|
||
|
|
return res.status(401).json({
|
||
|
|
success: false,
|
||
|
|
error: '登录失败,请检查邮箱和密码'
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// 获取用户详细信息
|
||
|
|
const userProfile = await getUserProfile(authData.user.id)
|
||
|
|
|
||
|
|
// 更新最后登录时间
|
||
|
|
if (userProfile) {
|
||
|
|
try {
|
||
|
|
await auth.updateUser({
|
||
|
|
user_metadata: {
|
||
|
|
...authData.user.user_metadata,
|
||
|
|
last_login: new Date().toISOString()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
} catch (updateError) {
|
||
|
|
console.error('Update last login error:', updateError)
|
||
|
|
// 不影响登录流程
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return res.status(200).json({
|
||
|
|
success: true,
|
||
|
|
message: '登录成功',
|
||
|
|
data: {
|
||
|
|
user: userProfile || {
|
||
|
|
id: authData.user.id,
|
||
|
|
email: authData.user.email,
|
||
|
|
name: authData.user.user_metadata?.name || '',
|
||
|
|
user_type: authData.user.user_metadata?.user_type || 'individual',
|
||
|
|
enterprise_id: authData.user.user_metadata?.enterprise_id || null,
|
||
|
|
status: 'active',
|
||
|
|
phone: authData.user.user_metadata?.phone || null,
|
||
|
|
created_at: authData.user.created_at,
|
||
|
|
updated_at: authData.user.updated_at
|
||
|
|
},
|
||
|
|
session: {
|
||
|
|
access_token: authData.session.access_token,
|
||
|
|
refresh_token: authData.session.refresh_token,
|
||
|
|
expires_at: authData.session.expires_at
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
} catch (error) {
|
||
|
|
return handleApiError(res, error, 'Login')
|
||
|
|
}
|
||
|
|
}
|