assistant/apps/admin/src/components/LoginDetectionNotice.tsx

30 lines
2.1 KiB
TypeScript

import { Alert, Space, Tag } from 'antd';
import type { LoginDetection } from '../types';
const states = {
logged_in: { type: 'success', label: '已登录', description: '无需重复扫码,确认当前账号后继续。页面信号不代替账号身份确认。' },
logged_out: { type: 'warning', label: '未登录', description: '请在官方浏览器窗口自行完成登录,再刷新并确认当前账号。' },
verification_required: { type: 'warning', label: '需验证码或人工验证', description: '请在官方浏览器窗口自行完成验证,再刷新并确认当前账号。' },
unknown: { type: 'info', label: '登录状态不确定', description: '当前可见页面信号不足,请在官方浏览器窗口核对账号;确认后可继续。' },
} as const;
const evidenceLabels: Record<string, string> = {
visible_current_account_navigation: '可见当前账号导航',
visible_login_dialog: '可见登录窗口',
visible_login_entry: '可见登录入口',
visible_verification_widget: '可见验证控件',
no_conclusive_visible_evidence: '缺少明确页面依据',
unsupported_platform: '此平台尚无检测适配',
inspection_unavailable: '当前页面暂不可检测',
};
export function LoginDetectionNotice({ detection, sessionNeedsReopen = false }: { detection?: LoginDetection; sessionNeedsReopen?: boolean }) {
if (!detection) return null;
const state = states[detection.state] || states.unknown;
const evidence = (detection.evidence || []).filter(item => Object.hasOwn(evidenceLabels, item)).slice(0, 8);
return <Alert className="login-detection-notice" type={state.type} showIcon data-testid="login-detection-notice"
message={`页面登录检测:${state.label}`} description={<>
<p>{sessionNeedsReopen ? '页面信号仅反映当前登录状态。本次会话已阻断,请先关闭并重新打开浏览器,再核对账号。' : state.description}</p>
{evidence.length > 0 && <Space wrap size={4} aria-label="有限页面信号">{evidence.map((item, index) => <Tag key={index}>{evidenceLabels[item]}</Tag>)}</Space>}
</>} />;
}