- 将服务文件按功能分类到core、ai、analytics、security等目录 - 修复logger导入路径问题,统一使用相对路径 - 更新相关文件的导入路径引用 - 添加新的批量操作组件导出文件 - 修复dashboard页面中的类型错误 - 添加dotenv依赖到package.json
355 lines
11 KiB
TypeScript
355 lines
11 KiB
TypeScript
import { http } from './http';
|
||
/**
|
||
* [MOCK] 商户管理数据<E695B0>? * AI注意: 这是Mock实现,不是真实业务逻辑
|
||
* 仅在USE_MOCK=true时启<E697B6>? */
|
||
|
||
export interface Merchant {
|
||
id: string;
|
||
tenantId: string;
|
||
companyName: string;
|
||
businessLicense: string;
|
||
contactEmail: string;
|
||
contactPhone: string;
|
||
status: 'PENDING' | 'ACTIVE' | 'SUSPENDED' | 'TERMINATED';
|
||
tier: 'BASIC' | 'PRO' | 'ENTERPRISE';
|
||
traceId: string;
|
||
createdAt: string;
|
||
updatedAt: string;
|
||
}
|
||
|
||
export interface MerchantShop {
|
||
id: string;
|
||
merchantId: string;
|
||
shopName: string;
|
||
platform: string;
|
||
shopUrl: string;
|
||
status: 'ACTIVE' | 'INACTIVE' | 'SUSPENDED';
|
||
createdAt: string;
|
||
updatedAt: string;
|
||
}
|
||
|
||
export interface MerchantOrder {
|
||
id: string;
|
||
merchantId: string;
|
||
merchantName: string;
|
||
orderId: string;
|
||
platform: string;
|
||
totalAmount: number;
|
||
status: string;
|
||
createdAt: string;
|
||
}
|
||
|
||
export interface MerchantSettlement {
|
||
id: string;
|
||
merchantId: string;
|
||
merchantName: string;
|
||
periodStart: string;
|
||
periodEnd: string;
|
||
totalAmount: number;
|
||
status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED';
|
||
createdAt: string;
|
||
updatedAt: string;
|
||
}
|
||
|
||
export interface IMerchantDataSource {
|
||
fetchMerchants(params?: { status?: string; tier?: string; search?: string }): Promise<Merchant[]>;
|
||
createMerchant(data: Partial<Merchant>): Promise<Merchant>;
|
||
updateMerchant(id: string, data: Partial<Merchant>): Promise<Merchant>;
|
||
deleteMerchant(id: string): Promise<void>;
|
||
|
||
fetchShops(params?: { merchantId?: string; platform?: string; status?: string }): Promise<MerchantShop[]>;
|
||
createShop(data: Partial<MerchantShop>): Promise<MerchantShop>;
|
||
updateShop(id: string, data: Partial<MerchantShop>): Promise<MerchantShop>;
|
||
deleteShop(id: string): Promise<void>;
|
||
|
||
fetchMerchantOrders(merchantId: string, params?: { status?: string }): Promise<MerchantOrder[]>;
|
||
fetchSettlements(params?: { merchantId?: string; status?: string }): Promise<MerchantSettlement[]>;
|
||
processSettlement(id: string, action: 'APPROVE' | 'REJECT'): Promise<MerchantSettlement>;
|
||
}
|
||
|
||
class MockMerchantDataSource implements IMerchantDataSource {
|
||
private merchants: Merchant[] = [
|
||
{
|
||
id: '1',
|
||
tenantId: 'tenant_001',
|
||
companyName: 'Test Company A',
|
||
businessLicense: 'BL-001',
|
||
contactEmail: 'contact@company-a.com',
|
||
contactPhone: '+1 (123) 456-7890',
|
||
status: 'ACTIVE',
|
||
tier: 'ENTERPRISE',
|
||
traceId: 'trace_001',
|
||
createdAt: '2026-03-01',
|
||
updatedAt: '2026-03-01',
|
||
},
|
||
{
|
||
id: '2',
|
||
tenantId: 'tenant_002',
|
||
companyName: 'Test Company B',
|
||
businessLicense: 'BL-002',
|
||
contactEmail: 'contact@company-b.com',
|
||
contactPhone: '+1 (234) 567-8901',
|
||
status: 'ACTIVE',
|
||
tier: 'PRO',
|
||
traceId: 'trace_002',
|
||
createdAt: '2026-03-05',
|
||
updatedAt: '2026-03-05',
|
||
},
|
||
];
|
||
|
||
private shops: MerchantShop[] = [
|
||
{
|
||
id: '1',
|
||
merchantId: '1',
|
||
shopName: 'Shop A - Amazon',
|
||
platform: 'Amazon',
|
||
shopUrl: 'https://amazon.com/shop-a',
|
||
status: 'ACTIVE',
|
||
createdAt: '2026-03-01',
|
||
updatedAt: '2026-03-01',
|
||
},
|
||
{
|
||
id: '2',
|
||
merchantId: '1',
|
||
shopName: 'Shop A - Shopify',
|
||
platform: 'Shopify',
|
||
shopUrl: 'https://shop-a.myshopify.com',
|
||
status: 'ACTIVE',
|
||
createdAt: '2026-03-02',
|
||
updatedAt: '2026-03-02',
|
||
},
|
||
];
|
||
|
||
private orders: MerchantOrder[] = [
|
||
{
|
||
id: '1',
|
||
merchantId: '1',
|
||
merchantName: 'Test Company A',
|
||
orderId: 'ORD-2026-001',
|
||
platform: 'Amazon',
|
||
totalAmount: 1500.00,
|
||
status: 'COMPLETED',
|
||
createdAt: '2026-03-15',
|
||
},
|
||
];
|
||
|
||
async fetchMerchants(params?: { status?: string; tier?: string; search?: string }): Promise<Merchant[]> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
let result = [...this.merchants];
|
||
if (params?.status) {
|
||
result = result.filter(m => m.status === params.status);
|
||
}
|
||
if (params?.tier) {
|
||
result = result.filter(m => m.tier === params.tier);
|
||
}
|
||
if (params?.search) {
|
||
result = result.filter(m => m.companyName.toLowerCase().includes(params.search!.toLowerCase()));
|
||
}
|
||
return result;
|
||
}
|
||
|
||
async createMerchant(data: Partial<Merchant>): Promise<Merchant> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const newMerchant: Merchant = {
|
||
id: `${Date.now()}`,
|
||
tenantId: `tenant_${Date.now()}`,
|
||
companyName: data.companyName || '',
|
||
businessLicense: data.businessLicense || '',
|
||
contactEmail: data.contactEmail || '',
|
||
contactPhone: data.contactPhone || '',
|
||
status: 'PENDING',
|
||
tier: 'BASIC',
|
||
traceId: `trace_${Date.now()}`,
|
||
createdAt: new Date().toISOString().split('T')[0],
|
||
updatedAt: new Date().toISOString().split('T')[0],
|
||
...data,
|
||
};
|
||
this.merchants.push(newMerchant);
|
||
return newMerchant;
|
||
}
|
||
|
||
async updateMerchant(id: string, data: Partial<Merchant>): Promise<Merchant> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const index = this.merchants.findIndex(m => m.id === id);
|
||
if (index === -1) throw new Error('Merchant not found');
|
||
this.merchants[index] = { ...this.merchants[index], ...data, updatedAt: new Date().toISOString().split('T')[0] };
|
||
return this.merchants[index];
|
||
}
|
||
|
||
async deleteMerchant(id: string): Promise<void> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const index = this.merchants.findIndex(m => m.id === id);
|
||
if (index !== -1) {
|
||
this.merchants.splice(index, 1);
|
||
}
|
||
}
|
||
|
||
async fetchShops(params?: { merchantId?: string; platform?: string; status?: string }): Promise<MerchantShop[]> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
let result = [...this.shops];
|
||
if (params?.merchantId) {
|
||
result = result.filter(s => s.merchantId === params.merchantId);
|
||
}
|
||
if (params?.platform) {
|
||
result = result.filter(s => s.platform === params.platform);
|
||
}
|
||
if (params?.status) {
|
||
result = result.filter(s => s.status === params.status);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
async createShop(data: Partial<MerchantShop>): Promise<MerchantShop> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const newShop: MerchantShop = {
|
||
id: `${Date.now()}`,
|
||
merchantId: data.merchantId || '',
|
||
shopName: data.shopName || '',
|
||
platform: data.platform || '',
|
||
shopUrl: data.shopUrl || '',
|
||
status: 'ACTIVE',
|
||
createdAt: new Date().toISOString().split('T')[0],
|
||
updatedAt: new Date().toISOString().split('T')[0],
|
||
...data,
|
||
};
|
||
this.shops.push(newShop);
|
||
return newShop;
|
||
}
|
||
|
||
async updateShop(id: string, data: Partial<MerchantShop>): Promise<MerchantShop> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const index = this.shops.findIndex(s => s.id === id);
|
||
if (index === -1) throw new Error('Shop not found');
|
||
this.shops[index] = { ...this.shops[index], ...data, updatedAt: new Date().toISOString().split('T')[0] };
|
||
return this.shops[index];
|
||
}
|
||
|
||
async deleteShop(id: string): Promise<void> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const index = this.shops.findIndex(s => s.id === id);
|
||
if (index !== -1) {
|
||
this.shops.splice(index, 1);
|
||
}
|
||
}
|
||
|
||
async fetchMerchantOrders(merchantId: string, params?: { status?: string }): Promise<MerchantOrder[]> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
let result = this.orders.filter(o => o.merchantId === merchantId);
|
||
if (params?.status) {
|
||
result = result.filter(o => o.status === params.status);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
private settlements: MerchantSettlement[] = [
|
||
{
|
||
id: '1',
|
||
merchantId: '1',
|
||
merchantName: 'Test Company A',
|
||
periodStart: '2026-03-01',
|
||
periodEnd: '2026-03-15',
|
||
totalAmount: 25000.00,
|
||
status: 'PENDING',
|
||
createdAt: '2026-03-16',
|
||
updatedAt: '2026-03-16',
|
||
},
|
||
];
|
||
|
||
async fetchSettlements(params?: { merchantId?: string; status?: string }): Promise<MerchantSettlement[]> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
let result = [...this.settlements];
|
||
if (params?.merchantId) {
|
||
result = result.filter(s => s.merchantId === params.merchantId);
|
||
}
|
||
if (params?.status) {
|
||
result = result.filter(s => s.status === params.status);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
async processSettlement(id: string, action: 'APPROVE' | 'REJECT'): Promise<MerchantSettlement> {
|
||
await new Promise(resolve => setTimeout(resolve, 300));
|
||
const index = this.settlements.findIndex(s => s.id === id);
|
||
if (index === -1) throw new Error('Settlement not found');
|
||
this.settlements[index] = {
|
||
...this.settlements[index],
|
||
status: action === 'APPROVE' ? 'COMPLETED' : 'FAILED',
|
||
updatedAt: new Date().toISOString().split('T')[0],
|
||
};
|
||
return this.settlements[index];
|
||
}
|
||
}
|
||
|
||
class ApiMerchantDataSource implements IMerchantDataSource {
|
||
private baseUrl = '/api/merchants';
|
||
|
||
async fetchMerchants(params?: { status?: string; tier?: string; search?: string }): Promise<Merchant[]> {
|
||
const response = await http.post(`${this.baseUrl}?${new URLSearchParams(params as any)}`);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async createMerchant(data: Partial<Merchant>): Promise<Merchant> {
|
||
const response = await http.post(this.baseUrl, data);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async updateMerchant(id: string, data: Partial<Merchant>): Promise<Merchant> {
|
||
const response = await http.put(`${this.baseUrl}/${id}`, data);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async deleteMerchant(id: string): Promise<void> {
|
||
const response = await http.post(`${this.baseUrl}/${id}`);
|
||
|
||
}
|
||
|
||
async fetchShops(params?: { merchantId?: string; platform?: string; status?: string }): Promise<MerchantShop[]> {
|
||
const response = await http.get(`${this.baseUrl}/shops?${new URLSearchParams(params as any)}`);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async createShop(data: Partial<MerchantShop>): Promise<MerchantShop> {
|
||
const response = await http.post(`${this.baseUrl}/shops`, data);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async updateShop(id: string, data: Partial<MerchantShop>): Promise<MerchantShop> {
|
||
const response = await http.put(`${this.baseUrl}/shops/${id}`, data);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async deleteShop(id: string): Promise<void> {
|
||
const response = await http.delete(`${this.baseUrl}/shops/${id}`);
|
||
|
||
}
|
||
|
||
async fetchMerchantOrders(merchantId: string, params?: { status?: string }): Promise<MerchantOrder[]> {
|
||
const response = await http.get(`${this.baseUrl}/${merchantId}/orders?${new URLSearchParams(params as any)}`);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async fetchSettlements(params?: { merchantId?: string; status?: string }): Promise<MerchantSettlement[]> {
|
||
const response = await http.get(`${this.baseUrl}/settlements?${new URLSearchParams(params as any)}`);
|
||
|
||
return response.data;
|
||
}
|
||
|
||
async processSettlement(id: string, action: 'APPROVE' | 'REJECT'): Promise<MerchantSettlement> {
|
||
const response = await http.post(`${this.baseUrl}/settlements/${id}/process`, { action });
|
||
|
||
return response.data;
|
||
}
|
||
}
|
||
|
||
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
|
||
export const merchantDataSource: IMerchantDataSource = useMock
|
||
? new MockMerchantDataSource()
|
||
: new ApiMerchantDataSource();
|