更新服务器信息为新的 IP 地址,调整相关文档和代码中的默认配置,确保部署和连接的一致性。同时,优化订单管理界面,增强商品信息的格式化逻辑,提升用户体验。
This commit is contained in:
@@ -68,7 +68,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
// 检查用户是否存在
|
||||
const users = await query(
|
||||
'SELECT id, referred_by FROM users WHERE id = ? OR open_id = ?',
|
||||
'SELECT id FROM users WHERE id = ? OR open_id = ?',
|
||||
[effectiveUserId, openId || effectiveUserId]
|
||||
) as any[]
|
||||
|
||||
@@ -90,35 +90,28 @@ export async function POST(request: NextRequest) {
|
||||
ORDER BY binding_date DESC LIMIT 1
|
||||
`, [user.id]) as any[]
|
||||
|
||||
let action = 'new' // new=新绑定, renew=续期, takeover=抢夺
|
||||
let action = 'new' // new=新绑定, renew=续期, switch=立即切换
|
||||
let oldReferrerId = null
|
||||
|
||||
if (existingBindings.length > 0) {
|
||||
const existing = existingBindings[0]
|
||||
const expiryDate = new Date(existing.expiry_date)
|
||||
|
||||
// 同一个推荐人 - 续期
|
||||
// 同一个推荐人 - 续期(刷新30天)
|
||||
if (existing.referrer_id === referrer.id) {
|
||||
action = 'renew'
|
||||
}
|
||||
// 不同推荐人 - 检查是否可以抢夺
|
||||
else if (expiryDate < now) {
|
||||
// 已过期,可以被抢夺
|
||||
action = 'takeover'
|
||||
// 不同推荐人 - 立即切换(新逻辑:无条件切换)
|
||||
else {
|
||||
action = 'switch'
|
||||
oldReferrerId = existing.referrer_id
|
||||
|
||||
// 将旧绑定标记为过期
|
||||
// 将旧绑定标记为 cancelled(被切换)
|
||||
await query(
|
||||
"UPDATE referral_bindings SET status = 'expired' WHERE id = ?",
|
||||
"UPDATE referral_bindings SET status = 'cancelled' WHERE id = ?",
|
||||
[existing.id]
|
||||
)
|
||||
} else {
|
||||
// 未过期,不能被抢夺
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '用户已绑定其他推荐人,绑定有效期内无法更换',
|
||||
expiryDate: expiryDate.toISOString()
|
||||
}, { status: 400 })
|
||||
|
||||
console.log(`[Referral Bind] 立即切换: ${user.id}: ${oldReferrerId} -> ${referrer.id}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +130,9 @@ export async function POST(request: NextRequest) {
|
||||
WHERE referee_id = ? AND referrer_id = ? AND status = 'active'
|
||||
`, [expiryDate, user.id, referrer.id])
|
||||
|
||||
console.log(`[Referral Bind] 续期: ${user.id} -> ${referrer.id}`)
|
||||
console.log(`[Referral Bind] 续期: ${user.id} -> ${referrer.id},新过期时间: ${expiryDate.toISOString()}`)
|
||||
} else {
|
||||
// 新绑定或抢夺
|
||||
// 新绑定或切换
|
||||
await query(`
|
||||
INSERT INTO referral_bindings (
|
||||
id, referrer_id, referee_id, referral_code, status, expiry_date, binding_date
|
||||
@@ -152,11 +145,7 @@ export async function POST(request: NextRequest) {
|
||||
status = 'active'
|
||||
`, [bindingId, referrer.id, user.id, referralCode, expiryDate])
|
||||
|
||||
// 更新用户的推荐人
|
||||
await query(
|
||||
'UPDATE users SET referred_by = ? WHERE id = ?',
|
||||
[referrer.id, user.id]
|
||||
)
|
||||
// 注意:不再更新 users.referred_by(已弃用,只使用 referral_bindings)
|
||||
|
||||
// 更新推荐人的推广数量(仅新绑定时)
|
||||
if (action === 'new') {
|
||||
@@ -164,17 +153,22 @@ export async function POST(request: NextRequest) {
|
||||
'UPDATE users SET referral_count = referral_count + 1 WHERE id = ?',
|
||||
[referrer.id]
|
||||
)
|
||||
console.log(`[Referral Bind] 新绑定: ${user.id} -> ${referrer.id}`)
|
||||
}
|
||||
|
||||
// 如果是抢夺,减少原推荐人的推广数量
|
||||
if (action === 'takeover' && oldReferrerId) {
|
||||
// 如果是立即切换,更新双方的推广数量
|
||||
if (action === 'switch' && oldReferrerId) {
|
||||
// 减少旧推荐人的数量
|
||||
await query(
|
||||
'UPDATE users SET referral_count = GREATEST(referral_count - 1, 0) WHERE id = ?',
|
||||
[oldReferrerId]
|
||||
)
|
||||
console.log(`[Referral Bind] 抢夺: ${user.id}: ${oldReferrerId} -> ${referrer.id}`)
|
||||
} else {
|
||||
console.log(`[Referral Bind] 新绑定: ${user.id} -> ${referrer.id}`)
|
||||
// 增加新推荐人的数量
|
||||
await query(
|
||||
'UPDATE users SET referral_count = referral_count + 1 WHERE id = ?',
|
||||
[referrer.id]
|
||||
)
|
||||
console.log(`[Referral Bind] 立即切换完成: ${user.id}: ${oldReferrerId} -> ${referrer.id}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,15 +182,23 @@ export async function POST(request: NextRequest) {
|
||||
// 访问日志表可能不存在,忽略错误
|
||||
}
|
||||
|
||||
const messages = {
|
||||
new: '绑定成功',
|
||||
renew: '绑定已续期',
|
||||
switch: '已切换推荐人'
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: action === 'renew' ? '绑定已续期' : (action === 'takeover' ? '绑定已更新' : '绑定成功'),
|
||||
message: messages[action] || '绑定成功',
|
||||
action,
|
||||
expiryDate: expiryDate.toISOString(),
|
||||
bindingDays,
|
||||
referrer: {
|
||||
id: referrer.id,
|
||||
nickname: referrer.nickname
|
||||
}
|
||||
},
|
||||
...(oldReferrerId && { oldReferrerId })
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
@@ -238,9 +240,9 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
if (userId) {
|
||||
// 查询用户的推荐关系
|
||||
// 查询用户是否存在
|
||||
const users = await query(
|
||||
'SELECT id, referred_by FROM users WHERE id = ?',
|
||||
'SELECT id FROM users WHERE id = ?',
|
||||
[userId]
|
||||
) as any[]
|
||||
|
||||
@@ -251,25 +253,50 @@ export async function GET(request: NextRequest) {
|
||||
}, { status: 404 })
|
||||
}
|
||||
|
||||
const user = users[0]
|
||||
|
||||
// 如果有推荐人,获取推荐人信息
|
||||
// 从 referral_bindings 查询当前有效的推荐人
|
||||
let referrer = null
|
||||
if (user.referred_by) {
|
||||
const referrers = await query(
|
||||
'SELECT id, nickname, avatar FROM users WHERE id = ?',
|
||||
[user.referred_by]
|
||||
) as any[]
|
||||
if (referrers.length > 0) {
|
||||
referrer = referrers[0]
|
||||
const activeBinding = await query(`
|
||||
SELECT
|
||||
rb.referrer_id,
|
||||
u.nickname,
|
||||
u.avatar,
|
||||
rb.expiry_date,
|
||||
rb.purchase_count
|
||||
FROM referral_bindings rb
|
||||
JOIN users u ON rb.referrer_id = u.id
|
||||
WHERE rb.referee_id = ?
|
||||
AND rb.status = 'active'
|
||||
AND rb.expiry_date > NOW()
|
||||
ORDER BY rb.binding_date DESC
|
||||
LIMIT 1
|
||||
`, [userId]) as any[]
|
||||
|
||||
if (activeBinding.length > 0) {
|
||||
referrer = {
|
||||
id: activeBinding[0].referrer_id,
|
||||
nickname: activeBinding[0].nickname,
|
||||
avatar: activeBinding[0].avatar,
|
||||
expiryDate: activeBinding[0].expiry_date,
|
||||
purchaseCount: activeBinding[0].purchase_count
|
||||
}
|
||||
}
|
||||
|
||||
// 获取该用户推荐的人
|
||||
const referees = await query(
|
||||
'SELECT id, nickname, avatar, created_at FROM users WHERE referred_by = ?',
|
||||
[userId]
|
||||
) as any[]
|
||||
// 获取该用户推荐的人(所有活跃绑定)
|
||||
const referees = await query(`
|
||||
SELECT
|
||||
u.id,
|
||||
u.nickname,
|
||||
u.avatar,
|
||||
rb.binding_date as created_at,
|
||||
rb.purchase_count,
|
||||
rb.total_commission
|
||||
FROM referral_bindings rb
|
||||
JOIN users u ON rb.referee_id = u.id
|
||||
WHERE rb.referrer_id = ?
|
||||
AND rb.status = 'active'
|
||||
AND rb.expiry_date > NOW()
|
||||
ORDER BY rb.binding_date DESC
|
||||
`, [userId]) as any[]
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
|
||||
@@ -31,11 +31,15 @@ export async function GET(request: NextRequest) {
|
||||
try {
|
||||
// 获取分销配置
|
||||
let distributorShare = DISTRIBUTOR_SHARE
|
||||
let minWithdrawAmount = 10 // 默认最低提现金额
|
||||
try {
|
||||
const config = await getConfig('referral_config')
|
||||
if (config?.distributorShare) {
|
||||
distributorShare = config.distributorShare / 100
|
||||
}
|
||||
if (config?.minWithdrawAmount) {
|
||||
minWithdrawAmount = Number(config.minWithdrawAmount)
|
||||
}
|
||||
} catch (e) { /* 使用默认配置 */ }
|
||||
|
||||
// 1. 获取用户基本信息
|
||||
@@ -54,15 +58,15 @@ export async function GET(request: NextRequest) {
|
||||
|
||||
const user = users[0]
|
||||
|
||||
// 2. 获取绑定关系统计(从referral_bindings表)
|
||||
// 2. 获取绑定关系统计(新逻辑:基于 purchase_count)
|
||||
let bindingStats = { total: 0, active: 0, converted: 0, expired: 0 }
|
||||
try {
|
||||
const bindings = await query(`
|
||||
SELECT
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN status = 'active' AND expiry_date > NOW() THEN 1 ELSE 0 END) as active,
|
||||
SUM(CASE WHEN status = 'converted' THEN 1 ELSE 0 END) as converted,
|
||||
SUM(CASE WHEN status = 'expired' OR (status = 'active' AND expiry_date <= NOW()) THEN 1 ELSE 0 END) as expired
|
||||
SUM(CASE WHEN status = 'active' AND purchase_count > 0 THEN 1 ELSE 0 END) as converted,
|
||||
SUM(CASE WHEN status IN ('expired', 'cancelled') OR (status = 'active' AND expiry_date <= NOW()) THEN 1 ELSE 0 END) as expired
|
||||
FROM referral_bindings
|
||||
WHERE referrer_id = ?
|
||||
`, [userId]) as any[]
|
||||
@@ -125,15 +129,16 @@ export async function GET(request: NextRequest) {
|
||||
LIMIT 50
|
||||
`, [userId]) as any[]
|
||||
|
||||
// 6. 获取已转化用户列表
|
||||
// 6. 获取已转化用户列表(新逻辑:有购买记录的活跃绑定)
|
||||
const convertedBindings = await query(`
|
||||
SELECT rb.id, rb.referee_id, rb.conversion_date, rb.commission_amount,
|
||||
SELECT rb.id, rb.referee_id, rb.last_purchase_date as conversion_date,
|
||||
rb.total_commission as commission_amount, rb.purchase_count,
|
||||
u.nickname, u.avatar,
|
||||
(SELECT COALESCE(SUM(amount), 0) FROM orders WHERE user_id = rb.referee_id AND status = 'paid') as order_amount
|
||||
FROM referral_bindings rb
|
||||
JOIN users u ON rb.referee_id = u.id
|
||||
WHERE rb.referrer_id = ? AND rb.status = 'converted'
|
||||
ORDER BY rb.conversion_date DESC
|
||||
WHERE rb.referrer_id = ? AND rb.status = 'active' AND rb.purchase_count > 0
|
||||
ORDER BY rb.last_purchase_date DESC
|
||||
LIMIT 50
|
||||
`, [userId]) as any[]
|
||||
|
||||
@@ -148,21 +153,44 @@ export async function GET(request: NextRequest) {
|
||||
LIMIT 50
|
||||
`, [userId]) as any[]
|
||||
|
||||
// 7. 获取收益明细
|
||||
// 7. 获取待审核提现金额
|
||||
let pendingWithdrawAmount = 0
|
||||
try {
|
||||
const pendingResult = await query(`
|
||||
SELECT COALESCE(SUM(amount), 0) as pending_amount
|
||||
FROM withdrawals
|
||||
WHERE user_id = ? AND status = 'pending'
|
||||
`, [userId]) as any[]
|
||||
pendingWithdrawAmount = parseFloat(pendingResult[0]?.pending_amount || 0)
|
||||
} catch (e) {
|
||||
console.log('[ReferralData] 获取待审核提现金额失败:', e)
|
||||
}
|
||||
|
||||
// 8. 获取收益明细(包含买家信息和商品详情)
|
||||
let earningsDetails: any[] = []
|
||||
try {
|
||||
earningsDetails = await query(`
|
||||
SELECT o.id, o.order_sn, o.amount, o.product_type, o.pay_time,
|
||||
u.nickname as buyer_nickname,
|
||||
rb.commission_amount
|
||||
SELECT
|
||||
o.id,
|
||||
o.order_sn,
|
||||
o.amount,
|
||||
o.product_type,
|
||||
o.product_id,
|
||||
o.description,
|
||||
o.pay_time,
|
||||
u.nickname as buyer_nickname,
|
||||
u.avatar as buyer_avatar,
|
||||
rb.total_commission / rb.purchase_count as commission_per_order
|
||||
FROM orders o
|
||||
JOIN users u ON o.user_id = u.id
|
||||
JOIN referral_bindings rb ON o.user_id = rb.referee_id AND rb.referrer_id = ?
|
||||
WHERE o.status = 'paid'
|
||||
WHERE o.status = 'paid' AND o.referrer_id = ?
|
||||
ORDER BY o.pay_time DESC
|
||||
LIMIT 30
|
||||
`, [userId]) as any[]
|
||||
} catch (e) { /* 忽略 */ }
|
||||
`, [userId, userId]) as any[]
|
||||
} catch (e) {
|
||||
console.log('[ReferralData] 获取收益明细失败:', e)
|
||||
}
|
||||
|
||||
// 8. 计算预估收益
|
||||
const estimatedEarnings = paymentStats.totalAmount * distributorShare
|
||||
@@ -181,16 +209,28 @@ export async function GET(request: NextRequest) {
|
||||
expiredCount: bindingStats.expired,
|
||||
|
||||
// === 收益数据 ===
|
||||
// 已结算收益
|
||||
earnings: parseFloat(user.earnings) || 0,
|
||||
// 待结算收益
|
||||
pendingEarnings: parseFloat(user.pending_earnings) || 0,
|
||||
// 累计佣金总额(所有获得的佣金)
|
||||
totalCommission: Math.round((
|
||||
(parseFloat(user.earnings) || 0) +
|
||||
(parseFloat(user.pending_earnings) || 0) +
|
||||
(parseFloat(user.withdrawn_earnings) || 0)
|
||||
) * 100) / 100,
|
||||
// 可提现金额(pending_earnings)
|
||||
availableEarnings: parseFloat(user.pending_earnings) || 0,
|
||||
// 待审核金额(提现申请中的金额)
|
||||
pendingWithdrawAmount: Math.round(pendingWithdrawAmount * 100) / 100,
|
||||
// 已提现金额
|
||||
withdrawnEarnings: parseFloat(user.withdrawn_earnings) || 0,
|
||||
// 已结算收益(保留兼容)
|
||||
earnings: parseFloat(user.earnings) || 0,
|
||||
// 待结算收益(保留兼容)
|
||||
pendingEarnings: parseFloat(user.pending_earnings) || 0,
|
||||
// 预估总收益
|
||||
estimatedEarnings: Math.round(estimatedEarnings * 100) / 100,
|
||||
// 分成比例
|
||||
shareRate: Math.round(distributorShare * 100),
|
||||
// 最低提现金额(新增:给小程序使用)
|
||||
minWithdrawAmount,
|
||||
|
||||
// === 推荐码 ===
|
||||
referralCode: user.referral_code,
|
||||
@@ -225,6 +265,7 @@ export async function GET(request: NextRequest) {
|
||||
avatar: b.avatar,
|
||||
commission: parseFloat(b.commission_amount) || 0,
|
||||
orderAmount: parseFloat(b.order_amount) || 0,
|
||||
purchaseCount: parseInt(b.purchase_count) || 0,
|
||||
conversionDate: b.conversion_date,
|
||||
status: 'converted'
|
||||
})),
|
||||
@@ -244,9 +285,12 @@ export async function GET(request: NextRequest) {
|
||||
id: e.id,
|
||||
orderSn: e.order_sn,
|
||||
amount: parseFloat(e.amount),
|
||||
commission: parseFloat(e.commission_amount) || parseFloat(e.amount) * distributorShare,
|
||||
commission: parseFloat(e.commission_per_order) || parseFloat(e.amount) * distributorShare,
|
||||
productType: e.product_type,
|
||||
buyerNickname: e.buyer_nickname,
|
||||
productId: e.product_id,
|
||||
description: e.description,
|
||||
buyerNickname: e.buyer_nickname || '用户' + e.id?.toString().slice(-4),
|
||||
buyerAvatar: e.buyer_avatar,
|
||||
payTime: e.pay_time
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user