/** * [MOCK] 黑名单管理数据源 * AI注意: 这是Mock实现,不是真实业务逻辑 * 仅在USE_MOCK=true时启用 */ export interface BlacklistRecord { id: string; tenant_id: string; type: 'CUSTOMER' | 'ADDRESS' | 'PHONE' | 'EMAIL' | 'IP'; value: string; reason: string; severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'; status: 'ACTIVE' | 'INACTIVE' | 'EXPIRED'; source: 'MANUAL' | 'AUTO' | 'IMPORT'; expiresAt?: string; createdAt: string; updatedAt: string; createdBy: 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?: { type?: 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', type: 'CUSTOMER', value: 'John Doe', reason: '多次恶意退款', severity: 'HIGH', status: 'ACTIVE', source: 'MANUAL', createdAt: '2026-03-01', updatedAt: '2026-03-01', createdBy: 'admin', }, { id: '2', tenant_id: 'tenant_001', type: 'ADDRESS', value: '123 Fraud St, Scam City', reason: '虚假地址', severity: 'MEDIUM', status: 'ACTIVE', source: 'AUTO', createdAt: '2026-03-05', updatedAt: '2026-03-05', createdBy: 'system', }, ]; 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) { result = result.filter(r => r.type === params.type); } if (params?.status) { result = result.filter(r => r.status === params.status); } if (params?.search) { result = result.filter(r => r.value.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', type: data.type || 'CUSTOMER', value: data.value || '', reason: data.reason || '', severity: data.severity || 'MEDIUM', status: 'ACTIVE', source: 'MANUAL', createdAt: new Date().toISOString().split('T')[0], updatedAt: new Date().toISOString().split('T')[0], createdBy: 'current_user', ...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, updatedAt: 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();