import { useState, type ReactNode } from 'react'; import { AlertTriangle, ShieldCheck, Trash2 } from 'lucide-react'; import { adminApi, clientApi, type DeletionPreflight, type DeletionResult, type DeletionTargetType } from '@/api/adminApi'; import { createUuid } from '@/utils/randomId'; import { Button } from './Button'; import { Modal } from './Modal'; import { Textarea } from './Textarea'; export function DeleteRiskAction({ portal, targetType, targetId, children = '删除', icon = , disabled, onCompleted }: { portal: 'admin' | 'client'; targetType: DeletionTargetType; targetId: string; children?: ReactNode; icon?: ReactNode; disabled?: boolean; onCompleted?: (result: DeletionResult) => void; }) { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [submitting, setSubmitting] = useState(false); const [preflight, setPreflight] = useState(null); const [result, setResult] = useState(null); const [reason, setReason] = useState(''); const [error, setError] = useState(''); const [idempotencyKey, setIdempotencyKey] = useState(''); async function begin() { const key = `delete:${targetType}:${targetId}:${createUuid()}`; setOpen(true); setLoading(true); setPreflight(null); setResult(null); setReason(''); setError(''); setIdempotencyKey(key); try { const data = portal === 'admin' ? await adminApi.getDeletionPreflight(targetType, targetId) : await clientApi.getDeletionPreflight(targetType as Exclude, targetId); setPreflight(data); } catch (failure) { setError(failure instanceof Error ? failure.message : '删除资格预检失败'); } finally { setLoading(false); } } async function confirm() { if (!preflight?.allowedActions.includes('delete') || reason.trim().length < 4) return; setSubmitting(true); setError(''); try { const body = { expectedUpdatedAt: preflight.expectedUpdatedAt, idempotencyKey, reason: reason.trim() }; const completed = portal === 'admin' ? await adminApi.deleteGovernedTarget(targetType, targetId, body) : await clientApi.deleteGovernedTarget(targetType as Exclude, targetId, body); setResult(completed); onCompleted?.(completed); } catch (failure) { setError(failure instanceof Error ? failure.message : '删除失败,请重新检查依赖后重试'); } finally { setSubmitting(false); } } function close() { if (!submitting) setOpen(false); } const blocked = Boolean(preflight && !preflight.allowedActions.includes('delete')); const footer = (requestClose: () => void) => result ? : <> ; return <> 0} footer={({ requestClose }) => footer(requestClose)} onClose={close} open={open} title="删除资格与影响确认">
{loading ?

正在从后台检查引用关系与当前状态…

: null} {preflight ? <>
{Object.entries(preflight.identity).map(([key, value]) =>
{identityLabels[key] ?? key}{value}
)}

依赖与资格检查

{preflight.dependencies.length ?
    {preflight.dependencies.map((item) =>
  • {item.label}{item.count} 项{item.items.length ? {item.items.join(';')} : 无活动引用}
  • )}
: null}
{preflight.blockedReasons.length ?
    {preflight.blockedReasons.map((item) =>
  • {item}
  • )}
:

资格检查通过,可以执行逻辑删除

}

影响范围

    {preflight.impacts.map((item) =>
  • {item}
  • )}

{preflight.recoverability.description}

{!blocked ?