fix: harden channel retry attribution and operations UI
This commit is contained in:
@@ -35,6 +35,20 @@ const deliveryTypeLabel: Record<string, string> = {
|
||||
uplink: '上行短信',
|
||||
};
|
||||
|
||||
const attemptStatusLabel: Record<string, string> = {
|
||||
awaiting_ack: '等待客户端确认',
|
||||
acknowledged: '客户端已确认',
|
||||
rejected: '客户端拒绝',
|
||||
failed: '投递失败',
|
||||
};
|
||||
|
||||
function attemptStatusTone(status: string) {
|
||||
if (status === 'acknowledged') return 'success' as const;
|
||||
if (status === 'rejected' || status === 'failed') return 'danger' as const;
|
||||
if (status === 'awaiting_ack') return 'info' as const;
|
||||
return 'neutral' as const;
|
||||
}
|
||||
|
||||
function DeliveryDetailModal({ record, onClose }: { record: DownstreamDeliveryRecord; onClose: () => void }) {
|
||||
const payloadText = useMemo(() => JSON.stringify(record.payload ?? {}, null, 2), [record.payload]);
|
||||
|
||||
@@ -68,29 +82,33 @@ function DeliveryDetailModal({ record, onClose }: { record: DownstreamDeliveryRe
|
||||
</div>
|
||||
<section className="report-history">
|
||||
<h3>逐次投递记录</h3>
|
||||
<div className="downstream-attempt-table" role="table" aria-label="逐次投递记录">
|
||||
<div className="downstream-attempt-table__header" role="row">
|
||||
<span>次数 / 状态</span><span>发送 / ACK 时间</span><span>连接 / Sequence / Msg_Id</span><span>结果</span>
|
||||
</div>
|
||||
<div className="downstream-attempt-timeline" aria-label="逐次投递记录">
|
||||
{(record.attempts ?? []).map((attempt) => (
|
||||
<div key={attempt.id} role="row">
|
||||
<strong>第 {attempt.attemptNo} 次<br />{attempt.status}</strong>
|
||||
<span>
|
||||
{attempt.sentAt ? formatDateTime(attempt.sentAt) : '-'}
|
||||
<br />
|
||||
ACK:{attempt.acknowledgedAt ? formatDateTime(attempt.acknowledgedAt) : '-'}
|
||||
</span>
|
||||
<span>
|
||||
{attempt.connectionId ?? '-'}
|
||||
<br />
|
||||
Seq:{attempt.sequenceId ?? '-'} / Msg:{attempt.messageId ?? '-'}
|
||||
</span>
|
||||
<span>
|
||||
ACK Result:{attempt.ackResult ?? '-'}
|
||||
<br />
|
||||
{attempt.errorMessage ?? attempt.failureType ?? '-'}
|
||||
</span>
|
||||
</div>
|
||||
<article className="downstream-attempt-card" key={attempt.id}>
|
||||
<div className={`downstream-attempt-marker downstream-attempt-marker--${attemptStatusTone(attempt.status)}`}>
|
||||
{attempt.attemptNo}
|
||||
</div>
|
||||
<div className="downstream-attempt-card__body">
|
||||
<header>
|
||||
<strong>第 {attempt.attemptNo} 次投递</strong>
|
||||
<Tag tone={attemptStatusTone(attempt.status)}>{attemptStatusLabel[attempt.status] ?? attempt.status}</Tag>
|
||||
</header>
|
||||
<dl className="downstream-attempt-card__times">
|
||||
<div><dt>发送时间</dt><dd>{attempt.sentAt ? formatDateTime(attempt.sentAt) : '-'}</dd></div>
|
||||
<div><dt>ACK 时间</dt><dd>{attempt.acknowledgedAt ? formatDateTime(attempt.acknowledgedAt) : '-'}</dd></div>
|
||||
<div><dt>ACK 截止</dt><dd>{attempt.ackDeadlineAt ? formatDateTime(attempt.ackDeadlineAt) : '-'}</dd></div>
|
||||
</dl>
|
||||
<dl className="downstream-attempt-card__identifiers">
|
||||
<div><dt>连接 ID</dt><dd>{attempt.connectionId ?? '-'}</dd></div>
|
||||
<div><dt>Sequence_Id</dt><dd>{attempt.sequenceId ?? '-'}</dd></div>
|
||||
<div><dt>Msg_Id</dt><dd>{attempt.messageId ?? '-'}</dd></div>
|
||||
</dl>
|
||||
<div className={`downstream-attempt-result${attempt.errorMessage || attempt.failureType ? ' downstream-attempt-result--error' : ''}`}>
|
||||
<span>ACK Result:{attempt.ackResult ?? '-'}</span>
|
||||
<strong>{attempt.errorMessage ?? attempt.failureType ?? '本次投递未记录异常'}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
{(record.attempts ?? []).length === 0 ? <p>暂无逐次投递记录</p> : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user