修改商城逻辑

This commit is contained in:
2025-08-28 09:14:56 +08:00
parent a1944a573e
commit 691789d5d3
28 changed files with 10842 additions and 292 deletions

View File

@@ -696,7 +696,7 @@ class MatchingService {
FROM users u
WHERE u.is_system_account = FALSE
AND u.id != ?
AND u.balance < 0
AND u.balance < -100
AND u.audit_status = 'approved'
ORDER BY u.balance ASC`,
[excludeUserId]
@@ -811,18 +811,18 @@ class MatchingService {
if (range <= 0) {
maxUserAllocation = minAmount;
} else {
// 使用极度偏向大值的策略
const randomFactor = Math.pow(Math.random(), 0.15); // 0.15的幂使分布极度偏向较大值
// 使用更均匀的分配策略
const randomFactor = Math.random(); // 使用均匀分布
// 基础分配:从range的80%开始,确保大部分分配都是较大值
const baseOffset = Math.floor(range * 0.8); // 80%的基础偏移
// 基础分配:在整个范围内更均匀分布,减少偏向性
const baseOffset = Math.floor(range * 0.15); // 降低到15%的基础偏移
const adjustedRange = range - baseOffset;
maxUserAllocation = Math.floor(randomFactor * adjustedRange) + minAmount + baseOffset;
// 几乎总是给予额外增量
const bonusRange = Math.min(range * 0.6, maxRandomAllocation - maxUserAllocation); // 增加到60%
if (bonusRange > 0 && Math.random() > 0.1) { // 90%概率获得额外增量
const bonus = Math.floor(Math.random() * bonusRange * 0.9); // 使用90%的bonus范围
// 进一步减少额外增量的影响
const bonusRange = Math.min(range * 0.1, maxRandomAllocation - maxUserAllocation); // 降低到10%
if (bonusRange > 0 && Math.random() > 0.7) { // 30%概率获得额外增量,进一步降低
const bonus = Math.floor(Math.random() * bonusRange * 0.3); // 使用30%的bonus范围
maxUserAllocation += bonus;
}
@@ -921,7 +921,7 @@ class MatchingService {
}
/**
* 生成随机分配金额数组
* 生成随机分配金额数组(更均匀的分配策略)
* @param {number} totalAmount - 总金额
* @param {number} transferCount - 分配笔数
* @param {number} minAmount - 最小金额
@@ -933,148 +933,87 @@ class MatchingService {
return [];
}
// 使用更均匀的分配策略
const amounts = [];
let remainingAmount = totalAmount;
// 为前n-1笔生成随机金额
for (let i = 0; i < transferCount - 1; i++) {
const remainingTransfers = transferCount - i;
const minForThisTransfer = minAmount;
const maxForThisTransfer = Math.min(
maxAmount,
remainingAmount - (remainingTransfers - 1) * minAmount // 确保剩余金额足够分配给后续转账
);
if (maxForThisTransfer < minForThisTransfer) {
// 如果无法满足约束,重新开始整个分配过程
return this.generateRandomAmountsWithRetry(totalAmount, transferCount, minAmount, maxAmount);
} else {
// 在有效范围内生成随机金额
const randomAmount = Math.floor(Math.random() * (maxForThisTransfer - minForThisTransfer + 1)) + minForThisTransfer;
amounts.push(randomAmount);
}
remainingAmount -= amounts[amounts.length - 1];
}
// 最后一笔分配剩余金额
if (remainingAmount >= minAmount && remainingAmount <= maxAmount) {
amounts.push(remainingAmount);
} else {
// 如果剩余金额不符合约束,使用重试机制
return this.generateRandomAmountsWithRetry(totalAmount, transferCount, minAmount, maxAmount);
}
return amounts;
}
/**
* 使用重试机制生成随机金额分配(确保完全随机性)
* @param {number} totalAmount - 总金额
* @param {number} transferCount - 分配笔数
* @param {number} minAmount - 最小金额
* @param {number} maxAmount - 最大金额
* @returns {number[]} 随机金额数组
*/
generateRandomAmountsWithRetry(totalAmount, transferCount, minAmount, maxAmount) {
const maxRetries = 100;
for (let retry = 0; retry < maxRetries; retry++) {
const amounts = [];
let remainingAmount = totalAmount;
let success = true;
// 为前n-1笔生成随机金额
for (let i = 0; i < transferCount - 1; i++) {
const remainingTransfers = transferCount - i;
const minForThisTransfer = minAmount;
const maxForThisTransfer = Math.min(
maxAmount,
remainingAmount - (remainingTransfers - 1) * minAmount
);
if (maxForThisTransfer < minForThisTransfer) {
success = false;
break;
}
// 在有效范围内生成随机金额
const randomAmount = Math.floor(Math.random() * (maxForThisTransfer - minForThisTransfer + 1)) + minForThisTransfer;
amounts.push(randomAmount);
remainingAmount -= randomAmount;
}
// 检查最后一笔是否符合约束
if (success && remainingAmount >= minAmount && remainingAmount <= maxAmount) {
amounts.push(remainingAmount);
return amounts;
}
}
// 如果重试失败,使用备用的随机分配策略
return this.generateFallbackRandomAmounts(totalAmount, transferCount, minAmount, maxAmount);
}
/**
* 备用随机分配策略(保证随机性的最后手段)
* @param {number} totalAmount - 总金额
* @param {number} transferCount - 分配笔数
* @param {number} minAmount - 最小金额
* @param {number} maxAmount - 最大金额
* @returns {number[]} 随机金额数组
*/
generateFallbackRandomAmounts(totalAmount, transferCount, minAmount, maxAmount) {
// 检查是否可能分配
if (totalAmount < minAmount * transferCount || totalAmount > maxAmount * transferCount) {
return [];
}
const amounts = [];
// 首先为每笔分配最小金额
for (let i = 0; i < transferCount; i++) {
amounts.push(minAmount);
}
let remainingToDistribute = totalAmount - (minAmount * transferCount);
// 随机分配剩余金额,确保不超过最大限制
// 计算平均每笔应该额外分配的金额
const averageExtra = Math.floor(remainingToDistribute / transferCount);
// 为每笔添加平均额外金额,但加入一些随机性
for (let i = 0; i < transferCount && remainingToDistribute > 0; i++) {
// 计算这笔最多还能增加多少不超过maxAmount
const maxPossibleIncrease = Math.min(
maxAmount - amounts[i],
remainingToDistribute
);
if (maxPossibleIncrease > 0) {
// 在平均值附近随机分配,但控制在更小的范围内以保证更均匀
const baseIncrease = Math.min(averageExtra, maxPossibleIncrease);
const randomVariation = Math.floor(baseIncrease * 0.15); // 减少到15%的随机变化
const minIncrease = Math.max(0, baseIncrease - randomVariation);
const maxIncrease = Math.min(maxPossibleIncrease, baseIncrease + randomVariation);
const increase = Math.floor(Math.random() * (maxIncrease - minIncrease + 1)) + minIncrease;
amounts[i] += increase;
remainingToDistribute -= increase;
}
}
// 如果还有剩余金额,尽量均匀分配给还能接受的笔数
while (remainingToDistribute > 0) {
// 找到所有还能增加金额的位置
const availableIndices = [];
for (let i = 0; i < transferCount; i++) {
if (amounts[i] < maxAmount) {
availableIndices.push(i);
}
}
// 如果没有可用位置,说明无法继续分配
if (availableIndices.length === 0) {
break; // 无法继续分配
}
// 计算每个可用位置应该分配多少
const perIndexAmount = Math.floor(remainingToDistribute / availableIndices.length);
const remainder = remainingToDistribute % availableIndices.length;
// 为每个可用位置分配相等的金额
for (let i = 0; i < availableIndices.length && remainingToDistribute > 0; i++) {
const index = availableIndices[i];
const maxIncrease = Math.min(maxAmount - amounts[index], remainingToDistribute);
if (maxIncrease > 0) {
// 基础分配金额
let increase = Math.min(perIndexAmount, maxIncrease);
// 如果是前几个位置,额外分配余数
if (i < remainder) {
increase = Math.min(increase + 1, maxIncrease);
}
amounts[index] += increase;
remainingToDistribute -= increase;
}
}
// 如果所有位置都已达到最大值,退出循环
if (perIndexAmount === 0 && remainder === 0) {
break;
}
// 随机选择一个可用位置
const randomIndex = availableIndices[Math.floor(Math.random() * availableIndices.length)];
// 计算这个位置最多还能增加多少
const maxIncrease = Math.min(
maxAmount - amounts[randomIndex],
remainingToDistribute
);
if (maxIncrease > 0) {
// 随机增加1到maxIncrease之间的金额
const increase = Math.floor(Math.random() * maxIncrease) + 1;
amounts[randomIndex] += increase;
remainingToDistribute -= increase;
}
}
// 如果还有剩余金额无法分配,说明约束条件无法满足
// 如果还有剩余金额无法分配,返回空数组表示失败
if (remainingToDistribute > 0) {
return [];
}
return amounts;
}