gis-common 4.2.25 → 4.2.26

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.
@@ -30,9 +30,6 @@ var EventType = /* @__PURE__ */ ((EventType2) => {
30
30
  })(EventType || {});
31
31
  var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
32
32
  ErrorType2["LOGIN_EXPIRED"] = "登录信息过期,请重新登录";
33
- ErrorType2["CROSS_ERROR"] = "不允许跨站点访问资源";
34
- ErrorType2["NO_DATA_FOUND"] = "资源不存在";
35
- ErrorType2["TIMEOUT"] = "请求超时";
36
33
  ErrorType2["INTERNAL_ERROR"] = "内部错误";
37
34
  ErrorType2["NETWORK_ERROR"] = "请求失败,请检查网络是否已连接";
38
35
  ErrorType2["PROCESS_FAIL"] = "任务处理失败";
@@ -54,6 +51,12 @@ var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
54
51
  ErrorType2["DATA_ERROR_COORDINATE"] = "格式类型验证失败,必须是坐标";
55
52
  ErrorType2["DATA_ERROR_COLOR"] = "格式类型验证失败,必须是颜色代码";
56
53
  ErrorType2["DATA_ERROR_GEOJSON"] = "格式类型验证失败,必须是GeoJSON";
54
+ ErrorType2["REQUEST_ERROR"] = "请求资源失败";
55
+ ErrorType2["REQUEST_ERROR_CROSS"] = "不允许跨站点访问资源";
56
+ ErrorType2["REQUEST_ERROR_TIMEOUT"] = "请求超时,请检查网络";
57
+ ErrorType2["REQUEST_ERROR_NOT_FOUND"] = "请求资源不存在";
58
+ ErrorType2["REQUEST_ERROR_FORBIDDEN"] = "请求资源禁止访问";
59
+ ErrorType2["REQUEST_ERROR_EMPTY"] = "请求数据记录为空";
57
60
  return ErrorType2;
58
61
  })(ErrorType || {});
