feat: densify sms records and improve uplink matching
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Search, Smartphone } from 'lucide-react';
|
||||
import { Search, Smartphone, UserX } from 'lucide-react';
|
||||
import { adminApi, type SmsMessageRecord, type SmsUplinkMatchCandidate, type SmsUplinkMessage } from '@/api/adminApi';
|
||||
import {
|
||||
Breadcrumb,
|
||||
@@ -40,28 +40,41 @@ function candidateStatusText(status?: string | null) {
|
||||
}
|
||||
|
||||
function UplinkDetailModal({
|
||||
blacklistFeedback,
|
||||
blacklisting,
|
||||
claimError,
|
||||
claimingId,
|
||||
detailError,
|
||||
matchedRecords,
|
||||
matching,
|
||||
message,
|
||||
onAddBlacklist,
|
||||
onClaim,
|
||||
onClose,
|
||||
}: {
|
||||
blacklistFeedback: string;
|
||||
blacklisting: boolean;
|
||||
claimError: string;
|
||||
claimingId: string;
|
||||
detailError: string;
|
||||
matchedRecords: SmsMessageRecord[];
|
||||
matching: boolean;
|
||||
message: SmsUplinkMessage;
|
||||
onAddBlacklist: () => void;
|
||||
onClaim: (candidate: SmsUplinkMatchCandidate) => void;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const candidates = message.matchCandidates ?? [];
|
||||
return (
|
||||
<Modal
|
||||
footer={<Button onClick={onClose} variant="ghost">关闭</Button>}
|
||||
footer={<>
|
||||
{message.tenantId && message.applicationId ? (
|
||||
<Button disabled={blacklisting} icon={<UserX size={15} />} onClick={onAddBlacklist}>
|
||||
{blacklisting ? '加入中...' : '加入应用黑名单'}
|
||||
</Button>
|
||||
) : null}
|
||||
<Button onClick={onClose} variant="ghost">关闭</Button>
|
||||
</>}
|
||||
onClose={onClose}
|
||||
open
|
||||
size="xl"
|
||||
@@ -92,13 +105,21 @@ function UplinkDetailModal({
|
||||
<strong>{message.destId || '-'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>网关消息ID</span>
|
||||
<strong>{message.messageId || '-'}</strong>
|
||||
<span>上行网关消息ID</span>
|
||||
<strong>{message.gatewayMessageId || '-'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>关联平台消息ID</span>
|
||||
<strong>{message.messageRecord?.messageId ?? message.messageId ?? '-'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>匹配状态</span>
|
||||
<strong>{matchStatusText(message.matchStatus)}</strong>
|
||||
</div>
|
||||
<div className="admin-uplink-info-grid__full">
|
||||
<span>匹配说明</span>
|
||||
<strong>{message.matchReason || '-'}</strong>
|
||||
</div>
|
||||
<div className="admin-uplink-info-grid__full">
|
||||
<span>上行内容</span>
|
||||
<strong>{message.content || '-'}</strong>
|
||||
@@ -160,11 +181,13 @@ function UplinkDetailModal({
|
||||
|
||||
<section className="admin-uplink-match-section">
|
||||
<h3>匹配发送记录</h3>
|
||||
{blacklistFeedback ? <p className={blacklistFeedback.startsWith('已') ? 'form-success' : 'form-error'}>{blacklistFeedback}</p> : null}
|
||||
{matching ? <p>正在查询真实下发记录...</p> : null}
|
||||
{detailError ? <p className="form-error">{detailError}</p> : null}
|
||||
{!matching && !message.messageId ? <div className="admin-uplink-empty-match">该上行记录没有网关消息ID,无法匹配下发记录</div> : null}
|
||||
{!matching && message.messageId && matchedRecords.length === 0 && !detailError ? (
|
||||
<div className="admin-uplink-empty-match">暂无匹配发送记录</div>
|
||||
{!matching && matchedRecords.length === 0 && !detailError ? (
|
||||
<div className="admin-uplink-empty-match">
|
||||
{message.matchStatus === 'ambiguous' ? '存在多个候选,请先认领正确应用' : '暂无匹配发送记录'}
|
||||
</div>
|
||||
) : null}
|
||||
{matchedRecords.map((record) => (
|
||||
<article className="admin-uplink-match-card" key={record.id}>
|
||||
@@ -211,6 +234,8 @@ export function AdminSmsUplinkRecordsPage() {
|
||||
const [error, setError] = useState('');
|
||||
const [detailError, setDetailError] = useState('');
|
||||
const [claimError, setClaimError] = useState('');
|
||||
const [blacklisting, setBlacklisting] = useState(false);
|
||||
const [blacklistFeedback, setBlacklistFeedback] = useState('');
|
||||
const [total, setTotal] = useState(0);
|
||||
const [page, setPage] = useState(1);
|
||||
const pageSize = 10;
|
||||
@@ -236,11 +261,12 @@ export function AdminSmsUplinkRecordsPage() {
|
||||
|
||||
function openDetail(message: SmsUplinkMessage) {
|
||||
setSelectedMessage(message);
|
||||
setMatchedRecords([]);
|
||||
setMatchedRecords(message.messageRecord ? [message.messageRecord] : []);
|
||||
setDetailError('');
|
||||
setClaimError('');
|
||||
setBlacklistFeedback('');
|
||||
|
||||
if (!message.messageId) {
|
||||
if (message.messageRecord || !message.messageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,6 +277,28 @@ export function AdminSmsUplinkRecordsPage() {
|
||||
.finally(() => setMatching(false));
|
||||
}
|
||||
|
||||
function handleAddBlacklist() {
|
||||
if (!selectedMessage?.tenantId || !selectedMessage.applicationId) {
|
||||
setBlacklistFeedback('请先匹配或认领企业应用');
|
||||
return;
|
||||
}
|
||||
if (!window.confirm(`确认将 ${selectedMessage.phoneNumber} 加入当前应用黑名单?`)) {
|
||||
return;
|
||||
}
|
||||
setBlacklisting(true);
|
||||
setBlacklistFeedback('');
|
||||
adminApi.createEnterpriseBlacklist({
|
||||
tenantId: selectedMessage.tenantId,
|
||||
applicationId: selectedMessage.applicationId,
|
||||
phoneNumber: selectedMessage.phoneNumber,
|
||||
reason: '上行短信人工加入',
|
||||
status: 'active',
|
||||
})
|
||||
.then(() => setBlacklistFeedback('已加入当前应用黑名单'))
|
||||
.catch((reason: Error) => setBlacklistFeedback(reason.message || '加入应用黑名单失败'))
|
||||
.finally(() => setBlacklisting(false));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadData(page);
|
||||
}, [page]);
|
||||
@@ -273,6 +321,7 @@ export function AdminSmsUplinkRecordsPage() {
|
||||
.then((updated) => {
|
||||
setMessages((items) => items.map((item) => (item.id === updated.id ? { ...item, ...updated } : item)));
|
||||
setSelectedMessage((current) => (current && current.id === updated.id ? { ...current, ...updated } : current));
|
||||
setMatchedRecords(updated.messageRecord ? [updated.messageRecord] : []);
|
||||
loadData(page);
|
||||
})
|
||||
.catch((reason: Error) => setClaimError(reason.message || '上行认领失败'))
|
||||
@@ -332,12 +381,15 @@ export function AdminSmsUplinkRecordsPage() {
|
||||
|
||||
{selectedMessage ? (
|
||||
<UplinkDetailModal
|
||||
blacklistFeedback={blacklistFeedback}
|
||||
blacklisting={blacklisting}
|
||||
claimError={claimError}
|
||||
claimingId={claimingId}
|
||||
detailError={detailError}
|
||||
matchedRecords={matchedRecords}
|
||||
matching={matching}
|
||||
message={selectedMessage}
|
||||
onAddBlacklist={handleAddBlacklist}
|
||||
onClaim={handleClaim}
|
||||
onClose={() => setSelectedMessage(null)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user