feat: 优化通道运营商与金额展示

This commit is contained in:
hectorzhao
2026-08-12 13:16:25 +08:00
parent dc358798e9
commit f350bf5ef3
20 changed files with 301 additions and 95 deletions
+19 -2
View File
@@ -22,7 +22,7 @@
.sms-channel-table__row {
display: grid;
gap: var(--space-3);
grid-template-columns: minmax(150px, 1.2fr) 88px 86px 96px minmax(280px, 1.6fr) 190px;
grid-template-columns: minmax(190px, 1.25fr) 110px 86px 96px minmax(280px, 1.6fr) 190px;
min-width: 940px;
}
@@ -60,11 +60,18 @@
overflow-wrap: anywhere;
}
.sms-channel-identity span {
.sms-channel-identity > span {
color: var(--color-text-muted);
font-size: var(--font-size-sm);
}
.sms-channel-identity__carriers {
display: flex;
flex-wrap: wrap;
gap: var(--space-2);
margin-top: var(--space-1);
}
.sms-channel-carrier-price {
align-items: flex-start;
display: grid;
@@ -72,6 +79,12 @@
justify-items: start;
}
.sms-channel-carrier-price strong {
color: var(--color-text-strong);
font-size: var(--font-size-sm);
font-variant-numeric: tabular-nums;
}
.sms-channel-status-cell {
align-items: flex-start;
display: grid;
@@ -136,6 +149,10 @@
text-overflow: ellipsis;
}
.sms-channel-rate .sms-channel-rate__empty {
color: #4b5563;
}
.sms-channel-actions {
display: grid;
gap: var(--space-2);
+12 -12
View File
@@ -1,15 +1,15 @@
import { Copy, Eye, FileText, Pencil, Power, Send } from 'lucide-react';
import { DeleteRiskAction, MoneyText, Pagination, Tag } from '@/components/ui';
import { formatCents } from '@/utils/currency';
import { CarrierTag, DeleteRiskAction, Pagination, Tag } from '@/components/ui';
import { formatRateAmount } from '@/utils/currency';
import { successRateClassName } from '@/utils/successRate';
import { carrierLabelMap, carrierToneMap, statusLabelMap, statusToneMap } from './channelModel';
import { statusLabelMap, statusToneMap } from './channelModel';
import type { ChannelConfirmAction, ChannelModalState, SmsChannel } from './channelTypes';
function RateBlock({ label, rate, count, isSuccess = false }: { label: string; rate: number; count: number; isSuccess?: boolean }) {
function RateBlock({ label, rate, count, empty, isSuccess = false }: { label: string; rate: number; count: number; empty: boolean; isSuccess?: boolean }) {
return (
<div className="sms-channel-rate">
<small>{label}</small>
<strong className={isSuccess ? successRateClassName(rate) : undefined}>{rate}%</strong>
<strong className={empty ? 'sms-channel-rate__empty' : isSuccess ? successRateClassName(rate) : undefined}>{empty ? '-' : `${rate}%`}</strong>
<span>{count.toLocaleString('zh-CN')}</span>
</div>
);
@@ -44,7 +44,7 @@ export function ChannelTable({
<div className="surface sms-channel-table">
<div className="sms-channel-table__head">
<span></span>
<span> / </span>
<span></span>
<span></span>
<span></span>
<span> / </span>
@@ -55,10 +55,10 @@ export function ChannelTable({
<div className="sms-channel-identity">
<strong>{channel.name}</strong>
<span> ID{channel.id}</span>
<div className="sms-channel-identity__carriers">{channel.carriers.map((carrier) => <CarrierTag carrier={carrier} key={carrier} />)}</div>
</div>
<div className="sms-channel-carrier-price">
<div>{channel.carriers.map((carrier) => <Tag key={carrier} tone={carrierToneMap[carrier]}>{carrierLabelMap[carrier]}</Tag>)}</div>
<strong><MoneyText>{formatCents(channel.unitPrice)} </MoneyText></strong>
<strong>{formatRateAmount(channel.unitPrice / 10_000)} /</strong>
</div>
<div className="sms-channel-status-cell">
<Tag tone={statusToneMap[channel.status]}>{statusLabelMap[channel.status]}</Tag>
@@ -68,10 +68,10 @@ export function ChannelTable({
</div>
<strong className="sms-channel-total">{channel.total.toLocaleString('zh-CN')}</strong>
<div className="sms-channel-quality">
<RateBlock count={channel.submitFailureCount} label="提交失败" rate={channel.submitFailureRate} />
<RateBlock count={channel.successCount} isSuccess label="送达成功" rate={channel.successRate} />
<RateBlock count={channel.unknownCount} label="回执未知" rate={channel.unknownRate} />
<RateBlock count={channel.failureCount} label="送达失败" rate={channel.failureRate} />
<RateBlock count={channel.submitFailureCount} empty={channel.total === 0} label="提交失败" rate={channel.submitFailureRate} />
<RateBlock count={channel.successCount} empty={channel.total === 0} isSuccess label="送达成功" rate={channel.successRate} />
<RateBlock count={channel.unknownCount} empty={channel.total === 0} label="回执未知" rate={channel.unknownRate} />
<RateBlock count={channel.failureCount} empty={channel.total === 0} label="送达失败" rate={channel.failureRate} />
</div>
<div className="sms-channel-actions">
<button className="sms-channel-report-entry" onClick={() => onOpenReports(channel)} type="button">