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:
parent
7a5faad665
commit
af95f8da0c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue