my-uniapp-tools 4.0.1 → 4.0.3

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
@@ -7,7 +7,6 @@
7
7
  - 🚀 **高性能**: 简化缓存机制,删除过度设计,性能提升20%+
8
8
  - 🛡️ **类型安全**: 完整的 TypeScript 支持
9
9
  - 🔧 **统一错误处理**: 全局错误管理和监控
10
- - 📊 **性能监控**: 可选的性能分析工具
11
10
  - 💾 **本地存储**: 支持TTL过期管理
12
11
  - 🔄 **简洁设计**: 遵循Linus"好品味"原则,消除特殊情况
13
12
  - 📱 **跨平台**: 支持 H5、App、微信/支付宝小程序
@@ -37,19 +36,13 @@ setStorageSync('userInfo', { name: '张三', age: 25 });
37
36
  useToast('操作成功');
38
37
  ```
39
38
 
40
- ### 高级配置
39
+ ### 错误监听(可选)
41
40
 
42
41
  ```javascript
43
- import { initUniAppTools } from 'my-uniapp-tools';
44
-
45
- // 初始化工具库
46
- initUniAppTools({
47
- enablePerformanceMonitor: true, // 启用性能监控
48
- performanceReportInterval: 30000, // 每30秒输出性能报告
49
- enableErrorHandler: true, // 启用错误处理
50
- onError: (error) => { // 自定义错误处理
51
- console.error(error);
52
- }
42
+ import { ErrorHandler } from 'my-uniapp-tools';
43
+
44
+ ErrorHandler.getInstance().onError((error) => {
45
+ console.error(`[${error.module}] ${error.code}: ${error.message}`, error);
53
46
  });
54
47
  ```
55
48
 
@@ -57,21 +50,6 @@ initUniAppTools({
57
50
 
58
51
  ### 🎯 核心功能
59
52
 
60
- #### initUniAppTools(config)
61
-
62
- 初始化工具库配置
63
-
64
- ```javascript
65
- initUniAppTools({
66
- enablePerformanceMonitor: false, // 是否启用性能监控
67
- performanceReportInterval: 0, // 性能报告间隔(ms),0表示不输出
68
- enableErrorHandler: true, // 是否启用错误处理
69
- onError: (error) => { // 自定义错误回调
70
- console.log(`[${error.module}] ${error.message}`);
71
- }
72
- });
73
- ```
74
-
75
53
  #### ErrorHandler
76
54
 
77
55
  全局错误处理器
@@ -88,25 +66,6 @@ errorHandler.onError((error) => {
88
66
  });
89
67
  ```
90
68
 
91
- #### PerformanceMonitor
92
-
93
- 性能监控工具(可选使用)
94
-
95
- ```javascript
96
- import { PerformanceMonitor } from 'my-uniapp-tools';
97
-
98
- const monitor = PerformanceMonitor.getInstance();
99
-
100
- // 开始监控
101
- monitor.start('operationName', 'moduleName');
102
-
103
- // 结束监控
104
- monitor.end('operationName');
105
-
106
- // 获取性能报告
107
- const report = monitor.getReport();
108
- ```
109
-
110
69
  ### 📋 剪贴板功能
111
70
 
112
71
  #### copyText(text, config?)
@@ -122,29 +81,8 @@ await copyText('要复制的文本', {
122
81
  showToast: true, // 是否显示提示
123
82
  successMessage: '复制成功', // 成功提示文本
124
83
  failMessage: '复制失败', // 失败提示文本
125
- timeout: 5000 // 超时时间(ms)
126
- });
127
- ```
128
-
129
- #### readClipboard(config?)
130
-
131
- 读取剪贴板内容(仅H5支持)
132
-
133
- ```javascript
134
- const content = await readClipboard();
135
- if (content) {
136
- console.log('剪贴板内容:', content);
137
- }
138
- ```
139
-
140
- #### isClipboardSupported()
141
-
142
- 检查剪贴板API是否可用
143
-
144
- ```javascript
145
- if (isClipboardSupported()) {
146
- // 执行剪贴板操作
147
- }
84
+ timeout: 5000 // 超时时间(ms)
85
+ });
148
86
  ```
149
87
 
150
88
  ### 💾 本地存储功能
@@ -489,7 +427,6 @@ throttledFn.cancel();
489
427
 
490
428
  ```javascript
