fix: track live downstream cmpp connections

This commit is contained in:
hectorzhao
2026-07-11 19:16:52 +08:00
parent 76e0417ccf
commit 2fea15ef25
21 changed files with 477 additions and 141 deletions
@@ -250,18 +250,20 @@ export function AdminEnterpriseTemplatesPage() {
const [applications, setApplications] = useState<ClientSmsApplication[]>([]);
const [deleteTarget, setDeleteTarget] = useState<ClientSmsTemplate | null>(null);
const [enterpriseKeyword, setEnterpriseKeyword] = useState('');
const [appliedEnterpriseKeyword, setAppliedEnterpriseKeyword] = useState('');
const [error, setError] = useState('');
const [signatureItems, setSignatureItems] = useState<ClientSmsSignature[]>([]);
const [templateModal, setTemplateModal] = useState<ClientSmsTemplate | 'new' | null>(null);
const [templatePreview, setTemplatePreview] = useState<ClientSmsTemplate | null>(null);
const [templates, setTemplates] = useState<ClientSmsTemplate[]>([]);
const [templateKeyword, setTemplateKeyword] = useState('');
const [appliedTemplateKeyword, setAppliedTemplateKeyword] = useState('');
const [tenants, setTenants] = useState<TenantOption[]>([]);
async function loadData() {
async function loadData(filters = { enterpriseKeyword: appliedEnterpriseKeyword, templateKeyword: appliedTemplateKeyword }) {
try {
const [templateItems, tenantItems, applicationItems, signatureList] = await Promise.all([
adminApi.listEnterpriseTemplates({ keyword: [enterpriseKeyword, templateKeyword].filter(Boolean).join(' ') }),
adminApi.listEnterpriseTemplates({ keyword: [filters.enterpriseKeyword, filters.templateKeyword].filter(Boolean).join(' ') }),
adminApi.listTenants(),
adminApi.listEnterpriseApplications(),
adminApi.listEnterpriseSignatures(),
@@ -283,9 +285,9 @@ export function AdminEnterpriseTemplatesPage() {
const filteredTemplates = useMemo(() => templates.filter((item) => {
const enterprise = item.tenant?.name ?? item.tenantId;
const application = item.application?.name ?? '';
return (!enterpriseKeyword || enterprise.includes(enterpriseKeyword))
&& (!templateKeyword || item.name.includes(templateKeyword) || item.content.includes(templateKeyword) || application.includes(templateKeyword));
}), [enterpriseKeyword, templateKeyword, templates]);
return (!appliedEnterpriseKeyword || enterprise.includes(appliedEnterpriseKeyword))
&& (!appliedTemplateKeyword || item.name.includes(appliedTemplateKeyword) || item.content.includes(appliedTemplateKeyword) || application.includes(appliedTemplateKeyword));
}), [appliedEnterpriseKeyword, appliedTemplateKeyword, templates]);
async function saveTemplate(state: TemplateFormState) {
const existing = templateModal && templateModal !== 'new' ? templateModal : null;
@@ -363,8 +365,22 @@ export function AdminEnterpriseTemplatesPage() {
<div className="surface admin-split-filter">
<Input label="企业名称" onChange={(event) => setEnterpriseKeyword(event.target.value)} placeholder="请输入企业名称" prefix={<Search size={16} />} value={enterpriseKeyword} />
<Input label="模板/应用/内容" onChange={(event) => setTemplateKeyword(event.target.value)} placeholder="请输入模板、应用或内容" prefix={<Search size={16} />} value={templateKeyword} />
<Button onClick={() => { setEnterpriseKeyword(''); setTemplateKeyword(''); void loadData(); }} variant="ghost"></Button>
<Button icon={<Search size={16} />} onClick={() => { void loadData(); }}></Button>
<div className="admin-split-filter__actions">
<Button icon={<Search size={16} />} onClick={() => {
const filters = { enterpriseKeyword: enterpriseKeyword.trim(), templateKeyword: templateKeyword.trim() };
setAppliedEnterpriseKeyword(filters.enterpriseKeyword);
setAppliedTemplateKeyword(filters.templateKeyword);
void loadData(filters);
}}></Button>
<Button onClick={() => {
const filters = { enterpriseKeyword: '', templateKeyword: '' };
setEnterpriseKeyword('');
setTemplateKeyword('');
setAppliedEnterpriseKeyword('');
setAppliedTemplateKeyword('');
void loadData(filters);
}} variant="ghost"></Button>
</div>
</div>
<div className="surface section-stack">
<Tabs