my-uniapp-tools 5.0.1 → 5.0.2
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 +39 -12
- package/dist/my-uniapp-tools.cjs.js +1 -1
- package/dist/my-uniapp-tools.esm.js +1 -1
- package/dist/navigation/index.d.ts +40 -138
- package/dist/utils/index.d.ts +19 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -81,8 +81,8 @@ await copyText('要复制的文本', {
|
|
|
81
81
|
showToast: true, // 是否显示提示
|
|
82
82
|
successMessage: '复制成功', // 成功提示文本
|
|
83
83
|
failMessage: '复制失败', // 失败提示文本
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
timeout: 5000 // 超时时间(ms)
|
|
85
|
+
});
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
### 💾 本地存储功能
|
|
@@ -247,6 +247,7 @@ clearSystemCache();
|
|
|
247
247
|
选择并上传文件(一体化业务入口)
|
|
248
248
|
|
|
249
249
|
**参数 UploadOptions(v5):**
|
|
250
|
+
|
|
250
251
|
- `url` (string, 必须): 上传地址
|
|
251
252
|
- `files` (UniFile[]): 直接上传已有文件(跳过选择阶段)
|
|
252
253
|
- `type` ('image' | 'file' | 'any'): 文件类型(选择阶段),默认 'image'
|
|
@@ -267,6 +268,7 @@ clearSystemCache();
|
|
|
267
268
|
- `failMessage` (string): 失败提示文本(保留字段)
|
|
268
269
|
|
|
269
270
|
**返回值**: `Promise<UploadResult[]>`
|
|
271
|
+
|
|
270
272
|
- `file` (UniFile | null): 文件信息
|
|
271
273
|
- `success` (boolean): 是否成功
|
|
272
274
|
- `statusCode` (number): HTTP状态码
|
|
@@ -342,9 +344,23 @@ const results = await selectAndUpload({
|
|
|
342
344
|
|
|
343
345
|
### 💳 支付(微信公众号 H5)
|
|
344
346
|
|
|
345
|
-
#### weChatOfficialAccountPayment(config,
|
|
347
|
+
#### weChatOfficialAccountPayment(config, options?)
|
|
348
|
+
|
|
349
|
+
在微信内置浏览器中调起支付,返回结构化的支付结果
|
|
350
|
+
|
|
351
|
+
**参数**:
|
|
352
|
+
|
|
353
|
+
- `config` (WeChatPayConfig): 微信支付配置对象
|
|
354
|
+
- `options` (WeChatPayOptions): 可选配置
|
|
355
|
+
- `reportError` (boolean): 是否上报错误到 ErrorHandler,默认 true
|
|
346
356
|
|
|
347
|
-
|
|
357
|
+
**返回值**: `Promise<PaymentResult>`
|
|
358
|
+
|
|
359
|
+
- `success` (boolean): 是否支付成功
|
|
360
|
+
- `status` ('success' | 'error' | 'cancel'): 支付状态
|
|
361
|
+
- `code` (string): 状态码
|
|
362
|
+
- `message` (string): 状态描述
|
|
363
|
+
- `raw` (WeChatPayResult | null): 微信原始回调数据
|
|
348
364
|
|
|
349
365
|
```javascript
|
|
350
366
|
import { weChatOfficialAccountPayment } from 'my-uniapp-tools';
|
|
@@ -355,15 +371,26 @@ const payConfig = await fetch('/api/pay/wechat/unified-order', {
|
|
|
355
371
|
body: JSON.stringify({ orderId: '123456' })
|
|
356
372
|
}).then(r => r.json());
|
|
357
373
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
)
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
374
|
+
// 调用支付(结构化返回值)
|
|
375
|
+
const result = await weChatOfficialAccountPayment(payConfig);
|
|
376
|
+
|
|
377
|
+
// 根据支付结果处理
|
|
378
|
+
if (result.success) {
|
|
379
|
+
uni.showToast({ title: '支付成功', icon: 'success' });
|
|
380
|
+
// 处理支付成功逻辑
|
|
381
|
+
} else if (result.status === 'cancel') {
|
|
382
|
+
uni.showToast({ title: '已取消支付', icon: 'none' });
|
|
383
|
+
} else {
|
|
384
|
+
uni.showToast({
|
|
385
|
+
title: result.message || '支付失败',
|
|
386
|
+
icon: 'none'
|
|
387
|
+
});
|
|
366
388
|
}
|
|
389
|
+
|
|
390
|
+
// 测试时禁用错误上报
|
|
391
|
+
const result = await weChatOfficialAccountPayment(payConfig, {
|
|
392
|
+
reportError: false
|
|
393
|
+
});
|
|
367
394
|
```
|
|
368
395
|
|
|
369
396
|
### 🛠️ 工具函数
|
|
@@ -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";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},m=(e=!0)=>e&&c?c:s(()=>{const t=uni.getWindowInfo();return e&&(c=t),t},"system","GET_WINDOW_INFO_ERROR",null),p=()=>{if(null!==i)return i;try{const e=m();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}},d=()=>{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}},g=()=>{try{const e=f();if(u(e)){const e=d();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=p(),n=g();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}function S(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}const R=e.areaList,T=e.useCascaderAreaData,x=(e="",t=!1,n="none",r=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:r})},_=n.getInstance();function A(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 v(e,n){_.handleError(new t(e,n,"navigation"),"navigation")}async function O(e){return new Promise(t=>{const n=A(e.url,e.params);uni.navigateTo({url:n,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>t(!0),fail:e=>{v("NAVIGATE_TO_FAILED",`页面跳转失败: ${n}`),t(!1)}})})}async function P(e){return new Promise(t=>{const n=A(e.url,e.params);uni.reLaunch({url:n,success:()=>t(!0),fail:e=>{v("RELAUNCH_FAILED",`重新启动失败: ${n}`),t(!1)}})})}async function C(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){v("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),n(!0)}},100)},fail:e=>{clearTimeout(o),v("NAVIGATE_BACK_FAILED","导航返回失败"),n(!1)}})})}const I=E(C,300),b={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3},L=n.getInstance();class D{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return D.instance||(D.instance=new D),D.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 L.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 L.handleError(new t("REMOVE_STORAGE_ERROR",`删除存储失败: ${e}`,"localStorage"),"localStorage"),!1}}clear(){try{return uni.clearStorageSync(),this.cache.clear(),!0}catch(e){return L.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 L.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 L.handleError(new t("CLEAN_EXPIRED_ERROR",`清理过期数据失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),0}}}const N=D.getInstance();function $(e,t,n={}){return N.set(e,t,n)}function M(e,t){return N.get(e,t)}const U="上传失败",k="已取消上传",F="选择文件失败",H="用户取消选择",j=e=>`部分文件大小超过 ${e}MB 限制`,B=e=>`存在不支持的文件类型,仅支持:${e.join(", ")}`,J="当前环境不支持文件选择",W=e=>`上传超时(${e}ms)`,G=e=>`上传请求失败: ${e}`,K=e=>`上传失败,状态码:${e}`,z={FILE_TYPE:"image",COUNT:1,SHOW_TOAST:!0};function Y(e){if(!e)return;const t=e.split(/[?#]/)[0].match(/\.([^./\\]+)$/);return t?t[1].toLowerCase():void 0}function q(e){const t=e.toLowerCase().replace(/^\./,"");return"jpeg"===t||"jpe"===t?"jpg":t}function V(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function X(e){return"string"==typeof e&&e.startsWith("blob:")}function Q(e){if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return e}}function Z(e){if(null==e)return"";const t=typeof e;if("string"===t||"number"===t||"boolean"===t)return String(e);if("object"===t)try{return JSON.stringify(e)}catch{return String(e)}return String(e)}function ee(e){if(!e)return;const t={};return Object.keys(e).forEach(n=>{t[n]=Z(e[n])}),t}function te(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:"选择文件失败"}function ne(e,t){return null==t||"number"!=typeof t||!Number.isFinite(t)||t<0?{valid:!0}:e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function re(e,t){return!Number.isFinite(t)||t<=0?0:"number"!=typeof e||!Number.isFinite(e)||e<=0?t:Math.min(Math.floor(e),t)}function se(e){return{toast:e.toast||x,shouldShowToast:e.showToast??z.SHOW_TOAST}}function oe(e){return Boolean(e?.aborted)}function ae(e){return[{file:null,success:!1,message:e}]}function ie(){return ae(k)}async function ce(e,t,n){const{url:r,files:s,type:o=z.FILE_TYPE,count:a=z.COUNT,maxSizeMB:i,extensions:c,signal:u,successMessage:l}=e,{toast:f,shouldShowToast:m}=se(e);if(!r.trim()){const e="上传地址不能为空";return m&&f(e,!1,"none"),ae(e)}if(oe(u))return m&&f(k,!1,"none"),ie();let p=s||[];if(0===p.length)try{const e=await t({type:o,count:a,extensions:c});if(!e.success)return m&&e.message&&f(e.message,!1,"none"),[{file:null,success:!1,message:e.message}];p=e.files}catch(e){const t=e instanceof Error?e.message:F;return m&&f(t,!1,"none"),ae(t)}if(0===p.length)return[];const d=function(e,t){if(!e||0===e.length)return{success:!1,message:"未选择任何文件"};const{maxSizeMB:n,extensions:r}=t;if(0===n)return{success:!1,message:"当前不允许选择文件"};const s=null!=n&&"number"==typeof n&&Number.isFinite(n)&&n>0,o=Array.isArray(r)&&r.length>0;if(!s&&!o)return{success:!0};const a=o?new Set(r.map(e=>q(e))):null;for(const t of e){if(s&&!ne(t.size,n).valid)return{success:!1,message:j(n)};if(o&&a){const e=t.ext?q(t.ext):void 0;if(!e||!a.has(e))return{success:!1,message:B(r)}}}return{success:!0}}(p,{maxSizeMB:i,extensions:c});if(!d.success){const e=d.message||F;return m&&f(e,!1,"none"),ae(e)}if(oe(u))return m&&f(k,!1,"none"),ie();const g=await async function(e,t,n,r){const{concurrency:s,signal:o,beforeUpload:a,onProgress:i,showProgressToast:c,progressToastFormatter:u}=t,{toast:l,shouldShowToast:f}=se(t),m=new Array(e.length);let p=0;const d=e.length,g=re(s,d),h=Boolean(c&&d>0),y="undefined"!=typeof uni?uni:null,w=Boolean(h&&y&&"function"==typeof y.showLoading&&"function"==typeof y.hideLoading),E=w,R=S((t,n)=>{if(!w)return;const r=function(e){const{files:t,index:n,pct:r,finishedCount:s,totalCount:o,progressToastFormatter:a}=e;return a?a(t[n],r,n+1,o):1===o?`上传中 ${r}%`:`上传中 (${s}/${o})`}({files:e,index:t,pct:n,finishedCount:p,totalCount:d,progressToastFormatter:u});y.showLoading({title:r,mask:!0})},200);const T=async s=>{const c=e[s];let u=null;try{if(oe(o))return u={file:c,success:!1,message:k},void(w&&R(s,0));const e=await async function(e){if(!a)return null;try{return await a(e)?null:{file:e,success:!1,message:k}}catch(t){const n=(e=>`上传前检查失败: ${e}`)(t.message||"unknown");return f&&l(n,!1,"error"),{file:e,success:!1,message:n}}}(c);if(e)return void(u=e);const m=function(e){return E?{...t,onProgress:(t,n)=>{R(e,n),i&&i(t,n)}}:t}(s);u=await r(c,m,n)}catch(e){u={file:c,success:!1,message:e.message||"Unknown error"}}finally{u||(u={file:c,success:!1,message:"Unknown error"}),m[s]=u,p++,u.success&&R(s,100)}};for(let e=0;e<d;e+=g){const t=Math.min(e+g,d),n=[];for(let r=e;r<t;r+=1)n.push(T(r));await Promise.all(n)}return w&&(R.cancel?.(),y.hideLoading()),m}(p,e,r,n);return g.filter(e=>e.success).length===g.length&&1===g.length&&m&&f(l||"上传成功",!1,"none"),g}function ue(e,t,n,r,s,o,a){return{id:V(t),name:a||`file_${t}`,size:n,path:e,ext:Y(a||e),source:r,platform:s,raw:o}}const le="undefined"!=typeof window&&"undefined"!=typeof document&&!function(){const e="undefined"==typeof uni?null:uni;return Boolean(e&&"function"==typeof e.uploadFile)}(),fe=le?function(e){const{type:t="image",count:n=1,extensions:r}=e;return new Promise(e=>{if("undefined"==typeof document||"undefined"==typeof window)return void e({success:!1,files:[],message:J});const s=document.createElement("input");s.type="file",s.multiple=n>1,s.style.display="none","image"===t?s.accept="image/*":r&&r.length>0&&(s.accept=r.map(e=>e.startsWith(".")?e:`.${e}`).join(","));let o=!1,a=null;const i=t=>{o||(o=!0,(()=>{a&&(clearTimeout(a),a=null),window.removeEventListener("focus",u);try{s.remove()}catch{}})(),e(t))},c=e=>{if(!e||0===e.length)return void i({success:!1,files:[],message:H});const t=Array.from(e).slice(0,n).map((e,t)=>({id:V(t),name:e.name,size:e.size,path:URL.createObjectURL(e),mimeType:e.type,ext:Y(e.name),source:"file",platform:"h5",raw:e}));i({success:!0,files:t})};s.addEventListener("change",()=>c(s.files)),s.addEventListener("cancel",()=>i({success:!1,files:[],message:H}));const u=()=>{o||(a=window.setTimeout(()=>{o||(s.files&&0!==s.files.length?c(s.files):i({success:!1,files:[],message:H}))},300))};window.addEventListener("focus",u),document.body.appendChild(s),s.click()})}:function(e){const{type:t="image",count:n=1}=e;return new Promise(e=>{const r="undefined"==typeof uni?null:uni;if(!r)return void e({success:!1,files:[],message:J});const s=function(){if("undefined"!=typeof wx&&wx?.getSystemInfoSync)return"weixin";if("undefined"!=typeof my&&my?.getSystemInfoSync)return"alipay";if("undefined"!=typeof window&&"undefined"!=typeof document)return"h5";if("undefined"!=typeof plus)return"app";let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}(),o=t=>{e({success:!1,files:[],message:te(t?.errMsg)})},a=[{name:"chooseMedia(image)",when:()=>"image"===t&&"weixin"===s&&"function"==typeof r.chooseMedia,run:()=>{r.chooseMedia({count:n,mediaType:["image"],success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>{const n=e.size||e.fileSize||e.originalFileSize||0;return ue(e.tempFilePath,t,n,"album",s,e)});e({success:!0,files:n})},fail:o})}},{name:"chooseImage",when:()=>"image"===t&&"function"==typeof r.chooseImage,run:()=>{r.chooseImage({count:n,success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:t?.tempFiles?[t.tempFiles]:[]).map((e,t)=>ue(e.path,t,e.size,"album",s,e));e({success:!0,files:n})},fail:o})}},{name:"chooseMessageFile(all)",when:()=>"function"==typeof r.chooseMessageFile,run:()=>{r.chooseMessageFile({count:n,type:"all",success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>ue(e.path,t,e.size,"file",s,e,e.name));e({success:!0,files:n})},fail:o})}}];for(const e of a)if(e.when())return void e.run();e({success:!1,files:[],message:"当前平台不支持文件选择"})})},me=le?function(e,t,n){const{fieldName:r="file",formData:s,headers:o,timeoutMs:a,autoRevokeObjectURL:i}=t,{signal:c,onProgress:u}=t;return new Promise(t=>{const l=e.raw;if(!(l&&l instanceof File))return void t({file:e,success:!1,message:"H5 环境缺少原生文件对象"});const f=new XMLHttpRequest;let m=!1;const p=n=>{m||(m=!0,i&&X(e.path)&&function(e){if(X(e)&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL)try{URL.revokeObjectURL(e)}catch{}}(e.path),t(n))};if(c){if(c.aborted)return void p({file:e,success:!1,message:k});c.addEventListener("abort",()=>{f.abort(),p({file:e,success:!1,message:k})},{once:!0})}f.open("POST",n),a&&a>0&&(f.timeout=a),o&&Object.keys(o).forEach(e=>{f.setRequestHeader(e,o[e])});const d=new FormData;d.append(r,l,e.name),s&&Object.keys(s).forEach(e=>{d.append(e,Z(s[e]))}),f.upload.onprogress=t=>{if(t.lengthComputable&&u){const n=Math.round(t.loaded/t.total*100);u(e,n)}},f.onload=()=>{const t=f.status,n=t>=200&&t<300;let r=Q(f.responseText);p({file:e,success:n,statusCode:t,data:r,message:n?void 0:K(t)})},f.onerror=()=>p({file:e,success:!1,message:U}),f.ontimeout=()=>p({file:e,success:!1,message:W(a||0)}),f.onabort=()=>p({file:e,success:!1,message:k});try{f.send(d)}catch(t){const n=t instanceof Error?t.message:"Unknown error";p({file:e,success:!1,message:G(n)})}})}:function(e,t,n){const{fieldName:r="file",formData:s,headers:o,timeoutMs:a}=t,{signal:i,onProgress:c}=t;return new Promise(t=>{const u="undefined"==typeof uni?null:uni;if(!u?.uploadFile)return void t({file:e,success:!1,message:"当前环境不支持文件上传"});let l=!1,f=null,m=null;const p=e=>{l||(l=!0,f&&clearTimeout(f),t(e))};a&&a>0&&(f=setTimeout(()=>{m?.abort?.(),p({file:e,success:!1,message:W(a)})},a)),m=u.uploadFile({url:n,filePath:e.path,name:r,header:o,formData:ee(s),success:t=>{const n=function(e){if(e&&"number"==typeof e.statusCode)return e.statusCode;if(e&&"number"==typeof e.status)return e.status;const t="string"==typeof e?.errMsg?e.errMsg:"";return/:ok\b/i.test(t)?200:0}(t),r=n>=200&&n<300,s=Q(t.data);p({file:e,success:r,statusCode:n,data:s,message:r?void 0:K(n)})},fail:t=>{l||p({file:e,success:!1,message:t?.errMsg||U})}}),c&&m?.onProgressUpdate&&m.onProgressUpdate(t=>{l||"number"!=typeof t.progress||c(e,t.progress)}),i&&(i.aborted?(m?.abort?.(),p({file:e,success:!1,message:k})):i.addEventListener("abort",()=>{m?.abort?.(),p({file:e,success:!1,message:k})},{once:!0}))})};async function pe(e){return ce(e,fe,me)}const de=n.getInstance();let ge=!1,he=null;const ye=n.getInstance(),we=n.getInstance(),Ee=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),Se=()=>"undefined"!=typeof window&&"undefined"!=typeof document,Re=()=>Se()&&Ee()&&window.wx||null,Te=(e,t=!1)=>{const n={};return e.forEach(e=>{"string"==typeof e&&""!==e.trim()&&(n[e]=t)}),n};let xe=!1,_e=null,Ae=!1;const ve=(e={})=>{const{timeoutMs:t=1e4}=e;if(xe||Se()&&window.wx)return xe=!0,Promise.resolve(!0);if(!Se())return Promise.resolve(!1);if(_e)return _e;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 _e=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&&(xe=!0),_e=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()}),_e};let Oe=null;const Pe=async(e,n={})=>{const{timeoutMs:r=1e4}=n;return Ee()?Oe||(Oe=(async()=>{if(!await ve({timeoutMs:r}))return we.handleError(new t("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;const n=Re();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=>{we.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){we.handleError(new t("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),u(!1)}});return Ae=i,i})().finally(()=>{Oe=null}),Oe):(console.warn("当前不在微信环境中"),!1)},Ce=e=>{const t=Re();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},Ie=e=>{const t=Re();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=Pe(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return(this.isConfigured||Ae)&&Ee()}getConfig(){return this.config}setShareData(e){this.isReady()?(Ce(e),Ie(e)):console.warn("微信 SDK 未就绪")}}exports.ErrorHandler=n,exports.UniAppToolsError=t,exports.VERSION="5.0.0",exports.WechatSDK=be,exports.areaList=R,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])=>{$(e,r,t)&&n++}),n},exports.buildUrl=A,exports.checkWechatJSAPI=(e,n={})=>{const{timeoutMs:r=8e3}=n;return new Promise(n=>{const s=Re();if(!s||"function"!=typeof s.checkJsApi)return void n(Te(e,!1));let o=!1;const a=e=>{o||(o=!0,n(e))},i=setTimeout(()=>a(Te(e,!1)),r);try{s.checkJsApi({jsApiList:e,success:t=>{clearTimeout(i),a({...Te(e,!1),...t?.checkResult||{}})}})}catch(n){clearTimeout(i),we.handleError(new t("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${n instanceof Error?n.message:String(n)}`,"weixin"),"weixin"),a(Te(e,!1))}})},exports.cleanExpiredStorage=function(){return N.cleanExpired()},exports.clearStorageSync=function(e){return e?N.remove(e):N.clear()},exports.clearSystemCache=()=>{c=null},exports.configWechatJSSDK=Pe,exports.copyText=async function(e,t={}){const n={...b,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&x("复制内容过长",!1,"error"),!1):await r(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&x(n.successMessage),t(!0)},fail:()=>{n.showToast&&x(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&x("复制内容不能为空",!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 v("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}},exports.getExtension=Y,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=d,exports.getNavHeight=()=>h().totalTopHeight,exports.getNavigationBarHeight=g,exports.getPageStack=function(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return v("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}},exports.getPlatform=f,exports.getStatusBarHeight=p,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 N.getInfo()},exports.getStorageSync=M,exports.getTopBarMetrics=h,exports.getTopNavBarHeight=()=>{const e=h();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},exports.injectAlipayJsSdk=(e="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js")=>"undefined"!=typeof window&&window.document?ge||window.ap?(ge=!0,Promise.resolve(!0)):he||(he=new Promise(n=>{let r=!1,s=null,o=null,a=!1,i=null,c=null,u=null;const l=(e,a,l)=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&(clearInterval(o),o=null),i&&c&&i.removeEventListener("load",c),i&&u&&i.removeEventListener("error",u),!e&&a&&l&&de.handleError(new t(a,l,"payment"),"payment"),e&&(ge=!0),he=null,n(e))};try{const t=(()=>{try{return new URL(e,window.location.href).href}catch{return e}})(),n=document.getElementsByTagName("script");let r=null;for(let e=0;e<n.length;e++){const s=n[e];if(s&&s.src===t){r=s;break}}const f=r??document.createElement("script");a=!r,i=f;const m=()=>{window.ap&&l(!0)},p=e=>{a&&f.parentNode&&f.parentNode.removeChild(f),l(!1,"ALIPAY_SDK_LOAD_ERROR",`支付宝 JSSDK 加载失败: ${String(e?.type||"error")}`)};if(c=m,u=p,f.addEventListener("load",m),f.addEventListener("error",p),o=setInterval(()=>{window.ap&&l(!0)},50),s=setTimeout(()=>{a&&f.parentNode&&f.parentNode.removeChild(f),l(!1,"ALIPAY_SDK_LOAD_TIMEOUT","支付宝 JSSDK 加载超时")},1e4),a){f.type="text/javascript",f.src=t,f.async=!0,f.setAttribute("data-uniapp-tools","alipay-jssdk");const e=document.head||document.body||document.documentElement||null;if(!e)return void l(!1,"ALIPAY_SDK_INJECT_ERROR","无法找到可用的 script 注入容器");e.appendChild(f)}window.ap&&l(!0)}catch(e){l(!1,"ALIPAY_SDK_INJECT_ERROR",`注入支付宝 JSSDK 发生异常: ${e instanceof Error?e.message:String(e)}`)}}),he):(de.handleError(new t("ALIPAY_SDK_ENV_ERROR","不在浏览器环境中,无法注入支付宝 JSSDK","payment"),"payment"),Promise.resolve(!1)),exports.isWechat=Ee,exports.loadWechatJSSDK=ve,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=O,exports.normalizeConcurrency=re,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=P,exports.redirectTo=async function(e){return new Promise(t=>{const n=A(e.url,e.params);uni.redirectTo({url:n,success:()=>t(!0),fail:e=>{v("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 O(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=pe,exports.selectAndUploadImage=async function(e){return pe({...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($(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1},exports.setStorageSync=$,exports.shareToFriend=Ie,exports.shareToTimeline=Ce,exports.switchTab=async function(e){return new Promise(t=>{uni.switchTab({url:e,success:()=>t(!0),fail:n=>{v("SWITCH_TAB_FAILED",`Tab切换失败: ${e}`),t(!1)}})})},exports.throttle=S,exports.useBack=C,exports.useBackDebounced=I,exports.useBackOrHome=async function(e="",t={}){const n=getCurrentPages(),r=t.delta||1;if(n.length>r)return await C(e,t);const s=t.homePage||"pages/index/index",o=s.startsWith("/")?s:`/${s}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),await P({url:o,params:t.homeParams})},exports.useCascaderAreaData=T,exports.useRegions=function(){return e.useCascaderAreaData()},exports.useToast=x,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=m,exports.validateSizeWithLimit=ne,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){ye.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 s={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(`[${s.module}] ${s.code}: ${s.message}`,s),this.errorCallbacks.forEach(e=>{try{e(s)}catch(e){console.error("Error in error callback:",e)}})}createModuleErrorHandler(e){return(n,s,r)=>{const o=new t(n,s,e);return r&&(o.stack=r.stack),this.handleError(o,e),o}}}async function s(e,t,s="ASYNC_ERROR"){try{return await e()}catch(e){return n.getInstance().createModuleErrorHandler(t)(s,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function r(e,t,s="SYNC_ERROR",r=null){try{return e()}catch(e){return n.getInstance().createModuleErrorHandler(t)(s,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),r}}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},d=(e=!0)=>e&&c?c:r(()=>{const t=uni.getWindowInfo();return e&&(c=t),t},"system","GET_WINDOW_INFO_ERROR",null),m=()=>{if(null!==i)return i;try{const e=d();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}},p=()=>{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}},g=()=>{try{const e=f();if(u(e)){const e=p();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=g();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{return"undefined"!=typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e))}catch(e){const n=e instanceof Error?e.message:String(e);throw y.handleError(new t("DEEP_CLONE_ERROR",`深拷贝失败: ${n}`,"utils"),"utils"),new Error(`深拷贝失败: ${n}`)}}function E(e,t,n=!1){let s,r=null;const o=function(...o){const a=n&&!r;return r&&clearTimeout(r),r=setTimeout(()=>{r=null,n||(s=e.apply(this,o))},t),a&&(s=e.apply(this,o)),s};return o.cancel=()=>{r&&(clearTimeout(r),r=null)},o}function S(e,t,n={}){let s,r=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?(r&&(clearTimeout(r),r=null),o=c,s=e.apply(this,n)):!r&&i&&(r=setTimeout(()=>{o=a?Date.now():0,r=null,s=e.apply(this,n)},u)),s};return c.cancel=()=>{r&&(clearTimeout(r),r=null),o=0},c}const R=e.areaList,T=e.useCascaderAreaData,_=(e="",t=!1,n="none",s=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:s})},x=n.getInstance();let A={defaultHomePage:"/pages/index/index"};function C(e,t){if(!t)return e;const n=Object.entries(t).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");return e+(e.includes("?")?"&":"?")+n}const P=C;function v(e,n,s){const r=s?.errMsg?`${n} - ${s.errMsg}`:n;x.handleError(new t(e,r,"navigation"),"navigation")}async function O(e="",t={}){return new Promise(n=>{const s=t.delta||1,r=t.timeout||5e3,o=getCurrentPages();if(o.length<=s)return console.warn(`[navigation] 无法返回${s}页,当前页面栈深度不足(当前: ${o.length})`),void n(!1);let a=!1;const i=setTimeout(()=>{a||(a=!0,console.warn("[navigation] 页面init回调执行超时"),n(!1))},r);uni.navigateBack({delta:s,success:()=>{clearTimeout(i),setTimeout(()=>{if(!a)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)}a=!0,n(!0)}catch(e){v("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),a=!0,n(!0)}},100)},fail:e=>{clearTimeout(i),v("NAVIGATE_BACK_FAILED","导航返回失败",e),a=!0,n(!1)}})})}const I=E(O,300);function b(){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 v("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}}const L=b;function N(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return v("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}}const D=N,U={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3},$=n.getInstance();class M{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return M.instance||(M.instance=new M),M.instance}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,n,s={}){try{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const t={value:n,timestamp:Date.now(),ttl:s.ttl},r=JSON.stringify(t);if(r.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,r),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 s=JSON.parse(n);let r;return r=s&&"object"==typeof s&&"value"in s&&"timestamp"in s?s:{value:s,timestamp:Date.now()},this.isExpired(r)?(this.remove(e),t):(this.cache.set(e,r),r.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 k=M.getInstance();function H(e,t,n={}){return k.set(e,t,n)}function B(e,t){return k.get(e,t)}const F="上传失败",j="已取消上传",W="选择文件失败",J="用户取消选择",K=e=>`部分文件大小超过 ${e}MB 限制`,G=e=>`存在不支持的文件类型,仅支持:${e.join(", ")}`,z="当前环境不支持文件选择",Y=e=>`上传超时(${e}ms)`,V=e=>`上传请求失败: ${e}`,q=e=>`上传失败,状态码:${e}`,X={FILE_TYPE:"image",COUNT:1,SHOW_TOAST:!0};function Q(e){if(!e)return;const t=e.split(/[?#]/)[0].match(/\.([^./\\]+)$/);return t?t[1].toLowerCase():void 0}function Z(e){const t=e.toLowerCase().replace(/^\./,"");return"jpeg"===t||"jpe"===t?"jpg":t}function ee(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function te(e){return"string"==typeof e&&e.startsWith("blob:")}function ne(e){if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return e}}function se(e){if(null==e)return"";const t=typeof e;if("string"===t||"number"===t||"boolean"===t)return String(e);if("object"===t)try{return JSON.stringify(e)}catch{return String(e)}return String(e)}function re(e){if(!e)return;const t={};return Object.keys(e).forEach(n=>{t[n]=se(e[n])}),t}function oe(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:"选择文件失败"}function ae(e,t){return null==t||"number"!=typeof t||!Number.isFinite(t)||t<0?{valid:!0}:e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function ie(e,t){return!Number.isFinite(t)||t<=0?0:"number"!=typeof e||!Number.isFinite(e)||e<=0?t:Math.min(Math.floor(e),t)}function ce(e){return{toast:e.toast||_,shouldShowToast:e.showToast??X.SHOW_TOAST}}function ue(e){return Boolean(e?.aborted)}function le(e){return[{file:null,success:!1,message:e}]}function fe(){return le(j)}async function de(e,t,n){const{url:s,files:r,type:o=X.FILE_TYPE,count:a=X.COUNT,maxSizeMB:i,extensions:c,signal:u,successMessage:l}=e,{toast:f,shouldShowToast:d}=ce(e);if(!s.trim()){const e="上传地址不能为空";return d&&f(e,!1,"none"),le(e)}if(ue(u))return d&&f(j,!1,"none"),fe();let m=r||[];if(0===m.length)try{const e=await t({type:o,count:a,extensions:c});if(!e.success)return d&&e.message&&f(e.message,!1,"none"),[{file:null,success:!1,message:e.message}];m=e.files}catch(e){const t=e instanceof Error?e.message:W;return d&&f(t,!1,"none"),le(t)}if(0===m.length)return[];const p=function(e,t){if(!e||0===e.length)return{success:!1,message:"未选择任何文件"};const{maxSizeMB:n,extensions:s}=t;if(0===n)return{success:!1,message:"当前不允许选择文件"};const r=null!=n&&"number"==typeof n&&Number.isFinite(n)&&n>0,o=Array.isArray(s)&&s.length>0;if(!r&&!o)return{success:!0};const a=o?new Set(s.map(e=>Z(e))):null;for(const t of e){if(r&&!ae(t.size,n).valid)return{success:!1,message:K(n)};if(o&&a){const e=t.ext?Z(t.ext):void 0;if(!e||!a.has(e))return{success:!1,message:G(s)}}}return{success:!0}}(m,{maxSizeMB:i,extensions:c});if(!p.success){const e=p.message||W;return d&&f(e,!1,"none"),le(e)}if(ue(u))return d&&f(j,!1,"none"),fe();const g=await async function(e,t,n,s){const{concurrency:r,signal:o,beforeUpload:a,onProgress:i,showProgressToast:c,progressToastFormatter:u}=t,{toast:l,shouldShowToast:f}=ce(t),d=new Array(e.length);let m=0;const p=e.length,g=ie(r,p),h=Boolean(c&&p>0),y="undefined"!=typeof uni?uni:null,w=Boolean(h&&y&&"function"==typeof y.showLoading&&"function"==typeof y.hideLoading),E=w,R=S((t,n)=>{if(!w)return;const s=function(e){const{files:t,index:n,pct:s,finishedCount:r,totalCount:o,progressToastFormatter:a}=e;return a?a(t[n],s,n+1,o):1===o?`上传中 ${s}%`:`上传中 (${r}/${o})`}({files:e,index:t,pct:n,finishedCount:m,totalCount:p,progressToastFormatter:u});y.showLoading({title:s,mask:!0})},200);const T=async r=>{const c=e[r];let u=null;try{if(ue(o))return u={file:c,success:!1,message:j},void(w&&R(r,0));const e=await async function(e){if(!a)return null;try{return await a(e)?null:{file:e,success:!1,message:j}}catch(t){const n=(e=>`上传前检查失败: ${e}`)(t.message||"unknown");return f&&l(n,!1,"error"),{file:e,success:!1,message:n}}}(c);if(e)return void(u=e);const d=function(e){return E?{...t,onProgress:(t,n)=>{R(e,n),i&&i(t,n)}}:t}(r);u=await s(c,d,n)}catch(e){u={file:c,success:!1,message:e.message||"Unknown error"}}finally{u||(u={file:c,success:!1,message:"Unknown error"}),d[r]=u,m++,u.success&&R(r,100)}};for(let e=0;e<p;e+=g){const t=Math.min(e+g,p),n=[];for(let s=e;s<t;s+=1)n.push(T(s));await Promise.all(n)}return w&&(R.cancel?.(),y.hideLoading()),d}(m,e,s,n);return g.filter(e=>e.success).length===g.length&&1===g.length&&d&&f(l||"上传成功",!1,"none"),g}function me(e,t,n,s,r,o,a){return{id:ee(t),name:a||`file_${t}`,size:n,path:e,ext:Q(a||e),source:s,platform:r,raw:o}}const pe="undefined"!=typeof window&&"undefined"!=typeof document&&!function(){const e="undefined"==typeof uni?null:uni;return Boolean(e&&"function"==typeof e.uploadFile)}(),ge=pe?function(e){const{type:t="image",count:n=1,extensions:s}=e;return new Promise(e=>{if("undefined"==typeof document||"undefined"==typeof window)return void e({success:!1,files:[],message:z});const r=document.createElement("input");r.type="file",r.multiple=n>1,r.style.display="none","image"===t?r.accept="image/*":s&&s.length>0&&(r.accept=s.map(e=>e.startsWith(".")?e:`.${e}`).join(","));let o=!1,a=null;const i=t=>{o||(o=!0,(()=>{a&&(clearTimeout(a),a=null),window.removeEventListener("focus",u);try{r.remove()}catch{}})(),e(t))},c=e=>{if(!e||0===e.length)return void i({success:!1,files:[],message:J});const t=Array.from(e).slice(0,n).map((e,t)=>({id:ee(t),name:e.name,size:e.size,path:URL.createObjectURL(e),mimeType:e.type,ext:Q(e.name),source:"file",platform:"h5",raw:e}));i({success:!0,files:t})};r.addEventListener("change",()=>c(r.files)),r.addEventListener("cancel",()=>i({success:!1,files:[],message:J}));const u=()=>{o||(a=window.setTimeout(()=>{o||(r.files&&0!==r.files.length?c(r.files):i({success:!1,files:[],message:J}))},300))};window.addEventListener("focus",u),document.body.appendChild(r),r.click()})}:function(e){const{type:t="image",count:n=1}=e;return new Promise(e=>{const s="undefined"==typeof uni?null:uni;if(!s)return void e({success:!1,files:[],message:z});const r=function(){if("undefined"!=typeof wx&&wx?.getSystemInfoSync)return"weixin";if("undefined"!=typeof my&&my?.getSystemInfoSync)return"alipay";if("undefined"!=typeof window&&"undefined"!=typeof document)return"h5";if("undefined"!=typeof plus)return"app";let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}(),o=t=>{e({success:!1,files:[],message:oe(t?.errMsg)})},a=[{name:"chooseMedia(image)",when:()=>"image"===t&&"weixin"===r&&"function"==typeof s.chooseMedia,run:()=>{s.chooseMedia({count:n,mediaType:["image"],success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>{const n=e.size||e.fileSize||e.originalFileSize||0;return me(e.tempFilePath,t,n,"album",r,e)});e({success:!0,files:n})},fail:o})}},{name:"chooseImage",when:()=>"image"===t&&"function"==typeof s.chooseImage,run:()=>{s.chooseImage({count:n,success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:t?.tempFiles?[t.tempFiles]:[]).map((e,t)=>me(e.path,t,e.size,"album",r,e));e({success:!0,files:n})},fail:o})}},{name:"chooseMessageFile(all)",when:()=>"function"==typeof s.chooseMessageFile,run:()=>{s.chooseMessageFile({count:n,type:"all",success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>me(e.path,t,e.size,"file",r,e,e.name));e({success:!0,files:n})},fail:o})}}];for(const e of a)if(e.when())return void e.run();e({success:!1,files:[],message:"当前平台不支持文件选择"})})},he=pe?function(e,t,n){const{fieldName:s="file",formData:r,headers:o,timeoutMs:a,autoRevokeObjectURL:i}=t,{signal:c,onProgress:u}=t;return new Promise(t=>{const l=e.raw;if(!(l&&l instanceof File))return void t({file:e,success:!1,message:"H5 环境缺少原生文件对象"});const f=new XMLHttpRequest;let d=!1;const m=n=>{d||(d=!0,i&&te(e.path)&&function(e){if(te(e)&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL)try{URL.revokeObjectURL(e)}catch{}}(e.path),t(n))};if(c){if(c.aborted)return void m({file:e,success:!1,message:j});c.addEventListener("abort",()=>{f.abort(),m({file:e,success:!1,message:j})},{once:!0})}f.open("POST",n),a&&a>0&&(f.timeout=a),o&&Object.keys(o).forEach(e=>{f.setRequestHeader(e,o[e])});const p=new FormData;p.append(s,l,e.name),r&&Object.keys(r).forEach(e=>{p.append(e,se(r[e]))}),f.upload.onprogress=t=>{if(t.lengthComputable&&u){const n=Math.round(t.loaded/t.total*100);u(e,n)}},f.onload=()=>{const t=f.status,n=t>=200&&t<300;let s=ne(f.responseText);m({file:e,success:n,statusCode:t,data:s,message:n?void 0:q(t)})},f.onerror=()=>m({file:e,success:!1,message:F}),f.ontimeout=()=>m({file:e,success:!1,message:Y(a||0)}),f.onabort=()=>m({file:e,success:!1,message:j});try{f.send(p)}catch(t){const n=t instanceof Error?t.message:"Unknown error";m({file:e,success:!1,message:V(n)})}})}:function(e,t,n){const{fieldName:s="file",formData:r,headers:o,timeoutMs:a}=t,{signal:i,onProgress:c}=t;return new Promise(t=>{const u="undefined"==typeof uni?null:uni;if(!u?.uploadFile)return void t({file:e,success:!1,message:"当前环境不支持文件上传"});let l=!1,f=null,d=null;const m=e=>{l||(l=!0,f&&clearTimeout(f),t(e))};a&&a>0&&(f=setTimeout(()=>{d?.abort?.(),m({file:e,success:!1,message:Y(a)})},a)),d=u.uploadFile({url:n,filePath:e.path,name:s,header:o,formData:re(r),success:t=>{const n=function(e){if(e&&"number"==typeof e.statusCode)return e.statusCode;if(e&&"number"==typeof e.status)return e.status;const t="string"==typeof e?.errMsg?e.errMsg:"";return/:ok\b/i.test(t)?200:0}(t),s=n>=200&&n<300,r=ne(t.data);m({file:e,success:s,statusCode:n,data:r,message:s?void 0:q(n)})},fail:t=>{l||m({file:e,success:!1,message:t?.errMsg||F})}}),c&&d?.onProgressUpdate&&d.onProgressUpdate(t=>{l||"number"!=typeof t.progress||c(e,t.progress)}),i&&(i.aborted?(d?.abort?.(),m({file:e,success:!1,message:j})):i.addEventListener("abort",()=>{d?.abort?.(),m({file:e,success:!1,message:j})},{once:!0}))})};async function ye(e){return de(e,ge,he)}const we=n.getInstance();let Ee=!1,Se=null;const Re=n.getInstance(),Te="WECHAT_PAY_INVALID_CONFIG",_e=n.getInstance(),xe=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),Ae=()=>"undefined"!=typeof window&&"undefined"!=typeof document,Ce=()=>Ae()&&xe()&&window.wx||null,Pe=(e,t=!1)=>{const n={};return e.forEach(e=>{"string"==typeof e&&""!==e.trim()&&(n[e]=t)}),n};let ve=!1,Oe=null,Ie=!1;const be=(e={})=>{const{timeoutMs:t=1e4}=e;if(ve||Ae()&&window.wx)return ve=!0,Promise.resolve(!0);if(!Ae())return Promise.resolve(!1);if(Oe)return Oe;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 Oe=new Promise(e=>{let s=!1,r=null,o=null,a=0;const i=t=>{s||(s=!0,r&&(clearTimeout(r),r=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(ve=!0),Oe=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)};r=setTimeout(()=>{i(!1)},t),c()}),Oe};let Le=null;const Ne=async(e,n={})=>{const{timeoutMs:s=1e4}=n;return xe()?Le||(Le=(async()=>{if(!await be({timeoutMs:s}))return _e.handleError(new t("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;const n=Ce();if(!n||"function"!=typeof n.config||"function"!=typeof n.ready||"function"!=typeof n.error)return!1;const r=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),s);try{r({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),o(()=>u(!0)),a(e=>{_e.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){_e.handleError(new t("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),u(!1)}});return Ie=i,i})().finally(()=>{Le=null}),Le):(console.warn("当前不在微信环境中"),!1)},De=e=>{const t=Ce();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},Ue=e=>{const t=Ce();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class $e{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return $e.instance||($e.instance=new $e),$e.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=Ne(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return(this.isConfigured||Ie)&&xe()}getConfig(){return this.config}setShareData(e){this.isReady()?(De(e),Ue(e)):console.warn("微信 SDK 未就绪")}}exports.ErrorHandler=n,exports.UniAppToolsError=t,exports.VERSION="5.0.0",exports.WechatSDK=$e,exports.areaList=R,exports.batchGetStorage=function(e){const t={};return e.forEach(e=>{t[e]=B(e)}),t},exports.batchSetStorage=function(e,t={}){let n=0;return Object.entries(e).forEach(([e,s])=>{H(e,s,t)&&n++}),n},exports.buildUrl=P,exports.checkWechatJSAPI=(e,n={})=>{const{timeoutMs:s=8e3}=n;return new Promise(n=>{const r=Ce();if(!r||"function"!=typeof r.checkJsApi)return void n(Pe(e,!1));let o=!1;const a=e=>{o||(o=!0,n(e))},i=setTimeout(()=>a(Pe(e,!1)),s);try{r.checkJsApi({jsApiList:e,success:t=>{clearTimeout(i),a({...Pe(e,!1),...t?.checkResult||{}})}})}catch(n){clearTimeout(i),_e.handleError(new t("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${n instanceof Error?n.message:String(n)}`,"weixin"),"weixin"),a(Pe(e,!1))}})},exports.cleanExpiredStorage=function(){return k.cleanExpired()},exports.clearStorageSync=function(e){return e?k.remove(e):k.clear()},exports.clearSystemCache=()=>{c=null},exports.configWechatJSSDK=Ne,exports.configureNavigation=function(e){A={...A,...e}},exports.copyText=async function(e,t={}){const n={...U,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&_("复制内容过长",!1,"error"),!1):await s(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&_(n.successMessage),t(!0)},fail:()=>{n.showToast&&_(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&_("复制内容不能为空",!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 s in n)if(n.hasOwnProperty(s)){const r=n[s],o=t[s];r&&"object"==typeof r&&!Array.isArray(r)&&o&&"object"==typeof o&&!Array.isArray(o)?e(o,r):t[s]=w(r)}}(n,t),n},exports.extractUrlParts=function(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,s={};return t.searchParams.forEach((e,t)=>{s[t]=e}),{path:n,params:s}}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=L,exports.getExtension=Q,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(s){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=p,exports.getNavHeight=()=>h().totalTopHeight,exports.getNavigationBarHeight=g,exports.getPageStack=D,exports.getPlatform=f,exports.getStatusBarHeight=m,exports.getStorage=async function(e,t){return await s(()=>new Promise(n=>{n(B(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t},exports.getStorageInfo=function(){return k.getInfo()},exports.getStorageSync=B,exports.getTopBarMetrics=h,exports.getTopNavBarHeight=()=>{const e=h();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},exports.injectAlipayJsSdk=(e="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js")=>"undefined"!=typeof window&&window.document?Ee||window.ap?(Ee=!0,Promise.resolve(!0)):Se||(Se=new Promise(n=>{const s={settled:!1,timeoutId:null,script:null,createdByThisCall:!1},r=e=>{s.settled||(s.settled=!0,s.timeoutId&&(clearTimeout(s.timeoutId),s.timeoutId=null),e.success?Ee=!0:we.handleError(new t(e.code,e.message,"payment"),"payment"),Se=null,n(e.success))};try{let t;try{t=new URL(e,window.location.href).href}catch{return void r({success:!1,code:"ALIPAY_SDK_INVALID_URL",message:`无效的 JSSDK 地址: ${e}`})}const n=Array.from(document.getElementsByTagName("script")).find(e=>e.src===t),o=n??document.createElement("script");s.script=o,s.createdByThisCall=!n;const a=()=>{setTimeout(()=>{window.ap?r({success:!0}):r({success:!1,code:"ALIPAY_SDK_INIT_ERROR",message:"支付宝 JSSDK 加载成功但未能初始化 window.ap"})},50)},i=e=>{s.createdByThisCall&&o.parentNode&&o.parentNode.removeChild(o),r({success:!1,code:"ALIPAY_SDK_LOAD_ERROR",message:`支付宝 JSSDK 加载失败: ${String(e?.type||"error")}`})};o.addEventListener("load",a,{once:!0}),o.addEventListener("error",i,{once:!0}),s.timeoutId=setTimeout(()=>{s.createdByThisCall&&o.parentNode&&o.parentNode.removeChild(o),r({success:!1,code:"ALIPAY_SDK_LOAD_TIMEOUT",message:"支付宝 JSSDK 加载超时"})},1e4),s.createdByThisCall&&(o.type="text/javascript",o.src=t,o.async=!0,o.setAttribute("data-uniapp-tools","alipay-jssdk"),(document.head||document.body||document.documentElement).appendChild(o)),window.ap&&r({success:!0})}catch(e){r({success:!1,code:"ALIPAY_SDK_UNEXPECTED_ERROR",message:`支付宝 JSSDK 注入过程发生意外异常: ${e instanceof Error?e.message:String(e)}`})}}),Se):(we.handleError(new t("ALIPAY_SDK_ENV_ERROR","不在浏览器环境中,无法注入支付宝 JSSDK","payment"),"payment"),Promise.resolve(!1)),exports.isWechat=xe,exports.loadWechatJSSDK=be,exports.mergeObjects=function(e,t){if(!t||0===Object.keys(t).length)return e;const n={...e};for(const s of Object.keys(e))Object.prototype.hasOwnProperty.call(t,s)&&(n[s]=t[s]);return n},exports.normalizeConcurrency=ie,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.safeAsync=s,exports.safeSync=r,exports.selectAndUpload=ye,exports.selectAndUploadImage=async function(e){return ye({...e,type:"image"})},exports.setPageIcon=(e,t="image/x-icon")=>r(()=>{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 s(()=>new Promise(s=>{s(H(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1},exports.setStorageSync=H,exports.shareToFriend=Ue,exports.shareToTimeline=De,exports.throttle=S,exports.useBack=O,exports.useBackDebounced=I,exports.useBackOrHome=async function(e="",t={}){const n=getCurrentPages(),s=t.delta||1;if(n.length>s)return await O(e,t);const r=t.homePage||A.defaultHomePage,o=r.startsWith("/")?r:`/${r}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),new Promise(e=>{const n=C(o,t.homeParams);uni.reLaunch({url:n,success:()=>e(!0),fail:t=>{v("RELAUNCH_FAILED",`重新启动失败: ${n}`,t),e(!1)}})})},exports.useBuildUrl=C,exports.useCascaderAreaData=T,exports.useCurrentPageInfo=b,exports.usePageStack=N,exports.useRegions=function(){return e.useCascaderAreaData()},exports.useToast=_,exports.useWindowInfo=d,exports.validateSizeWithLimit=ae,exports.wechatH5Pay=(e,n={})=>{const{reportError:s=!0}=n;return new Promise(n=>{const r=(e,n,r=null)=>{const o=new t(e,n,"payment");return s&&Re.handleError(o,"payment"),{success:!1,status:"error",code:e,message:n,raw:r}};if(!(e?.appId&&e?.timeStamp&&e?.nonceStr&&e?.package&&e?.signType&&e?.paySign))return void n(r(Te,"微信支付配置参数不完整"));if(!e.package.startsWith("prepay_id="))return void n(r(Te,"微信支付 package 格式非法,应以 'prepay_id=' 开头"));if("undefined"==typeof window||!window.navigator)return void n(r("WECHAT_PAY_ENV_ERROR","不在浏览器环境中,无法调用微信支付"));const o=()=>{try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,e=>{"get_brand_wcpay_request:ok"===e.err_msg?n({success:!0,status:"success",code:"WECHAT_PAY_SUCCESS",message:"支付成功",raw:e}):"get_brand_wcpay_request:cancel"===e.err_msg?n({success:!1,status:"cancel",code:"WECHAT_PAY_CANCEL",message:"用户取消支付",raw:e}):n({success:!1,status:"error",code:"WECHAT_PAY_FAIL",message:e.err_desc||"支付失败",raw:e})})}catch(e){n(r("WECHAT_PAY_INVOKE_ERROR",`调用微信支付接口失败: ${e instanceof Error?e.message:String(e)}`))}};if(void 0===window.WeixinJSBridge){const e=()=>{o(),window.document.removeEventListener("WeixinJSBridgeReady",e,!1)};window.document.addEventListener("WeixinJSBridgeReady",e,!1)}else o()})};
|
|
@@ -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 i=r.getInstance();let a=null,c=null,u=null;const l=()=>{u=null},f=e=>"weixin"===e||"alipay"===e;let m=!1;const d=()=>{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},g=(e=!0)=>e&&u?u:o(()=>{const t=uni.getWindowInfo();return e&&(u=t),t},"system","GET_WINDOW_INFO_ERROR",null),p=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return i.handleError(new n("GET_ACCOUNT_INFO_ERROR",`获取小程序账户信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),{appId:"",version:"",envVersion:"",accountInfo:{}}}},h=()=>{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){i.handleError(new n("UPDATE_DOWNLOAD_FAILED","新版本下载失败","system"),"system"),uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){i.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 i.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 i.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 i.handleError(new n("GET_NAVIGATION_BAR_HEIGHT_ERROR",`获取导航栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),44}},S=()=>{const e=d(),t=y(),n=E();return{platform:e,statusBarHeight:t,navigationBarHeight:n,totalTopHeight:t+n}},R=()=>{const e=S();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},T=()=>S().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){i.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),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 i=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(r=e.apply(this,o))},t),i&&(r=e.apply(this,o)),r};return o.cancel=()=>{s&&(clearTimeout(s),s=null)},o}function b(e,t,n={}){let r,s=null,o=0;const{leading:i=!0,trailing:a=!0}=n,c=function(...n){const c=Date.now();o||i||(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&&a&&(s=setTimeout(()=>{o=i?Date.now():0,s=null,r=e.apply(this,n)},u)),r};return c.cancel=()=>{s&&(clearTimeout(s),s=null),o=0},c}function L(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 x=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 $(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 N=e,D=t;function M(){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 F(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 j(e,t){k.handleError(new n(e,t,"navigation"),"navigation")}async function H(e){return new Promise(t=>{const n=F(e.url,e.params);uni.navigateTo({url:n,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>t(!0),fail:e=>{j("NAVIGATE_TO_FAILED",`页面跳转失败: ${n}`),t(!1)}})})}async function B(e){return new Promise(t=>{const n=F(e.url,e.params);uni.redirectTo({url:n,success:()=>t(!0),fail:e=>{j("REDIRECT_TO_FAILED",`页面重定向失败: ${n}`),t(!1)}})})}async function G(e){return new Promise(t=>{const n=F(e.url,e.params);uni.reLaunch({url:n,success:()=>t(!0),fail:e=>{j("RELAUNCH_FAILED",`重新启动失败: ${n}`),t(!1)}})})}async function J(e){return new Promise(t=>{uni.switchTab({url:e,success:()=>t(!0),fail:n=>{j("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){j("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),n(!0)}},100)},fail:e=>{clearTimeout(o),j("NAVIGATE_BACK_FAILED","导航返回失败"),n(!1)}})})}async function K(e,t=3){for(let n=0;n<t;n++){if(await H(e))return!0;n<t-1&&(await new Promise(e=>setTimeout(e,1e3*(n+1))),console.log(`[navigation] 第${n+2}次尝试跳转...`))}return!1}async function z(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 G({url:o,params:t.homeParams})}const Y=I(W,300);function q(){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 j("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}}function V(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return j("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 ie(e,t){return await s(()=>new Promise(n=>{n(re(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t}function ae(){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}const fe="上传失败",me="已取消上传",de="选择文件失败",ge="用户取消选择",pe=e=>`部分文件大小超过 ${e}MB 限制`,he=e=>`存在不支持的文件类型,仅支持:${e.join(", ")}`,ye="当前环境不支持文件选择",we=e=>`上传超时(${e}ms)`,Ee=e=>`上传请求失败: ${e}`,Se=e=>`上传失败,状态码:${e}`,Re={FILE_TYPE:"image",COUNT:1,SHOW_TOAST:!0};function Te(e){if(!e)return;const t=e.split(/[?#]/)[0].match(/\.([^./\\]+)$/);return t?t[1].toLowerCase():void 0}function _e(e){const t=e.toLowerCase().replace(/^\./,"");return"jpeg"===t||"jpe"===t?"jpg":t}function Ae(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function ve(e){return"string"==typeof e&&e.startsWith("blob:")}function Oe(e){if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return e}}function Pe(e){if(null==e)return"";const t=typeof e;if("string"===t||"number"===t||"boolean"===t)return String(e);if("object"===t)try{return JSON.stringify(e)}catch{return String(e)}return String(e)}function Ce(e){if(!e)return;const t={};return Object.keys(e).forEach(n=>{t[n]=Pe(e[n])}),t}function Ie(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:"选择文件失败"}function be(e,t){return null==t||"number"!=typeof t||!Number.isFinite(t)||t<0?{valid:!0}:e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function Le(e,t){return!Number.isFinite(t)||t<=0?0:"number"!=typeof e||!Number.isFinite(e)||e<=0?t:Math.min(Math.floor(e),t)}function xe(e){return{toast:e.toast||U,shouldShowToast:e.showToast??Re.SHOW_TOAST}}function $e(e){return Boolean(e?.aborted)}function Ne(e){return[{file:null,success:!1,message:e}]}function De(){return Ne(me)}async function Me(e,t,n){const{url:r,files:s,type:o=Re.FILE_TYPE,count:i=Re.COUNT,maxSizeMB:a,extensions:c,signal:u,successMessage:l}=e,{toast:f,shouldShowToast:m}=xe(e);if(!r.trim()){const e="上传地址不能为空";return m&&f(e,!1,"none"),Ne(e)}if($e(u))return m&&f(me,!1,"none"),De();let d=s||[];if(0===d.length)try{const e=await t({type:o,count:i,extensions:c});if(!e.success)return m&&e.message&&f(e.message,!1,"none"),[{file:null,success:!1,message:e.message}];d=e.files}catch(e){const t=e instanceof Error?e.message:de;return m&&f(t,!1,"none"),Ne(t)}if(0===d.length)return[];const g=function(e,t){if(!e||0===e.length)return{success:!1,message:"未选择任何文件"};const{maxSizeMB:n,extensions:r}=t;if(0===n)return{success:!1,message:"当前不允许选择文件"};const s=null!=n&&"number"==typeof n&&Number.isFinite(n)&&n>0,o=Array.isArray(r)&&r.length>0;if(!s&&!o)return{success:!0};const i=o?new Set(r.map(e=>_e(e))):null;for(const t of e){if(s&&!be(t.size,n).valid)return{success:!1,message:pe(n)};if(o&&i){const e=t.ext?_e(t.ext):void 0;if(!e||!i.has(e))return{success:!1,message:he(r)}}}return{success:!0}}(d,{maxSizeMB:a,extensions:c});if(!g.success){const e=g.message||de;return m&&f(e,!1,"none"),Ne(e)}if($e(u))return m&&f(me,!1,"none"),De();const p=await async function(e,t,n,r){const{concurrency:s,signal:o,beforeUpload:i,onProgress:a,showProgressToast:c,progressToastFormatter:u}=t,{toast:l,shouldShowToast:f}=xe(t),m=new Array(e.length);let d=0;const g=e.length,p=Le(s,g),h=Boolean(c&&g>0),y="undefined"!=typeof uni?uni:null,w=Boolean(h&&y&&"function"==typeof y.showLoading&&"function"==typeof y.hideLoading),E=w,S=b((t,n)=>{if(!w)return;const r=function(e){const{files:t,index:n,pct:r,finishedCount:s,totalCount:o,progressToastFormatter:i}=e;return i?i(t[n],r,n+1,o):1===o?`上传中 ${r}%`:`上传中 (${s}/${o})`}({files:e,index:t,pct:n,finishedCount:d,totalCount:g,progressToastFormatter:u});y.showLoading({title:r,mask:!0})},200);const R=async s=>{const c=e[s];let u=null;try{if($e(o))return u={file:c,success:!1,message:me},void(w&&S(s,0));const e=await async function(e){if(!i)return null;try{return await i(e)?null:{file:e,success:!1,message:me}}catch(t){const n=(e=>`上传前检查失败: ${e}`)(t.message||"unknown");return f&&l(n,!1,"error"),{file:e,success:!1,message:n}}}(c);if(e)return void(u=e);const m=function(e){return E?{...t,onProgress:(t,n)=>{S(e,n),a&&a(t,n)}}:t}(s);u=await r(c,m,n)}catch(e){u={file:c,success:!1,message:e.message||"Unknown error"}}finally{u||(u={file:c,success:!1,message:"Unknown error"}),m[s]=u,d++,u.success&&S(s,100)}};for(let e=0;e<g;e+=p){const t=Math.min(e+p,g),n=[];for(let r=e;r<t;r+=1)n.push(R(r));await Promise.all(n)}return w&&(S.cancel?.(),y.hideLoading()),m}(d,e,r,n);return p.filter(e=>e.success).length===p.length&&1===p.length&&m&&f(l||"上传成功",!1,"none"),p}function Ue(e,t,n,r,s,o,i){return{id:Ae(t),name:i||`file_${t}`,size:n,path:e,ext:Te(i||e),source:r,platform:s,raw:o}}const ke="undefined"!=typeof window&&"undefined"!=typeof document&&!function(){const e="undefined"==typeof uni?null:uni;return Boolean(e&&"function"==typeof e.uploadFile)}(),Fe=ke?function(e){const{type:t="image",count:n=1,extensions:r}=e;return new Promise(e=>{if("undefined"==typeof document||"undefined"==typeof window)return void e({success:!1,files:[],message:ye});const s=document.createElement("input");s.type="file",s.multiple=n>1,s.style.display="none","image"===t?s.accept="image/*":r&&r.length>0&&(s.accept=r.map(e=>e.startsWith(".")?e:`.${e}`).join(","));let o=!1,i=null;const a=t=>{o||(o=!0,(()=>{i&&(clearTimeout(i),i=null),window.removeEventListener("focus",u);try{s.remove()}catch{}})(),e(t))},c=e=>{if(!e||0===e.length)return void a({success:!1,files:[],message:ge});const t=Array.from(e).slice(0,n).map((e,t)=>({id:Ae(t),name:e.name,size:e.size,path:URL.createObjectURL(e),mimeType:e.type,ext:Te(e.name),source:"file",platform:"h5",raw:e}));a({success:!0,files:t})};s.addEventListener("change",()=>c(s.files)),s.addEventListener("cancel",()=>a({success:!1,files:[],message:ge}));const u=()=>{o||(i=window.setTimeout(()=>{o||(s.files&&0!==s.files.length?c(s.files):a({success:!1,files:[],message:ge}))},300))};window.addEventListener("focus",u),document.body.appendChild(s),s.click()})}:function(e){const{type:t="image",count:n=1}=e;return new Promise(e=>{const r="undefined"==typeof uni?null:uni;if(!r)return void e({success:!1,files:[],message:ye});const s=function(){if("undefined"!=typeof wx&&wx?.getSystemInfoSync)return"weixin";if("undefined"!=typeof my&&my?.getSystemInfoSync)return"alipay";if("undefined"!=typeof window&&"undefined"!=typeof document)return"h5";if("undefined"!=typeof plus)return"app";let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}(),o=t=>{e({success:!1,files:[],message:Ie(t?.errMsg)})},i=[{name:"chooseMedia(image)",when:()=>"image"===t&&"weixin"===s&&"function"==typeof r.chooseMedia,run:()=>{r.chooseMedia({count:n,mediaType:["image"],success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>{const n=e.size||e.fileSize||e.originalFileSize||0;return Ue(e.tempFilePath,t,n,"album",s,e)});e({success:!0,files:n})},fail:o})}},{name:"chooseImage",when:()=>"image"===t&&"function"==typeof r.chooseImage,run:()=>{r.chooseImage({count:n,success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:t?.tempFiles?[t.tempFiles]:[]).map((e,t)=>Ue(e.path,t,e.size,"album",s,e));e({success:!0,files:n})},fail:o})}},{name:"chooseMessageFile(all)",when:()=>"function"==typeof r.chooseMessageFile,run:()=>{r.chooseMessageFile({count:n,type:"all",success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>Ue(e.path,t,e.size,"file",s,e,e.name));e({success:!0,files:n})},fail:o})}}];for(const e of i)if(e.when())return void e.run();e({success:!1,files:[],message:"当前平台不支持文件选择"})})},je=ke?function(e,t,n){const{fieldName:r="file",formData:s,headers:o,timeoutMs:i,autoRevokeObjectURL:a}=t,{signal:c,onProgress:u}=t;return new Promise(t=>{const l=e.raw;if(!(l&&l instanceof File))return void t({file:e,success:!1,message:"H5 环境缺少原生文件对象"});const f=new XMLHttpRequest;let m=!1;const d=n=>{m||(m=!0,a&&ve(e.path)&&function(e){if(ve(e)&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL)try{URL.revokeObjectURL(e)}catch{}}(e.path),t(n))};if(c){if(c.aborted)return void d({file:e,success:!1,message:me});c.addEventListener("abort",()=>{f.abort(),d({file:e,success:!1,message:me})},{once:!0})}f.open("POST",n),i&&i>0&&(f.timeout=i),o&&Object.keys(o).forEach(e=>{f.setRequestHeader(e,o[e])});const g=new FormData;g.append(r,l,e.name),s&&Object.keys(s).forEach(e=>{g.append(e,Pe(s[e]))}),f.upload.onprogress=t=>{if(t.lengthComputable&&u){const n=Math.round(t.loaded/t.total*100);u(e,n)}},f.onload=()=>{const t=f.status,n=t>=200&&t<300;let r=Oe(f.responseText);d({file:e,success:n,statusCode:t,data:r,message:n?void 0:Se(t)})},f.onerror=()=>d({file:e,success:!1,message:fe}),f.ontimeout=()=>d({file:e,success:!1,message:we(i||0)}),f.onabort=()=>d({file:e,success:!1,message:me});try{f.send(g)}catch(t){const n=t instanceof Error?t.message:"Unknown error";d({file:e,success:!1,message:Ee(n)})}})}:function(e,t,n){const{fieldName:r="file",formData:s,headers:o,timeoutMs:i}=t,{signal:a,onProgress:c}=t;return new Promise(t=>{const u="undefined"==typeof uni?null:uni;if(!u?.uploadFile)return void t({file:e,success:!1,message:"当前环境不支持文件上传"});let l=!1,f=null,m=null;const d=e=>{l||(l=!0,f&&clearTimeout(f),t(e))};i&&i>0&&(f=setTimeout(()=>{m?.abort?.(),d({file:e,success:!1,message:we(i)})},i)),m=u.uploadFile({url:n,filePath:e.path,name:r,header:o,formData:Ce(s),success:t=>{const n=function(e){if(e&&"number"==typeof e.statusCode)return e.statusCode;if(e&&"number"==typeof e.status)return e.status;const t="string"==typeof e?.errMsg?e.errMsg:"";return/:ok\b/i.test(t)?200:0}(t),r=n>=200&&n<300,s=Oe(t.data);d({file:e,success:r,statusCode:n,data:s,message:r?void 0:Se(n)})},fail:t=>{l||d({file:e,success:!1,message:t?.errMsg||fe})}}),c&&m?.onProgressUpdate&&m.onProgressUpdate(t=>{l||"number"!=typeof t.progress||c(e,t.progress)}),a&&(a.aborted?(m?.abort?.(),d({file:e,success:!1,message:me})):a.addEventListener("abort",()=>{m?.abort?.(),d({file:e,success:!1,message:me})},{once:!0}))})};async function He(e){return Me(e,Fe,je)}async function Be(e){return He({...e,type:"image"})}const Ge=r.getInstance();let Je=!1,We=null;const Ke=(e="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js")=>"undefined"!=typeof window&&window.document?Je||window.ap?(Je=!0,Promise.resolve(!0)):We||(We=new Promise(t=>{let r=!1,s=null,o=null,i=!1,a=null,c=null,u=null;const l=(e,i,l)=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&(clearInterval(o),o=null),a&&c&&a.removeEventListener("load",c),a&&u&&a.removeEventListener("error",u),!e&&i&&l&&Ge.handleError(new n(i,l,"payment"),"payment"),e&&(Je=!0),We=null,t(e))};try{const t=(()=>{try{return new URL(e,window.location.href).href}catch{return e}})(),n=document.getElementsByTagName("script");let r=null;for(let e=0;e<n.length;e++){const s=n[e];if(s&&s.src===t){r=s;break}}const f=r??document.createElement("script");i=!r,a=f;const m=()=>{window.ap&&l(!0)},d=e=>{i&&f.parentNode&&f.parentNode.removeChild(f),l(!1,"ALIPAY_SDK_LOAD_ERROR",`支付宝 JSSDK 加载失败: ${String(e?.type||"error")}`)};if(c=m,u=d,f.addEventListener("load",m),f.addEventListener("error",d),o=setInterval(()=>{window.ap&&l(!0)},50),s=setTimeout(()=>{i&&f.parentNode&&f.parentNode.removeChild(f),l(!1,"ALIPAY_SDK_LOAD_TIMEOUT","支付宝 JSSDK 加载超时")},1e4),i){f.type="text/javascript",f.src=t,f.async=!0,f.setAttribute("data-uniapp-tools","alipay-jssdk");const e=document.head||document.body||document.documentElement||null;if(!e)return void l(!1,"ALIPAY_SDK_INJECT_ERROR","无法找到可用的 script 注入容器");e.appendChild(f)}window.ap&&l(!0)}catch(e){l(!1,"ALIPAY_SDK_INJECT_ERROR",`注入支付宝 JSSDK 发生异常: ${e instanceof Error?e.message:String(e)}`)}}),We):(Ge.handleError(new n("ALIPAY_SDK_ENV_ERROR","不在浏览器环境中,无法注入支付宝 JSSDK","payment"),"payment"),Promise.resolve(!1)),ze=r.getInstance(),Ye=(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){ze.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)}),qe=r.getInstance(),Ve=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),Xe=()=>"undefined"!=typeof window&&"undefined"!=typeof document,Qe=()=>Xe()&&Ve()&&window.wx||null,Ze=(e,t=!1)=>{const n={};return e.forEach(e=>{"string"==typeof e&&""!==e.trim()&&(n[e]=t)}),n};let et=!1,tt=null,nt=!1;const rt=(e={})=>{const{timeoutMs:t=1e4}=e;if(et||Xe()&&window.wx)return et=!0,Promise.resolve(!0);if(!Xe())return Promise.resolve(!1);if(tt)return tt;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 tt=new Promise(e=>{let r=!1,s=null,o=null,i=0;const a=t=>{r||(r=!0,s&&(clearTimeout(s),s=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(et=!0),tt=null,e(t))},c=()=>{if(i>=n.length)return void a(!1);if(!document.head)return void a(!1);const e=n[i];i+=1;const t=document.createElement("script");o=t,t.src=e,t.async=!0,t.onload=()=>a(!0),t.onerror=()=>{t.parentNode&&t.parentNode.removeChild(t),o=null,c()},document.head.appendChild(t)};s=setTimeout(()=>{a(!1)},t),c()}),tt};let st=null;const ot=async(e,t={})=>{const{timeoutMs:r=1e4}=t;return Ve()?st||(st=(async()=>{if(!await rt({timeoutMs:r}))return qe.handleError(new n("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;const t=Qe();if(!t||"function"!=typeof t.config||"function"!=typeof t.ready||"function"!=typeof t.error)return!1;const s=t.config,o=t.ready,i=t.error,a=await new Promise(t=>{let a=!1,c=null;const u=e=>{a||(a=!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)),i(e=>{qe.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){qe.handleError(new n("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),u(!1)}});return nt=a,a})().finally(()=>{st=null}),st):(console.warn("当前不在微信环境中"),!1)},it=(e,t={})=>{const{timeoutMs:r=8e3}=t;return new Promise(t=>{const s=Qe();if(!s||"function"!=typeof s.checkJsApi)return void t(Ze(e,!1));let o=!1;const i=e=>{o||(o=!0,t(e))},a=setTimeout(()=>i(Ze(e,!1)),r);try{s.checkJsApi({jsApiList:e,success:t=>{clearTimeout(a),i({...Ze(e,!1),...t?.checkResult||{}})}})}catch(t){clearTimeout(a),qe.handleError(new n("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${t instanceof Error?t.message:String(t)}`,"weixin"),"weixin"),i(Ze(e,!1))}})},at=e=>{const t=Qe();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},ct=e=>{const t=Qe();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class ut{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return ut.instance||(ut.instance=new ut),ut.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=ot(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return(this.isConfigured||nt)&&Ve()}getConfig(){return this.config}setShareData(e){this.isReady()?(at(e),ct(e)):console.warn("微信 SDK 未就绪")}}const lt="5.0.0";export{r as ErrorHandler,n as UniAppToolsError,lt as VERSION,ut as WechatSDK,N as areaList,le as batchGetStorage,ue as batchSetStorage,F as buildUrl,it as checkWechatJSAPI,ce as cleanExpiredStorage,se as clearStorageSync,l as clearSystemCache,ot as configWechatJSSDK,Q as copyText,I as debounce,O as deepClone,P as deepMerge,$ as extractUrlParts,p as getCurrentEnv,q as getCurrentPageInfo,Te as getExtension,x as getH5UrlParams,w as getMenuButtonBoundingClientRect,T as getNavHeight,E as getNavigationBarHeight,V as getPageStack,d as getPlatform,y as getStatusBarHeight,ie as getStorage,ae as getStorageInfo,re as getStorageSync,S as getTopBarMetrics,R as getTopNavBarHeight,Ke as injectAlipayJsSdk,Ve as isWechat,rt as loadWechatJSSDK,C as mergeObjects,H as navigateTo,Le as normalizeConcurrency,h as onCheckForUpdate,G as reLaunch,B as redirectTo,s as safeAsync,K as safeNavigateTo,o as safeSync,He as selectAndUpload,Be as selectAndUploadImage,A as setPageIcon,_ as setPageTitle,oe as setStorage,ne as setStorageSync,ct as shareToFriend,at as shareToTimeline,J as switchTab,b as throttle,W as useBack,Y as useBackDebounced,z as useBackOrHome,D as useCascaderAreaData,M as useRegions,U as useToast,L as useTryCatch,g as useWindowInfo,be as validateSizeWithLimit,Ye 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 s{static instance;errorCallbacks=[];static getInstance(){return s.instance||(s.instance=new s),s.instance}onError(e){this.errorCallbacks.push(e)}handleError(e,t){const s={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(`[${s.module}] ${s.code}: ${s.message}`,s),this.errorCallbacks.forEach(e=>{try{e(s)}catch(e){console.error("Error in error callback:",e)}})}createModuleErrorHandler(e){return(t,s,r)=>{const o=new n(t,s,e);return r&&(o.stack=r.stack),this.handleError(o,e),o}}}async function r(e,t,n="ASYNC_ERROR"){try{return await e()}catch(e){return s.getInstance().createModuleErrorHandler(t)(n,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function o(e,t,n="SYNC_ERROR",r=null){try{return e()}catch(e){return s.getInstance().createModuleErrorHandler(t)(n,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),r}}const i=s.getInstance();let a=null,c=null,u=null;const l=()=>{u=null},f=e=>"weixin"===e||"alipay"===e;let m=!1;const d=()=>{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},g=(e=!0)=>e&&u?u:o(()=>{const t=uni.getWindowInfo();return e&&(u=t),t},"system","GET_WINDOW_INFO_ERROR",null),p=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return i.handleError(new n("GET_ACCOUNT_INFO_ERROR",`获取小程序账户信息失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),{appId:"",version:"",envVersion:"",accountInfo:{}}}},h=()=>{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){i.handleError(new n("UPDATE_DOWNLOAD_FAILED","新版本下载失败","system"),"system"),uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){i.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 i.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 i.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 i.handleError(new n("GET_NAVIGATION_BAR_HEIGHT_ERROR",`获取导航栏高度失败: ${e instanceof Error?e.message:String(e)}`,"system"),"system"),44}},S=()=>{const e=d(),t=y(),n=E();return{platform:e,statusBarHeight:t,navigationBarHeight:n,totalTopHeight:t+n}},R=()=>{const e=S();return{statusBarHeight:e.statusBarHeight,navHeight:e.totalTopHeight}},_=()=>S().totalTopHeight,T=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){i.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),C=s.getInstance();function v(e){if(null===e||"object"!=typeof e)return e;try{return"undefined"!=typeof structuredClone?structuredClone(e):JSON.parse(JSON.stringify(e))}catch(e){const t=e instanceof Error?e.message:String(e);throw C.handleError(new n("DEEP_CLONE_ERROR",`深拷贝失败: ${t}`,"utils"),"utils"),new Error(`深拷贝失败: ${t}`)}}function O(e,t){const n=v(e);return function e(t,n){for(const s in n)if(n.hasOwnProperty(s)){const r=n[s],o=t[s];r&&"object"==typeof r&&!Array.isArray(r)&&o&&"object"==typeof o&&!Array.isArray(o)?e(o,r):t[s]=v(r)}}(n,t),n}function P(e,t){if(!t||0===Object.keys(t).length)return e;const n={...e};for(const s of Object.keys(e))Object.prototype.hasOwnProperty.call(t,s)&&(n[s]=t[s]);return n}function I(e,t,n=!1){let s,r=null;const o=function(...o){const i=n&&!r;return r&&clearTimeout(r),r=setTimeout(()=>{r=null,n||(s=e.apply(this,o))},t),i&&(s=e.apply(this,o)),s};return o.cancel=()=>{r&&(clearTimeout(r),r=null)},o}function L(e,t,n={}){let s,r=null,o=0;const{leading:i=!0,trailing:a=!0}=n,c=function(...n){const c=Date.now();o||i||(o=c);const u=t-(c-o);return u<=0||u>t?(r&&(clearTimeout(r),r=null),o=c,s=e.apply(this,n)):!r&&a&&(r=setTimeout(()=>{o=i?Date.now():0,r=null,s=e.apply(this,n)},u)),s};return c.cancel=()=>{r&&(clearTimeout(r),r=null),o=0},c}const b=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(s){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 C.handleError(new n("GET_H5_URL_PARAMS_ERROR",`获取H5 URL参数失败: ${t instanceof Error?t.message:String(t)}`,"utils"),"utils"),e?null:{}}};function N(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,s={};return t.searchParams.forEach((e,t)=>{s[t]=e}),{path:n,params:s}}catch(t){return C.handleError(new n("EXTRACT_URL_PARTS_ERROR",`无效的URL: ${e}`,"utils"),"utils"),{path:"",params:{}}}}const x=e,$=t;function D(){return t()}const M=(e="",t=!1,n="none",s=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:s})},U=s.getInstance();let k={defaultHomePage:"/pages/index/index"};function H(e){k={...k,...e}}function F(e,t){if(!t)return e;const n=Object.entries(t).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");return e+(e.includes("?")?"&":"?")+n}const j=F;function B(e,t,s){const r=s?.errMsg?`${t} - ${s.errMsg}`:t;U.handleError(new n(e,r,"navigation"),"navigation")}async function G(e="",t={}){return new Promise(n=>{const s=t.delta||1,r=t.timeout||5e3,o=getCurrentPages();if(o.length<=s)return console.warn(`[navigation] 无法返回${s}页,当前页面栈深度不足(当前: ${o.length})`),void n(!1);let i=!1;const a=setTimeout(()=>{i||(i=!0,console.warn("[navigation] 页面init回调执行超时"),n(!1))},r);uni.navigateBack({delta:s,success:()=>{clearTimeout(a),setTimeout(()=>{if(!i)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)}i=!0,n(!0)}catch(e){B("PAGE_CALLBACK_ERROR",`页面回调执行失败: ${e instanceof Error?e.message:String(e)}`),i=!0,n(!0)}},100)},fail:e=>{clearTimeout(a),B("NAVIGATE_BACK_FAILED","导航返回失败",e),i=!0,n(!1)}})})}async function W(e="",t={}){const n=getCurrentPages(),s=t.delta||1;if(n.length>s)return await G(e,t);const r=t.homePage||k.defaultHomePage,o=r.startsWith("/")?r:`/${r}`;return console.info(`[navigation] 页面栈深度不足,重定向到首页: ${o}`),new Promise(e=>{const n=F(o,t.homeParams);uni.reLaunch({url:n,success:()=>e(!0),fail:t=>{B("RELAUNCH_FAILED",`重新启动失败: ${n}`,t),e(!1)}})})}const J=I(G,300);function K(){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 B("GET_CURRENT_PAGE_ERROR",`获取当前页面信息失败: ${e instanceof Error?e.message:String(e)}`),null}}const z=K;function Y(){try{return getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}}))}catch(e){return B("GET_PAGE_STACK_ERROR",`获取页面栈信息失败: ${e instanceof Error?e.message:String(e)}`),[]}}const V=Y,q={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function X(e,t={}){const n={...q,...t};return e&&"string"==typeof e?e.length>1e4?(n.showToast&&M("复制内容过长",!1,"error"),!1):await r(()=>new Promise(t=>{uni.setClipboardData({data:e,showToast:!1,success:()=>{n.showToast&&M(n.successMessage),t(!0)},fail:()=>{n.showToast&&M(n.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_ERROR")??!1:(n.showToast&&M("复制内容不能为空",!1,"error"),!1)}const Q=s.getInstance();class Z{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return Z.instance||(Z.instance=new Z),Z.instance}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,s={}){try{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const n={value:t,timestamp:Date.now(),ttl:s.ttl},r=JSON.stringify(n);if(r.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,r),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 Q.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 s=JSON.parse(n);let r;return r=s&&"object"==typeof s&&"value"in s&&"timestamp"in s?s:{value:s,timestamp:Date.now()},this.isExpired(r)?(this.remove(e),t):(this.cache.set(e,r),r.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 Q.handleError(new n("REMOVE_STORAGE_ERROR",`删除存储失败: ${e}`,"localStorage"),"localStorage"),!1}}clear(){try{return uni.clearStorageSync(),this.cache.clear(),!0}catch(e){return Q.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 Q.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 Q.handleError(new n("CLEAN_EXPIRED_ERROR",`清理过期数据失败: ${e instanceof Error?e.message:String(e)}`,"localStorage"),"localStorage"),0}}}const ee=Z.getInstance();function te(e,t,n={}){return ee.set(e,t,n)}function ne(e,t){return ee.get(e,t)}function se(e){return e?ee.remove(e):ee.clear()}async function re(e,t,n={}){return await r(()=>new Promise(s=>{s(te(e,t,n))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1}async function oe(e,t){return await r(()=>new Promise(n=>{n(ne(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t}function ie(){return ee.getInfo()}function ae(){return ee.cleanExpired()}function ce(e,t={}){let n=0;return Object.entries(e).forEach(([e,s])=>{te(e,s,t)&&n++}),n}function ue(e){const t={};return e.forEach(e=>{t[e]=ne(e)}),t}const le="上传失败",fe="已取消上传",me="选择文件失败",de="用户取消选择",ge=e=>`部分文件大小超过 ${e}MB 限制`,pe=e=>`存在不支持的文件类型,仅支持:${e.join(", ")}`,he="当前环境不支持文件选择",ye=e=>`上传超时(${e}ms)`,we=e=>`上传请求失败: ${e}`,Ee=e=>`上传失败,状态码:${e}`,Se={FILE_TYPE:"image",COUNT:1,SHOW_TOAST:!0};function Re(e){if(!e)return;const t=e.split(/[?#]/)[0].match(/\.([^./\\]+)$/);return t?t[1].toLowerCase():void 0}function _e(e){const t=e.toLowerCase().replace(/^\./,"");return"jpeg"===t||"jpe"===t?"jpg":t}function Te(e){return`${Date.now()}_${e}_${Math.random().toString(16).slice(2)}`}function Ae(e){return"string"==typeof e&&e.startsWith("blob:")}function Ce(e){if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return e}}function ve(e){if(null==e)return"";const t=typeof e;if("string"===t||"number"===t||"boolean"===t)return String(e);if("object"===t)try{return JSON.stringify(e)}catch{return String(e)}return String(e)}function Oe(e){if(!e)return;const t={};return Object.keys(e).forEach(n=>{t[n]=ve(e[n])}),t}function Pe(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:"选择文件失败"}function Ie(e,t){return null==t||"number"!=typeof t||!Number.isFinite(t)||t<0?{valid:!0}:e>1024*t*1024?{valid:!1,message:`文件大小不能超过 ${t}MB`}:{valid:!0}}function Le(e,t){return!Number.isFinite(t)||t<=0?0:"number"!=typeof e||!Number.isFinite(e)||e<=0?t:Math.min(Math.floor(e),t)}function be(e){return{toast:e.toast||M,shouldShowToast:e.showToast??Se.SHOW_TOAST}}function Ne(e){return Boolean(e?.aborted)}function xe(e){return[{file:null,success:!1,message:e}]}function $e(){return xe(fe)}async function De(e,t,n){const{url:s,files:r,type:o=Se.FILE_TYPE,count:i=Se.COUNT,maxSizeMB:a,extensions:c,signal:u,successMessage:l}=e,{toast:f,shouldShowToast:m}=be(e);if(!s.trim()){const e="上传地址不能为空";return m&&f(e,!1,"none"),xe(e)}if(Ne(u))return m&&f(fe,!1,"none"),$e();let d=r||[];if(0===d.length)try{const e=await t({type:o,count:i,extensions:c});if(!e.success)return m&&e.message&&f(e.message,!1,"none"),[{file:null,success:!1,message:e.message}];d=e.files}catch(e){const t=e instanceof Error?e.message:me;return m&&f(t,!1,"none"),xe(t)}if(0===d.length)return[];const g=function(e,t){if(!e||0===e.length)return{success:!1,message:"未选择任何文件"};const{maxSizeMB:n,extensions:s}=t;if(0===n)return{success:!1,message:"当前不允许选择文件"};const r=null!=n&&"number"==typeof n&&Number.isFinite(n)&&n>0,o=Array.isArray(s)&&s.length>0;if(!r&&!o)return{success:!0};const i=o?new Set(s.map(e=>_e(e))):null;for(const t of e){if(r&&!Ie(t.size,n).valid)return{success:!1,message:ge(n)};if(o&&i){const e=t.ext?_e(t.ext):void 0;if(!e||!i.has(e))return{success:!1,message:pe(s)}}}return{success:!0}}(d,{maxSizeMB:a,extensions:c});if(!g.success){const e=g.message||me;return m&&f(e,!1,"none"),xe(e)}if(Ne(u))return m&&f(fe,!1,"none"),$e();const p=await async function(e,t,n,s){const{concurrency:r,signal:o,beforeUpload:i,onProgress:a,showProgressToast:c,progressToastFormatter:u}=t,{toast:l,shouldShowToast:f}=be(t),m=new Array(e.length);let d=0;const g=e.length,p=Le(r,g),h=Boolean(c&&g>0),y="undefined"!=typeof uni?uni:null,w=Boolean(h&&y&&"function"==typeof y.showLoading&&"function"==typeof y.hideLoading),E=w,S=L((t,n)=>{if(!w)return;const s=function(e){const{files:t,index:n,pct:s,finishedCount:r,totalCount:o,progressToastFormatter:i}=e;return i?i(t[n],s,n+1,o):1===o?`上传中 ${s}%`:`上传中 (${r}/${o})`}({files:e,index:t,pct:n,finishedCount:d,totalCount:g,progressToastFormatter:u});y.showLoading({title:s,mask:!0})},200);const R=async r=>{const c=e[r];let u=null;try{if(Ne(o))return u={file:c,success:!1,message:fe},void(w&&S(r,0));const e=await async function(e){if(!i)return null;try{return await i(e)?null:{file:e,success:!1,message:fe}}catch(t){const n=(e=>`上传前检查失败: ${e}`)(t.message||"unknown");return f&&l(n,!1,"error"),{file:e,success:!1,message:n}}}(c);if(e)return void(u=e);const m=function(e){return E?{...t,onProgress:(t,n)=>{S(e,n),a&&a(t,n)}}:t}(r);u=await s(c,m,n)}catch(e){u={file:c,success:!1,message:e.message||"Unknown error"}}finally{u||(u={file:c,success:!1,message:"Unknown error"}),m[r]=u,d++,u.success&&S(r,100)}};for(let e=0;e<g;e+=p){const t=Math.min(e+p,g),n=[];for(let s=e;s<t;s+=1)n.push(R(s));await Promise.all(n)}return w&&(S.cancel?.(),y.hideLoading()),m}(d,e,s,n);return p.filter(e=>e.success).length===p.length&&1===p.length&&m&&f(l||"上传成功",!1,"none"),p}function Me(e,t,n,s,r,o,i){return{id:Te(t),name:i||`file_${t}`,size:n,path:e,ext:Re(i||e),source:s,platform:r,raw:o}}const Ue="undefined"!=typeof window&&"undefined"!=typeof document&&!function(){const e="undefined"==typeof uni?null:uni;return Boolean(e&&"function"==typeof e.uploadFile)}(),ke=Ue?function(e){const{type:t="image",count:n=1,extensions:s}=e;return new Promise(e=>{if("undefined"==typeof document||"undefined"==typeof window)return void e({success:!1,files:[],message:he});const r=document.createElement("input");r.type="file",r.multiple=n>1,r.style.display="none","image"===t?r.accept="image/*":s&&s.length>0&&(r.accept=s.map(e=>e.startsWith(".")?e:`.${e}`).join(","));let o=!1,i=null;const a=t=>{o||(o=!0,(()=>{i&&(clearTimeout(i),i=null),window.removeEventListener("focus",u);try{r.remove()}catch{}})(),e(t))},c=e=>{if(!e||0===e.length)return void a({success:!1,files:[],message:de});const t=Array.from(e).slice(0,n).map((e,t)=>({id:Te(t),name:e.name,size:e.size,path:URL.createObjectURL(e),mimeType:e.type,ext:Re(e.name),source:"file",platform:"h5",raw:e}));a({success:!0,files:t})};r.addEventListener("change",()=>c(r.files)),r.addEventListener("cancel",()=>a({success:!1,files:[],message:de}));const u=()=>{o||(i=window.setTimeout(()=>{o||(r.files&&0!==r.files.length?c(r.files):a({success:!1,files:[],message:de}))},300))};window.addEventListener("focus",u),document.body.appendChild(r),r.click()})}:function(e){const{type:t="image",count:n=1}=e;return new Promise(e=>{const s="undefined"==typeof uni?null:uni;if(!s)return void e({success:!1,files:[],message:he});const r=function(){if("undefined"!=typeof wx&&wx?.getSystemInfoSync)return"weixin";if("undefined"!=typeof my&&my?.getSystemInfoSync)return"alipay";if("undefined"!=typeof window&&"undefined"!=typeof document)return"h5";if("undefined"!=typeof plus)return"app";let e="unknown";return e="h5",e="weixin",e="alipay",e="app","app"}(),o=t=>{e({success:!1,files:[],message:Pe(t?.errMsg)})},i=[{name:"chooseMedia(image)",when:()=>"image"===t&&"weixin"===r&&"function"==typeof s.chooseMedia,run:()=>{s.chooseMedia({count:n,mediaType:["image"],success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>{const n=e.size||e.fileSize||e.originalFileSize||0;return Me(e.tempFilePath,t,n,"album",r,e)});e({success:!0,files:n})},fail:o})}},{name:"chooseImage",when:()=>"image"===t&&"function"==typeof s.chooseImage,run:()=>{s.chooseImage({count:n,success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:t?.tempFiles?[t.tempFiles]:[]).map((e,t)=>Me(e.path,t,e.size,"album",r,e));e({success:!0,files:n})},fail:o})}},{name:"chooseMessageFile(all)",when:()=>"function"==typeof s.chooseMessageFile,run:()=>{s.chooseMessageFile({count:n,type:"all",success:t=>{const n=(Array.isArray(t?.tempFiles)?t.tempFiles:[]).map((e,t)=>Me(e.path,t,e.size,"file",r,e,e.name));e({success:!0,files:n})},fail:o})}}];for(const e of i)if(e.when())return void e.run();e({success:!1,files:[],message:"当前平台不支持文件选择"})})},He=Ue?function(e,t,n){const{fieldName:s="file",formData:r,headers:o,timeoutMs:i,autoRevokeObjectURL:a}=t,{signal:c,onProgress:u}=t;return new Promise(t=>{const l=e.raw;if(!(l&&l instanceof File))return void t({file:e,success:!1,message:"H5 环境缺少原生文件对象"});const f=new XMLHttpRequest;let m=!1;const d=n=>{m||(m=!0,a&&Ae(e.path)&&function(e){if(Ae(e)&&"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL)try{URL.revokeObjectURL(e)}catch{}}(e.path),t(n))};if(c){if(c.aborted)return void d({file:e,success:!1,message:fe});c.addEventListener("abort",()=>{f.abort(),d({file:e,success:!1,message:fe})},{once:!0})}f.open("POST",n),i&&i>0&&(f.timeout=i),o&&Object.keys(o).forEach(e=>{f.setRequestHeader(e,o[e])});const g=new FormData;g.append(s,l,e.name),r&&Object.keys(r).forEach(e=>{g.append(e,ve(r[e]))}),f.upload.onprogress=t=>{if(t.lengthComputable&&u){const n=Math.round(t.loaded/t.total*100);u(e,n)}},f.onload=()=>{const t=f.status,n=t>=200&&t<300;let s=Ce(f.responseText);d({file:e,success:n,statusCode:t,data:s,message:n?void 0:Ee(t)})},f.onerror=()=>d({file:e,success:!1,message:le}),f.ontimeout=()=>d({file:e,success:!1,message:ye(i||0)}),f.onabort=()=>d({file:e,success:!1,message:fe});try{f.send(g)}catch(t){const n=t instanceof Error?t.message:"Unknown error";d({file:e,success:!1,message:we(n)})}})}:function(e,t,n){const{fieldName:s="file",formData:r,headers:o,timeoutMs:i}=t,{signal:a,onProgress:c}=t;return new Promise(t=>{const u="undefined"==typeof uni?null:uni;if(!u?.uploadFile)return void t({file:e,success:!1,message:"当前环境不支持文件上传"});let l=!1,f=null,m=null;const d=e=>{l||(l=!0,f&&clearTimeout(f),t(e))};i&&i>0&&(f=setTimeout(()=>{m?.abort?.(),d({file:e,success:!1,message:ye(i)})},i)),m=u.uploadFile({url:n,filePath:e.path,name:s,header:o,formData:Oe(r),success:t=>{const n=function(e){if(e&&"number"==typeof e.statusCode)return e.statusCode;if(e&&"number"==typeof e.status)return e.status;const t="string"==typeof e?.errMsg?e.errMsg:"";return/:ok\b/i.test(t)?200:0}(t),s=n>=200&&n<300,r=Ce(t.data);d({file:e,success:s,statusCode:n,data:r,message:s?void 0:Ee(n)})},fail:t=>{l||d({file:e,success:!1,message:t?.errMsg||le})}}),c&&m?.onProgressUpdate&&m.onProgressUpdate(t=>{l||"number"!=typeof t.progress||c(e,t.progress)}),a&&(a.aborted?(m?.abort?.(),d({file:e,success:!1,message:fe})):a.addEventListener("abort",()=>{m?.abort?.(),d({file:e,success:!1,message:fe})},{once:!0}))})};async function Fe(e){return De(e,ke,He)}async function je(e){return Fe({...e,type:"image"})}const Be=s.getInstance();let Ge=!1,We=null;const Je=(e="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.min.js")=>"undefined"!=typeof window&&window.document?Ge||window.ap?(Ge=!0,Promise.resolve(!0)):We||(We=new Promise(t=>{const s={settled:!1,timeoutId:null,script:null,createdByThisCall:!1},r=e=>{s.settled||(s.settled=!0,s.timeoutId&&(clearTimeout(s.timeoutId),s.timeoutId=null),e.success?Ge=!0:Be.handleError(new n(e.code,e.message,"payment"),"payment"),We=null,t(e.success))};try{let t;try{t=new URL(e,window.location.href).href}catch{return void r({success:!1,code:"ALIPAY_SDK_INVALID_URL",message:`无效的 JSSDK 地址: ${e}`})}const n=Array.from(document.getElementsByTagName("script")).find(e=>e.src===t),o=n??document.createElement("script");s.script=o,s.createdByThisCall=!n;const i=()=>{setTimeout(()=>{window.ap?r({success:!0}):r({success:!1,code:"ALIPAY_SDK_INIT_ERROR",message:"支付宝 JSSDK 加载成功但未能初始化 window.ap"})},50)},a=e=>{s.createdByThisCall&&o.parentNode&&o.parentNode.removeChild(o),r({success:!1,code:"ALIPAY_SDK_LOAD_ERROR",message:`支付宝 JSSDK 加载失败: ${String(e?.type||"error")}`})};o.addEventListener("load",i,{once:!0}),o.addEventListener("error",a,{once:!0}),s.timeoutId=setTimeout(()=>{s.createdByThisCall&&o.parentNode&&o.parentNode.removeChild(o),r({success:!1,code:"ALIPAY_SDK_LOAD_TIMEOUT",message:"支付宝 JSSDK 加载超时"})},1e4),s.createdByThisCall&&(o.type="text/javascript",o.src=t,o.async=!0,o.setAttribute("data-uniapp-tools","alipay-jssdk"),(document.head||document.body||document.documentElement).appendChild(o)),window.ap&&r({success:!0})}catch(e){r({success:!1,code:"ALIPAY_SDK_UNEXPECTED_ERROR",message:`支付宝 JSSDK 注入过程发生意外异常: ${e instanceof Error?e.message:String(e)}`})}}),We):(Be.handleError(new n("ALIPAY_SDK_ENV_ERROR","不在浏览器环境中,无法注入支付宝 JSSDK","payment"),"payment"),Promise.resolve(!1)),Ke=s.getInstance(),ze="WECHAT_PAY_INVALID_CONFIG",Ye=(e,t={})=>{const{reportError:s=!0}=t;return new Promise(t=>{const r=(e,t,r=null)=>{const o=new n(e,t,"payment");return s&&Ke.handleError(o,"payment"),{success:!1,status:"error",code:e,message:t,raw:r}};if(!(e?.appId&&e?.timeStamp&&e?.nonceStr&&e?.package&&e?.signType&&e?.paySign))return void t(r(ze,"微信支付配置参数不完整"));if(!e.package.startsWith("prepay_id="))return void t(r(ze,"微信支付 package 格式非法,应以 'prepay_id=' 开头"));if("undefined"==typeof window||!window.navigator)return void t(r("WECHAT_PAY_ENV_ERROR","不在浏览器环境中,无法调用微信支付"));const o=()=>{try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,e=>{"get_brand_wcpay_request:ok"===e.err_msg?t({success:!0,status:"success",code:"WECHAT_PAY_SUCCESS",message:"支付成功",raw:e}):"get_brand_wcpay_request:cancel"===e.err_msg?t({success:!1,status:"cancel",code:"WECHAT_PAY_CANCEL",message:"用户取消支付",raw:e}):t({success:!1,status:"error",code:"WECHAT_PAY_FAIL",message:e.err_desc||"支付失败",raw:e})})}catch(e){t(r("WECHAT_PAY_INVOKE_ERROR",`调用微信支付接口失败: ${e instanceof Error?e.message:String(e)}`))}};if(void 0===window.WeixinJSBridge){const e=()=>{o(),window.document.removeEventListener("WeixinJSBridgeReady",e,!1)};window.document.addEventListener("WeixinJSBridgeReady",e,!1)}else o()})},Ve=s.getInstance(),qe=()=>!("undefined"==typeof navigator||!navigator.userAgent)&&navigator.userAgent.toLowerCase().includes("micromessenger"),Xe=()=>"undefined"!=typeof window&&"undefined"!=typeof document,Qe=()=>Xe()&&qe()&&window.wx||null,Ze=(e,t=!1)=>{const n={};return e.forEach(e=>{"string"==typeof e&&""!==e.trim()&&(n[e]=t)}),n};let et=!1,tt=null,nt=!1;const st=(e={})=>{const{timeoutMs:t=1e4}=e;if(et||Xe()&&window.wx)return et=!0,Promise.resolve(!0);if(!Xe())return Promise.resolve(!1);if(tt)return tt;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 tt=new Promise(e=>{let s=!1,r=null,o=null,i=0;const a=t=>{s||(s=!0,r&&(clearTimeout(r),r=null),o&&o.parentNode&&o.parentNode.removeChild(o),t&&(et=!0),tt=null,e(t))},c=()=>{if(i>=n.length)return void a(!1);if(!document.head)return void a(!1);const e=n[i];i+=1;const t=document.createElement("script");o=t,t.src=e,t.async=!0,t.onload=()=>a(!0),t.onerror=()=>{t.parentNode&&t.parentNode.removeChild(t),o=null,c()},document.head.appendChild(t)};r=setTimeout(()=>{a(!1)},t),c()}),tt};let rt=null;const ot=async(e,t={})=>{const{timeoutMs:s=1e4}=t;return qe()?rt||(rt=(async()=>{if(!await st({timeoutMs:s}))return Ve.handleError(new n("WECHAT_JSSDK_LOAD_FAILED","微信 JS-SDK 加载失败","weixin"),"weixin"),!1;const t=Qe();if(!t||"function"!=typeof t.config||"function"!=typeof t.ready||"function"!=typeof t.error)return!1;const r=t.config,o=t.ready,i=t.error,a=await new Promise(t=>{let a=!1,c=null;const u=e=>{a||(a=!0,c&&(clearTimeout(c),c=null),t(e))};c=setTimeout(()=>u(!1),s);try{r({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),o(()=>u(!0)),i(e=>{Ve.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){Ve.handleError(new n("WECHAT_JSSDK_CONFIG_EXCEPTION",`微信 JS-SDK 配置异常: ${e instanceof Error?e.message:String(e)}`,"weixin"),"weixin"),u(!1)}});return nt=a,a})().finally(()=>{rt=null}),rt):(console.warn("当前不在微信环境中"),!1)},it=(e,t={})=>{const{timeoutMs:s=8e3}=t;return new Promise(t=>{const r=Qe();if(!r||"function"!=typeof r.checkJsApi)return void t(Ze(e,!1));let o=!1;const i=e=>{o||(o=!0,t(e))},a=setTimeout(()=>i(Ze(e,!1)),s);try{r.checkJsApi({jsApiList:e,success:t=>{clearTimeout(a),i({...Ze(e,!1),...t?.checkResult||{}})}})}catch(t){clearTimeout(a),Ve.handleError(new n("CHECK_WECHAT_JSAPI_ERROR",`检查微信 JS-SDK API 异常: ${t instanceof Error?t.message:String(t)}`,"weixin"),"weixin"),i(Ze(e,!1))}})},at=e=>{const t=Qe();t&&(t.updateTimelineShareData?t.updateTimelineShareData(e):t.onMenuShareTimeline&&t.onMenuShareTimeline(e))},ct=e=>{const t=Qe();t&&(t.updateAppMessageShareData?t.updateAppMessageShareData(e):t.onMenuShareAppMessage&&t.onMenuShareAppMessage(e))};class ut{static instance;isConfigured=!1;config=null;initPromise=null;constructor(){}static getInstance(){return ut.instance||(ut.instance=new ut),ut.instance}async init(e){return this.initPromise||(this.config=e,this.initPromise=ot(e).then(e=>(this.isConfigured=e,e)).finally(()=>{this.initPromise=null})),this.initPromise}isReady(){return(this.isConfigured||nt)&&qe()}getConfig(){return this.config}setShareData(e){this.isReady()?(at(e),ct(e)):console.warn("微信 SDK 未就绪")}}const lt="5.0.0";export{s as ErrorHandler,n as UniAppToolsError,lt as VERSION,ut as WechatSDK,x as areaList,ue as batchGetStorage,ce as batchSetStorage,j as buildUrl,it as checkWechatJSAPI,ae as cleanExpiredStorage,se as clearStorageSync,l as clearSystemCache,ot as configWechatJSSDK,H as configureNavigation,X as copyText,I as debounce,v as deepClone,O as deepMerge,N as extractUrlParts,p as getCurrentEnv,z as getCurrentPageInfo,Re as getExtension,b as getH5UrlParams,w as getMenuButtonBoundingClientRect,_ as getNavHeight,E as getNavigationBarHeight,V as getPageStack,d as getPlatform,y as getStatusBarHeight,oe as getStorage,ie as getStorageInfo,ne as getStorageSync,S as getTopBarMetrics,R as getTopNavBarHeight,Je as injectAlipayJsSdk,qe as isWechat,st as loadWechatJSSDK,P as mergeObjects,Le as normalizeConcurrency,h as onCheckForUpdate,r as safeAsync,o as safeSync,Fe as selectAndUpload,je as selectAndUploadImage,A as setPageIcon,T as setPageTitle,re as setStorage,te as setStorageSync,ct as shareToFriend,at as shareToTimeline,L as throttle,G as useBack,J as useBackDebounced,W as useBackOrHome,F as useBuildUrl,$ as useCascaderAreaData,K as useCurrentPageInfo,Y as usePageStack,D as useRegions,M as useToast,g as useWindowInfo,Ie as validateSizeWithLimit,Ye as wechatH5Pay};
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 导航工具函数
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* 4. 移除性能监控(在开发环境手动测量即可)
|
|
9
|
-
* 5. 简化代码逻辑,提升可维护性
|
|
10
|
-
* 6. v4.0.0: 函数重新排序,抽取公共错误处理,补充详细注释
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* 页面跳转选项
|
|
4
|
+
* 设计原则:
|
|
5
|
+
* - 消除重复:通用包装器统一处理
|
|
6
|
+
* - 明确语义:超时是等回调,不是等API
|
|
7
|
+
* - 避免竞态:保存初始状态,不重复查询
|
|
14
8
|
*/
|
|
15
9
|
export interface NavigateOptions {
|
|
16
10
|
url: string;
|
|
@@ -19,121 +13,39 @@ export interface NavigateOptions {
|
|
|
19
13
|
animationDuration?: number;
|
|
20
14
|
events?: Record<string, Function>;
|
|
21
15
|
}
|
|
22
|
-
/**
|
|
23
|
-
* 返回导航配置选项
|
|
24
|
-
*/
|
|
25
16
|
export interface BackOptions {
|
|
26
17
|
delta?: number;
|
|
27
18
|
timeout?: number;
|
|
28
19
|
}
|
|
29
|
-
/**
|
|
30
|
-
* 返回上一页或跳转首页选项
|
|
31
|
-
*/
|
|
32
20
|
export interface BackOrHomeOptions extends BackOptions {
|
|
33
21
|
homePage?: string;
|
|
34
22
|
homeParams?: Record<string, any>;
|
|
35
23
|
}
|
|
24
|
+
interface NavigationConfig {
|
|
25
|
+
defaultHomePage: string;
|
|
26
|
+
}
|
|
36
27
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @param url 基础URL路径
|
|
40
|
-
* @param params URL查询参数对象
|
|
41
|
-
* @returns 完整的URL字符串
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* buildUrl('/pages/detail/detail', { id: 123, type: 'product' })
|
|
45
|
-
* // 返回: '/pages/detail/detail?id=123&type=product'
|
|
46
|
-
*/
|
|
47
|
-
export declare function buildUrl(url: string, params?: Record<string, any>): string;
|
|
48
|
-
/**
|
|
49
|
-
* 跳转到指定页面(保留当前页面)
|
|
50
|
-
*
|
|
51
|
-
* @param options 导航选项
|
|
52
|
-
* @param options.url 目标页面路径(必填)
|
|
53
|
-
* @param options.params URL参数对象
|
|
54
|
-
* @param options.animationType 窗口显示动画效果
|
|
55
|
-
* @param options.animationDuration 窗口动画持续时间(毫秒)
|
|
56
|
-
* @param options.events 页面间通信接口
|
|
57
|
-
* @returns Promise<boolean> 返回 true 表示跳转成功,false 表示失败
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* // 基础跳转
|
|
61
|
-
* await navigateTo({ url: '/pages/detail/detail' });
|
|
62
|
-
*
|
|
63
|
-
* // 带参数跳转
|
|
64
|
-
* await navigateTo({
|
|
65
|
-
* url: '/pages/detail/detail',
|
|
66
|
-
* params: { id: 123, type: 'product' }
|
|
67
|
-
* });
|
|
68
|
-
*
|
|
69
|
-
* // 带动画效果跳转
|
|
70
|
-
* await navigateTo({
|
|
71
|
-
* url: '/pages/detail/detail',
|
|
72
|
-
* animationType: 'slide-in-right',
|
|
73
|
-
* animationDuration: 300
|
|
74
|
-
* });
|
|
75
|
-
*/
|
|
76
|
-
export declare function navigateTo(options: NavigateOptions): Promise<boolean>;
|
|
77
|
-
/**
|
|
78
|
-
* 重定向到指定页面(关闭当前页面)
|
|
79
|
-
*
|
|
80
|
-
* @param options 导航选项
|
|
81
|
-
* @param options.url 目标页面路径(必填)
|
|
82
|
-
* @param options.params URL参数对象
|
|
83
|
-
* @returns Promise<boolean> 返回 true 表示重定向成功,false 表示失败
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* // 重定向到登录页
|
|
87
|
-
* await redirectTo({ url: '/pages/login/login' });
|
|
88
|
-
*
|
|
89
|
-
* // 带参数重定向
|
|
90
|
-
* await redirectTo({
|
|
91
|
-
* url: '/pages/result/result',
|
|
92
|
-
* params: { status: 'success', orderId: '12345' }
|
|
93
|
-
* });
|
|
94
|
-
*/
|
|
95
|
-
export declare function redirectTo(options: NavigateOptions): Promise<boolean>;
|
|
96
|
-
/**
|
|
97
|
-
* 重新启动到指定页面(关闭所有页面)
|
|
98
|
-
*
|
|
99
|
-
* @param options 导航选项
|
|
100
|
-
* @param options.url 目标页面路径(必填)
|
|
101
|
-
* @param options.params URL参数对象
|
|
102
|
-
* @returns Promise<boolean> 返回 true 表示重启成功,false 表示失败
|
|
103
|
-
*
|
|
28
|
+
* 配置导航模块
|
|
104
29
|
* @example
|
|
105
|
-
*
|
|
106
|
-
* await reLaunch({ url: '/pages/index/index' });
|
|
107
|
-
*
|
|
108
|
-
* // 登录成功后重启应用
|
|
109
|
-
* await reLaunch({
|
|
110
|
-
* url: '/pages/home/home',
|
|
111
|
-
* params: { user: 'john' }
|
|
112
|
-
* });
|
|
30
|
+
* configureNavigation({ defaultHomePage: '/pages/home/home' });
|
|
113
31
|
*/
|
|
114
|
-
export declare function
|
|
32
|
+
export declare function configureNavigation(config: Partial<NavigationConfig>): void;
|
|
33
|
+
export declare function useBuildUrl(url: string, params?: Record<string, any>): string;
|
|
115
34
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* @param url Tab页面路径
|
|
119
|
-
* @returns Promise<boolean> 返回 true 表示切换成功,false 表示失败
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* // 切换到首页Tab
|
|
123
|
-
* await switchTab('/pages/index/index');
|
|
124
|
-
*
|
|
125
|
-
* // 切换到我的Tab
|
|
126
|
-
* await switchTab('/pages/user/user');
|
|
35
|
+
* @deprecated 请使用 useBuildUrl 替代(符合 Vue composable 命名约定)
|
|
127
36
|
*/
|
|
128
|
-
export declare
|
|
37
|
+
export declare const buildUrl: typeof useBuildUrl;
|
|
129
38
|
/**
|
|
130
39
|
* 返回上一页
|
|
131
40
|
*
|
|
132
41
|
* @param params 返回上一页时传入的参数(会调用目标页面的 init 方法)
|
|
133
42
|
* @param options 导航选项
|
|
134
43
|
* @param options.delta 返回的页面数,默认1
|
|
135
|
-
* @param options.timeout
|
|
136
|
-
* @returns Promise<boolean> 返回 true 表示导航成功,false
|
|
44
|
+
* @param options.timeout 回调执行超时时间(毫秒),默认5000(注意:这不是导航API本身的超时)
|
|
45
|
+
* @returns Promise<boolean> 返回 true 表示导航成功,false 表示失败(页面栈不足或回调超时)
|
|
46
|
+
*
|
|
47
|
+
* @description
|
|
48
|
+
* 注意:timeout 参数并非导航API本身的超时(navigateBack是同步的),而是等待"页面切换完成 + init回调执行"的超时。
|
|
137
49
|
*
|
|
138
50
|
* @example
|
|
139
51
|
* // 基础返回
|
|
@@ -145,32 +57,10 @@ export declare function switchTab(url: string): Promise<boolean>;
|
|
|
145
57
|
* // 返回两层页面
|
|
146
58
|
* await useBack('', { delta: 2 });
|
|
147
59
|
*
|
|
148
|
-
* //
|
|
60
|
+
* // 设置回调执行超时时间
|
|
149
61
|
* await useBack('', { timeout: 3000 });
|
|
150
62
|
*/
|
|
151
63
|
export declare function useBack(params?: any, options?: BackOptions): Promise<boolean>;
|
|
152
|
-
/**
|
|
153
|
-
* 安全的页面跳转(带重试机制)
|
|
154
|
-
*
|
|
155
|
-
* @param options 导航选项
|
|
156
|
-
* @param maxRetries 最大重试次数,默认3次
|
|
157
|
-
* @returns Promise<boolean> 返回 true 表示跳转成功,false 表示所有重试都失败
|
|
158
|
-
*
|
|
159
|
-
* @description
|
|
160
|
-
* 当页面跳转失败时,会自动重试指定次数。
|
|
161
|
-
* 重试间隔会逐渐增加:第1次等待1秒,第2次等待2秒,第3次等待3秒
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* // 使用默认重试次数(3次)
|
|
165
|
-
* const success = await safeNavigateTo({ url: '/pages/detail/detail' });
|
|
166
|
-
*
|
|
167
|
-
* // 自定义重试次数
|
|
168
|
-
* const success = await safeNavigateTo(
|
|
169
|
-
* { url: '/pages/detail/detail' },
|
|
170
|
-
* 5 // 最多重试5次
|
|
171
|
-
* );
|
|
172
|
-
*/
|
|
173
|
-
export declare function safeNavigateTo(options: NavigateOptions, maxRetries?: number): Promise<boolean>;
|
|
174
64
|
/**
|
|
175
65
|
* 返回上一页,若页面栈不足则重定向到首页
|
|
176
66
|
*
|
|
@@ -178,7 +68,7 @@ export declare function safeNavigateTo(options: NavigateOptions, maxRetries?: nu
|
|
|
178
68
|
* @param options 导航选项
|
|
179
69
|
* @param options.delta 返回的页面数,默认1
|
|
180
70
|
* @param options.timeout 超时时间(毫秒),默认5000
|
|
181
|
-
* @param options.homePage
|
|
71
|
+
* @param options.homePage 首页路径,默认使用全局配置(可通过 configureNavigation 设置)
|
|
182
72
|
* @param options.homeParams 首页参数
|
|
183
73
|
* @returns Promise<boolean> 返回 true 表示操作成功,false 表示失败
|
|
184
74
|
*
|
|
@@ -186,12 +76,13 @@ export declare function safeNavigateTo(options: NavigateOptions, maxRetries?: nu
|
|
|
186
76
|
* 智能返回函数:
|
|
187
77
|
* - 如果页面栈深度足够,执行正常返回
|
|
188
78
|
* - 如果页面栈深度不足(如只有1个页面),则重定向到首页
|
|
79
|
+
* - 首页路径优先级:传入的 homePage > 全局配置 > 默认值 '/pages/index/index'
|
|
189
80
|
*
|
|
190
81
|
* @example
|
|
191
|
-
* //
|
|
82
|
+
* // 基础使用(页面栈不足时跳转到全局配置的首页)
|
|
192
83
|
* await useBackOrHome();
|
|
193
84
|
*
|
|
194
|
-
* //
|
|
85
|
+
* // 自定义首页路径(临时覆盖全局配置)
|
|
195
86
|
* await useBackOrHome('', {
|
|
196
87
|
* homePage: '/pages/home/home',
|
|
197
88
|
* homeParams: { from: 'auto' }
|
|
@@ -211,7 +102,9 @@ export declare function useBackOrHome(params?: any, options?: BackOrHomeOptions)
|
|
|
211
102
|
* // 在按钮点击事件中使用
|
|
212
103
|
* <button @click="useBackDebounced()">返回</button>
|
|
213
104
|
*/
|
|
214
|
-
export declare const useBackDebounced: typeof useBack
|
|
105
|
+
export declare const useBackDebounced: typeof useBack & {
|
|
106
|
+
cancel: () => void;
|
|
107
|
+
};
|
|
215
108
|
/**
|
|
216
109
|
* 获取当前页面信息
|
|
217
110
|
*
|
|
@@ -220,7 +113,7 @@ export declare const useBackDebounced: typeof useBack;
|
|
|
220
113
|
* @returns {any} options 当前页面的参数对象
|
|
221
114
|
*
|
|
222
115
|
* @example
|
|
223
|
-
* const pageInfo =
|
|
116
|
+
* const pageInfo = useCurrentPageInfo();
|
|
224
117
|
* if (pageInfo) {
|
|
225
118
|
* console.log('当前页面路由:', pageInfo.route);
|
|
226
119
|
* console.log('当前页面参数:', pageInfo.options);
|
|
@@ -232,10 +125,14 @@ export declare const useBackDebounced: typeof useBack;
|
|
|
232
125
|
* // options: { id: '123', type: 'product' }
|
|
233
126
|
* // }
|
|
234
127
|
*/
|
|
235
|
-
export declare function
|
|
128
|
+
export declare function useCurrentPageInfo(): {
|
|
236
129
|
route: string;
|
|
237
130
|
options: any;
|
|
238
131
|
} | null;
|
|
132
|
+
/**
|
|
133
|
+
* @deprecated 请使用 useCurrentPageInfo 替代(符合 Vue composable 命名约定)
|
|
134
|
+
*/
|
|
135
|
+
export declare const getCurrentPageInfo: typeof useCurrentPageInfo;
|
|
239
136
|
/**
|
|
240
137
|
* 获取页面栈信息
|
|
241
138
|
*
|
|
@@ -246,7 +143,7 @@ export declare function getCurrentPageInfo(): {
|
|
|
246
143
|
* 数组索引0是最底层的页面,最后一个元素是当前页面。
|
|
247
144
|
*
|
|
248
145
|
* @example
|
|
249
|
-
* const stack =
|
|
146
|
+
* const stack = usePageStack();
|
|
250
147
|
* console.log('页面栈深度:', stack.length);
|
|
251
148
|
* console.log('第一个页面:', stack[0]);
|
|
252
149
|
* console.log('当前页面:', stack[stack.length - 1]);
|
|
@@ -258,7 +155,12 @@ export declare function getCurrentPageInfo(): {
|
|
|
258
155
|
* // { route: 'pages/detail/detail', options: { id: '123' } }
|
|
259
156
|
* // ]
|
|
260
157
|
*/
|
|
261
|
-
export declare function
|
|
158
|
+
export declare function usePageStack(): Array<{
|
|
262
159
|
route: string;
|
|
263
160
|
options: any;
|
|
264
161
|
}>;
|
|
162
|
+
/**
|
|
163
|
+
* @deprecated 请使用 usePageStack 替代(符合 Vue composable 命名约定)
|
|
164
|
+
*/
|
|
165
|
+
export declare const getPageStack: typeof usePageStack;
|
|
166
|
+
export {};
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { useCascaderAreaData as vantUseCascaderAreaData } from '@vant/area-data';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @description H5 环境优先使用 structuredClone
|
|
6
|
+
* 高性能深拷贝(uni-app 多端兼容)
|
|
7
|
+
* @description H5 环境优先使用 structuredClone,降级为 JSON 序列化
|
|
8
8
|
*/
|
|
9
9
|
export declare function deepClone<T>(obj: T): T;
|
|
10
10
|
/**
|
|
@@ -18,26 +18,30 @@ export declare function deepMerge<T extends Record<string, any>>(target: T, sour
|
|
|
18
18
|
export declare function mergeObjects<T extends Record<string, any>, U extends Record<string, any>>(base: T, incoming: U): T;
|
|
19
19
|
/**
|
|
20
20
|
* 防抖函数
|
|
21
|
+
* @description 延迟执行,重复触发则重置定时器
|
|
22
|
+
* @param func 要防抖的函数
|
|
23
|
+
* @param wait 延迟时间(毫秒)
|
|
24
|
+
* @param immediate 是否立即执行(首次触发时)
|
|
25
|
+
* @returns 防抖包装后的函数,附带 cancel 方法
|
|
21
26
|
*/
|
|
22
|
-
export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number, immediate?: boolean): T
|
|
27
|
+
export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number, immediate?: boolean): T & {
|
|
28
|
+
cancel: () => void;
|
|
29
|
+
};
|
|
23
30
|
/**
|
|
24
31
|
* 节流函数
|
|
32
|
+
* @description 限制执行频率,确保在时间窗口内只执行一次
|
|
33
|
+
* @param func 要节流的函数
|
|
34
|
+
* @param wait 时间窗口(毫秒)
|
|
35
|
+
* @param options.leading 是否在时间窗口开始时执行(默认 true)
|
|
36
|
+
* @param options.trailing 是否在时间窗口结束时执行(默认 true)
|
|
37
|
+
* @returns 节流包装后的函数,附带 cancel 方法
|
|
25
38
|
*/
|
|
26
39
|
export declare function throttle<T extends (...args: any[]) => any>(func: T, wait: number, options?: {
|
|
27
40
|
leading?: boolean;
|
|
28
41
|
trailing?: boolean;
|
|
29
|
-
}): T
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* @returns 包装后的执行函数,返回 Promise<{ data, error }>
|
|
33
|
-
*/
|
|
34
|
-
export declare function useTryCatch<T extends (...args: any[]) => any>(fn: T, options?: {
|
|
35
|
-
onError?: (error: unknown) => void;
|
|
36
|
-
onFinally?: () => void;
|
|
37
|
-
}): (...args: Parameters<T>) => Promise<{
|
|
38
|
-
data: Awaited<ReturnType<T>> | null;
|
|
39
|
-
error: unknown;
|
|
40
|
-
}>;
|
|
42
|
+
}): T & {
|
|
43
|
+
cancel: () => void;
|
|
44
|
+
};
|
|
41
45
|
export interface UrlParams {
|
|
42
46
|
[key: string]: string;
|
|
43
47
|
}
|