@qlover/create-app 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/templates/react-app/README.en.md +257 -0
  5. package/dist/templates/react-app/README.md +29 -231
  6. package/dist/templates/react-app/__tests__/__mocks__/I18nService.ts +13 -0
  7. package/dist/templates/react-app/__tests__/__mocks__/MockAppConfit.ts +48 -0
  8. package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +16 -0
  9. package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +14 -0
  10. package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +92 -0
  11. package/dist/templates/react-app/__tests__/setup/index.ts +51 -0
  12. package/dist/templates/react-app/__tests__/src/App.test.tsx +139 -0
  13. package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +288 -0
  14. package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +102 -0
  15. package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +228 -0
  16. package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +207 -0
  17. package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +181 -0
  18. package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +61 -0
  19. package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +199 -0
  20. package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +192 -0
  21. package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +235 -0
  22. package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +224 -0
  23. package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +257 -0
  24. package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +72 -0
  25. package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +62 -0
  26. package/dist/templates/react-app/__tests__/src/main.test.tsx +46 -0
  27. package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +88 -0
  28. package/dist/templates/react-app/config/app.router.ts +155 -0
  29. package/dist/templates/react-app/config/common.ts +9 -1
  30. package/dist/templates/react-app/docs/en/bootstrap.md +562 -0
  31. package/dist/templates/react-app/docs/en/development-guide.md +523 -0
  32. package/dist/templates/react-app/docs/en/env.md +482 -0
  33. package/dist/templates/react-app/docs/en/global.md +509 -0
  34. package/dist/templates/react-app/docs/en/i18n.md +268 -0
  35. package/dist/templates/react-app/docs/en/index.md +173 -0
  36. package/dist/templates/react-app/docs/en/ioc.md +424 -0
  37. package/dist/templates/react-app/docs/en/project-structure.md +434 -0
  38. package/dist/templates/react-app/docs/en/request.md +425 -0
  39. package/dist/templates/react-app/docs/en/router.md +404 -0
  40. package/dist/templates/react-app/docs/en/store.md +321 -0
  41. package/dist/templates/react-app/docs/en/test-guide.md +782 -0
  42. package/dist/templates/react-app/docs/en/theme.md +424 -0
  43. package/dist/templates/react-app/docs/en/typescript-guide.md +473 -0
  44. package/dist/templates/react-app/docs/zh/bootstrap.md +7 -0
  45. package/dist/templates/react-app/docs/zh/development-guide.md +523 -0
  46. package/dist/templates/react-app/docs/zh/env.md +24 -25
  47. package/dist/templates/react-app/docs/zh/global.md +28 -27
  48. package/dist/templates/react-app/docs/zh/i18n.md +268 -0
  49. package/dist/templates/react-app/docs/zh/index.md +173 -0
  50. package/dist/templates/react-app/docs/zh/ioc.md +44 -32
  51. package/dist/templates/react-app/docs/zh/project-structure.md +434 -0
  52. package/dist/templates/react-app/docs/zh/request.md +429 -0
  53. package/dist/templates/react-app/docs/zh/router.md +408 -0
  54. package/dist/templates/react-app/docs/zh/store.md +321 -0
  55. package/dist/templates/react-app/docs/zh/test-guide.md +782 -0
  56. package/dist/templates/react-app/docs/zh/theme.md +424 -0
  57. package/dist/templates/react-app/docs/zh/typescript-guide.md +473 -0
  58. package/dist/templates/react-app/package.json +9 -20
  59. package/dist/templates/react-app/src/base/cases/AppConfig.ts +16 -9
  60. package/dist/templates/react-app/src/base/cases/PublicAssetsPath.ts +7 -1
  61. package/dist/templates/react-app/src/base/services/I18nService.ts +15 -4
  62. package/dist/templates/react-app/src/base/services/RouteService.ts +43 -7
  63. package/dist/templates/react-app/src/core/bootstraps/BootstrapApp.ts +31 -10
  64. package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +1 -1
  65. package/dist/templates/react-app/src/core/globals.ts +1 -3
  66. package/dist/templates/react-app/src/core/registers/RegisterCommon.ts +5 -3
  67. package/dist/templates/react-app/src/main.tsx +6 -1
  68. package/dist/templates/react-app/src/pages/404.tsx +0 -1
  69. package/dist/templates/react-app/src/pages/500.tsx +1 -1
  70. package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +3 -1
  71. package/dist/templates/react-app/src/styles/css/antd-themes/dark.css +3 -1
  72. package/dist/templates/react-app/src/styles/css/antd-themes/index.css +1 -1
  73. package/dist/templates/react-app/src/styles/css/antd-themes/pink.css +6 -1
  74. package/dist/templates/react-app/src/styles/css/page.css +1 -1
  75. package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +9 -2
  76. package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +5 -3
  77. package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +4 -6
  78. package/dist/templates/react-app/tsconfig.json +2 -1
  79. package/dist/templates/react-app/tsconfig.test.json +13 -0
  80. package/dist/templates/react-app/vite.config.ts +3 -2
  81. package/package.json +1 -1
