import Link from "next/link"; import type { SubscriptionAccessLog, SubscriptionRiskEvent, SubscriptionStatus, SubscriptionType, UserStatus, } from "@prisma/client"; import { AlertTriangle, ShieldCheck, UserRound } from "lucide-react"; import { DataTableShell } from "@/components/admin/data-table-shell"; import { DataTable, DataTableBody, DataTableCell, DataTableHead, DataTableHeadCell, DataTableHeaderRow, DataTableRow, } from "@/components/shared/data-table"; import { SubscriptionStatusBadge, SubscriptionTypeBadge, UserStatusBadge, } from "@/components/shared/domain-badges"; import { StatusBadge, type StatusTone } from "@/components/shared/status-badge"; import { buttonVariants } from "@/components/ui/button"; import { SubscriptionRiskReviewActions } from "@/components/subscriptions/subscription-risk-review-actions"; import { formatDate, formatDateShort } from "@/lib/utils"; interface RiskOwner { id: string; email: string; name: string | null; status: UserStatus; } interface RiskSubscription { id: string; status: SubscriptionStatus; endDate: Date; plan: { name: string; type: SubscriptionType; }; } function formatLocation(item: Pick) { const parts = [item.country, item.region || item.regionCode, item.city].filter(Boolean); return parts.length > 0 ? parts.join(" / ") : "未知"; } function kindLabel(kind: SubscriptionAccessLog["kind"] | SubscriptionRiskEvent["kind"]) { return kind === "AGGREGATE" ? "总订阅" : "单订阅"; } function reasonLabel(reason: SubscriptionRiskEvent["reason"]) { switch (reason) { case "CITY_VARIANCE_WARNING": return "城市异常警告"; case "CITY_VARIANCE_SUSPEND": return "城市异常暂停"; case "REGION_VARIANCE_WARNING": return "省/地区异常警告"; case "REGION_VARIANCE_SUSPEND": return "省/地区异常暂停"; case "COUNTRY_VARIANCE_WARNING": return "国家异常警告"; case "COUNTRY_VARIANCE_SUSPEND": return "国家异常暂停"; } } function reviewStatusLabel(status: SubscriptionRiskEvent["reviewStatus"]) { switch (status) { case "OPEN": return "待处理"; case "ACKNOWLEDGED": return "已确认"; case "RESOLVED": return "已解决"; } } function reviewStatusTone(status: SubscriptionRiskEvent["reviewStatus"]): StatusTone { if (status === "RESOLVED") return "success"; if (status === "ACKNOWLEDGED") return "info"; return "warning"; } function canRestoreFromEvent(event: SubscriptionRiskEvent, subscription: RiskSubscription) { return event.subscriptionId === subscription.id && subscription.status === "SUSPENDED" && subscription.endDate > new Date(); } export function SubscriptionAccessRiskSection({ accessLogs, riskEvents, owner, subscription, }: { accessLogs: SubscriptionAccessLog[]; riskEvents: SubscriptionRiskEvent[]; owner: RiskOwner; subscription: RiskSubscription; }) { return (

订阅访问风控

记录订阅拉取 IP、地区变化和人工处理状态。

查看全部风控
关联用户
{owner.email}

{owner.name || "未设置昵称"}

{owner.id}

当前订阅
{subscription.plan.name}

到期:{formatDateShort(subscription.endDate)}

{subscription.id}

{riskEvents.length > 0 && (
最近风控事件
{riskEvents.map((event) => (
{reasonLabel(event.reason)} {reviewStatusLabel(event.reviewStatus)} {formatDate(event.createdAt)} · {kindLabel(event.kind)}

{event.message}

{(event.reviewedByEmail || event.reviewNote) && (
{event.reviewedByEmail &&

处理人:{event.reviewedByEmail}{event.reviewedAt ? ` · ${formatDate(event.reviewedAt)}` : ""}

} {event.reviewNote &&

{event.reviewNote}

}
)}
))}
)} 时间 类型 IP 地区 结果 User-Agent {accessLogs.map((log) => ( {formatDate(log.createdAt)} {kindLabel(log.kind)} {log.ip} {formatLocation(log)} {log.allowed ? "已放行" : log.reason || "已拦截"} {log.userAgent || "—"} ))}
); }