fix: align reporting filters and carrier quality
This commit is contained in:
@@ -290,7 +290,14 @@ function SignatureQualityDrawer({
|
||||
item: SignatureChannelQualityItem;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const carriers = aggregateByCarrier(item.breakdowns);
|
||||
const carriers = item.carrierOverview.map((carrier) => ({
|
||||
...carrier,
|
||||
channelCount: new Set(
|
||||
item.breakdowns
|
||||
.filter((entry) => normalizeCarrier(entry.carrier) === normalizeCarrier(carrier.carrier))
|
||||
.map((entry) => entry.channelId),
|
||||
).size,
|
||||
}));
|
||||
const channels = [...new Map(item.breakdowns.map((entry) => [entry.channelId, entry.channelName])).entries()]
|
||||
.map(([channelId, channelName]) => ({ channelId, channelName }));
|
||||
const visibleCarriers = carrierOrder.filter((carrier) => item.breakdowns.some((entry) => normalizeCarrier(entry.carrier) === carrier));
|
||||
@@ -321,7 +328,7 @@ function SignatureQualityDrawer({
|
||||
<div className="signature-quality-section__heading">
|
||||
<div>
|
||||
<h3>运营商概览</h3>
|
||||
<p>同一运营商可以经过多个通道,以下数据按真实通道提交尝试汇总。</p>
|
||||
<p>按真实业务短信去重统计;补发不会重复计数,成功率取短信最终状态。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="signature-carrier-grid">
|
||||
@@ -329,10 +336,10 @@ function SignatureQualityDrawer({
|
||||
<article className={`signature-carrier-card signature-carrier-card--${normalizeCarrier(carrier.carrier)}`} key={carrier.carrier}>
|
||||
<div>
|
||||
<Tag tone={carrierTagTone(carrier.carrier)}>{carrierLabel(carrier.carrier)}</Tag>
|
||||
<strong>{carrier.total.toLocaleString('zh-CN')} 次</strong>
|
||||
<strong>{carrier.businessMessageCount.toLocaleString('zh-CN')} 条业务短信</strong>
|
||||
</div>
|
||||
<dl>
|
||||
<div><dt>成功率</dt><dd>{carrier.successRate.toFixed(1)}%</dd></div>
|
||||
<div><dt>最终成功率</dt><dd>{carrier.finalSuccessRate.toFixed(1)}%</dd></div>
|
||||
<div><dt>平均到达</dt><dd>{formatDuration(carrier.averageArrivalMs)}</dd></div>
|
||||
<div><dt>涉及通道</dt><dd>{carrier.channelCount} 个</dd></div>
|
||||
</dl>
|
||||
@@ -417,28 +424,6 @@ function QualityRate({ value }: { value: number }) {
|
||||
);
|
||||
}
|
||||
|
||||
function aggregateByCarrier(items: SignatureChannelCarrierQualityStat[]) {
|
||||
return carrierOrder
|
||||
.map((carrier) => {
|
||||
const entries = items.filter((item) => normalizeCarrier(item.carrier) === carrier);
|
||||
if (entries.length === 0) return null;
|
||||
const acceptedCount = entries.reduce((sum, item) => sum + item.acceptedCount, 0);
|
||||
const successCount = entries.reduce((sum, item) => sum + item.successCount, 0);
|
||||
const arrivalWeight = entries.reduce((sum, item) => (
|
||||
sum + (item.averageArrivalMs == null ? 0 : item.averageArrivalMs * item.successCount)
|
||||
), 0);
|
||||
const arrivalCount = entries.reduce((sum, item) => sum + (item.averageArrivalMs == null ? 0 : item.successCount), 0);
|
||||
return {
|
||||
carrier,
|
||||
total: entries.reduce((sum, item) => sum + item.total, 0),
|
||||
successRate: acceptedCount === 0 ? 0 : successCount * 100 / acceptedCount,
|
||||
averageArrivalMs: arrivalCount === 0 ? null : Math.round(arrivalWeight / arrivalCount),
|
||||
channelCount: new Set(entries.map((item) => item.channelId)).size,
|
||||
};
|
||||
})
|
||||
.filter((item): item is NonNullable<typeof item> => item !== null);
|
||||
}
|
||||
|
||||
function normalizeCarrier(value: string) {
|
||||
const normalized = value.toLowerCase();
|
||||
if (['mobile', 'cmcc', '移动'].includes(normalized)) return 'mobile';
|
||||
|
||||
@@ -204,31 +204,33 @@ export function AdminReportMaterialsPage() {
|
||||
{ key: 'files', title: '报备文件', align: 'right', render: (batch) => <div className="table-actions">{batch.exportFiles.map((file) => file.fileObjectId ? <a href={fileDownloadUrl(file.fileObjectId)} key={file.id}><Download size={15} />{file.fileName}({file.rowCount}行)</a> : null)}</div> },
|
||||
], []);
|
||||
|
||||
const filter = <div className="surface report-material-filter">
|
||||
const filter = <div className={`surface report-material-filter report-material-filter--${activeTab}`}>
|
||||
{activeTab === 'pending' ? <Select label="资料类型" onChange={(event) => { setReportType(event.target.value); setPendingPage(1); }} options={[{ label: '全部资料', value: 'all' }, { label: '签名资料', value: 'signature' }, { label: '引流信息', value: 'drainage' }]} value={reportType} /> : null}
|
||||
<Input label={activeTab === 'pending' ? '企业/应用/签名/站点' : '报备批次号'} onChange={(event) => setKeyword(event.target.value)} placeholder={activeTab === 'pending' ? '搜索待生成资料' : '搜索报备批次号'} value={keyword} />
|
||||
<DateRangeInput label={activeTab === 'pending' ? '资料变更时间' : '批次生成时间'} onChange={setDateRange} value={dateRange} />
|
||||
<Button icon={<Search size={16} />} onClick={() => {
|
||||
if (activeTab === 'pending') {
|
||||
setPendingPage(1);
|
||||
void loadPending(1);
|
||||
} else {
|
||||
setBatchPage(1);
|
||||
void loadBatches(1);
|
||||
}
|
||||
}}>查询</Button>
|
||||
<Button onClick={() => {
|
||||
setKeyword('');
|
||||
setDateRange({});
|
||||
if (activeTab === 'pending') {
|
||||
setReportType('all');
|
||||
setPendingPage(1);
|
||||
void loadPending(1, { keyword: '', dateRange: {}, reportType: 'all' });
|
||||
} else {
|
||||
setBatchPage(1);
|
||||
void loadBatches(1, { keyword: '', dateRange: {} });
|
||||
}
|
||||
}} variant="ghost">重置</Button>
|
||||
<div className="ui-query-actions">
|
||||
<Button icon={<Search size={16} />} onClick={() => {
|
||||
if (activeTab === 'pending') {
|
||||
setPendingPage(1);
|
||||
void loadPending(1);
|
||||
} else {
|
||||
setBatchPage(1);
|
||||
void loadBatches(1);
|
||||
}
|
||||
}}>查询</Button>
|
||||
<Button onClick={() => {
|
||||
setKeyword('');
|
||||
setDateRange({});
|
||||
if (activeTab === 'pending') {
|
||||
setReportType('all');
|
||||
setPendingPage(1);
|
||||
void loadPending(1, { keyword: '', dateRange: {}, reportType: 'all' });
|
||||
} else {
|
||||
setBatchPage(1);
|
||||
void loadBatches(1, { keyword: '', dateRange: {} });
|
||||
}
|
||||
}} variant="ghost">重置</Button>
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
return <section className="page-stack report-material-page">
|
||||
|
||||
Reference in New Issue
Block a user