feat: harden platform workflows and UI governance

This commit is contained in:
hectorzhao
2026-07-22 14:14:55 +08:00
parent ef957f7daa
commit 0f223f7f91
80 changed files with 4958 additions and 764 deletions
+6 -19
View File
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
import { CheckCircle2, Copy, Eye, ExternalLink, FileText, Info, Pencil, Plus, Power, Search, Send, Trash2 } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { adminApi, type AdminChannel, type ChannelConnectionLogResponse, type ChannelTestResponse, type CmppConnectionState } from '@/api/adminApi';
import { Breadcrumb, Button, Input, Modal, Pagination, Select, Tag, Textarea } from '@/components/ui';
import { Breadcrumb, Button, DeleteRiskAction, Input, Modal, Pagination, Select, Tag, Textarea } from '@/components/ui';
import { formatDateTime } from '@/utils/dateTime';
import { formatCents, isValidMoneyInput, moneyUnitsToYuan, yuanToMoneyUnits } from '@/utils/currency';
@@ -42,7 +42,7 @@ type ChannelModalState = {
};
type ChannelConfirmAction = {
type: 'toggle' | 'delete' | 'copy';
type: 'toggle' | 'copy';
channel: SmsChannel;
};
@@ -532,11 +532,6 @@ export function AdminChannelsPage() {
loadChannels();
}
async function deleteChannel(id: string) {
await adminApi.deleteChannel(id, '运营端删除通道');
setChannels((items) => items.filter((item) => item.id !== id));
}
async function copyChannel(channel: SmsChannel) {
await adminApi.copyChannel(channel.id);
loadChannels();
@@ -563,10 +558,6 @@ export function AdminChannelsPage() {
void toggleChannel(confirmAction.channel);
}
if (confirmAction.type === 'delete') {
void deleteChannel(confirmAction.channel.id);
}
if (confirmAction.type === 'copy') {
void copyChannel(confirmAction.channel);
}
@@ -574,17 +565,13 @@ export function AdminChannelsPage() {
setConfirmAction(null);
}
const confirmTitle = confirmAction?.type === 'delete'
? '确认删除通道'
: confirmAction?.type === 'copy'
const confirmTitle = confirmAction?.type === 'copy'
? '确认复制通道'
: confirmAction?.channel.status === 'stopped'
? '确认启用通道'
: '确认停用通道';
const confirmDescription = confirmAction?.type === 'delete'
? '删除后该通道将从列表移除,副本通道的本地记录也会同步清理。'
: confirmAction?.type === 'copy'
const confirmDescription = confirmAction?.type === 'copy'
? '系统将复制当前通道配置和报备详情,并新建一条名称带“副本”的通道。'
: confirmAction?.channel.status === 'stopped'
? '启用后通道会进入连接中状态,后续可继续观察网关连接。'
@@ -651,7 +638,7 @@ export function AdminChannelsPage() {
<button className={channel.status === 'stopped' ? 'is-success' : 'is-warning'} onClick={() => setConfirmAction({ type: 'toggle', channel })} type="button">
<Power size={15} />{channel.status === 'stopped' ? '启用' : '停用'}
</button>
<button className="is-danger" onClick={() => setConfirmAction({ type: 'delete', channel })} type="button"><Trash2 size={15} /></button>
<DeleteRiskAction onCompleted={() => void loadChannels()} portal="admin" targetId={channel.id} targetType="channel" />
</div>
</article>
))}
@@ -691,7 +678,7 @@ export function AdminChannelsPage() {
footer={(
<>
<Button onClick={() => setConfirmAction(null)} variant="ghost"></Button>
<Button onClick={submitConfirmAction} variant={confirmAction.type === 'delete' ? 'danger' : 'primary'}></Button>
<Button onClick={submitConfirmAction}></Button>
</>
)}
onClose={() => setConfirmAction(null)}