@hhfenpm/utils 1.0.3 → 1.0.5

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @hhfenpm/utils
2
2
 
3
- 通用工具函数库,从 ma-management 和 medical-anget 两个项目中抽离的公共工具函数。
3
+ 通用工具函数库
4
4
 
5
5
  ## 安装
6
6
 
@@ -11,15 +11,9 @@ npm install @hhfenpm/utils
11
11
  ## 使用
12
12
 
13
13
  ```javascript
14
- // 按需导入(推荐使用驼峰命名)
15
- import { formatDate, validatePhone, getSession } from "@hhfenpm/utils";
16
-
17
- // 或导入整个模块
18
- import * as utils from "@hhfenpm/utils";
14
+ import { formatDate, validatePhone, getSession } from "@hhfenpm/utils"
19
15
  ```
20
16
 
21
- **注意:** 本包导出的是驼峰命名(camelCase)的 API。如果您的项目需要向后兼容的下划线命名(如 `format_date`),请通过项目本地的 utils 层导入,这些层会提供向后兼容的别名。
22
-
23
17
  ## 功能模块
24
18
 
25
19
  ### 格式化 (format)
@@ -70,8 +64,7 @@ import * as utils from "@hhfenpm/utils";
70
64
  - `setSession(session, key)` - 设置 localStorage 中的 session
71
65
  - `getSession(key)` - 获取 localStorage 中的 session
72
66
  - `removeSession(key)` - 移除 localStorage 中的 session
73
- - `extendSession(patch, key)` - 扩展 session 中的部分属性(推荐使用)
74
- - `extentSession(patch, key)` - 扩展 session 中的部分属性(向后兼容,拼写错误但保留)
67
+ - `extendSession(patch, key)` - 扩展 session 中的部分属性
75
68
  - `setSessionStorage(session, key)` - 设置 sessionStorage
76
69
  - `getSessionStorage(key)` - 获取 sessionStorage
77
70
  - `removeSessionStorage(key)` - 移除 sessionStorage
@@ -128,35 +121,17 @@ import * as utils from "@hhfenpm/utils";
128
121
  - `options.cache` - 是否支持缓存,默认false
129
122
  - `options.noWarn` - 是否禁用警告,默认false
130
123
 
131
- ## 向后兼容说明
132
-
133
- 本包导出的是标准的驼峰命名(camelCase)API。如果您需要向后兼容的下划线命名(如 `format_date`、`format_decimal` 等),请通过项目本地的 utils 层导入:
134
-
135
- ```javascript
136
- // ✅ 推荐:通过项目 utils 层导入(提供向后兼容)
137
- import { format_date, format_decimal } from '@/utils/format'
138
-
139
- // ⚠️ 不推荐:直接导入 npm 包(只有驼峰命名)
140
- import { formatDate, formatDecimal } from '@hhfenpm/utils'
141
- ```
142
-
143
124
  ## 注意事项
144
125
 
145
- 1. **API 命名**:本包使用标准的驼峰命名(camelCase)。向后兼容的下划线命名由项目本地的 utils 层提供。
146
- 2. **依赖要求**:需要安装 `date-fns` 作为 peerDependency
147
- 3. **浏览器环境**:部分函数需要在浏览器环境中使用,在 Node.js 环境中会返回默认值或警告。
148
- 4. **拼写说明**:`extentSession` 是历史遗留的拼写错误,建议使用 `extendSession`,但 `extentSession` 仍然可用以保持向后兼容。
126
+ - 本包使用驼峰命名(camelCase)API
127
+ - 需要安装 `date-fns` 作为 peerDependency
128
+ - 部分函数需要在浏览器环境中使用
149
129
 
150
130
  ## 开发
151
131
 
152
132
  ```bash
153
- # 安装依赖
154
133
  npm install
155
-
156
- # 构建
157
134
  npm run build
158
-
159
- # 开发模式(监听文件变化)
160
135
  npm run dev
161
136
  ```
162
137
 
package/dist/index.esm.js CHANGED
@@ -2194,10 +2194,6 @@ function cleanEscapedString(input) {
2194
2194
  return matched[1].replace(doubleQuoteRegExp, "'");
2195
2195
  }
2196
2196
 
2197
- /**
2198
- * 数据格式化工具
2199
- */
2200
-
2201
2197
  /**
2202
2198
  * 日期格式化
2203
2199
  * @param {number|string} timestamp - 时间戳
@@ -2555,10 +2551,6 @@ function escapeRegExp(string) {
2555
2551
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
2556
2552
  }
2557
2553
 
2558
- /**
2559
- * 数据验证工具
2560
- */
2561
-
2562
2554
  /**
2563
2555
  * 基于Promise的表单字段验证(避免回调地狱)
2564
2556
  * @param {string} prop - 字段名
@@ -2615,13 +2607,9 @@ function isEmptyObj(obj) {
2615
2607
  function isEqual(a, b) {
2616
2608
  const classNameA = Object.prototype.toString.call(a);
2617
2609
  const classNameB = Object.prototype.toString.call(b);
2618
-
2619
- // 如果数据类型不相等,则返回false
2620
2610
  if (classNameA !== classNameB) {
2621
2611
  return false
2622
2612
  }
2623
-
2624
- // 如果数据类型相等,再根据不同数据类型分别判断
2625
2613
  if (classNameA === '[object Object]') {
2626
2614
  for (let key in a) {
2627
2615
  if (!isEqual(a[key], b[key])) return false
@@ -2735,13 +2723,9 @@ function isSupported() {
2735
2723
  }
2736
2724
 
2737
2725
  const browserInfo = getBrowserInfo();
2738
-
2739
- // Firefox需要版本大于38
2740
2726
  if (browserInfo.type === 'Mozilla Firefox') {
2741
2727
  return parseFloat(browserInfo.version) > 38
2742
2728
  }
2743
-
2744
- // 检测是否支持getUserMedia
2745
2729
  return !!(
2746
2730
  navigator.mediaDevices &&
2747
2731
  (navigator.mediaDevices.getUserMedia ||
@@ -2756,15 +2740,12 @@ function isSupported() {
2756
2740
  * @returns {Object} {isValid: boolean, message: string}
2757
2741
  */
