2026-03-20 17:53:46 +08:00
|
|
|
|
// 数据源工厂
|
|
|
|
|
|
import { IDataSource, IMockDataSource } from '@/types/datasource';
|
2026-03-19 14:19:01 +08:00
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
// 是否使用Mock数据
|
|
|
|
|
|
const useMock = process.env.REACT_APP_USE_MOCK === 'true' || process.env.NODE_ENV === 'development';
|
2026-03-19 14:19:01 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2026-03-20 17:53:46 +08:00
|
|
|
|
* 基础数据源类
|
|
|
|
|
|
* 提供通用的数据源方法实现
|
2026-03-19 14:19:01 +08:00
|
|
|
|
*/
|
2026-03-20 17:53:46 +08:00
|
|
|
|
export class BaseDataSource<T, P = any> implements IDataSource<T, P> {
|
2026-03-19 14:19:01 +08:00
|
|
|
|
protected baseUrl: string;
|
|
|
|
|
|
|
|
|
|
|
|
constructor(baseUrl: string) {
|
|
|
|
|
|
this.baseUrl = baseUrl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
async list(): Promise<T[]> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
return [];
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
async detail(id: string): Promise<T> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
throw new Error('Not implemented');
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async create(data: Partial<T>): Promise<T> {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
throw new Error('Not implemented');
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async update(id: string, data: Partial<T>): Promise<T> {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
throw new Error('Not implemented');
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async delete(id: string): Promise<void> {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
throw new Error('Not implemented');
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
// 构建查询参数
|
2026-03-19 14:19:01 +08:00
|
|
|
|
protected buildQueryParams(params?: P): string {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
if (!params) return '';
|
|
|
|
|
|
|
|
|
|
|
|
const queryParts = [];
|
|
|
|
|
|
for (const [key, value] of Object.entries(params)) {
|
|
|
|
|
|
if (value !== undefined && value !== null) {
|
|
|
|
|
|
queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
|
|
|
|
}
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
2026-03-20 17:53:46 +08:00
|
|
|
|
|
|
|
|
|
|
return queryParts.join('&');
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-03-20 17:53:46 +08:00
|
|
|
|
* 基础Mock数据源类
|
|
|
|
|
|
* 提供通用的Mock数据实现
|
2026-03-19 14:19:01 +08:00
|
|
|
|
*/
|
2026-03-22 11:25:28 +08:00
|
|
|
|
export class BaseMockDataSource<T, P = any> implements IMockDataSource<T> {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
protected mockData: T[] = [];
|
|
|
|
|
|
|
2026-03-22 11:25:28 +08:00
|
|
|
|
reset(): void {
|
|
|
|
|
|
this.mockData = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
getMockData(): T[] {
|
|
|
|
|
|
return this.mockData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
async list(): Promise<T[]> {
|
2026-03-19 14:19:01 +08:00
|
|
|
|
return this.mockData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
async detail(id: string): Promise<T> {
|
|
|
|
|
|
const item = this.mockData.find((item: any) => item.id === id);
|
|
|
|
|
|
if (!item) {
|
|
|
|
|
|
throw new Error('Item not found');
|
|
|
|
|
|
}
|
|
|
|
|
|
return item;
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async create(data: Partial<T>): Promise<T> {
|
|
|
|
|
|
const newItem = {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
id: `${this.mockData.length + 1}`,
|
|
|
|
|
|
...data
|
2026-03-19 14:19:01 +08:00
|
|
|
|
} as T;
|
2026-03-20 17:53:46 +08:00
|
|
|
|
this.mockData.push(newItem);
|
2026-03-19 14:19:01 +08:00
|
|
|
|
return newItem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async update(id: string, data: Partial<T>): Promise<T> {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
const index = this.mockData.findIndex((item: any) => item.id === id);
|
2026-03-19 14:19:01 +08:00
|
|
|
|
if (index === -1) {
|
|
|
|
|
|
throw new Error('Item not found');
|
|
|
|
|
|
}
|
2026-03-20 17:53:46 +08:00
|
|
|
|
this.mockData[index] = {
|
|
|
|
|
|
...this.mockData[index],
|
|
|
|
|
|
...data
|
|
|
|
|
|
};
|
2026-03-19 14:19:01 +08:00
|
|
|
|
return this.mockData[index];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async delete(id: string): Promise<void> {
|
2026-03-20 17:53:46 +08:00
|
|
|
|
const index = this.mockData.findIndex((item: any) => item.id === id);
|
|
|
|
|
|
if (index === -1) {
|
|
|
|
|
|
throw new Error('Item not found');
|
|
|
|
|
|
}
|
|
|
|
|
|
this.mockData.splice(index, 1);
|
2026-03-19 14:19:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-20 17:53:46 +08:00
|
|
|
|
// 延迟方法,用于模拟网络延迟
|
|
|
|
|
|
protected async delay(ms: number): Promise<void> {
|
2026-03-19 14:19:01 +08:00
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-03-20 17:53:46 +08:00
|
|
|
|
* 数据源工厂类
|
|
|
|
|
|
* 用于创建数据源实例,根据环境自动切换Mock和真实API
|
2026-03-19 14:19:01 +08:00
|
|
|
|
*/
|
|
|
|
|
|
export class DataSourceFactory {
|
|
|
|
|
|
/**
|
2026-03-20 17:53:46 +08:00
|
|
|
|
* 创建基础 DataSource 实例
|
2026-03-19 14:19:01 +08:00
|
|
|
|
* @param apiDataSource API实现类
|
|
|
|
|
|
* @param mockDataSource Mock实现类
|
|
|
|
|
|
* @returns DataSource 实例
|
|
|
|
|
|
*/
|
|
|
|
|
|
static create<T, P = any>(
|
|
|
|
|
|
apiDataSource: new () => IDataSource<T, P>,
|
|
|
|
|
|
mockDataSource: new () => IDataSource<T, P>
|
|
|
|
|
|
): IDataSource<T, P> {
|
|
|
|
|
|
return useMock ? new mockDataSource() : new apiDataSource();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 创建带有自定义方法的 DataSource 实例
|
|
|
|
|
|
* @param apiDataSource API实现类
|
|
|
|
|
|
* @param mockDataSource Mock实现类
|
|
|
|
|
|
* @returns DataSource 实例
|
|
|
|
|
|
*/
|
2026-03-20 17:53:46 +08:00
|
|
|
|
static createWithMethods<T, M extends Record<string, any>, P = any>({
|
2026-03-19 14:19:01 +08:00
|
|
|
|
apiDataSource,
|
|
|
|
|
|
mockDataSource,
|
|
|
|
|
|
}: {
|
|
|
|
|
|
apiDataSource: new () => IDataSource<T, P> & M;
|
|
|
|
|
|
mockDataSource: new () => IDataSource<T, P> & M;
|
|
|
|
|
|
}): IDataSource<T, P> & M {
|
|
|
|
|
|
return useMock ? new mockDataSource() : new apiDataSource();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Mock状态标记
|
|
|
|
|
|
* 用于调试和开发环境识别
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const __MOCK__ = useMock;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 当前数据源类型
|
|
|
|
|
|
*/
|
2026-03-20 17:53:46 +08:00
|
|
|
|
export const __DATA_SOURCE_TYPE__ = useMock ? 'mock' : 'api';
|