@hzab/data-model 2.0.0-alpha.1 → 2.0.0-alpha.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/data-model",
3
- "version": "2.0.0-alpha.1",
3
+ "version": "2.0.0-alpha.3",
4
4
  "description": "data model",
5
5
  "main": "src",
6
6
  "scripts": {
package/src/ArrayUtils.ts CHANGED
@@ -133,7 +133,7 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
133
133
  * @returns 匹配的子项或 null
134
134
  */
135
135
  findItemById(id: string | number): T | null {
136
- if (this._unuseabled(id)) {
136
+ if (this._isInvalidId(id)) {
137
137
  return null;
138
138
  }
139
139
  const { _idKey } = this;
@@ -152,7 +152,7 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
152
152
  const id = query[this._idKey];
153
153
 
154
154
  // 如果有 ID 且 ID 有效,优先通过 ID 查询
155
- if (!this._unuseabled(id)) {
155
+ if (!this._isInvalidId(id)) {
156
156
  return this.findItemById(id);
157
157
  }
158
158
 
@@ -428,7 +428,7 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
428
428
  replaceItem(data: T): StateCode {
429
429
  const { _idKey, _list } = this;
430
430
  const id = data[_idKey];
431
- if (this._unuseabled(id)) {
431
+ if (this._isInvalidId(id)) {
432
432
  return STATE_CODE.ERR_INPUT_ID;
433
433
  }
434
434
  const idx = _list.findIndex((it) => it[_idKey] === id);
@@ -448,13 +448,14 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
448
448
  updateItemValue(data: Partial<T> & { [key: string]: any }): StateCode {
449
449
  const { _idKey, _list } = this;
450
450
  const id = data[_idKey];
451
- if (this._unuseabled(id)) {
451
+ if (this._isInvalidId(id)) {
452
452
  return STATE_CODE.ERR_INPUT_ID;
453
453
  }
454
- const item = cloneDeep(_list.find((it) => it[_idKey] === id));
455
- if (!item) {
454
+ const index = _list.findIndex((it) => it[_idKey] === id);
455
+ if (index < 0) {
456
456
  return STATE_CODE.NOT_FOUNT;
457
457
  }
458
+ const item = _list[index];
458
459
  Object.keys(data).forEach((key) => {
459
460
  if (key !== _idKey) {
460
461
  (item as any)[key] = data[key];
@@ -471,7 +472,7 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
471
472
  */
472
473
  delItem(id: any): StateCode {
473
474
  const { _idKey, _list } = this;
474
- if (this._unuseabled(id)) {
475
+ if (this._isInvalidId(id)) {
475
476
  return STATE_CODE.ERR_INPUT_ID;
476
477
  }
477
478
  const idx = _list.findIndex((it) => it[_idKey] === id);
@@ -482,6 +483,49 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
482
483
  return STATE_CODE.SUC;
483
484
  }
484
485
 
486
+ /**
487
+ * 清空所有数据
488
+ * @returns 状态码
489
+ */
490
+ clearAll(): StateCode {
491
+ this._list = [];
492
+ return STATE_CODE.SUC;
493
+ }
494
+
495
+ /**
496
+ * 批量删除
497
+ * @param ids 要删除的 ID 数组
498
+ * @returns 删除成功的数量
499
+ */
500
+ deleteItems(ids: any[]): number {
501
+ let successCount = 0;
502
+ ids.forEach((id) => {
503
+ const res = this.delItem(id);
504
+ if (res === STATE_CODE.SUC) {
505
+ successCount++;
506
+ }
507
+ });
508
+ return successCount;
509
+ }
510
+
511
+ /**
512
+ * 判断列表是否为空
513
+ * @returns 是否为空
514
+ */
515
+ isEmpty(): boolean {
516
+ return this._list.length === 0;
517
+ }
518
+
519
+ /**
520
+ * 获取指定范围的列表
521
+ * @param start 起始索引
522
+ * @param end 结束索引
523
+ * @returns 切片后的列表
524
+ */
525
+ slice(start?: number, end?: number): T[] {
526
+ return cloneDeep(this._list.slice(start, end));
527
+ }
528
+
485
529
  /**
486
530
  * 检查单个 item 是否匹配所有 query 条件
487
531
  * @param item - 待检查的列表项
@@ -624,11 +668,11 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
624
668
  }
625
669
 
626
670
  /**
627
- * 检查 ID 是否有效
671
+ * 检查 ID 是否无效
628
672
  * @param id 要检查的 ID
629
673
  * @returns ID 是否无效(为空)
630
674
  */
631
- protected _unuseabled(id: any): boolean {
675
+ protected _isInvalidId(id: any): boolean {
632
676
  return isNil(id) || id === "";
633
677
  }
634
678
 
@@ -638,7 +682,7 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
638
682
  * @returns 设置 ID 后的子项
639
683
  */
640
684
  protected _setId(item: T): T {
641
- if (isObject(item) && this._unuseabled((item as any)[this._idKey])) {
685
+ if (isObject(item) && this._isInvalidId((item as any)[this._idKey])) {
642
686
  (item as any)[this._idKey] = nanoid();
643
687
  }
644
688
  return item;
@@ -649,7 +693,7 @@ export class ArrayUtils<T extends Record<string, any> = Record<string, any>> {
649
693
  * @param item 要设置创建时间的子项
650
694
  */
651
695
  protected _setCreateTime(item: T): void {
652
- if (isObject(item) && this._unuseabled((item as any).createTime)) {
696
+ if (isObject(item) && this._isInvalidId((item as any).createTime)) {
653
697
  (item as any).createTime = Date.now();
654
698
  }
655
699
  }
@@ -1,7 +1,9 @@
1
1
  import { merge, pickBy, isNil, cloneDeep, isObject } from "lodash";
2
2
 
3
3
  import { _$Temp } from "./utils";
4
- import ArrayUtils, { STATE_CODE, FindListResult, ItemQuery, ArrayUtilsOptions } from "./ArrayUtils";
4
+ import ArrayUtils, { STATE_CODE, FindListResult, ArrayUtilsOptions } from "./ArrayUtils";
5
+
6
+ import { JSONObject, QueryParams, RequestData, MapFunction, RequestMapFunction, GetListFunc } from "./type";
5
7
 
6
8
  const errMsg: Record<number | string, string> = {
7
9
  404: "未找到对应子项",
@@ -11,67 +13,67 @@ const errMsg: Record<number | string, string> = {
11
13
  /**
12
14
  * ArrayDataModel 构造函数参数接口
13
15
  */
14
- export interface ArrayDataModelOptions<T = any> extends ArrayUtilsOptions<T> {
16
+ export interface ArrayDataModelOptions<R = any> extends ArrayUtilsOptions<R> {
15
17
  /** 请求 url 替换的额外参数 */
16
- ctx?: Record<string, any>;
18
+ ctx?: JSONObject;
17
19
  /** GET 请求的参数 */
18
- query?: Record<string, any>;
20
+ query?: QueryParams;
19
21
 
20
22
  /** POST 接口地址 */
21
23
  createApi?: string;
22
24
  /** POST 接口提交前的数据处理回调 */
23
- createMap?: (record: T) => T;
25
+ createMap?: MapFunction;
24
26
  /** GET 详情 接口地址 */
25
27
  getApi?: string;
26
28
  /** GET 详情 接口返回后的数据处理回调 */
27
- getMap?: (record: T) => T;
29
+ getMap?: MapFunction;
28
30
  /** GET 列表 接口地址 */
29
31
  getListApi?: string;
30
32
  /** GET 列表 接口返回后的数据处理回调 */
31
- getListMap?: (record: T) => T;
33
+ getListMap?: MapFunction;
32
34
  /** GET 列表 接口回调,用于自定义列表请求接口 */
33
- getListFunc?: (query: Record<string, any>) => Promise<FindListResult<T>>;
35
+ getListFunc?: GetListFunc<R>;
34
36
  /** PUT 接口地址 */
35
37
  updateApi?: string;
36
38
  /** PUT 接口提交前的数据处理回调 */
37
- updateMap?: (record: T) => T;
39
+ updateMap?: MapFunction;
38
40
  /** PATCH 接口地址 */
39
41
  patchApi?: string;
40
42
  /** PATCH 接口提交前的数据处理回调 */
41
- patchMap?: (record: T) => T;
43
+ patchMap?: MapFunction;
42
44
  /** DELETE 接口地址 */
43
45
  deleteApi?: string;
44
46
  /** DELETE 批量删除 接口地址 */
45
47
  multipleDeleteApi?: string;
46
48
 
47
49
  /** GET 列表 接口请求前数据处理回调 */
48
- getListReqMap?: (params: Record<string, any>) => Record<string, any>;
50
+ getListReqMap?: RequestMapFunction<QueryParams>;
49
51
  /** GET 列表 接口请求结果数据处理回调 */
50
- getListResMap?: (result: FindListResult<T>) => FindListResult<T>;
52
+ getListResMap?: MapFunction;
51
53
  /** GET 详情 接口请求前数据处理回调 */
52
- getReqMap?: (params: Record<string, any>) => Record<string, any>;
54
+ getReqMap?: RequestMapFunction<QueryParams>;
53
55
  /** GET 详情 接口请求结果数据处理回调 */
54
- getResMap?: (record: T) => T;
56
+ getResMap?: MapFunction;
55
57
  /** POST 接口请求前数据处理回调 */
56
- createReqMap?: (params: Record<string, any>, originalParams?: any) => Record<string, any>;
58
+ createReqMap?: RequestMapFunction<RequestData>;
57
59
  /** POST 接口请求结果数据处理回调 */
58
- createResMap?: (data: Record<string, any>) => Record<string, any>;
60
+ createResMap?: MapFunction;
59
61
  /** PUT 接口请求前数据处理回调 */
60
- updateReqMap?: (params: Record<string, any>, originalParams?: any) => Record<string, any>;
62
+ updateReqMap?: RequestMapFunction<RequestData>;
61
63
  /** PUT 接口请求结果数据处理回调 */
62
- updateResMap?: (data: Record<string, any>) => Record<string, any>;
64
+ updateResMap?: MapFunction;
63
65
  /** PATCH 接口请求前数据处理回调 */
64
- patchReqMap?: (params: Record<string, any>, originalParams?: any) => Record<string, any>;
66
+ patchReqMap?: RequestMapFunction<RequestData>;
65
67
  /** PATCH 接口请求结果数据处理回调 */
66
- patchResMap?: (data: Record<string, any>) => Record<string, any>;
68
+ patchResMap?: MapFunction;
67
69
  /** DELETE 接口请求前数据处理回调 */
68
- deleteReqMap?: (config: Record<string, any>) => Record<string, any>;
70
+ deleteReqMap?: RequestMapFunction<JSONObject>;
69
71
  /** DELETE 接口请求结果数据处理回调 */
70
- deleteResMap?: (data: Record<string, any>) => Record<string, any>;
72
+ deleteResMap?: MapFunction;
71
73
  /** DELETE 批量删除 接口请求前数据处理回调 */
72
- multipleDeleteReqMap?: (config: Record<string, any>) => Record<string, any>;
74
+ multipleDeleteReqMap?: RequestMapFunction<JSONObject>;
73
75
  /** DELETE 批量删除 接口请求结果数据处理回调 */
74
- multipleDeleteResMap?: (data: { sucList: any[]; failList: any[] }) => { sucList: any[]; failList: any[] };
76
+ multipleDeleteResMap?: MapFunction;
75
77
 
76
78
  /** 查询选项 */
77
79
  arrOptions?: ArrOptions;
@@ -125,63 +127,63 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
125
127
  /** 请求 url 替换的额外参数 */
126
128
  ctx: Record<string, any>;
127
129
  /** GET 请求的参数 */
128
- query: Record<string, any>;
130
+ query: QueryParams;
129
131
 
130
132
  /** POST 接口地址 */
131
133
  createApi?: string;
132
134
  /** POST 接口提交前的数据处理回调 */
133
- createMap?: (record: T) => T;
135
+ createMap?: MapFunction;
134
136
  /** GET 详情 接口地址 */
135
137
  getApi?: string;
136
138
  /** GET 详情 接口返回后的数据处理回调 */
137
- getMap?: (record: T) => T;
139
+ getMap?: MapFunction;
138
140
  /** GET 列表 接口地址 */
139
141
  getListApi?: string;
140
142
  /** GET 列表 接口返回后的数据处理回调 */
141
- getListMap?: (record: T) => T;
142
- /** GET 列表 接口回调,用于自定义列表请求接口。query => ({list: [], pagination: { total: 0 }}) 优先级高于 getListApi */
143
- getListFunc?: (query: Record<string, any>) => Promise<FindListResult<T>>;
143
+ getListMap?: MapFunction;
144
+ /** GET 列表 接口回调,用于自定义列表请求接口 */
145
+ getListFunc?: GetListFunc<T>;
144
146
  /** PUT 接口地址 */
145
147
  updateApi?: string;
146
148
  /** PUT 接口提交前的数据处理回调 */
147
- updateMap?: (record: T) => T;
149
+ updateMap?: MapFunction;
148
150
  /** PATCH 接口地址 */
149
151
  patchApi?: string;
150
152
  /** PATCH 接口提交前的数据处理回调 */
151
- patchMap?: (record: T) => T;
153
+ patchMap?: MapFunction;
152
154
  /** DELETE 接口地址 */
153
155
  deleteApi?: string;
154
156
  /** DELETE 批量删除 接口地址 */
155
157
  multipleDeleteApi?: string;
156
158
 
157
159
  /** GET 列表 接口请求前数据处理回调 */
158
- getListReqMap?: (params: Record<string, any>) => Record<string, any>;
160
+ getListReqMap?: RequestMapFunction<QueryParams>;
159
161
  /** GET 列表 接口请求结果数据处理回调 */
160
- getListResMap?: (result: FindListResult<T>) => FindListResult<T>;
162
+ getListResMap?: MapFunction;
161
163
  /** GET 详情 接口请求前数据处理回调 */
162
- getReqMap?: (params: Record<string, any>) => Record<string, any>;
164
+ getReqMap?: RequestMapFunction<QueryParams>;
163
165
  /** GET 详情 接口请求结果数据处理回调 */
164
- getResMap?: (record: T) => T;
166
+ getResMap?: MapFunction;
165
167
  /** POST 接口请求前数据处理回调 */
166
- createReqMap?: (params: Record<string, any>, originalParams?: any) => Record<string, any>;
168
+ createReqMap?: RequestMapFunction<RequestData>;
167
169
  /** POST 接口请求结果数据处理回调 */
168
- createResMap?: (data: Record<string, any>) => Record<string, any>;
170
+ createResMap?: MapFunction;
169
171
  /** PUT 接口请求前数据处理回调 */
170
- updateReqMap?: (params: Record<string, any>, originalParams?: any) => Record<string, any>;
172
+ updateReqMap?: RequestMapFunction<RequestData>;
171
173
  /** PUT 接口请求结果数据处理回调 */
172
- updateResMap?: (data: Record<string, any>) => Record<string, any>;
174
+ updateResMap?: MapFunction;
173
175
  /** PATCH 接口请求前数据处理回调 */
174
- patchReqMap?: (params: Record<string, any>, originalParams?: any) => Record<string, any>;
176
+ patchReqMap?: RequestMapFunction<RequestData>;
175
177
  /** PATCH 接口请求结果数据处理回调 */
176
- patchResMap?: (data: Record<string, any>) => Record<string, any>;
178
+ patchResMap?: MapFunction;
177
179
  /** DELETE 接口请求前数据处理回调 */
178
- deleteReqMap?: (config: Record<string, any>) => Record<string, any>;
180
+ deleteReqMap?: RequestMapFunction<JSONObject>;
179
181
  /** DELETE 接口请求结果数据处理回调 */
180
- deleteResMap?: (data: Record<string, any>) => Record<string, any>;
182
+ deleteResMap?: MapFunction;
181
183
  /** DELETE 批量删除 接口请求前数据处理回调 */
182
- multipleDeleteReqMap?: (config: Record<string, any>) => Record<string, any>;
184
+ multipleDeleteReqMap?: RequestMapFunction<JSONObject>;
183
185
  /** DELETE 批量删除 接口请求结果数据处理回调 */
184
- multipleDeleteResMap?: (data: MultipleDeleteResult) => MultipleDeleteResult;
186
+ multipleDeleteResMap?: MapFunction;
185
187
 
186
188
  /** 查询选项 */
187
189
  private _arrOptions?: ArrOptions;
@@ -263,7 +265,7 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
263
265
  * @param q query 参数
264
266
  * @returns Promise<T>
265
267
  */
266
- get(q: Record<string, any> = {}): Promise<T | null> {
268
+ get(q: QueryParams = {}): Promise<T> {
267
269
  let query = merge({}, this.query, q);
268
270
  query = pickBy(query, (val) => !isNil(val) && val !== "");
269
271
 
@@ -288,7 +290,7 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
288
290
  * @param q query 参数
289
291
  * @returns Promise<FindListResult<T>>
290
292
  */
291
- async getList(q: Record<string, any> = {}): Promise<FindListResult<T>> {
293
+ async getList(q: QueryParams = {}): Promise<FindListResult<T>> {
292
294
  let query = merge({}, this.query, q);
293
295
  query = pickBy(query, (val) => !isNil(val) && val !== "");
294
296
 
@@ -321,22 +323,11 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
321
323
  * @param params 参数
322
324
  * @returns Promise<Record<string, any>>
323
325
  */
324
- create(params: Record<string, any> | FormData): Promise<Record<string, any>> {
326
+ create(params: RequestData | FormData): Promise<Record<string, any>> {
325
327
  return new Promise((resolve, reject) => {
326
328
  const _params = this.handleInputParams(params, this.createReqMap);
327
329
  const res = this.pushItem(_params);
328
- if (res === STATE_CODE.SUC) {
329
- let _res: Record<string, any> = {};
330
- if (this.createResMap) {
331
- _res = this.createResMap(_res);
332
- }
333
- resolve(_res);
334
- } else {
335
- reject({
336
- code: res,
337
- _message: errMsg[res] || "未知错误",
338
- });
339
- }
330
+ this.handleRes(res, resolve, reject, { resMap: this.createResMap });
340
331
  });
341
332
  }
342
333
 
@@ -345,22 +336,11 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
345
336
  * @param params 参数
346
337
  * @returns Promise<Record<string, any>>
347
338
  */
348
- update(params: Record<string, any> | FormData): Promise<Record<string, any>> {
339
+ update(params: RequestData | FormData): Promise<Record<string, any>> {
349
340
  return new Promise((resolve, reject) => {
350
341
  const _params = this.handleInputParams(params, this.updateReqMap);
351
342
  const res = this.replaceItem(_params as T);
352
- if (res === STATE_CODE.SUC) {
353
- let _res: Record<string, any> = {};
354
- if (this.updateResMap) {
355
- _res = this.updateResMap(_res);
356
- }
357
- resolve(_res);
358
- } else {
359
- reject({
360
- code: res,
361
- _message: errMsg[res] || "未知错误",
362
- });
363
- }
343
+ this.handleRes(res, resolve, reject, { resMap: this.updateResMap });
364
344
  });
365
345
  }
366
346
 
@@ -369,22 +349,11 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
369
349
  * @param params 参数
370
350
  * @returns Promise<Record<string, any>>
371
351
  */
372
- patch(params: Record<string, any> | FormData): Promise<Record<string, any>> {
352
+ patch(params: RequestData | FormData): Promise<Record<string, any>> {
373
353
  return new Promise((resolve, reject) => {
374
354
  const _params = this.handleInputParams(params, this.patchReqMap);
375
355
  const res = this.updateItemValue(_params);
376
- if (res === STATE_CODE.SUC) {
377
- let _res: Record<string, any> = {};
378
- if (this.patchResMap) {
379
- _res = this.patchResMap(_res);
380
- }
381
- resolve(_res);
382
- } else {
383
- reject({
384
- code: res,
385
- _message: errMsg[res] || "未知错误",
386
- });
387
- }
356
+ this.handleRes(res, resolve, reject, { resMap: this.patchResMap });
388
357
  });
389
358
  }
390
359
 
@@ -405,18 +374,7 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
405
374
  const { _idKey } = this;
406
375
  const id = (config as any)?.[_idKey] || config?.params?.[_idKey] || config?.data?.[_idKey] || ctx?.[_idKey];
407
376
  const res = this.delItem(id);
408
- if (res === STATE_CODE.SUC) {
409
- let _res: Record<string, any> = {};
410
- if (this.deleteResMap) {
411
- _res = this.deleteResMap(_res);
412
- }
413
- resolve(_res);
414
- } else {
415
- reject({
416
- code: res,
417
- _message: errMsg[res] || "未知错误",
418
- });
419
- }
377
+ this.handleRes(res, resolve, reject, { resMap: this.deleteResMap });
420
378
  });
421
379
  }
422
380
 
@@ -481,10 +439,10 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
481
439
  handleInputParams(
482
440
  params: any,
483
441
  reqMapFn?: (params: Record<string, any>, originalParams?: any) => Record<string, any>,
484
- ): Record<string, any> {
485
- let _params = cloneDeep(params);
442
+ ): Partial<T> & Record<string, any> {
443
+ let _params = cloneDeep(params) as Partial<T> & Record<string, any>;
486
444
  if (reqMapFn) {
487
- _params = reqMapFn.bind(this)(_params, params);
445
+ _params = reqMapFn(_params, params) as Partial<T> & Record<string, any>;
488
446
  }
489
447
  // TODO: FormData 文件存储?
490
448
  // if (params instanceof FormData) {
@@ -499,82 +457,21 @@ class ArrayDataModel<T = any> extends ArrayUtils<T> {
499
457
  * @param resolve 成功回调
500
458
  * @param reject 失败回调
501
459
  */
502
- handleRes(response: any, resolve: (res: any) => void, reject: (err: any) => void): void {
503
- if (typeof response !== "object") {
504
- reject(new Error("response not object"));
505
- return;
506
- }
507
- let _res = response;
508
- // 兼容 传入的是 response.data 的情况
509
- if (_res.data && _res.headers && _res.request) {
510
- _res = _res.data;
511
- }
512
- const { code, data } = _res;
513
- const message = this.handleMsg(response);
514
- if (code == 200) {
515
- const _data = data ?? {};
516
- if (isObject(_data)) {
517
- if (_data.content && _data.pageNumber && _data.total) {
518
- _data.list = _data.content;
519
- _data.pagination = { current: _data.pageNumber, total: _data.total };
520
- }
521
- // 前缀 _ 避免与 data 里已有的 message 冲突
522
- _data._msg = message;
523
- _data._message = message;
460
+ handleRes(res: any, resolve: (res: any) => void, reject: (err: any) => void, opt?): void {
461
+ const { resMap } = opt || {};
462
+ if (res === STATE_CODE.SUC) {
463
+ let _res: Record<string, any> = {};
464
+ if (resMap) {
465
+ _res = resMap(_res);
524
466
  }
525
- resolve(_data);
467
+ resolve(_res);
526
468
  } else {
527
- const error = new Error(message);
528
- (error as any).code = code;
529
- (error as any).response = response;
530
- (error as any)._msg = message;
531
- (error as any)._message = message;
532
- reject(error);
533
- }
534
- }
535
-
536
- /**
537
- * 错误处理器
538
- * @param err 错误对象
539
- * @param reject Promise reject 回调
540
- */
541
- errorHandler(err: any = {}, reject: (err: any) => void): void {
542
- const response = err.response || err;
543
- if (response) {
544
- const message = this.handleMsg(response, { useStatusText: true });
545
- const error = new Error(message);
546
- (error as any).code = response.status;
547
- (error as any).response = response;
548
- if (message) {
549
- // 前缀 _ 避免与 data 里已有的 message 冲突
550
- (error as any)._message = message;
551
- (error as any)._msg = message;
552
- }
553
- reject(error);
554
- return;
469
+ reject({
470
+ code: res,
471
+ _message: errMsg[res] || "未知错误",
472
+ _msg: errMsg[res] || "未知错误",
473
+ });
555
474
  }
556
- reject(err || { _msg: _$Temp.defaultErrMsg });
557
- }
558
-
559
- /**
560
- * 处理错误消息
561
- * @param response 响应对象
562
- * @param opt 选项
563
- * @returns 错误消息
564
- */
565
- handleMsg(
566
- response: any,
567
- opt: HandleMsgOptions = {
568
- useStatusText: false,
569
- },
570
- ): string {
571
- const { useStatusText } = opt || {};
572
- let message = (response.data && (response.data.message || response.data.msg)) || response.msg || response.message;
573
- if (!message && useStatusText) {
574
- message = response.statusText;
575
- }
576
-
577
- return message || _$Temp.defaultErrMsg;
578
475
  }
579
476
  }
580
477
 
package/src/data-model.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import _ from "lodash";
2
+
2
3
  import { axios, isCancel } from "./axios";
4
+
3
5
  import {
4
6
  objToFormData,
5
7
  formDataToObj,
@@ -9,11 +11,13 @@ import {
9
11
  setNetworkErrMsg,
10
12
  checkNetwork,
11
13
  } from "./utils";
14
+
12
15
  import {
13
16
  JSONObject,
14
17
  QueryParams,
15
18
  RequestData,
16
19
  ResponseData,
20
+ ResData,
17
21
  AxiosConfig,
18
22
  MapFunction,
19
23
  RequestMapFunction,
@@ -26,34 +30,34 @@ import {
26
30
  /**
27
31
  * DataModel 构造函数参数接口
28
32
  */
29
- export interface DataModelOptions<T = any> {
33
+ export interface DataModelOptions<R = any> {
30
34
  /** 请求 url 替换的额外参数 */
31
- ctx?: JSONObject;
35
+ ctx: Record<string, any>;
32
36
  /** GET 请求的参数 */
33
37
  query?: QueryParams;
34
38
 
35
39
  /** POST 接口地址 */
36
40
  createApi?: string;
37
41
  /** POST 接口提交前的数据处理回调 */
38
- createMap?: MapFunction<T, T>;
42
+ createMap?: MapFunction;
39
43
  /** GET 详情 接口地址 */
40
44
  getApi?: string;
41
45
  /** GET 详情 接口返回后的数据处理回调 */
42
- getMap?: MapFunction<T, T>;
46
+ getMap?: MapFunction;
43
47
  /** GET 列表 接口地址 */
44
48
  getListApi?: string;
45
49
  /** GET 列表 接口返回后的数据处理回调 */
46
- getListMap?: MapFunction<T, T>;
50
+ getListMap?: MapFunction;
47
51
  /** GET 列表 接口回调,用于自定义列表请求接口 */
48
- getListFunc?: GetListFunc<T>;
52
+ getListFunc?: GetListFunc<R>;
49
53
  /** PUT 接口地址 */
50
54
  updateApi?: string;
51
55
  /** PUT 接口提交前的数据处理回调 */
52
- updateMap?: MapFunction<T, T>;
56
+ updateMap?: MapFunction;
53
57
  /** PATCH 接口地址 */
54
58
  patchApi?: string;
55
59
  /** PATCH 接口提交前的数据处理回调 */
56
- patchMap?: MapFunction<T, T>;
60
+ patchMap?: MapFunction;
57
61
  /** DELETE 接口地址 */
58
62
  deleteApi?: string;
59
63
  /** DELETE 批量删除 接口地址 */
@@ -62,31 +66,31 @@ export interface DataModelOptions<T = any> {
62
66
  /** GET 列表 接口请求前数据处理回调 */
63
67
  getListReqMap?: RequestMapFunction<QueryParams>;
64
68
  /** GET 列表 接口请求结果数据处理回调 */
65
- getListResMap?: MapFunction<GetListResult<T>, GetListResult<T>>;
69
+ getListResMap?: MapFunction;
66
70
  /** GET 详情 接口请求前数据处理回调 */
67
71
  getReqMap?: RequestMapFunction<QueryParams>;
68
72
  /** GET 详情 接口请求结果数据处理回调 */
69
- getResMap?: MapFunction<T, T>;
73
+ getResMap?: MapFunction;
70
74
  /** POST 接口请求前数据处理回调 */
71
75
  createReqMap?: RequestMapFunction<RequestData>;
72
76
  /** POST 接口请求结果数据处理回调 */
73
- createResMap?: MapFunction<ResponseData, ResponseData>;
77
+ createResMap?: MapFunction;
74
78
  /** PUT 接口请求前数据处理回调 */
75
79
  updateReqMap?: RequestMapFunction<RequestData>;
76
80
  /** PUT 接口请求结果数据处理回调 */
77
- updateResMap?: MapFunction<ResponseData, ResponseData>;
81
+ updateResMap?: MapFunction;
78
82
  /** PATCH 接口请求前数据处理回调 */
79
83
  patchReqMap?: RequestMapFunction<RequestData>;
80
84
  /** PATCH 接口请求结果数据处理回调 */
81
- patchResMap?: MapFunction<ResponseData, ResponseData>;
85
+ patchResMap?: MapFunction;
82
86
  /** DELETE 接口请求前数据处理回调 */
83
87
  deleteReqMap?: RequestMapFunction<JSONObject>;
84
88
  /** DELETE 接口请求结果数据处理回调 */
85
- deleteResMap?: MapFunction<ResponseData, ResponseData>;
89
+ deleteResMap?: MapFunction;
86
90
  /** DELETE 批量删除 接口请求前数据处理回调 */
87
91
  multipleDeleteReqMap?: RequestMapFunction<JSONObject>;
88
92
  /** DELETE 批量删除 接口请求结果数据处理回调 */
89
- multipleDeleteResMap?: MapFunction<ResponseData, ResponseData>;
93
+ multipleDeleteResMap?: MapFunction;
90
94
 
91
95
  /** 统一 response 回调,用于处理定制 response 格式 */
92
96
  handleResponse?: HandleResponseFunc;
@@ -150,7 +154,7 @@ export interface HandleMsgOptions {
150
154
  * DataModel 类
151
155
  * 用于封装常用的 CRUD 请求方法
152
156
  */
153
- class DataModel<T = any> {
157
+ class DataModel<T = any, R = Record<string, any>> {
154
158
  /** 是否返回完整的接口数据(response.data) */
155
159
  isResponseData: boolean;
156
160
  /** 是否直接返回 response */
@@ -159,32 +163,32 @@ class DataModel<T = any> {
159
163
  handleResponse?: HandleResponseFunc;
160
164
 
161
165
  /** 请求 url 替换的额外参数 */
162
- ctx: JSONObject;
166
+ ctx: Record<string, any>;
163
167
  /** GET 请求的参数 */
164
168
  query: QueryParams;
165
169
 
166
170
  /** POST 接口地址 */
167
171
  createApi?: string;
168
172
  /** POST 接口提交前的数据处理回调 */
169
- createMap?: MapFunction<T, T>;
173
+ createMap?: MapFunction;
170
174
  /** GET 详情 接口地址 */
171
175
  getApi?: string;
172
176
  /** GET 详情 接口返回后的数据处理回调 */
173
- getMap?: MapFunction<T, T>;
177
+ getMap?: MapFunction;
174
178
  /** GET 列表 接口地址 */
175
179
  getListApi?: string;
176
180
  /** GET 列表 接口返回后的数据处理回调 */
177
- getListMap?: MapFunction<T, T>;
181
+ getListMap?: MapFunction;
178
182
  /** GET 列表 接口回调,用于自定义列表请求接口 */
179
183
  getListFunc?: GetListFunc<T>;
180
184
  /** PUT 接口地址 */
181
185
  updateApi?: string;
182
186
  /** PUT 接口提交前的数据处理回调 */
183
- updateMap?: MapFunction<T, T>;
187
+ updateMap?: MapFunction;
184
188
  /** PATCH 接口地址 */
185
189
  patchApi?: string;
186
190
  /** PATCH 接口提交前的数据处理回调 */
187
- patchMap?: MapFunction<T, T>;
191
+ patchMap?: MapFunction;
188
192
  /** DELETE 接口地址 */
189
193
  deleteApi?: string;
190
194
  /** DELETE 批量删除 接口地址 */
@@ -193,31 +197,31 @@ class DataModel<T = any> {
193
197
  /** GET 列表 接口请求前数据处理回调 */
194
198
  getListReqMap?: RequestMapFunction<QueryParams>;
195
199
  /** GET 列表 接口请求结果数据处理回调 */
196
- getListResMap?: MapFunction<GetListResult<T>, GetListResult<T>>;
200
+ getListResMap?: MapFunction;
197
201
  /** GET 详情 接口请求前数据处理回调 */
198
202
  getReqMap?: RequestMapFunction<QueryParams>;
199
203
  /** GET 详情 接口请求结果数据处理回调 */
200
- getResMap?: MapFunction<T, T>;
204
+ getResMap?: MapFunction;
201
205
  /** POST 接口请求前数据处理回调 */
202
206
  createReqMap?: RequestMapFunction<RequestData>;
203
207
  /** POST 接口请求结果数据处理回调 */
204
- createResMap?: MapFunction<ResponseData, ResponseData>;
208
+ createResMap?: MapFunction;
205
209
  /** PUT 接口请求前数据处理回调 */
206
210
  updateReqMap?: RequestMapFunction<RequestData>;
207
211
  /** PUT 接口请求结果数据处理回调 */
208
- updateResMap?: MapFunction<ResponseData, ResponseData>;
212
+ updateResMap?: MapFunction;
209
213
  /** PATCH 接口请求前数据处理回调 */
210
214
  patchReqMap?: RequestMapFunction<RequestData>;
211
215
  /** PATCH 接口请求结果数据处理回调 */
212
- patchResMap?: MapFunction<ResponseData, ResponseData>;
216
+ patchResMap?: MapFunction;
213
217
  /** DELETE 接口请求前数据处理回调 */
214
218
  deleteReqMap?: RequestMapFunction<JSONObject>;
215
219
  /** DELETE 接口请求结果数据处理回调 */
216
- deleteResMap?: MapFunction<ResponseData, ResponseData>;
220
+ deleteResMap?: MapFunction;
217
221
  /** DELETE 批量删除 接口请求前数据处理回调 */
218
222
  multipleDeleteReqMap?: RequestMapFunction<JSONObject>;
219
223
  /** DELETE 批量删除 接口请求结果数据处理回调 */
220
- multipleDeleteResMap?: MapFunction<ResponseData, ResponseData>;
224
+ multipleDeleteResMap?: MapFunction;
221
225
 
222
226
  /** 请求的 axios 实例 */
223
227
  axios: typeof axios;
@@ -417,9 +421,9 @@ class DataModel<T = any> {
417
421
  * @param q query 参数
418
422
  * @param ctx url 替换的额外参数
419
423
  * @param axiosConf axios 配置
420
- * @returns Promise<T>
424
+ * @returns Promise<any>
421
425
  */
422
- get(q: QueryParams = {}, ctx: JSONObject = {}, axiosConf?: AxiosConfig): Promise<T> {
426
+ get(q: QueryParams = {}, ctx: JSONObject = {}, axiosConf?: AxiosConfig): Promise<any> {
423
427
  let query = _.merge({}, this.query, q);
424
428
  query = _.pickBy(query, (val) => !_.isNil(val) && val !== "");
425
429
 
@@ -436,10 +440,10 @@ class DataModel<T = any> {
436
440
  ...axiosConf,
437
441
  params: query,
438
442
  })
439
- .then((response) => {
443
+ .then((response: ResponseData) => {
440
444
  this.handleRes(
441
445
  response,
442
- (res: T) => {
446
+ (res: ResData<R>) => {
443
447
  if (this.getMap) {
444
448
  res = this.getMap(res);
445
449
  }
@@ -503,6 +507,7 @@ class DataModel<T = any> {
503
507
  if (this.getListResMap) {
504
508
  resultList = this.getListResMap(resultList);
505
509
  }
510
+
506
511
  return resultList;
507
512
  }
508
513
 
@@ -511,9 +516,9 @@ class DataModel<T = any> {
511
516
  * @param params 参数
512
517
  * @param ctx url 替换的额外参数
513
518
  * @param axiosConf axios 配置
514
- * @returns Promise<ResponseData>
519
+ * @returns Promise<any>
515
520
  */
516
- create(params: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<ResponseData> {
521
+ create(params?: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<any> {
517
522
  return new Promise((resolve, reject) => {
518
523
  const opt: AxiosConfig = {
519
524
  ...this.axiosConf,
@@ -531,10 +536,10 @@ class DataModel<T = any> {
531
536
  }
532
537
  this.axios
533
538
  .post(apiUrl, _params, opt)
534
- .then((response) => {
539
+ .then((response: ResponseData) => {
535
540
  this.handleRes(
536
541
  response,
537
- (res: ResponseData) => {
542
+ (res) => {
538
543
  if (this.createResMap) {
539
544
  res = this.createResMap(res);
540
545
  }
@@ -552,9 +557,9 @@ class DataModel<T = any> {
552
557
  * @param params 参数
553
558
  * @param ctx url 替换的额外参数
554
559
  * @param axiosConf axios 配置
555
- * @returns Promise<ResponseData>
560
+ * @returns Promise<any>
556
561
  */
557
- update(params: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<ResponseData> {
562
+ update(params?: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<any> {
558
563
  return new Promise((resolve, reject) => {
559
564
  const opt: AxiosConfig = { ...this.axiosConf, ...this.updateAxiosConf, ...axiosConf };
560
565
  let _params = _.cloneDeep(formDataToObj(params));
@@ -571,7 +576,7 @@ class DataModel<T = any> {
571
576
  .then((response) => {
572
577
  this.handleRes(
573
578
  response,
574
- (res: ResponseData) => {
579
+ (res) => {
575
580
  if (this.updateResMap) {
576
581
  res = this.updateResMap(res);
577
582
  }
@@ -589,9 +594,9 @@ class DataModel<T = any> {
589
594
  * @param params 参数
590
595
  * @param ctx url 替换的额外参数
591
596
  * @param axiosConf axios 配置
592
- * @returns Promise<ResponseData>
597
+ * @returns Promise<any>
593
598
  */
594
- patch(params: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<ResponseData> {
599
+ patch(params?: RequestData | FormData, ctx?: JSONObject, axiosConf?: AxiosConfig): Promise<any> {
595
600
  return new Promise((resolve, reject) => {
596
601
  const opt: AxiosConfig = { ...this.axiosConf, ...this.patchAxiosConf, ...axiosConf };
597
602
  let _params = _.cloneDeep(formDataToObj(params));
@@ -608,7 +613,7 @@ class DataModel<T = any> {
608
613
  .then((response) => {
609
614
  this.handleRes(
610
615
  response,
611
- (res: ResponseData) => {
616
+ (res) => {
612
617
  if (this.patchResMap) {
613
618
  res = this.patchResMap(res);
614
619
  }
@@ -627,9 +632,9 @@ class DataModel<T = any> {
627
632
  * @param config.params axios.delete url 参数
628
633
  * @param config.data axios.delete data 参数
629
634
  * @param ctx url 替换的额外参数
630
- * @returns Promise<ResponseData>
635
+ * @returns Promise<any>
631
636
  */
632
- delete(config?: DeleteConfig, ctx?: JSONObject): Promise<ResponseData> {
637
+ delete(config?: DeleteConfig, ctx?: JSONObject): Promise<any> {
633
638
  let _config = _.cloneDeep(config) || {};
634
639
  if (this.deleteReqMap) {
635
640
  _config = this.deleteReqMap(_config);
@@ -646,7 +651,7 @@ class DataModel<T = any> {
646
651
  .then((response) => {
647
652
  this.handleRes(
648
653
  response,
649
- (res: ResponseData) => {
654
+ (res) => {
650
655
  if (this.deleteResMap) {
651
656
  res = this.deleteResMap(res);
652
657
  }
@@ -665,9 +670,9 @@ class DataModel<T = any> {
665
670
  * @param config.params axios.delete url 参数
666
671
  * @param config.data axios.delete data 参数
667
672
  * @param ctx url 替换的额外参数
668
- * @returns Promise<ResponseData>
673
+ * @returns Promise<any>
669
674
  */
670
- multipleDelete(config?: DeleteConfig, ctx?: JSONObject): Promise<ResponseData> {
675
+ multipleDelete(config?: DeleteConfig, ctx?: JSONObject): Promise<any> {
671
676
  let _config = _.cloneDeep(config) || {};
672
677
  if (this.multipleDeleteReqMap) {
673
678
  _config = this.multipleDeleteReqMap(_config);
@@ -703,7 +708,7 @@ class DataModel<T = any> {
703
708
  * @param resolve 成功回调
704
709
  * @param reject 失败回调
705
710
  */
706
- handleRes(response: any, resolve: (res: any) => void, reject: (err: ApiError) => void) {
711
+ handleRes(response: ResponseData, resolve: (res: any) => void, reject: (err: ApiError) => void) {
707
712
  if (isCancel(response)) {
708
713
  console.info("errorHandler isCancel", response);
709
714
  return;
@@ -720,12 +725,19 @@ class DataModel<T = any> {
720
725
  reject(new Error("response not object") as ApiError);
721
726
  return;
722
727
  }
723
- let _res = this.handleResponse ? this.handleResponse(response) : response;
724
- // 兼容 传入的是 response.data 的情况
725
- if (_res.data && _res.headers && _res.request) {
728
+
729
+ let _res: ResponseData | ResData;
730
+ _res = this.handleResponse ? this.handleResponse(response) : response;
731
+
732
+ const isAxiosResponse = (obj: any): obj is ResponseData => {
733
+ return obj && "status" in obj && "headers" in obj && "request" in obj;
734
+ };
735
+
736
+ if (isAxiosResponse(_res)) {
726
737
  _res = _res.data;
727
738
  }
728
- const { code, data } = _res;
739
+
740
+ const { code, data } = _res as ResData;
729
741
  const message = this.handleMsg(response);
730
742
  if (code == 200) {
731
743
  const _data = data ?? {};
@@ -815,7 +827,7 @@ class DataModel<T = any> {
815
827
  * @param httpCode HTTP 状态码
816
828
  * @returns 错误消息
817
829
  */
818
- getNetworkErrMsg(httpCode: any): string {
830
+ getNetworkErrMsg(httpCode: string): string {
819
831
  const { networkErrMsg } = _$Temp;
820
832
  if (httpCode === "ERR_NETWORK") {
821
833
  return networkErrMsg;
@@ -17,7 +17,7 @@ export function getPublicUrl(url: string | any, opt?: GetPublicUrlOptions): stri
17
17
  return url;
18
18
  }
19
19
  const { isFullPath } = opt || {};
20
- let baseURL = (process.env.WEBPACK_PUBLIC_PATH || ".")?.replace(/^\//, "")?.replace(/\/$/, "");
20
+ const baseURL = (process.env.WEBPACK_PUBLIC_PATH || ".")?.replace(/^\//, "")?.replace(/\/$/, "");
21
21
  if (isFullPath) {
22
22
  const fullPathname = (location.origin + location.pathname).replace(/[^\/]+.html\/?$/, "").replace(/\/$/, "");
23
23
  return `${fullPathname}/${baseURL?.replace(/^\./, "")}/${url?.replace(/^\//, "")}`;
package/src/type.ts CHANGED
@@ -1,98 +1,109 @@
1
- import { AxiosRequestConfig, AxiosInstance, AxiosResponse } from "axios";
2
-
3
- /**
4
- * 通用 JSON 对象类型
5
- */
6
- export type JSONObject = Record<string, any>;
7
-
8
- /**
9
- * 查询参数类型
10
- */
11
- export type QueryParams = JSONObject;
12
-
13
- /**
14
- * 请求数据类型
15
- */
16
- export type RequestData = JSONObject;
17
-
18
- /**
19
- * 响应数据类型
20
- */
21
- export type ResponseData = JSONObject;
22
-
23
- /**
24
- * Axios 配置类型
25
- */
26
- export type AxiosConfig = AxiosRequestConfig;
27
-
28
- /**
29
- * 数据映射函数类型
30
- * @template T - 输入类型
31
- * @template R - 输出类型(默认为 T)
32
- */
33
- export type MapFunction<T = any, R = T> = (data: T) => R;
34
-
35
- /**
36
- * 带原始参数的映射函数类型(用于请求前处理)
37
- * @template T - 处理后的参数类型
38
- * @template P - 原始参数类型
39
- */
40
- export type RequestMapFunction<T = RequestData, P = any> = (params: T, originalParams?: P) => T;
41
-
42
- /**
43
- * 列表请求返回结果接口
44
- * @template T - 列表项数据类型
45
- */
46
- export interface GetListResult<T = any> {
47
- /** 列表数据 */
48
- list: T[];
49
- /** 分页信息 */
50
- pagination: { current?: number; total: number; pageSize?: number };
51
- /** 其他扩展字段 */
52
- [key: string]: any;
53
- }
54
-
55
- /**
56
- * 自定义列表请求函数类型
57
- * @template T - 列表项数据类型
58
- */
59
- export type GetListFunc<T = any> = (query: QueryParams) => Promise<GetListResult<T>>;
60
-
61
- /**
62
- * 响应处理函数类型
63
- */
64
- export type HandleResponseFunc = (response: AxiosResponse) => ResponseData;
65
-
66
- /**
67
- * API 错误接口
68
- */
69
- export interface ApiError extends Error {
70
- /** 错误码 */
71
- code?: number | string;
72
- /** 响应对象 */
73
- response?: AxiosResponse;
74
- /** 错误消息(带下划线前缀) */
75
- _msg?: string;
76
- /** 错误消息(带下划线前缀) */
77
- _message?: string;
78
- /** 原始错误数据 */
79
- data?: any;
80
- }
81
-
82
- /**
83
- * 网络链接信息接口(非标准 API)
84
- */
85
- export interface NetworkConnection {
86
- type?: string;
87
- downlink?: number;
88
- effectiveType?: string;
89
- }
90
-
91
- /**
92
- * 扩展 Navigator 接口(包含非标准连接属性)
93
- */
94
- export interface ExtendedNavigator extends Navigator {
95
- connection?: NetworkConnection;
96
- mozConnection?: NetworkConnection;
97
- webkitConnection?: NetworkConnection;
98
- }
1
+ import { AxiosRequestConfig, AxiosInstance, AxiosResponse } from "axios";
2
+
3
+ /**
4
+ * 通用 JSON 对象类型
5
+ */
6
+ export type JSONObject = Record<string, any>;
7
+
8
+ /**
9
+ * 查询参数类型
10
+ */
11
+ export type QueryParams = JSONObject;
12
+
13
+ /**
14
+ * 请求数据类型
15
+ */
16
+ export type RequestData = JSONObject;
17
+
18
+ /**
19
+ * 响应数据类型
20
+ */
21
+ export interface ResponseData<T = Record<string, any>> extends AxiosResponse {
22
+ data: ResData<T>;
23
+ }
24
+
25
+ /**
26
+ * 接口返回数据格式
27
+ */
28
+ export interface ResData<T = Record<string, any>> {
29
+ code: number;
30
+ data: T;
31
+ msg: string;
32
+ }
33
+
34
+ /**
35
+ * Axios 配置类型
36
+ */
37
+ export type AxiosConfig = AxiosRequestConfig;
38
+
39
+ /**
40
+ * 数据映射函数类型
41
+ * @template T - 输入类型
42
+ * @template R - 输出类型(默认为 T)
43
+ */
44
+ export type MapFunction<T = any, R = T> = (data: T) => R;
45
+
46
+ /**
47
+ * 带原始参数的映射函数类型(用于请求前处理)
48
+ * @template T - 处理后的参数类型
49
+ * @template P - 原始参数类型
50
+ */
51
+ export type RequestMapFunction<T = RequestData, P = any> = (params: T, originalParams?: P) => T;
52
+
53
+ /**
54
+ * 列表请求返回结果接口
55
+ * @template T - 列表项数据类型
56
+ */
57
+ export interface GetListResult<T = any> {
58
+ /** 列表数据 */
59
+ list: T[];
60
+ /** 分页信息 */
61
+ pagination: { current?: number; total: number; pageSize?: number };
62
+ /** 其他扩展字段 */
63
+ [key: string]: any;
64
+ }
65
+
66
+ /**
67
+ * 自定义列表请求函数类型
68
+ * @template T - 列表项数据类型
69
+ */
70
+ export type GetListFunc<T = any> = (query: QueryParams) => Promise<GetListResult<T>>;
71
+
72
+ /**
73
+ * 响应处理函数类型
74
+ */
75
+ export type HandleResponseFunc = (response: AxiosResponse) => ResponseData;
76
+
77
+ /**
78
+ * API 错误接口
79
+ */
80
+ export interface ApiError extends Error {
81
+ /** 错误码 */
82
+ code?: number | string;
83
+ /** 响应对象 */
84
+ response?: AxiosResponse;
85
+ /** 错误消息(带下划线前缀) */
86
+ _msg?: string;
87
+ /** 错误消息(带下划线前缀) */
88
+ _message?: string;
89
+ /** 原始错误数据 */
90
+ data?: any;
91
+ }
92
+
93
+ /**
94
+ * 网络链接信息接口(非标准 API)
95
+ */
96
+ export interface NetworkConnection {
97
+ type?: string;
98
+ downlink?: number;
99
+ effectiveType?: string;
100
+ }
101
+
102
+ /**
103
+ * 扩展 Navigator 接口(包含非标准连接属性)
104
+ */
105
+ export interface ExtendedNavigator extends Navigator {
106
+ connection?: NetworkConnection;
107
+ mozConnection?: NetworkConnection;
108
+ webkitConnection?: NetworkConnection;
109
+ }