2758
2742
  function validateMeaninglessConsecutiveSymbols(input) {
2759
- // 检查是否为空
2760
2743
  if (input.trim() === '') {
2761
2744
  return {
2762
2745
  isValid: false,
2763
2746
  message: '请输入内容',
2764
2747
  }
2765
2748
  }
2766
-
2767
- // 检查连续符号(中英文符号)
2768
2749
  const symbolRegex =
2769
2750
  /([\-\+\=\*\.\,\;\:\!\@\#\$\%\^\&\_\(\)\[\]\{\}\|\\\/\?\<\>\~\"\'\`\s]|[\u3000-\u303F]|[\uFF00-\uFFEF])\1{6,}/;
2770
2751
  if (symbolRegex.test(input)) {
@@ -2773,8 +2754,6 @@ function validateMeaninglessConsecutiveSymbols(input) {
2773
2754
  message: '输入无意义内容,请修改',
2774
2755
  }
2775
2756
  }
2776
-
2777
- // 检查连续数字
2778
2757
  const digitRegex = /(\d)\1{6,}/;
2779
2758
  if (digitRegex.test(input)) {
2780
2759
  return {
@@ -2782,8 +2761,6 @@ function validateMeaninglessConsecutiveSymbols(input) {
2782
2761
  message: '输入无意义内容,请修改',
2783
2762
  }
2784
2763
  }
2785
-
2786
- // 检查连续相同文字(中英文)
2787
2764
  const charRegex = /([\u4e00-\u9fa5a-zA-Z])\1{2,}/;
2788
2765
  if (charRegex.test(input)) {
2789
2766
  return {
@@ -2791,17 +2768,12 @@ function validateMeaninglessConsecutiveSymbols(input) {
2791
2768
  message: '输入无意义内容,请修改',
2792
2769
  }
2793
2770
  }
2794
-
2795
2771
  return {
2796
2772
  isValid: true,
2797
2773
  message: '',
2798
2774
  }
2799
2775
  }
2800
2776
 
2801
- /**
2802
- * 内存缓存工具
2803
- */
2804
-
2805
2777
  /**
2806
2778
  * 内存缓存对象
2807
2779
  */
@@ -2866,11 +2838,6 @@ function buildUniqueUrl(url, method, params = {}, data = {}) {
2866
2838
  return url
2867
2839
  }
2868
2840
 
2869
- /**
2870
- * Session管理工具
2871
- * 提供localStorage和sessionStorage的封装,支持系统标识前缀
2872
- */
2873
-
2874
2841
  let systemFlag = null;
2875
2842
 
2876
2843
  /**
@@ -2967,15 +2934,6 @@ function extendSession(patch, key = 'session') {
2967
2934
  return getSession(key)
2968
2935
  }
2969
2936
 
2970
- /**
2971
- * 扩展session中的部分属性(向后兼容,拼写错误但保留)
2972
- * @param {Object} patch - 要扩展的属性
2973
- * @param {string} key - 键名,默认'session'
2974
- * @returns {*} 更新后的session
2975
- * @deprecated 请使用 extendSession,此函数保留仅为向后兼容
2976
- */
2977
- const extentSession = extendSession;
2978
-
2979
2937
  /**
2980
2938
  * 设置sessionStorage
2981
2939
  * @param {*} session - 要存储的数据
@@ -3026,11 +2984,6 @@ function removeSessionStorage(key = 'collapse') {
3026
2984
  sessionStorage.removeItem(getSystemKey(key));
3027
2985
  }
3028
2986
 
3029
- /**
3030
- * 图片URL处理工具
3031
- * 注意:需要配置 GLOBAL_CONFIG.backend_server
3032
- */
3033
-
3034
2987
  /**
3035
2988
  * 获取图片URL
3036
2989
  * @param {string} url - 图片路径
@@ -3038,23 +2991,17 @@ function removeSessionStorage(key = 'collapse') {
3038
2991
  */
3039
2992
  function getImgURL(url) {
3040
2993
  if (!url) return ''
3041
-
3042
- // 如果已经是完整的URL或data URL,直接返回
3043
2994
  if (/^http/g.test(url) || /^data:image/g.test(url)) {
3044
2995
  return url
3045
2996
  }
3046
-
3047
- // 获取基础URL
3048
2997
  const backendServer =
3049
2998
  typeof window !== 'undefined' && window.GLOBAL_CONFIG
3050
2999
  ? window.GLOBAL_CONFIG.backend_server
3051
3000
  : '';
3052
-
3053
3001
  if (!backendServer) {
3054
3002
  console.warn('未配置 backend_server,返回原始URL');
3055
3003
  return url
3056
3004
  }
3057
-
3058
3005
  return `${backendServer}/_uploads/files/${url}`
3059
3006
  }
3060
3007
 
@@ -3065,23 +3012,17 @@ function getImgURL(url) {
3065
3012
  */
3066
3013
  function getGaugeImgUrl(url) {
3067
3014
  if (!url) return ''
3068
-
3069
- // 如果已经是完整的URL或data URL,直接返回
3070
3015
  if (/^http/g.test(url) || /^data:image/g.test(url)) {
3071
3016
  return url
3072
3017
  }
3073
-
3074
- // 获取基础URL
3075
3018
  const backendServer =
3076
3019
  typeof window !== 'undefined' && window.GLOBAL_CONFIG
3077
3020
  ? window.GLOBAL_CONFIG.backend_server
3078
3021
  : '';
3079
-
3080
3022
  if (!backendServer) {
3081
3023
  console.warn('未配置 backend_server,返回原始URL');
3082
3024
  return url
3083
3025
  }
3084
-
3085
3026
  return `${backendServer}/api/v1/ma/mobile/resource/local/files?file=${url}`
3086
3027
  }
3087
3028
 
@@ -3095,20 +3036,12 @@ function doctorHeadImg(url, defaultUrl = './img/doc_defalut_male.jpg') {
3095
3036
  if (!url) {
3096
3037
  return defaultUrl
3097
3038
  }
3098
-
3099
- // 如果已经是完整的URL或data URL,直接返回
3100
3039
  if (/^http/g.test(url) || /^data:image/g.test(url)) {
3101
3040
  return url
3102
3041
  }
3103
-
3104
- // 使用OSS基础URL
3105
3042
  return `https://annetinfo1.oss-cn-shenzhen.aliyuncs.com/${url}`
3106
3043
  }
3107
3044
 
3108
- /**
3109
- * 设备检测工具函数
3110
- */
3111
-
3112
3045
  /**
3113
3046
  * 检测当前设备是否为平板
3114
3047
  * @returns {boolean} 是否为平板设备
@@ -3118,47 +3051,39 @@ function isTablet() {
3118
3051
  return false
3119
3052
  }
3120
3053
 
3121
- // 获取用户代理字符串
3122
3054
  const userAgent = navigator.userAgent.toLowerCase();
3123
-
3124
- // 检测常见的平板设备标识
3055
+ const isIETabletPC =
3056
+ /trident|msie/i.test(userAgent) && /tablet pc/i.test(userAgent);
3057
+ if (isIETabletPC) {
3058
+ return false
3059
+ }
3125
3060
  const tabletPatterns = [
3126
- /ipad/, // iPad
3127
- /android.*tablet/, // Android 平板
3128
- /kindle/, // Kindle
3129
- /silk/, // Amazon Silk
3130
- /playbook/, // BlackBerry PlayBook
3131
- /bb10/, // BlackBerry 10
3132
- /rim tablet/, // BlackBerry Tablet OS
3133
- /windows.*touch/, // Windows 平板
3134
- /tablet/, // 通用平板标识
3061
+ /ipad/,
3062
+ /android.*tablet/,
3063
+ /kindle/,
3064
+ /silk/,
3065
+ /playbook/,
3066
+ /bb10/,
3067
+ /rim tablet/,
3068
+ /windows.*touch/,
3069
+ /arm.*tablet/,
3135
3070
  ];
3136
-
3137
- // 检查用户代理是否匹配平板模式
3138
3071
  const isTabletByUserAgent = tabletPatterns.some(pattern =>
3139
3072
  pattern.test(userAgent)
3140
3073
  );
3141
-
3142
- // 检测屏幕尺寸和触摸支持
3143
3074
  const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
3144
3075
  const screenWidth = window.screen.width;
3145
3076
  const screenHeight = window.screen.height;
3146
3077
  const minDimension = Math.min(screenWidth, screenHeight);
3147
3078
  const maxDimension = Math.max(screenWidth, screenHeight);
3148
-
3149
- // 平板设备的典型屏幕尺寸范围
3150
3079
  const isTabletByScreenSize =
3151
3080
  minDimension >= 600 &&
3152
3081
  minDimension <= 1200 &&
3153
3082
  maxDimension >= 800 &&
3154
3083
  maxDimension <= 1600;
3155
-
3156
- // 检测是否为移动设备但屏幕较大(可能是平板)
3157
3084
  const isMobile =
3158
3085
  /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
3159
3086
  const isLargeMobile = isMobile && minDimension >= 600;
3160
-
3161
- // 综合判断:用户代理匹配 或 (屏幕尺寸符合平板特征 且 支持触摸) 或 (大屏移动设备)
3162
3087
  return (
3163
3088
  isTabletByUserAgent || (isTabletByScreenSize && hasTouch) || isLargeMobile
3164
3089
  )
@@ -3225,11 +3150,6 @@ function getDeviceInfo() {
3225
3150
  }
3226
3151
  }
3227
3152
 
3228
- /**
3229
- * URL参数处理工具
3230
- * 注意:部分函数依赖浏览器环境(window.location)
3231
- */
3232
-
3233
3153
  /**
3234
3154
  * 将查询字符串转换为对象
3235
3155
  * @param {string} str - 查询字符串,如 'a=1&b=2'
@@ -3267,7 +3187,6 @@ function toQueryString(obj) {
3267
3187
  const encodedKey = encodeURIComponent(key);
3268
3188
  const values = obj[key];
3269
3189
  if (values && values.constructor == Array) {
3270
- // 数组
3271
3190
  const queryValues = [];
3272
3191
  for (let i = 0, len = values.length, value; i < len; i++) {
3273
3192
  value = values[i];
@@ -3275,7 +3194,6 @@ function toQueryString(obj) {
3275
3194
  }
3276
3195
  ret = ret.concat(queryValues);
3277
3196
  } else {
3278
- // 字符串
3279
3197
  ret.push(toQueryPair(encodedKey, values));
3280
3198
  }
3281
3199
  }
@@ -3293,10 +3211,8 @@ function urlToJson(selfUrl) {
3293
3211
  }
3294
3212
  const url = selfUrl ? selfUrl : window.location.href;
3295
3213
 
3296
- const reg = /\?.*$/; // 正则取'?后的参数'
3214
+ const reg = /\?.*$/;
3297
3215
  const urlMatch = url.match(reg);
3298
-
3299
- // 匹配去掉?的纯参数(正则精髓,贪婪永远匹配最后一个?后的参数)
3300
3216
  const param =
3301
3217
  urlMatch && urlMatch.length ? urlMatch[0].replace(/^\?*.*\?/, '') : '';
3302
3218
 
@@ -3336,16 +3252,11 @@ function setUrl(json, originUrl = '') {
3336
3252
  return ''
3337
3253
  }
3338
3254
  let paramJson = urlToJson().paramJson;
3339
- // 新的参数
3340
3255
  let newJson = {
3341
3256
  ...paramJson,
3342
3257
  ...json,
3343
3258
  };
3344
-
3345
- // 参数对象 =》get参数
3346
3259
  let paramStr = toQueryString(newJson);
3347
-
3348
- // url的origin + pathname
3349
3260
  let oPath = originUrl
3350
3261
  ? originUrl
3351
3262
  : window.location.origin + window.location.pathname;
@@ -3367,10 +3278,6 @@ function getUrlParams(url) {
3367
3278
  return urlToJson(targetUrl).paramJson
3368
3279
  }
3369
3280
 
3370
- /**
3371
- * 通用工具函数
3372
- */
3373
-
3374
3281
  /**
3375
3282
  * 将毫秒转换为时分秒
3376
3283
  * @param {number} ms - 毫秒数
@@ -3385,14 +3292,14 @@ function convertMilliseconds(ms, secondsTo2decimal = false) {
3385
3292
  seconds: 0,
3386
3293
  }
3387
3294
 
3388
- const hours = Math.floor(ms / 3600000); // 计算小时
3389
- const minutes = Math.floor((ms % 3600000) / 60000); // 计算分钟
3295
+ const hours = Math.floor(ms / 3600000);
3296
+ const minutes = Math.floor((ms % 3600000) / 60000);
3390
3297
  let seconds = 0;
3391
3298
 
3392
3299
  if (secondsTo2decimal) {
3393
3300
  seconds = parseFloat(((ms % 60000) / 1000).toFixed(2));
3394
3301
  } else {
3395
- seconds = Math.floor((ms % 60000) / 1000); // 计算秒数
3302
+ seconds = Math.floor((ms % 60000) / 1000);
3396
3303
  }
3397
3304
 
3398
3305
  return {
@@ -3550,17 +3457,12 @@ async function copyText(text) {
3550
3457
  }
3551
3458
 
3552
3459
  try {
3553
- // 优先使用现代的Clipboard API
3554
3460
  if (navigator.clipboard && window.isSecureContext) {
3555
3461
  await navigator.clipboard.writeText(text);
3556
3462
  return true
3557
3463
  }
3558
-
3559
- // 降级方案:使用传统的document.execCommand方法
3560
3464
  const textArea = document.createElement('textarea');
3561
3465
  textArea.value = text;
3562
-
3563
- // 防止页面滚动
3564
3466
  textArea.style.position = 'fixed';
3565
3467
  textArea.style.left = '-999999px';
3566
3468
  textArea.style.top = '-999999px';
@@ -3582,10 +3484,6 @@ async function copyText(text) {
3582
3484
  }
3583
3485
  }
3584
3486
 
3585
- /**
3586
- * UUID生成工具
3587
- */
3588
-
3589
3487
  /**
3590
3488
  * 生成短UUID
3591
3489
  * @returns {string} UUID字符串
@@ -3617,11 +3515,6 @@ function uuidLong() {
3617
3515
  return `${uuid()}${uuid()}${uuid()}`
3618
3516
  }
3619
3517
 
3620
- /**
3621
- * 对象属性获取工具
3622
- * 类似lodash的get方法,支持路径字符串和数组
3623
- */
3624
-
3625
3518
  /**
3626
3519
  * 将字符串路径转换为数组
3627
3520
  * @param {string} string - 路径字符串,如 'a.b[0].c'
@@ -3629,7 +3522,7 @@ function uuidLong() {
3629
3522
  */
3630
3523
  function stringToPath(string) {
3631
3524
  const result = [];
3632
- if (string.charCodeAt(0) === 46 /* . */) {
3525
+ if (string.charCodeAt(0) === 46) {
3633
3526
  result.push('');
3634
3527
  }
3635
3528
  string.replace(
@@ -3644,7 +3537,7 @@ function stringToPath(string) {
3644
3537
  /**
3645
3538
  * 转换路径为数组格式
3646
3539
  * @param {string|Array} value - 路径字符串或数组
3647
- * @param {Object} object - 对象(用于兼容性,未使用)
3540
+ * @param {Object} object - 对象
3648
3541
  * @returns {Array} 路径数组
3649
3542
  */
3650
3543
  function castPath(value, object) {
@@ -3695,9 +3588,9 @@ function get(object, path, defaultValue) {
3695
3588
  var index = (options = {}) =>
3696
3589
  async config => {
3697
3590
  const defaultOptions = {
3698
- cacheTime: 0, // 缓存时间,设置为0,不清除缓存
3699
- cache: false, // 是否支持缓存
3700
- noWarn: false, // 是否有提示
3591
+ cacheTime: 0,
3592
+ cache: false,
3593
+ noWarn: false,
3701
3594
  ...options,
3702
3595
  };
3703
3596
 
@@ -3712,7 +3605,6 @@ var index = (options = {}) =>
3712
3605
  if (!responsePromise || !defaultOptions.cache) {
3713
3606
  responsePromise = (async () => {
3714
3607
  try {
3715
- // 需要确保axios可用
3716
3608
  let axios = null;
3717
3609
  if (typeof window !== 'undefined' && window.axios) {
3718
3610
  axios = window.axios;
@@ -3746,7 +3638,7 @@ var index = (options = {}) =>
3746
3638
  }
3747
3639
  }
3748
3640
 
3749
- return responsePromise.then(data => JSON.parse(JSON.stringify(data))) // 为防止数据源污染
3641
+ return responsePromise.then(data => JSON.parse(JSON.stringify(data)))
3750
3642
  };
3751
3643
 
3752
- export { arrToLabel, arrToObj, buildUniqueUrl, cache, calculateHeight, convertMilliseconds, copyContent, copyText, copyToClip, createGuid, debounce, index as defaultAdapter, detectZoom, doctorHeadImg, escapeRegExp, extendSession, extentSession, fileDownloadHelper, findNodeOfTree, formatDate, formatDateMinute, formatDecimal, formatDecimalString, formatMoney, formatNumber, formatText, get, getBrowserInfo, getDeviceInfo, getDeviceType, getGaugeImgUrl, getHalfYearAgoToday, getImgURL, getQueryString, getSession, getSessionStorage, getSystemKey, getUrlParams, hidePhone, isEmpty, isEmptyObj, isEqual, isSupported, isTablet, isTouchDevice, mapParseReviver, mapStringifyReplacer, myDebounce, queryToObj, removeSession, removeSessionStorage, setCursor, setSession, setSessionStorage, setSystemKey, setUrl, sleep, throttle, toQueryString, urlToJson, uuid, uuidLong, validateFieldAsync, validateMeaninglessConsecutiveSymbols, validatePhone };
3644
+ export { arrToLabel, arrToObj, buildUniqueUrl, cache, calculateHeight, convertMilliseconds, copyContent, copyText, copyToClip, createGuid, debounce, index as defaultAdapter, detectZoom, doctorHeadImg, escapeRegExp, extendSession, fileDownloadHelper, findNodeOfTree, formatDate, formatDateMinute, formatDecimal, formatDecimalString, formatMoney, formatNumber, formatText, get, getBrowserInfo, getDeviceInfo, getDeviceType, getGaugeImgUrl, getHalfYearAgoToday, getImgURL, getQueryString, getSession, getSessionStorage, getSystemKey, getUrlParams, hidePhone, isEmpty, isEmptyObj, isEqual, isSupported, isTablet, isTouchDevice, mapParseReviver, mapStringifyReplacer, myDebounce, queryToObj, removeSession, removeSessionStorage, setCursor, setSession, setSessionStorage, setSystemKey, setUrl, sleep, throttle, toQueryString, urlToJson, uuid, uuidLong, validateFieldAsync, validateMeaninglessConsecutiveSymbols, validatePhone };
package/dist/index.js CHANGED
@@ -2196,10 +2196,6 @@ function cleanEscapedString(input) {
2196
2196
  return matched[1].replace(doubleQuoteRegExp, "'");
2197
2197
  }
2198
2198
 
2199
- /**
2200
- * 数据格式化工具
2201
- */
2202
-
2203
2199
  /**
2204
2200
  * 日期格式化
2205
2201
  * @param {number|string} timestamp - 时间戳
@@ -2557,10 +2553,6 @@ function escapeRegExp(string) {
2557
2553
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
2558
2554
  }
2559
2555
 
2560
- /**
2561
- * 数据验证工具
2562
- */
2563
-
2564
2556
  /**
2565
2557
  * 基于Promise的表单字段验证(避免回调地狱)
2566
2558
  * @param {string} prop - 字段名
@@ -2617,13 +2609,9 @@ function isEmptyObj(obj) {
2617
2609
  function isEqual(a, b) {
2618
2610
  const classNameA = Object.prototype.toString.call(a);
2619
2611
  const classNameB = Object.prototype.toString.call(b);
2620
-
2621
- // 如果数据类型不相等,则返回false
2622
2612
  if (classNameA !== classNameB) {
2623
2613
  return false
2624
2614
  }
2625
-
2626
- // 如果数据类型相等,再根据不同数据类型分别判断
2627
2615
  if (classNameA === '[object Object]') {
2628
2616
  for (let key in a) {
2629
2617
  if (!isEqual(a[key], b[key])) return false
@@ -2737,13 +2725,9 @@ function isSupported() {
2737
2725
  }
2738
2726
 
2739
2727
  const browserInfo = getBrowserInfo();
2740
-
2741
- // Firefox需要版本大于38
2742
2728
  if (browserInfo.type === 'Mozilla Firefox') {
2743
2729
  return parseFloat(browserInfo.version) > 38
2744
2730
  }
2745
-
2746
- // 检测是否支持getUserMedia
2747
2731
  return !!(
2748
2732
  navigator.mediaDevices &&
2749
2733
  (navigator.mediaDevices.getUserMedia ||
@@ -2758,15 +2742,12 @@ function isSupported() {
2758
2742
  * @returns {Object} {isValid: boolean, message: string}
2759
2743
  */
2760
2744
  function validateMeaninglessConsecutiveSymbols(input) {
2761
- // 检查是否为空
2762
2745
  if (input.trim() === '') {
2763
2746
  return {
2764
2747
  isValid: false,
2765
2748
  message: '请输入内容',
2766
2749
  }
2767
2750
  }
2768
-
2769
- // 检查连续符号(中英文符号)
2770
2751
  const symbolRegex =
2771
2752
  /([\-\+\=\*\.\,\;\:\!\@\#\$\%\^\&\_\(\)\[\]\{\}\|\\\/\?\<\>\~\"\'\`\s]|[\u3000-\u303F]|[\uFF00-\uFFEF])\1{6,}/;
2772
2753
  if (symbolRegex.test(input)) {
@@ -2775,8 +2756,6 @@ function validateMeaninglessConsecutiveSymbols(input) {
2775
2756
  message: '输入无意义内容,请修改',
2776
2757
  }
2777
2758
  }
2778
-
2779
- // 检查连续数字
2780
2759
  const digitRegex = /(\d)\1{6,}/;
2781
2760
  if (digitRegex.test(input)) {
2782
2761
  return {
@@ -2784,8 +2763,6 @@ function validateMeaninglessConsecutiveSymbols(input) {
2784
2763
  message: '输入无意义内容,请修改',
2785
2764
  }
2786
2765
  }
2787
-
2788
- // 检查连续相同文字(中英文)
2789
2766
  const charRegex = /([\u4e00-\u9fa5a-zA-Z])\1{2,}/;
2790
2767
  if (charRegex.test(input)) {
2791
2768
  return {
@@ -2793,17 +2770,12 @@ function validateMeaninglessConsecutiveSymbols(input) {
2793
2770
  message: '输入无意义内容,请修改',
2794
2771
  }
2795
2772
  }
2796
-
2797
2773
  return {
2798
2774
  isValid: true,
2799
2775
  message: '',
2800
2776
  }
2801
2777
  }
2802
2778
 
2803
- /**
2804
- * 内存缓存工具
2805
- */
2806
-
2807
2779
  /**
2808
2780
  * 内存缓存对象
2809
2781
  */
@@ -2868,11 +2840,6 @@ function buildUniqueUrl(url, method, params = {}, data = {}) {
2868
2840
  return url
2869
2841
  }
2870
2842
 
2871
- /**
2872
- * Session管理工具
2873
- * 提供localStorage和sessionStorage的封装,支持系统标识前缀
2874
- */
2875
-
2876
2843
  let systemFlag = null;
2877
2844
 
2878
2845
  /**
@@ -2969,15 +2936,6 @@ function extendSession(patch, key = 'session') {
2969
2936
  return getSession(key)
2970
2937
  }
2971
2938
 
2972
- /**
2973
- * 扩展session中的部分属性(向后兼容,拼写错误但保留)
2974
- * @param {Object} patch - 要扩展的属性
2975
- * @param {string} key - 键名,默认'session'
2976
- * @returns {*} 更新后的session
2977
- * @deprecated 请使用 extendSession,此函数保留仅为向后兼容
2978
- */
2979
- const extentSession = extendSession;
2980
-
2981
2939
  /**
2982
2940
  * 设置sessionStorage
2983
2941
  * @param {*} session - 要存储的数据
@@ -3028,11 +2986,6 @@ function removeSessionStorage(key = 'collapse') {
3028
2986
  sessionStorage.removeItem(getSystemKey(key));
3029
2987
  }
3030
2988
 
3031
- /**
3032
- * 图片URL处理工具
3033
- * 注意:需要配置 GLOBAL_CONFIG.backend_server
3034
- */
3035
-
3036
2989
  /**
3037
2990
  * 获取图片URL
3038
2991
  * @param {string} url - 图片路径
@@ -3040,23 +2993,17 @@ function removeSessionStorage(key = 'collapse') {
3040
2993
  */
3041
2994
  function getImgURL(url) {
3042
2995
  if (!url) return ''
3043
-
3044
- // 如果已经是完整的URL或data URL,直接返回
3045
2996
  if (/^http/g.test(url) || /^data:image/g.test(url)) {
3046
2997
  return url
3047
2998
  }
3048
-
3049
- // 获取基础URL
3050
2999
  const backendServer =
3051
3000
  typeof window !== 'undefined' && window.GLOBAL_CONFIG
3052
3001
  ? window.GLOBAL_CONFIG.backend_server
3053
3002
  : '';
3054
-
3055
3003
  if (!backendServer) {
3056
3004
  console.warn('未配置 backend_server,返回原始URL');
3057
3005
  return url
3058
3006
  }
3059
-
3060
3007
  return `${backendServer}/_uploads/files/${url}`
3061
3008
  }
3062
3009
 
@@ -3067,23 +3014,17 @@ function getImgURL(url) {
3067
3014
  */
3068
3015
  function getGaugeImgUrl(url) {
3069
3016
  if (!url) return ''
3070
-
3071
- // 如果已经是完整的URL或data URL,直接返回
3072
3017
  if (/^http/g.test(url) || /^data:image/g.test(url)) {
3073
3018
  return url
3074
3019
  }
3075
-
3076
- // 获取基础URL
3077
3020
  const backendServer =
3078
3021
  typeof window !== 'undefined' && window.GLOBAL_CONFIG
3079
3022
  ? window.GLOBAL_CONFIG.backend_server
3080
3023
  : '';
3081
-
3082
3024
  if (!backendServer) {
3083
3025
  console.warn('未配置 backend_server,返回原始URL');
3084
3026
  return url
3085
3027
  }
3086
-
3087
3028
  return `${backendServer}/api/v1/ma/mobile/resource/local/files?file=${url}`
3088
3029
  }
3089
3030
 
@@ -3097,20 +3038,12 @@ function doctorHeadImg(url, defaultUrl = './img/doc_defalut_male.jpg') {
3097
3038
  if (!url) {
3098
3039
  return defaultUrl
3099
3040
  }
3100
-
3101
- // 如果已经是完整的URL或data URL,直接返回
3102
3041
  if (/^http/g.test(url) || /^data:image/g.test(url)) {
3103
3042
  return url
3104
3043
  }
3105
-
3106
- // 使用OSS基础URL
3107
3044
  return `https://annetinfo1.oss-cn-shenzhen.aliyuncs.com/${url}`
3108
3045
  }
3109
3046
 
3110
- /**
3111
- * 设备检测工具函数
3112
- */
3113
-
3114
3047
  /**
3115
3048
  * 检测当前设备是否为平板
3116
3049
  * @returns {boolean} 是否为平板设备
@@ -3120,47 +3053,39 @@ function isTablet() {
3120
3053
  return false
3121
3054
  }
3122
3055
 
3123
- // 获取用户代理字符串
3124
3056
  const userAgent = navigator.userAgent.toLowerCase();
3125
-
3126
- // 检测常见的平板设备标识
3057
+ const isIETabletPC =
3058
+ /trident|msie/i.test(userAgent) && /tablet pc/i.test(userAgent);
3059
+ if (isIETabletPC) {
3060
+ return false
3061
+ }
3127
3062
  const tabletPatterns = [
3128
- /ipad/, // iPad
3129
- /android.*tablet/, // Android 平板
3130
- /kindle/, // Kindle
3131
- /silk/, // Amazon Silk
3132
- /playbook/, // BlackBerry PlayBook
3133
- /bb10/, // BlackBerry 10
3134
- /rim tablet/, // BlackBerry Tablet OS
3135
- /windows.*touch/, // Windows 平板
3136
- /tablet/, // 通用平板标识
3063
+ /ipad/,
3064
+ /android.*tablet/,
3065
+ /kindle/,
3066
+ /silk/,
3067
+ /playbook/,
3068
+ /bb10/,
3069
+ /rim tablet/,
3070
+ /windows.*touch/,
3071
+ /arm.*tablet/,
3137
3072
  ];
3138
-
3139
- // 检查用户代理是否匹配平板模式
3140
3073
  const isTabletByUserAgent = tabletPatterns.some(pattern =>
3141
3074
  pattern.test(userAgent)
3142
3075
  );
3143
-
3144
- // 检测屏幕尺寸和触摸支持
3145
3076
  const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
3146
3077
  const screenWidth = window.screen.width;
3147
3078
  const screenHeight = window.screen.height;
3148
3079
  const minDimension = Math.min(screenWidth, screenHeight);
3149
3080
  const maxDimension = Math.max(screenWidth, screenHeight);
3150
-
3151
- // 平板设备的典型屏幕尺寸范围
3152
3081
  const isTabletByScreenSize =
3153
3082
  minDimension >= 600 &&
3154
3083
  minDimension <= 1200 &&
3155
3084
  maxDimension >= 800 &&
3156
3085
  maxDimension <= 1600;
3157
-
3158
- // 检测是否为移动设备但屏幕较大(可能是平板)
3159
3086
  const isMobile =
3160
3087
  /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
3161
3088
  const isLargeMobile = isMobile && minDimension >= 600;
3162
-
3163
- // 综合判断:用户代理匹配 或 (屏幕尺寸符合平板特征 且 支持触摸) 或 (大屏移动设备)
3164
3089
  return (
3165
3090
  isTabletByUserAgent || (isTabletByScreenSize && hasTouch) || isLargeMobile
3166
3091
  )
@@ -3227,11 +3152,6 @@ function getDeviceInfo() {
3227
3152
  }
3228
3153
  }
3229
3154
 
3230
- /**
3231
- * URL参数处理工具
3232
- * 注意:部分函数依赖浏览器环境(window.location)
3233
- */
3234
-
3235
3155
  /**
3236
3156
  * 将查询字符串转换为对象
3237
3157
  * @param {string} str - 查询字符串,如 'a=1&b=2'
@@ -3269,7 +3189,6 @@ function toQueryString(obj) {
3269
3189
  const encodedKey = encodeURIComponent(key);
3270
3190
  const values = obj[key];
3271
3191
  if (values && values.constructor == Array) {
3272
- // 数组
3273
3192
  const queryValues = [];
3274
3193
  for (let i = 0, len = values.length, value; i < len; i++) {
3275
3194
  value = values[i];
@@ -3277,7 +3196,6 @@ function toQueryString(obj) {
3277
3196
  }
3278
3197
  ret = ret.concat(queryValues);
3279
3198
  } else {
3280
- // 字符串
3281
3199
  ret.push(toQueryPair(encodedKey, values));
3282
3200
  }
3283
3201
  }
@@ -3295,10 +3213,8 @@ function urlToJson(selfUrl) {
3295
3213
  }
3296
3214
  const url = selfUrl ? selfUrl : window.location.href;
3297
3215
 
3298
- const reg = /\?.*$/; // 正则取'?后的参数'
3216
+ const reg = /\?.*$/;
3299
3217
  const urlMatch = url.match(reg);
3300
-
3301
- // 匹配去掉?的纯参数(正则精髓,贪婪永远匹配最后一个?后的参数)
3302
3218
  const param =
3303
3219
  urlMatch && urlMatch.length ? urlMatch[0].replace(/^\?*.*\?/, '') : '';
3304
3220
 
@@ -3338,16 +3254,11 @@ function setUrl(json, originUrl = '') {
3338
3254
  return ''
3339
3255
  }
3340
3256
  let paramJson = urlToJson().paramJson;
3341
- // 新的参数
3342
3257
  let newJson = {
3343
3258
  ...paramJson,
3344
3259
  ...json,
3345
3260
  };
3346
-
3347
- // 参数对象 =》get参数
3348
3261
  let paramStr = toQueryString(newJson);
3349
-
3350
- // url的origin + pathname
3351
3262
  let oPath = originUrl
3352
3263
  ? originUrl
3353
3264
  : window.location.origin + window.location.pathname;
@@ -3369,10 +3280,6 @@ function getUrlParams(url) {
3369
3280
  return urlToJson(targetUrl).paramJson
3370
3281
  }
3371
3282
 
3372
- /**
3373
- * 通用工具函数
3374
- */
3375
-
3376
3283
  /**
3377
3284
  * 将毫秒转换为时分秒
3378
3285
  * @param {number} ms - 毫秒数
@@ -3387,14 +3294,14 @@ function convertMilliseconds(ms, secondsTo2decimal = false) {
3387
3294
  seconds: 0,
3388
3295
  }
3389
3296
 
3390
- const hours = Math.floor(ms / 3600000); // 计算小时
3391
- const minutes = Math.floor((ms % 3600000) / 60000); // 计算分钟
3297
+ const hours = Math.floor(ms / 3600000);
3298
+ const minutes = Math.floor((ms % 3600000) / 60000);
3392
3299
  let seconds = 0;
3393
3300
 
3394
3301
  if (secondsTo2decimal) {
3395
3302
  seconds = parseFloat(((ms % 60000) / 1000).toFixed(2));
3396
3303
  } else {
3397
- seconds = Math.floor((ms % 60000) / 1000); // 计算秒数
3304
+ seconds = Math.floor((ms % 60000) / 1000);
3398
3305
  }
3399
3306
 
3400
3307
  return {
@@ -3552,17 +3459,12 @@ async function copyText(text) {
3552
3459
  }
3553
3460
 
3554
3461
  try {
3555
- // 优先使用现代的Clipboard API
3556
3462
  if (navigator.clipboard && window.isSecureContext) {
3557
3463
  await navigator.clipboard.writeText(text);
3558
3464
  return true
3559
3465
  }
3560
-
3561
- // 降级方案:使用传统的document.execCommand方法
3562
3466
  const textArea = document.createElement('textarea');
3563
3467
  textArea.value = text;
3564
-
3565
- // 防止页面滚动
3566
3468
  textArea.style.position = 'fixed';
3567
3469
  textArea.style.left = '-999999px';
3568
3470
  textArea.style.top = '-999999px';
@@ -3584,10 +3486,6 @@ async function copyText(text) {
3584
3486
  }
3585
3487
  }
3586
3488
 
3587
- /**
3588
- * UUID生成工具
3589
- */
3590
-
3591
3489
  /**
3592
3490
  * 生成短UUID
3593
3491
  * @returns {string} UUID字符串
@@ -3619,11 +3517,6 @@ function uuidLong() {
3619
3517
  return `${uuid()}${uuid()}${uuid()}`
3620
3518
  }
3621
3519
 
3622
- /**
3623
- * 对象属性获取工具
3624
- * 类似lodash的get方法,支持路径字符串和数组
3625
- */
3626
-
3627
3520
  /**
3628
3521
  * 将字符串路径转换为数组
3629
3522
  * @param {string} string - 路径字符串,如 'a.b[0].c'
@@ -3631,7 +3524,7 @@ function uuidLong() {
3631
3524
  */
3632
3525
  function stringToPath(string) {
3633
3526
  const result = [];
3634
- if (string.charCodeAt(0) === 46 /* . */) {
3527
+ if (string.charCodeAt(0) === 46) {
3635
3528
  result.push('');
3636
3529
  }
3637
3530
  string.replace(
@@ -3646,7 +3539,7 @@ function stringToPath(string) {
3646
3539
  /**
3647
3540
  * 转换路径为数组格式
3648
3541
  * @param {string|Array} value - 路径字符串或数组
3649
- * @param {Object} object - 对象(用于兼容性,未使用)
3542
+ * @param {Object} object - 对象
3650
3543
  * @returns {Array} 路径数组
3651
3544
  */
3652
3545
  function castPath(value, object) {
@@ -3697,9 +3590,9 @@ function get(object, path, defaultValue) {
3697
3590
  var index = (options = {}) =>
3698
3591
  async config => {
3699
3592
  const defaultOptions = {
3700
- cacheTime: 0, // 缓存时间,设置为0,不清除缓存
3701
- cache: false, // 是否支持缓存
3702
- noWarn: false, // 是否有提示
3593
+ cacheTime: 0,
3594
+ cache: false,
3595
+ noWarn: false,
3703
3596
  ...options,
3704
3597
  };
3705
3598
 
@@ -3714,7 +3607,6 @@ var index = (options = {}) =>
3714
3607
  if (!responsePromise || !defaultOptions.cache) {
3715
3608
  responsePromise = (async () => {
3716
3609
  try {
3717
- // 需要确保axios可用
3718
3610
  let axios = null;
3719
3611
  if (typeof window !== 'undefined' && window.axios) {
3720
3612
  axios = window.axios;
@@ -3748,7 +3640,7 @@ var index = (options = {}) =>
3748
3640
  }
3749
3641
  }
3750
3642
 
3751
- return responsePromise.then(data => JSON.parse(JSON.stringify(data))) // 为防止数据源污染
3643
+ return responsePromise.then(data => JSON.parse(JSON.stringify(data)))
3752
3644
  };
3753
3645
 
3754
3646
  exports.arrToLabel = arrToLabel;
@@ -3767,7 +3659,6 @@ exports.detectZoom = detectZoom;
3767
3659
  exports.doctorHeadImg = doctorHeadImg;
3768
3660
  exports.escapeRegExp = escapeRegExp;
3769
3661
  exports.extendSession = extendSession;
3770
- exports.extentSession = extentSession;
3771
3662
  exports.fileDownloadHelper = fileDownloadHelper;
3772
3663
  exports.findNodeOfTree = findNodeOfTree;
3773
3664
  exports.formatDate = formatDate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hhfenpm/utils",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "通用工具函数库,包含格式化、验证、缓存、Session管理、图片URL处理、设备检测、URL处理、UUID生成等常用工具",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",