This commit is contained in:
18631081161 2025-12-24 14:15:36 +08:00
parent 2e90b3e4b2
commit b25822aa61
5 changed files with 115 additions and 39 deletions

View File

@ -202,9 +202,9 @@
<span class="label">累计奖励(¥)</span>
<span class="value primary">¥{{ parseFloat(userDetails.invitations.totalRewardsRmb || userDetails.invitations.totalRewards || 0).toFixed(2) }}</span>
</div>
<div class="stat-item" v-if="parseFloat(userDetails.invitations.totalRewardsPeso || 0) > 0">
<div class="stat-item">
<span class="label">累计奖励()</span>
<span class="value primary">{{ parseFloat(userDetails.invitations.totalRewardsPeso || 0).toFixed(2) }}</span>
<span class="value success">{{ parseFloat(userDetails.invitations.totalRewardsPeso || 0).toFixed(2) }}</span>
</div>
</div>
</el-card>
@ -225,8 +225,20 @@
<span class="value">{{ userDetails.withdrawals.total }}</span>
</div>
<div class="stat-item">
<span class="label">提现金额</span>
<span class="value primary">¥{{ parseFloat(userDetails.withdrawals.totalAmount || 0).toFixed(2) }}</span>
<span class="label">已提现(¥)</span>
<span class="value primary">¥{{ userDetails.withdrawals.totalAmountRmb || '0.00' }}</span>
</div>
<div class="stat-item">
<span class="label">已提现()</span>
<span class="value success">{{ userDetails.withdrawals.totalAmountPeso || '0.00' }}</span>
</div>
<div class="stat-item">
<span class="label">待提现(¥)</span>
<span class="value primary">¥{{ userDetails.withdrawals.pendingBalanceRmb || '0.00' }}</span>
</div>
<div class="stat-item">
<span class="label">待提现()</span>
<span class="value success">{{ userDetails.withdrawals.pendingBalancePeso || '0.00' }}</span>
</div>
<div class="stat-item">
<span class="label">待审核</span>

View File

