From 1b0cc392551f7cacb4f914a3d9cda68b298b0319 Mon Sep 17 00:00:00 2001 From: 18631081161 <2088094923@qq.com> Date: Wed, 24 Dec 2025 16:26:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E7=8E=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/src/views/withdrawals/index.vue | 16 +++-- .../src/services/adminWithdrawalService.js | 62 ++++++++++--------- backend/src/services/withdrawalService.js | 10 +++ miniprogram/src/locale/en.js | 1 + miniprogram/src/locale/es.js | 1 + miniprogram/src/locale/zh.js | 1 + .../src/pages/me/invite-reward-page.vue | 2 +- 7 files changed, 60 insertions(+), 33 deletions(-) diff --git a/admin/src/views/withdrawals/index.vue b/admin/src/views/withdrawals/index.vue index 4d02160..05c12a2 100644 --- a/admin/src/views/withdrawals/index.vue +++ b/admin/src/views/withdrawals/index.vue @@ -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) } diff --git a/backend/src/services/adminWithdrawalService.js b/backend/src/services/adminWithdrawalService.js index 1480a50..0aa925d 100644 --- a/backend/src/services/adminWithdrawalService.js +++ b/backend/src/services/adminWithdrawalService.js @@ -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, diff --git a/backend/src/services/withdrawalService.js b/backend/src/services/withdrawalService.js index 478a978..a84702b 100644 --- a/backend/src/services/withdrawalService.js +++ b/backend/src/services/withdrawalService.js @@ -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; diff --git a/miniprogram/src/locale/en.js b/miniprogram/src/locale/en.js index e7e4be8..c7df088 100644 --- a/miniprogram/src/locale/en.js +++ b/miniprogram/src/locale/en.js @@ -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', diff --git a/miniprogram/src/locale/es.js b/miniprogram/src/locale/es.js index 0670f96..587d627 100644 --- a/miniprogram/src/locale/es.js +++ b/miniprogram/src/locale/es.js @@ -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', diff --git a/miniprogram/src/locale/zh.js b/miniprogram/src/locale/zh.js index 223a33a..b1726ea 100644 --- a/miniprogram/src/locale/zh.js +++ b/miniprogram/src/locale/zh.js @@ -223,6 +223,7 @@ export default { enterAmount: '请输入提现金额', enterPlaceholder: '请输入', amountHint: '每次最低1元', + availableWithdraw: '可提现', nextStep: '下一步', selectPaymentMethod: '请选择收款方式', wechat: '微信', diff --git a/miniprogram/src/pages/me/invite-reward-page.vue b/miniprogram/src/pages/me/invite-reward-page.vue index e52cd07..a482aa3 100644 --- a/miniprogram/src/pages/me/invite-reward-page.vue +++ b/miniprogram/src/pages/me/invite-reward-page.vue @@ -235,7 +235,7 @@ :placeholder="$t('invite.enterPlaceholder')" /> {{ withdrawCurrency === 'CNY' ? '¥' : '₱' }} - {{ $t('invite.amountHint') }},{{ withdrawCurrency === 'PHP' ? '₱' : '¥' }}{{ currentAvailableBalance }} + {{ $t('invite.amountHint') }},{{ $t('invite.availableWithdraw') || '可提现' }}{{ withdrawCurrency === 'PHP' ? '₱' : '¥' }}{{ currentAvailableBalance }} {{ $t('invite.nextStep') }}