@hzab/data-model 1.5.0 → 1.6.0-beta1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # @hzab/data-model@1.6.0
2
+
3
+ fix: 注释;通用函数抽离
4
+ feat: ArrayDataModel 本地数据 DataModel
5
+
1
6
  # @hzab/data-model@1.5.0
2
7
 
3
8
  - feat: 增加 patch 请求方式函数
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/data-model",
3
- "version": "1.5.0",
3
+ "version": "1.6.0-beta1",
4
4
  "description": "data model",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -21,12 +21,14 @@
21
21
  "author": "CaiYansong",
22
22
  "license": "ISC",
23
23
  "devDependencies": {
24
- "@hzab/permissions": "0.0.4",
25
- "@hzab/webpack-config": "^0.0.15",
24
+ "@hzab/permissions": "^0.1.1",
25
+ "@hzab/webpack-config": "^0.7.1",
26
26
  "@types/react": "^17.0.62",
27
27
  "@types/react-dom": "^17.0.20",
28
28
  "antd": "^4.14.0",
29
+ "axios": "^1.6.2",
29
30
  "eslint": "^8.30.0",
31
+ "js-cookie": "^3.0.5",
30
32
  "less": "^4.1.3",
31
33
  "mobx": "^6.7.0",
32
34
  "mobx-react": "^7.6.0",
@@ -34,17 +36,16 @@
34
36
  "react-dom": "^17.0.2",
35
37
  "react-router-dom": "^6.14.1",
36
38
  "typedoc": "^0.24.8",
37
- "typescript": "^4.9.4",
38
- "axios": "^1.6.2",
39
- "js-cookie": "^3.0.5"
39
+ "typescript": "^4.9.4"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "axios": ">=1.6.2",
43
43
  "js-cookie": ">=3.0.5"
44
44
  },
45
45
  "dependencies": {
46
- "axios": "^1.6.2",
47
- "js-cookie": "^3.0.5"
46
+ "axios": ">=1.6.2",
47
+ "js-cookie": ">=3.0.5",
48
+ "nanoid": "^3.3.7"
48
49
  },
