fix: implement channel group routing failover

This commit is contained in:
hectorzhao
2026-07-03 11:07:43 +08:00
parent 131f344ac4
commit a890b03163
16 changed files with 853 additions and 121 deletions
+40 -3
View File
@@ -1,7 +1,7 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { ArrowLeft } from 'lucide-react';
import { adminApi } from '@/api/adminApi';
import { adminApi, type ChannelGroup } from '@/api/adminApi';
import { Breadcrumb, Button, Input, Select } from '@/components/ui';
export function AdminSmsApplicationFormPage() {
@@ -14,8 +14,18 @@ export function AdminSmsApplicationFormPage() {
const [phoneDailyLimit, setPhoneDailyLimit] = useState('10');
const [mismatchPolicy, setMismatchPolicy] = useState('manual_review');
const [ipAddress, setIpAddress] = useState('');
const [groups, setGroups] = useState<ChannelGroup[]>([]);
const [mobileGroupId, setMobileGroupId] = useState('');
const [unicomGroupId, setUnicomGroupId] = useState('');
const [telecomGroupId, setTelecomGroupId] = useState('');
const [error, setError] = useState('');
useEffect(() => {
adminApi.listChannelGroups()
.then((items) => setGroups(items.filter((item) => item.status !== 'disabled' && item.status !== 'deleted')))
.catch((failure: Error) => setError(failure.message || '通道组加载失败'));
}, []);
function goBack() {
navigate('/admin/enterprise-applications');
}
@@ -29,6 +39,15 @@ export function AdminSmsApplicationFormPage() {
setError('短信应用编辑接口待补,当前不做本地模拟保存');
return;
}
const selectedGroups = [
{ carrier: 'mobile', groupId: mobileGroupId },
{ carrier: 'unicom', groupId: unicomGroupId },
{ carrier: 'telecom', groupId: telecomGroupId },
].filter((item) => item.groupId);
if (selectedGroups.length === 0) {
setError('请至少配置一个运营商通道组');
return;
}
adminApi.createEnterpriseApplication({
tenantId: enterpriseId,
name: appName,
@@ -38,10 +57,25 @@ export function AdminSmsApplicationFormPage() {
templateMismatchMode: mismatchPolicy,
ipAllowlist: ipAddress ? [ipAddress] : [],
})
.then(goBack)
.then(async (application) => {
await Promise.all(selectedGroups.map((item, index) => adminApi.createChannelRouteRule({
tenantId: enterpriseId,
applicationId: application.id,
groupId: item.groupId,
carrier: item.carrier,
priority: (index + 1) * 10,
status: 'active',
})));
goBack();
})
.catch((failure: Error) => setError(failure.message || '短信应用保存失败'));
}
const groupOptions = [
{ label: '不配置', value: '' },
...groups.map((group) => ({ label: group.name, value: group.id })),
];
return (
<section className="page-stack admin-app-form-page">
<div className="page-heading">
@@ -73,6 +107,9 @@ export function AdminSmsApplicationFormPage() {
value={mismatchPolicy}
/>
<Input label="IP 白名单" onChange={(event) => setIpAddress(event.target.value)} placeholder="例如 192.168.1.100/32" value={ipAddress} />
<Select label="移动通道组" onChange={(event) => setMobileGroupId(event.target.value)} options={groupOptions} value={mobileGroupId} />
<Select label="联通通道组" onChange={(event) => setUnicomGroupId(event.target.value)} options={groupOptions} value={unicomGroupId} />
<Select label="电信通道组" onChange={(event) => setTelecomGroupId(event.target.value)} options={groupOptions} value={telecomGroupId} />
</div>
</section>