提现.
This commit is contained in:
parent
c79e164f87
commit
1b0cc39255
|
|
@ -595,7 +595,9 @@ function formatPaymentDetails(method, details) {
|
|||
case 'alipay':
|
||||
return parsed.alipayAccount || parsed.account || '-'
|
||||
case 'bank':
|
||||
return parsed.bankAccount ? `****${parsed.bankAccount.slice(-4)}` : '-'
|
||||
// 支持两种字段名: bankCardNumber (小程序) 和 bankAccount (旧版)
|
||||
const bankAccountNum = parsed.bankCardNumber || parsed.bankAccount
|
||||
return bankAccountNum ? `****${bankAccountNum.slice(-4)}` : '-'
|
||||
default:
|
||||
return '-'
|
||||
}
|
||||
|
|
@ -614,10 +616,16 @@ function formatPaymentDetailsLong(method, details) {
|
|||
case 'alipay':
|
||||
return `支付宝账号: ${parsed.alipayAccount || parsed.account || '-'}`
|
||||
case 'bank':
|
||||
// 支持两种字段名: 小程序使用 bankCardNumber/cardholderName, 旧版使用 bankAccount/accountName
|
||||
const bankName = parsed.bankName || '银行'
|
||||
const account = parsed.bankAccount || '-'
|
||||
const name = parsed.accountName || '-'
|
||||
return `${bankName} | 账号: ${account} | 户名: ${name}`
|
||||
const account = parsed.bankCardNumber || parsed.bankAccount || '-'
|
||||
const name = parsed.cardholderName || parsed.accountName || '-'
|
||||
const swiftCode = parsed.swiftCode
|
||||
let result = `${bankName} | 账号: ${account} | 户名: ${name}`
|
||||
if (swiftCode) {
|
||||
result += ` | SWIFT: ${swiftCode}`
|
||||
}
|
||||
return result
|
||||
default:
|
||||
return JSON.stringify(parsed)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ const approveWithdrawal = async (withdrawalId, adminId, notes = '') => {
|
|||
{
|
||||
model: User,
|
||||
as: 'user',
|
||||
attributes: ['id', 'balance'],
|
||||
attributes: ['id', 'balance', 'balancePeso'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
@ -140,31 +140,7 @@ const approveWithdrawal = async (withdrawalId, adminId, notes = '') => {
|
|||
throw new Error(`Cannot approve withdrawal with status: ${withdrawal.status}`);
|
||||
}
|
||||
|
||||
// Get user with lock
|
||||
const user = await User.findByPk(withdrawal.userId, {
|
||||
transaction,
|
||||
lock: transaction.LOCK.UPDATE,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
// Check if user has sufficient balance
|
||||
const withdrawalAmount = parseFloat(withdrawal.amount);
|
||||
const userBalance = parseFloat(user.balance);
|
||||
|
||||
if (userBalance < withdrawalAmount) {
|
||||
throw new Error('User has insufficient balance');
|
||||
}
|
||||
|
||||
// Update user balance
|
||||
const newBalance = userBalance - withdrawalAmount;
|
||||
await user.update({
|
||||
balance: newBalance,
|
||||
}, { transaction });
|
||||
|
||||
// Update withdrawal status
|
||||
// Update withdrawal status (balance was already deducted when user submitted the request)
|
||||
await withdrawal.update({
|
||||
status: 'completed',
|
||||
reviewedBy: adminId,
|
||||
|
|
@ -176,15 +152,23 @@ const approveWithdrawal = async (withdrawalId, adminId, notes = '') => {
|
|||
|
||||
logger.info(`Withdrawal ${withdrawal.withdrawalNo} approved by admin ${adminId}`);
|
||||
|
||||
// Get current user balance for response
|
||||
const user = withdrawal.user;
|
||||
const currency = withdrawal.currency || 'CNY';
|
||||
const currentBalance = currency === 'PHP'
|
||||
? parseFloat(user?.balancePeso || 0).toFixed(2)
|
||||
: parseFloat(user?.balance || 0).toFixed(2);
|
||||
|
||||
return {
|
||||
id: withdrawal.id,
|
||||
withdrawalNo: withdrawal.withdrawalNo,
|
||||
amount: parseFloat(withdrawal.amount).toFixed(2),
|
||||
currency: currency,
|
||||
status: withdrawal.status,
|
||||
reviewedBy: withdrawal.reviewedBy,
|
||||
reviewedAt: withdrawal.reviewedAt,
|
||||
completedAt: withdrawal.completedAt,
|
||||
userBalance: newBalance.toFixed(2),
|
||||
userBalance: currentBalance,
|
||||
};
|
||||
} catch (error) {
|
||||
await transaction.rollback();
|
||||
|
|
@ -223,6 +207,27 @@ const rejectWithdrawal = async (withdrawalId, adminId, reason) => {
|
|||
throw new Error(`Cannot reject withdrawal with status: ${withdrawal.status}`);
|
||||
}
|
||||
|
||||
// Get user with lock to refund the balance
|
||||
const user = await User.findByPk(withdrawal.userId, {
|
||||
transaction,
|
||||
lock: transaction.LOCK.UPDATE,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
// Refund the withdrawal amount to user balance based on currency
|
||||
const withdrawalAmount = parseFloat(withdrawal.amount);
|
||||
const currency = withdrawal.currency || 'CNY';
|
||||
|
||||
if (currency === 'PHP') {
|
||||
user.balancePeso = parseFloat(user.balancePeso || 0) + withdrawalAmount;
|
||||
} else {
|
||||
user.balance = parseFloat(user.balance || 0) + withdrawalAmount;
|
||||
}
|
||||
await user.save({ transaction });
|
||||
|
||||
// Update withdrawal status
|
||||
await withdrawal.update({
|
||||
status: 'rejected',
|
||||
|
|
@ -233,12 +238,13 @@ const rejectWithdrawal = async (withdrawalId, adminId, reason) => {
|
|||
|
||||
await transaction.commit();
|
||||
|
||||
logger.info(`Withdrawal ${withdrawal.withdrawalNo} rejected by admin ${adminId}`);
|
||||
logger.info(`Withdrawal ${withdrawal.withdrawalNo} rejected by admin ${adminId}, amount refunded to user`);
|
||||
|
||||
return {
|
||||
id: withdrawal.id,
|
||||
withdrawalNo: withdrawal.withdrawalNo,
|
||||
amount: parseFloat(withdrawal.amount).toFixed(2),
|
||||
currency: currency,
|
||||
status: withdrawal.status,
|
||||
reviewedBy: withdrawal.reviewedBy,
|
||||
reviewedAt: withdrawal.reviewedAt,
|
||||
|
|
|
|||
|
|
@ -108,6 +108,16 @@ const createWithdrawal = async (userId, withdrawalData) => {
|
|||
status: 'waiting',
|
||||
}, { transaction });
|
||||
|
||||
// Deduct amount from user balance based on currency
|
||||
if (currency === 'PHP') {
|
||||
user.balancePeso = parseFloat(user.balancePeso || 0) - withdrawalAmount;
|
||||
if (user.balancePeso < 0) user.balancePeso = 0;
|
||||
} else {
|
||||
user.balance = parseFloat(user.balance || 0) - withdrawalAmount;
|
||||
if (user.balance < 0) user.balance = 0;
|
||||
}
|
||||
await user.save({ transaction });
|
||||
|
||||
await transaction.commit();
|
||||
|
||||
return withdrawal;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ If you have privacy questions, please contact us through the application.`
|
|||
enterAmount: 'Please enter withdraw amount',
|
||||
enterPlaceholder: 'Please enter',
|
||||
amountHint: 'Minimum 1 yuan per time',
|
||||
availableWithdraw: 'Available',
|
||||
nextStep: 'Next Step',
|
||||
selectPaymentMethod: 'Please select payment method',
|
||||
wechat: 'WeChat',
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ Si tiene preguntas sobre privacidad, contáctenos a través de la aplicación.`
|
|||
enterAmount: 'Por favor, ingrese el monto del retiro',
|
||||
enterPlaceholder: 'Por favor, ingrese',
|
||||
amountHint: 'Mínimo 1 yuan por vez',
|
||||
availableWithdraw: 'Disponible',
|
||||
nextStep: 'Siguiente Paso',
|
||||
selectPaymentMethod: 'Por favor, seleccione el método de pago',
|
||||
wechat: 'WeChat',
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ export default {
|
|||
enterAmount: '请输入提现金额',
|
||||
enterPlaceholder: '请输入',
|
||||
amountHint: '每次最低1元',
|
||||
availableWithdraw: '可提现',
|
||||
nextStep: '下一步',
|
||||
selectPaymentMethod: '请选择收款方式',
|
||||
wechat: '微信',
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@
|
|||
:placeholder="$t('invite.enterPlaceholder')" />
|
||||
<text class="currency-text">{{ withdrawCurrency === 'CNY' ? '¥' : '₱' }}</text>
|
||||
</view>
|
||||
<text class="amount-hint">{{ $t('invite.amountHint') }},{{ withdrawCurrency === 'PHP' ? '₱' : '¥' }}{{ currentAvailableBalance }}</text>
|
||||
<text class="amount-hint">{{ $t('invite.amountHint') }},{{ $t('invite.availableWithdraw') || '可提现' }}{{ withdrawCurrency === 'PHP' ? '₱' : '¥' }}{{ currentAvailableBalance }}</text>
|
||||
|
||||
<view class="apply-btn" @click="nextStep">
|
||||
<text class="apply-btn-text">{{ $t('invite.nextStep') }}</text>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user