fix: harden real backend workflows and channel connections
This commit is contained in:
@@ -1,16 +1,11 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Layers3, Plus, Search, UsersRound } from 'lucide-react';
|
||||
import { Layers3, Pencil, Plus, Search, Trash2, UsersRound } from 'lucide-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Breadcrumb, Button, Input, Modal, Pagination } from '@/components/ui';
|
||||
import { adminApi, type ChannelGroup } from '@/api/adminApi';
|
||||
|
||||
type GroupCarrier = 'mobile' | 'unicom' | 'telecom';
|
||||
|
||||
const carrierOptions: Array<{ label: string; value: GroupCarrier }> = [
|
||||
{ label: '移动', value: 'mobile' },
|
||||
{ label: '联通', value: 'unicom' },
|
||||
{ label: '电信', value: 'telecom' },
|
||||
];
|
||||
|
||||
const carrierLabels: Record<GroupCarrier, string> = {
|
||||
mobile: '移动',
|
||||
unicom: '联通',
|
||||
@@ -18,12 +13,10 @@ const carrierLabels: Record<GroupCarrier, string> = {
|
||||
};
|
||||
|
||||
export function AdminChannelGroupsPage() {
|
||||
const navigate = useNavigate();
|
||||
const [groupName, setGroupName] = useState('');
|
||||
const [groups, setGroups] = useState<ChannelGroup[]>([]);
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [name, setName] = useState('');
|
||||
const [code, setCode] = useState('');
|
||||
const [carrier, setCarrier] = useState<GroupCarrier>('mobile');
|
||||
const [deleteTarget, setDeleteTarget] = useState<ChannelGroup | null>(null);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
function loadData() {
|
||||
@@ -41,16 +34,14 @@ export function AdminChannelGroupsPage() {
|
||||
|
||||
const filteredGroups = useMemo(() => groups.filter((group) => !groupName.trim() || group.name.includes(groupName.trim())), [groupName, groups]);
|
||||
|
||||
function createGroup() {
|
||||
adminApi.createChannelGroup({ code, name, carrier, status: 'active' })
|
||||
function deleteGroup() {
|
||||
if (!deleteTarget) return;
|
||||
adminApi.deleteChannelGroup(deleteTarget.id)
|
||||
.then(() => {
|
||||
setModalOpen(false);
|
||||
setName('');
|
||||
setCode('');
|
||||
setCarrier('mobile');
|
||||
setDeleteTarget(null);
|
||||
loadData();
|
||||
})
|
||||
.catch((failure: Error) => setError(failure.message || '通道组创建失败'));
|
||||
.catch((failure: Error) => setError(failure.message || '通道组删除失败'));
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -59,7 +50,7 @@ export function AdminChannelGroupsPage() {
|
||||
<div>
|
||||
<Breadcrumb items={['短信通道组管理']} />
|
||||
</div>
|
||||
<Button icon={<Plus size={16} />} onClick={() => setModalOpen(true)}>
|
||||
<Button icon={<Plus size={16} />} onClick={() => navigate('/admin/channel-groups/new')}>
|
||||
添加通道组
|
||||
</Button>
|
||||
</div>
|
||||
@@ -92,6 +83,14 @@ export function AdminChannelGroupsPage() {
|
||||
})}
|
||||
{(group.items?.length ?? 0) === 0 ? <p className="muted">暂无绑定通道</p> : null}
|
||||
</div>
|
||||
<footer>
|
||||
<button onClick={() => navigate(`/admin/channel-groups/${group.id}/edit`)} type="button">
|
||||
<Pencil size={15} />编辑
|
||||
</button>
|
||||
<button className="is-danger" onClick={() => setDeleteTarget(group)} type="button">
|
||||
<Trash2 size={15} />删除
|
||||
</button>
|
||||
</footer>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
@@ -101,26 +100,17 @@ export function AdminChannelGroupsPage() {
|
||||
<Modal
|
||||
footer={(
|
||||
<>
|
||||
<Button onClick={() => setModalOpen(false)} variant="ghost">取消</Button>
|
||||
<Button disabled={!name || !code} onClick={createGroup}>保存</Button>
|
||||
<Button onClick={() => setDeleteTarget(null)} variant="ghost">取消</Button>
|
||||
<Button onClick={deleteGroup} variant="danger">确认删除</Button>
|
||||
</>
|
||||
)}
|
||||
onClose={() => setModalOpen(false)}
|
||||
open={modalOpen}
|
||||
title="添加通道组"
|
||||
onClose={() => setDeleteTarget(null)}
|
||||
open={Boolean(deleteTarget)}
|
||||
title="删除通道组"
|
||||
>
|
||||
<div className="admin-system-modal-form">
|
||||
<Input label="通道组编码" onChange={(event) => setCode(event.target.value)} value={code} />
|
||||
<Input label="通道组名称" onChange={(event) => setName(event.target.value)} value={name} />
|
||||
<div className="channel-group-radio-row">
|
||||
<span>运营商</span>
|
||||
{carrierOptions.map((item) => (
|
||||
<label key={item.value}>
|
||||
<input checked={carrier === item.value} onChange={() => setCarrier(item.value)} type="radio" />
|
||||
{item.label}
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
<div className="channel-confirm">
|
||||
<strong>{deleteTarget?.name}</strong>
|
||||
<p>删除前会校验真实路由绑定;已被企业应用使用的通道组不会被删除。</p>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user