refactor: 重构页面组件移除冗余Layout组件 feat: 实现WebSocket和事件总线系统 feat: 添加队列和调度系统 docs: 更新架构文档和服务映射 style: 清理重复接口定义使用数据源 chore: 更新依赖项配置 feat: 添加运行时系统和领域引导 ci: 配置ESLint边界检查规则 build: 添加Redis和WebSocket依赖 test: 添加MSW浏览器环境入口 perf: 优化数据获取逻辑使用统一数据源 fix: 修复类型定义和状态管理问题
225 lines
7.7 KiB
TypeScript
225 lines
7.7 KiB
TypeScript
/**
|
||
* [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<BlacklistRecord[]>;
|
||
addBlacklist(data: Partial<BlacklistRecord>): Promise<BlacklistRecord>;
|
||
updateBlacklist(id: string, data: Partial<BlacklistRecord>): Promise<BlacklistRecord>;
|
||
removeBlacklist(id: string): Promise<void>;
|
||
|
||
fetchRiskAssessments(params?: { status?: string; riskLevel?: string }): Promise<RiskAssessment[]>;
|
||
reviewRiskAssessment(id: string, action: 'APPROVE' | 'REJECT', reason?: string): Promise<RiskAssessment>;
|
||
}
|
||
|
||
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<BlacklistRecord[]> {
|
||
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<BlacklistRecord>): Promise<BlacklistRecord> {
|
||
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<BlacklistRecord>): Promise<BlacklistRecord> {
|
||
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<void> {
|
||
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<RiskAssessment[]> {
|
||
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<RiskAssessment> {
|
||
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<BlacklistRecord[]> {
|
||
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<BlacklistRecord>): Promise<BlacklistRecord> {
|
||
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<BlacklistRecord>): Promise<BlacklistRecord> {
|
||
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<void> {
|
||
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<RiskAssessment[]> {
|
||
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<RiskAssessment> {
|
||
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();
|