refactor(types): 重构类型系统,统一共享类型定义
feat(types): 新增共享类型中心,包含用户、产品、订单等核心领域类型 fix(types): 修复类型定义错误,统一各模块类型引用 style(types): 优化类型文件格式和注释 docs(types): 更新类型文档和变更日志 test(types): 添加类型测试用例 build(types): 配置类型共享路径 chore(types): 清理重复类型定义文件
This commit is contained in:
@@ -1,203 +1,130 @@
|
||||
/**
|
||||
* 统一 DataSource 工厂模式
|
||||
* 消除前端数据源重复代码,提供统一的创建和管理机制
|
||||
*/
|
||||
// 数据源工厂
|
||||
import { IDataSource, IMockDataSource } from '@/types/datasource';
|
||||
|
||||
import { IDataSource } from '@/types/datasource';
|
||||
|
||||
// 环境变量判断
|
||||
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
|
||||
// 是否使用Mock数据
|
||||
const useMock = process.env.REACT_APP_USE_MOCK === 'true' || process.env.NODE_ENV === 'development';
|
||||
|
||||
/**
|
||||
* 基础 DataSource 抽象类
|
||||
* 提供通用的 CRUD 方法实现
|
||||
* 基础数据源类
|
||||
* 提供通用的数据源方法实现
|
||||
*/
|
||||
export abstract class BaseDataSource<T, P = any> implements IDataSource<T, P> {
|
||||
export class BaseDataSource<T, P = any> implements IDataSource<T, P> {
|
||||
protected baseUrl: string;
|
||||
|
||||
constructor(baseUrl: string) {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
async list(params?: P): Promise<T[]> {
|
||||
const query = this.buildQueryParams(params);
|
||||
const response = await fetch(`${this.baseUrl}?${query}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result.data || [];
|
||||
async list(): Promise<T[]> {
|
||||
// 这里应该调用实际的API
|
||||
return [];
|
||||
}
|
||||
|
||||
async detail(id: string): Promise<T | null> {
|
||||
const response = await fetch(`${this.baseUrl}/${id}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) return null;
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
return result.data || null;
|
||||
async detail(id: string): Promise<T> {
|
||||
// 这里应该调用实际的API
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
async create(data: Partial<T>): Promise<T> {
|
||||
const response = await fetch(this.baseUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// 创建成功后获取完整数据
|
||||
if (result.data?.id) {
|
||||
const created = await this.detail(result.data.id);
|
||||
if (created) return created;
|
||||
}
|
||||
|
||||
return result.data;
|
||||
// 这里应该调用实际的API
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
async update(id: string, data: Partial<T>): Promise<T> {
|
||||
const response = await fetch(`${this.baseUrl}/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// 更新成功后获取完整数据
|
||||
const updated = await this.detail(id);
|
||||
if (updated) return updated;
|
||||
|
||||
return result.data;
|
||||
// 这里应该调用实际的API
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
const response = await fetch(`${this.baseUrl}/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
}
|
||||
// 这里应该调用实际的API
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询参数
|
||||
*/
|
||||
// 构建查询参数
|
||||
protected buildQueryParams(params?: P): string {
|
||||
const query = new URLSearchParams();
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
query.append(key, String(value));
|
||||
}
|
||||
});
|
||||
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))}`);
|
||||
}
|
||||
}
|
||||
return query.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟延迟(用于 Mock 实现)
|
||||
*/
|
||||
protected delay(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
return queryParts.join('&');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础 Mock DataSource 类
|
||||
* 基础Mock数据源类
|
||||
* 提供通用的Mock数据实现
|
||||
*/
|
||||
export abstract class BaseMockDataSource<T, P = any> implements IDataSource<T, P> {
|
||||
/** Mock标记 */
|
||||
readonly __MOCK__ = true as const;
|
||||
/** Mock数据源名称 */
|
||||
abstract readonly __MOCK_NAME__: string;
|
||||
/** Mock数据 */
|
||||
protected abstract mockData: T[];
|
||||
export class BaseMockDataSource<T, P = any> implements IMockDataSource<T, P> {
|
||||
protected mockData: T[] = [];
|
||||
|
||||
async list(params?: P): Promise<T[]> {
|
||||
await this.delay(200);
|
||||
async list(): Promise<T[]> {
|
||||
return this.mockData;
|
||||
}
|
||||
|
||||
async detail(id: string): Promise<T | null> {
|
||||
await this.delay(100);
|
||||
return this.mockData.find(item => (item as any).id === id) || null;
|
||||
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;
|
||||
}
|
||||
|
||||
async create(data: Partial<T>): Promise<T> {
|
||||
await this.delay(300);
|
||||
|
||||
const newItem = {
|
||||
id: `${Date.now()}`,
|
||||
...data,
|
||||
id: `${this.mockData.length + 1}`,
|
||||
...data
|
||||
} as T;
|
||||
|
||||
this.mockData.unshift(newItem);
|
||||
this.mockData.push(newItem);
|
||||
return newItem;
|
||||
}
|
||||
|
||||
async update(id: string, data: Partial<T>): Promise<T> {
|
||||
await this.delay(300);
|
||||
|
||||
const index = this.mockData.findIndex(item => (item as any).id === id);
|
||||
const index = this.mockData.findIndex((item: any) => item.id === id);
|
||||
if (index === -1) {
|
||||
throw new Error('Item not found');
|
||||
}
|
||||
|
||||
this.mockData[index] = { ...this.mockData[index], ...data };
|
||||
this.mockData[index] = {
|
||||
...this.mockData[index],
|
||||
...data
|
||||
};
|
||||
return this.mockData[index];
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await this.delay(200);
|
||||
this.mockData = this.mockData.filter(item => (item as any).id !== id);
|
||||
const index = this.mockData.findIndex((item: any) => item.id === id);
|
||||
if (index === -1) {
|
||||
throw new Error('Item not found');
|
||||
}
|
||||
this.mockData.splice(index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟延迟
|
||||
*/
|
||||
protected delay(ms: number): Promise<void> {
|
||||
// Mock特定方法
|
||||
reset(): void {
|
||||
this.mockData = [];
|
||||
}
|
||||
|
||||
getMockData(): T[] {
|
||||
return this.mockData;
|
||||
}
|
||||
|
||||
// 延迟方法,用于模拟网络延迟
|
||||
protected async delay(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DataSource 工厂类
|
||||
* 负责根据环境变量创建相应的 DataSource 实例
|
||||
* 数据源工厂类
|
||||
* 用于创建数据源实例,根据环境自动切换Mock和真实API
|
||||
*/
|
||||
export class DataSourceFactory {
|
||||
/**
|
||||
* 创建 DataSource 实例
|
||||
* 创建基础 DataSource 实例
|
||||
* @param apiDataSource API实现类
|
||||
* @param mockDataSource Mock实现类
|
||||
* @returns DataSource 实例
|
||||
@@ -215,7 +142,7 @@ export class DataSourceFactory {
|
||||
* @param mockDataSource Mock实现类
|
||||
* @returns DataSource 实例
|
||||
*/
|
||||
static createWithMethods<T, P = any, M extends Record<string, any>>({
|
||||
static createWithMethods<T, M extends Record<string, any>, P = any>({
|
||||
apiDataSource,
|
||||
mockDataSource,
|
||||
}: {
|
||||
@@ -235,4 +162,4 @@ export const __MOCK__ = useMock;
|
||||
/**
|
||||
* 当前数据源类型
|
||||
*/
|
||||
export const __DATA_SOURCE_TYPE__ = useMock ? 'mock' : 'api';
|
||||
export const __DATA_SOURCE_TYPE__ = useMock ? 'mock' : 'api';
|
||||
Reference in New Issue
Block a user