49
50
  "directories": {
50
51
  "lib": "lib"
@@ -0,0 +1,195 @@
1
+ import { nanoid } from "nanoid";
2
+ import _ from "lodash";
3
+
4
+ export const STATE_CODE = {
5
+ SUC: 200,
6
+ NOT_FOUNT: 404,
7
+ ERR: 500,
8
+ ERR_INPUT_ID: 501,
9
+ };
10
+
11
+ /**
12
+ * 数组模拟数据库存储
13
+ * TODO: FormData? 考虑到文件存储问题
14
+ */
15
+ export class ArrayUtils {
16
+ _idKey = "id";
17
+ _list = [];
18
+ constructor(params) {
19
+ const { idKey = "id", list } = params;
20
+ /** 子项唯一标志字段 */
21
+ this._idKey = idKey || "id";
22
+ /** 列表数据 */
23
+ this._list = list || [];
24
+ }
25
+
26
+ /**
27
+ * 通过 id 获取子项
28
+ * @param {*} id
29
+ * @returns
30
+ */
31
+ findItemById(id) {
32
+ if (hasId(id)) {
33
+ return null;
34
+ }
35
+ const { _idKey } = this;
36
+ return _.cloneDeep(this._list.find((it) => it[_idKey] === id));
37
+ }
38
+
39
+ /**
40
+ * 通过 id 获取子项
41
+ * @param {*} id
42
+ * @returns
43
+ */
44
+ findItem(query = {}) {
45
+ const { _idKey } = this;
46
+ const id = query[_idKey];
47
+ if (hasId(id)) {
48
+ return this.findItemById(id);
49
+ }
50
+ // TODO: query 查询
51
+ return _.cloneDeep(this._list.find((it) => it[_idKey] === id));
52
+ }
53
+
54
+ /**
55
+ * 获取列表
56
+ * TODO: 搜索?
57
+ * @param {*} query
58
+ */
59
+ findListByQuery(query) {
60
+ const { pageNum = 1, pageSize = 10 } = query || {};
61
+ const { _list } = this;
62
+ // 边界检查
63
+ if (pageNum < 1 || pageSize <= 0) {
64
+ return { list: [], pagination: { current: 1, total: 0 } };
65
+ }
66
+ // 计算起始索引
67
+ const startIndex = (pageNum - 1) * pageSize;
68
+ // 如果起始索引超出数组长度,返回空数组
69
+ if (startIndex >= _list.length) {
70
+ return { list: [], pagination: { current: 1, total: 0 } };
71
+ }
72
+ // 计算结束索引
73
+ const endIndex = startIndex + pageSize;
74
+
75
+ // 使用 slice 方法截取数据
76
+ return { list: _list.slice(startIndex, endIndex), pagination: { current: pageNum, total: this.getCount() } };
77
+ }
78
+
79
+ /**
80
+ * 获取完整列表
81
+ */
82
+ findAllList() {
83
+ return _.cloneDeep(this._list);
84
+ }
85
+
86
+ /**
87
+ * 获取总数
88
+ * @returns
89
+ */
90
+ getCount() {
91
+ return this._list.length;
92
+ }
93
+
94
+ /**
95
+ * push 数据
96
+ * @param {*} data
97
+ */
98
+ pushItem(data) {
99
+ // TODO: id 去重
100
+ const item = _.cloneDeep(data);
101
+ this.setId(item);
102
+ this._list.push(item);
103
+ return STATE_CODE.SUC;
104
+ }
105
+
106
+ /**
107
+ * unshift 数据
108
+ * @param {*} data
109
+ */
110
+ unshiftItem(data) {
111
+ // TODO: id 去重
112
+ const item = _.cloneDeep(data);
113
+ this.setId(item);
114
+ this._list.unshift(item);
115
+ return STATE_CODE.SUC;
116
+ }
117
+
118
+ /**
119
+ * 根据 id 更新子项——直接替换
120
+ * @param {Object} data
121
+ * @returns
122
+ */
123
+ replaceItem(data) {
124
+ const { _idKey, _list } = this;
125
+ const id = data[_idKey];
126
+ if (hasId(id)) {
127
+ return STATE_CODE.ERR_INPUT_ID;
128
+ }
129
+ const idx = _list.findIndex((it) => it[_idKey] === id);
130
+ if (idx < 0) {
131
+ return STATE_CODE.NOT_FOUNT;
132
+ }
133
+ _list.splice(idx, 1, data);
134
+ return STATE_CODE.SUC;
135
+ }
136
+
137
+ /**
138
+ * 根据 id 更新子项——仅修改传入的数据
139
+ * @param {Object} data
140
+ * @returns
141
+ */
142
+ updateItemValue(data) {
143
+ const { _idKey, _list } = this;
144
+ const id = data[_idKey];
145
+ if (hasId(id)) {
146
+ return STATE_CODE.ERR_INPUT_ID;
147
+ }
148
+ const item = _list.find((it) => it[_idKey] === id);
149
+ if (!item) {
150
+ return STATE_CODE.NOT_FOUNT;
151
+ }
152
+ Object.keys(data).forEach((key) => {
153
+ item[key] = data[key];
154
+ });
155
+ return STATE_CODE.SUC;
156
+ }
157
+
158
+ /**
159
+ * 删除子项
160
+ * @param {*} id
161
+ * @param {*} data
162
+ * @returns
163
+ */
164
+ delItem(id) {
165
+ const { _idKey, _list } = this;
166
+ if (hasId(id)) {
167
+ return STATE_CODE.ERR_INPUT_ID;
168
+ }
169
+ const idx = _list.findIndex((it) => it[_idKey] === id);
170
+ if (idx < 0) {
171
+ return STATE_CODE.NOT_FOUNT;
172
+ }
173
+ _list.splice(idx, 1);
174
+ return STATE_CODE.SUC;
175
+ }
176
+
177
+ /**
178
+ * 子项没有 id 的时候自动添加
179
+ * @param {*} item
180
+ * @returns
181
+ */
182
+ setId(item) {
183
+ const { _idKey } = this;
184
+ if (!item[_idKey]) {
185
+ item[_idKey] = nanoid();
186
+ }
187
+ return item;
188
+ }
189
+ }
190
+
191
+ export const hasId = (id) => {
192
+ return _.isNil(id) || id === "";
193
+ };
194
+
195
+ export default ArrayUtils;
@@ -0,0 +1,396 @@
1
+ import _ from "lodash";
2
+
3
+ import { objToFormData, formDataToObj, _$Temp } from "./utils";
4
+ import ArrayUtils, { STATE_CODE } from "./ArrayUtils";
5
+
6
+ /**
7
+ * ArrayDataModel 本地数据 DataModel
8
+ */
9
+ class ArrayDataModel extends ArrayUtils {
10
+ constructor(params) {
11
+ super(params);
12
+ const {
13
+ ctx,
14
+ query,
15
+ createApi,
16
+ createMap,
17
+ getApi,
18
+ getMap,
19
+ getListApi,
20
+ getListMap,
21
+ getListFunc,
22
+ updateApi,
23
+ updateMap,
24
+ patchApi,
25
+ patchMap,
26
+ deleteApi,
27
+ multipleDeleteApi,
28
+ } = params;
29
+
30
+ /** 请求 url 替换的额外参数 */
31
+ this.ctx = ctx || {};
32
+ /** GET 请求的参数 */
33
+ this.query = query || {};
34
+
35
+ /** POST 接口地址 */
36
+ this.createApi = createApi;
37
+ /** POST 接口提交前的数据处理回调 record => (record) */
38
+ this.createMap = createMap;
39
+ /** GET 详情 接口地址 */
40
+ this.getApi = getApi;
41
+ /** GET 详情 接口返回后的数据处理回调 record => (record) */
42
+ this.getMap = getMap;
43
+ /** GET 列表 接口地址 */
44
+ this.getListApi = getListApi;
45
+ /** GET 列表 接口返回后的数据处理回调 record => (record) */
46
+ this.getListMap = getListMap;
47
+ /** GET 列表 接口回调,用于自定义列表请求接口。query => ({list: [], pagination: { total: 0 }}) 优先级高于 getListApi */
48
+ this.getListFunc = getListFunc;
49
+ /** PUT 接口地址 */
50
+ this.updateApi = updateApi;
51
+ /** PUT 接口提交前的数据处理回调 record => (record) */
52
+ this.updateMap = updateMap;
53
+ /** PATCH 接口地址 */
54
+ this.patchApi = patchApi;
55
+ /** PATCH 接口提交前的数据处理回调 record => (record) */
56
+ this.patchMap = patchMap;
57
+ /** DELETE 接口地址 */
58
+ this.deleteApi = deleteApi;
59
+ /** DELETE 批量删除 接口地址 */
60
+ this.multipleDeleteApi = multipleDeleteApi;
61
+
62
+ const {
63
+ getListReqMap,
64
+ getListResMap,
65
+ getReqMap,
66
+ getResMap,
67
+ createReqMap,
68
+ createResMap,
69
+ updateReqMap,
70
+ updateResMap,
71
+ patchReqMap,
72
+ patchResMap,
73
+ deleteReqMap,
74
+ deleteResMap,
75
+ multipleDeleteReqMap,
76
+ multipleDeleteResMap,
77
+ } = params || {};
78
+
79
+ /** GET 列表 接口请求前数据处理回调 */
80
+ this.getListReqMap = getListReqMap;
81
+ /** GET 列表 接口请求结果数据处理回调 */
82
+ this.getListResMap = getListResMap;
83
+ /** GET 详情 接口请求前数据处理回调 */
84
+ this.getReqMap = getReqMap;
85
+ /** GET 详情 接口请求结果数据处理回调 */
86
+ this.getResMap = getResMap;
87
+ /** POST 接口请求前数据处理回调 */
88
+ this.createReqMap = createReqMap;
89
+ /** POST 接口请求结果数据处理回调 */
90
+ this.createResMap = createResMap;
91
+ /** PUT 接口请求前数据处理回调 */
92
+ this.updateReqMap = updateReqMap;
93
+ /** PUT 接口请求结果数据处理回调 */
94
+ this.updateResMap = updateResMap;
95
+ /** PATCH 接口请求前数据处理回调 */
96
+ this.patchReqMap = patchReqMap;
97
+ /** PATCH 接口请求结果数据处理回调 */
98
+ this.patchResMap = patchResMap;
99
+ /** DELETE 接口请求前数据处理回调 */
100
+ this.deleteReqMap = deleteReqMap;
101
+ /** DELETE 接口请求结果数据处理回调 */
102
+ this.deleteResMap = deleteResMap;
103
+ /** DELETE 批量删除 接口请求前数据处理回调 */
104
+ this.multipleDeleteReqMap = multipleDeleteReqMap;
105
+ /** DELETE 批量删除 接口请求结果数据处理回调 */
106
+ this.multipleDeleteResMap = multipleDeleteResMap;
107
+ }
108
+
109
+ /**
110
+ * GET 详情请求
111
+ * @param {Object} q query 参数
112
+ * @returns
113
+ */
114
+ get(q = {}) {
115
+ let query = _.merge({}, this.query, q);
116
+ query = _.pickBy(query, (val) => !_.isNil(val) && val !== "");
117
+
118
+ if (this.getReqMap) {
119
+ query = this.getReqMap(query);
120
+ }
121
+
122
+ return new Promise((resolve, reject) => {
123
+ let res = this.findItem(query);
124
+ if (this.getResMap) {
125
+ res = this.getResMap(res);
126
+ }
127
+ resolve(res);
128
+ });
129
+ }
130
+
131
+ /**
132
+ * GET 列表请求
133
+ * @param {Object} q query 参数
134
+ * @returns
135
+ */
136
+ async getList(q) {
137
+ let query = _.merge({}, this.query, q);
138
+ query = _.pickBy(query, (val) => !_.isNil(val) && val !== "");
139
+
140
+ if (this.getListReqMap) {
141
+ query = this.getListReqMap(query);
142
+ }
143
+
144
+ let resultList = null;
145
+ if (this.getListFunc) {
146
+ resultList = await this.getListFunc(query);
147
+ if (this.getListResMap) {
148
+ resultList = this.getListResMap(resultList);
149
+ }
150
+ } else {
151
+ const getPro = this.findListByQuery(query);
152
+ resultList = await getPro;
153
+ if (this.getListResMap) {
154
+ resultList = this.getListResMap(resultList);
155
+ }
156
+ }
157
+ return resultList;
158
+ }
159
+
160
+ /**
161
+ * POST 请求
162
+ * @param {Object} params 参数
163
+ * @returns
164
+ */
165
+ create(params) {
166
+ return new Promise((resolve, reject) => {
167
+ const _params = this.handleInputParams(params, this.createReqMap);
168
+ const res = this.pushItem(_params);
169
+ if (res === STATE_CODE.SUC) {
170
+ let _res = {};
171
+ if (this.createResMap) {
172
+ _res = this.createResMap();
173
+ }
174
+ resolve(_res);
175
+ } else {
176
+ reject(res);
177
+ }
178
+ });
179
+ }
180
+
181
+ /**
182
+ * PUT 请求
183
+ * @param {Object} params 参数
184
+ * @returns
185
+ */
186
+ update(params) {
187
+ return new Promise((resolve, reject) => {
188
+ const _params = this.handleInputParams(params, this.updateReqMap);
189
+ const res = this.replaceItem(_params);
190
+ if (res === STATE_CODE.SUC) {
191
+ let _res = {};
192
+ if (this.updateResMap) {
193
+ _res = this.updateResMap();
194
+ }
195
+ resolve(_res);
196
+ } else {
197
+ reject(res);
198
+ }
199
+ });
200
+ }
201
+
202
+ /**
203
+ * PATCH 请求
204
+ * @param {Object} params 参数
205
+ * @returns
206
+ */
207
+ patch(params) {
208
+ return new Promise((resolve, reject) => {
209
+ const _params = this.handleInputParams(params, this.patchReqMap);
210
+ const res = this.updateItemValue(_params);
211
+ if (res === STATE_CODE.SUC) {
212
+ let _res = {};
213
+ if (this.patchResMap) {
214
+ _res = this.patchResMap();
215
+ }
216
+ resolve(_res);
217
+ } else {
218
+ reject(res);
219
+ }
220
+ });
221
+ }
222
+
223
+ /**
224
+ * 删除接口
225
+ * @param {*} config axios.delete config 参数,
226
+ * @param {*} config.params axios.delete url 参数,
227
+ * @param {*} config.data axios.delete data 参数,
228
+ * @param {*} ctx
229
+ * @returns
230
+ */
231
+ delete(config, ctx) {
232
+ let _config = _.cloneDeep(config) || {};
233
+ if (this.deleteReqMap) {
234
+ _config = this.deleteReqMap(_config);
235
+ }
236
+ return new Promise((resolve, reject) => {
237
+ const { _idKey } = this;
238
+ const id = config[_idKey] || config.params?.[_idKey] || config.data?.[_idKey] || ctx[_idKey];
239
+ const res = this.delItem(id);
240
+ console.log("res", res);
241
+
242
+ if (res === STATE_CODE.SUC) {
243
+ let _res = {};
244
+ if (this.deleteResMap) {
245
+ _res = this.deleteResMap();
246
+ }
247
+ resolve(_res);
248
+ } else {
249
+ reject(res);
250
+ }
251
+ });
252
+ }
253
+
254
+ /**
255
+ * 批量删除接口
256
+ * @param {*} config axios.delete config 参数,
257
+ * @param {*} config.params axios.delete url 参数,
258
+ * @param {*} config.data axios.delete data 参数,
259
+ * @param {*} ctx
260
+ * @returns
261
+ */
262
+ multipleDelete(config, ctx) {
263
+ let _config = _.cloneDeep(config) || {};
264
+ if (this.multipleDeleteReqMap) {
265
+ _config = this.multipleDeleteReqMap(_config);
266
+ }
267
+ return new Promise((resolve, reject) => {
268
+ const { _idKey } = this;
269
+ let ids = config[_idKey] || config.params?.[_idKey] || config.data?.[_idKey] || ctx[_idKey];
270
+
271
+ if (typeof ids === "string") {
272
+ ids = ids.split(",");
273
+ }
274
+
275
+ if (Array.isArray(ids)) {
276
+ const sucList = [];
277
+ const failList = [];
278
+ ids.forEach((id) => {
279
+ try {
280
+ const res = this.delItem(id);
281
+ if (res === STATE_CODE.SUC) {
282
+ sucList.push(id);
283
+ } else {
284
+ failList.push(id);
285
+ }
286
+ } catch (error) {
287
+ console.log("error", error);
288
+ }
289
+ });
290
+ if (sucList.length > 0) {
291
+ let _res = { sucList, failList };
292
+ if (this.multipleDeleteResMap) {
293
+ _res = this.multipleDeleteResMap();
294
+ }
295
+ resolve(_res);
296
+ } else {
297
+ reject({ failList });
298
+ }
299
+ return;
300
+ }
301
+
302
+ reject({});
303
+ });
304
+ }
305
+
306
+ /**
307
+ * 处理传入的数据
308
+ * @returns
309
+ */
310
+ handleInputParams(params, reqMapFn) {
311
+ let _params = _.cloneDeep(formDataToObj(params));
312
+ if (reqMapFn) {
313
+ _params = reqMapFn.bind(this)(_params, params);
314
+ }
315
+ // TODO: FormData 文件存储?
316
+ // if (params instanceof FormData) {
317
+ // _params = objToFormData(_params);
318
+ // }
319
+ return _params;
320
+ }
321
+
322
+ handleRes(response, resolve, reject) {
323
+ if (typeof response !== "object") {
324
+ reject(new Error("response not object"));
325
+ return;
326
+ }
327
+ let _res = response;
328
+ // 兼容 传入的是 response.data 的情况
329
+ if (_res.data && _res.headers && _res.request) {
330
+ _res = _res.data;
331
+ }
332
+ const { code, data } = _res;
333
+ const message = this.handleMsg(response);
334
+ if (code == 200) {
335
+ let _data = data ?? {};
336
+ if (_.isObject(_data)) {
337
+ if (_data.content && _data.pageNumber && _data.total) {
338
+ _data.list = _data.content;
339
+ _data.pagination = { current: _data.pageNumber, total: _data.total };
340
+ }
341
+ // 前缀 _ 避免与 data 里已有的 message 冲突
342
+ _data._msg = message;
343
+ _data._message = message;
344
+ }
345
+ resolve(_data);
346
+ } else {
347
+ const error = new Error(message);
348
+ error.code = code;
349
+ error.response = response;
350
+ error._msg = message;
351
+ error._message = message;
352
+ reject(error);
353
+ }
354
+ }
355
+
356
+ errorHandler(err, reject) {
357
+ const response = err.response || err;
358
+ if (response) {
359
+ const message = this.handleMsg(response, { useStatusText: true });
360
+ const error = new Error(message);
361
+ error.code = response.status;
362
+ error.response = response;
363
+ if (message) {
364
+ // 前缀 _ 避免与 data 里已有的 message 冲突
365
+ error._message = message;
366
+ error._msg = message;
367
+ }
368
+ return reject(error);
369
+ }
370
+ return reject(err || { _msg: _$Temp.defaultErrMsg });
371
+ }
372
+
373
+ handleMsg(
374
+ response,
375
+ opt = {
376
+ // 是否使用 response.statusText 作为兜底 msg
377
+ useStatusText: false,
378
+ },
379
+ ) {
380
+ const {
381
+ // 是否使用 response.statusText 作为兜底 msg
382
+ useStatusText,
383
+ } = opt || {};
384
+ let message = (response.data && (response.data.message || response.data.msg)) || response.msg;
385
+
386
+ if (!message && useStatusText) {
387
+ message = response.statusText;
388
+ }
389
+
390
+ return message || _$Temp.defaultErrMsg;
391
+ }
392
+ }
393
+
394
+ export { ArrayDataModel };
395
+
396
+ export default ArrayDataModel;
package/src/data-model.js CHANGED
@@ -1,13 +1,7 @@
1
1
  import _ from "lodash";
2
2
  import axios from "axios";
3
3
 
4
- const DEFAULT_MSG = "未知错误";
5
- const NETWORK_MSG = "网络异常,请检查网络是否开启";
6
-
7
- const _$Temp = {
8
- defaultErrMsg: DEFAULT_MSG,
9
- networkErrMsg: NETWORK_MSG,
10
- };
4
+ import { objToFormData, formDataToObj, _$Temp, setDefaultAxios, setDefaultErrMsg, setNetworkErrMsg } from "./utils";
11
5
 
12
6
  class DataModel {
13
7
  constructor(params) {
@@ -20,7 +14,6 @@ class DataModel {
20
14
  getMap,
21
15
  getListApi,
22
16
  getListMap,
23
- // 统一 response 回调,用于处理定制 response 格式
24
17
  handleResponse,
25
18
  getListFunc,
26
19
  updateApi,
@@ -29,35 +22,49 @@ class DataModel {
29
22
  patchMap,
30
23
  deleteApi,
31
24
  multipleDeleteApi,
32
- axios: as,
33
- axiosConf,
34
25
  // 是否返回完整的接口数据(response.data)
35
26
  isResponseData,
36
27
  // 是否直接返回 response
37
28
  isResponse,
38
29
  } = params;
39
30
 
31
+ /** 是否返回完整的接口数据(response.data) */
40
32
  this.isResponseData = isResponseData;
33
+ /** 是否直接返回 response */
41
34
  this.isResponse = isResponse;
35
+ /** 统一 response 回调,用于处理定制 response 格式 */
36
+ this.handleResponse = handleResponse;
42
37
 
38
+ /** 请求 url 替换的额外参数 */
43
39
  this.ctx = ctx || {};
40
+ /** GET 请求的参数 */
44
41
  this.query = query || {};
45
- this.axios = as || _$Temp.axios || axios;
46
- this.axiosConf = axiosConf || {};
47
42
 
43
+ /** POST 接口地址 */
48
44
  this.createApi = createApi;
45
+ /** POST 接口提交前的数据处理回调 record => (record) */
49
46
  this.createMap = createMap;
47
+ /** GET 详情 接口地址 */
50
48
  this.getApi = getApi;
49
+ /** GET 详情 接口返回后的数据处理回调 record => (record) */
51
50
  this.getMap = getMap;
51
+ /** GET 列表 接口地址 */
52
52
  this.getListApi = getListApi;
53
+ /** GET 列表 接口返回后的数据处理回调 record => (record) */
53
54
  this.getListMap = getListMap;
54
- this.handleResponse = handleResponse;
55
+ /** GET 列表 接口回调,用于自定义列表请求接口。query => ({list: [], pagination: { total: 0 }}) 优先级高于 getListApi */
55
56
  this.getListFunc = getListFunc;
57
+ /** PUT 接口地址 */
56
58
  this.updateApi = updateApi;
59
+ /** PUT 接口提交前的数据处理回调 record => (record) */
57
60
  this.updateMap = updateMap;
61
+ /** PATCH 接口地址 */
58
62
  this.patchApi = patchApi;
63
+ /** PATCH 接口提交前的数据处理回调 record => (record) */
59
64
  this.patchMap = patchMap;
65
+ /** DELETE 接口地址 */
60
66
  this.deleteApi = deleteApi;
67
+ /** DELETE 批量删除 接口地址 */
61
68
  this.multipleDeleteApi = multipleDeleteApi;
62
69
 
63
70
  const {
@@ -76,22 +83,40 @@ class DataModel {
76
83
  multipleDeleteReqMap,
77
84
  multipleDeleteResMap,
78
85
  } = params || {};
86
+
87
+ /** GET 列表 接口请求前数据处理回调 */
79
88
  this.getListReqMap = getListReqMap;
89
+ /** GET 列表 接口请求结果数据处理回调 */
80
90
  this.getListResMap = getListResMap;
91
+ /** GET 详情 接口请求前数据处理回调 */
81
92
  this.getReqMap = getReqMap;
93
+ /** GET 详情 接口请求结果数据处理回调 */
82
94
  this.getResMap = getResMap;
95
+ /** POST 接口请求前数据处理回调 */
83
96
  this.createReqMap = createReqMap;
97
+ /** POST 接口请求结果数据处理回调 */
84
98
  this.createResMap = createResMap;
99
+ /** PUT 接口请求前数据处理回调 */
85
100
  this.updateReqMap = updateReqMap;
101
+ /** PUT 接口请求结果数据处理回调 */
86
102
  this.updateResMap = updateResMap;
103
+ /** PATCH 接口请求前数据处理回调 */
87
104
  this.patchReqMap = patchReqMap;
105
+ /** PATCH 接口请求结果数据处理回调 */
88
106
  this.patchResMap = patchResMap;
107
+ /** DELETE 接口请求前数据处理回调 */
89
108
  this.deleteReqMap = deleteReqMap;
109
+ /** DELETE 接口请求结果数据处理回调 */
90
110
  this.deleteResMap = deleteResMap;
111
+ /** DELETE 批量删除 接口请求前数据处理回调 */
91
112
  this.multipleDeleteReqMap = multipleDeleteReqMap;
113
+ /** DELETE 批量删除 接口请求结果数据处理回调 */
92
114
  this.multipleDeleteResMap = multipleDeleteResMap;
93
115
 
116
+ // axios 相关配置
94
117
  const {
118
+ axios: as,
119
+ axiosConf,
95
120
  getListAxiosConf,
96
121
  getAxiosConf,
97
122
  createAxiosConf,
@@ -100,15 +125,36 @@ class DataModel {
100
125
  deleteAxiosConf,
101
126
  multipleDeleteAxiosConf,
102
127
  } = params || {};
128
+
129
+ /** 请求的 axios 实例 */
130
+ this.axios = as || _$Temp.axios || axios;
131
+ /** axios 配置 */
132
+ this.axiosConf = axiosConf || {};
133
+
134
+ /** GET 列表接口 axios 配置 */
103
135
  this.getListAxiosConf = getListAxiosConf;
136
+ /** GET 详情接口 axios 配置 */
104
137
  this.getAxiosConf = getAxiosConf;
138
+ /** POST 接口 axios 配置 */
105
139
  this.createAxiosConf = createAxiosConf;
140
+ /** PUT 接口 axios 配置 */
106
141
  this.updateAxiosConf = updateAxiosConf;
142
+ /** PATCH 接口 axios 配置 */
107
143
  this.patchAxiosConf = patchAxiosConf;
144
+ /** DELETE 接口 axios 配置 */
108
145
  this.deleteAxiosConf = deleteAxiosConf;
146
+ /** DELETE 批量删除接口 axios 配置 */
109
147
  this.multipleDeleteAxiosConf = multipleDeleteAxiosConf;
110
148
  }
111
149
 
150
+ /**
151
+ * 获取请求 url 地址
152
+ * @param {string} api 接口地址 https://a.com/test/:oId/:uId
153
+ * @param {Object} record { uId: 81 }
154
+ * @param {Object} ctx { oId: 100 }
155
+ * @param {Object} opt
156
+ * @returns
157
+ */
112
158
  getApiUrl(api, record, ctx = this.ctx, opt) {
113
159
  const { from } = opt ?? {};
114
160
  if (!api) {
@@ -126,6 +172,13 @@ class DataModel {
126
172
  return apiUrl;
127
173
  }
128
174
 
175
+ /**
176
+ * GET 详情请求
177
+ * @param {Object} q query 参数
178
+ * @param {Object} ctx url 替换的额外参数
179
+ * @param {Object} axiosConf axios 配置
180
+ * @returns
181
+ */
129
182
  get(q = {}, ctx = {}, axiosConf) {
130
183
  let query = _.merge({}, this.query, q);
131
184
  query = _.pickBy(query, (val) => !_.isNil(val) && val !== "");
@@ -162,6 +215,13 @@ class DataModel {
162
215
  });
163
216
  }
164
217
 
218
+ /**
219
+ * GET 列表请求
220
+ * @param {Object} q query 参数
221
+ * @param {Object} ctx url 替换的额外参数
222
+ * @param {Object} axiosConf axios 配置
223
+ * @returns
224
+ */
165
225
  async getList(q, ctx, axiosConf) {
166
226
  let query = _.merge({}, this.query, q);
167
227
  query = _.pickBy(query, (val) => !_.isNil(val) && val !== "");
@@ -209,6 +269,13 @@ class DataModel {
209
269
  return resultList;
210
270
  }
211
271
 
272
+ /**
273
+ * POST 请求
274
+ * @param {Object} params 参数
275
+ * @param {Object} ctx url 替换的额外参数
276
+ * @param {Object} axiosConf axios 配置
277
+ * @returns
278
+ */
212
279
  create(params, ctx, axiosConf) {
213
280
  return new Promise((resolve, reject) => {
214
281
  const opt = {
@@ -243,6 +310,13 @@ class DataModel {
243
310
  });
244
311
  }
245
312
 
313
+ /**
314
+ * PUT 请求
315
+ * @param {Object} params 参数
316
+ * @param {Object} ctx url 替换的额外参数
317
+ * @param {Object} axiosConf axios 配置
318
+ * @returns
319
+ */
246
320
  update(params, ctx, axiosConf) {
247
321
  return new Promise((resolve, reject) => {
248
322
  const opt = { ...this.axiosConf, ...this.updateAxiosConf, ...axiosConf };
@@ -273,6 +347,13 @@ class DataModel {
273
347
  });
274
348
  }
275
349
 
350
+ /**
351
+ * PATCH 请求
352
+ * @param {Object} params 参数
353
+ * @param {Object} ctx url 替换的额外参数
354
+ * @param {Object} axiosConf axios 配置
355
+ * @returns
356
+ */
276
357
  patch(params, ctx, axiosConf) {
277
358
  return new Promise((resolve, reject) => {
278
359
  const opt = { ...this.axiosConf, ...this.patchAxiosConf, ...axiosConf };
@@ -498,46 +579,6 @@ export function checkNetwork() {
498
579
  return !noNetwork;
499
580
  }
500
581
 
501
- function setDefaultAxios(ax) {
502
- if (ax) {
503
- _$Temp.axios = ax;
504
- }
505
- }
506
-
507
- export function setDefaultErrMsg(msg) {
508
- if (msg) {
509
- _$Temp.defaultErrMsg = msg;
510
- }
511
- }
512
-
513
- export function setNetworkErrMsg(msg) {
514
- if (msg) {
515
- _$Temp.networkErrMsg = msg;
516
- }
517
- }
518
-
519
- export function objToFormData(data) {
520
- if (data instanceof FormData) {
521
- return data;
522
- }
523
- const formData = new FormData();
524
- Object.keys(data)?.forEach((key) => {
525
- formData.set(key, data[key]);
526
- });
527
- return formData;
528
- }
529
-
530
- export function formDataToObj(formData) {
531
- if (!(formData instanceof FormData)) {
532
- return formData;
533
- }
534
- const tempData = {};
535
- for (const [key, value] of formData.entries()) {
536
- tempData[key] = value;
537
- }
538
- return tempData;
539
- }
540
-
541
- export { axios, DataModel, setDefaultAxios };
582
+ export { axios, DataModel, formDataToObj, objToFormData, setDefaultAxios, setDefaultErrMsg, setNetworkErrMsg };
542
583
 
543
584
  export default DataModel;
package/src/utils.js ADDED
@@ -0,0 +1,92 @@
1
+ /** 默认错误提示文案 */
2
+ const DEFAULT_MSG = "未知错误";
3
+ /** 网络异常提示文案 */
4
+ const NETWORK_MSG = "网络异常,请检查网络是否开启";
5
+
6
+ /** 暂存相关变量 */
7
+ export const _$Temp = {
8
+ defaultErrMsg: DEFAULT_MSG,
9
+ networkErrMsg: NETWORK_MSG,
10
+ };
11
+
12
+ /**
13
+ * 设置默认的 axios
14
+ * @param {*} ax
15
+ */
16
+ export function setDefaultAxios(ax) {
17
+ if (ax) {
18
+ _$Temp.axios = ax;
19
+ }
20
+ }
21
+
22
+ /**
23
+ * 设置默认的错误提示文案
24
+ * @param {*} ax
25
+ */
26
+ export function setDefaultErrMsg(msg) {
27
+ if (msg) {
28
+ _$Temp.defaultErrMsg = msg;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * 设置默认的网络异常提示文案
34
+ * @param {*} ax
35
+ */
36
+ export function setNetworkErrMsg(msg) {
37
+ if (msg) {
38
+ _$Temp.networkErrMsg = msg;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * 检测网络状态
44
+ * @param {*} errMsg 网络异常消息
45
+ * @returns
46
+ */
47
+ export function checkNetwork() {
48
+ if (!navigator) {
49
+ return true;
50
+ }
51
+ if (navigator.onLine === false) {
52
+ return false;
53
+ }
54
+ const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
55
+ if (!connection) {
56
+ return true;
57
+ }
58
+ const noNetwork = connection?.type === "none" || connection.downlink === 0 || connection.effectiveType === null;
59
+ return !noNetwork;
60
+ }
61
+
62
+ /**
63
+ * 对象转 FormData 格式
64
+ * @param {Object} data
65
+ * @returns
66
+ */
67
+ export function objToFormData(data) {
68
+ if (data instanceof FormData) {
69
+ return data;
70
+ }
71
+ const formData = new FormData();
72
+ Object.keys(data)?.forEach((key) => {
73
+ formData.set(key, data[key]);
74
+ });
75
+ return formData;
76
+ }
77
+
78
+ /**
79
+ * FormData 转对象
80
+ * @param {FormData} formData
81
+ * @returns
82
+ */
83
+ export function formDataToObj(formData) {
84
+ if (!(formData instanceof FormData)) {
85
+ return formData;
86
+ }
87
+ const tempData = {};
88
+ for (const [key, value] of formData.entries()) {
89
+ tempData[key] = value;
90
+ }
91
+ return tempData;
92
+ }