2026-01-29 12:26:43 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 微信手机号解密API
|
|
|
|
|
|
* 获取用户手机号(需要小程序 getPhoneNumber 授权)
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
|
|
import { query } from '@/lib/db'
|
|
|
|
|
|
|
|
|
|
|
|
const APPID = process.env.WECHAT_APPID || 'wxb8bbb2b10dec74aa'
|
2026-01-29 16:17:56 +08:00
|
|
|
|
const APPSECRET = process.env.WECHAT_APPSECRET || '3c1fb1f63e6e052222bbcead9d07fe0c'
|
2026-01-29 12:26:43 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* POST - 解密手机号
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function POST(request: NextRequest) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const body = await request.json()
|
|
|
|
|
|
const { code, userId } = body
|
|
|
|
|
|
|
|
|
|
|
|
if (!code) {
|
|
|
|
|
|
return NextResponse.json({ success: false, message: '缺少code参数' }, { status: 400 })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 获取 access_token
|
|
|
|
|
|
const tokenUrl = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
|
|
|
|
|
|
const tokenRes = await fetch(tokenUrl)
|
|
|
|
|
|
const tokenData = await tokenRes.json()
|
|
|
|
|
|
|
|
|
|
|
|
if (!tokenData.access_token) {
|
|
|
|
|
|
console.error('[Phone] 获取access_token失败:', tokenData)
|
|
|
|
|
|
return NextResponse.json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '获取access_token失败',
|
|
|
|
|
|
error: tokenData.errmsg
|
|
|
|
|
|
}, { status: 500 })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 获取手机号
|
|
|
|
|
|
const phoneUrl = `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${tokenData.access_token}`
|
|
|
|
|
|
const phoneRes = await fetch(phoneUrl, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
|
body: JSON.stringify({ code })
|
|
|
|
|
|
})
|
|
|
|
|
|
const phoneData = await phoneRes.json()
|
|
|
|
|
|
|
|
|
|
|
|
if (phoneData.errcode !== 0) {
|
|
|
|
|
|
console.error('[Phone] 获取手机号失败:', phoneData)
|
|
|
|
|
|
return NextResponse.json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '获取手机号失败',
|
|
|
|
|
|
error: phoneData.errmsg
|
|
|
|
|
|
}, { status: 500 })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const phoneNumber = phoneData.phone_info?.phoneNumber || phoneData.phone_info?.purePhoneNumber
|
|
|
|
|
|
|
|
|
|
|
|
if (!phoneNumber) {
|
|
|
|
|
|
return NextResponse.json({ success: false, message: '未获取到手机号' }, { status: 500 })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 如果有userId,更新到数据库
|
|
|
|
|
|
if (userId) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await query('UPDATE users SET phone = ? WHERE id = ?', [phoneNumber, userId])
|
|
|
|
|
|
console.log('[Phone] 手机号已绑定到用户:', userId)
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log('[Phone] 更新数据库失败,但返回手机号成功')
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return NextResponse.json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
phoneNumber,
|
|
|
|
|
|
countryCode: phoneData.phone_info?.countryCode || '86'
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('[Phone] Error:', error)
|
|
|
|
|
|
return NextResponse.json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '服务器错误',
|
|
|
|
|
|
error: String(error)
|
|
|
|
|
|
}, { status: 500 })
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|