fix: harden channel retry attribution and operations UI
This commit is contained in:
@@ -11,10 +11,30 @@ type AdminCustomersPageProps = {
|
||||
|
||||
type CustomerRow = TenantManagementRow;
|
||||
|
||||
function ConfirmModal({ message, onCancel, onConfirm }: { message: string; onCancel: () => void; onConfirm: () => void }) {
|
||||
function ConfirmModal({
|
||||
error,
|
||||
isSubmitting,
|
||||
message,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
type,
|
||||
}: {
|
||||
error: string;
|
||||
isSubmitting: boolean;
|
||||
message: string;
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
type: 'toggle' | 'delete';
|
||||
}) {
|
||||
return (
|
||||
<Modal footer={<><Button onClick={onCancel} variant="ghost">取消</Button><Button onClick={onConfirm}>确认</Button></>} onClose={onCancel} open title="操作确认">
|
||||
<Modal
|
||||
footer={<><Button disabled={isSubmitting} onClick={onCancel} variant="ghost">取消</Button><Button disabled={isSubmitting} onClick={onConfirm} variant={type === 'delete' ? 'danger' : 'primary'}>{isSubmitting ? '处理中...' : '确认'}</Button></>}
|
||||
onClose={() => { if (!isSubmitting) onCancel(); }}
|
||||
open
|
||||
title={type === 'delete' ? '删除企业' : '变更企业状态'}
|
||||
>
|
||||
<p className="admin-confirm-text">{message}</p>
|
||||
{error ? <p className="form-error" role="alert">{error}</p> : null}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -26,6 +46,8 @@ export function AdminCustomersPage({ basePath = '/admin/customers' }: AdminCusto
|
||||
const [queryStatus, setQueryStatus] = useState('all');
|
||||
const [filters, setFilters] = useState({ name: '', status: 'all' });
|
||||
const [confirmAction, setConfirmAction] = useState<{ type: 'toggle' | 'delete'; record: CustomerRow } | null>(null);
|
||||
const [confirmError, setConfirmError] = useState('');
|
||||
const [confirming, setConfirming] = useState(false);
|
||||
const [rechargeTarget, setRechargeTarget] = useState<CustomerRow | null>(null);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
@@ -82,10 +104,10 @@ export function AdminCustomersPage({ basePath = '/admin/customers' }: AdminCusto
|
||||
<div className="table-actions">
|
||||
<Button icon={<DollarSign size={15} />} onClick={() => openRechargeModal(record)} size="sm" variant="ghost">充值</Button>
|
||||
<Button onClick={() => navigate(`${basePath}/${record.id}/edit`)} size="sm" variant="ghost">编辑</Button>
|
||||
<Button onClick={() => setConfirmAction({ type: 'toggle', record })} size="sm" variant={record.status === 'active' ? 'warning' : 'success'}>
|
||||
<Button onClick={() => openConfirmAction({ type: 'toggle', record })} size="sm" variant={record.status === 'active' ? 'warning' : 'success'}>
|
||||
{record.status === 'active' ? '禁用' : '启用'}
|
||||
</Button>
|
||||
<Button icon={<Trash2 size={15} />} onClick={() => setConfirmAction({ type: 'delete', record })} size="sm" variant="danger">删除</Button>
|
||||
<Button icon={<Trash2 size={15} />} onClick={() => openConfirmAction({ type: 'delete', record })} size="sm" variant="danger">删除</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -95,15 +117,35 @@ export function AdminCustomersPage({ basePath = '/admin/customers' }: AdminCusto
|
||||
setRechargeTarget(record);
|
||||
}
|
||||
|
||||
function submitConfirmAction() {
|
||||
function openConfirmAction(action: { type: 'toggle' | 'delete'; record: CustomerRow }) {
|
||||
setConfirmError('');
|
||||
setConfirmAction(action);
|
||||
}
|
||||
|
||||
async function submitConfirmAction() {
|
||||
if (!confirmAction) return;
|
||||
const action = confirmAction.type === 'delete'
|
||||
? adminApi.deleteTenant(confirmAction.record.id)
|
||||
: adminApi.changeTenantStatus(confirmAction.record.id, confirmAction.record.status === 'active' ? 'disabled' : 'active');
|
||||
action.then(() => {
|
||||
setConfirmAction(null);
|
||||
loadData();
|
||||
}).catch((failure: Error) => setError(failure.message || '企业状态更新失败'));
|
||||
setConfirming(true);
|
||||
setConfirmError('');
|
||||
try {
|
||||
if (confirmAction.type === 'delete') {
|
||||
await adminApi.deleteTenant(confirmAction.record.id);
|
||||
} else {
|
||||
await adminApi.changeTenantStatus(confirmAction.record.id, confirmAction.record.status === 'active' ? 'disabled' : 'active');
|
||||
}
|
||||
} catch (failure) {
|
||||
const detail = failure instanceof Error ? failure.message : '企业操作失败';
|
||||
setConfirmError(`${confirmAction.type === 'delete' ? '删除' : '状态变更'}失败:${detail}`);
|
||||
setConfirming(false);
|
||||
return;
|
||||
}
|
||||
setConfirmAction(null);
|
||||
try {
|
||||
await loadData();
|
||||
} catch (failure) {
|
||||
setError(failure instanceof Error ? failure.message : '企业列表刷新失败');
|
||||
} finally {
|
||||
setConfirming(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -140,9 +182,12 @@ export function AdminCustomersPage({ basePath = '/admin/customers' }: AdminCusto
|
||||
|
||||
{confirmAction ? (
|
||||
<ConfirmModal
|
||||
error={confirmError}
|
||||
isSubmitting={confirming}
|
||||
message={confirmAction.type === 'delete' ? `确认删除企业“${confirmAction.record.name}”吗?` : `确认${confirmAction.record.status === 'active' ? '禁用' : '启用'}企业“${confirmAction.record.name}”吗?`}
|
||||
onCancel={() => setConfirmAction(null)}
|
||||
onConfirm={submitConfirmAction}
|
||||
onCancel={() => { setConfirmAction(null); setConfirmError(''); }}
|
||||
onConfirm={() => void submitConfirmAction()}
|
||||
type={confirmAction.type}
|
||||
/>
|
||||
) : null}
|
||||
<ManualRechargeDialog
|
||||
|
||||
Reference in New Issue
Block a user