import { http } from './http'; /** * [MOCK] 用户资产数据�? * AI注意: 这是Mock实现,不是真实业务逻辑 * 仅在USE_MOCK=true时启�? */ export type MemberLevel = 'BRONZE' | 'SILVER' | 'GOLD' | 'PLATINUM' | 'DIAMOND'; export interface UserAsset { id: string; tenantId: string; userId: string; userName: string; email: string; userEmail?: string; // �?email 同义 memberLevel: MemberLevel; points: number; memberScore?: number; // �?points 同义 totalSpent: number; availableBalance: number; availablePoints?: number; // �?availableBalance 同义 frozenBalance: number; frozenPoints?: number; // �?frozenBalance 同义 cashbackBalance?: number; couponCount?: number; totalOrders: number; joinDate: string; lastActiveDate: string; status: 'ACTIVE' | 'INACTIVE' | 'SUSPENDED'; } export interface MemberLevelConfig { id: string; level: MemberLevel; name: string; minSpent: number; discount: number; pointsMultiplier: number; benefits: string[]; color: string; icon: string; } export type PointsSourceType = | 'PURCHASE' | 'REVIEW' | 'REFERRAL' | 'PROMOTION' | 'ADMIN_ADJUST' | 'EXPIRED' | 'REFUND' | 'MANUAL_DEDUCT'; export type PointsStatus = 'PENDING' | 'CONFIRMED' | 'FROZEN' | 'EXPIRED' | 'CANCELLED'; export interface PointsRecord { id: string; userId: string; userName: string; type: 'EARN' | 'REDEEM' | 'EXPIRE' | 'ADJUST'; amount: number; balance: number; source: string; description: string; createdAt: string; // 额外字段,用�?PointsManage 页面 tenantId?: string; shopId?: string; traceId?: string; businessType?: 'TOC' | 'TOB'; points?: number; // �?amount 同义 sourceType?: string; // �?source 同义 status?: 'PENDING' | 'CONFIRMED' | 'FROZEN' | 'EXPIRED' | 'CANCELLED'; expiredAt?: string; sourceId?: string; } export interface IUserAssetDataSource { fetchUserAssets(params?: { memberLevel?: string; status?: string; search?: string }): Promise; updateUserAsset(id: string, data: Partial): Promise; fetchMemberLevelConfigs(): Promise; updateMemberLevelConfig(id: string, data: Partial): Promise; fetchPointsRecords(params?: { userId?: string; type?: string }): Promise; adjustPoints(userId: string, amount: number, reason: string): Promise; } class MockUserAssetDataSource implements IUserAssetDataSource { private userAssets: UserAsset[] = [ { id: '1', tenantId: 'tenant_001', userId: 'user_001', userName: 'John Doe', email: 'john@example.com', memberLevel: 'GOLD', points: 5000, totalSpent: 15000, availableBalance: 500, frozenBalance: 100, totalOrders: 25, joinDate: '2025-01-15', lastActiveDate: '2026-03-18', status: 'ACTIVE', }, { id: '2', tenantId: 'tenant_001', userId: 'user_002', userName: 'Jane Smith', email: 'jane@example.com', memberLevel: 'PLATINUM', points: 15000, totalSpent: 50000, availableBalance: 1200, frozenBalance: 0, totalOrders: 85, joinDate: '2024-06-20', lastActiveDate: '2026-03-19', status: 'ACTIVE', }, ]; private memberLevelConfigs: MemberLevelConfig[] = [ { id: '1', level: 'BRONZE', name: 'Bronze', minSpent: 0, discount: 0, pointsMultiplier: 1, benefits: ['Basic support'], color: '#CD7F32', icon: '🥉' }, { id: '2', level: 'SILVER', name: 'Silver', minSpent: 1000, discount: 5, pointsMultiplier: 1.2, benefits: ['Priority support', '5% discount'], color: '#C0C0C0', icon: '🥈' }, { id: '3', level: 'GOLD', name: 'Gold', minSpent: 5000, discount: 10, pointsMultiplier: 1.5, benefits: ['VIP support', '10% discount', 'Free shipping'], color: '#FFD700', icon: '🥇' }, { id: '4', level: 'PLATINUM', name: 'Platinum', minSpent: 20000, discount: 15, pointsMultiplier: 2, benefits: ['Dedicated support', '15% discount', 'Free express shipping', 'Birthday gift'], color: '#E5E4E2', icon: '💎' }, { id: '5', level: 'DIAMOND', name: 'Diamond', minSpent: 50000, discount: 20, pointsMultiplier: 3, benefits: ['Personal account manager', '20% discount', 'Exclusive events'], color: '#B9F2FF', icon: '💠' }, ]; private pointsRecords: PointsRecord[] = [ { id: '1', userId: 'user_001', userName: 'John Doe', type: 'EARN', amount: 100, balance: 5000, source: 'Purchase', description: 'Order #ORD-001', createdAt: '2026-03-15', // 额外字段 tenantId: 'T001', shopId: 'S001', traceId: 'TR001', businessType: 'TOC', points: 100, sourceType: 'PURCHASE', status: 'CONFIRMED' }, { id: '2', userId: 'user_001', userName: 'John Doe', type: 'REDEEM', amount: -50, balance: 4950, source: 'Redemption', description: 'Coupon redemption', createdAt: '2026-03-16', // 额外字段 tenantId: 'T001', shopId: 'S001', traceId: 'TR002', businessType: 'TOC', points: -50, sourceType: 'MANUAL_DEDUCT', status: 'CONFIRMED' }, ]; async fetchUserAssets(params?: { memberLevel?: string; status?: string; search?: string }): Promise { await new Promise(resolve => setTimeout(resolve, 300)); let result = [...this.userAssets]; if (params?.memberLevel) { result = result.filter(u => u.memberLevel === params.memberLevel); } if (params?.status) { result = result.filter(u => u.status === params.status); } if (params?.search) { result = result.filter(u => u.userName.toLowerCase().includes(params.search!.toLowerCase()) || u.email.toLowerCase().includes(params.search!.toLowerCase())); } return result; } async updateUserAsset(id: string, data: Partial): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const index = this.userAssets.findIndex(u => u.id === id); if (index === -1) throw new Error('User asset not found'); this.userAssets[index] = { ...this.userAssets[index], ...data }; return this.userAssets[index]; } async fetchMemberLevelConfigs(): Promise { await new Promise(resolve => setTimeout(resolve, 300)); return [...this.memberLevelConfigs]; } async updateMemberLevelConfig(id: string, data: Partial): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const index = this.memberLevelConfigs.findIndex(c => c.id === id); if (index === -1) throw new Error('Config not found'); this.memberLevelConfigs[index] = { ...this.memberLevelConfigs[index], ...data }; return this.memberLevelConfigs[index]; } async fetchPointsRecords(params?: { userId?: string; type?: string }): Promise { await new Promise(resolve => setTimeout(resolve, 300)); let result = [...this.pointsRecords]; if (params?.userId) { result = result.filter(r => r.userId === params.userId); } if (params?.type) { result = result.filter(r => r.type === params.type); } return result; } async adjustPoints(userId: string, amount: number, reason: string): Promise { await new Promise(resolve => setTimeout(resolve, 300)); const user = this.userAssets.find(u => u.userId === userId); if (!user) throw new Error('User not found'); const newBalance = user.points + amount; const record: PointsRecord = { id: `${Date.now()}`, userId, userName: user.userName, type: amount > 0 ? 'EARN' : 'REDEEM', amount, balance: newBalance, source: 'Manual Adjustment', description: reason, createdAt: new Date().toISOString().split('T')[0], }; user.points = newBalance; this.pointsRecords.push(record); return record; } } class ApiUserAssetDataSource implements IUserAssetDataSource { private baseUrl = '/api/user-assets'; async fetchUserAssets(params?: { memberLevel?: string; status?: string; search?: string }): Promise { const response = await http.get(`${this.baseUrl}?${new URLSearchParams(params as any)}`); return response.data; } async updateUserAsset(id: string, data: Partial): Promise { const response = await http.put(`${this.baseUrl}/${id}`, data); return response.data; } async fetchMemberLevelConfigs(): Promise { const response = await http.get(`${this.baseUrl}/member-levels`); return response.data; } async updateMemberLevelConfig(id: string, data: Partial): Promise { const response = await http.put(`${this.baseUrl}/member-levels/${id}`, data); return response.data; } async fetchPointsRecords(params?: { userId?: string; type?: string }): Promise { const response = await http.get(`${this.baseUrl}/points?${new URLSearchParams(params as any)}`); return response.data; } async adjustPoints(userId: string, amount: number, reason: string): Promise { const response = await http.post(`${this.baseUrl}/points/adjust`, { userId, amount, reason }); return response.data; } } const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true'; export const userAssetDataSource: IUserAssetDataSource = useMock ? new MockUserAssetDataSource() : new ApiUserAssetDataSource();