fix: track live downstream cmpp connections
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Plus, Search } from 'lucide-react';
|
||||
import { Database, ListFilter, Plus, RotateCcw, Search } from 'lucide-react';
|
||||
import { Breadcrumb, Button, Input, Modal, Pagination, Select, Table, Tabs, type TableColumn } from '@/components/ui';
|
||||
import { adminApi, type DictionaryItem } from '@/api/adminApi';
|
||||
import { formatDateTime } from '@/utils/dateTime';
|
||||
|
||||
type PhoneSegment = DictionaryItem & {
|
||||
prefix?: string;
|
||||
@@ -42,20 +43,12 @@ export function AdminPhoneSegmentsPage() {
|
||||
const [rulePage, setRulePage] = useState(1);
|
||||
const [reloadKey, setReloadKey] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = window.setTimeout(() => {
|
||||
setSegmentQuery(keyword.trim());
|
||||
setPage(1);
|
||||
}, 300);
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [keyword]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
Promise.all([
|
||||
adminApi.listPhoneSegments({ keyword: segmentQuery || undefined, page, pageSize }),
|
||||
adminApi.listPhoneCarrierRules({ keyword: activeTab === 'rules' ? segmentQuery || undefined : undefined, page: rulePage, pageSize }),
|
||||
adminApi.listPhoneCarrierRules({ keyword: segmentQuery || undefined, page: rulePage, pageSize }),
|
||||
])
|
||||
.then(([segmentPage, ruleResponse]) => {
|
||||
if (cancelled) return;
|
||||
@@ -74,7 +67,7 @@ export function AdminPhoneSegmentsPage() {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [activeTab, page, reloadKey, rulePage, segmentQuery]);
|
||||
}, [page, reloadKey, rulePage, segmentQuery]);
|
||||
|
||||
const segmentTotalPages = Math.max(1, Math.ceil(segmentTotal / pageSize));
|
||||
const ruleTotalPages = Math.max(1, Math.ceil(ruleTotal / pageSize));
|
||||
@@ -103,12 +96,25 @@ export function AdminPhoneSegmentsPage() {
|
||||
.catch((failure: Error) => setError(failure.message || '运营商区分规则新增失败'));
|
||||
}
|
||||
|
||||
function query() {
|
||||
setSegmentQuery(keyword.trim());
|
||||
setPage(1);
|
||||
setRulePage(1);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
setKeyword('');
|
||||
setSegmentQuery('');
|
||||
setPage(1);
|
||||
setRulePage(1);
|
||||
}
|
||||
|
||||
const columns = useMemo<Array<TableColumn<PhoneSegment>>>(() => [
|
||||
{ key: 'segment', title: '手机号段(手机号码前7位)', width: '230px', render: (record) => <strong>{record.prefix}</strong> },
|
||||
{ key: 'carrier', title: '运营商', width: '150px', render: (record) => record.carrier ?? '-' },
|
||||
{ key: 'province', title: '省份', width: '140px', render: (record) => record.province ?? '-' },
|
||||
{ key: 'city', title: '城市', width: '140px', render: (record) => record.city ?? '-' },
|
||||
{ key: 'createdAt', title: '创建时间', width: '190px', render: (record) => record.createdAt ?? '-' },
|
||||
{ key: 'createdAt', title: '创建时间', width: '190px', render: (record) => formatDateTime(record.createdAt) },
|
||||
], []);
|
||||
|
||||
const ruleColumns = useMemo<Array<TableColumn<CarrierRule>>>(() => [
|
||||
@@ -119,28 +125,42 @@ export function AdminPhoneSegmentsPage() {
|
||||
], []);
|
||||
|
||||
return (
|
||||
<section className="page-stack admin-system-page">
|
||||
<section className="page-stack admin-system-page phone-segment-workbench">
|
||||
<div className="page-heading">
|
||||
<div>
|
||||
<Breadcrumb items={['系统管理', '手机号段库']} />
|
||||
<h1>手机号段库</h1>
|
||||
</div>
|
||||
</div>
|
||||
{error ? <p className="form-error">{error}</p> : null}
|
||||
|
||||
<div className="surface admin-system-toolbar phone-segment-toolbar">
|
||||
<Input onChange={(event) => setKeyword(event.target.value)} placeholder={activeTab === 'segments' ? '搜索手机号段、运营商、省份或城市' : '搜索运营商、正则或备注'} prefix={<Search size={16} />} value={keyword} />
|
||||
<Button icon={<Plus size={16} />} onClick={() => activeTab === 'segments' ? setCreating(true) : setCreatingRule(true)}>
|
||||
{activeTab === 'segments' ? '新增号段' : '新增规则'}
|
||||
</Button>
|
||||
</div>
|
||||
{error ? <p className="form-error">{error}</p> : null}
|
||||
|
||||
<div className="phone-segment-overview" aria-label="号段数据概览">
|
||||
<section>
|
||||
<span><Database size={20} /></span>
|
||||
<div><strong>{segmentTotal.toLocaleString('zh-CN')}</strong><p>已收录手机号段</p></div>
|
||||
</section>
|
||||
<section>
|
||||
<span><ListFilter size={20} /></span>
|
||||
<div><strong>{ruleTotal.toLocaleString('zh-CN')}</strong><p>运营商识别规则</p></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div className="surface phone-segment-query">
|
||||
<Input label="关键词" onChange={(event) => setKeyword(event.target.value)} placeholder={activeTab === 'segments' ? '手机号段、运营商、省份或城市' : '运营商、正则或备注'} prefix={<Search size={16} />} value={keyword} />
|
||||
<div className="phone-segment-query__actions">
|
||||
<Button icon={<Search size={16} />} onClick={query}>查询</Button>
|
||||
<Button icon={<RotateCcw size={16} />} onClick={reset} variant="ghost">重置</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="surface admin-system-table-card">
|
||||
<Tabs
|
||||
className="phone-segment-tabs"
|
||||
className="phone-segment-workbench__tabs"
|
||||
onChange={(value) => {
|
||||
setActiveTab(value as 'segments' | 'rules');
|
||||
setRulePage(1);
|
||||
}}
|
||||
value={activeTab}
|
||||
items={[
|
||||
|
||||
Reference in New Issue
Block a user