fix(mining-admin): 根据挖矿开始时间自动计算挖矿天数

之前错误地从Excel第6列读取preMineDays,但该列为空。
现在根据"挖矿开始时间"到今天自动计算实际挖矿天数。

修改内容:
- 修正Excel列索引(用户ID在第1列,不是第2列)
- 解析日期支持多种格式(2025.11.8, 2025-11-08, 2025/11/8)
- 自动计算从挖矿开始日期到今天的天数作为preMineDays

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-21 18:50:46 -08:00
parent 7a5faad665
commit af95f8da0c
1 changed files with 75 additions and 16 deletions

View File

@ -252,49 +252,81 @@ export class BatchMiningService {
/**
* Excel
* Excel :
* | ID | | | | |
* ID | | | | | ()
*
* preMineDays () "挖矿开始时间"
*/
parseExcelData(rows: any[]): BatchMiningItem[] {
this.logger.log(`[parseExcelData] 开始解析 Excel 数据, 总行数: ${rows.length}`);
const items: BatchMiningItem[] = [];
const today = new Date();
today.setHours(0, 0, 0, 0);
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
// 跳过标题行和汇总
if (!row || typeof row[1] !== 'string' || row[1] === '注册ID' || row[1] === '合计') {
this.logger.debug(`[parseExcelData] 跳过行 ${i + 1}: 标题行或汇总`);
// 跳过
if (!row || !row[0]) {
this.logger.debug(`[parseExcelData] 跳过行 ${i + 1}: `);
continue;
}
// 跳过认种量为 0 或无效的
const treeCount = parseInt(row[2], 10);
if (isNaN(treeCount) || treeCount <= 0) {
this.logger.debug(`[parseExcelData] 跳过行 ${i + 1}: 认种量无效 (${row[2]})`);
// 跳过标题
const firstCell = String(row[0]).trim();
if (firstCell === '用户ID' || firstCell === '注册ID' || firstCell === '序号') {
this.logger.debug(`[parseExcelData] 跳过行 ${i + 1}: 标题行`);
continue;
}
// 确保注册 ID 格式正确(补全 D 前缀)
let accountSequence = String(row[1]);
// 获取用户ID (第一列)
let accountSequence = String(row[0]).trim();
if (!accountSequence.startsWith('D')) {
accountSequence = 'D' + accountSequence;
}
const batch = parseInt(row[4], 10);
const preMineDays = parseInt(row[5], 10);
// 获取认种量 (第二列)
const treeCount = parseInt(row[1], 10);
if (isNaN(treeCount) || treeCount <= 0) {
this.logger.debug(`[parseExcelData] 跳过行 ${i + 1}: 认种量无效 (${row[1]})`);
continue;
}
if (isNaN(batch) || isNaN(preMineDays) || preMineDays <= 0) {
this.logger.warn(`[parseExcelData] 跳过行 ${i + 1}: 批次或提前天数无效 (batch=${row[4]}, preMineDays=${row[5]})`);
// 获取挖矿开始时间 (第四列索引3)
const miningStartDateStr = String(row[3] || '').trim();
if (!miningStartDateStr) {
this.logger.warn(`[parseExcelData] 跳过行 ${i + 1}: 挖矿开始时间为空`);
continue;
}
// 解析挖矿开始时间 (格式: 2025.11.8 或 2025-11-08)
const miningStartDate = this.parseDate(miningStartDateStr);
if (!miningStartDate) {
this.logger.warn(`[parseExcelData] 跳过行 ${i + 1}: 挖矿开始时间格式无效 (${miningStartDateStr})`);
continue;
}
// 计算从挖矿开始到今天的天数
const diffTime = today.getTime() - miningStartDate.getTime();
const preMineDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
if (preMineDays <= 0) {
this.logger.warn(`[parseExcelData] 跳过行 ${i + 1}: 挖矿天数<=0 (开始日期: ${miningStartDateStr}, 天数: ${preMineDays})`);
continue;
}
// 获取批次 (第五列索引4)
const batch = parseInt(row[4], 10);
if (isNaN(batch) || batch <= 0) {
this.logger.warn(`[parseExcelData] 跳过行 ${i + 1}: 批次无效 (${row[4]})`);
continue;
}
items.push({
accountSequence,
treeCount,
miningStartDate: String(row[3] || ''),
miningStartDate: miningStartDateStr,
batch,
preMineDays,
remark: row[6] ? String(row[6]) : undefined,
remark: row[5] ? String(row[5]) : undefined,
});
}
@ -306,4 +338,31 @@ export class BatchMiningService {
return items;
}
/**
*
* 支持格式: 2025.11.8, 2025-11-08, 2025/11/8
*/
private parseDate(dateStr: string): Date | null {
// 尝试不同格式
const formats = [
/^(\d{4})\.(\d{1,2})\.(\d{1,2})$/, // 2025.11.8
/^(\d{4})-(\d{1,2})-(\d{1,2})$/, // 2025-11-08
/^(\d{4})\/(\d{1,2})\/(\d{1,2})$/, // 2025/11/8
];
for (const format of formats) {
const match = dateStr.match(format);
if (match) {
const year = parseInt(match[1], 10);
const month = parseInt(match[2], 10) - 1; // 月份从0开始
const day = parseInt(match[3], 10);
const date = new Date(year, month, day);
date.setHours(0, 0, 0, 0);
return date;
}
}
return null;
}
}