'use strict'; const balanceUtil = require('./util.js'); const merchantMap = balanceUtil.MERCHANT_MAP; module.exports = { /** * 提现 * @url admin/finance/balance/sys/withdraw 前端调用的url参数地址 */ main: async (event) => { let { data = {}, userInfo, util } = event; let { vk } = util; const transaction = await vk.baseDao.startTransaction(); try { const merchantId = String(data.merchantId || '').trim(); if (!merchantMap[merchantId]) { throw new Error('提现商户不正确'); } const amount = balanceUtil.normalizeAmount(data.amount); if (amount <= 0) { throw new Error('提现金额必须大于0'); } const balanceRecord = await balanceUtil.ensureBalanceRecord({ transaction, vk }); const balanceInfoMap = balanceUtil.buildBalanceInfoMap(balanceRecord.balanceInfo || {}); const merchantBalanceInfo = balanceInfoMap[merchantId] || { accNo: merchantId, merchantName: merchantMap[merchantId], balance: 0, updateTime: '' }; const merchantBalance = balanceUtil.normalizeAmount(merchantBalanceInfo.balance || 0); const { pendingAmount, availableBalance } = await balanceUtil.getAvailableWithdrawBalance({ transaction, vk, merchantId, merchantBalance }); if (availableBalance <= 0) { throw new Error( pendingAmount > 0 ? `可提现余额不足(处理中提现¥${pendingAmount.toFixed(2)}已占用)` : '当前企业余额小于等于0,无法提现' ); } if (amount > availableBalance) { throw new Error( pendingAmount > 0 ? `提现金额不能大于可提现余额¥${availableBalance.toFixed(2)}(已排除处理中提现¥${pendingAmount.toFixed(2)})` : '提现金额不能大于当前企业余额' ); } const description = String(data.description || '').trim() || `余额提现-${merchantMap[merchantId]}`; const requestRes = await vk.request({ method: "POST", url: 'http://jjx-union-pay.gxwebsoft.com/api/union-pay-jjx/transByAmount', header: { "content-type": "application/json; charset=utf-8", }, data: { accNo: merchantId, amount }, timeout: 60000 }); console.log('requestRes', requestRes) const code = Number(requestRes && requestRes.code); const success = requestRes && ( code === 0 || code === 200 || requestRes.success === true || (typeof requestRes.code === 'undefined' && !requestRes.msg && !requestRes.message) ); if (!success) { throw new Error( (requestRes && (requestRes.msg || requestRes.message)) || (requestRes && requestRes.content && (requestRes.content.msg || requestRes.content.message)) || '提现失败' ); } const logData = { description, amount, type: 'expense', logTime: Date.now(), operatorId: userInfo && userInfo.uid ? userInfo.uid : '', source: 'withdraw', merchantId, merchantName: merchantMap[merchantId], srcReqId: requestRes.srcReqId, status: 1, // 新逻辑:处理中不扣余额,成功后再扣;用于兼容旧数据(旧单默认已扣) balanceDeducted: false }; await vk.baseDao.add({ db: transaction, dbName: 'jjx-balance-log', dataJson: logData }); // 处理中提现不立刻扣减余额缓存,避免与远端余额同步互相覆盖; // 可提现额度通过「余额 - 处理中提现」计算,防止重复提现超总额。 await transaction.commit(); return { code: 0, msg: '', data: { balance: merchantBalance, pendingAmount: balanceUtil.normalizeAmount(pendingAmount + amount), availableBalance: balanceUtil.normalizeAmount(Math.max(0, availableBalance - amount)), merchantBalance } }; } catch (err) { return await balanceUtil.rollbackTransaction({ transaction, err }); } } };