Files
soul/app/api/wechat/login/route.ts
卡若 4dd2f9f4a7 feat: 完善后台管理+搜索功能+分销系统
主要更新:
- 后台菜单精简(9项→6项)
- 新增搜索功能(敏感信息过滤)
- 分销绑定和提现系统完善
- 数据库初始化API(自动修复表结构)
- 用户管理:显示绑定关系详情
- 小程序:上下章导航优化、匹配页面重构
- 修复hydration和数据类型问题
2026-01-25 19:37:59 +08:00

157 lines
5.2 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.

// app/api/wechat/login/route.ts
// 微信小程序登录接口
import { NextRequest, NextResponse } from 'next/server'
import { query } from '@/lib/db'
// 使用真实的小程序AppID和Secret
const APPID = process.env.WECHAT_APPID || 'wxb8bbb2b10dec74aa'
const SECRET = process.env.WECHAT_APPSECRET || '3c1fb1f63e6e052222bbcead9d07fe0c'
// POST: 微信小程序登录
export async function POST(req: NextRequest) {
try {
const body = await req.json()
const { code, referralCode } = body
if (!code) {
return NextResponse.json(
{ error: '缺少code参数' },
{ status: 400 }
)
}
// 调用微信API获取session_key和openid
const wxUrl = `https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${code}&grant_type=authorization_code`
const wxResponse = await fetch(wxUrl)
const wxData = await wxResponse.json()
if (wxData.errcode) {
console.error('微信登录失败:', wxData)
return NextResponse.json(
{ error: wxData.errmsg || '微信登录失败' },
{ status: 400 }
)
}
const { openid, session_key, unionid } = wxData
// 生成token
const token = Buffer.from(`${openid}:${Date.now()}`).toString('base64')
// 查询或创建用户
let user: any = null
let isNewUser = false
try {
// 先查询用户是否存在
const existingUsers = await query('SELECT * FROM users WHERE open_id = ?', [openid]) as any[]
if (existingUsers.length > 0) {
// 用户已存在更新session_key
user = existingUsers[0]
await query('UPDATE users SET session_key = ?, updated_at = NOW() WHERE open_id = ?', [session_key, openid])
console.log('[WechatLogin] 用户已存在:', user.id)
} else {
// 创建新用户
isNewUser = true
const userId = 'user_' + Date.now().toString(36) + Math.random().toString(36).substr(2, 6)
const userReferralCode = generateInviteCode(openid)
const nickname = '用户' + openid.substr(-4)
// 处理推荐绑定
let referredBy = null
if (referralCode) {
const referrers = await query('SELECT id FROM users WHERE referral_code = ?', [referralCode]) as any[]
if (referrers.length > 0) {
referredBy = referrers[0].id
// 更新推荐人的推广数量
await query('UPDATE users SET referral_count = referral_count + 1 WHERE id = ?', [referredBy])
}
}
await query(`
INSERT INTO users (
id, open_id, session_key, nickname, avatar, referral_code, referred_by,
has_full_book, purchased_sections, earnings, pending_earnings, referral_count
) VALUES (?, ?, ?, ?, ?, ?, ?, FALSE, '[]', 0, 0, 0)
`, [
userId, openid, session_key, nickname,
'https://picsum.photos/200/200?random=' + openid.substr(-2),
userReferralCode, referredBy
])
// 获取新创建的用户
const newUsers = await query('SELECT * FROM users WHERE id = ?', [userId]) as any[]
user = newUsers[0]
console.log('[WechatLogin] 新用户创建成功:', userId)
}
} catch (dbError) {
console.error('[WechatLogin] 数据库操作失败,使用临时用户:', dbError)
// 数据库失败时使用临时用户信息
user = {
id: openid,
open_id: openid,
nickname: '用户' + openid.substr(-4),
avatar: 'https://picsum.photos/200/200?random=' + openid.substr(-2),
referral_code: generateInviteCode(openid),
has_full_book: false,
purchased_sections: [],
earnings: 0,
pending_earnings: 0,
referral_count: 0,
created_at: new Date().toISOString()
}
}
// 统一用户数据格式
const responseUser = {
id: user.id,
openId: user.open_id || openid,
unionid,
nickname: user.nickname,
avatar: user.avatar,
phone: user.phone,
wechatId: user.wechat_id,
referralCode: user.referral_code,
referredBy: user.referred_by,
hasFullBook: user.has_full_book || false,
purchasedSections: typeof user.purchased_sections === 'string'
? JSON.parse(user.purchased_sections || '[]')
: (user.purchased_sections || []),
earnings: parseFloat(user.earnings) || 0,
pendingEarnings: parseFloat(user.pending_earnings) || 0,
referralCount: user.referral_count || 0,
createdAt: user.created_at
}
return NextResponse.json({
success: true,
token,
user: responseUser,
isNewUser,
message: isNewUser ? '注册成功' : '登录成功'
})
} catch (error) {
console.error('登录接口错误:', error)
return NextResponse.json(
{ error: '服务器错误' },
{ status: 500 }
)
}
}
// 生成邀请码
function generateInviteCode(openid: string): string {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
const hash = openid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
let code = ''
for (let i = 0; i < 6; i++) {
code += chars.charAt((hash + i) % chars.length)
}
return code
}