fix(batch-mining): 修正总天数计算逻辑

- 总挖矿天数 = 从2025-11-08到今天的自然天数
- 最后阶段天数 = 总天数 - 前面各阶段天数之和
- 不再累加preMineDays作为总天数

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-21 23:46:27 -08:00
parent d47276a460
commit 18e9749ad8
1 changed files with 40 additions and 47 deletions

View File

@ -350,18 +350,13 @@ export class BatchMiningService {
/**
*
*
* "提前天数"
*
* - = 118
* - preMineDays
* - 1 preMineDays=3 12313
* - 2 preMineDays=2 2321+22
* - 3 preMineDays=1 3411+2+31
* - 4 preMineDays=0 4
*
*
* - 阶段1: 只有批次11 preMineDays 2
* - 阶段2: 批次1+22 preMineDays 3
* - 阶段3: 批次1+2+33 preMineDays 4
* - 最后阶段: 所有批次一起挖 (totalMiningDays - )
* - 阶段1: 只有批次11 preMineDays
* - 阶段2: 批次1+22 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<number, number>();
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;
}