@ -271,16 +271,19 @@ const getUserDetails = async (userId) => {
where: { userId },
attributes: [
'status',
'currency',
[require('sequelize').fn('COUNT', require('sequelize').col('id')), 'count'],
[require('sequelize').fn('SUM', require('sequelize').col('amount')), 'total'],
],
group: ['status'],
group: ['status', 'currency'],
raw: true,
});
const withdrawalCounts = {
total: 0,
totalAmount: 0,
totalAmountRmb: 0,
totalAmountPeso: 0,
waiting: 0,
processing: 0,
completed: 0,
@ -288,11 +291,27 @@ const getUserDetails = async (userId) => {
};
withdrawalStats.forEach((stat) => {
withdrawalCounts[stat.status] = parseInt(stat.count);
withdrawalCounts.total += parseInt(stat.count);
withdrawalCounts.totalAmount += parseFloat(stat.total || 0);
const count = parseInt(stat.count);
const amount = parseFloat(stat.total || 0);
withdrawalCounts[stat.status] = (withdrawalCounts[stat.status] || 0) + count;
withdrawalCounts.total += count;
withdrawalCounts.totalAmount += amount;
// 按货币类型统计提现金额
if (stat.currency === 'PHP') {
withdrawalCounts.totalAmountPeso += amount;
} else {
withdrawalCounts.totalAmountRmb += amount;
}
});
// Add pending balance by currency from user model
withdrawalCounts.pendingBalanceRmb = parseFloat(user.balance || 0).toFixed(2);
withdrawalCounts.pendingBalancePeso = parseFloat(user.balancePeso || 0).toFixed(2);
withdrawalCounts.totalAmountRmb = withdrawalCounts.totalAmountRmb.toFixed(2);
withdrawalCounts.totalAmountPeso = withdrawalCounts.totalAmountPeso.toFixed(2);
// Get recent login history
const loginHistory = await LoginHistory.findAll({
where: { userId, userType: 'user' },

View File

@ -104,24 +104,57 @@ const getInvitationRecords = async (userId, options = {}) => {
offset: parseInt(offset),
});
// Get commission data for each invitee from Commission table
const Commission = require('../models/Commission');
// Format records - filter out records where invitee was deleted
const records = rows
.filter(invitation => invitation.invitee != null)
.map(invitation => ({
id: invitation.id,
invitee: {
id: invitation.invitee.id,
uid: invitation.invitee.uid,
nickname: invitation.invitee.nickname,
avatar: invitation.invitee.avatar,
registeredAt: invitation.registeredAt,
},
firstPaymentAt: invitation.firstPaymentAt,
firstPaymentAmount: invitation.firstPaymentAmount ? parseFloat(invitation.firstPaymentAmount).toFixed(2) : null,
rewardAmount: invitation.rewardAmount ? parseFloat(invitation.rewardAmount).toFixed(2) : null,
rewardStatus: invitation.rewardStatus,
createdAt: invitation.createdAt,
}));
const records = await Promise.all(
rows
.filter(invitation => invitation.invitee != null)
.map(async (invitation) => {
// Get total commission for this invitee from Commission table
const commissions = await Commission.findAll({
where: {
inviterId: userId,
inviteeId: invitation.invitee.id,
status: 'credited'
},
attributes: ['commissionAmount', 'currency'],
});
let totalRewardRmb = 0;
let totalRewardPeso = 0;
let hasPaid = false;
commissions.forEach(c => {
hasPaid = true;
const amount = parseFloat(c.commissionAmount || 0);
if (c.currency === 'PHP') {
totalRewardPeso += amount;
} else {
totalRewardRmb += amount;
}
});
return {
id: invitation.id,
invitee: {
id: invitation.invitee.id,
uid: invitation.invitee.uid,
nickname: invitation.invitee.nickname,
avatar: invitation.invitee.avatar,
registeredAt: invitation.registeredAt,
},
firstPaymentAt: hasPaid ? (invitation.firstPaymentAt || new Date()) : null,
rewardAmountRmb: totalRewardRmb.toFixed(2),
rewardAmountPeso: totalRewardPeso.toFixed(2),
// Legacy field for backward compatibility
rewardAmount: (totalRewardRmb + totalRewardPeso).toFixed(2),
rewardStatus: hasPaid ? 'credited' : 'pending',
createdAt: invitation.createdAt,
};
})
);
return {
records,

View File

@ -98,8 +98,8 @@ const createPaymentOrder = async (data, adminId) => {
exists = !!existingOrder;
}
// Calculate total amount for commission (use RMB if available)
const totalAmountForCommission = rmbAmount > 0 ? rmbAmount : legacyAmount;
// Calculate total amount for commission (check any currency)
const totalAmountForCommission = rmbAmount > 0 ? rmbAmount : (pesoAmount > 0 ? pesoAmount : legacyAmount);
// Create payment order
const paymentOrder = await PaymentOrder.create({
@ -116,7 +116,7 @@ const createPaymentOrder = async (data, adminId) => {
status: 'active',
});
// Calculate commission (if applicable, based on RMB amount)
// Calculate commission (if applicable, for any currency)
let commission = null;
if (totalAmountForCommission > 0) {
try {

View File

@ -124,8 +124,8 @@
<text class="table-cell">{{ item.uid }}</text>
<text class="table-cell">{{ item.time }}</text>
<view class="table-cell status-cell">
<text v-if="item.paid && item.amount" class="paid-amount">¥{{ item.amount }}</text>
<text v-else class="unpaid-text">¥0</text>
<text class="paid-amount">¥{{ (item.rewardRmb || 0).toFixed(2) }}</text>
<text class="paid-amount peso">{{ (item.rewardPeso || 0).toFixed(2) }}</text>
</view>
</view>
</view>
@ -468,13 +468,20 @@
console.log('GetInvitationRecords response:', res)
// : { code: 0, message: "", data: { records: [...] } }
if (res && res.code === 0 && res.data && res.data.records) {
this.inviteRecords = res.data.records.map(item => ({
username: item.invitee?.nickname || '-',
uid: item.invitee?.uid || '-',
time: this.formatDate(item.createdAt),
paid: item.firstPaymentAt != null,
amount: item.rewardAmount ? parseFloat(item.rewardAmount) : 0
}))
this.inviteRecords = res.data.records.map(item => {
const rewardRmb = parseFloat(item.rewardAmountRmb || 0)
const rewardPeso = parseFloat(item.rewardAmountPeso || 0)
return {
username: item.invitee?.nickname || '-',
uid: item.invitee?.uid || '-',
time: this.formatDate(item.createdAt),
paid: item.firstPaymentAt != null,
rewardRmb: rewardRmb,
rewardPeso: rewardPeso,
// Legacy field
amount: item.rewardAmount ? parseFloat(item.rewardAmount) : 0
}
})
}
} catch (error) {
console.error('获取邀请记录失败:', error)
@ -1305,13 +1312,18 @@
&.status-cell {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.paid-amount {
font-size: 28rpx;
font-size: 26rpx;
font-weight: bold;
color: #333333;
color: #FF3B4E;
&.peso {
color: #67c23a;
}
}
.unpaid-text {