Files
soul/app/api/distribution/route.ts
卡若 b60edb3d47 feat: 完整重构小程序匹配功能 + 修复UI对齐 + 文章数据API
主要更新:
1. 按H5网页端完全重构匹配功能(match页面)
   - 4种匹配类型: 创业合伙/资源对接/导师顾问/团队招募
   - 资源对接等类型弹出手机号/微信号输入框
   - 去掉重新匹配按钮,改为返回按钮

2. 修复所有卡片对齐和宽度问题
   - 目录页附录卡片居中
   - 首页阅读进度卡片满宽度
   - 我的页面菜单卡片对齐
   - 推广中心分享卡片统一宽度

3. 修复目录页图标和文字对齐
   - section-icon固定40rpx宽高
   - section-title与图标垂直居中

4. 更新真实完整文章标题(62篇)
   - 从book目录读取真实markdown文件名
   - 替换之前的简化标题

5. 新增文章数据API
   - /api/db/chapters - 获取完整书籍结构
   - 支持按ID获取单篇文章内容
2026-01-21 15:49:12 +08:00

886 lines
25 KiB
TypeScript

/**
* 分销模块API
* 功能:绑定追踪、提现管理、统计概览
*/
import { NextRequest, NextResponse } from 'next/server';
// 模拟数据存储(实际项目应使用数据库)
let distributionBindings: Array<{
id: string;
referrerId: string;
referrerCode: string;
visitorId: string;
visitorPhone?: string;
visitorNickname?: string;
bindingTime: string;
expireTime: string;
status: 'active' | 'converted' | 'expired' | 'cancelled';
convertedAt?: string;
orderId?: string;
orderAmount?: number;
commission?: number;
source: 'link' | 'miniprogram' | 'poster' | 'qrcode';
createdAt: string;
}> = [];
let clickRecords: Array<{
id: string;
referralCode: string;
referrerId: string;
visitorId: string;
source: string;
clickTime: string;
}> = [];
let distributors: Array<{
id: string;
userId: string;
nickname: string;
phone: string;
referralCode: string;
totalClicks: number;
totalBindings: number;
activeBindings: number;
convertedBindings: number;
expiredBindings: number;
totalEarnings: number;
pendingEarnings: number;
withdrawnEarnings: number;
autoWithdraw: boolean;
autoWithdrawThreshold: number;
autoWithdrawAccount?: {
type: 'wechat' | 'alipay';
account: string;
name: string;
};
level: 'normal' | 'silver' | 'gold' | 'diamond';
commissionRate: number;
status: 'active' | 'frozen' | 'disabled';
createdAt: string;
}> = [];
let withdrawRecords: Array<{
id: string;
distributorId: string;
userId: string;
userName: string;
amount: number;
fee: number;
actualAmount: number;
method: 'wechat' | 'alipay';
account: string;
accountName: string;
status: 'pending' | 'processing' | 'completed' | 'failed' | 'rejected';
isAuto: boolean;
paymentNo?: string;
paymentTime?: string;
reviewNote?: string;
createdAt: string;
completedAt?: string;
}> = [];
// 配置
const BINDING_DAYS = 30;
const MIN_WITHDRAW_AMOUNT = 10;
const DEFAULT_COMMISSION_RATE = 90;
// 生成ID
function generateId(prefix: string = ''): string {
return `${prefix}${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// GET: 获取分销数据
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url);
const type = searchParams.get('type') || 'overview';
const userId = searchParams.get('userId');
const page = parseInt(searchParams.get('page') || '1');
const pageSize = parseInt(searchParams.get('pageSize') || '20');
try {
switch (type) {
case 'overview':
return getOverview();
case 'bindings':
return getBindings(userId, page, pageSize);
case 'my-bindings':
if (!userId) {
return NextResponse.json({ error: '缺少用户ID' }, { status: 400 });
}
return getMyBindings(userId);
case 'withdrawals':
return getWithdrawals(userId, page, pageSize);
case 'reminders':
if (!userId) {
return NextResponse.json({ error: '缺少用户ID' }, { status: 400 });
}
return getReminders(userId);
case 'distributor':
if (!userId) {
return NextResponse.json({ error: '缺少用户ID' }, { status: 400 });
}
return getDistributor(userId);
case 'ranking':
return getRanking();
default:
return NextResponse.json({ error: '未知类型' }, { status: 400 });
}
} catch (error) {
console.error('分销API错误:', error);
return NextResponse.json({ error: '服务器错误' }, { status: 500 });
}
}
// POST: 分销操作
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { action } = body;
switch (action) {
case 'record_click':
return recordClick(body);
case 'convert':
return convertBinding(body);
case 'request_withdraw':
return requestWithdraw(body);
case 'set_auto_withdraw':
return setAutoWithdraw(body);
case 'process_expired':
return processExpiredBindings();
default:
return NextResponse.json({ error: '未知操作' }, { status: 400 });
}
} catch (error) {
console.error('分销API错误:', error);
return NextResponse.json({ error: '服务器错误' }, { status: 500 });
}
}
// PUT: 更新操作(后台管理)
export async function PUT(req: NextRequest) {
try {
const body = await req.json();
const { action } = body;
switch (action) {
case 'approve_withdraw':
return approveWithdraw(body);
case 'reject_withdraw':
return rejectWithdraw(body);
case 'update_distributor':
return updateDistributor(body);
default:
return NextResponse.json({ error: '未知操作' }, { status: 400 });
}
} catch (error) {
console.error('分销API错误:', error);
return NextResponse.json({ error: '服务器错误' }, { status: 500 });
}
}
// ========== 具体实现 ==========
// 获取概览数据
function getOverview() {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
const weekFromNow = new Date();
weekFromNow.setDate(weekFromNow.getDate() + 7);
const overview = {
// 今日数据
todayClicks: clickRecords.filter(c => new Date(c.clickTime) >= today).length,
todayBindings: distributionBindings.filter(b => new Date(b.createdAt) >= today).length,
todayConversions: distributionBindings.filter(b =>
b.status === 'converted' && b.convertedAt && new Date(b.convertedAt) >= today
).length,
todayEarnings: distributionBindings
.filter(b => b.status === 'converted' && b.convertedAt && new Date(b.convertedAt) >= today)
.reduce((sum, b) => sum + (b.commission || 0), 0),
// 本月数据
monthClicks: clickRecords.filter(c => new Date(c.clickTime) >= monthStart).length,
monthBindings: distributionBindings.filter(b => new Date(b.createdAt) >= monthStart).length,
monthConversions: distributionBindings.filter(b =>
b.status === 'converted' && b.convertedAt && new Date(b.convertedAt) >= monthStart
).length,
monthEarnings: distributionBindings
.filter(b => b.status === 'converted' && b.convertedAt && new Date(b.convertedAt) >= monthStart)
.reduce((sum, b) => sum + (b.commission || 0), 0),
// 总计
totalClicks: clickRecords.length,
totalBindings: distributionBindings.length,
totalConversions: distributionBindings.filter(b => b.status === 'converted').length,
totalEarnings: distributionBindings
.filter(b => b.status === 'converted')
.reduce((sum, b) => sum + (b.commission || 0), 0),
// 即将过期
expiringBindings: distributionBindings.filter(b =>
b.status === 'active' &&
new Date(b.expireTime) <= weekFromNow &&
new Date(b.expireTime) > now
).length,
// 待处理提现
pendingWithdrawals: withdrawRecords.filter(w => w.status === 'pending').length,
pendingWithdrawAmount: withdrawRecords
.filter(w => w.status === 'pending')
.reduce((sum, w) => sum + w.amount, 0),
// 转化率
conversionRate: clickRecords.length > 0
? (distributionBindings.filter(b => b.status === 'converted').length / clickRecords.length * 100).toFixed(2)
: '0.00',
// 分销商数量
totalDistributors: distributors.length,
activeDistributors: distributors.filter(d => d.status === 'active').length,
};
return NextResponse.json({ success: true, overview });
}
// 获取绑定列表(后台)
function getBindings(userId: string | null, page: number, pageSize: number) {
let filteredBindings = [...distributionBindings];
if (userId) {
filteredBindings = filteredBindings.filter(b => b.referrerId === userId);
}
// 按创建时间倒序
filteredBindings.sort((a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
const total = filteredBindings.length;
const start = (page - 1) * pageSize;
const paginatedBindings = filteredBindings.slice(start, start + pageSize);
// 添加剩余天数
const now = new Date();
const bindingsWithDays = paginatedBindings.map(b => ({
...b,
daysRemaining: b.status === 'active'
? Math.max(0, Math.ceil((new Date(b.expireTime).getTime() - now.getTime()) / (1000 * 60 * 60 * 24)))
: 0,
}));
return NextResponse.json({
success: true,
bindings: bindingsWithDays,
pagination: {
page,
pageSize,
total,
totalPages: Math.ceil(total / pageSize),
},
});
}
// 获取我的绑定用户(分销中心)
function getMyBindings(userId: string) {
const myBindings = distributionBindings.filter(b => b.referrerId === userId);
const now = new Date();
// 按状态分类
const active = myBindings
.filter(b => b.status === 'active')
.map(b => ({
...b,
daysRemaining: Math.max(0, Math.ceil((new Date(b.expireTime).getTime() - now.getTime()) / (1000 * 60 * 60 * 24))),
}))
.sort((a, b) => a.daysRemaining - b.daysRemaining); // 即将过期的排前面
const converted = myBindings.filter(b => b.status === 'converted');
const expired = myBindings.filter(b => b.status === 'expired');
// 统计
const stats = {
totalBindings: myBindings.length,
activeCount: active.length,
convertedCount: converted.length,
expiredCount: expired.length,
expiringCount: active.filter(b => b.daysRemaining <= 7).length,
totalCommission: converted.reduce((sum, b) => sum + (b.commission || 0), 0),
};
return NextResponse.json({
success: true,
bindings: {
active,
converted,
expired,
},
stats,
});
}
// 获取提现记录
function getWithdrawals(userId: string | null, page: number, pageSize: number) {
let filteredWithdrawals = [...withdrawRecords];
if (userId) {
filteredWithdrawals = filteredWithdrawals.filter(w => w.userId === userId);
}
// 按创建时间倒序
filteredWithdrawals.sort((a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
const total = filteredWithdrawals.length;
const start = (page - 1) * pageSize;
const paginatedWithdrawals = filteredWithdrawals.slice(start, start + pageSize);
// 统计
const stats = {
pending: filteredWithdrawals.filter(w => w.status === 'pending').length,
pendingAmount: filteredWithdrawals
.filter(w => w.status === 'pending')
.reduce((sum, w) => sum + w.amount, 0),
completed: filteredWithdrawals.filter(w => w.status === 'completed').length,
completedAmount: filteredWithdrawals
.filter(w => w.status === 'completed')
.reduce((sum, w) => sum + w.amount, 0),
};
return NextResponse.json({
success: true,
withdrawals: paginatedWithdrawals,
stats,
pagination: {
page,
pageSize,
total,
totalPages: Math.ceil(total / pageSize),
},
});
}
// 获取提醒
function getReminders(userId: string) {
const now = new Date();
const weekFromNow = new Date();
weekFromNow.setDate(weekFromNow.getDate() + 7);
const myBindings = distributionBindings.filter(b =>
b.referrerId === userId && b.status === 'active'
);
const expiringSoon = myBindings.filter(b => {
const expireTime = new Date(b.expireTime);
return expireTime <= weekFromNow && expireTime > now;
}).map(b => ({
type: 'expiring_soon',
binding: b,
daysRemaining: Math.ceil((new Date(b.expireTime).getTime() - now.getTime()) / (1000 * 60 * 60 * 24)),
message: `用户 ${b.visitorNickname || b.visitorPhone || '未知'} 的绑定将在 ${Math.ceil((new Date(b.expireTime).getTime() - now.getTime()) / (1000 * 60 * 60 * 24))} 天后过期`,
}));
return NextResponse.json({
success: true,
reminders: expiringSoon,
count: expiringSoon.length,
});
}
// 获取分销商信息
function getDistributor(userId: string) {
const distributor = distributors.find(d => d.userId === userId);
if (!distributor) {
return NextResponse.json({
success: true,
distributor: null,
message: '用户尚未成为分销商',
});
}
return NextResponse.json({ success: true, distributor });
}
// 获取排行榜
function getRanking() {
const ranking = [...distributors]
.filter(d => d.status === 'active')
.sort((a, b) => b.totalEarnings - a.totalEarnings)
.slice(0, 10)
.map((d, index) => ({
rank: index + 1,
distributorId: d.id,
nickname: d.nickname,
totalEarnings: d.totalEarnings,
totalConversions: d.convertedBindings,
level: d.level,
}));
return NextResponse.json({ success: true, ranking });
}
// 记录点击
function recordClick(body: {
referralCode: string;
referrerId: string;
visitorId: string;
visitorPhone?: string;
visitorNickname?: string;
source: 'link' | 'miniprogram' | 'poster' | 'qrcode';
}) {
const now = new Date();
// 1. 记录点击
const click = {
id: generateId('click_'),
referralCode: body.referralCode,
referrerId: body.referrerId,
visitorId: body.visitorId,
source: body.source,
clickTime: now.toISOString(),
};
clickRecords.push(click);
// 2. 检查现有绑定
const existingBinding = distributionBindings.find(b =>
b.visitorId === body.visitorId &&
b.status === 'active' &&
new Date(b.expireTime) > now
);
if (existingBinding) {
// 已有有效绑定,只记录点击
return NextResponse.json({
success: true,
message: '点击已记录,用户已被其他分销商绑定',
click,
binding: null,
});
}
// 3. 创建新绑定
const expireDate = new Date(now);
expireDate.setDate(expireDate.getDate() + BINDING_DAYS);
const binding = {
id: generateId('bind_'),
referrerId: body.referrerId,
referrerCode: body.referralCode,
visitorId: body.visitorId,
visitorPhone: body.visitorPhone,
visitorNickname: body.visitorNickname,
bindingTime: now.toISOString(),
expireTime: expireDate.toISOString(),
status: 'active' as const,
source: body.source,
createdAt: now.toISOString(),
};
distributionBindings.push(binding);
// 4. 更新分销商统计
const distributorIndex = distributors.findIndex(d => d.userId === body.referrerId);
if (distributorIndex !== -1) {
distributors[distributorIndex].totalClicks++;
distributors[distributorIndex].totalBindings++;
distributors[distributorIndex].activeBindings++;
}
return NextResponse.json({
success: true,
message: '点击已记录,绑定创建成功',
click,
binding,
expireTime: expireDate.toISOString(),
bindingDays: BINDING_DAYS,
});
}
// 转化绑定(用户付款)
function convertBinding(body: {
visitorId: string;
orderId: string;
orderAmount: number;
}) {
const now = new Date();
// 查找有效绑定
const bindingIndex = distributionBindings.findIndex(b =>
b.visitorId === body.visitorId &&
b.status === 'active' &&
new Date(b.expireTime) > now
);
if (bindingIndex === -1) {
return NextResponse.json({
success: false,
message: '未找到有效绑定,该订单不计入分销',
});
}
const binding = distributionBindings[bindingIndex];
// 查找分销商
const distributorIndex = distributors.findIndex(d => d.userId === binding.referrerId);
const commissionRate = distributorIndex !== -1
? distributors[distributorIndex].commissionRate
: DEFAULT_COMMISSION_RATE;
const commission = body.orderAmount * (commissionRate / 100);
// 更新绑定
distributionBindings[bindingIndex] = {
...binding,
status: 'converted',
convertedAt: now.toISOString(),
orderId: body.orderId,
orderAmount: body.orderAmount,
commission,
};
// 更新分销商
if (distributorIndex !== -1) {
distributors[distributorIndex].activeBindings--;
distributors[distributorIndex].convertedBindings++;
distributors[distributorIndex].totalEarnings += commission;
distributors[distributorIndex].pendingEarnings += commission;
// 检查是否需要自动提现
checkAutoWithdraw(distributors[distributorIndex]);
}
return NextResponse.json({
success: true,
message: '订单转化成功',
binding: distributionBindings[bindingIndex],
commission,
referrerId: binding.referrerId,
});
}
// 申请提现
function requestWithdraw(body: {
userId: string;
amount: number;
method: 'wechat' | 'alipay';
account: string;
accountName: string;
}) {
// 查找分销商
const distributorIndex = distributors.findIndex(d => d.userId === body.userId);
if (distributorIndex === -1) {
return NextResponse.json({ success: false, error: '分销商不存在' }, { status: 404 });
}
const distributor = distributors[distributorIndex];
if (body.amount < MIN_WITHDRAW_AMOUNT) {
return NextResponse.json({
success: false,
error: `最低提现金额为 ${MIN_WITHDRAW_AMOUNT}`
}, { status: 400 });
}
if (body.amount > distributor.pendingEarnings) {
return NextResponse.json({
success: false,
error: '提现金额超过可提现余额'
}, { status: 400 });
}
// 创建提现记录
const withdrawal = {
id: generateId('withdraw_'),
distributorId: distributor.id,
userId: body.userId,
userName: distributor.nickname,
amount: body.amount,
fee: 0,
actualAmount: body.amount,
method: body.method,
account: body.account,
accountName: body.accountName,
status: 'pending' as const,
isAuto: false,
createdAt: new Date().toISOString(),
};
withdrawRecords.push(withdrawal);
// 扣除待提现金额
distributors[distributorIndex].pendingEarnings -= body.amount;
return NextResponse.json({
success: true,
message: '提现申请已提交',
withdrawal,
});
}
// 设置自动提现
function setAutoWithdraw(body: {
userId: string;
enabled: boolean;
threshold?: number;
account?: {
type: 'wechat' | 'alipay';
account: string;
name: string;
};
}) {
const distributorIndex = distributors.findIndex(d => d.userId === body.userId);
if (distributorIndex === -1) {
return NextResponse.json({ success: false, error: '分销商不存在' }, { status: 404 });
}
distributors[distributorIndex] = {
...distributors[distributorIndex],
autoWithdraw: body.enabled,
autoWithdrawThreshold: body.threshold || distributors[distributorIndex].autoWithdrawThreshold,
autoWithdrawAccount: body.account || distributors[distributorIndex].autoWithdrawAccount,
};
return NextResponse.json({
success: true,
message: body.enabled ? '自动提现已开启' : '自动提现已关闭',
distributor: distributors[distributorIndex],
});
}
// 处理过期绑定
function processExpiredBindings() {
const now = new Date();
let expiredCount = 0;
distributionBindings.forEach((binding, index) => {
if (binding.status === 'active' && new Date(binding.expireTime) <= now) {
distributionBindings[index].status = 'expired';
expiredCount++;
// 更新分销商统计
const distributorIndex = distributors.findIndex(d => d.userId === binding.referrerId);
if (distributorIndex !== -1) {
distributors[distributorIndex].activeBindings--;
distributors[distributorIndex].expiredBindings++;
}
}
});
return NextResponse.json({
success: true,
message: `已处理 ${expiredCount} 个过期绑定`,
expiredCount,
});
}
// 审核通过提现
async function approveWithdraw(body: { withdrawalId: string; reviewedBy?: string }) {
const withdrawalIndex = withdrawRecords.findIndex(w => w.id === body.withdrawalId);
if (withdrawalIndex === -1) {
return NextResponse.json({ success: false, error: '提现记录不存在' }, { status: 404 });
}
const withdrawal = withdrawRecords[withdrawalIndex];
if (withdrawal.status !== 'pending') {
return NextResponse.json({ success: false, error: '该提现申请已处理' }, { status: 400 });
}
// 更新状态为处理中
withdrawRecords[withdrawalIndex].status = 'processing';
// 模拟打款(实际项目中调用支付接口)
try {
// 模拟延迟
await new Promise(resolve => setTimeout(resolve, 500));
// 打款成功
withdrawRecords[withdrawalIndex] = {
...withdrawRecords[withdrawalIndex],
status: 'completed',
paymentNo: `PAY${Date.now()}`,
paymentTime: new Date().toISOString(),
completedAt: new Date().toISOString(),
};
// 更新分销商已提现金额
const distributorIndex = distributors.findIndex(d => d.userId === withdrawal.userId);
if (distributorIndex !== -1) {
distributors[distributorIndex].withdrawnEarnings += withdrawal.amount;
}
return NextResponse.json({
success: true,
message: '打款成功',
withdrawal: withdrawRecords[withdrawalIndex],
});
} catch (error) {
// 打款失败,退还金额
withdrawRecords[withdrawalIndex].status = 'failed';
const distributorIndex = distributors.findIndex(d => d.userId === withdrawal.userId);
if (distributorIndex !== -1) {
distributors[distributorIndex].pendingEarnings += withdrawal.amount;
}
return NextResponse.json({ success: false, error: '打款失败' }, { status: 500 });
}
}
// 拒绝提现
function rejectWithdraw(body: { withdrawalId: string; reason: string; reviewedBy?: string }) {
const withdrawalIndex = withdrawRecords.findIndex(w => w.id === body.withdrawalId);
if (withdrawalIndex === -1) {
return NextResponse.json({ success: false, error: '提现记录不存在' }, { status: 404 });
}
const withdrawal = withdrawRecords[withdrawalIndex];
if (withdrawal.status !== 'pending') {
return NextResponse.json({ success: false, error: '该提现申请已处理' }, { status: 400 });
}
// 更新状态
withdrawRecords[withdrawalIndex] = {
...withdrawal,
status: 'rejected',
reviewNote: body.reason,
};
// 退还金额
const distributorIndex = distributors.findIndex(d => d.userId === withdrawal.userId);
if (distributorIndex !== -1) {
distributors[distributorIndex].pendingEarnings += withdrawal.amount;
}
return NextResponse.json({
success: true,
message: '提现申请已拒绝',
withdrawal: withdrawRecords[withdrawalIndex],
});
}
// 更新分销商信息
function updateDistributor(body: {
userId: string;
commissionRate?: number;
level?: 'normal' | 'silver' | 'gold' | 'diamond';
status?: 'active' | 'frozen' | 'disabled';
}) {
const distributorIndex = distributors.findIndex(d => d.userId === body.userId);
if (distributorIndex === -1) {
return NextResponse.json({ success: false, error: '分销商不存在' }, { status: 404 });
}
distributors[distributorIndex] = {
...distributors[distributorIndex],
...(body.commissionRate !== undefined && { commissionRate: body.commissionRate }),
...(body.level && { level: body.level }),
...(body.status && { status: body.status }),
};
return NextResponse.json({
success: true,
message: '分销商信息已更新',
distributor: distributors[distributorIndex],
});
}
// 检查自动提现
function checkAutoWithdraw(distributor: typeof distributors[0]) {
if (!distributor.autoWithdraw || !distributor.autoWithdrawAccount) {
return;
}
if (distributor.pendingEarnings >= distributor.autoWithdrawThreshold) {
// 创建自动提现记录
const withdrawal = {
id: generateId('withdraw_'),
distributorId: distributor.id,
userId: distributor.userId,
userName: distributor.nickname,
amount: distributor.pendingEarnings,
fee: 0,
actualAmount: distributor.pendingEarnings,
method: distributor.autoWithdrawAccount.type,
account: distributor.autoWithdrawAccount.account,
accountName: distributor.autoWithdrawAccount.name,
status: 'processing' as const,
isAuto: true,
createdAt: new Date().toISOString(),
};
withdrawRecords.push(withdrawal);
// 扣除待提现金额
const distributorIndex = distributors.findIndex(d => d.id === distributor.id);
if (distributorIndex !== -1) {
distributors[distributorIndex].pendingEarnings = 0;
}
// 模拟打款(实际项目中调用支付接口)
processAutoWithdraw(withdrawal.id);
}
}
// 处理自动提现打款
async function processAutoWithdraw(withdrawalId: string) {
const withdrawalIndex = withdrawRecords.findIndex(w => w.id === withdrawalId);
if (withdrawalIndex === -1) return;
try {
// 模拟延迟
await new Promise(resolve => setTimeout(resolve, 1000));
// 打款成功
const withdrawal = withdrawRecords[withdrawalIndex];
withdrawRecords[withdrawalIndex] = {
...withdrawal,
status: 'completed',
paymentNo: `AUTO_PAY${Date.now()}`,
paymentTime: new Date().toISOString(),
completedAt: new Date().toISOString(),
};
// 更新分销商已提现金额
const distributorIndex = distributors.findIndex(d => d.userId === withdrawal.userId);
if (distributorIndex !== -1) {
distributors[distributorIndex].withdrawnEarnings += withdrawal.amount;
}
console.log(`自动提现成功: ${withdrawal.userName}, 金额: ¥${withdrawal.amount}`);
} catch (error) {
// 打款失败
withdrawRecords[withdrawalIndex].status = 'failed';
const withdrawal = withdrawRecords[withdrawalIndex];
const distributorIndex = distributors.findIndex(d => d.userId === withdrawal.userId);
if (distributorIndex !== -1) {
distributors[distributorIndex].pendingEarnings += withdrawal.amount;
}
console.error(`自动提现失败: ${withdrawal.userName}`);
}
}