Files
jjx-web/uniCloud-tcb/cloudfunctions/router/service/admin/finance/balance/sys/withdraw.js
T
b2894lxlx b341d6ad97 fix: 提现排除处理中金额,选择报价改为重点提示
可提现额度扣除处理中提现,避免重复提现超总额;收到报价选择供应商时展示重点提示而非服务费提示。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-11 00:48:08 +08:00

131 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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
});
}
}
};