fix: stabilize admin tracking event display

This commit is contained in:
2026-05-08 11:15:42 +08:00
parent a71df45437
commit 0235200d32
6 changed files with 297 additions and 18 deletions

View File

@@ -246,7 +246,7 @@ export function AdminTrackingEventsPage({
{formatMetadataJson(entry.metadataJson)}
</pre>
</td>
<td>{entry.occurredAt || '-'}</td>
<td>{formatOccurredAt(entry.occurredAt)}</td>
<td>
<button
className="admin-secondary-button"
@@ -314,7 +314,7 @@ function TrackingEventDetailPanel({
{formatMetadataJson(entry.metadataJson)}
</pre>
) : (
formatExportCell(entry[column.key]) || '-'
formatExportCell(entry[column.key], column.key) || '-'
)}
</dd>
</div>
@@ -358,7 +358,10 @@ function exportTrackingEventsAsExcel(entries: AdminTrackingEventEntryPayload[])
exportColumns.map((column) => `<th>${escapeHtml(column.label)}</th>`).join(''),
...entries.map((entry) =>
exportColumns
.map((column) => `<td style="mso-number-format:'\\@';">${escapeHtml(formatExportCell(entry[column.key]))}</td>`)
.map(
(column) =>
`<td style="mso-number-format:'\\@';">${escapeHtml(formatExportCell(entry[column.key], column.key))}</td>`,
)
.join(''),
),
];
@@ -376,13 +379,41 @@ function exportTrackingEventsAsExcel(entries: AdminTrackingEventEntryPayload[])
URL.revokeObjectURL(url);
}
function formatExportCell(value: unknown) {
function formatExportCell(value: unknown, key?: keyof AdminTrackingEventEntryPayload) {
if (value === null || typeof value === 'undefined') {
return '';
}
if (key === 'occurredAt') {
return formatOccurredAt(String(value));
}
return String(value);
}
function formatOccurredAt(value: string) {
const trimmed = value.trim();
if (!trimmed) {
return '-';
}
if (/^\d+$/.test(trimmed)) {
const micros = Number(trimmed);
if (Number.isSafeInteger(micros)) {
return formatDateTime(new Date(Math.floor(micros / 1000)));
}
}
const parsed = new Date(trimmed);
if (!Number.isNaN(parsed.getTime())) {
return formatDateTime(parsed);
}
return trimmed;
}
function formatDateTime(date: Date) {
const pad = (value: number, size = 2) => String(value).padStart(size, '0');
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(
date.getHours(),
)}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
function escapeHtml(value: string) {
return value
.replace(/&/g, '&amp;')