fix(batch-mining): 修正补发计算逻辑
- 去掉虚构的'全网算力'概念 - 每天固定分配70%产出给参与用户 - 用户收益 = 每日产出 × 70% × 天数 × (用户算力/当前参与总算力) - 总补发金额固定为: 日产出 × 70% × 总天数 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
702fa937e8
commit
f14ad0b7ad
|
|
@ -89,8 +89,8 @@ export interface BatchMiningPreviewResult {
|
|||
// 常量
|
||||
const BASE_CONTRIBUTION_PER_TREE = new Decimal('22617'); // 每棵树的基础算力
|
||||
const SECONDS_PER_DAY = 86400;
|
||||
// 用户算力占全网算力的比例(用户占70%,30%是系统、运营、层级、团队的)
|
||||
const USER_NETWORK_RATIO = new Decimal('0.70');
|
||||
// 每天产出的70%分给补发用户
|
||||
const DAILY_DISTRIBUTION_RATIO = new Decimal('0.70');
|
||||
|
||||
/**
|
||||
* 挖矿阶段信息
|
||||
|
|
@ -100,7 +100,7 @@ interface MiningPhase {
|
|||
startDate: Date;
|
||||
endDate: Date;
|
||||
daysInPhase: number;
|
||||
networkContribution: Decimal; // 该阶段的全网算力
|
||||
participatingContribution: Decimal; // 该阶段参与用户的总算力
|
||||
participatingBatches: number[]; // 参与该阶段的批次号
|
||||
}
|
||||
|
||||
|
|
@ -109,9 +109,9 @@ interface MiningPhase {
|
|||
*
|
||||
* 核心逻辑(分阶段计算):
|
||||
* 1. 根据各批次的挖矿开始时间,划分挖矿阶段
|
||||
* 2. 每个阶段有不同的全网算力(随着新批次加入而增加)
|
||||
* 3. 用户算力 = 认种棵数 × 基础算力/棵 × 70%
|
||||
* 4. 用户在每个阶段的收益 = (用户算力 / 该阶段全网算力) × 每秒分配量 × 阶段天数 × 86400
|
||||
* 2. 每天产出的70%固定分给当前参与的用户
|
||||
* 3. 用户算力 = 认种棵数 × 基础算力/棵
|
||||
* 4. 用户在每个阶段的收益 = 每日产出 × 70% × 阶段天数 × (用户算力 / 当前参与总算力)
|
||||
* 5. 用户总收益 = 用户参与的各阶段收益之和
|
||||
*/
|
||||
@Injectable()
|
||||
|
|
@ -196,18 +196,23 @@ export class BatchMiningService {
|
|||
}
|
||||
|
||||
// 定义挖矿阶段
|
||||
// 阶段1: 批次1独挖3天
|
||||
// 阶段2: 批次1+2共挖2天
|
||||
// 阶段3: 批次1+2+3共挖1天
|
||||
// 阶段4: 所有批次共挖(剩余天数)
|
||||
// 阶段1: 批次1独挖 preMineDays 天
|
||||
// 阶段2: 批次1+2共挖 preMineDays 天
|
||||
// ...依次类推
|
||||
// 最后阶段: 所有批次共挖(剩余天数)
|
||||
const phases = this.buildMiningPhases(items, sortedBatches, batchContributions);
|
||||
this.logger.log(`[preview] 挖矿阶段: ${JSON.stringify(phases.map(p => ({
|
||||
phase: p.phaseNumber,
|
||||
days: p.daysInPhase,
|
||||
batches: p.participatingBatches,
|
||||
networkContribution: p.networkContribution.toFixed(2)
|
||||
participatingContribution: p.participatingContribution.toFixed(2)
|
||||
})))}`);
|
||||
|
||||
// 每天补发额度 = 日产出 × 70%
|
||||
const dailyDistribution = secondDistribution.times(SECONDS_PER_DAY);
|
||||
const dailyAllocation = dailyDistribution.times(DAILY_DISTRIBUTION_RATIO);
|
||||
this.logger.log(`[preview] 每日产出: ${dailyDistribution.toFixed(8)}, 每日补发额度(70%): ${dailyAllocation.toFixed(8)}`);
|
||||
|
||||
// 计算每个用户在各阶段的收益
|
||||
const userAmounts = new Map<string, Decimal>();
|
||||
for (const item of items) {
|
||||
|
|
@ -215,15 +220,16 @@ export class BatchMiningService {
|
|||
}
|
||||
|
||||
for (const phase of phases) {
|
||||
const dailyDistribution = secondDistribution.times(SECONDS_PER_DAY);
|
||||
const phaseDistribution = dailyDistribution.times(phase.daysInPhase);
|
||||
// 该阶段的总补发额 = 每日补发额度 × 阶段天数
|
||||
const phaseAllocation = dailyAllocation.times(phase.daysInPhase);
|
||||
|
||||
for (const item of items) {
|
||||
// 检查该用户的批次是否参与此阶段
|
||||
if (phase.participatingBatches.includes(item.batch)) {
|
||||
const userContribution = userContributions.get(item.accountSequence)!;
|
||||
const ratio = userContribution.dividedBy(phase.networkContribution);
|
||||
const phaseAmount = phaseDistribution.times(ratio);
|
||||
// 用户收益 = 阶段补发额 × (用户算力 / 当前参与总算力)
|
||||
const ratio = userContribution.dividedBy(phase.participatingContribution);
|
||||
const phaseAmount = phaseAllocation.times(ratio);
|
||||
|
||||
const currentAmount = userAmounts.get(item.accountSequence)!;
|
||||
userAmounts.set(item.accountSequence, currentAmount.plus(phaseAmount));
|
||||
|
|
@ -235,14 +241,12 @@ export class BatchMiningService {
|
|||
let grandTotalAmount = new Decimal(0);
|
||||
const batchResults: BatchMiningPreviewResult['batches'] = [];
|
||||
|
||||
// 计算累计全网算力(最终状态)
|
||||
// 用户只占全网的70%(30%是系统、运营、层级、团队),所以全网算力 = 用户算力 / 0.7
|
||||
// 计算用户总算力(用于显示)
|
||||
let totalUserContribution = new Decimal(0);
|
||||
for (const contribution of batchContributions.values()) {
|
||||
totalUserContribution = totalUserContribution.plus(contribution);
|
||||
}
|
||||
const finalNetworkContribution = totalUserContribution.dividedBy(USER_NETWORK_RATIO);
|
||||
this.logger.log(`[preview] 用户总算力: ${totalUserContribution.toFixed(2)}, 全网算力(用户占70%): ${finalNetworkContribution.toFixed(2)}`);
|
||||
this.logger.log(`[preview] 用户总算力: ${totalUserContribution.toFixed(2)}`);
|
||||
|
||||
for (const batchNum of sortedBatches) {
|
||||
const batchItems = batchGroups.get(batchNum)!;
|
||||
|
|
@ -254,14 +258,15 @@ export class BatchMiningService {
|
|||
for (const item of batchItems) {
|
||||
const userContribution = userContributions.get(item.accountSequence)!;
|
||||
const amount = userAmounts.get(item.accountSequence)!;
|
||||
const ratio = userContribution.dividedBy(finalNetworkContribution);
|
||||
// 显示用:用户算力占总用户算力的比例
|
||||
const ratio = userContribution.dividedBy(totalUserContribution);
|
||||
|
||||
users.push({
|
||||
accountSequence: item.accountSequence,
|
||||
treeCount: item.treeCount,
|
||||
preMineDays: item.preMineDays,
|
||||
userContribution: userContribution.toFixed(10),
|
||||
networkContribution: finalNetworkContribution.toFixed(10),
|
||||
networkContribution: totalUserContribution.toFixed(10), // 显示总用户算力
|
||||
contributionRatio: ratio.toFixed(18),
|
||||
totalSeconds: (item.preMineDays * SECONDS_PER_DAY).toString(),
|
||||
estimatedAmount: amount.toFixed(8),
|
||||
|
|
@ -367,25 +372,22 @@ export class BatchMiningService {
|
|||
const phaseDays = currentPreMineDays;
|
||||
|
||||
if (phaseDays > 0) {
|
||||
// 计算该阶段参与用户的算力
|
||||
// 计算该阶段参与用户的总算力
|
||||
let participatingContribution = new Decimal(0);
|
||||
for (const batch of participatingBatches) {
|
||||
participatingContribution = participatingContribution.plus(batchContributions.get(batch) || 0);
|
||||
}
|
||||
// 实际全网算力 = 参与用户算力 / 用户占比
|
||||
// 因为用户只占全网的70%(30%是系统、运营、层级、团队),所以全网算力 = 用户算力 / 0.7
|
||||
const networkContribution = participatingContribution.dividedBy(USER_NETWORK_RATIO);
|
||||
|
||||
phases.push({
|
||||
phaseNumber: currentPhase,
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
daysInPhase: phaseDays,
|
||||
networkContribution,
|
||||
participatingContribution,
|
||||
participatingBatches: [...participatingBatches],
|
||||
});
|
||||
|
||||
this.logger.log(`[buildMiningPhases] 阶段${currentPhase}: ${phaseDays}天, 批次[${participatingBatches.join(',')}], 参与算力=${participatingContribution.toFixed(2)}, 全网算力=${networkContribution.toFixed(2)}`);
|
||||
this.logger.log(`[buildMiningPhases] 阶段${currentPhase}: ${phaseDays}天, 批次[${participatingBatches.join(',')}], 参与算力=${participatingContribution.toFixed(2)}`);
|
||||
currentPhase++;
|
||||
usedDays += phaseDays;
|
||||
}
|
||||
|
|
@ -399,19 +401,17 @@ export class BatchMiningService {
|
|||
for (const batch of sortedBatches) {
|
||||
participatingContribution = participatingContribution.plus(batchContributions.get(batch) || 0);
|
||||
}
|
||||
// 实际全网算力 = 参与用户算力 / 用户占比
|
||||
const networkContribution = participatingContribution.dividedBy(USER_NETWORK_RATIO);
|
||||
|
||||
phases.push({
|
||||
phaseNumber: currentPhase,
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
daysInPhase: remainingDays,
|
||||
networkContribution,
|
||||
participatingContribution,
|
||||
participatingBatches: [...sortedBatches],
|
||||
});
|
||||
|
||||
this.logger.log(`[buildMiningPhases] 阶段${currentPhase}(最终): ${remainingDays}天, 所有批次[${sortedBatches.join(',')}], 参与算力=${participatingContribution.toFixed(2)}, 全网算力=${networkContribution.toFixed(2)}`);
|
||||
this.logger.log(`[buildMiningPhases] 阶段${currentPhase}(最终): ${remainingDays}天, 所有批次[${sortedBatches.join(',')}], 参与算力=${participatingContribution.toFixed(2)}`);
|
||||
}
|
||||
|
||||
return phases;
|
||||
|
|
@ -447,7 +447,57 @@ export class BatchMiningService {
|
|||
const batchGroups = this.groupByBatch(items);
|
||||
const sortedBatches = Array.from(batchGroups.keys()).sort((a, b) => a - b);
|
||||
|
||||
let cumulativeContribution = new Decimal(0);
|
||||
// 计算每个批次的算力
|
||||
const batchContributions = new Map<number, Decimal>();
|
||||
for (const batchNum of sortedBatches) {
|
||||
const batchItems = batchGroups.get(batchNum)!;
|
||||
let batchTotal = new Decimal(0);
|
||||
for (const item of batchItems) {
|
||||
batchTotal = batchTotal.plus(this.calculateUserContribution(item.treeCount));
|
||||
}
|
||||
batchContributions.set(batchNum, batchTotal);
|
||||
}
|
||||
|
||||
// 计算每个用户的算力
|
||||
const userContributions = new Map<string, Decimal>();
|
||||
for (const item of items) {
|
||||
userContributions.set(item.accountSequence, this.calculateUserContribution(item.treeCount));
|
||||
}
|
||||
|
||||
// 构建挖矿阶段
|
||||
const phases = this.buildMiningPhases(items, sortedBatches, batchContributions);
|
||||
|
||||
// 每天补发额度 = 日产出 × 70%
|
||||
const dailyDistribution = secondDistribution.times(SECONDS_PER_DAY);
|
||||
const dailyAllocation = dailyDistribution.times(DAILY_DISTRIBUTION_RATIO);
|
||||
|
||||
// 计算每个用户在各阶段的收益
|
||||
const userAmounts = new Map<string, Decimal>();
|
||||
for (const item of items) {
|
||||
userAmounts.set(item.accountSequence, new Decimal(0));
|
||||
}
|
||||
|
||||
for (const phase of phases) {
|
||||
const phaseAllocation = dailyAllocation.times(phase.daysInPhase);
|
||||
|
||||
for (const item of items) {
|
||||
if (phase.participatingBatches.includes(item.batch)) {
|
||||
const userContribution = userContributions.get(item.accountSequence)!;
|
||||
const ratio = userContribution.dividedBy(phase.participatingContribution);
|
||||
const phaseAmount = phaseAllocation.times(ratio);
|
||||
|
||||
const currentAmount = userAmounts.get(item.accountSequence)!;
|
||||
userAmounts.set(item.accountSequence, currentAmount.plus(phaseAmount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算总用户算力(用于记录)
|
||||
let totalUserContribution = new Decimal(0);
|
||||
for (const contribution of batchContributions.values()) {
|
||||
totalUserContribution = totalUserContribution.plus(contribution);
|
||||
}
|
||||
|
||||
const results: BatchMiningItemResult[] = [];
|
||||
let successCount = 0;
|
||||
let failedCount = 0;
|
||||
|
|
@ -467,156 +517,141 @@ export class BatchMiningService {
|
|||
},
|
||||
});
|
||||
|
||||
// 2. 按批次处理
|
||||
for (const batchNum of sortedBatches) {
|
||||
const batchItems = batchGroups.get(batchNum)!;
|
||||
// 2. 处理每个用户
|
||||
for (const item of items) {
|
||||
try {
|
||||
const userContribution = userContributions.get(item.accountSequence)!;
|
||||
const amount = userAmounts.get(item.accountSequence)!;
|
||||
const ratio = userContribution.dividedBy(totalUserContribution);
|
||||
const totalSeconds = BigInt(item.preMineDays * SECONDS_PER_DAY);
|
||||
const manualAmount = new ShareAmount(amount);
|
||||
|
||||
// 计算当前批次的总算力
|
||||
let batchTotalContribution = new Decimal(0);
|
||||
for (const item of batchItems) {
|
||||
const userContribution = this.calculateUserContribution(item.treeCount);
|
||||
batchTotalContribution = batchTotalContribution.plus(userContribution);
|
||||
}
|
||||
// 查找或创建挖矿账户
|
||||
let account = await tx.miningAccount.findUnique({
|
||||
where: { accountSequence: item.accountSequence },
|
||||
});
|
||||
|
||||
// 当前批次的全网算力
|
||||
cumulativeContribution = cumulativeContribution.plus(batchTotalContribution);
|
||||
|
||||
// 处理当前批次的每个用户
|
||||
for (const item of batchItems) {
|
||||
try {
|
||||
const userContribution = this.calculateUserContribution(item.treeCount);
|
||||
const ratio = userContribution.dividedBy(cumulativeContribution);
|
||||
const totalSeconds = BigInt(item.preMineDays * SECONDS_PER_DAY);
|
||||
const amount = secondDistribution.times(totalSeconds.toString()).times(ratio);
|
||||
const manualAmount = new ShareAmount(amount);
|
||||
|
||||
// 查找或创建挖矿账户
|
||||
let account = await tx.miningAccount.findUnique({
|
||||
where: { accountSequence: item.accountSequence },
|
||||
});
|
||||
|
||||
if (!account) {
|
||||
// 创建新账户
|
||||
account = await tx.miningAccount.create({
|
||||
data: {
|
||||
accountSequence: item.accountSequence,
|
||||
totalMined: new Decimal(0),
|
||||
availableBalance: new Decimal(0),
|
||||
frozenBalance: new Decimal(0),
|
||||
totalContribution: userContribution, // 设置初始算力
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const balanceBefore = new Decimal(account.availableBalance);
|
||||
const balanceAfter = balanceBefore.plus(manualAmount.value);
|
||||
const totalMinedAfter = new Decimal(account.totalMined).plus(manualAmount.value);
|
||||
|
||||
// 更新账户余额
|
||||
await tx.miningAccount.update({
|
||||
where: { accountSequence: item.accountSequence },
|
||||
data: {
|
||||
totalMined: totalMinedAfter,
|
||||
availableBalance: balanceAfter,
|
||||
totalContribution: userContribution, // 同时更新算力
|
||||
updatedAt: now,
|
||||
},
|
||||
});
|
||||
|
||||
// 创建明细记录
|
||||
const description = `批量补发挖矿收益 - 批次:${batchNum} - 认种棵数:${item.treeCount} - 提前挖${item.preMineDays}天 - 操作人:${operatorName} - ${reason}`;
|
||||
|
||||
await tx.miningTransaction.create({
|
||||
if (!account) {
|
||||
// 创建新账户
|
||||
account = await tx.miningAccount.create({
|
||||
data: {
|
||||
accountSequence: item.accountSequence,
|
||||
type: 'BATCH_MINING',
|
||||
amount: manualAmount.value,
|
||||
balanceBefore,
|
||||
balanceAfter,
|
||||
referenceId: execution.id,
|
||||
referenceType: 'BATCH_MINING',
|
||||
memo: description,
|
||||
totalMined: new Decimal(0),
|
||||
availableBalance: new Decimal(0),
|
||||
frozenBalance: new Decimal(0),
|
||||
totalContribution: userContribution, // 设置初始算力
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 创建批量补发明细记录
|
||||
await tx.batchMiningRecord.create({
|
||||
data: {
|
||||
const balanceBefore = new Decimal(account.availableBalance);
|
||||
const balanceAfter = balanceBefore.plus(manualAmount.value);
|
||||
const totalMinedAfter = new Decimal(account.totalMined).plus(manualAmount.value);
|
||||
|
||||
// 更新账户余额
|
||||
await tx.miningAccount.update({
|
||||
where: { accountSequence: item.accountSequence },
|
||||
data: {
|
||||
totalMined: totalMinedAfter,
|
||||
availableBalance: balanceAfter,
|
||||
totalContribution: userContribution, // 同时更新算力
|
||||
updatedAt: now,
|
||||
},
|
||||
});
|
||||
|
||||
// 创建明细记录
|
||||
const description = `批量补发挖矿收益 - 批次:${item.batch} - 认种棵数:${item.treeCount} - 提前挖${item.preMineDays}天 - 操作人:${operatorName} - ${reason}`;
|
||||
|
||||
await tx.miningTransaction.create({
|
||||
data: {
|
||||
accountSequence: item.accountSequence,
|
||||
type: 'BATCH_MINING',
|
||||
amount: manualAmount.value,
|
||||
balanceBefore,
|
||||
balanceAfter,
|
||||
referenceId: execution.id,
|
||||
referenceType: 'BATCH_MINING',
|
||||
memo: description,
|
||||
},
|
||||
});
|
||||
|
||||
// 创建批量补发明细记录
|
||||
await tx.batchMiningRecord.create({
|
||||
data: {
|
||||
executionId: execution.id,
|
||||
accountSequence: item.accountSequence,
|
||||
batch: item.batch,
|
||||
treeCount: item.treeCount,
|
||||
preMineDays: item.preMineDays,
|
||||
userContribution,
|
||||
networkContribution: totalUserContribution,
|
||||
contributionRatio: ratio,
|
||||
totalSeconds,
|
||||
amount: manualAmount.value,
|
||||
remark: item.remark,
|
||||
},
|
||||
});
|
||||
|
||||
// 发布事件到 Kafka
|
||||
await tx.outboxEvent.create({
|
||||
data: {
|
||||
aggregateType: 'BatchMining',
|
||||
aggregateId: execution.id,
|
||||
eventType: 'BATCH_MINING_COMPLETED',
|
||||
topic: 'mining.batch-mining.completed',
|
||||
key: item.accountSequence,
|
||||
payload: {
|
||||
eventId: `${execution.id}-${item.accountSequence}`,
|
||||
executionId: execution.id,
|
||||
accountSequence: item.accountSequence,
|
||||
batch: batchNum,
|
||||
batch: item.batch,
|
||||
amount: manualAmount.value.toString(),
|
||||
treeCount: item.treeCount,
|
||||
preMineDays: item.preMineDays,
|
||||
userContribution,
|
||||
networkContribution: cumulativeContribution,
|
||||
contributionRatio: ratio,
|
||||
totalSeconds,
|
||||
amount: manualAmount.value,
|
||||
remark: item.remark,
|
||||
userContribution: userContribution.toString(),
|
||||
networkContribution: totalUserContribution.toString(),
|
||||
contributionRatio: ratio.toString(),
|
||||
totalSeconds: totalSeconds.toString(),
|
||||
operatorId,
|
||||
operatorName,
|
||||
reason,
|
||||
},
|
||||
});
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
|
||||
// 发布事件到 Kafka
|
||||
await tx.outboxEvent.create({
|
||||
data: {
|
||||
aggregateType: 'BatchMining',
|
||||
aggregateId: execution.id,
|
||||
eventType: 'BATCH_MINING_COMPLETED',
|
||||
topic: 'mining.batch-mining.completed',
|
||||
key: item.accountSequence,
|
||||
payload: {
|
||||
eventId: `${execution.id}-${item.accountSequence}`,
|
||||
executionId: execution.id,
|
||||
accountSequence: item.accountSequence,
|
||||
batch: batchNum,
|
||||
amount: manualAmount.value.toString(),
|
||||
treeCount: item.treeCount,
|
||||
preMineDays: item.preMineDays,
|
||||
userContribution: userContribution.toString(),
|
||||
networkContribution: cumulativeContribution.toString(),
|
||||
contributionRatio: ratio.toString(),
|
||||
totalSeconds: totalSeconds.toString(),
|
||||
operatorId,
|
||||
operatorName,
|
||||
reason,
|
||||
},
|
||||
status: 'PENDING',
|
||||
},
|
||||
});
|
||||
results.push({
|
||||
accountSequence: item.accountSequence,
|
||||
batch: item.batch,
|
||||
treeCount: item.treeCount,
|
||||
userContribution: userContribution.toFixed(10),
|
||||
networkContribution: totalUserContribution.toFixed(10),
|
||||
contributionRatio: ratio.toFixed(18),
|
||||
preMineDays: item.preMineDays,
|
||||
totalSeconds: totalSeconds.toString(),
|
||||
amount: manualAmount.value.toFixed(8),
|
||||
success: true,
|
||||
});
|
||||
|
||||
results.push({
|
||||
accountSequence: item.accountSequence,
|
||||
batch: batchNum,
|
||||
treeCount: item.treeCount,
|
||||
userContribution: userContribution.toFixed(10),
|
||||
networkContribution: cumulativeContribution.toFixed(10),
|
||||
contributionRatio: ratio.toFixed(18),
|
||||
preMineDays: item.preMineDays,
|
||||
totalSeconds: totalSeconds.toString(),
|
||||
amount: manualAmount.value.toFixed(8),
|
||||
success: true,
|
||||
});
|
||||
successCount++;
|
||||
totalAmount = totalAmount.plus(manualAmount.value);
|
||||
|
||||
successCount++;
|
||||
totalAmount = totalAmount.plus(manualAmount.value);
|
||||
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Failed to process ${item.accountSequence}: ${error.message}`);
|
||||
results.push({
|
||||
accountSequence: item.accountSequence,
|
||||
batch: batchNum,
|
||||
treeCount: item.treeCount,
|
||||
userContribution: '0',
|
||||
networkContribution: '0',
|
||||
contributionRatio: '0',
|
||||
preMineDays: item.preMineDays,
|
||||
totalSeconds: '0',
|
||||
amount: '0',
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
failedCount++;
|
||||
}
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Failed to process ${item.accountSequence}: ${error.message}`);
|
||||
results.push({
|
||||
accountSequence: item.accountSequence,
|
||||
batch: item.batch,
|
||||
treeCount: item.treeCount,
|
||||
userContribution: '0',
|
||||
networkContribution: '0',
|
||||
contributionRatio: '0',
|
||||
preMineDays: item.preMineDays,
|
||||
totalSeconds: '0',
|
||||
amount: '0',
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
failedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue