@hhfenpm/utils 1.0.3 → 1.0.4

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,34 @@ function isTablet() {
3118
3051
  return false
3119
3052
  }
3120
3053
 
3121
- // 获取用户代理字符串
3122
3054
  const userAgent = navigator.userAgent.toLowerCase();
3123
-
3124
- // 检测常见的平板设备标识
3125
3055
  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/, // 通用平板标识
3056
+ /ipad/,
3057
+ /android.*tablet/,
3058
+ /kindle/,
3059
+ /silk/,
3060
+ /playbook/,
3061
+ /bb10/,
3062
+ /rim tablet/,
3063
+ /windows.*touch/,
3064
+ /tablet/,
3135
3065
  ];
3136
-
3137
- // 检查用户代理是否匹配平板模式
3138
3066
  const isTabletByUserAgent = tabletPatterns.some(pattern =>
3139
3067
  pattern.test(userAgent)
3140
3068
  );
3141
-
3142
- // 检测屏幕尺寸和触摸支持
3143
3069
  const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
3144
3070
  const screenWidth = window.screen.width;
3145
3071
  const screenHeight = window.screen.height;
3146
3072
  const minDimension = Math.min(screenWidth, screenHeight);
3147
3073
  const maxDimension = Math.max(screenWidth, screenHeight);
3148
-
3149
- // 平板设备的典型屏幕尺寸范围
3150
3074
  const isTabletByScreenSize =
3151
3075
  minDimension >= 600 &&
3152
3076
  minDimension <= 1200 &&
3153
3077
  maxDimension >= 800 &&
3154
3078
  maxDimension <= 1600;
3155
-
3156
- // 检测是否为移动设备但屏幕较大(可能是平板)
3157
3079
  const isMobile =
3158
3080
  /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
3159
3081
  const isLargeMobile = isMobile && minDimension >= 600;
3160
-
3161
- // 综合判断:用户代理匹配 或 (屏幕尺寸符合平板特征 且 支持触摸) 或 (大屏移动设备)
3162
3082
  return (
3163
3083
  isTabletByUserAgent || (isTabletByScreenSize && hasTouch) || isLargeMobile
3164
3084
  )
@@ -3225,11 +3145,6 @@ function getDeviceInfo() {
3225
3145
  }
3226
3146
  }
3227
3147
 
3228
- /**
3229
- * URL参数处理工具
3230
- * 注意:部分函数依赖浏览器环境(window.location)
3231
- */
3232
-
3233
3148
  /**
3234
3149
  * 将查询字符串转换为对象
3235
3150
  * @param {string} str - 查询字符串,如 'a=1&b=2'
@@ -3267,7 +3182,6 @@ function toQueryString(obj) {
3267
3182
  const encodedKey = encodeURIComponent(key);
3268
3183
  const values = obj[key];
3269
3184
  if (values && values.constructor == Array) {
3270
- // 数组
3271
3185
  const queryValues = [];
3272
3186
  for (let i = 0, len = values.length, value; i < len; i++) {
3273
3187
  value = values[i];
@@ -3275,7 +3189,6 @@ function toQueryString(obj) {
3275
3189
  }
3276
3190
  ret = ret.concat(queryValues);
3277
3191
  } else {
3278
- // 字符串
3279
3192
  ret.push(toQueryPair(encodedKey, values));
3280
3193
  }
3281
3194
  }
@@ -3293,10 +3206,8 @@ function urlToJson(selfUrl) {
3293
3206
  }
3294
3207
  const url = selfUrl ? selfUrl : window.location.href;
3295
3208
 
3296
- const reg = /\?.*$/; // 正则取'?后的参数'
3209
+ const reg = /\?.*$/;
3297
3210
  const urlMatch = url.match(reg);
3298
-
3299
- // 匹配去掉?的纯参数(正则精髓,贪婪永远匹配最后一个?后的参数)
3300
3211
  const param =
3301
3212
  urlMatch && urlMatch.length ? urlMatch[0].replace(/^\?*.*\?/, '') : '';
3302
3213
 
@@ -3336,16 +3247,11 @@ function setUrl(json, originUrl = '') {
3336
3247
  return ''
3337
3248
  }
3338
3249
  let paramJson = urlToJson().paramJson;
3339
- // 新的参数
3340
3250
  let newJson = {
3341
3251
  ...paramJson,
3342
3252
  ...json,
3343
3253
  };
3344
-
3345
- // 参数对象 =》get参数
3346
3254
  let paramStr = toQueryString(newJson);
3347
-
3348
- // url的origin + pathname
3349
3255
  let oPath = originUrl
3350
3256
  ? originUrl
3351
3257
  : window.location.origin + window.location.pathname;
@@ -3367,10 +3273,6 @@ function getUrlParams(url) {
3367
3273
  return urlToJson(targetUrl).paramJson
3368
3274
  }
3369
3275
 
3370
- /**
3371
- * 通用工具函数
3372
- */
3373
-
3374
3276
  /**
3375
3277
  * 将毫秒转换为时分秒
3376
3278
  * @param {number} ms - 毫秒数
@@ -3385,14 +3287,14 @@ function convertMilliseconds(ms, secondsTo2decimal = false) {
3385
3287
  seconds: 0,
3386
3288
  }
3387
3289
 
3388
- const hours = Math.floor(ms / 3600000); // 计算小时
3389
- const minutes = Math.floor((ms % 3600000) / 60000); // 计算分钟
3290
+ const hours = Math.floor(ms / 3600000);
3291
+ const minutes = Math.floor((ms % 3600000) / 60000);
3390
3292
  let seconds = 0;
3391
3293
 
3392
3294
  if (secondsTo2decimal) {
3393
3295
  seconds = parseFloat(((ms % 60000) / 1000).toFixed(2));
3394
3296
  } else {
3395
- seconds = Math.floor((ms % 60000) / 1000); // 计算秒数
3297
+ seconds = Math.floor((ms % 60000) / 1000);
3396
3298
  }
3397
3299
 
3398
3300
  return {
@@ -3550,17 +3452,12 @@ async function copyText(text) {
3550
3452
  }
3551
3453
 
3552
3454
  try {
3553
- // 优先使用现代的Clipboard API
3554
3455
  if (navigator.clipboard && window.isSecureContext) {
3555
3456
  await navigator.clipboard.writeText(text);
3556
3457
  return true
3557
3458
  }
3558
-
3559
- // 降级方案:使用传统的document.execCommand方法
3560
3459
  const textArea = document.createElement('textarea');
3561
3460
  textArea.value = text;
3562
-
3563
- // 防止页面滚动
3564
3461
  textArea.style.position = 'fixed';
3565
3462
  textArea.style.left = '-999999px';
3566
3463
  textArea.style.top = '-999999px';
@@ -3582,10 +3479,6 @@ async function copyText(text) {
3582
3479
  }
3583
3480
  }
3584
3481
 
3585
- /**
3586
- * UUID生成工具
3587
- */
3588
-
3589
3482
  /**
3590
3483
  * 生成短UUID
3591
3484
  * @returns {string} UUID字符串
@@ -3617,11 +3510,6 @@ function uuidLong() {
3617
3510
  return `${uuid()}${uuid()}${uuid()}`
3618
3511
  }
3619
3512
 
3620
- /**
3621
- * 对象属性获取工具
3622
- * 类似lodash的get方法,支持路径字符串和数组
3623
- */
3624
-
3625
3513
  /**
3626
3514
  * 将字符串路径转换为数组
3627
3515
  * @param {string} string - 路径字符串,如 'a.b[0].c'
@@ -3629,7 +3517,7 @@ function uuidLong() {
3629
3517
  */
3630
3518
  function stringToPath(string) {
3631
3519
  const result = [];
3632
- if (string.charCodeAt(0) === 46 /* . */) {
3520
+ if (string.charCodeAt(0) === 46) {
3633
3521
  result.push('');
3634
3522
  }
3635
3523
  string.replace(
@@ -3644,7 +3532,7 @@ function stringToPath(string) {
3644
3532
  /**
3645
3533
  * 转换路径为数组格式
3646
3534
  * @param {string|Array} value - 路径字符串或数组
3647
- * @param {Object} object - 对象(用于兼容性,未使用)
3535
+ * @param {Object} object - 对象
3648
3536
  * @returns {Array} 路径数组
3649
3537
  */
3650
3538
  function castPath(value, object) {
@@ -3695,9 +3583,9 @@ function get(object, path, defaultValue) {
3695
3583
  var index = (options = {}) =>
3696
3584
  async config => {
3697
3585
  const defaultOptions = {
3698
- cacheTime: 0, // 缓存时间,设置为0,不清除缓存
3699
- cache: false, // 是否支持缓存
3700
- noWarn: false, // 是否有提示
3586
+ cacheTime: 0,
3587
+ cache: false,
3588
+ noWarn: false,
3701
3589
  ...options,
3702
3590
  };
3703
3591
 
@@ -3712,7 +3600,6 @@ var index = (options = {}) =>
3712
3600
  if (!responsePromise || !defaultOptions.cache) {
3713
3601
  responsePromise = (async () => {
3714
3602
  try {
3715
- // 需要确保axios可用
3716
3603
  let axios = null;
3717
3604
  if (typeof window !== 'undefined' && window.axios) {
3718
3605
  axios = window.axios;
@@ -3746,7 +3633,7 @@ var index = (options = {}) =>
3746
3633
  }
3747
3634
  }
3748
3635
 
3749
- return responsePromise.then(data => JSON.parse(JSON.stringify(data))) // 为防止数据源污染
3636
+ return responsePromise.then(data => JSON.parse(JSON.stringify(data)))
3750
3637
  };
3751
3638
 
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 };
3639
+ 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,34 @@ function isTablet() {
3120
3053
  return false
3121
3054
  }
3122
3055
 
3123
- // 获取用户代理字符串
3124
3056
  const userAgent = navigator.userAgent.toLowerCase();
3125
-
3126
- // 检测常见的平板设备标识
3127
3057
  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/, // 通用平板标识
3058
+ /ipad/,
3059
+ /android.*tablet/,
3060
+ /kindle/,
3061
+ /silk/,
3062
+ /playbook/,
3063
+ /bb10/,
3064
+ /rim tablet/,
3065
+ /windows.*touch/,
3066
+ /tablet/,
3137
3067
  ];
3138
-
3139
- // 检查用户代理是否匹配平板模式
3140
3068
  const isTabletByUserAgent = tabletPatterns.some(pattern =>
3141
3069
  pattern.test(userAgent)
3142
3070
  );
3143
-
3144
- // 检测屏幕尺寸和触摸支持
3145
3071
  const hasTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
3146
3072
  const screenWidth = window.screen.width;
3147
3073
  const screenHeight = window.screen.height;
3148
3074
  const minDimension = Math.min(screenWidth, screenHeight);
3149
3075
  const maxDimension = Math.max(screenWidth, screenHeight);
3150
-
3151
- // 平板设备的典型屏幕尺寸范围
3152
3076
  const isTabletByScreenSize =
3153
3077
  minDimension >= 600 &&
3154
3078
  minDimension <= 1200 &&
3155
3079
  maxDimension >= 800 &&
3156
3080
  maxDimension <= 1600;
3157
-
3158
- // 检测是否为移动设备但屏幕较大(可能是平板)
3159
3081
  const isMobile =
3160
3082
  /android|webos|iphone|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
3161
3083
  const isLargeMobile = isMobile && minDimension >= 600;
3162
-
3163
- // 综合判断:用户代理匹配 或 (屏幕尺寸符合平板特征 且 支持触摸) 或 (大屏移动设备)
3164
3084
  return (
3165
3085
  isTabletByUserAgent || (isTabletByScreenSize && hasTouch) || isLargeMobile
3166
3086
  )
@@ -3227,11 +3147,6 @@ function getDeviceInfo() {
3227
3147
  }
3228
3148
  }
3229
3149
 
3230
- /**
3231
- * URL参数处理工具
3232
- * 注意:部分函数依赖浏览器环境(window.location)
3233
- */
3234
-
3235
3150
  /**
3236
3151
  * 将查询字符串转换为对象
3237
3152
  * @param {string} str - 查询字符串,如 'a=1&b=2'
@@ -3269,7 +3184,6 @@ function toQueryString(obj) {
3269
3184
  const encodedKey = encodeURIComponent(key);
3270
3185
  const values = obj[key];
3271
3186
  if (values && values.constructor == Array) {
3272
- // 数组
3273
3187
  const queryValues = [];
3274
3188
  for (let i = 0, len = values.length, value; i < len; i++) {
3275
3189
  value = values[i];
@@ -3277,7 +3191,6 @@ function toQueryString(obj) {
3277
3191
  }
3278
3192
  ret = ret.concat(queryValues);
3279
3193
  } else {
3280
- // 字符串
3281
3194
  ret.push(toQueryPair(encodedKey, values));
3282
3195
  }
3283
3196
  }
@@ -3295,10 +3208,8 @@ function urlToJson(selfUrl) {
3295
3208
  }
3296
3209
  const url = selfUrl ? selfUrl : window.location.href;
3297
3210
 
3298
- const reg = /\?.*$/; // 正则取'?后的参数'
3211
+ const reg = /\?.*$/;
3299
3212
  const urlMatch = url.match(reg);
3300
-
3301
- // 匹配去掉?的纯参数(正则精髓,贪婪永远匹配最后一个?后的参数)
3302
3213
  const param =
3303
3214
  urlMatch && urlMatch.length ? urlMatch[0].replace(/^\?*.*\?/, '') : '';
3304
3215
 
@@ -3338,16 +3249,11 @@ function setUrl(json, originUrl = '') {
3338
3249
  return ''
3339
3250
  }
3340
3251
  let paramJson = urlToJson().paramJson;
3341
- // 新的参数
3342
3252
  let newJson = {
3343
3253
  ...paramJson,
3344
3254
  ...json,
3345
3255
  };
3346
-
3347
- // 参数对象 =》get参数
3348
3256
  let paramStr = toQueryString(newJson);
3349
-
3350
- // url的origin + pathname
3351
3257
  let oPath = originUrl
3352
3258
  ? originUrl
3353
3259
  : window.location.origin + window.location.pathname;
@@ -3369,10 +3275,6 @@ function getUrlParams(url) {
3369
3275
  return urlToJson(targetUrl).paramJson
3370
3276
  }
3371
3277
 
3372
- /**
3373
- * 通用工具函数
3374
- */
3375
-
3376
3278
  /**
3377
3279
  * 将毫秒转换为时分秒
3378
3280
  * @param {number} ms - 毫秒数
@@ -3387,14 +3289,14 @@ function convertMilliseconds(ms, secondsTo2decimal = false) {
3387
3289
  seconds: 0,
3388
3290
  }
3389
3291
 
3390
- const hours = Math.floor(ms / 3600000); // 计算小时
3391
- const minutes = Math.floor((ms % 3600000) / 60000); // 计算分钟
3292
+ const hours = Math.floor(ms / 3600000);
3293
+ const minutes = Math.floor((ms % 3600000) / 60000);
3392
3294
  let seconds = 0;
3393
3295
 
3394
3296
  if (secondsTo2decimal) {
3395
3297
  seconds = parseFloat(((ms % 60000) / 1000).toFixed(2));
3396
3298
  } else {
3397
- seconds = Math.floor((ms % 60000) / 1000); // 计算秒数
3299
+ seconds = Math.floor((ms % 60000) / 1000);
3398
3300
  }
3399
3301
 
3400
3302
  return {
@@ -3552,17 +3454,12 @@ async function copyText(text) {
3552
3454
  }
3553
3455
 
3554
3456
  try {
3555
- // 优先使用现代的Clipboard API
3556
3457
  if (navigator.clipboard && window.isSecureContext) {
3557
3458
  await navigator.clipboard.writeText(text);
3558
3459
  return true
3559
3460
  }
3560
-
3561
- // 降级方案:使用传统的document.execCommand方法
3562
3461
  const textArea = document.createElement('textarea');
3563
3462
  textArea.value = text;
3564
-
3565
- // 防止页面滚动
3566
3463
  textArea.style.position = 'fixed';
3567
3464
  textArea.style.left = '-999999px';
3568
3465
  textArea.style.top = '-999999px';
@@ -3584,10 +3481,6 @@ async function copyText(text) {
3584
3481
  }
3585
3482
  }
3586
3483
 
3587
- /**
3588
- * UUID生成工具
3589
- */
3590
-
3591
3484
  /**
3592
3485
  * 生成短UUID
3593
3486
  * @returns {string} UUID字符串
@@ -3619,11 +3512,6 @@ function uuidLong() {
3619
3512
  return `${uuid()}${uuid()}${uuid()}`
3620
3513
  }
3621
3514
 
3622
- /**
3623
- * 对象属性获取工具
3624
- * 类似lodash的get方法,支持路径字符串和数组
3625
- */
3626
-
3627
3515
  /**
3628
3516
  * 将字符串路径转换为数组
3629
3517
  * @param {string} string - 路径字符串,如 'a.b[0].c'
@@ -3631,7 +3519,7 @@ function uuidLong() {
3631
3519
  */
3632
3520
  function stringToPath(string) {
3633
3521
  const result = [];
3634
- if (string.charCodeAt(0) === 46 /* . */) {
3522
+ if (string.charCodeAt(0) === 46) {
3635
3523
  result.push('');
3636
3524
  }
3637
3525
  string.replace(
@@ -3646,7 +3534,7 @@ function stringToPath(string) {
3646
3534
  /**
3647
3535
  * 转换路径为数组格式
3648
3536
  * @param {string|Array} value - 路径字符串或数组
3649
- * @param {Object} object - 对象(用于兼容性,未使用)
3537
+ * @param {Object} object - 对象
3650
3538
  * @returns {Array} 路径数组
3651
3539
  */
3652
3540
  function castPath(value, object) {
@@ -3697,9 +3585,9 @@ function get(object, path, defaultValue) {
3697
3585
  var index = (options = {}) =>
3698
3586
  async config => {
3699
3587
  const defaultOptions = {
3700
- cacheTime: 0, // 缓存时间,设置为0,不清除缓存
3701
- cache: false, // 是否支持缓存
3702
- noWarn: false, // 是否有提示
3588
+ cacheTime: 0,
3589
+ cache: false,
3590
+ noWarn: false,
3703
3591
  ...options,
3704
3592
  };
3705
3593
 
@@ -3714,7 +3602,6 @@ var index = (options = {}) =>
3714
3602
  if (!responsePromise || !defaultOptions.cache) {
3715
3603
  responsePromise = (async () => {
3716
3604
  try {
3717
- // 需要确保axios可用
3718
3605
  let axios = null;
3719
3606
  if (typeof window !== 'undefined' && window.axios) {
3720
3607
  axios = window.axios;
@@ -3748,7 +3635,7 @@ var index = (options = {}) =>
3748
3635
  }
3749
3636
  }
3750
3637
 
3751
- return responsePromise.then(data => JSON.parse(JSON.stringify(data))) // 为防止数据源污染
3638
+ return responsePromise.then(data => JSON.parse(JSON.stringify(data)))
3752
3639
  };
3753
3640
 
3754
3641
  exports.arrToLabel = arrToLabel;
@@ -3767,7 +3654,6 @@ exports.detectZoom = detectZoom;
3767
3654
  exports.doctorHeadImg = doctorHeadImg;
3768
3655
  exports.escapeRegExp = escapeRegExp;
3769
3656
  exports.extendSession = extendSession;
3770
- exports.extentSession = extentSession;
3771
3657
  exports.fileDownloadHelper = fileDownloadHelper;
3772
3658
  exports.findNodeOfTree = findNodeOfTree;
3773
3659
  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.4",
4
4
  "description": "通用工具函数库,包含格式化、验证、缓存、Session管理、图片URL处理、设备检测、URL处理、UUID生成等常用工具",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",