refactor: 重构代码结构和类型定义,优化类型安全性和代码可维护性

- 添加类型定义文件和类型引用
- 删除废弃的页面模块和导出文件
- 新增聚合管理模块和插件系统
- 修复类型错误和潜在运行时问题
- 更新API基础URL和配置
- 优化组件类型定义和事件处理
- 重构数据源接口和实现
- 完善文档和开发进度记录
This commit is contained in:
2026-03-22 11:25:28 +08:00
parent 15ee1758f5
commit a037843851
88 changed files with 42703 additions and 6395 deletions

View File

@@ -296,6 +296,7 @@ class MockAfterSalesDataSource implements IAfterSalesDataSource {
return [
{
id: 'TICKET-001',
ticketId: 'TKT-2026-001',
orderId: 'order-001',
customerId: 'C001',
customerName: 'John Doe',

View File

@@ -2,7 +2,7 @@ import axios, { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse } from
const API_BASE_URL = process.env.NODE_ENV === 'production'
? '/api'
: 'http://localhost:3000/api';
: 'http://localhost:3001/api';
const apiClient: AxiosInstance = axios.create({
baseURL: API_BASE_URL,

View File

@@ -52,6 +52,18 @@ export interface Customer {
email?: string;
}
export interface Product {
id: string;
sku: string;
name: string;
price: number;
stock: number;
category?: string;
moq?: number;
costPrice?: number;
suggestedPrice?: number;
}
export interface BatchOrderQueryParams {
customerId?: string;
status?: string;

View File

@@ -8,10 +8,13 @@
* @created 2026-03-19
*/
import { Certificate, CertificateQueryParams } from '@/types/certificate';
import { Certificate, CertificateQueryParams, CertificateStatus, CertificateType } from '@/types/certificate';
import { IDataSource } from '@/types/datasource';
import { BaseDataSource, BaseMockDataSource, DataSourceFactory } from './dataSourceFactory';
export type { Certificate } from '@/types/certificate';
export { CertificateStatus, CertificateType };
// ============================================
// 真实API实现
// ============================================
@@ -72,8 +75,8 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
{
id: '1',
name: 'CE认证证书',
type: 'PRODUCT_CERT',
status: 'APPROVED',
type: CertificateType.PRODUCT_CERT,
status: CertificateStatus.APPROVED,
fileUrl: '/files/ce-cert.pdf',
fileName: 'CE-Certificate-2026.pdf',
uploadDate: '2026-03-15',
@@ -87,8 +90,8 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
{
id: '2',
name: '营业执照',
type: 'BUSINESS_LICENSE',
status: 'APPROVED',
type: CertificateType.BUSINESS_LICENSE,
status: CertificateStatus.APPROVED,
fileUrl: '/files/business-license.pdf',
fileName: 'Business-License-2026.pdf',
uploadDate: '2026-01-10',
@@ -100,8 +103,8 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
{
id: '3',
name: 'FCC认证',
type: 'SAFETY_CERT',
status: 'PENDING',
type: CertificateType.SAFETY_CERT,
status: CertificateStatus.PENDING,
fileUrl: '/files/fcc-cert.pdf',
fileName: 'FCC-Certificate.pdf',
uploadDate: '2026-03-18',
@@ -113,8 +116,8 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
{
id: '4',
name: 'ISO9001',
type: 'QUALITY_CERT',
status: 'EXPIRED',
type: CertificateType.QUALITY_CERT,
status: CertificateStatus.EXPIRED,
fileUrl: '/files/iso9001.pdf',
fileName: 'ISO9001-2025.pdf',
uploadDate: '2025-01-01',
@@ -126,8 +129,8 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
{
id: '5',
name: 'RoHS认证',
type: 'PRODUCT_CERT',
status: 'APPROVED',
type: CertificateType.PRODUCT_CERT,
status: CertificateStatus.APPROVED,
fileUrl: '/files/rohs-cert.pdf',
fileName: 'RoHS-Certificate.pdf',
uploadDate: '2026-02-20',
@@ -141,8 +144,8 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
{
id: '6',
name: 'UL认证',
type: 'SAFETY_CERT',
status: 'PENDING',
type: CertificateType.SAFETY_CERT,
status: CertificateStatus.PENDING,
fileUrl: '/files/ul-cert.pdf',
fileName: 'UL-Certificate.pdf',
uploadDate: '2026-03-19',
@@ -168,7 +171,7 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
}
const updates: Partial<Certificate> = {
status: status as 'APPROVED' | 'PENDING' | 'REJECTED' | 'EXPIRED',
status: status as CertificateStatus,
};
if (status === 'APPROVED') {

View File

@@ -59,9 +59,17 @@ export class BaseDataSource<T, P = any> implements IDataSource<T, P> {
* 基础Mock数据源类
* 提供通用的Mock数据实现
*/
export class BaseMockDataSource<T, P = any> implements IMockDataSource<T, P> {
export class BaseMockDataSource<T, P = any> implements IMockDataSource<T> {
protected mockData: T[] = [];
reset(): void {
this.mockData = [];
}
getMockData(): T[] {
return this.mockData;
}
async list(): Promise<T[]> {
return this.mockData;
}
@@ -103,15 +111,6 @@ export class BaseMockDataSource<T, P = any> implements IMockDataSource<T, P> {
this.mockData.splice(index, 1);
}
// Mock特定方法
reset(): void {
this.mockData = [];
}
getMockData(): T[] {
return this.mockData;
}
// 延迟方法,用于模拟网络延迟
protected async delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));

View File

@@ -2,7 +2,7 @@ import axios from 'axios';
// 创建axios实例
const http = axios.create({
baseURL: 'http://localhost:3000', // 后端API基础URL
baseURL: 'http://localhost:3001', // 后端API基础URL
timeout: 10000, // 请求超时时间
headers: {
'Content-Type': 'application/json',

View File

@@ -58,6 +58,83 @@ export interface SiteQueryParams {
status?: string;
}
export interface SiteAnalytics {
id: string;
siteId: string;
dateRange: {
start: string;
end: string;
};
metrics: {
visitors: number;
pageViews: number;
bounceRate: number;
avgSessionDuration: number;
};
sales: {
totalRevenue: number;
totalOrders: number;
avgOrderValue: number;
conversionRate: number;
};
topProducts: Array<{
id: string;
name: string;
sales: number;
quantity: number;
}>;
trafficSources: Array<{
source: string;
visitors: number;
percentage: number;
}>;
}
export type SiteConfig = IndependentSite;
export interface SiteOrder {
id: string;
siteId: string;
orderNumber: string;
customerName: string;
customerEmail: string;
total: number;
currency: string;
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
paymentMethod: string;
paymentStatus: 'pending' | 'paid' | 'failed' | 'refunded';
shippingAddress: {
name: string;
address: string;
city: string;
country: string;
zipCode: string;
};
items: Array<{
productId: string;
productName: string;
quantity: number;
price: number;
}>;
createdAt: string;
updatedAt: string;
}
export interface SiteProduct {
id: string;
siteId: string;
name: string;
sku: string;
price: number;
stock: number;
status: 'published' | 'draft' | 'unpublished';
description?: string;
images?: string[];
category?: string;
createdAt: string;
updatedAt: string;
}
// ============================================
// IndependentSite专用接口
// ============================================
@@ -129,7 +206,7 @@ class ApiIndependentSiteDataSource implements IIndependentSiteDataSource {
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启用
*/
class MockIndependentSiteDataSource implements IIndependentSiteDataSource, IMockDataSource<IndependentSite, SiteQueryParams> {
class MockIndependentSiteDataSource implements IIndependentSiteDataSource, IMockDataSource<IndependentSite> {
readonly __MOCK__ = true as const;
readonly __MOCK_NAME__ = 'MockIndependentSiteDataSource';

View File

@@ -4,32 +4,55 @@
* 仅在USE_MOCK=true时启用
*/
import { Inventory } from '../types/inventory';
import { Inventory, InventoryStatus } from '../types/inventory';
export interface Warehouse {
id: string;
name: string;
code: string;
address: string;
city: string;
country: string;
capacity: number;
currentUsage: number;
status: 'active' | 'inactive' | 'maintenance';
manager: string;
phone: string;
email: string;
createdAt: string;
updatedAt: string;
}
export interface InventoryForecast {
id: string;
productId: string;
productName: string;
sku: string;
currentStock: number;
forecastedDemand: number;
recommendedOrder: number;
leadTime: number;
riskLevel: 'low' | 'medium' | 'high';
date: string;
}
export interface InventoryQueryParams {
productId?: string;
status?: InventoryStatus;
warehouseId?: string;
page?: number;
pageSize?: number;
}
// 库存数据接口
export interface InventoryDataSource {
list(params?: {
page?: number;
pageSize?: number;
productId?: string;
status?: string;
warehouseId?: string;
}): Promise<{ data: Inventory[]; total: number }>;
list(params?: InventoryQueryParams): Promise<{ data: Inventory[]; total: number }>;
get(id: string): Promise<Inventory | null>;
create(inventory: Omit<Inventory, 'id' | 'createdAt' | 'updatedAt'>): Promise<Inventory>;
update(id: string, inventory: Partial<Inventory>): Promise<Inventory | null>;
updateStock(id: string, quantity: number): Promise<Inventory | null>;
getByProductId(productId: string): Promise<Inventory[]>;
getByWarehouseId(warehouseId: string): Promise<Inventory[]>;
getLowStockAlerts(threshold: number): Promise<Inventory[]>;
getInventoryStatistics(): Promise<{
totalItems: number;
totalStock: number;
@@ -37,19 +60,12 @@ export interface InventoryDataSource {
outOfStockItems: number;
warehouseDistribution: Record<string, number>;
}>;
fetchWarehouses(): Promise<Warehouse[]>;
getInventoryForecasts(): Promise<InventoryForecast[]>;
}
// 库存DataSource实现
export class InventoryDataSourceImpl implements InventoryDataSource {
async list(params?: {
page?: number;
pageSize?: number;
productId?: string;
status?: string;
warehouseId?: string;
}): Promise<{ data: Inventory[]; total: number }> {
// 这里应该调用实际的API
// 暂时返回Mock数据
async list(params?: InventoryQueryParams): Promise<{ data: Inventory[]; total: number }> {
const mockInventory: Inventory[] = [
{
id: 'inv_1',
@@ -57,7 +73,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手表',
quantity: 100,
threshold: 20,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-10'),
@@ -70,7 +86,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '无线耳机',
quantity: 200,
threshold: 30,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-11'),
@@ -83,7 +99,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '运动鞋',
quantity: 150,
threshold: 25,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_2',
warehouseName: '上海仓库',
lastStockUpdate: new Date('2026-03-12'),
@@ -96,7 +112,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手机',
quantity: 5,
threshold: 10,
status: 'low_stock',
status: InventoryStatus.LOW_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-09'),
@@ -109,7 +125,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '平板电脑',
quantity: 0,
threshold: 15,
status: 'out_of_stock',
status: InventoryStatus.OUT_OF_STOCK,
warehouseId: 'warehouse_2',
warehouseName: '上海仓库',
lastStockUpdate: new Date('2026-03-08'),
@@ -145,8 +161,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async get(id: string): Promise<Inventory | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockInventory: Inventory[] = [
{
id: 'inv_1',
@@ -154,7 +168,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手表',
quantity: 100,
threshold: 20,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-10'),
@@ -167,7 +181,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '无线耳机',
quantity: 200,
threshold: 30,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-11'),
@@ -181,8 +195,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async create(inventory: Omit<Inventory, 'id' | 'createdAt' | 'updatedAt'>): Promise<Inventory> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const newInventory: Inventory = {
...inventory,
id: `inv_${Date.now()}`,
@@ -194,8 +206,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async update(id: string, inventory: Partial<Inventory>): Promise<Inventory | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const existingInventory = await this.get(id);
if (!existingInventory) {
return null;
@@ -211,22 +221,20 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async updateStock(id: string, quantity: number): Promise<Inventory | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const existingInventory = await this.get(id);
if (!existingInventory) {
return null;
}
const newQuantity = existingInventory.quantity + quantity;
let status: 'in_stock' | 'low_stock' | 'out_of_stock';
let status: InventoryStatus;
if (newQuantity <= 0) {
status = 'out_of_stock';
status = InventoryStatus.OUT_OF_STOCK;
} else if (newQuantity < existingInventory.threshold) {
status = 'low_stock';
status = InventoryStatus.LOW_STOCK;
} else {
status = 'in_stock';
status = InventoryStatus.IN_STOCK;
}
const updatedInventory: Inventory = {
@@ -241,8 +249,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async getByProductId(productId: string): Promise<Inventory[]> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockInventory: Inventory[] = [
{
id: 'inv_1',
@@ -250,7 +256,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手表',
quantity: 100,
threshold: 20,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-10'),
@@ -263,7 +269,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '无线耳机',
quantity: 200,
threshold: 30,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-11'),
@@ -276,8 +282,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async getByWarehouseId(warehouseId: string): Promise<Inventory[]> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockInventory: Inventory[] = [
{
id: 'inv_1',
@@ -285,7 +289,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手表',
quantity: 100,
threshold: 20,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-10'),
@@ -298,7 +302,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '无线耳机',
quantity: 200,
threshold: 30,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-11'),
@@ -311,7 +315,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '运动鞋',
quantity: 150,
threshold: 25,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_2',
warehouseName: '上海仓库',
lastStockUpdate: new Date('2026-03-12'),
@@ -324,8 +328,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
}
async getLowStockAlerts(threshold: number): Promise<Inventory[]> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockInventory: Inventory[] = [
{
id: 'inv_1',
@@ -333,7 +335,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手表',
quantity: 100,
threshold: 20,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-10'),
@@ -346,7 +348,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手机',
quantity: 5,
threshold: 10,
status: 'low_stock',
status: InventoryStatus.LOW_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-09'),
@@ -359,7 +361,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '平板电脑',
quantity: 0,
threshold: 15,
status: 'out_of_stock',
status: InventoryStatus.OUT_OF_STOCK,
warehouseId: 'warehouse_2',
warehouseName: '上海仓库',
lastStockUpdate: new Date('2026-03-08'),
@@ -378,8 +380,6 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
outOfStockItems: number;
warehouseDistribution: Record<string, number>;
}> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockInventory: Inventory[] = [
{
id: 'inv_1',
@@ -387,7 +387,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手表',
quantity: 100,
threshold: 20,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-10'),
@@ -400,7 +400,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '无线耳机',
quantity: 200,
threshold: 30,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-11'),
@@ -413,7 +413,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '运动鞋',
quantity: 150,
threshold: 25,
status: 'in_stock',
status: InventoryStatus.IN_STOCK,
warehouseId: 'warehouse_2',
warehouseName: '上海仓库',
lastStockUpdate: new Date('2026-03-12'),
@@ -426,7 +426,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '智能手机',
quantity: 5,
threshold: 10,
status: 'low_stock',
status: InventoryStatus.LOW_STOCK,
warehouseId: 'warehouse_1',
warehouseName: '北京仓库',
lastStockUpdate: new Date('2026-03-09'),
@@ -439,7 +439,7 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
productName: '平板电脑',
quantity: 0,
threshold: 15,
status: 'out_of_stock',
status: InventoryStatus.OUT_OF_STOCK,
warehouseId: 'warehouse_2',
warehouseName: '上海仓库',
lastStockUpdate: new Date('2026-03-08'),
@@ -450,12 +450,14 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
const totalItems = mockInventory.length;
const totalStock = mockInventory.reduce((sum, item) => sum + item.quantity, 0);
const lowStockItems = mockInventory.filter(i => i.status === 'low_stock').length;
const outOfStockItems = mockInventory.filter(i => i.status === 'out_of_stock').length;
const lowStockItems = mockInventory.filter(i => i.status === InventoryStatus.LOW_STOCK).length;
const outOfStockItems = mockInventory.filter(i => i.status === InventoryStatus.OUT_OF_STOCK).length;
const warehouseDistribution: Record<string, number> = {};
mockInventory.forEach(item => {
warehouseDistribution[item.warehouseName] = (warehouseDistribution[item.warehouseName] || 0) + item.quantity;
if (item.warehouseName) {
warehouseDistribution[item.warehouseName] = (warehouseDistribution[item.warehouseName] || 0) + item.quantity;
}
});
return {
@@ -466,7 +468,84 @@ export class InventoryDataSourceImpl implements InventoryDataSource {
warehouseDistribution,
};
}
async fetchWarehouses(): Promise<Warehouse[]> {
return [
{
id: 'warehouse_1',
name: '北京仓库',
code: 'BJ-WH-001',
address: '北京市朝阳区建国路88号',
city: '北京',
country: '中国',
capacity: 10000,
currentUsage: 7500,
status: 'active',
manager: '张三',
phone: '010-12345678',
email: 'zhangsan@example.com',
createdAt: '2026-01-01',
updatedAt: '2026-03-15',
},
{
id: 'warehouse_2',
name: '上海仓库',
code: 'SH-WH-001',
address: '上海市浦东新区张江路100号',
city: '上海',
country: '中国',
capacity: 15000,
currentUsage: 12000,
status: 'active',
manager: '李四',
phone: '021-87654321',
email: 'lisi@example.com',
createdAt: '2026-01-15',
updatedAt: '2026-03-16',
},
];
}
async getInventoryForecasts(): Promise<InventoryForecast[]> {
return [
{
id: 'forecast_1',
productId: '1',
productName: '智能手表',
sku: 'WATCH-001',
currentStock: 100,
forecastedDemand: 150,
recommendedOrder: 50,
leadTime: 7,
riskLevel: 'low',
date: '2026-03-21',
},
{
id: 'forecast_2',
productId: '2',
productName: '无线耳机',
sku: 'EARPHONE-001',
currentStock: 200,
forecastedDemand: 180,
recommendedOrder: 0,
leadTime: 5,
riskLevel: 'low',
date: '2026-03-21',
},
{
id: 'forecast_3',
productId: '4',
productName: '智能手机',
sku: 'PHONE-001',
currentStock: 5,
forecastedDemand: 50,
recommendedOrder: 45,
leadTime: 10,
riskLevel: 'high',
date: '2026-03-21',
},
];
}
}
// 导出DataSource实例
export const inventoryDataSource = new InventoryDataSourceImpl();

View File

@@ -37,6 +37,23 @@ export interface TrackingEvent {
timestamp: string;
}
export interface FreightQuote {
id: string;
channel: string;
carrier: string;
name: string;
basePrice: number;
pricePerKg: number;
pricePerVol: number;
estimatedDays: number;
totalPrice: number;
fuelSurcharge: number;
remoteAreaSurcharge: number;
customsDuty: number;
insurance: number;
totalWithDuty: number;
}
export interface ILogisticsDataSource {
fetchProviders(): Promise<LogisticsProvider[]>;
createProvider(data: Partial<LogisticsProvider>): Promise<LogisticsProvider>;

View File

@@ -31,6 +31,8 @@ export interface Competitor {
lastUpdated: string;
trackedProducts: string[];
marketShare?: number;
website?: string;
socialFollowers?: number;
}
export interface IMarketingDataSource {

View File

@@ -32,7 +32,9 @@ export interface MerchantShop {
export interface MerchantOrder {
id: string;
merchantId: string;
merchantName: string;
orderId: string;
platform: string;
totalAmount: number;
status: string;
createdAt: string;
@@ -123,7 +125,9 @@ class MockMerchantDataSource implements IMerchantDataSource {
{
id: '1',
merchantId: '1',
merchantName: 'Test Company A',
orderId: 'ORD-2026-001',
platform: 'Amazon',
totalAmount: 1500.00,
status: 'COMPLETED',
createdAt: '2026-03-15',

View File

@@ -6,7 +6,6 @@
import { Order } from '../types/order';
// 订单数据接口
export interface OrderDataSource {
list(params?: {
page?: number;
@@ -40,7 +39,6 @@ export interface OrderDataSource {
}>;
}
// 订单DataSource实现
export class OrderDataSourceImpl implements OrderDataSource {
async list(params?: {
page?: number;
@@ -50,8 +48,6 @@ export class OrderDataSourceImpl implements OrderDataSource {
startDate?: string;
endDate?: string;
}): Promise<{ data: Order[]; total: number }> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockOrders: Order[] = [
{
id: '1',
@@ -62,17 +58,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '1',
productName: '智能手表',
quantity: 1,
price: 199.99
unitPrice: 199.99,
totalPrice: 199.99
}
],
totalAmount: 199.99,
status: 'completed',
status: 'delivered',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-10'),
updatedAt: new Date('2026-03-10'),
@@ -86,17 +84,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '2',
productName: '无线耳机',
quantity: 2,
price: 129.99
unitPrice: 129.99,
totalPrice: 259.98
}
],
totalAmount: 259.98,
status: 'processing',
paymentMethod: 'paypal',
shippingAddress: {
street: '上海市浦东新区',
name: '李四',
address: '上海市浦东新区',
city: '上海',
country: '中国',
zipCode: '200000'
zip: '200000'
},
createdAt: new Date('2026-03-11'),
updatedAt: new Date('2026-03-11'),
@@ -110,17 +110,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '3',
productName: '运动鞋',
quantity: 1,
price: 89.99
unitPrice: 89.99,
totalPrice: 89.99
}
],
totalAmount: 89.99,
status: 'pending',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-12'),
updatedAt: new Date('2026-03-12'),
@@ -150,8 +152,6 @@ export class OrderDataSourceImpl implements OrderDataSource {
}
async get(id: string): Promise<Order | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockOrders: Order[] = [
{
id: '1',
@@ -162,17 +162,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '1',
productName: '智能手表',
quantity: 1,
price: 199.99
unitPrice: 199.99,
totalPrice: 199.99
}
],
totalAmount: 199.99,
status: 'completed',
status: 'delivered',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-10'),
updatedAt: new Date('2026-03-10'),
@@ -186,17 +188,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '2',
productName: '无线耳机',
quantity: 2,
price: 129.99
unitPrice: 129.99,
totalPrice: 259.98
}
],
totalAmount: 259.98,
status: 'processing',
paymentMethod: 'paypal',
shippingAddress: {
street: '上海市浦东新区',
name: '李四',
address: '上海市浦东新区',
city: '上海',
country: '中国',
zipCode: '200000'
zip: '200000'
},
createdAt: new Date('2026-03-11'),
updatedAt: new Date('2026-03-11'),
@@ -208,8 +212,6 @@ export class OrderDataSourceImpl implements OrderDataSource {
}
async create(order: Omit<Order, 'id' | 'createdAt' | 'updatedAt'>): Promise<Order> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const newOrder: Order = {
...order,
id: `order_${Date.now()}`,
@@ -221,8 +223,6 @@ export class OrderDataSourceImpl implements OrderDataSource {
}
async update(id: string, order: Partial<Order>): Promise<Order | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const existingOrder = await this.get(id);
if (!existingOrder) {
return null;
@@ -238,8 +238,6 @@ export class OrderDataSourceImpl implements OrderDataSource {
}
async updateStatus(id: string, status: string): Promise<Order | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const existingOrder = await this.get(id);
if (!existingOrder) {
return null;
@@ -247,7 +245,7 @@ export class OrderDataSourceImpl implements OrderDataSource {
const updatedOrder: Order = {
...existingOrder,
status: status as 'pending' | 'processing' | 'shipped' | 'completed' | 'cancelled',
status: status as Order['status'],
updatedAt: new Date(),
};
@@ -255,14 +253,21 @@ export class OrderDataSourceImpl implements OrderDataSource {
}
async cancel(id: string): Promise<Order | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
return this.updateStatus(id, 'cancelled');
const existingOrder = await this.get(id);
if (!existingOrder) {
return null;
}
const updatedOrder: Order = {
...existingOrder,
status: 'cancelled',
updatedAt: new Date(),
};
return updatedOrder;
}
async getByCustomerId(customerId: string): Promise<Order[]> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockOrders: Order[] = [
{
id: '1',
@@ -273,17 +278,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '1',
productName: '智能手表',
quantity: 1,
price: 199.99
unitPrice: 199.99,
totalPrice: 199.99
}
],
totalAmount: 199.99,
status: 'completed',
status: 'delivered',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-10'),
updatedAt: new Date('2026-03-10'),
@@ -297,17 +304,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '3',
productName: '运动鞋',
quantity: 1,
price: 89.99
unitPrice: 89.99,
totalPrice: 89.99
}
],
totalAmount: 89.99,
status: 'pending',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-12'),
updatedAt: new Date('2026-03-12'),
@@ -326,8 +335,6 @@ export class OrderDataSourceImpl implements OrderDataSource {
averageOrderValue: number;
statusDistribution: Record<string, number>;
}> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockOrders: Order[] = [
{
id: '1',
@@ -338,17 +345,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '1',
productName: '智能手表',
quantity: 1,
price: 199.99
unitPrice: 199.99,
totalPrice: 199.99
}
],
totalAmount: 199.99,
status: 'completed',
status: 'delivered',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-10'),
updatedAt: new Date('2026-03-10'),
@@ -362,17 +371,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '2',
productName: '无线耳机',
quantity: 2,
price: 129.99
unitPrice: 129.99,
totalPrice: 259.98
}
],
totalAmount: 259.98,
status: 'processing',
paymentMethod: 'paypal',
shippingAddress: {
street: '上海市浦东新区',
name: '李四',
address: '上海市浦东新区',
city: '上海',
country: '中国',
zipCode: '200000'
zip: '200000'
},
createdAt: new Date('2026-03-11'),
updatedAt: new Date('2026-03-11'),
@@ -386,17 +397,19 @@ export class OrderDataSourceImpl implements OrderDataSource {
productId: '3',
productName: '运动鞋',
quantity: 1,
price: 89.99
unitPrice: 89.99,
totalPrice: 89.99
}
],
totalAmount: 89.99,
status: 'pending',
paymentMethod: 'credit_card',
shippingAddress: {
street: '北京市朝阳区',
name: '张三',
address: '北京市朝阳区',
city: '北京',
country: '中国',
zipCode: '100000'
zip: '100000'
},
createdAt: new Date('2026-03-12'),
updatedAt: new Date('2026-03-12'),
@@ -421,5 +434,4 @@ export class OrderDataSourceImpl implements OrderDataSource {
}
}
// 导出DataSource实例
export const orderDataSource = new OrderDataSourceImpl();

View File

@@ -1,5 +1,10 @@
// 产品数据源
import { Product } from '@/types/product';
/**
* [MOCK-007] 产品模块DataSource
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
import { Product, ProductStatus } from '@/types/product';
import { IDataSource, IMockDataSource } from '@/types/datasource';
export interface ProfitMonitor {
@@ -30,54 +35,45 @@ export interface ROIAnalysis {
status: 'ACTIVE' | 'COMPLETED' | 'PAUSED';
}
// API实现
export class ProductApiDataSource implements IDataSource<Product> {
async list(): Promise<Product[]> {
// 这里应该调用实际的API
return [];
}
async detail(id: string): Promise<Product> {
// 这里应该调用实际的API
throw new Error('Not implemented');
}
async create(data: Partial<Product>): Promise<Product> {
// 这里应该调用实际的API
throw new Error('Not implemented');
}
async update(id: string, data: Partial<Product>): Promise<Product> {
// 这里应该调用实际的API
throw new Error('Not implemented');
}
async delete(id: string): Promise<void> {
// 这里应该调用实际的API
throw new Error('Not implemented');
}
// 额外的方法
async getByCategory(category: string): Promise<Product[]> {
// 这里应该调用实际的API
return [];
}
async updateStatus(id: string, status: 'active' | 'inactive' | 'discontinued'): Promise<Product | null> {
// 这里应该调用实际的API
async updateStatus(id: string, status: ProductStatus): Promise<Product | null> {
throw new Error('Not implemented');
}
}
// Mock实现
export class ProductMockDataSource implements IMockDataSource<Product> {
private mockProducts: Product[] = [
{
id: '1',
name: '智能手机',
sku: 'PHONE-001',
description: '最新款智能手机',
price: 5999.99,
category: '电子产品',
categories: ['电子产品'],
status: 'active',
stock: 100,
images: ['https://example.com/phone1.jpg', 'https://example.com/phone2.jpg'],
@@ -87,9 +83,10 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
{
id: '2',
name: '笔记本电脑',
sku: 'LAPTOP-001',
description: '高性能笔记本电脑',
price: 8999.99,
category: '电子产品',
categories: ['电子产品'],
status: 'active',
stock: 50,
images: ['https://example.com/laptop1.jpg', 'https://example.com/laptop2.jpg'],
@@ -99,9 +96,10 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
{
id: '3',
name: '运动鞋',
sku: 'SHOE-001',
description: '轻便透气运动鞋',
price: 89.99,
category: '服装',
categories: ['服装'],
status: 'active',
stock: 150,
images: ['https://example.com/shoe1.jpg', 'https://example.com/shoe2.jpg'],
@@ -126,9 +124,10 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
const newProduct: Product = {
id: `${this.mockProducts.length + 1}`,
name: data.name || '',
sku: data.sku || `SKU-${Date.now()}`,
description: data.description || '',
price: data.price || 0,
category: data.category || '',
categories: data.categories || [],
status: data.status || 'active',
stock: data.stock || 0,
images: data.images || [],
@@ -160,12 +159,11 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
this.mockProducts.splice(index, 1);
}
// 额外的方法
async getByCategory(category: string): Promise<Product[]> {
return this.mockProducts.filter(p => p.category === category);
return this.mockProducts.filter(p => p.categories?.includes(category));
}
async updateStatus(id: string, status: 'active' | 'inactive' | 'discontinued'): Promise<Product | null> {
async updateStatus(id: string, status: ProductStatus): Promise<Product | null> {
const existingProduct = this.mockProducts.find(p => p.id === id);
if (!existingProduct) {
return null;
@@ -185,15 +183,15 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
return updatedProduct;
}
// Mock特定方法
reset(): void {
this.mockProducts = [
{
id: '1',
name: '智能手机',
sku: 'PHONE-001',
description: '最新款智能手机',
price: 5999.99,
category: '电子产品',
categories: ['电子产品'],
status: 'active',
stock: 100,
images: ['https://example.com/phone1.jpg', 'https://example.com/phone2.jpg'],
@@ -203,9 +201,10 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
{
id: '2',
name: '笔记本电脑',
sku: 'LAPTOP-001',
description: '高性能笔记本电脑',
price: 8999.99,
category: '电子产品',
categories: ['电子产品'],
status: 'active',
stock: 50,
images: ['https://example.com/laptop1.jpg', 'https://example.com/laptop2.jpg'],
@@ -215,9 +214,10 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
{
id: '3',
name: '运动鞋',
sku: 'SHOE-001',
description: '轻便透气运动鞋',
price: 89.99,
category: '服装',
categories: ['服装'],
status: 'active',
stock: 150,
images: ['https://example.com/shoe1.jpg', 'https://example.com/shoe2.jpg'],
@@ -232,8 +232,4 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
}
}
// 数据源导出
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
export const productDataSource = useMock
? new ProductMockDataSource()
: new ProductApiDataSource();
export const productDataSource = new ProductMockDataSource();

View File

@@ -236,7 +236,7 @@ export class UserDataSourceImpl implements UserDataSource {
return mockUsers.filter(u =>
u.name.toLowerCase().includes(keyword.toLowerCase()) ||
u.email.toLowerCase().includes(keyword.toLowerCase()) ||
u.phone.includes(keyword)
(u.phone && u.phone.includes(keyword))
);
}