diff --git a/backend/services/mining-service/src/application/services/batch-mining.service.ts b/backend/services/mining-service/src/application/services/batch-mining.service.ts index 17b3eb0f..803fdbdc 100644 --- a/backend/services/mining-service/src/application/services/batch-mining.service.ts +++ b/backend/services/mining-service/src/application/services/batch-mining.service.ts @@ -350,18 +350,13 @@ export class BatchMiningService { /** * 构建挖矿阶段 * - * 根据批次的"提前天数"构建各挖矿阶段: + * 业务规则: + * - 总挖矿天数 = 从第一批用户开始挖矿(11月8日)到今天的自然天数 * - preMineDays 表示该批次比下一批次提前开始的天数 - * - 批次1的 preMineDays=3 意味着批次1比批次2提前3天,所以批次1先独挖3天 - * - 批次2的 preMineDays=2 意味着批次2比批次3提前2天,所以批次1+2一起挖2天 - * - 批次3的 preMineDays=1 意味着批次3比批次4提前1天,所以批次1+2+3一起挖1天 - * - 批次4的 preMineDays=0 意味着批次4是最后一批,所有批次一起挖剩余天数 - * - * 正确的阶段划分: - * - 阶段1: 只有批次1,持续批次1的 preMineDays 天(在批次2加入之前) - * - 阶段2: 批次1+2,持续批次2的 preMineDays 天(在批次3加入之前) - * - 阶段3: 批次1+2+3,持续批次3的 preMineDays 天(在批次4加入之前) - * - 最后阶段: 所有批次一起挖 (totalMiningDays - 所有提前天数之和) + * - 阶段1: 只有批次1,持续批次1的 preMineDays 天 + * - 阶段2: 批次1+2,持续批次2的 preMineDays 天 + * - ... + * - 最后阶段: 所有批次一起挖,持续 (总天数 - 前面各阶段天数之和) 天 */ private buildMiningPhases( items: BatchMiningItem[], @@ -374,6 +369,14 @@ export class BatchMiningService { return phases; } + // 计算总挖矿天数:从2025年11月8日到今天 + const miningStartDate = new Date('2025-11-08'); + miningStartDate.setHours(0, 0, 0, 0); + const today = new Date(); + today.setHours(0, 0, 0, 0); + const totalMiningDays = Math.floor((today.getTime() - miningStartDate.getTime()) / (1000 * 60 * 60 * 24)); + this.logger.log(`[buildMiningPhases] 总挖矿天数: ${totalMiningDays} (从2025-11-08到今天)`); + // 获取每个批次的提前天数 const batchPreMineDays = new Map(); for (const item of items) { @@ -386,65 +389,55 @@ export class BatchMiningService { let currentPhase = 1; let participatingBatches: number[] = []; - let totalDays = 0; - - // 正确的阶段划分逻辑: - // - 阶段N的天数 = 批次N的 preMineDays(表示批次N比批次N+1提前的天数) - // - 阶段N的参与者 = 批次1到批次N(即在批次N+1加入之前,批次1-N一起挖) - // - // 示例(13个批次,preMineDays分别为 8,7,6,6,6,6,6,6,6,6,6,6,0): - // - 阶段1: 只有批次1,挖8天(批次1比批次2提前8天) - // - 阶段2: 批次1+2,挖7天(批次2比批次3提前7天) - // - ... - // - 阶段12: 批次1-12,挖6天(批次12比批次13提前6天) - // - 阶段13: 批次1-13,挖1天(最后批次preMineDays=0时算1天) - // - // 总天数 = 8+7+6×10+1 = 76天(如果最后批次preMineDays=0) - // 或者如果Excel中preMineDays总和就是75,则不需要额外加1 + let usedDays = 0; + // 阶段划分: + // - 阶段1到N-1: 各批次依次加入,每个阶段持续该批次的 preMineDays 天 + // - 最后阶段: 所有批次一起挖剩余天数 for (let i = 0; i < sortedBatches.length; i++) { const currentBatch = sortedBatches[i]; - let currentPreMineDays = batchPreMineDays.get(currentBatch) || 0; + const currentPreMineDays = batchPreMineDays.get(currentBatch) || 0; const isLastBatch = i === sortedBatches.length - 1; - // 当前批次加入参与列表(在计算阶段之前加入) + // 当前批次加入参与列表 participatingBatches.push(currentBatch); - // 最后一个批次如果 preMineDays=0,改为1天(所有批次至少要一起挖1天) - if (isLastBatch && currentPreMineDays === 0) { - currentPreMineDays = 1; - this.logger.log(`[buildMiningPhases] 最后批次${currentBatch}的preMineDays=0,改为1天`); + // 计算该阶段参与用户的总算力 + let participatingContribution = new Decimal(0); + for (const batch of participatingBatches) { + participatingContribution = participatingContribution.plus(batchContributions.get(batch) || 0); } - // 只有当该阶段有天数时才创建阶段 - if (currentPreMineDays > 0) { - // 计算该阶段参与用户的总算力 - let participatingContribution = new Decimal(0); - for (const batch of participatingBatches) { - participatingContribution = participatingContribution.plus(batchContributions.get(batch) || 0); - } + let daysInPhase: number; + if (isLastBatch) { + // 最后阶段:所有批次一起挖剩余天数 + daysInPhase = totalMiningDays - usedDays; + this.logger.log(`[buildMiningPhases] 最后阶段: 剩余天数 = ${totalMiningDays} - ${usedDays} = ${daysInPhase}`); + } else { + // 非最后阶段:使用该批次的 preMineDays + daysInPhase = currentPreMineDays; + } + if (daysInPhase > 0) { phases.push({ phaseNumber: currentPhase, startDate: new Date(), endDate: new Date(), - daysInPhase: currentPreMineDays, + daysInPhase, participatingContribution, participatingBatches: [...participatingBatches], }); - this.logger.log(`[buildMiningPhases] 阶段${currentPhase}: ${currentPreMineDays}天, 批次[${participatingBatches.join(',')}], 参与算力=${participatingContribution.toFixed(2)}`); + this.logger.log(`[buildMiningPhases] 阶段${currentPhase}: ${daysInPhase}天, 批次[${participatingBatches.join(',')}], 参与算力=${participatingContribution.toFixed(2)}`); currentPhase++; - totalDays += currentPreMineDays; + usedDays += daysInPhase; } } - // 计算预期的每日补发额度(用于验证) - // 每日产出 = 1000000 / (365 * 2) = 1369.863014 - // 用户分到的70% = 958.9041096 per day + // 验证 const expectedDailyAllocation = new Decimal('958.904109589041'); - const expectedTotal = expectedDailyAllocation.times(totalDays); - this.logger.log(`[buildMiningPhases] 总天数: ${totalDays}, 预期总金额: ${expectedTotal.toFixed(2)} (${totalDays}天 × 958.904/天)`); + const expectedTotal = expectedDailyAllocation.times(usedDays); + this.logger.log(`[buildMiningPhases] 实际使用天数: ${usedDays}, 预期总金额: ${expectedTotal.toFixed(2)} (${usedDays}天 × 958.904/天)`); return phases; }