@@ -0,0 +1,429 @@
1
+ # 请求系统
2
+
3
+ ## 概述
4
+
5
+ 请求系统基于 `@qlover/fe-corekit` 的 request 模块实现,提供了一个功能强大、可扩展的 HTTP 请求解决方案。系统采用插件化架构,支持请求拦截、响应处理、错误处理等功能。
6
+
7
+ ## 核心特性
8
+
9
+ - 🔌 **插件化架构**:支持自定义插件扩展
10
+ - 🔄 **请求调度**:统一的请求调度管理
11
+ - 🛡️ **类型安全**:完整的 TypeScript 支持
12
+ - 🎯 **请求中断**:支持请求取消
13
+ - 📝 **日志记录**:详细的请求日志
14
+ - 🔧 **Mock 支持**:内置数据 Mock 功能
15
+
16
+ ## 基础架构
17
+
18
+ ```typescript
19
+ // 请求系统架构
20
+ Request → Scheduler → Adapter → Plugins → Network
21
+ ```
22
+
23
+ ## 使用方式
24
+
25
+ ### 1. 创建 API 服务
26
+
27
+ ```typescript
28
+ import { RequestAdapterFetch, RequestScheduler } from '@qlover/fe-corekit';
29
+
30
+ @injectable()
31
+ export class FeApi extends RequestScheduler<FeApiConfig> {
32
+ constructor(@inject(FeApiAdapter) adapter: RequestAdapterFetch) {
33
+ super(adapter);
34
+ }
35
+
36
+ // API 方法定义
37
+ async getIpInfo(): Promise<FeApiGetIpInfo['response']> {
38
+ return this.get('http://ip-api.com/json/');
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### 2. 配置请求适配器
44
+
45
+ ```typescript
46
+ import { RequestAdapterFetch } from '@qlover/fe-corekit';
47
+
48
+ const apiAdapter = new RequestAdapterFetch({
49
+ responseType: 'json',
50
+ baseURL: '/api'
51
+ });
52
+
53
+ // 配置插件
54
+ apiAdapter.usePlugin(new FetchURLPlugin());
55
+ apiAdapter.usePlugin(
56
+ new RequestCommonPlugin({
57
+ tokenPrefix: 'Bearer',
58
+ token: () => getToken()
59
+ })
60
+ );
61
+ ```
62
+
63
+ ### 3. 注册请求服务
64
+
65
+ ```typescript
66
+ // core/registers/RegisterCommon.ts
67
+ export const RegisterCommon: IOCRegister = {
68
+ register(container) {
69
+ // 注册请求插件
70
+ const feApiAbort = new FetchAbortPlugin();
71
+ const feApiRequestCommonPlugin = new RequestCommonPlugin({
72
+ tokenPrefix: AppConfig.openAiTokenPrefix,
73
+ requiredToken: true,
74
+ token: () => container.get(UserService).getToken()
75
+ });
76
+
77
+ container.bind(FetchAbortPlugin, feApiAbort);
78
+ container.bind(IOCIdentifier.FeApiCommonPlugin, feApiRequestCommonPlugin);
79
+ container.bind(
80
+ IOCIdentifier.ApiMockPlugin,
81
+ new ApiMockPlugin(mockDataJson, container.get(Logger))
82
+ );
83
+ }
84
+ };
85
+ ```
86
+
87
+ ### 4. 在组件中使用
88
+
89
+ ```typescript
90
+ @injectable()
91
+ export class RequestController extends StoreInterface<RequestControllerState> {
92
+ constructor(
93
+ @inject(FeApi) private readonly feApi: FeApi,
94
+ @inject(UserApi) private readonly userApi: UserApi
95
+ ) {
96
+ super(createDefaultState);
97
+ }
98
+
99
+ async fetchData() {
100
+ if (this.state.loading) return;
101
+
102
+ this.setState({ loading: true });
103
+ try {
104
+ const result = await this.feApi.getData();
105
+ this.setState({ loading: false, data: result });
106
+ } catch (error) {
107
+ this.setState({ loading: false, error });
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ ## 插件系统
114
+
115
+ ### 1. 内置插件
116
+
117
+ #### FetchURLPlugin
118
+
119
+ - URL 处理和构建
120
+ - 参数序列化
121
+ - baseURL 处理
122
+
123
+ ```typescript
124
+ apiAdapter.usePlugin(new FetchURLPlugin());
125
+ ```
126
+
127
+ #### RequestCommonPlugin
128
+
129
+ - 通用请求头设置
130
+ - Token 管理
131
+ - 认证信息处理
132
+
133
+ ```typescript
134
+ apiAdapter.usePlugin(
135
+ new RequestCommonPlugin({
136
+ tokenPrefix: 'Bearer',
137
+ requiredToken: true,
138
+ token: () => getToken()
139
+ })
140
+ );
141
+ ```
142
+
143
+ #### ApiMockPlugin
144
+
145
+ - Mock 数据支持
146
+ - 开发环境调试
147
+ - 接口模拟
148
+
149
+ ```typescript
150
+ apiAdapter.usePlugin(new ApiMockPlugin(mockDataJson, logger));
151
+ ```
152
+
153
+ #### RequestLogger
154
+
155
+ - 请求日志记录
156
+ - 错误追踪
157
+ - 调试信息
158
+
159
+ ```typescript
160
+ @injectable()
161
+ export class RequestLogger
162
+ implements ExecutorPlugin<RequestAdapterFetchConfig>
163
+ {
164
+ readonly pluginName = 'RequestLogger';
165
+
166
+ onBefore(context) {
167
+ this.logger.log(`Request: ${context.parameters.url}`);
168
+ }
169
+
170
+ onSuccess(context) {
171
+ this.logger.log(`Success: ${context.parameters.url}`);
172
+ }
173
+
174
+ onError(context) {
175
+ this.logger.error(`Error: ${context.parameters.url}`);
176
+ }
177
+ }
178
+ ```
179
+
180
+ ### 2. 自定义插件
181
+
182
+ 创建自定义插件:
183
+
184
+ ```typescript
185
+ export class CustomPlugin implements ExecutorPlugin<RequestAdapterFetchConfig> {
186
+ readonly pluginName = 'CustomPlugin';
187
+
188
+ onBefore(context) {
189
+ // 请求前处理
190
+ }
191
+
192
+ onSuccess(context) {
193
+ // 请求成功处理
194
+ }
195
+
196
+ onError(context) {
197
+ // 请求失败处理
198
+ }
199
+ }
200
+ ```
201
+
202
+ ## 请求配置
203
+
204
+ ### 1. 基础配置
205
+
206
+ ```typescript
207
+ interface RequestConfig {
208
+ url: string;
209
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
210
+ headers?: Record<string, string>;
211
+ params?: Record<string, any>;
212
+ data?: any;
213
+ timeout?: number;
214
+ responseType?: 'json' | 'text' | 'blob';
215
+ }
216
+ ```
217
+
218
+ ### 2. 高级配置
219
+
220
+ ```typescript
221
+ interface AdvancedConfig extends RequestConfig {
222
+ requestId?: string; // 用于请求取消
223
+ mock?: boolean; // 启用 Mock 数据
224
+ retries?: number; // 重试次数
225
+ withCredentials?: boolean; // 跨域携带凭证
226
+ }
227
+ ```
228
+
229
+ ## 错误处理
230
+
231
+ ### 1. 统一错误处理
232
+
233
+ ```typescript
234
+ export class ApiCatchPlugin implements ExecutorPlugin {
235
+ onError(context) {
236
+ const error = context.error;
237
+
238
+ if (error.status === 401) {
239
+ // 处理认证错误
240
+ handleAuthError();
241
+ } else if (error.status === 500) {
242
+ // 处理服务器错误
243
+ handleServerError();
244
+ }
245
+ }
246
+ }
247
+ ```
248
+
249
+ ### 2. 业务层错误处理
250
+
251
+ ```typescript
252
+ try {
253
+ const result = await api.getData();
254
+ handleSuccess(result);
255
+ } catch (error) {
256
+ if (error instanceof ApiError) {
257
+ handleApiError(error);
258
+ } else {
259
+ handleUnexpectedError(error);
260
+ }
261
+ }
262
+ ```
263
+
264
+ ## 最佳实践
265
+
266
+ ### 1. API 组织
267
+
268
+ - 按功能模块组织 API
269
+ - 使用统一的响应类型
270
+ - 实现完整的类型定义
271
+
272
+ ```typescript
273
+ // 用户相关 API
274
+ export class UserApi extends RequestScheduler {
275
+ login(data: LoginData): Promise<LoginResponse> {}
276
+ register(data: RegisterData): Promise<RegisterResponse> {}
277
+ getUserInfo(): Promise<UserInfo> {}
278
+ }
279
+
280
+ // 订单相关 API
281
+ export class OrderApi extends RequestScheduler {
282
+ createOrder(data: OrderData): Promise<OrderResponse> {}
283
+ getOrderList(): Promise<OrderList> {}
284
+ cancelOrder(id: string): Promise<void> {}
285
+ }
286
+ ```
287
+
288
+ ### 2. 请求状态管理
289
+
290
+ - 使用 Store 管理请求状态
291
+ - 实现加载状态控制
292
+ - 处理并发请求
293
+
294
+ ```typescript
295
+ interface RequestState<T> {
296
+ loading: boolean;
297
+ data: T | null;
298
+ error: Error | null;
299
+ }
300
+
301
+ class DataStore extends StoreInterface<RequestState<Data>> {
302
+ async fetchData() {
303
+ if (this.state.loading) return;
304
+
305
+ this.setState({ loading: true });
306
+ try {
307
+ const data = await api.getData();
308
+ this.setState({ loading: false, data });
309
+ } catch (error) {
310
+ this.setState({ loading: false, error });
311
+ }
312
+ }
313
+ }
314
+ ```
315
+
316
+ ### 3. 请求缓存
317
+
318
+ - 实现请求结果缓存
319
+ - 避免重复请求
320
+ - 管理缓存生命周期
321
+
322
+ ```typescript
323
+ class CachePlugin implements ExecutorPlugin {
324
+ private cache = new Map();
325
+
326
+ onBefore(context) {
327
+ const cached = this.cache.get(context.parameters.url);
328
+ if (cached && !isExpired(cached)) {
329
+ return cached.data;
330
+ }
331
+ }
332
+
333
+ onSuccess(context) {
334
+ this.cache.set(context.parameters.url, {
335
+ data: context.returnValue,
336
+ timestamp: Date.now()
337
+ });
338
+ }
339
+ }
340
+ ```
341
+
342
+ ## 调试与测试
343
+
344
+ ### 1. 开发环境配置
345
+
346
+ ```typescript
347
+ // 开发环境配置
348
+ const devConfig = {
349
+ baseURL: '/api',
350
+ timeout: 5000,
351
+ mock: true,
352
+ debug: true
353
+ };
354
+
355
+ // 生产环境配置
356
+ const prodConfig = {
357
+ baseURL: 'https://api.example.com',
358
+ timeout: 10000,
359
+ mock: false,
360
+ debug: false
361
+ };
362
+ ```
363
+
364
+ ### 2. Mock 数据配置
365
+
366
+ ```json
367
+ {
368
+ "GET /api/users": {
369
+ "code": 0,
370
+ "data": [
371
+ { "id": 1, "name": "User 1" },
372
+ { "id": 2, "name": "User 2" }
373
+ ]
374
+ },
375
+ "POST /api/login": {
376
+ "code": 0,
377
+ "data": {
378
+ "token": "mock-token",
379
+ "user": { "id": 1, "name": "User" }
380
+ }
381
+ }
382
+ }
383
+ ```
384
+
385
+ ### 3. 请求测试
386
+
387
+ ```typescript
388
+ describe('UserApi', () => {
389
+ let api: UserApi;
390
+
391
+ beforeEach(() => {
392
+ api = new UserApi(new MockAdapter());
393
+ });
394
+
395
+ it('should login successfully', async () => {
396
+ const result = await api.login({
397
+ username: 'test',
398
+ password: '123456'
399
+ });
400
+
401
+ expect(result.code).toBe(0);
402
+ expect(result.data.token).toBeDefined();
403
+ });
404
+ });
405
+ ```
406
+
407
+ ## 性能优化
408
+
409
+ ### 1. 请求优化
410
+
411
+ - 实现请求合并
412
+ - 控制并发数量
413
+ - 优化请求时机
414
+
415
+ ### 2. 缓存策略
416
+
417
+ - 合理使用缓存
418
+ - 实现缓存更新
419
+ - 管理缓存大小
420
+
421
+ ### 3. 错误重试
422
+
423
+ - 配置重试策略
424
+ - 处理网络问题
425
+ - 避免无效重试
426
+
427
+ ```
428
+
429
+ ```