Files
makemd/dashboard/src/services/merchantDataSource.ts
wurenzhi 2748456d8a refactor(services): 重构服务文件结构,将服务按功能分类到不同目录
- 将服务文件按功能分类到core、ai、analytics、security等目录
- 修复logger导入路径问题,统一使用相对路径
- 更新相关文件的导入路径引用
- 添加新的批量操作组件导出文件
- 修复dashboard页面中的类型错误
- 添加dotenv依赖到package.json
2026-03-25 13:46:26 +08:00

355 lines
11 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();