/** * [MOCK] 黑名单管理数据源 * AI注意: 这是Mock实现,不是真实业务逻辑 * 仅在USE_MOCK=true时启用 */ export interface BlacklistRecord { id: string; tenant_id: string; shop_id: string; task_id?: string; trace_id: string; business_type: 'TOC' | 'TOB'; buyer_id: string; buyer_name: string; buyer_email: string; buyer_phone?: string; platform: string; platform_buyer_id: string; blacklist_reason: string; blacklist_type: 'FRAUD' | 'CHARGEBACK' | 'ABUSE' | 'OTHER'; risk_score: number; blacklist_date: string; expiry_date?: string; status: 'ACTIVE' | 'INACTIVE' | 'EXPIRED'; evidence?: string; created_by: string; created_at: string; updated_at: string; type?: 'CUSTOMER' | 'ADDRESS' | 'IP' | 'EMAIL'; value?: string; reason?: string; severity?: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'; source?: 'MANUAL' | 'AUTO'; createdBy?: string; updatedAt?: string; } export interface RiskAssessment { id: string; orderId: string; customerId: string; customerName: string; riskScore: number; riskLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'; riskFactors: string[]; status: 'PENDING' | 'REVIEWING' | 'APPROVED' | 'REJECTED'; reviewedBy?: string; reviewedAt?: string; createdAt: string; updatedAt: string; } export interface IBlacklistDataSource { fetchBlacklist(params?: { platform?: string; status?: string; search?: string }): Promise; addBlacklist(data: Partial): Promise; updateBlacklist(id: string, data: Partial): Promise; removeBlacklist(id: string): Promise; fetchRiskAssessments(params?: { status?: string; riskLevel?: string }): Promise; reviewRiskAssessment(id: string, action: 'APPROVE' | 'REJECT', reason?: string): Promise; } class MockBlacklistDataSource implements IBlacklistDataSource { private blacklist: BlacklistRecord[] = [ { id: '1', tenant_id: 'tenant_001', shop_id: 'shop_001', trace_id: 'trace_001', business_type: 'TOC', buyer_id: 'buyer_001', buyer_name: 'John Doe', buyer_email: 'john.doe@example.com', platform: 'AMAZON', platform_buyer_id: 'amazon_001', blacklist_reason: '多次恶意退款', blacklist_type: 'FRAUD', risk_score: 85, blacklist_date: '2026-03-01', status: 'ACTIVE', created_by: 'admin', created_at: '2026-03-01', updated_at: '2026-03-01', type: 'CUSTOMER', value: 'John Doe', reason: '多次恶意退款', severity: 'HIGH', source: 'MANUAL', createdBy: 'admin', updatedAt: '2026-03-01', }, { id: '2', tenant_id: 'tenant_001', shop_id: 'shop_001', trace_id: 'trace_002', business_type: 'TOC', buyer_id: 'buyer_002', buyer_name: 'Jane Smith', buyer_email: 'jane.smith@example.com', platform: 'EBAY', platform_buyer_id: 'ebay_001', blacklist_reason: '虚假地址', blacklist_type: 'ABUSE', risk_score: 65, blacklist_date: '2026-03-05', status: 'ACTIVE', created_by: 'system', created_at: '2026-03-05', updated_at: '2026-03-05', type: 'ADDRESS', value: '123 Fraud St, Scam City', reason: '虚假地址', severity: 'MEDIUM', source: 'AUTO', createdBy: 'system', updatedAt: '2026-03-05', }, ]; private riskAssessments: RiskAssessment[] = [ { id: '1', orderId: 'ORD-2026-001', customerId: 'CUST-001', customerName: 'Suspicious Customer', riskScore: 85, riskLevel: 'HIGH', riskFactors: ['新账户', '高额订单', '异常地址'], status: 'PENDING', createdAt: '2026-03-15', updatedAt: '2026-03-15', }, ]; async fetchBlacklist(params?: { type?: string; status?: string; search?: string }): Promise { await new Promise(resolve => setTimeout(resolve, 300)); let result = [...this.blacklist]; if (params?.type) { // 移除type过滤,因为type属性不存在 } if (params?.status) { result = result.filter(r => r.status === params.status); } if (params?.search) { result = result.filter(r => r.buyer_name.toLowerCase().includes(params.search!.toLowerCase())); } return result; } async addBlacklist(data: Partial): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const newRecord: BlacklistRecord = { id: `${Date.now()}`, tenant_id: 'tenant_001', shop_id: data.shop_id || 'shop_001', trace_id: data.trace_id || `trace_${Date.now()}`, business_type: data.business_type || 'TOC', buyer_id: data.buyer_id || `buyer_${Date.now()}`, buyer_name: data.buyer_name || '', buyer_email: data.buyer_email || '', buyer_phone: data.buyer_phone, platform: data.platform || '', platform_buyer_id: data.platform_buyer_id || '', blacklist_reason: data.blacklist_reason || '', blacklist_type: data.blacklist_type || 'OTHER', risk_score: data.risk_score || 50, blacklist_date: data.blacklist_date || new Date().toISOString().split('T')[0], expiry_date: data.expiry_date, status: 'ACTIVE', evidence: data.evidence, created_by: data.created_by || 'current_user', created_at: new Date().toISOString().split('T')[0], updated_at: new Date().toISOString().split('T')[0], ...data, }; this.blacklist.push(newRecord); return newRecord; } async updateBlacklist(id: string, data: Partial): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const index = this.blacklist.findIndex(r => r.id === id); if (index === -1) throw new Error('Record not found'); this.blacklist[index] = { ...this.blacklist[index], ...data, updated_at: new Date().toISOString().split('T')[0] }; return this.blacklist[index]; } async removeBlacklist(id: string): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const index = this.blacklist.findIndex(r => r.id === id); if (index !== -1) { this.blacklist.splice(index, 1); } } async fetchRiskAssessments(params?: { status?: string; riskLevel?: string }): Promise { await new Promise(resolve => setTimeout(resolve, 300)); let result = [...this.riskAssessments]; if (params?.status) { result = result.filter(r => r.status === params.status); } if (params?.riskLevel) { result = result.filter(r => r.riskLevel === params.riskLevel); } return result; } async reviewRiskAssessment(id: string, action: 'APPROVE' | 'REJECT', reason?: string): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const index = this.riskAssessments.findIndex(r => r.id === id); if (index === -1) throw new Error('Assessment not found'); this.riskAssessments[index] = { ...this.riskAssessments[index], status: action === 'APPROVE' ? 'APPROVED' : 'REJECTED', reviewedBy: 'current_user', reviewedAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; return this.riskAssessments[index]; } } class ApiBlacklistDataSource implements IBlacklistDataSource { private baseUrl = '/api/blacklist'; async fetchBlacklist(params?: { type?: string; status?: string; search?: string }): Promise { const response = await fetch(`${this.baseUrl}?${new URLSearchParams(params as any)}`); if (!response.ok) throw new Error('Failed to fetch blacklist'); return response.json(); } async addBlacklist(data: Partial): Promise { const response = await fetch(this.baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); if (!response.ok) throw new Error('Failed to add blacklist record'); return response.json(); } async updateBlacklist(id: string, data: Partial): Promise { const response = await fetch(`${this.baseUrl}/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); if (!response.ok) throw new Error('Failed to update blacklist record'); return response.json(); } async removeBlacklist(id: string): Promise { const response = await fetch(`${this.baseUrl}/${id}`, { method: 'DELETE' }); if (!response.ok) throw new Error('Failed to remove blacklist record'); } async fetchRiskAssessments(params?: { status?: string; riskLevel?: string }): Promise { const response = await fetch(`${this.baseUrl}/risk-assessments?${new URLSearchParams(params as any)}`); if (!response.ok) throw new Error('Failed to fetch risk assessments'); return response.json(); } async reviewRiskAssessment(id: string, action: 'APPROVE' | 'REJECT', reason?: string): Promise { const response = await fetch(`${this.baseUrl}/risk-assessments/${id}/review`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action, reason }), }); if (!response.ok) throw new Error('Failed to review risk assessment'); return response.json(); } } const useMock = process.env.REACT_APP_USE_MOCK === 'true'; export const blacklistDataSource: IBlacklistDataSource = useMock ? new MockBlacklistDataSource() : new ApiBlacklistDataSource();