491
429
  import {
492
- initUniAppTools,
493
430
  copyText,
494
431
  setStorageSync,
495
432
  navigateTo,
@@ -497,12 +434,6 @@ import {
497
434
  debounce
498
435
  } from 'my-uniapp-tools';
499
436
 
500
- // 应用启动时初始化
501
- initUniAppTools({
502
- enablePerformanceMonitor: false,
503
- enableErrorHandler: true
504
- });
505
-
506
437
  // 页面中使用
507
438
  export default {
508
439
  data() {
@@ -602,10 +533,6 @@ errorHandler.onError((error) => {
602
533
 
603
534
  ## 🐛 常见问题
604
535
 
605
- ### Q: 如何启用性能监控?
606
-
607
- A: 在应用启动时调用 `initUniAppTools({ enablePerformanceMonitor: true, performanceReportInterval: 30000 })`
608
-
609
536
  ### Q: 存储的数据会自动过期吗?
610
537
 
611
538
  A: 是的,设置了TTL的数据会自动过期,可以调用 `cleanExpiredStorage()` 手动清理
@@ -618,25 +545,6 @@ A: 支持 uni-app 的所有平台:H5、App、微信小程序、支付宝小程
618
545
 
619
546
  A: 使用 `safeNavigateTo` 函数,它提供重试机制和更好的错误处理
620
547
 
621
- ### Q: 旧版upload API怎么迁移?
622
-
623
- A: v3.0.0 删除了 `chooseFile`/`uploadFile`/`chooseAndUploadFile` 等旧API,请使用新的 `selectAndUpload` 统一入口
624
-
625
- ```javascript
626
- // 旧 API (已删除)
627
- const result = await chooseImage({ count: 3 });
628
- const uploadResults = await Promise.all(
629
- result.tempFilePaths.map(path => uploadFile(path, { url }))
630
- );
631
-
632
- // 新 API (推荐)
633
- const results = await selectAndUpload({
634
- url,
635
- type: 'image',
636
- count: 3
637
- });
638
- ```
639
-
640
548
  ## 📄 更新日志
641
549
 
642
550
  ### v3.0.2 (当前版本)
package/dist/index.d.ts CHANGED
@@ -1,19 +1,3 @@
1
- /**
2
- * 初始化 UniAppTools
3
- * @param {Object} config 配置项
4
- * @param {boolean} config.enableErrorHandler - 是否启用错误处理器,默认true
5
- * @param {Function} config.onError - 错误回调函数
6
- * @param {boolean} config.showInitMessage - 是否显示初始化消息提示,默认false
7
- * @param {boolean} config.silent - 是否静默模式(不输出任何日志),默认false
8
- * @param {'info'|'warn'|'error'} config.logLevel - 日志输出级别,默认'warn'
9
- */
10
- export function initUniAppTools(config?: {
11
- enableErrorHandler: boolean;
12
- onError: Function;
13
- showInitMessage: boolean;
14
- silent: boolean;
15
- logLevel: "info" | "warn" | "error";
16
- }): void;
17
1
  export * from "./core/errorHandler";
18
2
  export * from "./system";
19
3
  export * from "./utils";
@@ -1 +1 @@
1
- "use strict";var e=require("@vant/area-data");class t extends Error{code;module;timestamp;constructor(e,t,n){super(t),this.name="UniAppToolsError",this.code=e,this.module=n,this.timestamp=Date.now()}}class n{static instance;errorCallbacks=[];static getInstance(){return n.instance||(n.instance=new n),n.instance}onError(e){this.errorCallbacks.push(e)}handleError(e,n){const r={code:e instanceof t?e.code:"UNKNOWN_ERROR",message:e.message,module:e instanceof t?e.module:n,timestamp:e instanceof t?e.timestamp:Date.now(),stack:e.stack};console.error(`[${r.module}] ${r.code}: ${r.message}`,r),this.errorCallbacks.forEach(e=>{try{e(r)}catch(e){console.error("Error in error callback:",e)}})}createModuleErrorHandler(e){return(n,r,s)=>{const o=new t(n,r,e);return s&&(o.stack=s.stack),this.handleError(o,e),o}}}async function r(e,t,r="ASYNC_ERROR"){try{return await e()}catch(e){return n.getInstance().createModuleErrorHandler(t)(r,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function s(e,t,r="SYNC_ERROR",s=null){try{return e()}catch(e){return n.getInstance().createModuleErrorHandler(t)(r,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}const o=n.getInstance();let a=null,i=null,c=null;const u=e=>"weixin"===e||"alipay"===e;let l=!1;const f=()=>{if(a)return a;let e="unknown";return e="weixin",e="web",e="app",e="alipay",e="h5",a="h5","h5"},p=(e=!0)=>e&&c?c:s(()=>{const t=uni.getWindowInfo();return e&&(c=t),t},"system","GET_WINDOW_INFO_ERROR",null),m=()=>{if(null!==i)return i;try{const e=p();return i=e?.statusBarHeight||0,i}catch(e){return o.handleError(new t("GET_STATUS_BAR_HEIGHT_ERROR",`获取状态栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),0}},g=()=>{try{const e=f();return u(e)?uni.getMenuButtonBoundingClientRect():null}catch(e){return o.handleError(new t("GET_MENU_BUTTON_ERROR",`获取菜单按钮边界信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),null}},d=()=>{try{const e=f();if(u(e)){const e=g();return e?.height||44}return 44}catch(e){return o.handleError(new t("GET_NAVIGATION_BAR_HEIGHT_ERROR",`获取导航栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),44}},h=()=>{const e=f(),t=m(),n=d();return{platform:e,statusBarHeight:t,navigationBarHeight:n,totalTopHeight:t+n}},y=n.getInstance();function E(e){if(null===e||"object"!=typeof e)return e;try{if("undefined"!=typeof structuredClone)try{return structuredClone(e)}catch(e){}return JSON.parse(JSON.stringify(e))}catch(e){throw y.handleError(new t("DEEP_CLONE_ERROR",`深拷贝失败: ${e instanceof Error?e.message:String(e)}`,"utils"),"utils"),new Error(`深拷贝失败: ${e instanceof Error?e.message:String(e)}`)}}function w(e,t,n=!1){let r,s=null;const o=function(...o){const a=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(r=e.apply(this,o))},t),a&&(r=e.apply(this,o)),r};return o.cancel=()=>{s&&(clearTimeout(s),s=null)},o}const S=e.areaList,R=e.useCascaderAreaData,T=(e="",t=!1,n="none",r=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:r})},x=n.getInstance();function _(e,t){if(!t||0===Object.keys(t).length)return e;const n=Object.entries(t).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");return e+(e.includes("?")?"&":"?")+n}function A(e,n){x.handleError(new t(e,n,"navigation"),"navigation")}async function v(e){return new Promise(t=>{const n=_(e.url,e.params);uni.navigateTo({url:n,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>t(!0),fail:e=>{A("NAVIGATE_TO_FAILED",`页面跳转失败: ${n}`),t(!1)}})})}async function C(e){return new Promise(t=>{const n=_(e.url,e.params);uni.reLaunch({url:n,success:()=>t(!0),fail:e=>{A("RELAUNCH_FAILED",`重新启动失败: ${n}`),t(!1)}})})}async function P(e="",t={}){return new Promise(n=>{const r=t.delta||1,s=t.timeout||5e3;if(getCurrentPages().length<=r)return console.warn(`[navigation] 无法返回${r}页,当前页面栈深度不足`),void n(!1);const o=setTimeout(()=>{console.warn("[navigation] 导航返回超时"),n(!1)},s);uni.navigateBack({delta:r,success:()=>{clearTimeout(o),setTimeout(()=>{try{const t=getCurrentPages();if(t.length>0){const n=t[t.length-1];n.$vm&&"function"==typeof n.$vm.init&&n.$vm.init(e)}n(!0)}catch(e){A("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),n(!0)}},100)},fail:e=>{clearTimeout(o),A("NAVIGATE_BACK_FAILED","导航返回失败"),n(!1)}})})}const O=w(P,300),I={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3},$=n.getInstance();class b{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return b.instance||(b.instance=new b),b.instance}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,n,r={}){try{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const t={value:n,timestamp:Date.now(),ttl:r.ttl},s=JSON.stringify(t);if(s.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,s),this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}return this.cache.set(e,t),!0}catch(e){throw $.handleError(new t("SET_STORAGE_ERROR",`设置存储失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),e}}get(e,t){try{if(!e||"string"!=typeof e)return t;if(this.cache.has(e)){const n=this.cache.get(e);return this.isExpired(n)?(this.cache.delete(e),this.remove(e),t):n.value}const n=uni.getStorageSync(e);if(!n||"string"!=typeof n)return t;const r=JSON.parse(n);let s;return s=r&&"object"==typeof r&&"value"in r&&"timestamp"in r?r:{value:r,timestamp:Date.now()},this.isExpired(s)?(this.remove(e),t):(this.cache.set(e,s),s.value)}catch(n){return console.warn(`[localStorage] 获取存储失败 [${e}]:`,n),t}}remove(e){try{return!(!e||"string"!=typeof e||(uni.removeStorageSync(e),this.cache.delete(e),0))}catch(n){return $.handleError(new t("REMOVE_STORAGE_ERROR",`删除存储失败: ${e}`,"localStorage"),"localStorage"),!1}}clear(){try{return uni.clearStorageSync(),this.cache.clear(),!0}catch(e){return $.handleError(new t("CLEAR_STORAGE_ERROR","清空存储失败","localStorage"),"localStorage"),!1}}getInfo(){try{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}}catch(e){return $.handleError(new t("GET_STORAGE_INFO_ERROR",`获取存储信息失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),{keys:[],currentSize:0,limitSize:0}}}cleanExpired(){try{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t}catch(e){return $.handleError(new t("CLEAN_EXPIRED_ERROR",`清理过期数据失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),0}}}const D=b.getInstance();function U(e,t,n={}){return D.set(e,t,n)}function L(e,t){return D.get(e,t)}function M(e){const t=e.lastIndexOf(".");if(-1!==t&&t!==e.length-1)return e.slice(t+1).toLowerCase()}function N(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function k(e,t){return t&&e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function H(e,t){if(0===e.length)return{success:!1,files:e,message:"未选择任何文件"};const{maxSelectFileSizeMB:n,extensions:r}=t;if(n&&e.some(e=>!k(e.size,n).valid))return{success:!1,files:e,message:`部分文件大小超过 ${n}MB 限制`};if(r&&r.length>0){const t=r.map(e=>e.toLowerCase());if(e.some(e=>!e.ext||!t.includes(e.ext)))return{success:!1,files:e,message:`存在不支持的文件类型,仅支持:${r.join(", ")}`}}return{success:!0,files:e}}async function F(e,t,n){const{url:r,maxUploadFileSizeMB:s,showToast:o=!0,beforeUpload:a}=t;if("function"==typeof a&&!await Promise.resolve(a(e)))return{file:e,success:!1,message:"已取消上传"};if(!r){const t="上传地址不能为空";return o&&T(t,!1,"error"),Promise.resolve({file:e,success:!1,message:t})}const i=k(e.size,s);return i.valid?"h5"===e.platform&&e.raw instanceof File?function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f,autoRevokeObjectURL:p=!1}=t;return new Promise(t=>{const m=e.raw;if(!(m&&m instanceof File)){const n="H5 环境缺少原生文件对象";return i&&T(n,!1,"none"),void t({file:e,success:!1,message:n})}const g=p&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL&&"string"==typeof e.path&&e.path.startsWith("blob:"),d=()=>{if(g)try{URL.revokeObjectURL(e.path)}catch{}},h=new XMLHttpRequest,y=new FormData;y.append(s,m,e.name),o&&Object.keys(o).forEach(e=>{y.append(e,String(o[e]))}),l&&h.upload.addEventListener("progress",t=>{if(t.lengthComputable){const n=Math.round(t.loaded/t.total*100);l(e,n)}}),h.addEventListener("load",()=>{const r=h.status,s=r>=200&&r<300;let o=h.responseText;try{o=JSON.parse(h.responseText)}catch{}if(s)i&&1===n&&T(c,!1,"none"),d(),t({file:e,success:!0,statusCode:r,data:o});else{const n=`上传失败,状态码:${r}`;i&&T(n,!1,"none"),d(),t({file:e,success:!1,statusCode:r,data:o,message:n})}}),h.addEventListener("error",()=>{const n=u;i&&T(n,!1,"none"),d(),t({file:e,success:!1,message:n})}),h.addEventListener("timeout",()=>{const n=f?`上传超时(${f}ms)`:"上传超时";i&&T(n,!1,"none"),d(),t({file:e,success:!1,message:n})}),h.addEventListener("abort",()=>{d(),t({file:e,success:!1,message:"上传已取消"})}),h.open("POST",r),"number"==typeof f&&f>0&&(h.timeout=f),a&&Object.keys(a).forEach(e=>{h.setRequestHeader(e,a[e])}),h.send(y)})}(e,t,n):function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f}=t,p="undefined"==typeof uni?null:uni;if(!p||"function"!=typeof p.uploadFile){const t="当前环境不支持文件上传";return i&&T(t,!1,"none"),Promise.resolve({file:e,success:!1,message:t})}return new Promise(t=>{let m=!1,g=null;const d=e=>{m||(m=!0,g&&(clearTimeout(g),g=null),t(e))};let h=null;"number"==typeof f&&f>0&&(g=setTimeout(()=>{try{h&&"function"==typeof h.abort&&h.abort()}catch{}const t=`上传超时(${f}ms)`;i&&T(t,!1,"none"),d({file:e,success:!1,message:t})},f)),h=p.uploadFile({url:r,filePath:e.path,name:s,formData:o,header:a,success:t=>{let r=t.data;try{r=JSON.parse(t.data)}catch{}const s=t.statusCode;if(s>=200&&s<300)i&&1===n&&T(c,!1,"none"),d({file:e,success:!0,statusCode:s,data:r});else{const t=`上传失败,状态码:${s}`;i&&T(t,!1,"none"),d({file:e,success:!1,statusCode:s,data:r,message:t})}},fail:t=>{const n=t?.errMsg||u;i&&T(n,!1,"none"),d({file:e,success:!1,message:n})}}),l&&h&&"function"==typeof h.onProgressUpdate&&h.onProgressUpdate(t=>{l(e,t.progress)})})}(e,t,n):(o&&i.message&&T(i.message,!1,"error"),Promise.resolve({file:e,success:!1,message:i.message}))}async function B(e){const{showToast:t=!0,failMessage:n="选择文件失败"}=e;try{const r=await async function(e){return"undefined"!=typeof document&&"undefined"!=typeof window?function(e){const{type:t="image",count:n=1,extensions:r}=e;return new Promise(s=>{if("undefined"==typeof document)return void s({success:!1,files:[],message:"当前环境不支持文件选择"});const o=document.createElement("input");o.type="file",o.multiple=n>1,"image"===t?o.accept="image/*":r&&r.length>0&&(o.accept=r.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),o.onchange=t=>{const n=t.target,r=n?.files;if(!r||0===r.length)return s({success:!1,files:[],message:"用户取消选择"}),void document.body.removeChild(o);const a=H(Array.from(r).map((e,t)=>{const n=M(e.name),r=URL.createObjectURL(e);return{id:N(t),name:e.name,size:e.size,path:r,mimeType:e.type,ext:n,source:"file",platform:"h5",raw:e}}),e);s(a),document.body.removeChild(o)},o.style.display="none",document.body.appendChild(o),o.click()})}(e):function(e){const{type:t="image",count:n=1}=e;return new Promise(r=>{const s="undefined"==typeof uni?null:uni;if(!s)return void r({success:!1,files:[],message:"当前环境不支持文件选择"});const o=e=>{const t=function(e){const t=(e||"").trim();if(!t)return"选择文件失败";const n=t.toLowerCase();return n.includes("fail cancel")||n.includes("cancel")?"用户取消选择":/[\u4e00-\u9fff]/.test(t)?t:"选择文件失败"}(e?.errMsg);r({success:!1,files:[],message:t})},a=function(){let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}();"image"!==t||"function"!=typeof s.chooseImage?"function"!=typeof s.chooseMessageFile?"function"!=typeof s.chooseFile?r({success:!1,files:[],message:"当前平台不支持文件选择"}):s.chooseFile({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=M(e.path);return{id:N(t),name:`file_${t}`,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(H(n,e))},fail:o}):s.chooseMessageFile({count:n,type:"all",success:t=>{const n=t.tempFiles.map((e,t)=>{const n=M(e.name||e.path);return{id:N(t),name:e.name,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(H(n,e))},fail:o}):s.chooseImage({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=M(e.path);return{id:N(t),name:`image_${t}`,size:e.size,path:e.path,ext:n,source:"album",platform:a,raw:e}});r(H(n,e))},fail:o})})}(e)}(e);if(!r.success){const e=r.message||n;return t&&e&&T(e,!1,"none"),[{file:null,success:!1,message:e}]}const s=r.files;if(0===s.length)return[];const o=s.length;return await async function(e,t,n){const r=new Array(e.length),s=t.concurrency&&t.concurrency>0?Math.min(t.concurrency,e.length):e.length;let o=0;const a=async()=>{for(;;){const s=o;if(s>=e.length)break;o+=1;const a=e[s],i=await F(a,t,n);r[s]=i}},i=[];for(let e=0;e<s;e+=1)i.push(a());return await Promise.all(i),r}(s,e,o)}catch(e){const r=n;return t&&r&&T(r,!1,"none"),[{file:null,success:!1,message:r}]}}const j=n.getInstance(),G=n.getInstance(),W=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),J=()=>"undefined"!=typeof window&&"undefined"!=typeof document,z=()=>J()&&W()&&window.wx||null;let K=!1,q=null;const V=(e={})=>{const{timeoutMs:t=1e4}=e;if(K||J()&&window.wx)return K=!0,Promise.resolve(!0);if(!J())return Promise.resolve(!1);if(q)return q;const n=e.cdnUrls&&e.cdnUrls.length>0?e.cdnUrls:["https://res.wx.qq.com/open/js/jweixin-1.6.0.js","https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"];return q=new Promise(e=>{let r=!1,s=null,o=null,a=0;const i=t=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(K=!0),q=null,e(t))},c=()=>{if(a>=n.length)return void i(!1);if(!document.head)return void i(!1);const e=n[a];a+=1;const t=document.createElement("script");o=t,t.src=e,t.async=!0,t.onload=()=>i(!0),t.onerror=()=>{t.parentNode&&t.parentNode.removeChild(t),o=null,c()},document.head.appendChild(t)};s=setTimeout(()=>{i(!1)},t),c()}),q};let Y=null;const X=async(e,n={})=>{const{timeoutMs:r=1e4}=n;if(!W())return console.warn("当前不在微信环境中"),!1;if(Y)return Y;if(!await V({timeoutMs:r}))return G.handleError(new t("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;if(!J())return!1;const s=window.wx;return!!s&&(Y=new Promise(n=>{let o=!1,a=null;const i=e=>{o||(o=!0,a&&(clearTimeout(a),a=null),Y=null,n(e))};a=setTimeout(()=>i(!1),r);try{s.config({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),s.ready(()=>{console.log("微信 JS-SDK 初始化完成"),i(!0)}),s.error(e=>{G.handleError(new t("WECHAT_JSSDK_CONFIG_ERROR",`微信 JS-SDK 配置错误: ${JSON.stringify(e)}`,"weixin"),"weixin"),i(!1)})}catch(e){G.handleError(new t("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),i(!1)}}),Y)},Q=e=>{const t=z();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},Z=e=>{const t=z();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class ee{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return ee.instance||(ee.instance=new ee),ee.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=X(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return this.isConfigured&&W()}getConfig(){return this.config}setShareData(e){this.isReady()?(Q(e),Z(e)):console.warn("微信 SDK 未就绪")}}const te="4.0.0",ne={info:0,warn:1,error:2};exports.ErrorHandler=n,exports.UniAppToolsError=t,exports.VERSION=te,exports.WechatSDK=ee,exports.areaList=S,exports.batchGetStorage=function(e){const t={};return e.forEach(e=>{t[e]=L(e)}),t},exports.batchSetStorage=function(e,t={}){let n=0;return Object.entries(e).forEach(([e,r])=>{U(e,r,t)&&n++}),n},exports.buildUrl=_,exports.checkWechatJSAPI=(e,n={})=>{const{timeoutMs:r=8e3}=n;return new Promise(n=>{const s=z();if(!s||"function"!=typeof s.checkJsApi)return void n({});let o=!1;const a=e=>{o||(o=!0,n(e))},i=setTimeout(()=>a({}),r);try{s.checkJsApi({jsApiList:e,success:e=>{clearTimeout(i),a(e?.checkResult||{})}})}catch(e){clearTimeout(i),G.handleError(new t("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),a({})}})},exports.cleanExpiredStorage=function(){return D.cleanExpired()},exports.clearStorageSync=function(e){return e?D.remove(e):D.clear()},exports.clearSystemCache=()=>{c=null},exports.configWechatJSSDK=X,exports.copyText=async function(e,t={}){const n={...I,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&T("复制内容过长",!1,"error"),!1):await r(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&T(n.successMessage),t(!0)},fail:()=>{n.showToast&&T(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&T("复制内容不能为空",!1,"error"),!1)},exports.debounce=w,exports.deepClone=E,exports.deepMerge=function(e,t){const n=E(e);return function e(t,n){for(const r in n)if(n.hasOwnProperty(r)){const s=n[r],o=t[r];s&&"object"==typeof s&&!Array.isArray(s)&&o&&"object"==typeof o&&!Array.isArray(o)?e(o,s):t[r]=E(s)}}(n,t),n},exports.extractUrlParts=function(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,r={};return t.searchParams.forEach((e,t)=>{r[t]=e}),{path:n,params:r}}catch(n){return y.handleError(new t("EXTRACT_URL_PARTS_ERROR",`无效的URL: ${e}`,"utils"),"utils"),{path:"",params:{}}}},exports.getCurrentEnv=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return o.handleError(new t("GET_ACCOUNT_INFO_ERROR",`获取小程序账户信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),{appId:"",version:"",envVersion:"",accountInfo:{}}}},exports.getCurrentPageInfo=function(){try{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}}catch(e){return A("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}},exports.getH5UrlParams=e=>{try{if("undefined"==typeof window||!window.location)throw new Error("不在 H5 浏览器环境中");const t=new URLSearchParams(window.location.search),n={};return t.forEach((e,t)=>{try{n[t]=decodeURIComponent(e)}catch(r){n[t]=e}}),console.log("🔗 H5 URL参数解析:",{fullUrl:window.location.href,searchParams:window.location.search,parsedParams:n,paramName:e}),e?n.hasOwnProperty(e)?n[e]:null:n}catch(n){return y.handleError(new t("GET_H5_URL_PARAMS_ERROR",`获取H5 URL参数失败: ${n instanceof Error?n.message:String(n)}`,"utils"),"utils"),e?null:{}}},exports.getMenuButtonBoundingClientRect=g,exports.getNavHeight=()=>h().totalTopHeight,exports.getNavigationBarHeight=d,exports.getPageStack=function(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return A("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}},exports.getPlatform=f,exports.getStatusBarHeight=m,exports.getStorage=async function(e,t){return await r(()=>new Promise(n=>{n(L(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t},exports.getStorageInfo=function(){return D.getInfo()},exports.getStorageSync=L,exports.getTopBarMetrics=h,exports.getTopNavBarHeight=()=>{const e=h();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},exports.initUniAppTools=function(e={}){const{enableErrorHandler:t=!0,onError:r=null,showInitMessage:s=!1,silent:o=!1,logLevel:a="warn"}=e,i=ne[a]||ne.warn;if(t){const e=n.getInstance();"function"==typeof r?e.onError(r):e.onError(e=>{((...e)=>{!o&&i<=ne.error&&console.error(...e)})(`[UniAppTools] ${e.module} - ${e.code}: ${e.message}`,e)})}if(((...e)=>{!o&&i<=ne.info&&console.log(...e)})(`[UniAppTools] v${te} 初始化完成`),s&&"undefined"!=typeof uni)try{uni.showToast({title:`工具库v${te}已就绪`,icon:"none",duration:2e3})}catch(e){}},exports.isWechat=W,exports.loadWechatJSSDK=V,exports.mergeObjects=function(e,t){if(!t||0===Object.keys(t).length)return e;const n={...e};for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n},exports.navigateTo=v,exports.onCheckForUpdate=()=>{if(!l)try{const e=uni.getUpdateManager();l=!0,e.onCheckForUpdate(function(e){e.hasUpdate}),e.onUpdateReady(function(t){uni.showModal({title:"更新提示",content:"新版本已经准备好,是否重启应用?",showCancel:!0,cancelText:"稍后",confirmText:"立即重启",success(t){t.confirm&&e.applyUpdate()}})}),e.onUpdateFailed(function(e){o.handleError(new t("UPDATE_DOWNLOAD_FAILED","新版本下载失败","system"),"system"),uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){o.handleError(new t("CHECK_UPDATE_ERROR",`版本更新检查失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system")}},exports.reLaunch=C,exports.redirectTo=async function(e){return new Promise(t=>{const n=_(e.url,e.params);uni.redirectTo({url:n,success:()=>t(!0),fail:e=>{A("REDIRECT_TO_FAILED",`页面重定向失败: ${n}`),t(!1)}})})},exports.safeAsync=r,exports.safeNavigateTo=async function(e,t=3){for(let n=0;n<t;n++){if(await v(e))return!0;n<t-1&&(await new Promise(e=>setTimeout(e,1e3*(n+1))),console.log(`[navigation] 第${n+2}次尝试跳转...`))}return!1},exports.safeSync=s,exports.selectAndUpload=B,exports.selectAndUploadImage=async function(e){return B({...e,type:"image"})},exports.setPageIcon=(e,t="image/x-icon")=>s(()=>{const n=f();if("h5"===n||"web"===n){if("undefined"!=typeof document){document.querySelectorAll('link[rel*="icon"]').forEach(e=>e.remove());const n=document.createElement("link");return n.rel="icon",n.type=t,n.href=e,document.head.appendChild(n),!0}}else console.warn("setPageIcon 仅在H5/Web平台有效");return!1},"system","SET_PAGE_ICON_ERROR",!1),exports.setPageTitle=e=>"string"!=typeof e?(console.warn("setPageTitle: title必须是字符串"),Promise.resolve(!1)):""===e.trim()?(console.warn("setPageTitle: title不能为空"),Promise.resolve(!1)):new Promise(n=>{try{uni.setNavigationBarTitle({title:e,success:()=>{n(!0)},fail:e=>{console.warn("设置页面标题失败:",e),n(!1)}})}catch(e){o.handleError(new t("SET_PAGE_TITLE_ERROR",`setPageTitle执行异常: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),n(!1)}}),exports.setStorage=async function(e,t,n={}){return await r(()=>new Promise(r=>{r(U(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1},exports.setStorageSync=U,exports.shareToFriend=Z,exports.shareToTimeline=Q,exports.switchTab=async function(e){return new Promise(t=>{uni.switchTab({url:e,success:()=>t(!0),fail:n=>{A("SWITCH_TAB_FAILED",`Tab切换失败: ${e}`),t(!1)}})})},exports.throttle=function(e,t,n={}){let r,s=null,o=0;const{leading:a=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();o||a||(o=c);const u=t-(c-o);return u<=0||u>t?(s&&(clearTimeout(s),s=null),o=c,r=e.apply(this,n)):!s&&i&&(s=setTimeout(()=>{o=a?Date.now():0,s=null,r=e.apply(this,n)},u)),r};return c.cancel=()=>{s&&(clearTimeout(s),s=null),o=0},c},exports.useBack=P,exports.useBackDebounced=O,exports.useBackOrHome=async function(e="",t={}){const n=getCurrentPages(),r=t.delta||1;if(n.length>r)return await P(e,t);const s=t.homePage||"pages/index/index",o=s.startsWith("/")?s:`/${s}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),await C({url:o,params:t.homeParams})},exports.useCascaderAreaData=R,exports.useRegions=function(){return e.useCascaderAreaData()},exports.useToast=T,exports.useTryCatch=function(e,t={}){return async(...n)=>{try{return{data:await e(...n),error:null}}catch(e){return t.onError?.(e),{data:null,error:e}}finally{t.onFinally?.()}}},exports.useWindowInfo=p,exports.weChatOfficialAccountPayment=(e,n,r)=>new Promise(o=>{s(()=>{if("undefined"==typeof window||!window.navigator)throw new Error("不在浏览器环境中,无法调用微信支付");if(!(e&&e.appId&&e.timeStamp&&e.nonceStr&&e.package&&e.paySign))throw new Error("微信支付配置参数不完整");function s(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){console.log("🚀 ~ 微信支付结果:",e),"get_brand_wcpay_request:ok"===e.err_msg?(console.log("✅ 微信支付成功"),n?.(e),o(!0)):(console.warn("❌ 微信支付失败或取消:",e.err_msg),r?.(e),o(!1))})}catch(e){j.handleError(new t("WECHAT_PAY_INVOKE_ERROR",`调用微信支付接口失败: ${e instanceof Error?e.message:String(e)}`,"payment"),"payment");const n={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};r?.(n),o(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",s,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",s),e.attachEvent("onWeixinJSBridgeReady",s))}else s();return!0},"payment","WECHAT_PAY_ERROR",!1)||o(!1)});
1
+ "use strict";var e=require("@vant/area-data");class t extends Error{code;module;timestamp;constructor(e,t,n){super(t),this.name="UniAppToolsError",this.code=e,this.module=n,this.timestamp=Date.now()}}class n{static instance;errorCallbacks=[];static getInstance(){return n.instance||(n.instance=new n),n.instance}onError(e){this.errorCallbacks.push(e)}handleError(e,n){const r={code:e instanceof t?e.code:"UNKNOWN_ERROR",message:e.message,module:e instanceof t?e.module:n,timestamp:e instanceof t?e.timestamp:Date.now(),stack:e.stack};console.error(`[${r.module}] ${r.code}: ${r.message}`,r),this.errorCallbacks.forEach(e=>{try{e(r)}catch(e){console.error("Error in error callback:",e)}})}createModuleErrorHandler(e){return(n,r,s)=>{const o=new t(n,r,e);return s&&(o.stack=s.stack),this.handleError(o,e),o}}}async function r(e,t,r="ASYNC_ERROR"){try{return await e()}catch(e){return n.getInstance().createModuleErrorHandler(t)(r,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function s(e,t,r="SYNC_ERROR",s=null){try{return e()}catch(e){return n.getInstance().createModuleErrorHandler(t)(r,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}const o=n.getInstance();let a=null,i=null,c=null;const u=e=>"weixin"===e||"alipay"===e;let l=!1;const f=()=>{if(a)return a;let e="unknown";try{"undefined"!=typeof uni&&("undefined"!=typeof wx&&wx.getSystemInfoSync?e="weixin":"undefined"!=typeof my&&my.getSystemInfoSync?e="alipay":"undefined"!=typeof window&&window.document?e="h5":"undefined"!=typeof plus&&(e="app"))}catch(t){e="weixin",e="web",e="app",e="alipay",e="h5"}return a=e,e},p=(e=!0)=>e&&c?c:s(()=>{const t=uni.getWindowInfo();return e&&(c=t),t},"system","GET_WINDOW_INFO_ERROR",null),m=()=>{if(null!==i)return i;try{const e=p();return i=e?.statusBarHeight||0,i}catch(e){return o.handleError(new t("GET_STATUS_BAR_HEIGHT_ERROR",`获取状态栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),0}},g=()=>{try{const e=f();return u(e)?uni.getMenuButtonBoundingClientRect():null}catch(e){return o.handleError(new t("GET_MENU_BUTTON_ERROR",`获取菜单按钮边界信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),null}},d=()=>{try{const e=f();if(u(e)){const e=g();return e?.height||44}return 44}catch(e){return o.handleError(new t("GET_NAVIGATION_BAR_HEIGHT_ERROR",`获取导航栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),44}},h=()=>{const e=f(),t=m(),n=d();return{platform:e,statusBarHeight:t,navigationBarHeight:n,totalTopHeight:t+n}},y=n.getInstance();function w(e){if(null===e||"object"!=typeof e)return e;try{if("undefined"!=typeof structuredClone)try{return structuredClone(e)}catch(e){}return JSON.parse(JSON.stringify(e))}catch(e){throw y.handleError(new t("DEEP_CLONE_ERROR",`深拷贝失败: ${e instanceof Error?e.message:String(e)}`,"utils"),"utils"),new Error(`深拷贝失败: ${e instanceof Error?e.message:String(e)}`)}}function E(e,t,n=!1){let r,s=null;const o=function(...o){const a=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(r=e.apply(this,o))},t),a&&(r=e.apply(this,o)),r};return o.cancel=()=>{s&&(clearTimeout(s),s=null)},o}const S=e.areaList,R=e.useCascaderAreaData,T=(e="",t=!1,n="none",r=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:r})},x=n.getInstance();function _(e,t){if(!t||0===Object.keys(t).length)return e;const n=Object.entries(t).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");return e+(e.includes("?")?"&":"?")+n}function A(e,n){x.handleError(new t(e,n,"navigation"),"navigation")}async function v(e){return new Promise(t=>{const n=_(e.url,e.params);uni.navigateTo({url:n,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>t(!0),fail:e=>{A("NAVIGATE_TO_FAILED",`页面跳转失败: ${n}`),t(!1)}})})}async function C(e){return new Promise(t=>{const n=_(e.url,e.params);uni.reLaunch({url:n,success:()=>t(!0),fail:e=>{A("RELAUNCH_FAILED",`重新启动失败: ${n}`),t(!1)}})})}async function P(e="",t={}){return new Promise(n=>{const r=t.delta||1,s=t.timeout||5e3;if(getCurrentPages().length<=r)return console.warn(`[navigation] 无法返回${r}页,当前页面栈深度不足`),void n(!1);const o=setTimeout(()=>{console.warn("[navigation] 导航返回超时"),n(!1)},s);uni.navigateBack({delta:r,success:()=>{clearTimeout(o),setTimeout(()=>{try{const t=getCurrentPages();if(t.length>0){const n=t[t.length-1];n.$vm&&"function"==typeof n.$vm.init&&n.$vm.init(e)}n(!0)}catch(e){A("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),n(!0)}},100)},fail:e=>{clearTimeout(o),A("NAVIGATE_BACK_FAILED","导航返回失败"),n(!1)}})})}const O=E(P,300),I={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3},$=n.getInstance();class b{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return b.instance||(b.instance=new b),b.instance}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,n,r={}){try{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const t={value:n,timestamp:Date.now(),ttl:r.ttl},s=JSON.stringify(t);if(s.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,s),this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}return this.cache.set(e,t),!0}catch(e){throw $.handleError(new t("SET_STORAGE_ERROR",`设置存储失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),e}}get(e,t){try{if(!e||"string"!=typeof e)return t;if(this.cache.has(e)){const n=this.cache.get(e);return this.isExpired(n)?(this.cache.delete(e),this.remove(e),t):n.value}const n=uni.getStorageSync(e);if(!n||"string"!=typeof n)return t;const r=JSON.parse(n);let s;return s=r&&"object"==typeof r&&"value"in r&&"timestamp"in r?r:{value:r,timestamp:Date.now()},this.isExpired(s)?(this.remove(e),t):(this.cache.set(e,s),s.value)}catch(n){return console.warn(`[localStorage] 获取存储失败 [${e}]:`,n),t}}remove(e){try{return!(!e||"string"!=typeof e||(uni.removeStorageSync(e),this.cache.delete(e),0))}catch(n){return $.handleError(new t("REMOVE_STORAGE_ERROR",`删除存储失败: ${e}`,"localStorage"),"localStorage"),!1}}clear(){try{return uni.clearStorageSync(),this.cache.clear(),!0}catch(e){return $.handleError(new t("CLEAR_STORAGE_ERROR","清空存储失败","localStorage"),"localStorage"),!1}}getInfo(){try{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}}catch(e){return $.handleError(new t("GET_STORAGE_INFO_ERROR",`获取存储信息失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),{keys:[],currentSize:0,limitSize:0}}}cleanExpired(){try{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t}catch(e){return $.handleError(new t("CLEAN_EXPIRED_ERROR",`清理过期数据失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),0}}}const D=b.getInstance();function L(e,t,n={}){return D.set(e,t,n)}function M(e,t){return D.get(e,t)}function U(e){const t=e.lastIndexOf(".");if(-1!==t&&t!==e.length-1)return e.slice(t+1).toLowerCase()}function N(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function k(e,t){return t&&e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function H(e,t){if(0===e.length)return{success:!1,files:e,message:"未选择任何文件"};const{maxSelectFileSizeMB:n,extensions:r}=t;if(n&&e.some(e=>!k(e.size,n).valid))return{success:!1,files:e,message:`部分文件大小超过 ${n}MB 限制`};if(r&&r.length>0){const t=r.map(e=>e.toLowerCase());if(e.some(e=>!e.ext||!t.includes(e.ext)))return{success:!1,files:e,message:`存在不支持的文件类型,仅支持:${r.join(", ")}`}}return{success:!0,files:e}}async function F(e,t,n){const{url:r,maxUploadFileSizeMB:s,showToast:o=!0,beforeUpload:a}=t;if("function"==typeof a&&!await Promise.resolve(a(e)))return{file:e,success:!1,message:"已取消上传"};if(!r){const t="上传地址不能为空";return o&&T(t,!1,"error"),Promise.resolve({file:e,success:!1,message:t})}const i=k(e.size,s);return i.valid?"h5"===e.platform&&e.raw instanceof File?function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f,autoRevokeObjectURL:p=!1}=t;return new Promise(t=>{const m=e.raw;if(!(m&&m instanceof File)){const n="H5 环境缺少原生文件对象";return i&&T(n,!1,"none"),void t({file:e,success:!1,message:n})}const g=p&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL&&"string"==typeof e.path&&e.path.startsWith("blob:"),d=()=>{if(g)try{URL.revokeObjectURL(e.path)}catch{}},h=new XMLHttpRequest,y=new FormData;y.append(s,m,e.name),o&&Object.keys(o).forEach(e=>{y.append(e,String(o[e]))}),l&&h.upload.addEventListener("progress",t=>{if(t.lengthComputable){const n=Math.round(t.loaded/t.total*100);l(e,n)}}),h.addEventListener("load",()=>{const r=h.status,s=r>=200&&r<300;let o=h.responseText;try{o=JSON.parse(h.responseText)}catch{}if(s)i&&1===n&&T(c,!1,"none"),d(),t({file:e,success:!0,statusCode:r,data:o});else{const n=`上传失败,状态码:${r}`;i&&T(n,!1,"none"),d(),t({file:e,success:!1,statusCode:r,data:o,message:n})}}),h.addEventListener("error",()=>{const n=u;i&&T(n,!1,"none"),d(),t({file:e,success:!1,message:n})}),h.addEventListener("timeout",()=>{const n=f?`上传超时(${f}ms)`:"上传超时";i&&T(n,!1,"none"),d(),t({file:e,success:!1,message:n})}),h.addEventListener("abort",()=>{d(),t({file:e,success:!1,message:"上传已取消"})}),h.open("POST",r),"number"==typeof f&&f>0&&(h.timeout=f),a&&Object.keys(a).forEach(e=>{h.setRequestHeader(e,a[e])}),h.send(y)})}(e,t,n):function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f}=t,p="undefined"==typeof uni?null:uni;if(!p||"function"!=typeof p.uploadFile){const t="当前环境不支持文件上传";return i&&T(t,!1,"none"),Promise.resolve({file:e,success:!1,message:t})}return new Promise(t=>{let m=!1,g=null;const d=e=>{m||(m=!0,g&&(clearTimeout(g),g=null),t(e))};let h=null;"number"==typeof f&&f>0&&(g=setTimeout(()=>{try{h&&"function"==typeof h.abort&&h.abort()}catch{}const t=`上传超时(${f}ms)`;i&&T(t,!1,"none"),d({file:e,success:!1,message:t})},f)),h=p.uploadFile({url:r,filePath:e.path,name:s,formData:o,header:a,success:t=>{let r=t.data;try{r=JSON.parse(t.data)}catch{}const s=t.statusCode;if(s>=200&&s<300)i&&1===n&&T(c,!1,"none"),d({file:e,success:!0,statusCode:s,data:r});else{const t=`上传失败,状态码:${s}`;i&&T(t,!1,"none"),d({file:e,success:!1,statusCode:s,data:r,message:t})}},fail:t=>{const n=t?.errMsg||u;i&&T(n,!1,"none"),d({file:e,success:!1,message:n})}}),l&&h&&"function"==typeof h.onProgressUpdate&&h.onProgressUpdate(t=>{l(e,t.progress)})})}(e,t,n):(o&&i.message&&T(i.message,!1,"error"),Promise.resolve({file:e,success:!1,message:i.message}))}async function B(e){const{showToast:t=!0,failMessage:n="选择文件失败"}=e;try{const r=await async function(e){return"undefined"!=typeof document&&"undefined"!=typeof window?function(e){const{type:t="image",count:n=1,extensions:r}=e;return new Promise(s=>{if("undefined"==typeof document)return void s({success:!1,files:[],message:"当前环境不支持文件选择"});const o=document.createElement("input");o.type="file",o.multiple=n>1,"image"===t?o.accept="image/*":r&&r.length>0&&(o.accept=r.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),o.onchange=t=>{const n=t.target,r=n?.files;if(!r||0===r.length)return s({success:!1,files:[],message:"用户取消选择"}),void document.body.removeChild(o);const a=H(Array.from(r).map((e,t)=>{const n=U(e.name),r=URL.createObjectURL(e);return{id:N(t),name:e.name,size:e.size,path:r,mimeType:e.type,ext:n,source:"file",platform:"h5",raw:e}}),e);s(a),document.body.removeChild(o)},o.style.display="none",document.body.appendChild(o),o.click()})}(e):function(e){const{type:t="image",count:n=1}=e;return new Promise(r=>{const s="undefined"==typeof uni?null:uni;if(!s)return void r({success:!1,files:[],message:"当前环境不支持文件选择"});const o=e=>{const t=function(e){const t=(e||"").trim();if(!t)return"选择文件失败";const n=t.toLowerCase();return n.includes("fail cancel")||n.includes("cancel")?"用户取消选择":/[\u4e00-\u9fff]/.test(t)?t:"选择文件失败"}(e?.errMsg);r({success:!1,files:[],message:t})},a=function(){let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}();"image"!==t||"function"!=typeof s.chooseImage?"function"!=typeof s.chooseMessageFile?"function"!=typeof s.chooseFile?r({success:!1,files:[],message:"当前平台不支持文件选择"}):s.chooseFile({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=U(e.path);return{id:N(t),name:`file_${t}`,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(H(n,e))},fail:o}):s.chooseMessageFile({count:n,type:"all",success:t=>{const n=t.tempFiles.map((e,t)=>{const n=U(e.name||e.path);return{id:N(t),name:e.name,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(H(n,e))},fail:o}):s.chooseImage({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=U(e.path);return{id:N(t),name:`image_${t}`,size:e.size,path:e.path,ext:n,source:"album",platform:a,raw:e}});r(H(n,e))},fail:o})})}(e)}(e);if(!r.success){const e=r.message||n;return t&&e&&T(e,!1,"none"),[{file:null,success:!1,message:e}]}const s=r.files;if(0===s.length)return[];const o=s.length;return await async function(e,t,n){const r=new Array(e.length),s=t.concurrency&&t.concurrency>0?Math.min(t.concurrency,e.length):e.length;let o=0;const a=async()=>{for(;;){const s=o;if(s>=e.length)break;o+=1;const a=e[s],i=await F(a,t,n);r[s]=i}},i=[];for(let e=0;e<s;e+=1)i.push(a());return await Promise.all(i),r}(s,e,o)}catch(e){const r=n;return t&&r&&T(r,!1,"none"),[{file:null,success:!1,message:r}]}}const j=n.getInstance(),G=n.getInstance(),W=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),J=()=>"undefined"!=typeof window&&"undefined"!=typeof document,z=()=>J()&&W()&&window.wx||null,K=(e,t=!1)=>{const n={};return e.forEach(e=>{"string"==typeof e&&""!==e.trim()&&(n[e]=t)}),n};let q=!1,V=null,Y=!1;const X=(e={})=>{const{timeoutMs:t=1e4}=e;if(q||J()&&window.wx)return q=!0,Promise.resolve(!0);if(!J())return Promise.resolve(!1);if(V)return V;const n=e.cdnUrls&&e.cdnUrls.length>0?e.cdnUrls:["https://res.wx.qq.com/open/js/jweixin-1.6.0.js","https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"];return V=new Promise(e=>{let r=!1,s=null,o=null,a=0;const i=t=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(q=!0),V=null,e(t))},c=()=>{if(a>=n.length)return void i(!1);if(!document.head)return void i(!1);const e=n[a];a+=1;const t=document.createElement("script");o=t,t.src=e,t.async=!0,t.onload=()=>i(!0),t.onerror=()=>{t.parentNode&&t.parentNode.removeChild(t),o=null,c()},document.head.appendChild(t)};s=setTimeout(()=>{i(!1)},t),c()}),V};let Q=null;const Z=async(e,n={})=>{const{timeoutMs:r=1e4}=n;return W()?Q||(Q=(async()=>{if(!await X({timeoutMs:r}))return G.handleError(new t("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;const n=z();if(!n||"function"!=typeof n.config||"function"!=typeof n.ready||"function"!=typeof n.error)return!1;const s=n.config,o=n.ready,a=n.error,i=await new Promise(n=>{let i=!1,c=null;const u=e=>{i||(i=!0,c&&(clearTimeout(c),c=null),n(e))};c=setTimeout(()=>u(!1),r);try{s({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),o(()=>u(!0)),a(e=>{G.handleError(new t("WECHAT_JSSDK_CONFIG_ERROR",`微信 JS-SDK 配置错误: ${(e=>{try{return JSON.stringify(e)}catch{return String(e)}})(e)}`,"weixin"),"weixin"),u(!1)})}catch(e){G.handleError(new t("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),u(!1)}});return Y=i,i})().finally(()=>{Q=null}),Q):(console.warn("当前不在微信环境中"),!1)},ee=e=>{const t=z();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},te=e=>{const t=z();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class ne{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return ne.instance||(ne.instance=new ne),ne.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=Z(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return(this.isConfigured||Y)&&W()}getConfig(){return this.config}setShareData(e){this.isReady()?(ee(e),te(e)):console.warn("微信 SDK 未就绪")}}exports.ErrorHandler=n,exports.UniAppToolsError=t,exports.VERSION="4.0.0",exports.WechatSDK=ne,exports.areaList=S,exports.batchGetStorage=function(e){const t={};return e.forEach(e=>{t[e]=M(e)}),t},exports.batchSetStorage=function(e,t={}){let n=0;return Object.entries(e).forEach(([e,r])=>{L(e,r,t)&&n++}),n},exports.buildUrl=_,exports.checkWechatJSAPI=(e,n={})=>{const{timeoutMs:r=8e3}=n;return new Promise(n=>{const s=z();if(!s||"function"!=typeof s.checkJsApi)return void n(K(e,!1));let o=!1;const a=e=>{o||(o=!0,n(e))},i=setTimeout(()=>a(K(e,!1)),r);try{s.checkJsApi({jsApiList:e,success:t=>{clearTimeout(i),a({...K(e,!1),...t?.checkResult||{}})}})}catch(n){clearTimeout(i),G.handleError(new t("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${n instanceof Error?n.message:String(n)}`,"weixin"),"weixin"),a(K(e,!1))}})},exports.cleanExpiredStorage=function(){return D.cleanExpired()},exports.clearStorageSync=function(e){return e?D.remove(e):D.clear()},exports.clearSystemCache=()=>{c=null},exports.configWechatJSSDK=Z,exports.copyText=async function(e,t={}){const n={...I,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&T("复制内容过长",!1,"error"),!1):await r(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&T(n.successMessage),t(!0)},fail:()=>{n.showToast&&T(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&T("复制内容不能为空",!1,"error"),!1)},exports.debounce=E,exports.deepClone=w,exports.deepMerge=function(e,t){const n=w(e);return function e(t,n){for(const r in n)if(n.hasOwnProperty(r)){const s=n[r],o=t[r];s&&"object"==typeof s&&!Array.isArray(s)&&o&&"object"==typeof o&&!Array.isArray(o)?e(o,s):t[r]=w(s)}}(n,t),n},exports.extractUrlParts=function(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,r={};return t.searchParams.forEach((e,t)=>{r[t]=e}),{path:n,params:r}}catch(n){return y.handleError(new t("EXTRACT_URL_PARTS_ERROR",`无效的URL: ${e}`,"utils"),"utils"),{path:"",params:{}}}},exports.getCurrentEnv=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return o.handleError(new t("GET_ACCOUNT_INFO_ERROR",`获取小程序账户信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),{appId:"",version:"",envVersion:"",accountInfo:{}}}},exports.getCurrentPageInfo=function(){try{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}}catch(e){return A("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}},exports.getH5UrlParams=e=>{try{if("undefined"==typeof window||!window.location)throw new Error("不在 H5 浏览器环境中");const t=new URLSearchParams(window.location.search),n={};return t.forEach((e,t)=>{try{n[t]=decodeURIComponent(e)}catch(r){n[t]=e}}),console.log("🔗 H5 URL参数解析:",{fullUrl:window.location.href,searchParams:window.location.search,parsedParams:n,paramName:e}),e?n.hasOwnProperty(e)?n[e]:null:n}catch(n){return y.handleError(new t("GET_H5_URL_PARAMS_ERROR",`获取H5 URL参数失败: ${n instanceof Error?n.message:String(n)}`,"utils"),"utils"),e?null:{}}},exports.getMenuButtonBoundingClientRect=g,exports.getNavHeight=()=>h().totalTopHeight,exports.getNavigationBarHeight=d,exports.getPageStack=function(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return A("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}},exports.getPlatform=f,exports.getStatusBarHeight=m,exports.getStorage=async function(e,t){return await r(()=>new Promise(n=>{n(M(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t},exports.getStorageInfo=function(){return D.getInfo()},exports.getStorageSync=M,exports.getTopBarMetrics=h,exports.getTopNavBarHeight=()=>{const e=h();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},exports.isWechat=W,exports.loadWechatJSSDK=X,exports.mergeObjects=function(e,t){if(!t||0===Object.keys(t).length)return e;const n={...e};for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n},exports.navigateTo=v,exports.onCheckForUpdate=()=>{if(!l)try{const e=uni.getUpdateManager();l=!0,e.onCheckForUpdate(function(e){e.hasUpdate}),e.onUpdateReady(function(t){uni.showModal({title:"更新提示",content:"新版本已经准备好,是否重启应用?",showCancel:!0,cancelText:"稍后",confirmText:"立即重启",success(t){t.confirm&&e.applyUpdate()}})}),e.onUpdateFailed(function(e){o.handleError(new t("UPDATE_DOWNLOAD_FAILED","新版本下载失败","system"),"system"),uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){o.handleError(new t("CHECK_UPDATE_ERROR",`版本更新检查失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system")}},exports.reLaunch=C,exports.redirectTo=async function(e){return new Promise(t=>{const n=_(e.url,e.params);uni.redirectTo({url:n,success:()=>t(!0),fail:e=>{A("REDIRECT_TO_FAILED",`页面重定向失败: ${n}`),t(!1)}})})},exports.safeAsync=r,exports.safeNavigateTo=async function(e,t=3){for(let n=0;n<t;n++){if(await v(e))return!0;n<t-1&&(await new Promise(e=>setTimeout(e,1e3*(n+1))),console.log(`[navigation] 第${n+2}次尝试跳转...`))}return!1},exports.safeSync=s,exports.selectAndUpload=B,exports.selectAndUploadImage=async function(e){return B({...e,type:"image"})},exports.setPageIcon=(e,t="image/x-icon")=>s(()=>{const n=f();if("h5"===n||"web"===n){if("undefined"!=typeof document){document.querySelectorAll('link[rel*="icon"]').forEach(e=>e.remove());const n=document.createElement("link");return n.rel="icon",n.type=t,n.href=e,document.head.appendChild(n),!0}}else console.warn("setPageIcon 仅在H5/Web平台有效");return!1},"system","SET_PAGE_ICON_ERROR",!1),exports.setPageTitle=e=>"string"!=typeof e?(console.warn("setPageTitle: title必须是字符串"),Promise.resolve(!1)):""===e.trim()?(console.warn("setPageTitle: title不能为空"),Promise.resolve(!1)):new Promise(n=>{try{uni.setNavigationBarTitle({title:e,success:()=>{n(!0)},fail:e=>{console.warn("设置页面标题失败:",e),n(!1)}})}catch(e){o.handleError(new t("SET_PAGE_TITLE_ERROR",`setPageTitle执行异常: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),n(!1)}}),exports.setStorage=async function(e,t,n={}){return await r(()=>new Promise(r=>{r(L(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1},exports.setStorageSync=L,exports.shareToFriend=te,exports.shareToTimeline=ee,exports.switchTab=async function(e){return new Promise(t=>{uni.switchTab({url:e,success:()=>t(!0),fail:n=>{A("SWITCH_TAB_FAILED",`Tab切换失败: ${e}`),t(!1)}})})},exports.throttle=function(e,t,n={}){let r,s=null,o=0;const{leading:a=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();o||a||(o=c);const u=t-(c-o);return u<=0||u>t?(s&&(clearTimeout(s),s=null),o=c,r=e.apply(this,n)):!s&&i&&(s=setTimeout(()=>{o=a?Date.now():0,s=null,r=e.apply(this,n)},u)),r};return c.cancel=()=>{s&&(clearTimeout(s),s=null),o=0},c},exports.useBack=P,exports.useBackDebounced=O,exports.useBackOrHome=async function(e="",t={}){const n=getCurrentPages(),r=t.delta||1;if(n.length>r)return await P(e,t);const s=t.homePage||"pages/index/index",o=s.startsWith("/")?s:`/${s}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),await C({url:o,params:t.homeParams})},exports.useCascaderAreaData=R,exports.useRegions=function(){return e.useCascaderAreaData()},exports.useToast=T,exports.useTryCatch=function(e,t={}){return async(...n)=>{try{return{data:await e(...n),error:null}}catch(e){return t.onError?.(e),{data:null,error:e}}finally{t.onFinally?.()}}},exports.useWindowInfo=p,exports.weChatOfficialAccountPayment=(e,n,r)=>new Promise(o=>{s(()=>{if("undefined"==typeof window||!window.navigator)throw new Error("不在浏览器环境中,无法调用微信支付");if(!(e&&e.appId&&e.timeStamp&&e.nonceStr&&e.package&&e.paySign))throw new Error("微信支付配置参数不完整");function s(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){console.log("🚀 ~ 微信支付结果:",e),"get_brand_wcpay_request:ok"===e.err_msg?(console.log("✅ 微信支付成功"),n?.(e),o(!0)):(console.warn("❌ 微信支付失败或取消:",e.err_msg),r?.(e),o(!1))})}catch(e){j.handleError(new t("WECHAT_PAY_INVOKE_ERROR",`调用微信支付接口失败: ${e instanceof Error?e.message:String(e)}`,"payment"),"payment");const n={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};r?.(n),o(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",s,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",s),e.attachEvent("onWeixinJSBridgeReady",s))}else s();return!0},"payment","WECHAT_PAY_ERROR",!1)||o(!1)});
@@ -1 +1 @@
1
- import{areaList as e,useCascaderAreaData as t}from"@vant/area-data";class n extends Error{code;module;timestamp;constructor(e,t,n){super(t),this.name="UniAppToolsError",this.code=e,this.module=n,this.timestamp=Date.now()}}class r{static instance;errorCallbacks=[];static getInstance(){return r.instance||(r.instance=new r),r.instance}onError(e){this.errorCallbacks.push(e)}handleError(e,t){const r={code:e instanceof n?e.code:"UNKNOWN_ERROR",message:e.message,module:e instanceof n?e.module:t,timestamp:e instanceof n?e.timestamp:Date.now(),stack:e.stack};console.error(`[${r.module}] ${r.code}: ${r.message}`,r),this.errorCallbacks.forEach(e=>{try{e(r)}catch(e){console.error("Error in error callback:",e)}})}createModuleErrorHandler(e){return(t,r,s)=>{const o=new n(t,r,e);return s&&(o.stack=s.stack),this.handleError(o,e),o}}}async function s(e,t,n="ASYNC_ERROR"){try{return await e()}catch(e){return r.getInstance().createModuleErrorHandler(t)(n,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function o(e,t,n="SYNC_ERROR",s=null){try{return e()}catch(e){return r.getInstance().createModuleErrorHandler(t)(n,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}const a=r.getInstance();let i=null,c=null,u=null;const l=()=>{u=null},f=e=>"weixin"===e||"alipay"===e;let m=!1;const g=()=>{if(i)return i;let e="unknown";return e="weixin",e="web",e="app",e="alipay",e="h5",i="h5","h5"},d=(e=!0)=>e&&u?u:o(()=>{const t=uni.getWindowInfo();return e&&(u=t),t},"system","GET_WINDOW_INFO_ERROR",null),h=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return a.handleError(new n("GET_ACCOUNT_INFO_ERROR",`获取小程序账户信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),{appId:"",version:"",envVersion:"",accountInfo:{}}}},p=()=>{if(!m)try{const e=uni.getUpdateManager();m=!0,e.onCheckForUpdate(function(e){e.hasUpdate}),e.onUpdateReady(function(t){uni.showModal({title:"更新提示",content:"新版本已经准备好,是否重启应用?",showCancel:!0,cancelText:"稍后",confirmText:"立即重启",success(t){t.confirm&&e.applyUpdate()}})}),e.onUpdateFailed(function(e){a.handleError(new n("UPDATE_DOWNLOAD_FAILED","新版本下载失败","system"),"system"),uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){a.handleError(new n("CHECK_UPDATE_ERROR",`版本更新检查失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system")}},y=()=>{if(null!==c)return c;try{const e=d();return c=e?.statusBarHeight||0,c}catch(e){return a.handleError(new n("GET_STATUS_BAR_HEIGHT_ERROR",`获取状态栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),0}},w=()=>{try{const e=g();return f(e)?uni.getMenuButtonBoundingClientRect():null}catch(e){return a.handleError(new n("GET_MENU_BUTTON_ERROR",`获取菜单按钮边界信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),null}},E=()=>{try{const e=g();if(f(e)){const e=w();return e?.height||44}return 44}catch(e){return a.handleError(new n("GET_NAVIGATION_BAR_HEIGHT_ERROR",`获取导航栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),44}},R=()=>{const e=g(),t=y(),n=E();return{platform:e,statusBarHeight:t,navigationBarHeight:n,totalTopHeight:t+n}},S=()=>{const e=R();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},T=()=>R().totalTopHeight,_=e=>"string"!=typeof e?(console.warn("setPageTitle: title必须是字符串"),Promise.resolve(!1)):""===e.trim()?(console.warn("setPageTitle: title不能为空"),Promise.resolve(!1)):new Promise(t=>{try{uni.setNavigationBarTitle({title:e,success:()=>{t(!0)},fail:e=>{console.warn("设置页面标题失败:",e),t(!1)}})}catch(e){a.handleError(new n("SET_PAGE_TITLE_ERROR",`setPageTitle执行异常: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),t(!1)}}),A=(e,t="image/x-icon")=>o(()=>{const n=g();if("h5"===n||"web"===n){if("undefined"!=typeof document){document.querySelectorAll('link[rel*="icon"]').forEach(e=>e.remove());const n=document.createElement("link");return n.rel="icon",n.type=t,n.href=e,document.head.appendChild(n),!0}}else console.warn("setPageIcon 仅在H5/Web平台有效");return!1},"system","SET_PAGE_ICON_ERROR",!1),v=r.getInstance();function O(e){if(null===e||"object"!=typeof e)return e;try{if("undefined"!=typeof structuredClone)try{return structuredClone(e)}catch(e){}return JSON.parse(JSON.stringify(e))}catch(e){throw v.handleError(new n("DEEP_CLONE_ERROR",`深拷贝失败: ${e instanceof Error?e.message:String(e)}`,"utils"),"utils"),new Error(`深拷贝失败: ${e instanceof Error?e.message:String(e)}`)}}function P(e,t){const n=O(e);return function e(t,n){for(const r in n)if(n.hasOwnProperty(r)){const s=n[r],o=t[r];s&&"object"==typeof s&&!Array.isArray(s)&&o&&"object"==typeof o&&!Array.isArray(o)?e(o,s):t[r]=O(s)}}(n,t),n}function C(e,t){if(!t||0===Object.keys(t).length)return e;const n={...e};for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n}function I(e,t,n=!1){let r,s=null;const o=function(...o){const a=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(r=e.apply(this,o))},t),a&&(r=e.apply(this,o)),r};return o.cancel=()=>{s&&(clearTimeout(s),s=null)},o}function $(e,t,n={}){let r,s=null,o=0;const{leading:a=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();o||a||(o=c);const u=t-(c-o);return u<=0||u>t?(s&&(clearTimeout(s),s=null),o=c,r=e.apply(this,n)):!s&&i&&(s=setTimeout(()=>{o=a?Date.now():0,s=null,r=e.apply(this,n)},u)),r};return c.cancel=()=>{s&&(clearTimeout(s),s=null),o=0},c}function x(e,t={}){return async(...n)=>{try{return{data:await e(...n),error:null}}catch(e){return t.onError?.(e),{data:null,error:e}}finally{t.onFinally?.()}}}const L=e=>{try{if("undefined"==typeof window||!window.location)throw new Error("不在 H5 浏览器环境中");const t=new URLSearchParams(window.location.search),n={};return t.forEach((e,t)=>{try{n[t]=decodeURIComponent(e)}catch(r){n[t]=e}}),console.log("🔗 H5 URL参数解析:",{fullUrl:window.location.href,searchParams:window.location.search,parsedParams:n,paramName:e}),e?n.hasOwnProperty(e)?n[e]:null:n}catch(t){return v.handleError(new n("GET_H5_URL_PARAMS_ERROR",`获取H5 URL参数失败: ${t instanceof Error?t.message:String(t)}`,"utils"),"utils"),e?null:{}}};function M(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,r={};return t.searchParams.forEach((e,t)=>{r[t]=e}),{path:n,params:r}}catch(t){return v.handleError(new n("EXTRACT_URL_PARTS_ERROR",`无效的URL: ${e}`,"utils"),"utils"),{path:"",params:{}}}}const b=e,D=t;function U(){return t()}const N=(e="",t=!1,n="none",r=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:r})},k=r.getInstance();function H(e,t){if(!t||0===Object.keys(t).length)return e;const n=Object.entries(t).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");return e+(e.includes("?")?"&":"?")+n}function F(e,t){k.handleError(new n(e,t,"navigation"),"navigation")}async function j(e){return new Promise(t=>{const n=H(e.url,e.params);uni.navigateTo({url:n,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>t(!0),fail:e=>{F("NAVIGATE_TO_FAILED",`页面跳转失败: ${n}`),t(!1)}})})}async function G(e){return new Promise(t=>{const n=H(e.url,e.params);uni.redirectTo({url:n,success:()=>t(!0),fail:e=>{F("REDIRECT_TO_FAILED",`页面重定向失败: ${n}`),t(!1)}})})}async function B(e){return new Promise(t=>{const n=H(e.url,e.params);uni.reLaunch({url:n,success:()=>t(!0),fail:e=>{F("RELAUNCH_FAILED",`重新启动失败: ${n}`),t(!1)}})})}async function J(e){return new Promise(t=>{uni.switchTab({url:e,success:()=>t(!0),fail:n=>{F("SWITCH_TAB_FAILED",`Tab切换失败: ${e}`),t(!1)}})})}async function W(e="",t={}){return new Promise(n=>{const r=t.delta||1,s=t.timeout||5e3;if(getCurrentPages().length<=r)return console.warn(`[navigation] 无法返回${r}页,当前页面栈深度不足`),void n(!1);const o=setTimeout(()=>{console.warn("[navigation] 导航返回超时"),n(!1)},s);uni.navigateBack({delta:r,success:()=>{clearTimeout(o),setTimeout(()=>{try{const t=getCurrentPages();if(t.length>0){const n=t[t.length-1];n.$vm&&"function"==typeof n.$vm.init&&n.$vm.init(e)}n(!0)}catch(e){F("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),n(!0)}},100)},fail:e=>{clearTimeout(o),F("NAVIGATE_BACK_FAILED","导航返回失败"),n(!1)}})})}async function z(e,t=3){for(let n=0;n<t;n++){if(await j(e))return!0;n<t-1&&(await new Promise(e=>setTimeout(e,1e3*(n+1))),console.log(`[navigation] 第${n+2}次尝试跳转...`))}return!1}async function K(e="",t={}){const n=getCurrentPages(),r=t.delta||1;if(n.length>r)return await W(e,t);const s=t.homePage||"pages/index/index",o=s.startsWith("/")?s:`/${s}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),await B({url:o,params:t.homeParams})}const q=I(W,300);function V(){try{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}}catch(e){return F("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}}function Y(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return F("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}}const X={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function Q(e,t={}){const n={...X,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&N("复制内容过长",!1,"error"),!1):await s(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&N(n.successMessage),t(!0)},fail:()=>{n.showToast&&N(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&N("复制内容不能为空",!1,"error"),!1)}const Z=r.getInstance();class ee{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return ee.instance||(ee.instance=new ee),ee.instance}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,r={}){try{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const n={value:t,timestamp:Date.now(),ttl:r.ttl},s=JSON.stringify(n);if(s.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,s),this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}return this.cache.set(e,n),!0}catch(e){throw Z.handleError(new n("SET_STORAGE_ERROR",`设置存储失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),e}}get(e,t){try{if(!e||"string"!=typeof e)return t;if(this.cache.has(e)){const n=this.cache.get(e);return this.isExpired(n)?(this.cache.delete(e),this.remove(e),t):n.value}const n=uni.getStorageSync(e);if(!n||"string"!=typeof n)return t;const r=JSON.parse(n);let s;return s=r&&"object"==typeof r&&"value"in r&&"timestamp"in r?r:{value:r,timestamp:Date.now()},this.isExpired(s)?(this.remove(e),t):(this.cache.set(e,s),s.value)}catch(n){return console.warn(`[localStorage] 获取存储失败 [${e}]:`,n),t}}remove(e){try{return!(!e||"string"!=typeof e||(uni.removeStorageSync(e),this.cache.delete(e),0))}catch(t){return Z.handleError(new n("REMOVE_STORAGE_ERROR",`删除存储失败: ${e}`,"localStorage"),"localStorage"),!1}}clear(){try{return uni.clearStorageSync(),this.cache.clear(),!0}catch(e){return Z.handleError(new n("CLEAR_STORAGE_ERROR","清空存储失败","localStorage"),"localStorage"),!1}}getInfo(){try{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}}catch(e){return Z.handleError(new n("GET_STORAGE_INFO_ERROR",`获取存储信息失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),{keys:[],currentSize:0,limitSize:0}}}cleanExpired(){try{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t}catch(e){return Z.handleError(new n("CLEAN_EXPIRED_ERROR",`清理过期数据失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),0}}}const te=ee.getInstance();function ne(e,t,n={}){return te.set(e,t,n)}function re(e,t){return te.get(e,t)}function se(e){return e?te.remove(e):te.clear()}async function oe(e,t,n={}){return await s(()=>new Promise(r=>{r(ne(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1}async function ae(e,t){return await s(()=>new Promise(n=>{n(re(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t}function ie(){return te.getInfo()}function ce(){return te.cleanExpired()}function ue(e,t={}){let n=0;return Object.entries(e).forEach(([e,r])=>{ne(e,r,t)&&n++}),n}function le(e){const t={};return e.forEach(e=>{t[e]=re(e)}),t}function fe(e){const t=e.lastIndexOf(".");if(-1!==t&&t!==e.length-1)return e.slice(t+1).toLowerCase()}function me(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function ge(e,t){return t&&e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function de(e,t){if(0===e.length)return{success:!1,files:e,message:"未选择任何文件"};const{maxSelectFileSizeMB:n,extensions:r}=t;if(n&&e.some(e=>!ge(e.size,n).valid))return{success:!1,files:e,message:`部分文件大小超过 ${n}MB 限制`};if(r&&r.length>0){const t=r.map(e=>e.toLowerCase());if(e.some(e=>!e.ext||!t.includes(e.ext)))return{success:!1,files:e,message:`存在不支持的文件类型,仅支持:${r.join(", ")}`}}return{success:!0,files:e}}async function he(e,t,n){const{url:r,maxUploadFileSizeMB:s,showToast:o=!0,beforeUpload:a}=t;if("function"==typeof a&&!await Promise.resolve(a(e)))return{file:e,success:!1,message:"已取消上传"};if(!r){const t="上传地址不能为空";return o&&N(t,!1,"error"),Promise.resolve({file:e,success:!1,message:t})}const i=ge(e.size,s);return i.valid?"h5"===e.platform&&e.raw instanceof File?function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f,autoRevokeObjectURL:m=!1}=t;return new Promise(t=>{const g=e.raw;if(!(g&&g instanceof File)){const n="H5 环境缺少原生文件对象";return i&&N(n,!1,"none"),void t({file:e,success:!1,message:n})}const d=m&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL&&"string"==typeof e.path&&e.path.startsWith("blob:"),h=()=>{if(d)try{URL.revokeObjectURL(e.path)}catch{}},p=new XMLHttpRequest,y=new FormData;y.append(s,g,e.name),o&&Object.keys(o).forEach(e=>{y.append(e,String(o[e]))}),l&&p.upload.addEventListener("progress",t=>{if(t.lengthComputable){const n=Math.round(t.loaded/t.total*100);l(e,n)}}),p.addEventListener("load",()=>{const r=p.status,s=r>=200&&r<300;let o=p.responseText;try{o=JSON.parse(p.responseText)}catch{}if(s)i&&1===n&&N(c,!1,"none"),h(),t({file:e,success:!0,statusCode:r,data:o});else{const n=`上传失败,状态码:${r}`;i&&N(n,!1,"none"),h(),t({file:e,success:!1,statusCode:r,data:o,message:n})}}),p.addEventListener("error",()=>{const n=u;i&&N(n,!1,"none"),h(),t({file:e,success:!1,message:n})}),p.addEventListener("timeout",()=>{const n=f?`上传超时(${f}ms)`:"上传超时";i&&N(n,!1,"none"),h(),t({file:e,success:!1,message:n})}),p.addEventListener("abort",()=>{h(),t({file:e,success:!1,message:"上传已取消"})}),p.open("POST",r),"number"==typeof f&&f>0&&(p.timeout=f),a&&Object.keys(a).forEach(e=>{p.setRequestHeader(e,a[e])}),p.send(y)})}(e,t,n):function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f}=t,m="undefined"==typeof uni?null:uni;if(!m||"function"!=typeof m.uploadFile){const t="当前环境不支持文件上传";return i&&N(t,!1,"none"),Promise.resolve({file:e,success:!1,message:t})}return new Promise(t=>{let g=!1,d=null;const h=e=>{g||(g=!0,d&&(clearTimeout(d),d=null),t(e))};let p=null;"number"==typeof f&&f>0&&(d=setTimeout(()=>{try{p&&"function"==typeof p.abort&&p.abort()}catch{}const t=`上传超时(${f}ms)`;i&&N(t,!1,"none"),h({file:e,success:!1,message:t})},f)),p=m.uploadFile({url:r,filePath:e.path,name:s,formData:o,header:a,success:t=>{let r=t.data;try{r=JSON.parse(t.data)}catch{}const s=t.statusCode;if(s>=200&&s<300)i&&1===n&&N(c,!1,"none"),h({file:e,success:!0,statusCode:s,data:r});else{const t=`上传失败,状态码:${s}`;i&&N(t,!1,"none"),h({file:e,success:!1,statusCode:s,data:r,message:t})}},fail:t=>{const n=t?.errMsg||u;i&&N(n,!1,"none"),h({file:e,success:!1,message:n})}}),l&&p&&"function"==typeof p.onProgressUpdate&&p.onProgressUpdate(t=>{l(e,t.progress)})})}(e,t,n):(o&&i.message&&N(i.message,!1,"error"),Promise.resolve({file:e,success:!1,message:i.message}))}async function pe(e){const{showToast:t=!0,failMessage:n="选择文件失败"}=e;try{const r=await async function(e){return"undefined"!=typeof document&&"undefined"!=typeof window?function(e){const{type:t="image",count:n=1,extensions:r}=e;return new Promise(s=>{if("undefined"==typeof document)return void s({success:!1,files:[],message:"当前环境不支持文件选择"});const o=document.createElement("input");o.type="file",o.multiple=n>1,"image"===t?o.accept="image/*":r&&r.length>0&&(o.accept=r.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),o.onchange=t=>{const n=t.target,r=n?.files;if(!r||0===r.length)return s({success:!1,files:[],message:"用户取消选择"}),void document.body.removeChild(o);const a=de(Array.from(r).map((e,t)=>{const n=fe(e.name),r=URL.createObjectURL(e);return{id:me(t),name:e.name,size:e.size,path:r,mimeType:e.type,ext:n,source:"file",platform:"h5",raw:e}}),e);s(a),document.body.removeChild(o)},o.style.display="none",document.body.appendChild(o),o.click()})}(e):function(e){const{type:t="image",count:n=1}=e;return new Promise(r=>{const s="undefined"==typeof uni?null:uni;if(!s)return void r({success:!1,files:[],message:"当前环境不支持文件选择"});const o=e=>{const t=function(e){const t=(e||"").trim();if(!t)return"选择文件失败";const n=t.toLowerCase();return n.includes("fail cancel")||n.includes("cancel")?"用户取消选择":/[\u4e00-\u9fff]/.test(t)?t:"选择文件失败"}(e?.errMsg);r({success:!1,files:[],message:t})},a=function(){let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}();"image"!==t||"function"!=typeof s.chooseImage?"function"!=typeof s.chooseMessageFile?"function"!=typeof s.chooseFile?r({success:!1,files:[],message:"当前平台不支持文件选择"}):s.chooseFile({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=fe(e.path);return{id:me(t),name:`file_${t}`,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(de(n,e))},fail:o}):s.chooseMessageFile({count:n,type:"all",success:t=>{const n=t.tempFiles.map((e,t)=>{const n=fe(e.name||e.path);return{id:me(t),name:e.name,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(de(n,e))},fail:o}):s.chooseImage({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=fe(e.path);return{id:me(t),name:`image_${t}`,size:e.size,path:e.path,ext:n,source:"album",platform:a,raw:e}});r(de(n,e))},fail:o})})}(e)}(e);if(!r.success){const e=r.message||n;return t&&e&&N(e,!1,"none"),[{file:null,success:!1,message:e}]}const s=r.files;if(0===s.length)return[];const o=s.length;return await async function(e,t,n){const r=new Array(e.length),s=t.concurrency&&t.concurrency>0?Math.min(t.concurrency,e.length):e.length;let o=0;const a=async()=>{for(;;){const s=o;if(s>=e.length)break;o+=1;const a=e[s],i=await he(a,t,n);r[s]=i}},i=[];for(let e=0;e<s;e+=1)i.push(a());return await Promise.all(i),r}(s,e,o)}catch(e){const r=n;return t&&r&&N(r,!1,"none"),[{file:null,success:!1,message:r}]}}async function ye(e){return pe({...e,type:"image"})}const we=r.getInstance(),Ee=(e,t,r)=>new Promise(s=>{o(()=>{if("undefined"==typeof window||!window.navigator)throw new Error("不在浏览器环境中,无法调用微信支付");if(!(e&&e.appId&&e.timeStamp&&e.nonceStr&&e.package&&e.paySign))throw new Error("微信支付配置参数不完整");function o(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){console.log("🚀 ~ 微信支付结果:",e),"get_brand_wcpay_request:ok"===e.err_msg?(console.log("✅ 微信支付成功"),t?.(e),s(!0)):(console.warn("❌ 微信支付失败或取消:",e.err_msg),r?.(e),s(!1))})}catch(e){we.handleError(new n("WECHAT_PAY_INVOKE_ERROR",`调用微信支付接口失败: ${e instanceof Error?e.message:String(e)}`,"payment"),"payment");const t={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};r?.(t),s(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",o,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",o),e.attachEvent("onWeixinJSBridgeReady",o))}else o();return!0},"payment","WECHAT_PAY_ERROR",!1)||s(!1)}),Re=r.getInstance(),Se=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),Te=()=>"undefined"!=typeof window&&"undefined"!=typeof document,_e=()=>Te()&&Se()&&window.wx||null;let Ae=!1,ve=null;const Oe=(e={})=>{const{timeoutMs:t=1e4}=e;if(Ae||Te()&&window.wx)return Ae=!0,Promise.resolve(!0);if(!Te())return Promise.resolve(!1);if(ve)return ve;const n=e.cdnUrls&&e.cdnUrls.length>0?e.cdnUrls:["https://res.wx.qq.com/open/js/jweixin-1.6.0.js","https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"];return ve=new Promise(e=>{let r=!1,s=null,o=null,a=0;const i=t=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(Ae=!0),ve=null,e(t))},c=()=>{if(a>=n.length)return void i(!1);if(!document.head)return void i(!1);const e=n[a];a+=1;const t=document.createElement("script");o=t,t.src=e,t.async=!0,t.onload=()=>i(!0),t.onerror=()=>{t.parentNode&&t.parentNode.removeChild(t),o=null,c()},document.head.appendChild(t)};s=setTimeout(()=>{i(!1)},t),c()}),ve};let Pe=null;const Ce=async(e,t={})=>{const{timeoutMs:r=1e4}=t;if(!Se())return console.warn("当前不在微信环境中"),!1;if(Pe)return Pe;if(!await Oe({timeoutMs:r}))return Re.handleError(new n("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;if(!Te())return!1;const s=window.wx;return!!s&&(Pe=new Promise(t=>{let o=!1,a=null;const i=e=>{o||(o=!0,a&&(clearTimeout(a),a=null),Pe=null,t(e))};a=setTimeout(()=>i(!1),r);try{s.config({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),s.ready(()=>{console.log("微信 JS-SDK 初始化完成"),i(!0)}),s.error(e=>{Re.handleError(new n("WECHAT_JSSDK_CONFIG_ERROR",`微信 JS-SDK 配置错误: ${JSON.stringify(e)}`,"weixin"),"weixin"),i(!1)})}catch(e){Re.handleError(new n("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),i(!1)}}),Pe)},Ie=(e,t={})=>{const{timeoutMs:r=8e3}=t;return new Promise(t=>{const s=_e();if(!s||"function"!=typeof s.checkJsApi)return void t({});let o=!1;const a=e=>{o||(o=!0,t(e))},i=setTimeout(()=>a({}),r);try{s.checkJsApi({jsApiList:e,success:e=>{clearTimeout(i),a(e?.checkResult||{})}})}catch(e){clearTimeout(i),Re.handleError(new n("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),a({})}})},$e=e=>{const t=_e();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},xe=e=>{const t=_e();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class Le{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return Le.instance||(Le.instance=new Le),Le.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=Ce(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return this.isConfigured&&Se()}getConfig(){return this.config}setShareData(e){this.isReady()?($e(e),xe(e)):console.warn("微信 SDK 未就绪")}}const Me="4.0.0",be={info:0,warn:1,error:2};function De(e={}){const{enableErrorHandler:t=!0,onError:n=null,showInitMessage:s=!1,silent:o=!1,logLevel:a="warn"}=e,i=be[a]||be.warn;if(t){const e=r.getInstance();"function"==typeof n?e.onError(n):e.onError(e=>{((...e)=>{!o&&i<=be.error&&console.error(...e)})(`[UniAppTools] ${e.module} - ${e.code}: ${e.message}`,e)})}if(((...e)=>{!o&&i<=be.info&&console.log(...e)})(`[UniAppTools] v${Me} 初始化完成`),s&&"undefined"!=typeof uni)try{uni.showToast({title:`工具库v${Me}已就绪`,icon:"none",duration:2e3})}catch(e){}}export{r as ErrorHandler,n as UniAppToolsError,Me as VERSION,Le as WechatSDK,b as areaList,le as batchGetStorage,ue as batchSetStorage,H as buildUrl,Ie as checkWechatJSAPI,ce as cleanExpiredStorage,se as clearStorageSync,l as clearSystemCache,Ce as configWechatJSSDK,Q as copyText,I as debounce,O as deepClone,P as deepMerge,M as extractUrlParts,h as getCurrentEnv,V as getCurrentPageInfo,L as getH5UrlParams,w as getMenuButtonBoundingClientRect,T as getNavHeight,E as getNavigationBarHeight,Y as getPageStack,g as getPlatform,y as getStatusBarHeight,ae as getStorage,ie as getStorageInfo,re as getStorageSync,R as getTopBarMetrics,S as getTopNavBarHeight,De as initUniAppTools,Se as isWechat,Oe as loadWechatJSSDK,C as mergeObjects,j as navigateTo,p as onCheckForUpdate,B as reLaunch,G as redirectTo,s as safeAsync,z as safeNavigateTo,o as safeSync,pe as selectAndUpload,ye as selectAndUploadImage,A as setPageIcon,_ as setPageTitle,oe as setStorage,ne as setStorageSync,xe as shareToFriend,$e as shareToTimeline,J as switchTab,$ as throttle,W as useBack,q as useBackDebounced,K as useBackOrHome,D as useCascaderAreaData,U as useRegions,N as useToast,x as useTryCatch,d as useWindowInfo,Ee as weChatOfficialAccountPayment};
1
+ import{areaList as e,useCascaderAreaData as t}from"@vant/area-data";class n extends Error{code;module;timestamp;constructor(e,t,n){super(t),this.name="UniAppToolsError",this.code=e,this.module=n,this.timestamp=Date.now()}}class r{static instance;errorCallbacks=[];static getInstance(){return r.instance||(r.instance=new r),r.instance}onError(e){this.errorCallbacks.push(e)}handleError(e,t){const r={code:e instanceof n?e.code:"UNKNOWN_ERROR",message:e.message,module:e instanceof n?e.module:t,timestamp:e instanceof n?e.timestamp:Date.now(),stack:e.stack};console.error(`[${r.module}] ${r.code}: ${r.message}`,r),this.errorCallbacks.forEach(e=>{try{e(r)}catch(e){console.error("Error in error callback:",e)}})}createModuleErrorHandler(e){return(t,r,s)=>{const o=new n(t,r,e);return s&&(o.stack=s.stack),this.handleError(o,e),o}}}async function s(e,t,n="ASYNC_ERROR"){try{return await e()}catch(e){return r.getInstance().createModuleErrorHandler(t)(n,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function o(e,t,n="SYNC_ERROR",s=null){try{return e()}catch(e){return r.getInstance().createModuleErrorHandler(t)(n,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}const a=r.getInstance();let i=null,c=null,u=null;const l=()=>{u=null},f=e=>"weixin"===e||"alipay"===e;let m=!1;const d=()=>{if(i)return i;let e="unknown";try{"undefined"!=typeof uni&&("undefined"!=typeof wx&&wx.getSystemInfoSync?e="weixin":"undefined"!=typeof my&&my.getSystemInfoSync?e="alipay":"undefined"!=typeof window&&window.document?e="h5":"undefined"!=typeof plus&&(e="app"))}catch(t){e="weixin",e="web",e="app",e="alipay",e="h5"}return i=e,e},g=(e=!0)=>e&&u?u:o(()=>{const t=uni.getWindowInfo();return e&&(u=t),t},"system","GET_WINDOW_INFO_ERROR",null),h=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return a.handleError(new n("GET_ACCOUNT_INFO_ERROR",`获取小程序账户信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),{appId:"",version:"",envVersion:"",accountInfo:{}}}},p=()=>{if(!m)try{const e=uni.getUpdateManager();m=!0,e.onCheckForUpdate(function(e){e.hasUpdate}),e.onUpdateReady(function(t){uni.showModal({title:"更新提示",content:"新版本已经准备好,是否重启应用?",showCancel:!0,cancelText:"稍后",confirmText:"立即重启",success(t){t.confirm&&e.applyUpdate()}})}),e.onUpdateFailed(function(e){a.handleError(new n("UPDATE_DOWNLOAD_FAILED","新版本下载失败","system"),"system"),uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){a.handleError(new n("CHECK_UPDATE_ERROR",`版本更新检查失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system")}},y=()=>{if(null!==c)return c;try{const e=g();return c=e?.statusBarHeight||0,c}catch(e){return a.handleError(new n("GET_STATUS_BAR_HEIGHT_ERROR",`获取状态栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),0}},w=()=>{try{const e=d();return f(e)?uni.getMenuButtonBoundingClientRect():null}catch(e){return a.handleError(new n("GET_MENU_BUTTON_ERROR",`获取菜单按钮边界信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),null}},E=()=>{try{const e=d();if(f(e)){const e=w();return e?.height||44}return 44}catch(e){return a.handleError(new n("GET_NAVIGATION_BAR_HEIGHT_ERROR",`获取导航栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),44}},R=()=>{const e=d(),t=y(),n=E();return{platform:e,statusBarHeight:t,navigationBarHeight:n,totalTopHeight:t+n}},S=()=>{const e=R();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},T=()=>R().totalTopHeight,_=e=>"string"!=typeof e?(console.warn("setPageTitle: title必须是字符串"),Promise.resolve(!1)):""===e.trim()?(console.warn("setPageTitle: title不能为空"),Promise.resolve(!1)):new Promise(t=>{try{uni.setNavigationBarTitle({title:e,success:()=>{t(!0)},fail:e=>{console.warn("设置页面标题失败:",e),t(!1)}})}catch(e){a.handleError(new n("SET_PAGE_TITLE_ERROR",`setPageTitle执行异常: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),t(!1)}}),A=(e,t="image/x-icon")=>o(()=>{const n=d();if("h5"===n||"web"===n){if("undefined"!=typeof document){document.querySelectorAll('link[rel*="icon"]').forEach(e=>e.remove());const n=document.createElement("link");return n.rel="icon",n.type=t,n.href=e,document.head.appendChild(n),!0}}else console.warn("setPageIcon 仅在H5/Web平台有效");return!1},"system","SET_PAGE_ICON_ERROR",!1),O=r.getInstance();function v(e){if(null===e||"object"!=typeof e)return e;try{if("undefined"!=typeof structuredClone)try{return structuredClone(e)}catch(e){}return JSON.parse(JSON.stringify(e))}catch(e){throw O.handleError(new n("DEEP_CLONE_ERROR",`深拷贝失败: ${e instanceof Error?e.message:String(e)}`,"utils"),"utils"),new Error(`深拷贝失败: ${e instanceof Error?e.message:String(e)}`)}}function P(e,t){const n=v(e);return function e(t,n){for(const r in n)if(n.hasOwnProperty(r)){const s=n[r],o=t[r];s&&"object"==typeof s&&!Array.isArray(s)&&o&&"object"==typeof o&&!Array.isArray(o)?e(o,s):t[r]=v(s)}}(n,t),n}function C(e,t){if(!t||0===Object.keys(t).length)return e;const n={...e};for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n}function I(e,t,n=!1){let r,s=null;const o=function(...o){const a=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(r=e.apply(this,o))},t),a&&(r=e.apply(this,o)),r};return o.cancel=()=>{s&&(clearTimeout(s),s=null)},o}function x(e,t,n={}){let r,s=null,o=0;const{leading:a=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();o||a||(o=c);const u=t-(c-o);return u<=0||u>t?(s&&(clearTimeout(s),s=null),o=c,r=e.apply(this,n)):!s&&i&&(s=setTimeout(()=>{o=a?Date.now():0,s=null,r=e.apply(this,n)},u)),r};return c.cancel=()=>{s&&(clearTimeout(s),s=null),o=0},c}function $(e,t={}){return async(...n)=>{try{return{data:await e(...n),error:null}}catch(e){return t.onError?.(e),{data:null,error:e}}finally{t.onFinally?.()}}}const L=e=>{try{if("undefined"==typeof window||!window.location)throw new Error("不在 H5 浏览器环境中");const t=new URLSearchParams(window.location.search),n={};return t.forEach((e,t)=>{try{n[t]=decodeURIComponent(e)}catch(r){n[t]=e}}),console.log("🔗 H5 URL参数解析:",{fullUrl:window.location.href,searchParams:window.location.search,parsedParams:n,paramName:e}),e?n.hasOwnProperty(e)?n[e]:null:n}catch(t){return O.handleError(new n("GET_H5_URL_PARAMS_ERROR",`获取H5 URL参数失败: ${t instanceof Error?t.message:String(t)}`,"utils"),"utils"),e?null:{}}};function M(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,r={};return t.searchParams.forEach((e,t)=>{r[t]=e}),{path:n,params:r}}catch(t){return O.handleError(new n("EXTRACT_URL_PARTS_ERROR",`无效的URL: ${e}`,"utils"),"utils"),{path:"",params:{}}}}const b=e,D=t;function N(){return t()}const U=(e="",t=!1,n="none",r=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:r})},k=r.getInstance();function H(e,t){if(!t||0===Object.keys(t).length)return e;const n=Object.entries(t).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");return e+(e.includes("?")?"&":"?")+n}function F(e,t){k.handleError(new n(e,t,"navigation"),"navigation")}async function j(e){return new Promise(t=>{const n=H(e.url,e.params);uni.navigateTo({url:n,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>t(!0),fail:e=>{F("NAVIGATE_TO_FAILED",`页面跳转失败: ${n}`),t(!1)}})})}async function G(e){return new Promise(t=>{const n=H(e.url,e.params);uni.redirectTo({url:n,success:()=>t(!0),fail:e=>{F("REDIRECT_TO_FAILED",`页面重定向失败: ${n}`),t(!1)}})})}async function B(e){return new Promise(t=>{const n=H(e.url,e.params);uni.reLaunch({url:n,success:()=>t(!0),fail:e=>{F("RELAUNCH_FAILED",`重新启动失败: ${n}`),t(!1)}})})}async function J(e){return new Promise(t=>{uni.switchTab({url:e,success:()=>t(!0),fail:n=>{F("SWITCH_TAB_FAILED",`Tab切换失败: ${e}`),t(!1)}})})}async function W(e="",t={}){return new Promise(n=>{const r=t.delta||1,s=t.timeout||5e3;if(getCurrentPages().length<=r)return console.warn(`[navigation] 无法返回${r}页,当前页面栈深度不足`),void n(!1);const o=setTimeout(()=>{console.warn("[navigation] 导航返回超时"),n(!1)},s);uni.navigateBack({delta:r,success:()=>{clearTimeout(o),setTimeout(()=>{try{const t=getCurrentPages();if(t.length>0){const n=t[t.length-1];n.$vm&&"function"==typeof n.$vm.init&&n.$vm.init(e)}n(!0)}catch(e){F("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),n(!0)}},100)},fail:e=>{clearTimeout(o),F("NAVIGATE_BACK_FAILED","导航返回失败"),n(!1)}})})}async function z(e,t=3){for(let n=0;n<t;n++){if(await j(e))return!0;n<t-1&&(await new Promise(e=>setTimeout(e,1e3*(n+1))),console.log(`[navigation] 第${n+2}次尝试跳转...`))}return!1}async function K(e="",t={}){const n=getCurrentPages(),r=t.delta||1;if(n.length>r)return await W(e,t);const s=t.homePage||"pages/index/index",o=s.startsWith("/")?s:`/${s}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),await B({url:o,params:t.homeParams})}const q=I(W,300);function V(){try{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}}catch(e){return F("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}}function Y(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return F("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}}const X={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function Q(e,t={}){const n={...X,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&U("复制内容过长",!1,"error"),!1):await s(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&U(n.successMessage),t(!0)},fail:()=>{n.showToast&&U(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&U("复制内容不能为空",!1,"error"),!1)}const Z=r.getInstance();class ee{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return ee.instance||(ee.instance=new ee),ee.instance}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,r={}){try{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const n={value:t,timestamp:Date.now(),ttl:r.ttl},s=JSON.stringify(n);if(s.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,s),this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}return this.cache.set(e,n),!0}catch(e){throw Z.handleError(new n("SET_STORAGE_ERROR",`设置存储失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),e}}get(e,t){try{if(!e||"string"!=typeof e)return t;if(this.cache.has(e)){const n=this.cache.get(e);return this.isExpired(n)?(this.cache.delete(e),this.remove(e),t):n.value}const n=uni.getStorageSync(e);if(!n||"string"!=typeof n)return t;const r=JSON.parse(n);let s;return s=r&&"object"==typeof r&&"value"in r&&"timestamp"in r?r:{value:r,timestamp:Date.now()},this.isExpired(s)?(this.remove(e),t):(this.cache.set(e,s),s.value)}catch(n){return console.warn(`[localStorage] 获取存储失败 [${e}]:`,n),t}}remove(e){try{return!(!e||"string"!=typeof e||(uni.removeStorageSync(e),this.cache.delete(e),0))}catch(t){return Z.handleError(new n("REMOVE_STORAGE_ERROR",`删除存储失败: ${e}`,"localStorage"),"localStorage"),!1}}clear(){try{return uni.clearStorageSync(),this.cache.clear(),!0}catch(e){return Z.handleError(new n("CLEAR_STORAGE_ERROR","清空存储失败","localStorage"),"localStorage"),!1}}getInfo(){try{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}}catch(e){return Z.handleError(new n("GET_STORAGE_INFO_ERROR",`获取存储信息失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),{keys:[],currentSize:0,limitSize:0}}}cleanExpired(){try{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t}catch(e){return Z.handleError(new n("CLEAN_EXPIRED_ERROR",`清理过期数据失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),0}}}const te=ee.getInstance();function ne(e,t,n={}){return te.set(e,t,n)}function re(e,t){return te.get(e,t)}function se(e){return e?te.remove(e):te.clear()}async function oe(e,t,n={}){return await s(()=>new Promise(r=>{r(ne(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1}async function ae(e,t){return await s(()=>new Promise(n=>{n(re(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t}function ie(){return te.getInfo()}function ce(){return te.cleanExpired()}function ue(e,t={}){let n=0;return Object.entries(e).forEach(([e,r])=>{ne(e,r,t)&&n++}),n}function le(e){const t={};return e.forEach(e=>{t[e]=re(e)}),t}function fe(e){const t=e.lastIndexOf(".");if(-1!==t&&t!==e.length-1)return e.slice(t+1).toLowerCase()}function me(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function de(e,t){return t&&e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function ge(e,t){if(0===e.length)return{success:!1,files:e,message:"未选择任何文件"};const{maxSelectFileSizeMB:n,extensions:r}=t;if(n&&e.some(e=>!de(e.size,n).valid))return{success:!1,files:e,message:`部分文件大小超过 ${n}MB 限制`};if(r&&r.length>0){const t=r.map(e=>e.toLowerCase());if(e.some(e=>!e.ext||!t.includes(e.ext)))return{success:!1,files:e,message:`存在不支持的文件类型,仅支持:${r.join(", ")}`}}return{success:!0,files:e}}async function he(e,t,n){const{url:r,maxUploadFileSizeMB:s,showToast:o=!0,beforeUpload:a}=t;if("function"==typeof a&&!await Promise.resolve(a(e)))return{file:e,success:!1,message:"已取消上传"};if(!r){const t="上传地址不能为空";return o&&U(t,!1,"error"),Promise.resolve({file:e,success:!1,message:t})}const i=de(e.size,s);return i.valid?"h5"===e.platform&&e.raw instanceof File?function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f,autoRevokeObjectURL:m=!1}=t;return new Promise(t=>{const d=e.raw;if(!(d&&d instanceof File)){const n="H5 环境缺少原生文件对象";return i&&U(n,!1,"none"),void t({file:e,success:!1,message:n})}const g=m&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL&&"string"==typeof e.path&&e.path.startsWith("blob:"),h=()=>{if(g)try{URL.revokeObjectURL(e.path)}catch{}},p=new XMLHttpRequest,y=new FormData;y.append(s,d,e.name),o&&Object.keys(o).forEach(e=>{y.append(e,String(o[e]))}),l&&p.upload.addEventListener("progress",t=>{if(t.lengthComputable){const n=Math.round(t.loaded/t.total*100);l(e,n)}}),p.addEventListener("load",()=>{const r=p.status,s=r>=200&&r<300;let o=p.responseText;try{o=JSON.parse(p.responseText)}catch{}if(s)i&&1===n&&U(c,!1,"none"),h(),t({file:e,success:!0,statusCode:r,data:o});else{const n=`上传失败,状态码:${r}`;i&&U(n,!1,"none"),h(),t({file:e,success:!1,statusCode:r,data:o,message:n})}}),p.addEventListener("error",()=>{const n=u;i&&U(n,!1,"none"),h(),t({file:e,success:!1,message:n})}),p.addEventListener("timeout",()=>{const n=f?`上传超时(${f}ms)`:"上传超时";i&&U(n,!1,"none"),h(),t({file:e,success:!1,message:n})}),p.addEventListener("abort",()=>{h(),t({file:e,success:!1,message:"上传已取消"})}),p.open("POST",r),"number"==typeof f&&f>0&&(p.timeout=f),a&&Object.keys(a).forEach(e=>{p.setRequestHeader(e,a[e])}),p.send(y)})}(e,t,n):function(e,t,n){const{url:r,fieldName:s="file",formData:o,headers:a,showToast:i=!0,successMessage:c="上传成功",failMessage:u="上传失败",onProgress:l,uploadTimeoutMs:f}=t,m="undefined"==typeof uni?null:uni;if(!m||"function"!=typeof m.uploadFile){const t="当前环境不支持文件上传";return i&&U(t,!1,"none"),Promise.resolve({file:e,success:!1,message:t})}return new Promise(t=>{let d=!1,g=null;const h=e=>{d||(d=!0,g&&(clearTimeout(g),g=null),t(e))};let p=null;"number"==typeof f&&f>0&&(g=setTimeout(()=>{try{p&&"function"==typeof p.abort&&p.abort()}catch{}const t=`上传超时(${f}ms)`;i&&U(t,!1,"none"),h({file:e,success:!1,message:t})},f)),p=m.uploadFile({url:r,filePath:e.path,name:s,formData:o,header:a,success:t=>{let r=t.data;try{r=JSON.parse(t.data)}catch{}const s=t.statusCode;if(s>=200&&s<300)i&&1===n&&U(c,!1,"none"),h({file:e,success:!0,statusCode:s,data:r});else{const t=`上传失败,状态码:${s}`;i&&U(t,!1,"none"),h({file:e,success:!1,statusCode:s,data:r,message:t})}},fail:t=>{const n=t?.errMsg||u;i&&U(n,!1,"none"),h({file:e,success:!1,message:n})}}),l&&p&&"function"==typeof p.onProgressUpdate&&p.onProgressUpdate(t=>{l(e,t.progress)})})}(e,t,n):(o&&i.message&&U(i.message,!1,"error"),Promise.resolve({file:e,success:!1,message:i.message}))}async function pe(e){const{showToast:t=!0,failMessage:n="选择文件失败"}=e;try{const r=await async function(e){return"undefined"!=typeof document&&"undefined"!=typeof window?function(e){const{type:t="image",count:n=1,extensions:r}=e;return new Promise(s=>{if("undefined"==typeof document)return void s({success:!1,files:[],message:"当前环境不支持文件选择"});const o=document.createElement("input");o.type="file",o.multiple=n>1,"image"===t?o.accept="image/*":r&&r.length>0&&(o.accept=r.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),o.onchange=t=>{const n=t.target,r=n?.files;if(!r||0===r.length)return s({success:!1,files:[],message:"用户取消选择"}),void document.body.removeChild(o);const a=ge(Array.from(r).map((e,t)=>{const n=fe(e.name),r=URL.createObjectURL(e);return{id:me(t),name:e.name,size:e.size,path:r,mimeType:e.type,ext:n,source:"file",platform:"h5",raw:e}}),e);s(a),document.body.removeChild(o)},o.style.display="none",document.body.appendChild(o),o.click()})}(e):function(e){const{type:t="image",count:n=1}=e;return new Promise(r=>{const s="undefined"==typeof uni?null:uni;if(!s)return void r({success:!1,files:[],message:"当前环境不支持文件选择"});const o=e=>{const t=function(e){const t=(e||"").trim();if(!t)return"选择文件失败";const n=t.toLowerCase();return n.includes("fail cancel")||n.includes("cancel")?"用户取消选择":/[\u4e00-\u9fff]/.test(t)?t:"选择文件失败"}(e?.errMsg);r({success:!1,files:[],message:t})},a=function(){let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}();"image"!==t||"function"!=typeof s.chooseImage?"function"!=typeof s.chooseMessageFile?"function"!=typeof s.chooseFile?r({success:!1,files:[],message:"当前平台不支持文件选择"}):s.chooseFile({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=fe(e.path);return{id:me(t),name:`file_${t}`,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(ge(n,e))},fail:o}):s.chooseMessageFile({count:n,type:"all",success:t=>{const n=t.tempFiles.map((e,t)=>{const n=fe(e.name||e.path);return{id:me(t),name:e.name,size:e.size,path:e.path,ext:n,source:"file",platform:a,raw:e}});r(ge(n,e))},fail:o}):s.chooseImage({count:n,success:t=>{const n=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>{const n=fe(e.path);return{id:me(t),name:`image_${t}`,size:e.size,path:e.path,ext:n,source:"album",platform:a,raw:e}});r(ge(n,e))},fail:o})})}(e)}(e);if(!r.success){const e=r.message||n;return t&&e&&U(e,!1,"none"),[{file:null,success:!1,message:e}]}const s=r.files;if(0===s.length)return[];const o=s.length;return await async function(e,t,n){const r=new Array(e.length),s=t.concurrency&&t.concurrency>0?Math.min(t.concurrency,e.length):e.length;let o=0;const a=async()=>{for(;;){const s=o;if(s>=e.length)break;o+=1;const a=e[s],i=await he(a,t,n);r[s]=i}},i=[];for(let e=0;e<s;e+=1)i.push(a());return await Promise.all(i),r}(s,e,o)}catch(e){const r=n;return t&&r&&U(r,!1,"none"),[{file:null,success:!1,message:r}]}}async function ye(e){return pe({...e,type:"image"})}const we=r.getInstance(),Ee=(e,t,r)=>new Promise(s=>{o(()=>{if("undefined"==typeof window||!window.navigator)throw new Error("不在浏览器环境中,无法调用微信支付");if(!(e&&e.appId&&e.timeStamp&&e.nonceStr&&e.package&&e.paySign))throw new Error("微信支付配置参数不完整");function o(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){console.log("🚀 ~ 微信支付结果:",e),"get_brand_wcpay_request:ok"===e.err_msg?(console.log("✅ 微信支付成功"),t?.(e),s(!0)):(console.warn("❌ 微信支付失败或取消:",e.err_msg),r?.(e),s(!1))})}catch(e){we.handleError(new n("WECHAT_PAY_INVOKE_ERROR",`调用微信支付接口失败: ${e instanceof Error?e.message:String(e)}`,"payment"),"payment");const t={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};r?.(t),s(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",o,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",o),e.attachEvent("onWeixinJSBridgeReady",o))}else o();return!0},"payment","WECHAT_PAY_ERROR",!1)||s(!1)}),Re=r.getInstance(),Se=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),Te=()=>"undefined"!=typeof window&&"undefined"!=typeof document,_e=()=>Te()&&Se()&&window.wx||null,Ae=(e,t=!1)=>{const n={};return e.forEach(e=>{"string"==typeof e&&""!==e.trim()&&(n[e]=t)}),n};let Oe=!1,ve=null,Pe=!1;const Ce=(e={})=>{const{timeoutMs:t=1e4}=e;if(Oe||Te()&&window.wx)return Oe=!0,Promise.resolve(!0);if(!Te())return Promise.resolve(!1);if(ve)return ve;const n=e.cdnUrls&&e.cdnUrls.length>0?e.cdnUrls:["https://res.wx.qq.com/open/js/jweixin-1.6.0.js","https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"];return ve=new Promise(e=>{let r=!1,s=null,o=null,a=0;const i=t=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(Oe=!0),ve=null,e(t))},c=()=>{if(a>=n.length)return void i(!1);if(!document.head)return void i(!1);const e=n[a];a+=1;const t=document.createElement("script");o=t,t.src=e,t.async=!0,t.onload=()=>i(!0),t.onerror=()=>{t.parentNode&&t.parentNode.removeChild(t),o=null,c()},document.head.appendChild(t)};s=setTimeout(()=>{i(!1)},t),c()}),ve};let Ie=null;const xe=async(e,t={})=>{const{timeoutMs:r=1e4}=t;return Se()?Ie||(Ie=(async()=>{if(!await Ce({timeoutMs:r}))return Re.handleError(new n("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;const t=_e();if(!t||"function"!=typeof t.config||"function"!=typeof t.ready||"function"!=typeof t.error)return!1;const s=t.config,o=t.ready,a=t.error,i=await new Promise(t=>{let i=!1,c=null;const u=e=>{i||(i=!0,c&&(clearTimeout(c),c=null),t(e))};c=setTimeout(()=>u(!1),r);try{s({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),o(()=>u(!0)),a(e=>{Re.handleError(new n("WECHAT_JSSDK_CONFIG_ERROR",`微信 JS-SDK 配置错误: ${(e=>{try{return JSON.stringify(e)}catch{return String(e)}})(e)}`,"weixin"),"weixin"),u(!1)})}catch(e){Re.handleError(new n("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),u(!1)}});return Pe=i,i})().finally(()=>{Ie=null}),Ie):(console.warn("当前不在微信环境中"),!1)},$e=(e,t={})=>{const{timeoutMs:r=8e3}=t;return new Promise(t=>{const s=_e();if(!s||"function"!=typeof s.checkJsApi)return void t(Ae(e,!1));let o=!1;const a=e=>{o||(o=!0,t(e))},i=setTimeout(()=>a(Ae(e,!1)),r);try{s.checkJsApi({jsApiList:e,success:t=>{clearTimeout(i),a({...Ae(e,!1),...t?.checkResult||{}})}})}catch(t){clearTimeout(i),Re.handleError(new n("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${t instanceof Error?t.message:String(t)}`,"weixin"),"weixin"),a(Ae(e,!1))}})},Le=e=>{const t=_e();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},Me=e=>{const t=_e();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class be{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return be.instance||(be.instance=new be),be.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=xe(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return(this.isConfigured||Pe)&&Se()}getConfig(){return this.config}setShareData(e){this.isReady()?(Le(e),Me(e)):console.warn("微信 SDK 未就绪")}}const De="4.0.0";export{r as ErrorHandler,n as UniAppToolsError,De as VERSION,be as WechatSDK,b as areaList,le as batchGetStorage,ue as batchSetStorage,H as buildUrl,$e as checkWechatJSAPI,ce as cleanExpiredStorage,se as clearStorageSync,l as clearSystemCache,xe as configWechatJSSDK,Q as copyText,I as debounce,v as deepClone,P as deepMerge,M as extractUrlParts,h as getCurrentEnv,V as getCurrentPageInfo,L as getH5UrlParams,w as getMenuButtonBoundingClientRect,T as getNavHeight,E as getNavigationBarHeight,Y as getPageStack,d as getPlatform,y as getStatusBarHeight,ae as getStorage,ie as getStorageInfo,re as getStorageSync,R as getTopBarMetrics,S as getTopNavBarHeight,Se as isWechat,Ce as loadWechatJSSDK,C as mergeObjects,j as navigateTo,p as onCheckForUpdate,B as reLaunch,G as redirectTo,s as safeAsync,z as safeNavigateTo,o as safeSync,pe as selectAndUpload,ye as selectAndUploadImage,A as setPageIcon,_ as setPageTitle,oe as setStorage,ne as setStorageSync,Me as shareToFriend,Le as shareToTimeline,J as switchTab,x as throttle,W as useBack,q as useBackDebounced,K as useBackOrHome,D as useCascaderAreaData,N as useRegions,U as useToast,$ as useTryCatch,g as useWindowInfo,Ee as weChatOfficialAccountPayment};
@@ -26,7 +26,7 @@ export declare const clearSystemCache: () => void;
26
26
  /**
27
27
  * 获取当前运行平台
28
28
  * @returns 平台类型字符串 ('weixin' | 'web' | 'app' | 'alipay' | 'h5' | 'unknown')
29
- * @description 通过条件编译判断当前代码运行的平台环境
29
+ * @description 通过运行时检测判断当前代码运行的平台环境(支持npm包引入)
30
30
  */
31
31
  export declare const getPlatform: () => PlatformType;
32
32
  /**
@@ -14,22 +14,29 @@ interface WxShareConfig {
14
14
  success?: () => void;
15
15
  cancel?: () => void;
16
16
  }
17
+ /**
18
+ * checkJsApi 返回结果
19
+ */
20
+ interface WxCheckJsApiSuccessResult {
21
+ checkResult?: Record<string, boolean>;
22
+ [key: string]: unknown;
23
+ }
17
24
  declare global {
18
25
  interface Window {
19
26
  wx?: {
20
- config: (config: WxConfig) => void;
21
- ready: (callback: () => void) => void;
22
- error: (callback: (res: any) => void) => void;
23
- checkJsApi: (config: {
27
+ config?: (config: WxConfig) => void;
28
+ ready?: (callback: () => void) => void;
29
+ error?: (callback: (res: unknown) => void) => void;
30
+ checkJsApi?: (config: {
24
31
  jsApiList: string[];
25
- success: (res: any) => void;
32
+ success: (res: WxCheckJsApiSuccessResult) => void;
26
33
  }) => void;
27
- updateAppMessageShareData: (config: WxShareConfig) => void;
28
- updateTimelineShareData: (config: WxShareConfig) => void;
29
- onMenuShareTimeline: (config: WxShareConfig) => void;
30
- onMenuShareAppMessage: (config: WxShareConfig) => void;
31
- onMenuShareWeibo: (config: WxShareConfig) => void;
32
- onMenuShareQZone: (config: WxShareConfig) => void;
34
+ updateAppMessageShareData?: (config: WxShareConfig) => void;
35
+ updateTimelineShareData?: (config: WxShareConfig) => void;
36
+ onMenuShareTimeline?: (config: WxShareConfig) => void;
37
+ onMenuShareAppMessage?: (config: WxShareConfig) => void;
38
+ onMenuShareWeibo?: (config: WxShareConfig) => void;
39
+ onMenuShareQZone?: (config: WxShareConfig) => void;
33
40
  };
34
41
  }
35
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-uniapp-tools",
3
- "version": "4.0.1",
3
+ "version": "4.0.3",
4
4
  "type": "module",
5
5
  "description": "一个功能强大、性能优化的 uni-app 开发工具库,提供剪贴板、本地存储、导航、系统信息等常用功能",
6
6
  "main": "dist/my-uniapp-tools.cjs.js",