/** * OmniCard AI (CRMmp) - 用户端跨端核心数据契约与 TypeScript / UTS 类型体系 * 严格遵循 AGENTS.md 规范与出海 SaaS 契约,与 backend / admin 镜像对齐 */ export type CardStatus = 'draft' | 'published' | 'archived'; export interface CardProfile { id?: string | number; tenantId?: string | number; userId?: string | number; name: string; title?: string; company?: string; slogan?: string; avatarUrl?: string; phone?: string; email?: string; whatsapp?: string; linkedin?: string; telegram?: string; twitter?: string; wechat?: string; timezone?: string; audioPronunciationUrl?: string; audioPronounceUrl?: string; status?: CardStatus; themeCode?: string; url?: string; address?: string; city?: string; country?: string; [key: string]: any; } export type BentoBlockType = 'hero' | 'case' | 'article' | 'social' | 'video' | 'form'; export type BentoColSpan = 1 | 2; export type BentoRowSpan = 1 | 2; export interface BentoBlockPublic { id: number | string; cardId: number | string; type: BentoBlockType; colSpan: BentoColSpan; rowSpan: BentoRowSpan; sortOrder: number; title?: string; content?: string; mediaUrl?: string; linkUrl?: string; metaJson?: string | Record; } export interface BrandKit { logoUrl: string; primaryColor: string; } export interface CardPortalDetail { id: number | string; slug?: string; name: string; title: string; company: string; slogan?: string; avatarUrl?: string; phone?: string; email?: string; whatsapp?: string; linkedin?: string; telegram?: string; twitter?: string; wechat?: string; timezone?: string; audioPronunciationUrl?: string; audioPronounceUrl?: string; themeCode?: string; status: CardStatus; bentoBlocks: BentoBlockPublic[]; brandKit?: BrandKit; cachedAt?: number; } export type LeadStatus = 'new' | 'contacted' | 'hot' | 'won' | 'archived'; export type LeadSource = 'nfc' | 'qr' | 'link' | 'ai_chat'; export interface LeadEntity { id: string | number; tenantId?: string | number; cardId: string | number; visitorId?: string; name: string; company?: string; phone?: string; email?: string; status: LeadStatus; intentScore: number; source: LeadSource; notes?: string; } export interface SubmitLeadParams { cardId: string | number; name: string; company?: string; phone?: string; email?: string; source?: string; notes?: string; visitorId?: string; [key: string]: any; } export type TouchType = 'nfc' | 'qr' | 'link'; export interface RadarTrack { id: string | number; tenantId?: string | number; cardId: string | number; visitorId: string; ip?: string; country?: string; city?: string; touchType: TouchType; stayDurationMs: number; scrollDepth: number; viewedBlocks: string[]; createdAt?: string | Date; } export interface RecordRadarTrackParams { cardId: string | number; visitorId: string; touchType?: string; stayDurationMs?: number; scrollDepth?: number; viewedBlocks?: string[]; ip?: string; country?: string; city?: string; [key: string]: any; } export interface ApiResponse { code: number; message: string; data: T; } export type NFCMaterial = 'wood' | 'metal' | 'pvc'; export type NFCStatus = 'active' | 'suspended' | 'unbound'; export type NFCSceneMode = 'business' | 'social'; export interface NFCRecord { id: string | number; uid: string; tenantId: string | number; cardId?: string | number | null; batchNo: string; material: NFCMaterial; status: NFCStatus; sceneMode: NFCSceneMode; lastScannedAt?: string | Date | null; } export interface NfcBindParams { uid: string; cardId: number; } export interface NfcUidParams { uid: string; } export interface OwnerPageQuery { page: number; size: number; keyWord?: string; status?: LeadStatus; cardId?: string | number; visitorId?: string; } export interface OwnerPageData { list: T[]; pagination: { page: number; size: number; total: number; }; } export type AiChatRole = 'user' | 'assistant' | 'system'; export type ChatMessageType = 'text' | 'lead_card'; export interface ChatLeadPayload { title: string; description: string; name: string; contact: string; submitted: boolean; submitting?: boolean; successMessage?: string; errorMessage?: string; } export interface ChatMessage { role: AiChatRole; content: string; type?: ChatMessageType; cardPayload?: ChatLeadPayload; } export interface AiChatMessage { role: AiChatRole; content: string; type?: ChatMessageType; cardPayload?: ChatLeadPayload; } export interface AiChatRequest { cardId: string | number; locale?: string; messages: AiChatMessage[]; } export interface AiChatReply { reply: string; locale: string; shouldCollectLead: boolean; }