update at 2026-02-13 17:44:25
This commit is contained in:
@@ -31,6 +31,34 @@ function parseNumericValue(text: string): number | null {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将单元格值格式化为可读文本,用于告警输出。
|
||||
* 空字符串会明确展示为“(空)”,便于定位“看起来没填值”的问题行。
|
||||
*/
|
||||
function formatCellValueForWarning(value: string): string {
|
||||
if (value.length === 0) {
|
||||
return '(空)';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装“列位置 + 列名 + 原始值”的告警片段,便于用户快速定位问题字段。
|
||||
*/
|
||||
function buildColumnDebugText(row: string[], headers: string[], columns: number[]): string {
|
||||
if (columns.length === 0) {
|
||||
return '未选择列';
|
||||
}
|
||||
|
||||
return columns
|
||||
.map((columnIndex) => {
|
||||
const headerName = headers[columnIndex] ?? `列${columnIndex + 1}`;
|
||||
const rawValue = row[columnIndex] ?? '';
|
||||
return `第 ${columnIndex + 1} 列(${headerName})="${formatCellValueForWarning(rawValue)}"`;
|
||||
})
|
||||
.join(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照配置生成 source 名称。
|
||||
* 若未选择描述列,则回退为数据列文本。
|
||||
@@ -87,30 +115,48 @@ export function buildSankeyData(table: RawTable, config: MappingConfig): SankeyB
|
||||
const linkValueMap = new Map<string, number>();
|
||||
const warnings: string[] = [];
|
||||
let droppedRows = 0;
|
||||
const sourceDataColumnIndex = config.sourceDataColumn;
|
||||
const sourceDataColumnName =
|
||||
table.headers[sourceDataColumnIndex] ?? `列${sourceDataColumnIndex + 1}`;
|
||||
|
||||
const lastNonEmptyTargetValueByColumn = new Map<number, string>();
|
||||
|
||||
table.rows.forEach((row, rowIndex) => {
|
||||
const excelRow = rowIndex + 2;
|
||||
const sourceRaw = normalizeText(row[config.sourceDataColumn as number] ?? '');
|
||||
const sourceCellRaw = row[sourceDataColumnIndex] ?? '';
|
||||
const sourceRaw = normalizeText(sourceCellRaw);
|
||||
const sourceValue = parseNumericValue(sourceRaw);
|
||||
|
||||
if (sourceValue === null) {
|
||||
warnings.push(`第 ${excelRow} 行: 源数据不是有效数字,已跳过`);
|
||||
warnings.push(
|
||||
`第 ${excelRow} 行, 第 ${sourceDataColumnIndex + 1} 列(${sourceDataColumnName}): 源数据不是有效数字,原始值="${formatCellValueForWarning(sourceCellRaw)}",已跳过`
|
||||
);
|
||||
droppedRows += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceName = buildSourceName(row, config);
|
||||
if (!sourceName) {
|
||||
warnings.push(`第 ${excelRow} 行: 源描述为空,已跳过`);
|
||||
const sourceDescDebugText = buildColumnDebugText(
|
||||
row,
|
||||
table.headers,
|
||||
config.sourceDescriptionColumns
|
||||
);
|
||||
warnings.push(`第 ${excelRow} 行: 源描述为空,字段=${sourceDescDebugText},已跳过`);
|
||||
droppedRows += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const targetName = buildTargetName(row, config, lastNonEmptyTargetValueByColumn);
|
||||
if (!targetName) {
|
||||
warnings.push(`第 ${excelRow} 行: 目标描述为空,已跳过`);
|
||||
const targetDescDebugText = buildColumnDebugText(
|
||||
row,
|
||||
table.headers,
|
||||
config.targetDescriptionColumns
|
||||
);
|
||||
warnings.push(
|
||||
`第 ${excelRow} 行: 目标描述为空,字段=${targetDescDebugText},且无可继承的上方值,已跳过`
|
||||
);
|
||||
droppedRows += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user