@hzab/data-model 1.8.6 → 1.8.8-beta

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,4 +1,8 @@
1
- # @hzab/data-model@1.8.5
1
+ # @hzab/data-model@1.8.8
2
+
3
+ feat: array-data-model 支持 query 过滤
4
+
5
+ # @hzab/data-model@1.8.6
2
6
 
3
7
  fix: getToken opt.hasCookie 是否读取 cookie 的 token。默认不读取 cookie 的 token
4
8
  fix: setToken 默认不设置到 cookie 上
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@hzab/data-model",
3
- "version": "1.8.6",
3
+ "version": "1.8.8-beta",
4
4
  "description": "data model",
5
5
  "main": "src",
6
6
  "scripts": {
7
7
  "dev": "npm run prepare && webpack serve -c ./config/webpack.config.js --env local",
8
8
  "build": "webpack -c ./config/webpack.config.js --env production",
9
+ "publish-beta": "npm publish --beta",
9
10
  "publish-patch": "npm version patch && npm publish --access public",
10
11
  "publish-minor": "npm version minor && npm publish --access public",
11
12
  "publish-major": "npm version major && npm publish --access public",
package/src/ArrayUtils.js CHANGED
@@ -30,7 +30,7 @@ export class ArrayUtils {
30
30
  * @returns
31
31
  */
32
32
  findItemById(id) {
33
- if (hasId(id)) {
33
+ if (this._hasId(id)) {
34
34
  return null;
35
35
  }
36
36
  const { _idKey } = this;
@@ -42,99 +42,157 @@ export class ArrayUtils {
42
42
  * @param {*} id
43
43
  * @returns
44
44
  */
45
- findItem(query = {}) {
46
- const { _idKey } = this;
47
- const id = query[_idKey];
48
- if (hasId(id)) {
45
+ findItem(query = {}, options = {}) {
46
+ const { fuzzy = false, ignoreCase = false } = options;
47
+ const id = query[this._idKey];
48
+
49
+ if (!this._hasId(id)) {
49
50
  return this.findItemById(id);
50
51
  }
51
- // TODO: query 查询
52
- return _.cloneDeep(this._list.find((it) => it[_idKey] === id));
52
+
53
+ const validQuery = this._filterEmptyQuery(query);
54
+ if (_.isEmpty(validQuery)) {
55
+ return null;
56
+ }
57
+
58
+ const matchItem = this._list.find((item) => {
59
+ return this._isItemMatchQuery(item, validQuery, { fuzzy, ignoreCase });
60
+ });
61
+
62
+ return matchItem ? _.cloneDeep(matchItem) : null;
53
63
  }
54
64
 
55
65
  /**
56
- * 获取列表
57
- * TODO: 搜索?
58
- * @param {*} query
66
+ * 通过 query 筛选列表(支持多条件筛选、分页、排序)
67
+ * @param {Object} query - 综合查询参数
68
+ * @param {number} [query.pageNum=1] - 页码(默认1)
69
+ * @param {number} [query.pageSize=10] - 每页条数(默认10)
70
+ * @param {string|string[]} [query.sortKey] - 排序字段(支持嵌套路径,如 'user.age')
71
+ * @param {string} [query.sortType='desc'] - 排序方式(desc/asc)
72
+ * @param {string} [query.orderByColumn] - 兼容旧排序字段参数
73
+ * @param {string} [query.isAsc] - 兼容旧排序方式参数
74
+ * @param {Object} [options={}] - 查询选项
75
+ * @param {boolean} [options.fuzzy=false] - 字符串字段是否开启模糊匹配
76
+ * @param {boolean} [options.ignoreCase=true] - 模糊匹配时是否忽略大小写
77
+ * @returns {Object} 分页结果
78
+ * @returns {Object[]} result.list - 筛选后的列表(深拷贝)
79
+ * @returns {Object} result.pagination - 分页信息(current/total/pageSize)
59
80
  */
60
- findListByQuery(query) {
61
- const { pageNum = 1, pageSize = 10, sortKey, sortType, orderByColumn, isAsc } = query || {};
62
- // 排序
63
- const _list = this.getSortList(sortKey || orderByColumn, sortType || isAsc);
64
-
65
- // 分页
66
- // 边界检查
67
- if (pageNum < 1 || pageSize <= 0) {
68
- return { list: [], pagination: { current: 1, total: 0 } };
69
- }
70
- // 计算起始索引
71
- const startIndex = (pageNum - 1) * pageSize;
72
- // 如果起始索引超出数组长度,返回空数组
73
- if (startIndex >= _list.length) {
74
- return { list: [], pagination: { current: 1, total: 0 } };
81
+ findListByQuery(query = {}, options = {}) {
82
+ const {
83
+ pageNum = 1,
84
+ pageSize = 10,
85
+ sortKey,
86
+ sortType,
87
+ orderByColumn,
88
+ isAsc,
89
+ ...filterQuery // 提取筛选条件(排除分页排序参数)
90
+ } = query;
91
+
92
+ const { fuzzy = true, ignoreCase = false } = options;
93
+
94
+ // 数据筛选(基于 query 条件)
95
+ let filteredList = [...this._list];
96
+ const validFilterQuery = this._filterEmptyQuery(filterQuery);
97
+
98
+ if (!_.isEmpty(validFilterQuery)) {
99
+ filteredList = filteredList.filter((item) => {
100
+ return this._isItemMatchQuery(item, validFilterQuery, { fuzzy, ignoreCase });
101
+ });
75
102
  }
76
- // 计算结束索引
77
- const endIndex = startIndex + pageSize;
78
103
 
79
- // 使用 slice 方法截取数据
80
- return { list: _list.slice(startIndex, endIndex), pagination: { current: pageNum, total: this.getCount() } };
104
+ // 数据排序(基于筛选后的数据)
105
+ const sortedList = this.getSortList(
106
+ sortKey || orderByColumn,
107
+ sortType || isAsc,
108
+ filteredList, // 传入筛选后列表,避免排序影响原数据
109
+ );
110
+
111
+ // 分页处理(边界校验)
112
+ const pagination = {
113
+ current: Math.max(1, pageNum), // 页码最小为1
114
+ pageSize: Math.max(1, pageSize), // 每页条数最小为1
115
+ total: filteredList.length,
116
+ };
117
+
118
+ // 计算分页截取范围
119
+ const startIndex = (pagination.current - 1) * pagination.pageSize;
120
+ const endIndex = startIndex + pagination.pageSize;
121
+ const paginatedList = sortedList.slice(startIndex, endIndex);
122
+
123
+ return {
124
+ list: _.cloneDeep(paginatedList),
125
+ pagination: { ...pagination },
126
+ };
81
127
  }
82
128
 
83
129
  /**
84
130
  * 对目标数据进行多维度排序
85
- * @param list
86
- * @param {*} sortKey 排序的字段 支持 a.b.c 写法
87
- * @param {*} sortType 排序方式 正序: asc 倒序: desc
88
- * @returns
131
+ * @param {string|string[]|Object[]} sortKey - 排序字段配置
132
+ * @param {string} sortType - 排序方式(desc/asc)
133
+ * @param {Object[]} [customList] - 自定义排序列表(默认使用内部 _list)
134
+ * @returns {Object[]} 排序后的列表
89
135
  */
90
- getSortList(sortKey, sortType) {
91
- const _list = _.cloneDeep(this._list);
136
+ getSortList(sortKey, sortType, customList) {
137
+ const sourceList = customList || this._list;
138
+ const _list = _.cloneDeep(sourceList);
139
+
140
+ // 无排序条件时直接返回原列表
92
141
  if (!sortKey && !sortType) {
93
142
  return _list;
94
143
  }
144
+
145
+ // 统一排序字段格式为数组
95
146
  const paths = Array.isArray(sortKey) ? sortKey : [sortKey];
147
+
96
148
  _list.sort((a, b) => {
97
- return this.compareData(a, b, { paths, sortType });
149
+ return this.compareData(a, b, { paths, sortType, pathIdx: 0 });
98
150
  });
151
+
99
152
  return _list;
100
153
  }
101
154
 
102
155
  /**
103
- * 根据传入的 paths 比较对象目标数据先后顺序
104
- * @param dataA
105
- * @param dataB
106
- * @param opt
107
- * @param opt.paths 数据 path 数组
108
- * @param opt.pathIdx 当前数据下标
109
- * @param opt.sortType 排序规则
110
- * @returns
156
+ * 比较两个数据对象的排序顺序(支持多字段优先级排序)
157
+ * @param {Object} dataA - 比较对象A
158
+ * @param {Object} dataB - 比较对象B
159
+ * @param {Object} opt - 比较配置
160
+ * @param {string[]|Object[]} opt.paths - 排序字段路径数组
161
+ * @param {number} opt.pathIdx - 当前比较的字段索引
162
+ * @param {string} opt.sortType - 排序方式(desc/asc)
163
+ * @returns {number} 排序结果(-1/0/1)
111
164
  */
112
- compareData(dataA, dataB, opt = { paths, pathIdx: 0, sortType: "desc" }) {
165
+ compareData(dataA, dataB, opt = {}) {
113
166
  const { paths, pathIdx = 0, sortType = "desc" } = opt;
114
- const path = paths[pathIdx];
115
- let _path = path;
167
+ const currentPath = paths[pathIdx];
116
168
 
117
- if (path && typeof path === "object") {
118
- // 外部自定义比较函数
119
- if (typeof path.customCompare === "function") {
120
- return direction * path.customCompare(dataA, dataB, opt);
121
- }
122
- _path = path.path;
169
+ // 处理自定义比较逻辑
170
+ if (currentPath && typeof currentPath === "object" && typeof currentPath.customCompare === "function") {
171
+ const direction = sortType === "asc" ? -1 : 1;
172
+ return direction * currentPath.customCompare(dataA, dataB, opt);
123
173
  }
124
174
 
125
- /** 排序规则 */
175
+ // 提取实际字段路径(支持配置对象格式)
176
+ const path = typeof currentPath === "object" ? currentPath.path : currentPath;
177
+ if (!path) {
178
+ return 0;
179
+ }
180
+
181
+ // 确定排序方向(支持按字段单独配置排序方式)
126
182
  let direction = 1;
127
- // 兼容 string 及 object 类型
128
183
  let _sortType = sortType;
129
184
  if (typeof _sortType === "object") {
130
- _sortType = _sortType[_path];
185
+ _sortType = _sortType[path] || "desc";
131
186
  }
132
187
  if (_sortType === "asc") {
133
188
  direction = -1;
134
189
  }
135
190
 
136
- let valueA = this.handleValByKey(dataA, path);
137
- let valueB = this.handleValByKey(dataB, path);
191
+ // 获取并处理字段值(支持日期转换、自定义格式化)
192
+ const valueA = this.handleValByKey(dataA, currentPath);
193
+ const valueB = this.handleValByKey(dataB, currentPath);
194
+
195
+ // 数值比较
138
196
  if (valueA < valueB) {
139
197
  return -1 * direction;
140
198
  }
@@ -142,43 +200,53 @@ export class ArrayUtils {
142
200
  return 1 * direction;
143
201
  }
144
202
 
145
- if (pathIdx + 1 >= paths.length) {
146
- return 0;
147
- }
148
-
149
- if (valueA == valueB) {
150
- // 继续使用次选排序规则排序
203
+ // 当前字段值相等时,使用下一个优先级字段排序
204
+ if (pathIdx + 1 < paths.length) {
151
205
  return this.compareData(dataA, dataB, { ...opt, pathIdx: pathIdx + 1 });
152
206
  }
207
+
208
+ // 所有字段都相等时,保持原有顺序
209
+ return 0;
153
210
  }
154
211
 
155
212
  /**
156
- * 根据 path 配置对数据进行处理
157
- * @param {Object} data 数据
158
- * @param {string/Object} path 取值路径字符串 或 取值配置
159
- * @param {string} path.path 取值路径字符串
160
- * @param {string} path.type 值类型 用于进行相关转换
161
- * @param {Function} path.customFormat 自定义数据处理函数
213
+ * 根据路径获取并处理字段值(支持嵌套路径、类型转换、自定义格式化)
214
+ * @param {Object} data - 数据源对象
215
+ * @param {string|Object} pathConfig - 字段配置
216
+ * @param {string} [pathConfig.path] - 字段路径(如 'user.address.city')
217
+ * @param {string} [pathConfig.type] - 字段类型(支持 'date' 自动转时间戳)
218
+ * @param {Function} [pathConfig.customFormat] - 自定义值处理函数
219
+ * @returns {*} 处理后的字段值
162
220
  */
163
- handleValByKey(data, path) {
164
- if (typeof path === "string") {
165
- return _.get(data, path);
221
+ handleValByKey(data, pathConfig) {
222
+ // 处理字符串路径
223
+ if (typeof pathConfig === "string") {
224
+ return _.get(data, pathConfig);
166
225
  }
167
- if (path === null || path === undefined) {
168
- return;
226
+
227
+ // 处理空配置
228
+ if (_.isNil(pathConfig)) {
229
+ return undefined;
169
230
  }
170
- if (typeof path === "object") {
171
- let val = _.get(data, path.path);
172
- // 日期格式转为时间戳进行比较
173
- if (path?.type === "date") {
174
- val = dayjs(val).valueOf();
231
+
232
+ // 处理对象配置
233
+ if (typeof pathConfig === "object") {
234
+ let val = _.get(data, pathConfig.path);
235
+
236
+ // 日期类型转换为时间戳(便于数值比较)
237
+ if (pathConfig.type === "date") {
238
+ val = dayjs(val).isValid() ? dayjs(val).valueOf() : 0;
175
239
  }
176
- // 外部自定义数据格式函数,便于排序比较
177
- if (typeof path?.customFormat === "function") {
178
- val = customFormat(val);
240
+
241
+ // 自定义值格式化
242
+ if (typeof pathConfig.customFormat === "function") {
243
+ val = pathConfig.customFormat(val, data);
179
244
  }
245
+
180
246
  return val;
181
247
  }
248
+
249
+ return undefined;
182
250
  }
183
251
 
184
252
  /**
@@ -202,10 +270,13 @@ export class ArrayUtils {
202
270
  */
203
271
  pushItem(data) {
204
272
  // TODO: id 去重
205
- const item = _.cloneDeep(data);
206
- this.setId(item);
207
- this.setCreateTime(item);
208
- this._list.push(item);
273
+ const items = Array.isArray(data) ? data : [data];
274
+ items.forEach((item) => {
275
+ const cloneItem = _.cloneDeep(item);
276
+ this._setId(cloneItem);
277
+ this._setCreateTime(cloneItem);
278
+ this._list.push(cloneItem);
279
+ });
209
280
  return STATE_CODE.SUC;
210
281
  }
211
282
 
@@ -216,8 +287,8 @@ export class ArrayUtils {
216
287
  unshiftItem(data) {
217
288
  // TODO: id 去重
218
289
  const item = _.cloneDeep(data);
219
- this.setId(item);
220
- this.setCreateTime(item);
290
+ this._setId(item);
291
+ this._setCreateTime(item);
221
292
  this._list.unshift(item);
222
293
  return STATE_CODE.SUC;
223
294
  }
@@ -230,7 +301,7 @@ export class ArrayUtils {
230
301
  replaceItem(data) {
231
302
  const { _idKey, _list } = this;
232
303
  const id = data[_idKey];
233
- if (hasId(id)) {
304
+ if (this._hasId(id)) {
234
305
  return STATE_CODE.ERR_INPUT_ID;
235
306
  }
236
307
  const idx = _list.findIndex((it) => it[_idKey] === id);
@@ -238,7 +309,7 @@ export class ArrayUtils {
238
309
  return STATE_CODE.NOT_FOUNT;
239
310
  }
240
311
  _list.splice(idx, 1, data);
241
- this.setUpdateTime(data);
312
+ this._setUpdateTime(data);
242
313
  return STATE_CODE.SUC;
243
314
  }
244
315
 
@@ -250,7 +321,7 @@ export class ArrayUtils {
250
321
  updateItemValue(data) {
251
322
  const { _idKey, _list } = this;
252
323
  const id = data[_idKey];
253
- if (hasId(id)) {
324
+ if (this._hasId(id)) {
254
325
  return STATE_CODE.ERR_INPUT_ID;
255
326
  }
256
327
  const item = _list.find((it) => it[_idKey] === id);
@@ -260,7 +331,7 @@ export class ArrayUtils {
260
331
  Object.keys(data).forEach((key) => {
261
332
  item[key] = data[key];
262
333
  });
263
- this.setUpdateTime(data);
334
+ this._setUpdateTime(data);
264
335
  return STATE_CODE.SUC;
265
336
  }
266
337
 
@@ -272,7 +343,7 @@ export class ArrayUtils {
272
343
  */
273
344
  delItem(id) {
274
345
  const { _idKey, _list } = this;
275
- if (hasId(id)) {
346
+ if (this._hasId(id)) {
276
347
  return STATE_CODE.ERR_INPUT_ID;
277
348
  }
278
349
  const idx = _list.findIndex((it) => it[_idKey] === id);
@@ -283,15 +354,165 @@ export class ArrayUtils {
283
354
  return STATE_CODE.SUC;
284
355
  }
285
356
 
357
+ /**
358
+ * 检查单个 item 是否匹配所有 query 条件
359
+ * @private
360
+ * @param {Object} item - 待检查的列表项
361
+ * @param {Object} query - 查询条件
362
+ * @param {Object} options - 匹配选项
363
+ * @param {boolean} options.fuzzy - 是否开启模糊匹配
364
+ * @param {boolean} options.ignoreCase - 模糊匹配是否忽略大小写
365
+ * @returns {boolean} 是否匹配所有条件
366
+ */
367
+ _isItemMatchQuery(item, query, { fuzzy, ignoreCase }) {
368
+ // 遍历所有查询条件,必须全部满足才返回 true
369
+ return Object.entries(query).every(([key, targetValue]) => {
370
+ // 获取 item 中对应字段的值(支持嵌套路径,如 'user.name')
371
+ const itemValue = _.get(item, key);
372
+
373
+ // 处理空值情况(null/undefined 仅匹配 null/undefined)
374
+ if (_.isNil(itemValue)) {
375
+ return _.isNil(targetValue);
376
+ }
377
+
378
+ // 处理数组类型查询(支持 in 操作,如 { status: [1, 2] })
379
+ if (Array.isArray(targetValue)) {
380
+ return targetValue.some((val) => this._compareSingleValue(itemValue, val, fuzzy, ignoreCase));
381
+ }
382
+
383
+ // 处理范围查询(如 { age: { $gt: 18, $lt: 30 } })
384
+ if (typeof targetValue === "object" && !Array.isArray(targetValue)) {
385
+ return this._handleRangeQuery(itemValue, targetValue);
386
+ }
387
+
388
+ // 处理普通值匹配(精确/模糊)
389
+ return this._compareSingleValue(itemValue, targetValue, fuzzy, ignoreCase);
390
+ });
391
+ }
392
+
393
+ /**
394
+ * 比较单个值是否匹配(支持精确/模糊匹配)
395
+ * @private
396
+ * @param {*} itemValue - 列表项字段值
397
+ * @param {*} targetValue - 查询目标值
398
+ * @param {boolean} fuzzy - 是否模糊匹配
399
+ * @param {boolean} ignoreCase - 是否忽略大小写
400
+ * @returns {boolean} 是否匹配
401
+ */
402
+ _compareSingleValue(itemValue, targetValue, fuzzy, ignoreCase) {
403
+ // 类型不同时直接不匹配(避免隐式类型转换导致的问题)
404
+ if (typeof itemValue !== typeof targetValue) {
405
+ // 特殊处理:数字和字符串数字的匹配(如 123 和 '123')
406
+ if (
407
+ (typeof itemValue === "number" && typeof targetValue === "string" && !isNaN(Number(targetValue))) ||
408
+ (typeof itemValue === "string" && typeof targetValue === "number" && !isNaN(Number(itemValue)))
409
+ ) {
410
+ return Number(itemValue) === targetValue;
411
+ }
412
+ return false;
413
+ }
414
+
415
+ // 字符串处理(支持模糊匹配和大小写忽略)
416
+ if (typeof itemValue === "string" && fuzzy) {
417
+ const itemStr = ignoreCase ? itemValue.toLowerCase() : itemValue;
418
+ const targetStr = ignoreCase ? String(targetValue).toLowerCase() : String(targetValue);
419
+ return itemStr.includes(targetStr);
420
+ }
421
+
422
+ // 其他类型(数字、布尔等)精确匹配
423
+ return itemValue === targetValue;
424
+ }
425
+
426
+ /**
427
+ * 处理范围查询(如 $gt/$lt/$gte/$lte)
428
+ * @private
429
+ * @param {number|string|Date} itemValue - 列表项字段值
430
+ * @param {Object} rangeConfig - 范围配置({ $gt: 18, $lt: 30 })
431
+ * @returns {boolean} 是否在范围内
432
+ */
433
+ _handleRangeQuery(itemValue, rangeConfig) {
434
+ const { $gt, $lt, $gte, $lte } = rangeConfig;
435
+ let isValid = true;
436
+
437
+ // 转换为可比较的类型(优先处理日期)
438
+ const compareValue = this._convertToComparableValue(itemValue);
439
+ const convertTarget = (val) => this._convertToComparableValue(val);
440
+
441
+ // 大于(>)
442
+ if ($gt !== undefined) {
443
+ isValid = isValid && compareValue > convertTarget($gt);
444
+ }
445
+ // 小于(<)
446
+ if ($lt !== undefined) {
447
+ isValid = isValid && compareValue < convertTarget($lt);
448
+ }
449
+ // 大于等于(>=)
450
+ if ($gte !== undefined) {
451
+ isValid = isValid && compareValue >= convertTarget($gte);
452
+ }
453
+ // 小于等于(<=)
454
+ if ($lte !== undefined) {
455
+ isValid = isValid && compareValue <= convertTarget($lte);
456
+ }
457
+
458
+ return isValid;
459
+ }
460
+
461
+ /**
462
+ * 将值转换为可比较的类型(统一数字、日期格式)
463
+ * @private
464
+ * @param {*} value - 待转换的值
465
+ * @returns {number|string} 可比较的值
466
+ */
467
+ _convertToComparableValue(value) {
468
+ // 日期转换为时间戳
469
+ if (value instanceof Date || dayjs(value).isValid()) {
470
+ return dayjs(value).valueOf();
471
+ }
472
+ // 字符串数字转换为数字
473
+ if (typeof value === "string" && !isNaN(Number(value))) {
474
+ return Number(value);
475
+ }
476
+ return value;
477
+ }
478
+
479
+ /**
480
+ * 过滤空查询条件(移除 undefined/null/空字符串/空数组/空对象)
481
+ * @private
482
+ * @param {Object} query - 原始查询条件
483
+ * @returns {Object} 过滤后的有效查询条件
484
+ */
485
+ _filterEmptyQuery(query) {
486
+ return Object.entries(query).reduce((acc, [key, value]) => {
487
+ // 保留非空值:
488
+ // 1. 不是 null/undefined
489
+ // 2. 不是空字符串
490
+ // 3. 不是空数组
491
+ // 4. 不是空对象
492
+ if (
493
+ !_.isNil(value) &&
494
+ value !== "" &&
495
+ !(Array.isArray(value) && value.length === 0) &&
496
+ !(typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0)
497
+ ) {
498
+ acc[key] = value;
499
+ }
500
+ return acc;
501
+ }, {});
502
+ }
503
+
504
+ _hasId(id) {
505
+ return _.isNil(id) || id === "";
506
+ }
507
+
286
508
  /**
287
509
  * 子项没有 id 的时候自动添加
288
510
  * @param {*} item
289
511
  * @returns
290
512
  */
291
- setId(item) {
292
- const { _idKey } = this;
293
- if (!item[_idKey]) {
294
- item[_idKey] = nanoid();
513
+ _setId(item) {
514
+ if (_.isObject(item) && this._hasId(item[this._idKey])) {
515
+ item[this._idKey] = nanoid();
295
516
  }
296
517
  return item;
297
518
  }
@@ -300,21 +521,19 @@ export class ArrayUtils {
300
521
  * 设置创建时间
301
522
  * @param {*} item
302
523
  */
303
- setCreateTime(item) {
304
- item.createTime = Date.now();
524
+ _setCreateTime(item) {
525
+ if (_.isObject(item) && this._hasId(item.createTime)) {
526
+ item.createTime = Date.now();
527
+ }
305
528
  }
306
529
 
307
530
  /**
308
531
  * 设置更新时间
309
532
  * @param {*} item
310
533
  */
311
- setUpdateTime(item) {
534
+ _setUpdateTime(item) {
312
535
  item.createTime = Date.now();
313
536
  }
314
537
  }
315
538
 
316
- export const hasId = (id) => {
317
- return _.isNil(id) || id === "";
318
- };
319
-
320
539
  export default ArrayUtils;
@@ -107,6 +107,17 @@ class ArrayDataModel extends ArrayUtils {
107
107
  this.multipleDeleteReqMap = multipleDeleteReqMap;
108
108
  /** DELETE 批量删除 接口请求结果数据处理回调 */
109
109
  this.multipleDeleteResMap = multipleDeleteResMap;
110
+
111
+ const {
112
+ /**
113
+ *
114
+ * @param {Object} [options={}] - 查询选项
115
+ * @param {boolean} [options.fuzzy=false] - 字符串字段是否开启模糊匹配
116
+ * @param {boolean} [options.ignoreCase=true] - 模糊匹配时是否忽略大小写
117
+ */
118
+ arrOptions,
119
+ } = params || {};
120
+ this._arrOptions = arrOptions;
110
121
  }
111
122
 
112
123
  /**
@@ -123,7 +134,7 @@ class ArrayDataModel extends ArrayUtils {
123
134
  }
124
135
 
125
136
  return new Promise((resolve, reject) => {
126
- let res = this.findItem(query);
137
+ let res = this.findItem(query, this._arrOptions);
127
138
  if (this.getMap) {
128
139
  res = this.getMap(res);
129
140
  }
@@ -151,7 +162,7 @@ class ArrayDataModel extends ArrayUtils {
151
162
  if (this.getListFunc) {
152
163
  resultList = await this.getListFunc(query);
153
164
  } else {
154
- const getPro = this.findListByQuery(query);
165
+ const getPro = this.findListByQuery(query, this._arrOptions);
155
166
  resultList = await getPro;
156
167
  }
157
168
  if (this.getListMap) {