59
62
  var LayerType = /* @__PURE__ */ ((LayerType2) => {
@@ -87,6 +90,7 @@ var GraphicType = /* @__PURE__ */ ((GraphicType2) => {
87
90
  return GraphicType2;
88
91
  })(GraphicType || {});
89
92
  var LineSymbol = /* @__PURE__ */ ((LineSymbol2) => {
93
+ LineSymbol2[LineSymbol2["SOLID"] = 0] = "SOLID";
90
94
  LineSymbol2["DASH"] = "10,5";
91
95
  LineSymbol2["DOT"] = "3";
92
96
  LineSymbol2["DASHDOT"] = "10,3,3,3";
@@ -94,10 +98,10 @@ var LineSymbol = /* @__PURE__ */ ((LineSymbol2) => {
94
98
  return LineSymbol2;
95
99
  })(LineSymbol || {});
96
100
  var MeasureMode = /* @__PURE__ */ ((MeasureMode2) => {
97
- MeasureMode2["DISTANCE"] = "distance";
98
- MeasureMode2["AREA"] = "area";
99
- MeasureMode2["HEIGHT"] = "height";
100
- MeasureMode2["ANGLE"] = "angle";
101
+ MeasureMode2[MeasureMode2["DISTANCE"] = 0] = "DISTANCE";
102
+ MeasureMode2[MeasureMode2["AREA"] = 1] = "AREA";
103
+ MeasureMode2[MeasureMode2["HEIGHT"] = 2] = "HEIGHT";
104
+ MeasureMode2[MeasureMode2["ANGLE"] = 3] = "ANGLE";
101
105
  return MeasureMode2;
102
106
  })(MeasureMode || {});
103
107
  class AudioPlayer {
@@ -128,7 +132,7 @@ class AudioPlayer {
128
132
  }
129
133
  class Cookie {
130
134
  static set(name, value, days = 30) {
131
- if (typeof name !== "string" || typeof value !== "string" || typeof days !== "number") {
135
+ if (typeof name !== "string" || typeof days !== "number") {
132
136
  throw new Error("Invalid arguments");
133
137
  }
134
138
  const exp = /* @__PURE__ */ new Date();
@@ -152,870 +156,876 @@ class Cookie {
152
156
  }
153
157
  }
154
158
  }
155
- const MathUtil = {
156
- DEG2RAD: Math.PI / 180,
157
- RAD2DEG: 180 / Math.PI,
158
- randInt(low, high) {
159
- return low + Math.floor(Math.random() * (high - low + 1));
159
+ const Util = {
160
+ /**
161
+ * 获取数据类型
162
+ *
163
+ * @param data 待判断的数据
164
+ * @returns 返回数据类型字符串
165
+ */
166
+ getDataType(data) {
167
+ return Object.prototype.toString.call(data).slice(8, -1);
160
168
  },
161
- randFloat(low, high) {
162
- return low + Math.random() * (high - low);
169
+ asArray(obj) {
170
+ return this.isEmpty(obj) ? [] : Array.isArray(obj) ? obj : [obj];
171
+ },
172
+ asNumber(a) {
173
+ return Number.isNaN(Number(a)) ? 0 : Number(a);
163
174
  },
164
175
  /**
165
- * 角度转弧度
176
+ * 将值转换为字符串
166
177
  *
167
- * @param {*} degrees
168
- * @returns {*}
178
+ * @param value 要转换的值
179
+ * @returns 转换后的字符串,如果值为空,则返回空字符串
169
180
  */
170
- deg2Rad(degrees) {
171
- return degrees * this.DEG2RAD;
181
+ asString(value) {
182
+ if (this.isEmpty(value)) {
183
+ return "";
184
+ } else {
185
+ switch (this.getDataType(value)) {
186
+ case "Object":
187
+ case "Array":
188
+ return JSON.stringify(value);
189
+ default:
190
+ return value;
191
+ }
192
+ }
172
193
  },
173
194
  /**
174
- * 弧度转角度
195
+ * 判断传入的值是否为空
175
196
  *
176
- * @param {*} radians
177
- * @returns {*}
197
+ * @param value 待判断的值
198
+ * @returns 返回布尔值,表示是否为空
178
199
  */
179
- rad2Deg(radians) {
180
- return radians * this.RAD2DEG;
200
+ isEmpty(value) {
201
+ if (value == null) {
202
+ return true;
203
+ }
204
+ const type = this.getDataType(value);
205
+ switch (type) {
206
+ case "String":
207
+ return value.trim() === "";
208
+ case "Array":
209
+ return !value.length;
210
+ case "Object":
211
+ return !Object.keys(value).length;
212
+ case "Boolean":
213
+ return !value;
214
+ default:
215
+ return false;
216
+ }
181
217
  },
182
- round(value, n = 2) {
183
- return Math.round(value * Math.pow(10, n)) / Math.pow(10, n);
218
+ /**
219
+ * 将JSON对象转换为FormData对象
220
+ *
221
+ * @param json 待转换的JSON对象,其属性值为字符串或Blob类型
222
+ * @returns 转换后的FormData对象
223
+ */
224
+ json2form(json) {
225
+ const formData = new FormData();
226
+ if (this.isEmpty(json)) return formData;
227
+ Object.keys(json).forEach((key) => {
228
+ formData.append(key, json[key] instanceof Object ? JSON.stringify(json[key]) : json[key]);
229
+ });
230
+ return formData;
184
231
  },
185
232
  /**
186
- * 将数值限制在指定范围内
233
+ * 生成GUID
187
234
  *
188
- * @param val 需要限制的数值
189
- * @param min 最小值
190
- * @param max 最大值
191
- * @returns 返回限制后的数值
235
+ * @returns 返回一个由8个16进制数组成的GUID字符串
192
236
  */
193
- clamp(val, min, max) {
194
- return Math.max(min, Math.min(max, val));
195
- }
196
- };
197
- const ColorName = {
198
- aliceblue: [240, 248, 255],
199
- antiquewhite: [250, 235, 215],
200
- aqua: [0, 255, 255],
201
- aquamarine: [127, 255, 212],
202
- azure: [240, 255, 255],
203
- beige: [245, 245, 220],
204
- bisque: [255, 228, 196],
205
- black: [0, 0, 0],
206
- blanchedalmond: [255, 235, 205],
207
- blue: [0, 0, 255],
208
- blueviolet: [138, 43, 226],
209
- brown: [165, 42, 42],
210
- burlywood: [222, 184, 135],
211
- cadetblue: [95, 158, 160],
212
- chartreuse: [127, 255, 0],
213
- chocolate: [210, 105, 30],
214
- coral: [255, 127, 80],
215
- cornflowerblue: [100, 149, 237],
216
- cornsilk: [255, 248, 220],
217
- crimson: [220, 20, 60],
218
- cyan: [0, 255, 255],
219
- darkblue: [0, 0, 139],
220
- darkcyan: [0, 139, 139],
221
- darkgoldenrod: [184, 134, 11],
222
- darkgray: [169, 169, 169],
223
- darkgreen: [0, 100, 0],
224
- darkgrey: [169, 169, 169],
225
- darkkhaki: [189, 183, 107],
226
- darkmagenta: [139, 0, 139],
227
- darkolivegreen: [85, 107, 47],
228
- darkorange: [255, 140, 0],
229
- darkorchid: [153, 50, 204],
230
- darkred: [139, 0, 0],
231
- darksalmon: [233, 150, 122],
232
- darkseagreen: [143, 188, 143],
233
- darkslateblue: [72, 61, 139],
234
- darkslategray: [47, 79, 79],
235
- darkslategrey: [47, 79, 79],
236
- darkturquoise: [0, 206, 209],
237
- darkviolet: [148, 0, 211],
238
- deeppink: [255, 20, 147],
239
- deepskyblue: [0, 191, 255],
240
- dimgray: [105, 105, 105],
241
- dimgrey: [105, 105, 105],
242
- dodgerblue: [30, 144, 255],
243
- firebrick: [178, 34, 34],
244
- floralwhite: [255, 250, 240],
245
- forestgreen: [34, 139, 34],
246
- fuchsia: [255, 0, 255],
247
- gainsboro: [220, 220, 220],
248
- ghostwhite: [248, 248, 255],
249
- gold: [255, 215, 0],
250
- goldenrod: [218, 165, 32],
251
- gray: [128, 128, 128],
252
- green: [0, 128, 0],
253
- greenyellow: [173, 255, 47],
254
- grey: [128, 128, 128],
255
- honeydew: [240, 255, 240],
256
- hotpink: [255, 105, 180],
257
- indianred: [205, 92, 92],
258
- indigo: [75, 0, 130],
259
- ivory: [255, 255, 240],
260
- khaki: [240, 230, 140],
261
- lavender: [230, 230, 250],
262
- lavenderblush: [255, 240, 245],
263
- lawngreen: [124, 252, 0],
264
- lemonchiffon: [255, 250, 205],
265
- lightblue: [173, 216, 230],
266
- lightcoral: [240, 128, 128],
267
- lightcyan: [224, 255, 255],
268
- lightgoldenrodyellow: [250, 250, 210],
269
- lightgray: [211, 211, 211],
270
- lightgreen: [144, 238, 144],
271
- lightgrey: [211, 211, 211],
272
- lightpink: [255, 182, 193],
273
- lightsalmon: [255, 160, 122],
274
- lightseagreen: [32, 178, 170],
275
- lightskyblue: [135, 206, 250],
276
- lightslategray: [119, 136, 153],
277
- lightslategrey: [119, 136, 153],
278
- lightsteelblue: [176, 196, 222],
279
- lightyellow: [255, 255, 224],
280
- lime: [0, 255, 0],
281
- limegreen: [50, 205, 50],
282
- linen: [250, 240, 230],
283
- magenta: [255, 0, 255],
284
- maroon: [128, 0, 0],
285
- mediumaquamarine: [102, 205, 170],
286
- mediumblue: [0, 0, 205],
287
- mediumorchid: [186, 85, 211],
288
- mediumpurple: [147, 112, 219],
289
- mediumseagreen: [60, 179, 113],
290
- mediumslateblue: [123, 104, 238],
291
- mediumspringgreen: [0, 250, 154],
292
- mediumturquoise: [72, 209, 204],
293
- mediumvioletred: [199, 21, 133],
294
- midnightblue: [25, 25, 112],
295
- mintcream: [245, 255, 250],
296
- mistyrose: [255, 228, 225],
297
- moccasin: [255, 228, 181],
298
- navajowhite: [255, 222, 173],
299
- navy: [0, 0, 128],
300
- oldlace: [253, 245, 230],
301
- olive: [128, 128, 0],
302
- olivedrab: [107, 142, 35],
303
- orange: [255, 165, 0],
304
- orangered: [255, 69, 0],
305
- orchid: [218, 112, 214],
306
- palegoldenrod: [238, 232, 170],
307
- palegreen: [152, 251, 152],
308
- paleturquoise: [175, 238, 238],
309
- palevioletred: [219, 112, 147],
310
- papayawhip: [255, 239, 213],
311
- peachpuff: [255, 218, 185],
312
- peru: [205, 133, 63],
313
- pink: [255, 192, 203],
314
- plum: [221, 160, 221],
315
- powderblue: [176, 224, 230],
316
- purple: [128, 0, 128],
317
- rebeccapurple: [102, 51, 153],
318
- red: [255, 0, 0],
319
- rosybrown: [188, 143, 143],
320
- royalblue: [65, 105, 225],
321
- saddlebrown: [139, 69, 19],
322
- salmon: [250, 128, 114],
323
- sandybrown: [244, 164, 96],
324
- seagreen: [46, 139, 87],
325
- seashell: [255, 245, 238],
326
- sienna: [160, 82, 45],
327
- silver: [192, 192, 192],
328
- skyblue: [135, 206, 235],
329
- slateblue: [106, 90, 205],
330
- slategray: [112, 128, 144],
331
- slategrey: [112, 128, 144],
332
- snow: [255, 250, 250],
333
- springgreen: [0, 255, 127],
334
- steelblue: [70, 130, 180],
335
- tan: [210, 180, 140],
336
- teal: [0, 128, 128],
337
- thistle: [216, 191, 216],
338
- tomato: [255, 99, 71],
339
- turquoise: [64, 224, 208],
340
- violet: [238, 130, 238],
341
- wheat: [245, 222, 179],
342
- white: [255, 255, 255],
343
- whitesmoke: [245, 245, 245],
344
- yellow: [255, 255, 0],
345
- yellowgreen: [154, 205, 50]
346
- };
347
- class Color {
348
- constructor(r, g, b, a) {
349
- __publicField(this, "_r");
350
- __publicField(this, "_g");
351
- __publicField(this, "_b");
352
- __publicField(this, "_alpha");
353
- this._validateColorChannel(r);
354
- this._validateColorChannel(g);
355
- this._validateColorChannel(b);
356
- this._r = r;
357
- this._g = g;
358
- this._b = b;
359
- this._alpha = MathUtil.clamp(a || 1, 0, 1);
360
- }
361
- _validateColorChannel(channel) {
362
- if (channel < 0 || channel > 255) {
363
- throw new Error("Color channel must be between 0 and 255.");
364
- }
365
- }
366
- toString() {
367
- return `rgba(${this._r}, ${this._g}, ${this._b}, ${this._alpha})`;
368
- }
369
- toJson() {
370
- return { r: this._r, g: this._g, b: this._b, a: this._alpha };
371
- }
372
- get rgba() {
373
- return `rgba(${this._r}, ${this._g}, ${this._b}, ${this._alpha})`;
374
- }
375
- get hex() {
376
- return Color.rgb2hex(this._r, this._g, this._b, this._alpha);
377
- }
378
- setAlpha(a) {
379
- this._alpha = MathUtil.clamp(a, 0, 1);
380
- return this;
381
- }
382
- // 设置颜色的RGB值
383
- setRgb(r, g, b) {
384
- this._validateColorChannel(r);
385
- this._validateColorChannel(g);
386
- this._validateColorChannel(b);
387
- this._r = r;
388
- this._g = g;
389
- this._b = b;
390
- return this;
391
- }
392
- /**
393
- * 从RGBA字符串创建Color对象
394
- *
395
- * @param rgbaValue RGBA颜色值字符串,格式为"rgba(r,g,b,a)"或"rgb(r,g,b)"
396
- * @returns 返回Color对象
397
- * @throws 如果rgbaValue不是有效的RGBA颜色值,则抛出错误
398
- */
399
- static fromRgba(rgbaValue) {
400
- const rgbaMatch = rgbaValue.match(/^rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.]+))?\s*\)$/);
401
- if (!rgbaMatch) throw new Error("Invalid RGBA color value");
402
- const r = parseInt(rgbaMatch[1], 10);
403
- const g = parseInt(rgbaMatch[2], 10);
404
- const b = parseInt(rgbaMatch[3], 10);
405
- const a = rgbaMatch[5] ? parseFloat(rgbaMatch[5]) : 1;
406
- return new Color(r, g, b, a);
407
- }
408
- /**
409
- * 将十六进制颜色值转换为颜色对象
410
- *
411
- * @param hexValue 十六进制颜色值,可带或不带#前缀,支持3位和6位表示
412
- * @returns 返回颜色对象
413
- */
414
- static fromHex(hexValue, a = 1) {
415
- const rgxShort = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
416
- const hex = hexValue.replace(rgxShort, (m, r2, g2, b2) => r2 + r2 + g2 + g2 + b2 + b2);
417
- const rgx = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
418
- const rgb = rgx.exec(hex);
419
- if (!rgb) {
420
- throw new Error("Invalid HEX color value");
421
- }
422
- const r = parseInt(rgb[1], 16);
423
- const g = parseInt(rgb[2], 16);
424
- const b = parseInt(rgb[3], 16);
425
- return new Color(r, g, b, a);
426
- }
237
+ guid() {
238
+ const S4 = function() {
239
+ return ((1 + Math.random()) * 65536 | 0).toString(16).substring(1);
240
+ };
241
+ return S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4();
242
+ },
427
243
  /**
428
- * 从 HSL 字符串创建颜色对象
244
+ * 将参数进行解码并返回解码后的字符串
429
245
  *
430
- * @param hsl HSL 字符串,格式为 hsl(h, s%, l%) 或 hsla(h, s%, l%, a)
431
- * @returns 返回颜色对象,如果 hsl 字符串无效则返回 null
246
+ * @param args 参数
247
+ * @returns 解码后的字符串
432
248
  */
433
- static fromHsl(hslValue) {
434
- const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue) || /hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec(hslValue);
435
- if (!hsl) {
436
- throw new Error("Invalid HSL color value");
437
- }
438
- const h = parseInt(hsl[1], 10) / 360;
439
- const s = parseInt(hsl[2], 10) / 100;
440
- const l = parseInt(hsl[3], 10) / 100;
441
- const a = hsl[4] ? parseFloat(hsl[4]) : 1;
442
- function hue2rgb(p, q, t) {
443
- if (t < 0) t += 1;
444
- if (t > 1) t -= 1;
445
- if (t < 1 / 6) return p + (q - p) * 6 * t;
446
- if (t < 1 / 2) return q;
447
- if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
448
- return p;
449
- }
450
- let r, g, b;
451
- if (s === 0) {
452
- r = g = b = l;
249
+ decodeDict(...args) {
250
+ let res = "";
251
+ if (args.length > 1) {
252
+ const items = args.slice(1, args.length % 2 === 0 ? args.length - 1 : args.length);
253
+ for (let i = 0; i < items.length; i = i + 2) {
254
+ const item = items[i];
255
+ if (args[0] === item) {
256
+ res = items[i + 1];
257
+ }
258
+ }
259
+ if (!res && args.length % 2 === 0) {
260
+ res = args[args.length - 1];
261
+ }
453
262
  } else {
454
- const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
455
- const p = 2 * l - q;
456
- r = hue2rgb(p, q, h + 1 / 3);
457
- g = hue2rgb(p, q, h);
458
- b = hue2rgb(p, q, h - 1 / 3);
459
- }
460
- return new Color(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a);
461
- }
462
- static fromName(str) {
463
- const rgba = ColorName[str];
464
- if (!rgba) {
465
- throw new Error(`Invalid color name: ${str}`);
263
+ res = args[0];
466
264
  }
467
- return new Color(rgba[0], rgba[1], rgba[2], rgba.length > 3 ? rgba[3] : 1);
468
- }
265
+ return res;
266
+ },
469
267
  /**
470
- * 从字符串中创建颜色对象
268
+ * 将一个或多个对象的所有可枚举属性复制到目标对象。
471
269
  *
472
- * @param str 字符串类型的颜色值,支持rgba、hex、hsl格式
473
- * @returns 返回创建的颜色对象
474
- * @throws 当颜色值无效时,抛出错误
270
+ * @param dest 目标对象,用于接收复制的属性。
271
+ * @param args 一个或多个源对象,用于提供要复制的属性。
272
+ * @returns 返回目标对象,包含所有复制的属性。
475
273
  */
476
- static from(str) {
477
- if (this.isRgb(str)) {
478
- return this.fromRgba(str);
479
- } else if (this.isHex(str)) {
480
- return this.fromHex(str);
481
- } else if (this.isHsl(str)) {
482
- return this.fromHsl(str);
483
- } else if (Object.keys(ColorName).map((key) => key.toString()).includes(str)) {
484
- return this.fromName(str);
485
- } else {
486
- throw new Error("Invalid color value");
274
+ extend(dest, ...args) {
275
+ let i, j, len, src;
276
+ for (j = 0, len = args.length; j < len; j++) {
277
+ src = args[j];
278
+ for (i in src) {
279
+ dest[i] = src[i];
280
+ }
487
281
  }
488
- }
282
+ return dest;
283
+ },
489
284
  /**
490
- * 将RGB颜色值转换为十六进制颜色值
285
+ * 将扁平化数组转换为树形结构数组
491
286
  *
492
- * @param r 红色分量值,取值范围0-255
493
- * @param g 绿色分量值,取值范围0-255
494
- * @param b 蓝色分量值,取值范围0-255
495
- * @param a 可选参数,透明度分量值,取值范围0-1
496
- * @returns 十六进制颜色值,格式为#RRGGBB或#RRGGBBAA
287
+ * @param data 扁平化数组
288
+ * @param idPropertyName 数据中标识id的字段名,默认为'id'
289
+ * @param parentIdPropertyName 数据中标识父节点id的字段名,默认为'parentId'
290
+ * @param childrenPropertyName 树形结构中标识子节点的字段名,默认为'children'
291
+ * @returns 转换后的树形结构数组
497
292
  */
498
- static rgb2hex(r, g, b, a) {
499
- var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
500
- if (a !== void 0) {
501
- const alpha = Math.round(a * 255).toString(16).padStart(2, "0");
502
- return hex + alpha;
503
- }
504
- return hex;
505
- }
506
- static isHex(a) {
507
- return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a);
508
- }
509
- static isRgb(a) {
510
- return /^rgba?\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*[\d.]+)?\s*\)$/.test(a);
511
- }
512
- static isHsl(a) {
513
- return /^(hsl|hsla)\(\d+,\s*[\d.]+%,\s*[\d.]+%(,\s*[\d.]+)?\)$/.test(a);
514
- }
515
- static isColor(a) {
516
- return this.isHex(a) || this.isRgb(a) || this.isHsl(a);
517
- }
518
- static random() {
519
- let r = Math.floor(Math.random() * 256);
520
- let g = Math.floor(Math.random() * 256);
521
- let b = Math.floor(Math.random() * 256);
522
- let a = Math.random();
523
- return new Color(r, g, b, a);
524
- }
525
- }
526
- class CanvasDrawer {
527
- constructor(el) {
528
- __publicField(this, "context", null);
529
- if (typeof el === "string") {
530
- el = document.querySelector("#" + el);
531
- if (!el) {
532
- throw new Error("Element not found");
293
+ convertToTree2(data, idPropertyName = "id", parentIdPropertyName = "parentId", childrenPropertyName = "children") {
294
+ const result = [];
295
+ function buildChildren(item) {
296
+ const children = data.filter((item2) => item2[parentIdPropertyName] === item[idPropertyName]).map((child) => {
297
+ if (!result.some((r) => r[idPropertyName] === child[idPropertyName])) {
298
+ buildChildren(child);
299
+ }
300
+ return child;
301
+ });
302
+ if (children.length > 0) {
303
+ item[childrenPropertyName] = children;
533
304
  }
534
305
  }
535
- if (el instanceof HTMLElement) {
536
- const canvas = el;
537
- if (canvas.getContext) {
538
- this.context = canvas.getContext("2d");
539
- } else {
540
- throw new Error("getContext is not available on this element");
306
+ data.forEach((item) => {
307
+ if (!data.some((other) => other[parentIdPropertyName] === item[idPropertyName])) {
308
+ buildChildren(item);
309
+ result.push(item);
541
310
  }
542
- } else {
543
- throw new Error("Element is not an HTMLElement");
544
- }
545
- }
311
+ });
312
+ return result;
313
+ },
546
314
  /**
547
- * 绘制线条
315
+ * 异步加载script
548
316
  *
549
- * @param start 起始坐标点
550
- * @param end 终止坐标点
551
- * @param options 绘制选项,包括线条宽度和颜色
552
- * @throws 当画布上下文不存在时抛出错误
317
+ * @param {*} url
553
318
  */
554
- drawLine({ x: startX, y: startY }, { x: endX, y: endY }, options = {}) {
555
- if (!this.context) {
556
- throw new Error("Canvas context is null or undefined");
557
- }
558
- this.context.beginPath();
559
- const width = options.width || 1;
560
- const color = options.color || "#000";
561
- this.context.lineWidth = width;
562
- this.context.strokeStyle = color;
563
- this.context.moveTo(startX, startY);
564
- this.context.lineTo(endX, endY);
565
- this.context.stroke();
566
- }
567
- /**
568
- * 绘制圆弧
569
- *
570
- * @param x 圆心x坐标
571
- * @param y 圆心y坐标
572
- * @param radius 半径
573
- * @param startAngle 起始角度(度)
574
- * @param endAngle 结束角度(度)
575
- * @param anticlockwise 是否逆时针绘制
576
- * @param isFill 是否填充
577
- * @param bgColor 背景颜色
578
- * @throws 当Canvas context为null或undefined时抛出错误
579
- */
580
- drawArc({ x, y }, radius, startAngle, endAngle, anticlockwise, isFill, bgColor) {
581
- if (!this.context) {
582
- throw new Error("Canvas context is null or undefined");
583
- }
584
- if (isFill) {
585
- this.context.fillStyle = bgColor;
586
- this.context.beginPath();
587
- this.context.arc(x, y, radius, MathUtil.deg2Rad(startAngle), MathUtil.deg2Rad(endAngle), anticlockwise);
588
- this.context.fill();
589
- } else {
590
- this.context.strokeStyle = bgColor;
591
- this.context.beginPath();
592
- this.context.arc(x, y, radius, MathUtil.deg2Rad(startAngle), MathUtil.deg2Rad(endAngle), anticlockwise);
593
- this.context.stroke();
594
- }
595
- }
596
- drawImage(src, { x, y }) {
597
- const img = new Image();
598
- img.src = src;
599
- img.onload = () => {
600
- const width = img.width;
601
- const height = img.height;
602
- if (!this.context) {
603
- throw new Error("Canvas context is null");
604
- }
605
- this.context.drawImage(img, x, y, -width / 2, -height / 2);
606
- };
607
- }
608
- static createCanvas(width = 1, height = 1) {
609
- const canvas = document.createElement("canvas");
610
- if (width) {
611
- canvas.width = width;
612
- }
613
- if (height) {
614
- canvas.height = height;
615
- }
616
- return canvas;
617
- }
618
- }
619
- class EventDispatcher {
620
- constructor() {
621
- __publicField(this, "_listeners", {});
622
- __publicField(this, "_mutex", {});
623
- __publicField(this, "_context");
624
- }
625
- addEventListener(type, listener, context, mutexStatus) {
626
- this._context = context;
627
- const mutex = this._mutex;
628
- const listeners = this._listeners;
629
- if (listeners[type] === void 0) {
630
- listeners[type] = [];
631
- }
632
- if (listeners[type].indexOf(listener) === -1) {
633
- if (mutexStatus) {
634
- mutex[type] = listener;
635
- }
636
- listeners[type].push(listener);
637
- }
638
- return this;
639
- }
640
- hasEventListener(type, listener) {
641
- if (this._listeners === null || this._listeners === void 0) return false;
642
- const listeners = this._listeners;
643
- return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1;
644
- }
645
- removeEventListener(type, listener) {
646
- if (this._listeners === void 0) return;
647
- const listeners = this._listeners;
648
- const listenerArray = listeners[type];
649
- if (this._mutex[type] === listener) {
650
- this._mutex[type] = null;
651
- }
652
- if (listenerArray !== void 0) {
653
- const index = listenerArray.map((d) => d.toString()).indexOf(listener.toString());
654
- if (index !== -1) {
655
- listenerArray.splice(index, 1);
656
- }
657
- }
658
- }
659
- dispatchEvent(event) {
660
- if (this._listeners === void 0) return;
661
- const listeners = this._listeners;
662
- const listenerArray = listeners[event.type];
663
- if (listenerArray !== void 0) {
664
- event.target = this;
665
- const array = listenerArray.slice(0);
666
- if (this._mutex[event.type] !== void 0) {
667
- const find = array.find((item) => item === this._mutex[event.type]);
668
- if (find) {
669
- find.call(this._context || this, event);
670
- return;
671
- }
672
- }
673
- for (let i = 0, l = array.length; i < l; i++) {
674
- const item = array[i];
675
- if (typeof item === "function") {
676
- item.call(this._context || this, event);
319
+ asyncLoadScript(url) {
320
+ return new Promise((resolve, reject) => {
321
+ try {
322
+ const oscript = document.createElement("script");
323
+ oscript.type = "text/javascript";
324
+ oscript.src = url;
325
+ if ("readyState" in oscript) {
326
+ oscript.onreadystatechange = function() {
327
+ if (oscript.readyState === "complete" || oscript.readyState === "loaded") {
328
+ resolve(oscript);
329
+ }
330
+ };
331
+ } else {
332
+ oscript.onload = function() {
333
+ resolve(oscript);
334
+ };
335
+ oscript.onerror = function() {
336
+ reject(new Error("Script failed to load for URL: " + url));
337
+ };
677
338
  }
339
+ document.body.appendChild(oscript);
340
+ } catch (error) {
341
+ reject(error);
678
342
  }
679
- }
680
- }
681
- removeAllListener() {
682
- this._mutex = {};
683
- for (const key in this._listeners) {
684
- this._listeners[key] = [];
685
- }
686
- }
687
- }
688
- const Util = {
343
+ });
344
+ },
689
345
  /**
690
- * 获取数据类型
346
+ * 加载样式文件
691
347
  *
692
- * @param data 待判断的数据
693
- * @returns 返回数据类型字符串
348
+ * @param urls 样式文件URL数组
349
+ * @returns 无返回值
694
350
  */
695
- getDataType(data) {
696
- return Object.prototype.toString.call(data).slice(8, -1);
697
- },
698
- asArray(obj) {
699
- return this.isEmpty(obj) ? [] : Array.isArray(obj) ? obj : [obj];
700
- },
701
- asNumber(a) {
702
- return Number.isNaN(Number(a)) ? 0 : Number(a);
351
+ loadStyle(urls) {
352
+ urls.forEach((url) => {
353
+ const css = document.createElement("link");
354
+ css.href = url;
355
+ css.rel = "stylesheet";
356
+ css.type = "text/css";
357
+ css.onerror = function() {
358
+ console.error(`Style loading failed for URL: ${url}`);
359
+ };
360
+ document.head.appendChild(css);
361
+ });
703
362
  },
704
363
  /**
705
- * 将值转换为字符串
364
+ * 将模板字符串中的占位符替换为给定对象中的值
706
365
  *
707
- * @param value 要转换的值
708
- * @returns 转换后的字符串,如果值为空,则返回空字符串
366
+ * @param str 模板字符串
367
+ * @param data 包含替换值的对象
368
+ * @returns 替换后的字符串
369
+ * @throws 当对象中没有找到与占位符对应的值时,抛出错误
709
370
  */
710
- asString(value) {
711
- if (this.isEmpty(value)) {
712
- return "";
713
- } else {
714
- switch (this.getDataType(value)) {
715
- case "Object":
716
- case "Array":
717
- return JSON.stringify(value);
718
- default:
719
- return value;
371
+ template(str, data) {
372
+ const templateRe = /\{ *([\w_-]+) *\}/g;
373
+ return str.replace(templateRe, (match, key) => {
374
+ const value = data[key];
375
+ if (value === void 0) {
376
+ throw new Error(`${ErrorType.JSON_PARSE_ERROR}: ${match}`);
377
+ } else if (typeof value === "function") {
378
+ return value(data);
379
+ } else {
380
+ return value;
720
381
  }
721
- }
382
+ });
722
383
  },
723
384
  /**
724
- * 判断传入的值是否为空
385
+ * 删除对象中所有值为空的属性
725
386
  *
726
- * @param value 待判断的值
727
- * @returns 返回布尔值,表示是否为空
387
+ * @param data 待处理的对象
388
+ * @returns 返回处理后的对象
728
389
  */
729
- isEmpty(value) {
730
- if (value == null) {
731
- return true;
390
+ deleteEmptyProperty(data) {
391
+ return Object.fromEntries(
392
+ Object.keys(data).filter((d) => !this.isEmpty(data[d])).map((i) => [i, data[i]])
393
+ );
394
+ },
395
+ deepAssign(target, ...sources) {
396
+ if (typeof target !== "object" || target === null) {
397
+ target = {};
732
398
  }
733
- const type = this.getDataType(value);
734
- switch (type) {
735
- case "String":
736
- return value.trim() === "";
737
- case "Array":
738
- return !value.length;
739
- case "Object":
740
- return !Object.keys(value).length;
741
- case "Boolean":
742
- return !value;
743
- default:
744
- return false;
399
+ for (const source of sources) {
400
+ if (typeof source === "object" && source !== null) {
401
+ for (const key in source) {
402
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
403
+ if (typeof source[key] === "object" && source[key] !== null) {
404
+ if (!target[key]) {
405
+ target[key] = Array.isArray(source[key]) ? [] : {};
406
+ }
407
+ this.deepAssign(target[key], source[key]);
408
+ } else {
409
+ target[key] = source[key];
410
+ }
411
+ }
412
+ }
413
+ }
745
414
  }
415
+ return target;
746
416
  },
747
417
  /**
748
- * 将JSON对象转换为FormData对象
418
+ * 复制文本到剪贴板
749
419
  *
750
- * @param json 待转换的JSON对象,其属性值为字符串或Blob类型
751
- * @returns 转换后的FormData对象
420
+ * @param text 要复制的文本
421
+ * @returns 返回一个Promise,表示复制操作的结果
752
422
  */
753
- json2form(json) {
754
- const formData = new FormData();
755
- if (this.isEmpty(json)) return formData;
756
- Object.keys(json).forEach((key) => {
757
- formData.append(key, json[key] instanceof Object ? JSON.stringify(json[key]) : json[key]);
758
- });
759
- return formData;
760
- },
761
- /**
762
- * 生成GUID
763
- *
764
- * @returns 返回一个由8个16进制数组成的GUID字符串
423
+ handleCopyValue(text) {
424
+ if (navigator.clipboard && window.isSecureContext) {
425
+ return navigator.clipboard.writeText(text);
426
+ } else {
427
+ const textArea = document.createElement("textarea");
428
+ textArea.style.position = "fixed";
429
+ textArea.style.top = textArea.style.left = "-100vh";
430
+ textArea.style.opacity = "0";
431
+ textArea.value = text;
432
+ document.body.appendChild(textArea);
433
+ textArea.focus();
434
+ textArea.select();
435
+ return new Promise((resolve, reject) => {
436
+ try {
437
+ document.execCommand("copy");
438
+ resolve();
439
+ } catch (error) {
440
+ reject(new Error("copy failed"));
441
+ } finally {
442
+ textArea.remove();
443
+ }
444
+ });
445
+ }
446
+ },
447
+ isArray(a) {
448
+ return Array.isArray(a);
449
+ },
450
+ isObject(a) {
451
+ return typeof a === "object" && a !== null;
452
+ },
453
+ isNil(a) {
454
+ return a === void 0 || a === "undefined" || a === null || a === "null";
455
+ },
456
+ isNumber(a) {
457
+ return typeof a === "number" && !isNaN(a) || typeof a === "string" && Number.isFinite(+a);
458
+ },
459
+ isInteger(a) {
460
+ return parseInt(a) === a;
461
+ },
462
+ isFunction(obj) {
463
+ if (this.isNil(obj)) {
464
+ return false;
465
+ }
466
+ return typeof obj === "function" || obj.constructor !== null && obj.constructor === Function;
467
+ },
468
+ /**
469
+ * 判断传入参数是否为DOM元素
470
+ *
471
+ * @param a 待判断的参数
472
+ * @returns 返回布尔值,表示是否为DOM元素
765
473
  */
766
- guid() {
767
- const S4 = function() {
768
- return ((1 + Math.random()) * 65536 | 0).toString(16).substring(1);
769
- };
770
- return S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4();
474
+ isElement(a) {
475
+ return typeof a === "object" && a.nodeType === 1;
771
476
  },
772
477
  /**
773
- * 将参数进行解码并返回解码后的字符串
478
+ * 检查版本
774
479
  *
775
- * @param args 参数
776
- * @returns 解码后的字符串
480
+ * @param currentV 当前版本号
481
+ * @param targetV 要求版本号
482
+ * @returns 返回布尔值,表示当前版本是否需要升级到目标版本
777
483
  */
778
- decodeDict(...args) {
779
- let res = "";
780
- if (args.length > 1) {
781
- const items = args.slice(1, args.length % 2 === 0 ? args.length - 1 : args.length);
782
- for (let i = 0; i < items.length; i = i + 2) {
783
- const item = items[i];
784
- if (args[0] === item) {
785
- res = items[i + 1];
786
- }
787
- }
788
- if (!res && args.length % 2 === 0) {
789
- res = args[args.length - 1];
790
- }
791
- } else {
792
- res = args[0];
793
- }
794
- return res;
484
+ checheVersion(currentV, targetV) {
485
+ var numC = currentV.replace(/[^0-9]/gi, "");
486
+ var numT = targetV.replace(/[^0-9]/gi, "");
487
+ return numC < numT;
488
+ }
489
+ };
490
+ const MathUtil = {
491
+ DEG2RAD: Math.PI / 180,
492
+ RAD2DEG: 180 / Math.PI,
493
+ randInt(low, high) {
494
+ return low + Math.floor(Math.random() * (high - low + 1));
495
+ },
496
+ randFloat(low, high) {
497
+ return low + Math.random() * (high - low);
795
498
  },
796
499
  /**
797
- * 将一个或多个对象的所有可枚举属性复制到目标对象。
500
+ * 角度转弧度
798
501
  *
799
- * @param dest 目标对象,用于接收复制的属性。
800
- * @param args 一个或多个源对象,用于提供要复制的属性。
801
- * @returns 返回目标对象,包含所有复制的属性。
502
+ * @param {*} degrees
503
+ * @returns {*}
802
504
  */
803
- extend(dest, ...args) {
804
- let i, j, len, src;
805
- for (j = 0, len = args.length; j < len; j++) {
806
- src = args[j];
807
- for (i in src) {
808
- dest[i] = src[i];
809
- }
810
- }
811
- return dest;
505
+ deg2Rad(degrees) {
506
+ return degrees * this.DEG2RAD;
812
507
  },
813
508
  /**
814
- * 将扁平化数组转换为树形结构数组
509
+ * 弧度转角度
815
510
  *
816
- * @param data 扁平化数组
817
- * @param idPropertyName 数据中标识id的字段名,默认为'id'
818
- * @param parentIdPropertyName 数据中标识父节点id的字段名,默认为'parentId'
819
- * @param childrenPropertyName 树形结构中标识子节点的字段名,默认为'children'
820
- * @returns 转换后的树形结构数组
511
+ * @param {*} radians
512
+ * @returns {*}
821
513
  */
822
- convertToTree2(data, idPropertyName = "id", parentIdPropertyName = "parentId", childrenPropertyName = "children") {
823
- const result = [];
824
- function buildChildren(item) {
825
- const children = data.filter((item2) => item2[parentIdPropertyName] === item[idPropertyName]).map((child) => {
826
- if (!result.some((r) => r[idPropertyName] === child[idPropertyName])) {
827
- buildChildren(child);
828
- }
829
- return child;
830
- });
831
- if (children.length > 0) {
832
- item[childrenPropertyName] = children;
833
- }
834
- }
835
- data.forEach((item) => {
836
- if (!data.some((other) => other[parentIdPropertyName] === item[idPropertyName])) {
837
- buildChildren(item);
838
- result.push(item);
839
- }
840
- });
841
- return result;
514
+ rad2Deg(radians) {
515
+ return radians * this.RAD2DEG;
842
516
  },
517
+ round(value, n = 2) {
518
+ return Util.isNumber(value) ? Math.round(Number(value) * Math.pow(10, n)) / Math.pow(10, n) : 0;
519
+ },
520
+ /**
521
+ * 将数值限制在指定范围内
522
+ *
523
+ * @param val 需要限制的数值
524
+ * @param min 最小值
525
+ * @param max 最大值
526
+ * @returns 返回限制后的数值
527
+ */
528
+ clamp(val, min, max) {
529
+ return Math.max(min, Math.min(max, val));
530
+ }
531
+ };
532
+ const ColorName = {
533
+ aliceblue: [240, 248, 255],
534
+ antiquewhite: [250, 235, 215],
535
+ aqua: [0, 255, 255],
536
+ aquamarine: [127, 255, 212],
537
+ azure: [240, 255, 255],
538
+ beige: [245, 245, 220],
539
+ bisque: [255, 228, 196],
540
+ black: [0, 0, 0],
541
+ blanchedalmond: [255, 235, 205],
542
+ blue: [0, 0, 255],
543
+ blueviolet: [138, 43, 226],
544
+ brown: [165, 42, 42],
545
+ burlywood: [222, 184, 135],
546
+ cadetblue: [95, 158, 160],
547
+ chartreuse: [127, 255, 0],
548
+ chocolate: [210, 105, 30],
549
+ coral: [255, 127, 80],
550
+ cornflowerblue: [100, 149, 237],
551
+ cornsilk: [255, 248, 220],
552
+ crimson: [220, 20, 60],
553
+ cyan: [0, 255, 255],
554
+ darkblue: [0, 0, 139],
555
+ darkcyan: [0, 139, 139],
556
+ darkgoldenrod: [184, 134, 11],
557
+ darkgray: [169, 169, 169],
558
+ darkgreen: [0, 100, 0],
559
+ darkgrey: [169, 169, 169],
560
+ darkkhaki: [189, 183, 107],
561
+ darkmagenta: [139, 0, 139],
562
+ darkolivegreen: [85, 107, 47],
563
+ darkorange: [255, 140, 0],
564
+ darkorchid: [153, 50, 204],
565
+ darkred: [139, 0, 0],
566
+ darksalmon: [233, 150, 122],
567
+ darkseagreen: [143, 188, 143],
568
+ darkslateblue: [72, 61, 139],
569
+ darkslategray: [47, 79, 79],
570
+ darkslategrey: [47, 79, 79],
571
+ darkturquoise: [0, 206, 209],
572
+ darkviolet: [148, 0, 211],
573
+ deeppink: [255, 20, 147],
574
+ deepskyblue: [0, 191, 255],
575
+ dimgray: [105, 105, 105],
576
+ dimgrey: [105, 105, 105],
577
+ dodgerblue: [30, 144, 255],
578
+ firebrick: [178, 34, 34],
579
+ floralwhite: [255, 250, 240],
580
+ forestgreen: [34, 139, 34],
581
+ fuchsia: [255, 0, 255],
582
+ gainsboro: [220, 220, 220],
583
+ ghostwhite: [248, 248, 255],
584
+ gold: [255, 215, 0],
585
+ goldenrod: [218, 165, 32],
586
+ gray: [128, 128, 128],
587
+ green: [0, 128, 0],
588
+ greenyellow: [173, 255, 47],
589
+ grey: [128, 128, 128],
590
+ honeydew: [240, 255, 240],
591
+ hotpink: [255, 105, 180],
592
+ indianred: [205, 92, 92],
593
+ indigo: [75, 0, 130],
594
+ ivory: [255, 255, 240],
595
+ khaki: [240, 230, 140],
596
+ lavender: [230, 230, 250],
597
+ lavenderblush: [255, 240, 245],
598
+ lawngreen: [124, 252, 0],
599
+ lemonchiffon: [255, 250, 205],
600
+ lightblue: [173, 216, 230],
601
+ lightcoral: [240, 128, 128],
602
+ lightcyan: [224, 255, 255],
603
+ lightgoldenrodyellow: [250, 250, 210],
604
+ lightgray: [211, 211, 211],
605
+ lightgreen: [144, 238, 144],
606
+ lightgrey: [211, 211, 211],
607
+ lightpink: [255, 182, 193],
608
+ lightsalmon: [255, 160, 122],
609
+ lightseagreen: [32, 178, 170],
610
+ lightskyblue: [135, 206, 250],
611
+ lightslategray: [119, 136, 153],
612
+ lightslategrey: [119, 136, 153],
613
+ lightsteelblue: [176, 196, 222],
614
+ lightyellow: [255, 255, 224],
615
+ lime: [0, 255, 0],
616
+ limegreen: [50, 205, 50],
617
+ linen: [250, 240, 230],
618
+ magenta: [255, 0, 255],
619
+ maroon: [128, 0, 0],
620
+ mediumaquamarine: [102, 205, 170],
621
+ mediumblue: [0, 0, 205],
622
+ mediumorchid: [186, 85, 211],
623
+ mediumpurple: [147, 112, 219],
624
+ mediumseagreen: [60, 179, 113],
625
+ mediumslateblue: [123, 104, 238],
626
+ mediumspringgreen: [0, 250, 154],
627
+ mediumturquoise: [72, 209, 204],
628
+ mediumvioletred: [199, 21, 133],
629
+ midnightblue: [25, 25, 112],
630
+ mintcream: [245, 255, 250],
631
+ mistyrose: [255, 228, 225],
632
+ moccasin: [255, 228, 181],
633
+ navajowhite: [255, 222, 173],
634
+ navy: [0, 0, 128],
635
+ oldlace: [253, 245, 230],
636
+ olive: [128, 128, 0],
637
+ olivedrab: [107, 142, 35],
638
+ orange: [255, 165, 0],
639
+ orangered: [255, 69, 0],
640
+ orchid: [218, 112, 214],
641
+ palegoldenrod: [238, 232, 170],
642
+ palegreen: [152, 251, 152],
643
+ paleturquoise: [175, 238, 238],
644
+ palevioletred: [219, 112, 147],
645
+ papayawhip: [255, 239, 213],
646
+ peachpuff: [255, 218, 185],
647
+ peru: [205, 133, 63],
648
+ pink: [255, 192, 203],
649
+ plum: [221, 160, 221],
650
+ powderblue: [176, 224, 230],
651
+ purple: [128, 0, 128],
652
+ rebeccapurple: [102, 51, 153],
653
+ red: [255, 0, 0],
654
+ rosybrown: [188, 143, 143],
655
+ royalblue: [65, 105, 225],
656
+ saddlebrown: [139, 69, 19],
657
+ salmon: [250, 128, 114],
658
+ sandybrown: [244, 164, 96],
659
+ seagreen: [46, 139, 87],
660
+ seashell: [255, 245, 238],
661
+ sienna: [160, 82, 45],
662
+ silver: [192, 192, 192],
663
+ skyblue: [135, 206, 235],
664
+ slateblue: [106, 90, 205],
665
+ slategray: [112, 128, 144],
666
+ slategrey: [112, 128, 144],
667
+ snow: [255, 250, 250],
668
+ springgreen: [0, 255, 127],
669
+ steelblue: [70, 130, 180],
670
+ tan: [210, 180, 140],
671
+ teal: [0, 128, 128],
672
+ thistle: [216, 191, 216],
673
+ tomato: [255, 99, 71],
674
+ turquoise: [64, 224, 208],
675
+ violet: [238, 130, 238],
676
+ wheat: [245, 222, 179],
677
+ white: [255, 255, 255],
678
+ whitesmoke: [245, 245, 245],
679
+ yellow: [255, 255, 0],
680
+ yellowgreen: [154, 205, 50]
681
+ };
682
+ class Color {
683
+ constructor(r, g, b, a) {
684
+ __publicField(this, "_r");
685
+ __publicField(this, "_g");
686
+ __publicField(this, "_b");
687
+ __publicField(this, "_alpha");
688
+ this._validateColorChannel(r);
689
+ this._validateColorChannel(g);
690
+ this._validateColorChannel(b);
691
+ this._r = r;
692
+ this._g = g;
693
+ this._b = b;
694
+ this._alpha = MathUtil.clamp(a || 1, 0, 1);
695
+ }
696
+ _validateColorChannel(channel) {
697
+ if (channel < 0 || channel > 255) {
698
+ throw new Error("Color channel must be between 0 and 255.");
699
+ }
700
+ }
701
+ toString() {
702
+ return `rgba(${this._r}, ${this._g}, ${this._b}, ${this._alpha})`;
703
+ }
704
+ toJson() {
705
+ return { r: this._r, g: this._g, b: this._b, a: this._alpha };
706
+ }
707
+ get rgba() {
708
+ return `rgba(${this._r}, ${this._g}, ${this._b}, ${this._alpha})`;
709
+ }
710
+ get hex() {
711
+ return Color.rgb2hex(this._r, this._g, this._b, this._alpha);
712
+ }
713
+ setAlpha(a) {
714
+ this._alpha = MathUtil.clamp(a, 0, 1);
715
+ return this;
716
+ }
717
+ // 设置颜色的RGB值
718
+ setRgb(r, g, b) {
719
+ this._validateColorChannel(r);
720
+ this._validateColorChannel(g);
721
+ this._validateColorChannel(b);
722
+ this._r = r;
723
+ this._g = g;
724
+ this._b = b;
725
+ return this;
726
+ }
843
727
  /**
844
- * 异步加载script
728
+ * 从RGBA字符串创建Color对象
845
729
  *
846
- * @param {*} url
730
+ * @param rgbaValue RGBA颜色值字符串,格式为"rgba(r,g,b,a)"或"rgb(r,g,b)"
731
+ * @returns 返回Color对象
732
+ * @throws 如果rgbaValue不是有效的RGBA颜色值,则抛出错误
847
733
  */
848
- asyncLoadScript(url) {
849
- return new Promise((resolve, reject) => {
850
- try {
851
- const oscript = document.createElement("script");
852
- oscript.type = "text/javascript";
853
- oscript.src = url;
854
- if ("readyState" in oscript) {
855
- oscript.onreadystatechange = function() {
856
- if (oscript.readyState === "complete" || oscript.readyState === "loaded") {
857
- resolve(oscript);
858
- }
859
- };
860
- } else {
861
- oscript.onload = function() {
862
- resolve(oscript);
863
- };
864
- oscript.onerror = function() {
865
- reject(new Error("Script failed to load for URL: " + url));
866
- };
867
- }
868
- document.body.appendChild(oscript);
869
- } catch (error) {
870
- reject(error);
871
- }
872
- });
873
- },
734
+ static fromRgba(rgbaValue) {
735
+ const rgbaMatch = rgbaValue.match(/^rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.]+))?\s*\)$/);
736
+ if (!rgbaMatch) throw new Error("Invalid RGBA color value");
737
+ const r = parseInt(rgbaMatch[1], 10);
738
+ const g = parseInt(rgbaMatch[2], 10);
739
+ const b = parseInt(rgbaMatch[3], 10);
740
+ const a = rgbaMatch[5] ? parseFloat(rgbaMatch[5]) : 1;
741
+ return new Color(r, g, b, a);
742
+ }
874
743
  /**
875
- * 加载样式文件
744
+ * 将十六进制颜色值转换为颜色对象
876
745
  *
877
- * @param urls 样式文件URL数组
878
- * @returns 无返回值
746
+ * @param hexValue 十六进制颜色值,可带或不带#前缀,支持3位和6位表示
747
+ * @returns 返回颜色对象
879
748
  */
880
- loadStyle(urls) {
881
- urls.forEach((url) => {
882
- const css = document.createElement("link");
883
- css.href = url;
884
- css.rel = "stylesheet";
885
- css.type = "text/css";
886
- css.onerror = function() {
887
- console.error(`Style loading failed for URL: ${url}`);
888
- };
889
- document.head.appendChild(css);
890
- });
891
- },
749
+ static fromHex(hexValue, a = 1) {
750
+ const rgxShort = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
751
+ const hex = hexValue.replace(rgxShort, (m, r2, g2, b2) => r2 + r2 + g2 + g2 + b2 + b2);
752
+ const rgx = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
753
+ const rgb = rgx.exec(hex);
754
+ if (!rgb) {
755
+ throw new Error("Invalid HEX color value");
756
+ }
757
+ const r = parseInt(rgb[1], 16);
758
+ const g = parseInt(rgb[2], 16);
759
+ const b = parseInt(rgb[3], 16);
760
+ return new Color(r, g, b, a);
761
+ }
892
762
  /**
893
- * 将模板字符串中的占位符替换为给定对象中的值
763
+ * 从 HSL 字符串创建颜色对象
894
764
  *
895
- * @param str 模板字符串
896
- * @param data 包含替换值的对象
897
- * @returns 替换后的字符串
898
- * @throws 当对象中没有找到与占位符对应的值时,抛出错误
765
+ * @param hsl HSL 字符串,格式为 hsl(h, s%, l%) 或 hsla(h, s%, l%, a)
766
+ * @returns 返回颜色对象,如果 hsl 字符串无效则返回 null
899
767
  */
900
- template(str, data) {
901
- const templateRe = /\{ *([\w_-]+) *\}/g;
902
- return str.replace(templateRe, (match, key) => {
903
- const value = data[key];
904
- if (value === void 0) {
905
- throw new Error(`${ErrorType.JSON_PARSE_ERROR}: ${match}`);
906
- } else if (typeof value === "function") {
907
- return value(data);
908
- } else {
909
- return value;
910
- }
911
- });
912
- },
768
+ static fromHsl(hslValue) {
769
+ const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue) || /hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec(hslValue);
770
+ if (!hsl) {
771
+ throw new Error("Invalid HSL color value");
772
+ }
773
+ const h = parseInt(hsl[1], 10) / 360;
774
+ const s = parseInt(hsl[2], 10) / 100;
775
+ const l = parseInt(hsl[3], 10) / 100;
776
+ const a = hsl[4] ? parseFloat(hsl[4]) : 1;
777
+ function hue2rgb(p, q, t) {
778
+ if (t < 0) t += 1;
779
+ if (t > 1) t -= 1;
780
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
781
+ if (t < 1 / 2) return q;
782
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
783
+ return p;
784
+ }
785
+ let r, g, b;
786
+ if (s === 0) {
787
+ r = g = b = l;
788
+ } else {
789
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
790
+ const p = 2 * l - q;
791
+ r = hue2rgb(p, q, h + 1 / 3);
792
+ g = hue2rgb(p, q, h);
793
+ b = hue2rgb(p, q, h - 1 / 3);
794
+ }
795
+ return new Color(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a);
796
+ }
797
+ static fromName(str) {
798
+ const rgba = ColorName[str];
799
+ if (!rgba) {
800
+ throw new Error(`Invalid color name: ${str}`);
801
+ }
802
+ return new Color(rgba[0], rgba[1], rgba[2], rgba.length > 3 ? rgba[3] : 1);
803
+ }
913
804
  /**
914
- * 删除对象中所有值为空的属性
805
+ * 从字符串中创建颜色对象
915
806
  *
916
- * @param data 待处理的对象
917
- * @returns 返回处理后的对象
807
+ * @param str 字符串类型的颜色值,支持rgba、hex、hsl格式
808
+ * @returns 返回创建的颜色对象
809
+ * @throws 当颜色值无效时,抛出错误
918
810
  */
919
- deleteEmptyProperty(data) {
920
- return Object.fromEntries(
921
- Object.keys(data).filter((d) => !this.isEmpty(data[d])).map((i) => [i, data[i]])
922
- );
923
- },
924
- deepAssign(target, ...sources) {
925
- if (typeof target !== "object" || target === null) {
926
- target = {};
927
- }
928
- for (const source of sources) {
929
- if (typeof source === "object" && source !== null) {
930
- for (const key in source) {
931
- if (Object.prototype.hasOwnProperty.call(source, key)) {
932
- if (typeof source[key] === "object" && source[key] !== null) {
933
- if (!target[key]) {
934
- target[key] = Array.isArray(source[key]) ? [] : {};
935
- }
936
- this.deepAssign(target[key], source[key]);
937
- } else {
938
- target[key] = source[key];
939
- }
940
- }
941
- }
942
- }
811
+ static from(str) {
812
+ if (this.isRgb(str)) {
813
+ return this.fromRgba(str);
814
+ } else if (this.isHex(str)) {
815
+ return this.fromHex(str);
816
+ } else if (this.isHsl(str)) {
817
+ return this.fromHsl(str);
818
+ } else if (Object.keys(ColorName).map((key) => key.toString()).includes(str)) {
819
+ return this.fromName(str);
820
+ } else {
821
+ throw new Error("Invalid color value");
943
822
  }
944
- return target;
945
- },
823
+ }
946
824
  /**
947
- * 复制文本到剪贴板
825
+ * 将RGB颜色值转换为十六进制颜色值
948
826
  *
949
- * @param text 要复制的文本
950
- * @returns 返回一个Promise,表示复制操作的结果
827
+ * @param r 红色分量值,取值范围0-255
828
+ * @param g 绿色分量值,取值范围0-255
829
+ * @param b 蓝色分量值,取值范围0-255
830
+ * @param a 可选参数,透明度分量值,取值范围0-1
831
+ * @returns 十六进制颜色值,格式为#RRGGBB或#RRGGBBAA
951
832
  */
952
- handleCopyValue(text) {
953
- if (navigator.clipboard && window.isSecureContext) {
954
- return navigator.clipboard.writeText(text);
955
- } else {
956
- const textArea = document.createElement("textarea");
957
- textArea.style.position = "fixed";
958
- textArea.style.top = textArea.style.left = "-100vh";
959
- textArea.style.opacity = "0";
960
- textArea.value = text;
961
- document.body.appendChild(textArea);
962
- textArea.focus();
963
- textArea.select();
964
- return new Promise((resolve, reject) => {
965
- try {
966
- document.execCommand("copy");
967
- resolve();
968
- } catch (error) {
969
- reject(new Error("copy failed"));
970
- } finally {
971
- textArea.remove();
972
- }
973
- });
833
+ static rgb2hex(r, g, b, a) {
834
+ var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
835
+ if (a !== void 0) {
836
+ const alpha = Math.round(a * 255).toString(16).padStart(2, "0");
837
+ return hex + alpha;
974
838
  }
975
- },
976
- isArray(a) {
977
- return Array.isArray(a);
978
- },
979
- isObject(a) {
980
- return typeof a === "object" && a !== null;
981
- },
982
- isNil(a) {
983
- return a === void 0 || a === "undefined" || a === null || a === "null";
984
- },
985
- isNumber(a) {
986
- return typeof a === "number" && !isNaN(a) || typeof a === "string" && Number.isFinite(+a);
987
- },
988
- isInteger(a) {
989
- return parseInt(a) === a;
990
- },
991
- isFunction(obj) {
992
- if (this.isNil(obj)) {
993
- return false;
839
+ return hex;
840
+ }
841
+ static isHex(a) {
842
+ return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a);
843
+ }
844
+ static isRgb(a) {
845
+ return /^rgba?\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*[\d.]+)?\s*\)$/.test(a);
846
+ }
847
+ static isHsl(a) {
848
+ return /^(hsl|hsla)\(\d+,\s*[\d.]+%,\s*[\d.]+%(,\s*[\d.]+)?\)$/.test(a);
849
+ }
850
+ static isColor(a) {
851
+ return this.isHex(a) || this.isRgb(a) || this.isHsl(a);
852
+ }
853
+ static random() {
854
+ let r = Math.floor(Math.random() * 256);
855
+ let g = Math.floor(Math.random() * 256);
856
+ let b = Math.floor(Math.random() * 256);
857
+ let a = Math.random();
858
+ return new Color(r, g, b, a);
859
+ }
860
+ }
861
+ class CanvasDrawer {
862
+ constructor(el) {
863
+ __publicField(this, "context", null);
864
+ if (typeof el === "string") {
865
+ el = document.querySelector("#" + el);
866
+ if (!el) {
867
+ throw new Error("Element not found");
868
+ }
994
869
  }
995
- return typeof obj === "function" || obj.constructor !== null && obj.constructor === Function;
996
- },
870
+ if (el instanceof HTMLElement) {
871
+ const canvas = el;
872
+ if (canvas.getContext) {
873
+ this.context = canvas.getContext("2d");
874
+ } else {
875
+ throw new Error("getContext is not available on this element");
876
+ }
877
+ } else {
878
+ throw new Error("Element is not an HTMLElement");
879
+ }
880
+ }
997
881
  /**
998
- * 判断传入参数是否为DOM元素
882
+ * 绘制线条
999
883
  *
1000
- * @param a 待判断的参数
1001
- * @returns 返回布尔值,表示是否为DOM元素
884
+ * @param start 起始坐标点
885
+ * @param end 终止坐标点
886
+ * @param options 绘制选项,包括线条宽度和颜色
887
+ * @throws 当画布上下文不存在时抛出错误
1002
888
  */
1003
- isElement(a) {
1004
- return typeof a === "object" && a.nodeType === 1;
1005
- },
889
+ drawLine({ x: startX, y: startY }, { x: endX, y: endY }, options = {}) {
890
+ if (!this.context) {
891
+ throw new Error("Canvas context is null or undefined");
892
+ }
893
+ this.context.beginPath();
894
+ const width = options.width || 1;
895
+ const color = options.color || "#000";
896
+ this.context.lineWidth = width;
897
+ this.context.strokeStyle = color;
898
+ this.context.moveTo(startX, startY);
899
+ this.context.lineTo(endX, endY);
900
+ this.context.stroke();
901
+ }
1006
902
  /**
1007
- * 检查版本
903
+ * 绘制圆弧
1008
904
  *
1009
- * @param currentV 当前版本号
1010
- * @param targetV 要求版本号
1011
- * @returns 返回布尔值,表示当前版本是否需要升级到目标版本
905
+ * @param x 圆心x坐标
906
+ * @param y 圆心y坐标
907
+ * @param radius 半径
908
+ * @param startAngle 起始角度(度)
909
+ * @param endAngle 结束角度(度)
910
+ * @param anticlockwise 是否逆时针绘制
911
+ * @param isFill 是否填充
912
+ * @param bgColor 背景颜色
913
+ * @throws 当Canvas context为null或undefined时抛出错误
1012
914
  */
1013
- checheVersion(currentV, targetV) {
1014
- var numC = currentV.replace(/[^0-9]/gi, "");
1015
- var numT = targetV.replace(/[^0-9]/gi, "");
1016
- return numC < numT;
915
+ drawArc({ x, y }, radius, startAngle, endAngle, anticlockwise, isFill, bgColor) {
916
+ if (!this.context) {
917
+ throw new Error("Canvas context is null or undefined");
918
+ }
919
+ if (isFill) {
920
+ this.context.fillStyle = bgColor;
921
+ this.context.beginPath();
922
+ this.context.arc(x, y, radius, MathUtil.deg2Rad(startAngle), MathUtil.deg2Rad(endAngle), anticlockwise);
923
+ this.context.fill();
924
+ } else {
925
+ this.context.strokeStyle = bgColor;
926
+ this.context.beginPath();
927
+ this.context.arc(x, y, radius, MathUtil.deg2Rad(startAngle), MathUtil.deg2Rad(endAngle), anticlockwise);
928
+ this.context.stroke();
929
+ }
1017
930
  }
1018
- };
931
+ drawImage(src, { x, y }) {
932
+ const img = new Image();
933
+ img.src = src;
934
+ img.onload = () => {
935
+ const width = img.width;
936
+ const height = img.height;
937
+ if (!this.context) {
938
+ throw new Error("Canvas context is null");
939
+ }
940
+ this.context.drawImage(img, x, y, -width / 2, -height / 2);
941
+ };
942
+ }
943
+ static createCanvas(width = 1, height = 1) {
944
+ const canvas = document.createElement("canvas");
945
+ if (width) {
946
+ canvas.width = width;
947
+ }
948
+ if (height) {
949
+ canvas.height = height;
950
+ }
951
+ return canvas;
952
+ }
953
+ }
954
+ class EventDispatcher {
955
+ constructor() {
956
+ __publicField(this, "_listeners", {});
957
+ __publicField(this, "_mutex", {});
958
+ __publicField(this, "_context");
959
+ }
960
+ addEventListener(type, listener, context, mutexStatus) {
961
+ this._context = context;
962
+ const mutex = this._mutex;
963
+ const listeners = this._listeners;
964
+ if (listeners[type] === void 0) {
965
+ listeners[type] = [];
966
+ }
967
+ if (listeners[type].indexOf(listener) === -1) {
968
+ if (mutexStatus) {
969
+ mutex[type] = listener;
970
+ }
971
+ listeners[type].push(listener);
972
+ }
973
+ return this;
974
+ }
975
+ hasEventListener(type, listener) {
976
+ if (this._listeners === null || this._listeners === void 0) return false;
977
+ const listeners = this._listeners;
978
+ return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1;
979
+ }
980
+ removeEventListener(type, listener) {
981
+ if (this._listeners === void 0) return;
982
+ const listeners = this._listeners;
983
+ const listenerArray = listeners[type];
984
+ if (this._mutex[type] === listener) {
985
+ this._mutex[type] = null;
986
+ }
987
+ if (listenerArray !== void 0) {
988
+ const index = listenerArray.map((d) => d.toString()).indexOf(listener.toString());
989
+ if (index !== -1) {
990
+ listenerArray.splice(index, 1);
991
+ }
992
+ }
993
+ }
994
+ dispatchEvent(event) {
995
+ if (this._listeners === void 0) return;
996
+ const listeners = this._listeners;
997
+ const listenerArray = listeners[event.type];
998
+ if (listenerArray !== void 0) {
999
+ event.target = this;
1000
+ const array = listenerArray.slice(0);
1001
+ if (this._mutex[event.type] !== void 0) {
1002
+ const find = array.find((item) => item === this._mutex[event.type]);
1003
+ if (find) {
1004
+ find.call(this._context || this, event);
1005
+ return;
1006
+ }
1007
+ }
1008
+ for (let i = 0, l = array.length; i < l; i++) {
1009
+ const item = array[i];
1010
+ if (typeof item === "function") {
1011
+ item.call(this._context || this, event);
1012
+ }
1013
+ }
1014
+ }
1015
+ }
1016
+ removeAllListener() {
1017
+ this._mutex = {};
1018
+ for (const key in this._listeners) {
1019
+ this._listeners[key] = [];
1020
+ }
1021
+ }
1022
+ on(type, listener, context, mutexStatus) {
1023
+ return this.addEventListener.call(this, type, listener, context, mutexStatus);
1024
+ }
1025
+ off(type, listener) {
1026
+ return this.removeEventListener.call(this, type, listener);
1027
+ }
1028
+ }
1019
1029
  const ObjectUtil = {
1020
1030
  deepClone(a) {
1021
1031
  return structuredClone(a);
@@ -1024,9 +1034,13 @@ const ObjectUtil = {
1024
1034
  return JSON.stringify(a) === JSON.stringify(b);
1025
1035
  },
1026
1036
  parse(str) {
1027
- if (typeof str === "string" && str.startsWith("{") && str.endsWith("}")) return JSON.parse(str);
1028
- if (Util.isEmpty(str)) return {};
1029
- if (Util.isObject(str)) return str;
1037
+ try {
1038
+ if (typeof str === "string" && str.startsWith("{") && str.endsWith("}")) return JSON.parse(str);
1039
+ if (Util.isEmpty(str)) return {};
1040
+ if (Util.isObject(str)) return str;
1041
+ } catch (error) {
1042
+ throw new Error(ErrorType.JSON_PARSE_ERROR + " -> " + str);
1043
+ }
1030
1044
  }
1031
1045
  };
1032
1046
  class HashMap extends Map {
@@ -1086,10 +1100,10 @@ class WebSocketClient extends EventDispatcher {
1086
1100
  this.disconnect();
1087
1101
  if (this.url) {
1088
1102
  try {
1103
+ const self = this;
1089
1104
  console.info("创建ws连接>>>" + this.url);
1090
1105
  this.client = new WebSocket(this.url);
1091
1106
  if (this.client) {
1092
- const self = this;
1093
1107
  this.client.onopen = function(message) {
1094
1108
  self.dispatchEvent({
1095
1109
  type: EventType.WEB_SOCKET_CONNECT,
@@ -1138,14 +1152,14 @@ class WebSocketClient extends EventDispatcher {
1138
1152
  if (this.checkTimes > times) return;
1139
1153
  setTimeout(() => {
1140
1154
  this.checkTimes++;
1141
- if (this.client && this.client.readyState !== 0 && this.client.readyState !== 1) {
1155
+ if (this.state !== WebSocket.CONNECTING && this.state !== WebSocket.OPEN) {
1142
1156
  this.connect();
1143
1157
  }
1144
1158
  this.connCheckStatus(times);
1145
1159
  }, 2e3);
1146
1160
  }
1147
1161
  send(message) {
1148
- if (this.client && this.client.readyState === 1) {
1162
+ if (this.client && this.state === WebSocket.OPEN) {
1149
1163
  this.client.send(message);
1150
1164
  return true;
1151
1165
  }
@@ -1154,13 +1168,17 @@ class WebSocketClient extends EventDispatcher {
1154
1168
  }
1155
1169
  heartbeat() {
1156
1170
  setTimeout(() => {
1157
- if (this.client && this.client.readyState === 1) {
1171
+ if (this.state === WebSocket.OPEN) {
1158
1172
  this.send("HeartBeat");
1159
1173
  }
1160
1174
  console.log("HeartBeat," + this.url);
1161
1175
  setTimeout(this.heartbeat, 3e4);
1162
1176
  }, 1e3);
1163
1177
  }
1178
+ get state() {
1179
+ var _a2;
1180
+ return (_a2 = this.client) == null ? void 0 : _a2.readyState;
1181
+ }
1164
1182
  }
1165
1183
  const ImageUtil = {
1166
1184
  emptyImageUrl: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
@@ -1752,205 +1770,23 @@ class GeoUtil {
1752
1770
  const x = lng * Math.PI / 180 * earthRad;
1753
1771
  var a = lat * Math.PI / 180;
1754
1772
  const y = earthRad / 2 * Math.log((1 + Math.sin(a)) / (1 - Math.sin(a)));
1755
- return { x, y };
1756
- }
1757
- /**
1758
- * 根据百分比获取坐标
1759
- *
1760
- * @param start 起点坐标
1761
- * @param end 终点坐标
1762
- * @param percent 百分比,取值范围0-1
1763
- * @returns 返回插值后的坐标
1764
- */
1765
- static interpolate({ x: x1, y: y1, z: z1 = 0 }, { x: x2, y: y2, z: z2 = 0 }, percent) {
1766
- const dx = x2 - x1, dy = y2 - y1, dz = z2 - z1;
1767
- return { x: x1 + dx * percent, y: y1 + dy * percent, z: z1 + dz * percent };
1768
- }
1769
- }
1770
- __publicField(GeoUtil, "toRadian", Math.PI / 180);
1771
- __publicField(GeoUtil, "R", 6371393);
1772
- const StringUtil = {
1773
- /**
1774
- * 校验字符串是否符合指定类型
1775
- *
1776
- * @param str 待校验字符串
1777
- * @param type 校验类型,可选值包括:
1778
- * - 'phone': 手机号码
1779
- * - 'tel': 座机
1780
- * - 'card': 身份证
1781
- * - 'pwd': 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
1782
- * - 'postal': 邮政编码
1783
- * - 'QQ': QQ号
1784
- * - 'email': 邮箱
1785
- * - 'money': 金额(小数点2位)
1786
- * - 'URL': 网址
1787
- * - 'IP': IP地址
1788
- * - 'date': 日期时间
1789
- * - 'number': 数字
1790
- * - 'english': 英文
1791
- * - 'chinese': 中文
1792
- * - 'lower': 小写字母
1793
- * - 'upper': 大写字母
1794
- * - 'HTML': HTML标记
1795
- * @returns 校验结果,符合返回true,否则返回false
1796
- */
1797
- checkStr(str, type) {
1798
- switch (type) {
1799
- case "phone":
1800
- return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
1801
- case "tel":
1802
- return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
1803
- case "card":
1804
- return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
1805
- case "pwd":
1806
- return /^[a-zA-Z]\w{5,17}$/.test(str);
1807
- case "postal":
1808
- return /[1-9]\d{5}(?!\d)/.test(str);
1809
- case "QQ":
1810
- return /^[1-9][0-9]{4,9}$/.test(str);
1811
- case "email":
1812
- return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
1813
- case "money":
1814
- return /^\d*(?:\.\d{0,2})?$/.test(str);
1815
- case "URL":
1816
- return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str);
1817
- case "IP":
1818
- return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str);
1819
- case "date":
1820
- return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) || /^(\d{4})\-(\d{2})\-(\d{2})$/.test(str);
1821
- case "number":
1822
- return /^[0-9]$/.test(str);
1823
- case "english":
1824
- return /^[a-zA-Z]+$/.test(str);
1825
- case "chinese":
1826
- return /^[\u4E00-\u9FA5]+$/.test(str);
1827
- case "lower":
1828
- return /^[a-z]+$/.test(str);
1829
- case "upper":
1830
- return /^[A-Z]+$/.test(str);
1831
- case "HTML":
1832
- return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
1833
- default:
1834
- return true;
1835
- }
1836
- },
1837
- /**
1838
- * 转换字符串大小写
1839
- *
1840
- * @param str 待转换的字符串
1841
- * @param type 转换类型,可选值为 1-5,默认为 4
1842
- * 1:首字母大写,其余小写
1843
- * 2:首字母小写,其余大写
1844
- * 3:字母大小写反转
1845
- * 4:全部大写
1846
- * 5:全部小写
1847
- * @returns 转换后的字符串
1848
- */
1849
- changeCase(str, type) {
1850
- type = type || 4;
1851
- switch (type) {
1852
- case 1:
1853
- return str.replace(/\b\w+\b/g, function(word) {
1854
- return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
1855
- });
1856
- case 2:
1857
- return str.replace(/\b\w+\b/g, function(word) {
1858
- return word.substring(0, 1).toLowerCase() + word.substring(1).toUpperCase();
1859
- });
1860
- case 3:
1861
- return str.split("").map(function(word) {
1862
- if (/[a-z]/.test(word)) {
1863
- return word.toUpperCase();
1864
- } else {
1865
- return word.toLowerCase();
1866
- }
1867
- }).join("");
1868
- case 4:
1869
- return str.toUpperCase();
1870
- case 5:
1871
- return str.toLowerCase();
1872
- default:
1873
- return str;
1874
- }
1875
- },
1876
- /**
1877
- * 计算字符串的字节长度
1878
- *
1879
- * @param str 需要计算字节长度的字符串
1880
- * @returns 返回字符串的字节长度
1881
- */
1882
- getByteLength(str) {
1883
- return str.replace(/[\u0391-\uFFE5]/g, "aa").length;
1884
- },
1773
+ return { x, y };
1774
+ }
1885
1775
  /**
1886
- * 截取字符串中指定字节长度的子串
1776
+ * 根据百分比获取坐标
1887
1777
  *
1888
- * @param str 字符串对象,包含replace、length和substring方法
1889
- * @param start 截取起始位置
1890
- * @param n 截取字节长度
1891
- * @returns 返回截取后的子串
1778
+ * @param start 起点坐标
1779
+ * @param end 终点坐标
1780
+ * @param percent 百分比,取值范围0-1
1781
+ * @returns 返回插值后的坐标
1892
1782
  */
1893
- subStringByte(str, start, n) {
1894
- var r = /[^\x00-\xff]/g;
1895
- if (str.replace(r, "mm").length <= n) {
1896
- return str;
1897
- }
1898
- var m = Math.floor(n / 2);
1899
- for (var i = m; i < str.length; i++) {
1900
- let sub = str.substring(start, i);
1901
- if (sub.replace(r, "mm").length >= n) {
1902
- return sub;
1903
- }
1904
- }
1905
- return str;
1906
- },
1907
- string2Bytes(str) {
1908
- const bytes = [];
1909
- let c;
1910
- const len = str.length;
1911
- for (let i = 0; i < len; i++) {
1912
- c = str.charCodeAt(i);
1913
- if (c >= 65536 && c <= 1114111) {
1914
- bytes.push(c >> 18 & 7 | 240);
1915
- bytes.push(c >> 12 & 63 | 128);
1916
- bytes.push(c >> 6 & 63 | 128);
1917
- bytes.push(c & 63 | 128);
1918
- } else if (c >= 2048 && c <= 65535) {
1919
- bytes.push(c >> 12 & 15 | 224);
1920
- bytes.push(c >> 6 & 63 | 128);
1921
- bytes.push(c & 63 | 128);
1922
- } else if (c >= 128 && c <= 2047) {
1923
- bytes.push(c >> 6 & 31 | 192);
1924
- bytes.push(c & 63 | 128);
1925
- } else {
1926
- bytes.push(c & 255);
1927
- }
1928
- }
1929
- return new Uint8Array(bytes);
1930
- },
1931
- bytes2String(uint8arr) {
1932
- if (typeof uint8arr === "string") {
1933
- return uint8arr;
1934
- }
1935
- let str = "";
1936
- const _arr = uint8arr;
1937
- for (let i = 0; i < _arr.length; i++) {
1938
- const one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/);
1939
- if (v && one.length == 8) {
1940
- const bytesLength = v[0].length;
1941
- let store = _arr[i].toString(2).slice(7 - bytesLength);
1942
- for (let st = 1; st < bytesLength; st++) {
1943
- store += _arr[st + i].toString(2).slice(2);
1944
- }
1945
- str += String.fromCharCode(parseInt(store, 2));
1946
- i += bytesLength - 1;
1947
- } else {
1948
- str += String.fromCharCode(_arr[i]);
1949
- }
1950
- }
1951
- return str;
1783
+ static interpolate({ x: x1, y: y1, z: z1 = 0 }, { x: x2, y: y2, z: z2 = 0 }, percent) {
1784
+ const dx = x2 - x1, dy = y2 - y1, dz = z2 - z1;
1785
+ return { x: x1 + dx * percent, y: y1 + dy * percent, z: z1 + dz * percent };
1952
1786
  }
1953
- };
1787
+ }
1788
+ __publicField(GeoUtil, "toRadian", Math.PI / 180);
1789
+ __publicField(GeoUtil, "R", 6371393);
1954
1790
  const TYPES = ["Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon"];
1955
1791
  const GeoJsonUtil = {
1956
1792
  /**
@@ -2192,67 +2028,118 @@ const GeoJsonUtil = {
2192
2028
  };
2193
2029
  }
2194
2030
  };
2031
+ const ExceptionUtil = {
2032
+ getException(type, message) {
2033
+ const _Exception = function() {
2034
+ Error.call(this, message);
2035
+ this.name = type;
2036
+ this.message = message;
2037
+ this.stack = new Error().stack;
2038
+ };
2039
+ if (Error) _Exception.__proto__ = Error;
2040
+ _Exception.prototype = Object.create(Error && Error.prototype);
2041
+ _Exception.prototype.constructor = _Exception;
2042
+ return _Exception;
2043
+ },
2044
+ throwException(msg) {
2045
+ const _Exception = this.getException("Exception", msg);
2046
+ throw new _Exception(msg);
2047
+ },
2048
+ throwColorException(msg) {
2049
+ const _Exception = this.getException("ColorException", ErrorType.DATA_ERROR_COLOR + " -> " + msg);
2050
+ throw new _Exception(msg);
2051
+ },
2052
+ throwCoordinateException(msg) {
2053
+ const _Exception = this.getException("CoordinateException", ErrorType.DATA_ERROR_COORDINATE + " -> " + msg);
2054
+ throw new _Exception(msg);
2055
+ },
2056
+ throwGeoJsonException(msg) {
2057
+ const _Exception = this.getException("GeoJsonException", ErrorType.DATA_ERROR_GEOJSON + " -> " + msg);
2058
+ throw new _Exception(msg);
2059
+ },
2060
+ throwEmptyException(msg) {
2061
+ const _Exception = this.getException("EmptyException", ErrorType.PARAMETER_ERROR_LACK + " -> " + msg);
2062
+ throw new _Exception(msg);
2063
+ },
2064
+ throwIntegerException(msg) {
2065
+ const _Exception = this.getException("IntegerException", ErrorType.PARAMETER_ERROR_INTEGER + " -> " + msg);
2066
+ throw new _Exception(msg);
2067
+ },
2068
+ throwNumberException(msg) {
2069
+ const _Exception = this.getException("NumberException", ErrorType.PARAMETER_ERROR_NUMBER + " -> " + msg);
2070
+ throw new _Exception(msg);
2071
+ },
2072
+ throwArrayException(msg) {
2073
+ const _Exception = this.getException("ArrayException", ErrorType.PARAMETER_ERROR_ARRAY + " -> " + msg);
2074
+ throw new _Exception(msg);
2075
+ },
2076
+ throwFunctionException(msg) {
2077
+ const _Exception = this.getException("FunctionException", ErrorType.PARAMETER_ERROR_FUNCTION + " -> " + msg);
2078
+ throw new _Exception(msg);
2079
+ },
2080
+ throwProcessException(msg) {
2081
+ const _Exception = this.getException("ProcessException", ErrorType.PROCESS_FAIL + " -> " + msg);
2082
+ throw new _Exception(msg);
2083
+ },
2084
+ throwNetworkException(msg) {
2085
+ const _Exception = this.getException("NetworkException", ErrorType.REQUEST_ERROR_TIMEOUT + " -> " + msg);
2086
+ throw new _Exception(msg);
2087
+ }
2088
+ };
2195
2089
  const AssertUtil = {
2196
2090
  assertEmpty(...arg) {
2197
2091
  arg.forEach((a) => {
2198
2092
  if (Util.isEmpty(a)) {
2199
- throw Error(ErrorType.PARAMETER_ERROR_LACK + " -> " + a);
2093
+ ExceptionUtil.throwEmptyException(a);
2200
2094
  }
2201
2095
  });
2202
2096
  },
2203
2097
  assertInteger(...arg) {
2204
2098
  arg.forEach((a) => {
2205
2099
  if (!Util.isInteger(a)) {
2206
- throw Error(ErrorType.PARAMETER_ERROR_INTEGER + " -> " + a);
2100
+ ExceptionUtil.throwIntegerException(a);
2207
2101
  }
2208
2102
  });
2209
2103
  },
2210
2104
  assertNumber(...arg) {
2211
2105
  arg.forEach((a) => {
2212
2106
  if (!Util.isNumber(a)) {
2213
- throw Error(ErrorType.PARAMETER_ERROR_NUMBER + " -> " + a);
2107
+ ExceptionUtil.throwNumberException(a);
2214
2108
  }
2215
2109
  });
2216
2110
  },
2217
2111
  assertArray(...arg) {
2218
2112
  arg.forEach((a) => {
2219
2113
  if (!Util.isArray(a)) {
2220
- throw Error(ErrorType.PARAMETER_ERROR_ARRAY + " -> " + a);
2114
+ ExceptionUtil.throwArrayException(a);
2221
2115
  }
2222
2116
  });
2223
2117
  },
2224
2118
  assertFunction(...arg) {
2225
2119
  arg.forEach((a) => {
2226
2120
  if (!Util.isFunction(a)) {
2227
- throw Error(ErrorType.PARAMETER_ERROR_FUNCTION + " -> " + a);
2228
- }
2229
- });
2230
- },
2231
- assertObject(...arg) {
2232
- arg.forEach((a) => {
2233
- if (!Util.isObject(a)) {
2234
- throw Error(ErrorType.PARAMETER_ERROR_OBJECT + " -> " + a);
2121
+ ExceptionUtil.throwFunctionException(a);
2235
2122
  }
2236
2123
  });
2237
2124
  },
2238
2125
  assertColor(...arg) {
2239
2126
  arg.forEach((a) => {
2240
2127
  if (!Color.isColor(a)) {
2241
- throw Error(ErrorType.DATA_ERROR_COLOR + " -> " + a);
2128
+ ExceptionUtil.throwColorException(a);
2242
2129
  }
2243
2130
  });
2244
2131
  },
2245
2132
  assertLnglat(...arg) {
2246
2133
  arg.forEach((a) => {
2247
2134
  if (!GeoUtil.isLnglat(a.lng, a.lat)) {
2248
- throw Error(ErrorType.DATA_ERROR_COORDINATE + " -> " + a);
2135
+ ExceptionUtil.throwCoordinateException(a);
2249
2136
  }
2250
2137
  });
2251
2138
  },
2252
2139
  assertGeoJson(...arg) {
2253
2140
  arg.forEach((a) => {
2254
2141
  if (!GeoJsonUtil.isGeoJson(a)) {
2255
- throw Error(ErrorType.DATA_ERROR_GEOJSON + " -> " + a);
2142
+ ExceptionUtil.throwGeoJsonException(a);
2256
2143
  }
2257
2144
  });
2258
2145
  },
@@ -2275,73 +2162,6 @@ const AssertUtil = {
2275
2162
  if (!value.endsWith(prefix)) {
2276
2163
  throw Error("字符串" + value + "结尾不是 -> " + prefix);
2277
2164
  }
2278
- },
2279
- /**
2280
- * 判断字符串是否合法
2281
- *
2282
- * @param value 待判断的字符串
2283
- * @param type 字符串类型
2284
- * @throws 当字符串不合法时,抛出错误,错误信息为“参数错误 -> 不是{typename}”
2285
- */
2286
- assertLegal(value, type) {
2287
- const bool = StringUtil.checkStr(value, type);
2288
- let typename = "";
2289
- switch (type) {
2290
- case "phone":
2291
- typename = "电话";
2292
- break;
2293
- case "tel":
2294
- typename = "座机";
2295
- break;
2296
- case "card":
2297
- typename = "身份证";
2298
- break;
2299
- case "pwd":
2300
- typename = "密码";
2301
- break;
2302
- case "postal":
2303
- typename = "邮政编码";
2304
- break;
2305
- case "QQ":
2306
- typename = "QQ";
2307
- break;
2308
- case "email":
2309
- typename = "邮箱";
2310
- break;
2311
- case "money":
2312
- typename = "金额";
2313
- break;
2314
- case "URL":
2315
- typename = "网址";
2316
- break;
2317
- case "IP":
2318
- typename = "IP";
2319
- break;
2320
- case "date":
2321
- typename = "日期时间";
2322
- break;
2323
- case "number":
2324
- typename = "数字";
2325
- break;
2326
- case "english":
2327
- typename = "英文";
2328
- break;
2329
- case "chinese":
2330
- typename = "中文";
2331
- break;
2332
- case "lower":
2333
- typename = "小写";
2334
- break;
2335
- case "upper":
2336
- typename = "大写";
2337
- break;
2338
- case "HTML":
2339
- typename = "HTML标记";
2340
- break;
2341
- }
2342
- if (!bool) {
2343
- throw Error(ErrorType.DATA_ERROR + " -> 不是" + typename);
2344
- }
2345
2165
  }
2346
2166
  };
2347
2167
  const myArray = Object.create(Array);
@@ -3555,6 +3375,124 @@ const OptimizeUtil = {
3555
3375
  };
3556
3376
  }
3557
3377
  };
3378
+ const StringUtil = {
3379
+ /**
3380
+ * 转换字符串大小写
3381
+ *
3382
+ * @param str 待转换的字符串
3383
+ * @param type 转换类型,可选值为 1-5,默认为 4
3384
+ * 1:首字母大写,其余小写
3385
+ * 2:首字母小写,其余大写
3386
+ * 3:字母大小写反转
3387
+ * 4:全部大写
3388
+ * 5:全部小写
3389
+ * @returns 转换后的字符串
3390
+ */
3391
+ changeCase(str, type) {
3392
+ type = type || 4;
3393
+ switch (type) {
3394
+ case 1:
3395
+ return str.replace(/\b\w+\b/g, function(word) {
3396
+ return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
3397
+ });
3398
+ case 2:
3399
+ return str.replace(/\b\w+\b/g, function(word) {
3400
+ return word.substring(0, 1).toLowerCase() + word.substring(1).toUpperCase();
3401
+ });
3402
+ case 3:
3403
+ return str.split("").map(function(word) {
3404
+ if (/[a-z]/.test(word)) {
3405
+ return word.toUpperCase();
3406
+ } else {
3407
+ return word.toLowerCase();
3408
+ }
3409
+ }).join("");
3410
+ case 4:
3411
+ return str.toUpperCase();
3412
+ case 5:
3413
+ return str.toLowerCase();
3414
+ default:
3415
+ return str;
3416
+ }
3417
+ },
3418
+ /**
3419
+ * 计算字符串的字节长度
3420
+ *
3421
+ * @param str 需要计算字节长度的字符串
3422
+ * @returns 返回字符串的字节长度
3423
+ */
3424
+ getByteLength(str) {
3425
+ return str.replace(/[\u0391-\uFFE5]/g, "aa").length;
3426
+ },
3427
+ /**
3428
+ * 截取字符串中指定字节长度的子串
3429
+ *
3430
+ * @param str 字符串对象,包含replace、length和substring方法
3431
+ * @param start 截取起始位置
3432
+ * @param n 截取字节长度
3433
+ * @returns 返回截取后的子串
3434
+ */
3435
+ subStringByte(str, start, n) {
3436
+ var r = /[^\x00-\xff]/g;
3437
+ if (str.replace(r, "mm").length <= n) {
3438
+ return str;
3439
+ }
3440
+ var m = Math.floor(n / 2);
3441
+ for (var i = m; i < str.length; i++) {
3442
+ let sub = str.substring(start, i);
3443
+ if (sub.replace(r, "mm").length >= n) {
3444
+ return sub;
3445
+ }
3446
+ }
3447
+ return str;
3448
+ },
3449
+ string2Bytes(str) {
3450
+ const bytes = [];
3451
+ let c;
3452
+ const len = str.length;
3453
+ for (let i = 0; i < len; i++) {
3454
+ c = str.charCodeAt(i);
3455
+ if (c >= 65536 && c <= 1114111) {
3456
+ bytes.push(c >> 18 & 7 | 240);
3457
+ bytes.push(c >> 12 & 63 | 128);
3458
+ bytes.push(c >> 6 & 63 | 128);
3459
+ bytes.push(c & 63 | 128);
3460
+ } else if (c >= 2048 && c <= 65535) {
3461
+ bytes.push(c >> 12 & 15 | 224);
3462
+ bytes.push(c >> 6 & 63 | 128);
3463
+ bytes.push(c & 63 | 128);
3464
+ } else if (c >= 128 && c <= 2047) {
3465
+ bytes.push(c >> 6 & 31 | 192);
3466
+ bytes.push(c & 63 | 128);
3467
+ } else {
3468
+ bytes.push(c & 255);
3469
+ }
3470
+ }
3471
+ return new Uint8Array(bytes);
3472
+ },
3473
+ bytes2String(uint8arr) {
3474
+ if (typeof uint8arr === "string") {
3475
+ return uint8arr;
3476
+ }
3477
+ let str = "";
3478
+ const _arr = uint8arr;
3479
+ for (let i = 0; i < _arr.length; i++) {
3480
+ const one = _arr[i].toString(2), v = one.match(/^1+?(?=0)/);
3481
+ if (v && one.length == 8) {
3482
+ const bytesLength = v[0].length;
3483
+ let store = _arr[i].toString(2).slice(7 - bytesLength);
3484
+ for (let st = 1; st < bytesLength; st++) {
3485
+ store += _arr[st + i].toString(2).slice(2);
3486
+ }
3487
+ str += String.fromCharCode(parseInt(store, 2));
3488
+ i += bytesLength - 1;
3489
+ } else {
3490
+ str += String.fromCharCode(_arr[i]);
3491
+ }
3492
+ }
3493
+ return str;
3494
+ }
3495
+ };
3558
3496
  const UrlUtil = {
3559
3497
  /**
3560
3498
  * 将json对象转换为查询字符串
@@ -3604,6 +3542,53 @@ const UrlUtil = {
3604
3542
  return obj;
3605
3543
  }
3606
3544
  };
3545
+ const ValidateUtil = {
3546
+ isUrl(v) {
3547
+ return /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/.test(
3548
+ v
3549
+ );
3550
+ },
3551
+ isPhone(v) {
3552
+ return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(v);
3553
+ },
3554
+ isTel(v) {
3555
+ return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(v);
3556
+ },
3557
+ /**
3558
+ * 判断是否是强密码,至少包含一个大写字母、一个小写字母、一个数字的组合、长度8-20位
3559
+ *
3560
+ * @param v 待检测的密码字符串
3561
+ * @returns 如果是是强密码,则返回 true;否则返回 false
3562
+ */
3563
+ isStrongPwd(v) {
3564
+ return /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,20}$/.test(v);
3565
+ },
3566
+ isEmail(v) {
3567
+ return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
3568
+ v
3569
+ );
3570
+ },
3571
+ isIP(v) {
3572
+ return /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test(
3573
+ v
3574
+ );
3575
+ },
3576
+ isEnglish(v) {
3577
+ return /^[a-zA-Z]+$/.test(v);
3578
+ },
3579
+ isChinese(v) {
3580
+ return /^[\u4E00-\u9FA5]+$/.test(v);
3581
+ },
3582
+ isHTML(v) {
3583
+ return /<("[^"]*"|'[^']*'|[^'">])*>/.test(v);
3584
+ },
3585
+ isXML(v) {
3586
+ return /^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$/.test(v);
3587
+ },
3588
+ isIDCard(v) {
3589
+ return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(v);
3590
+ }
3591
+ };
3607
3592
  const _MqttClient = class _MqttClient extends EventDispatcher {
3608
3593
  constructor(url = `ws://${window.document.domain}:20007/mqtt`, config = {}) {
3609
3594
  super();
@@ -3625,18 +3610,18 @@ const _MqttClient = class _MqttClient extends EventDispatcher {
3625
3610
  this.client = connect(this.url, this.options);
3626
3611
  this._onConnect();
3627
3612
  this._onMessage();
3628
- this.state = 0;
3613
+ this.state = 1;
3629
3614
  this.topics = [];
3630
3615
  }
3631
3616
  _onConnect() {
3632
3617
  this.client.on("connect", () => {
3633
- this.state = 1;
3618
+ this.state = 2;
3634
3619
  console.log("链接mqtt成功==>" + this.url);
3635
3620
  this.dispatchEvent({ type: EventType.MQTT_CONNECT, message: this });
3636
3621
  });
3637
3622
  this.client.on("error", (err) => {
3638
3623
  console.log("链接mqtt报错", err);
3639
- this.state = -1;
3624
+ this.state = 0;
3640
3625
  this.dispatchEvent({ type: EventType.MQTT_ERROR, message: this });
3641
3626
  this.client.end();
3642
3627
  this.client.reconnect();
@@ -3669,7 +3654,7 @@ const _MqttClient = class _MqttClient extends EventDispatcher {
3669
3654
  return this;
3670
3655
  }
3671
3656
  subscribe(topic) {
3672
- this.state === 1 ? this.client.subscribe(topic, { qos: 1 }, (error, e) => {
3657
+ this.state === 2 ? this.client.subscribe(topic, { qos: 1 }, (error, e) => {
3673
3658
  error instanceof Error ? console.error("订阅失败==>" + topic, error) : (this.topics = ArrayUtil.union(this.topics, topic), console.log("订阅成功==>" + topic));
3674
3659
  }) : this.addEventListener(EventType.MQTT_CONNECT, (res) => {
3675
3660
  this.client.subscribe(topic, { qos: 1 }, (error, e) => {
@@ -3835,6 +3820,7 @@ export {
3835
3820
  ErrorType,
3836
3821
  EventDispatcher,
3837
3822
  EventType,
3823
+ ExceptionUtil,
3838
3824
  FileUtil,
3839
3825
  FormType,
3840
3826
  GeoJsonUtil,
@@ -3854,5 +3840,6 @@ export {
3854
3840
  StringUtil,
3855
3841
  UrlUtil,
3856
3842
  Util,
3843
+ ValidateUtil,
3857
3844
  WebSocketClient
3858
3845
  };