my-uniapp-tools 1.0.17 → 1.0.21

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/dist/index.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  export function initUniAppTools(config?: {}): Promise<void>;
2
2
  export * from "./core/errorHandler";
3
3
  export * from "./core/performance";
4
+ export * from "./system";
5
+ export * from "./utils";
4
6
  export * from "./ui";
5
7
  export * from "./navigation";
6
8
  export * from "./clipboard";
7
- export * from "./system";
8
9
  export * from "./localStorage";
9
- export * from "./utils";
10
10
  export * from "./upload";
11
11
  export * from "./payment";
12
+ export * from "./weixin";
12
13
  export const VERSION: "1.0.8";
@@ -1 +1 @@
1
- "use strict";class e 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 t{static instance;errorCallbacks=[];static getInstance(){return t.instance||(t.instance=new t),t.instance}onError(e){this.errorCallbacks.push(e)}handleError(t,n){const s={code:t instanceof e?t.code:"UNKNOWN_ERROR",message:t.message,module:t instanceof e?t.module:n,timestamp:t instanceof e?t.timestamp:Date.now(),stack:t.stack};this.errorCallbacks.forEach(e=>{try{e(s)}catch(e){}})}createModuleErrorHandler(t){return(n,s,a)=>{const r=new e(n,s,t);return a&&(r.stack=a.stack),this.handleError(r,t),r}}}async function n(e,n,s="ASYNC_ERROR"){try{return await e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(s,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function s(e,n,s="SYNC_ERROR",a=null){try{return e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(s,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),a}}var a=Object.freeze({__proto__:null,ErrorHandler:t,UniAppToolsError:e,safeAsync:n,safeSync:s});class r{static instance;metrics=new Map;completedMetrics=[];maxStoredMetrics=100;static getInstance(){return r.instance||(r.instance=new r),r.instance}start(e,t,n){const s={name:e,startTime:performance.now(),module:t,metadata:n};this.metrics.set(e,s)}end(e){const t=this.metrics.get(e);return t?(t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.metrics.delete(e),this.completedMetrics.push(t),this.completedMetrics.length>this.maxStoredMetrics&&this.completedMetrics.shift(),t):null}getReport(){const e={},t={};this.completedMetrics.forEach(n=>{e[n.module]||(e[n.module]=[]),e[n.module].push(n);const s=`${n.module}.${n.name}`;t[s]||(t[s]={total:0,count:0}),t[s].total+=n.duration||0,t[s].count+=1});const n={};Object.entries(t).forEach(([e,t])=>{n[e]=t.total/t.count});const s=[...this.completedMetrics].sort((e,t)=>(t.duration||0)-(e.duration||0)).slice(0,10);return{byModule:e,slowest:s,average:n}}clear(){this.metrics.clear(),this.completedMetrics=[]}}function o(e){return function(t,n,s){const a=s.value;s.value=function(...s){const o=r.getInstance(),i=`${t.constructor.name}.${n}`;o.start(i,e,{args:s.length});try{const e=a.apply(this,s);return e instanceof Promise?e.finally(()=>{o.end(i)}):(o.end(i),e)}catch(e){throw o.end(i),e}}}}var i=Object.freeze({__proto__:null,PerformanceMonitor:r,measurePerformance:o});const c=(e="",t=!1,n="none",s=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:s})};function u(e){return s(()=>{if(null===e||"object"!=typeof e)return e;const t=new WeakMap;return function e(n){if(null===n||"object"!=typeof n)return n;if(t.has(n))return t.get(n);if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(n instanceof Map){const s=new Map;return t.set(n,s),n.forEach((t,n)=>{s.set(e(n),e(t))}),s}if(n instanceof Set){const s=new Set;return t.set(n,s),n.forEach(t=>{s.add(e(t))}),s}if(Array.isArray(n)){const s=new Array(n.length);t.set(n,s);for(let t=0;t<n.length;t++)s[t]=e(n[t]);return s}const s=Object.create(Object.getPrototypeOf(n));t.set(n,s);const a=Object.getOwnPropertyDescriptors(n);for(const t in a){const n=a[t];void 0!==n.value&&(n.value=e(n.value)),Object.defineProperty(s,t,n)}return s}(e)},"utils","DEEP_CLONE_ERROR",e)}function l(e,t){const n=r.getInstance();n.start("mergeObjects","utils");const a=s(()=>Object.assign(e,t),"utils","MERGE_OBJECTS_ERROR",e);return n.end("mergeObjects"),a}function p(e,t,n=!1){let s,a=null;const r=function(...r){const o=n&&!a;return a&&clearTimeout(a),a=setTimeout(()=>{a=null,n||(s=e.apply(this,r))},t),o&&(s=e.apply(this,r)),s};return r.cancel=()=>{a&&(clearTimeout(a),a=null)},r}class g{static instance;navigationQueue=[];isNavigating=!1;maxQueueSize=10;static getInstance(){return g.instance||(g.instance=new g),g.instance}async processQueue(){if(!this.isNavigating&&0!==this.navigationQueue.length){for(this.isNavigating=!0;this.navigationQueue.length>0;){const e=this.navigationQueue.shift();if(e)try{await e(),await new Promise(e=>setTimeout(e,100))}catch(e){}}this.isNavigating=!1}}addToQueue(e){this.navigationQueue.length>=this.maxQueueSize&&this.navigationQueue.shift(),this.navigationQueue.push(e),this.processQueue()}async navigateTo(e){const t=r.getInstance();return t.start("navigateTo","navigation",{url:e.url}),new Promise(s=>{this.addToQueue(async()=>{const a=await n(()=>new Promise(n=>{let s=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");s+=(s.includes("?")?"&":"?")+t}uni.navigateTo({url:s,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>{t.end("navigateTo"),n(!0)},fail:e=>{t.end("navigateTo"),n(!1)}})}),"navigation","NAVIGATE_TO_ERROR");s(a??!1)})})}async redirectTo(e){const t=r.getInstance();return t.start("redirectTo","navigation",{url:e.url}),new Promise(s=>{this.addToQueue(async()=>{const a=await n(()=>new Promise(n=>{let s=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");s+=(s.includes("?")?"&":"?")+t}uni.redirectTo({url:s,success:()=>{t.end("redirectTo"),n(!0)},fail:e=>{t.end("redirectTo"),n(!1)}})}),"navigation","REDIRECT_TO_ERROR");s(a??!1)})})}async navigateBack(e="",t={}){const s=r.getInstance();s.start("navigateBack","navigation");const a={delta:1,timeout:5e3,enableDebounce:!0,debounceWait:300,...t};return new Promise(t=>{this.addToQueue(async()=>{const r=await n(()=>new Promise(t=>{if(getCurrentPages().length<=a.delta)return void t(!1);const n=setTimeout(()=>{t(!1)},a.timeout);uni.navigateBack({delta:a.delta,success:()=>{clearTimeout(n),setTimeout(()=>{try{const n=getCurrentPages();if(n.length>0){const t=n[n.length-1];t.$vm&&"function"==typeof t.$vm.init?t.$vm.init(e):t.route}s.end("navigateBack"),t(!0)}catch(e){s.end("navigateBack"),t(!0)}},100)},fail:e=>{clearTimeout(n),s.end("navigateBack"),t(!1)}})}),"navigation","NAVIGATE_BACK_ERROR");t(r??!1)})})}async switchTab(e){const t=r.getInstance();return t.start("switchTab","navigation",{url:e}),new Promise(s=>{this.addToQueue(async()=>{const a=await n(()=>new Promise(n=>{uni.switchTab({url:e,success:()=>{t.end("switchTab"),n(!0)},fail:e=>{t.end("switchTab"),n(!1)}})}),"navigation","SWITCH_TAB_ERROR");s(a??!1)})})}async reLaunch(e){const t=r.getInstance();return t.start("reLaunch","navigation",{url:e.url}),new Promise(s=>{this.addToQueue(async()=>{const a=await n(()=>new Promise(n=>{let s=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");s+=(s.includes("?")?"&":"?")+t}uni.reLaunch({url:s,success:()=>{t.end("reLaunch"),n(!0)},fail:e=>{t.end("reLaunch"),n(!1)}})}),"navigation","RELAUNCH_ERROR");s(a??!1)})})}getCurrentPageInfo(){return s(()=>{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}},"navigation","GET_CURRENT_PAGE_ERROR",null)}getPageStack(){return s(()=>getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}})),"navigation","GET_PAGE_STACK_ERROR",[])??[]}clearQueue(){this.navigationQueue=[],this.isNavigating=!1}}const d=g.getInstance(),m=async(e="",t={})=>await d.navigateBack(e,t),h=p(m,300),f=async e=>await d.navigateTo(e),y={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function w(e,t={}){const a=r.getInstance();a.start("copyText","clipboard",{textLength:e.length});const o={...y,...t};if(!e||"string"!=typeof e)return o.showToast&&c("复制内容不能为空",!1,"error"),a.end("copyText"),!1;if(e.length>1e4)return o.showToast&&c("复制内容过长",!1,"error"),a.end("copyText"),!1;let i=!1;return i=await n(()=>new Promise(t=>{uni.setClipboardData({data:e,success:()=>{o.showToast&&c(o.successMessage),t(!0)},fail:()=>{o.showToast&&c(o.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_NATIVE_ERROR")??!1,i=await async function(e,t){if(navigator.clipboard&&window.isSecureContext){if(await n(async()=>(await Promise.race([navigator.clipboard.writeText(e),new Promise((e,n)=>setTimeout(()=>n(new Error("Clipboard API timeout")),t.timeout))]),!0),"clipboard","CLIPBOARD_API_ERROR"))return t.showToast&&c(t.successMessage),!0}return function(e,t){return s(()=>{const n=document.createElement("textarea");Object.assign(n.style,{position:"fixed",top:"-9999px",left:"-9999px",width:"1px",height:"1px",padding:"0",border:"none",outline:"none",boxShadow:"none",background:"transparent",fontSize:"16px"}),n.value=e,n.setAttribute("readonly",""),n.setAttribute("contenteditable","true"),document.body.appendChild(n),n.focus(),n.select(),n.setSelectionRange(0,e.length);const s=document.execCommand("copy");return document.body.removeChild(n),s?(t.showToast&&c(t.successMessage),!0):(t.showToast&&c(t.failMessage),!1)},"clipboard","FALLBACK_COPY_ERROR",!1)??!1}(e,t)}(e,o),a.end("copyText"),i}class R{static instance;cache=new Map;defaultTTL=3e4;static getInstance(){return R.instance||(R.instance=new R),R.instance}set(e,t,n=this.defaultTTL){this.cache.set(e,{data:t,timestamp:Date.now(),ttl:n})}get(e){const t=this.cache.get(e);return t?Date.now()-t.timestamp>t.ttl?(this.cache.delete(e),null):t.data:null}clear(){this.cache.clear()}}const E=R.getInstance(),T=()=>{let e;return e="weixin",e="web",e="app",e="alipay",e="h5","h5"},S=()=>{try{return uni.getSystemInfoSync().statusBarHeight||0}catch(e){return 0}},x=()=>{try{const e=T();return"weixin"===e||"alipay"===e?uni.getMenuButtonBoundingClientRect():null}catch(e){return null}},v=()=>{try{const e=S(),t=T();if("weixin"===t||"alipay"===t){const t=x();if(t){return t.height+e}}return e+0}catch(e){return S()+0}};class P{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return P.instance||(P.instance=new P),P.instance}compress(e){return e.replace(/(.)\1{2,}/g,(e,t)=>`${t}*${e.length}`)}decompress(e){return e.replace(/(.)\*(\d+)/g,(e,t,n)=>t.repeat(parseInt(n)))}encrypt(e){return btoa(encodeURIComponent(e))}decrypt(e){try{return decodeURIComponent(atob(e))}catch{return e}}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,n={}){const a=r.getInstance();a.start(`setStorage_${e}`,"localStorage");const o=s(()=>{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const s={value:t,timestamp:Date.now(),ttl:n.ttl,compressed:n.compress,encrypted:n.encrypt};let a=JSON.stringify(s);if(n.compress&&(a=this.compress(a)),n.encrypt&&(a=this.encrypt(a)),a.length>1048576)throw new Error("存储数据过大");if(uni.setStorageSync(e,a),this.cache.size>=this.maxCacheSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}return this.cache.set(e,s),!0},"localStorage","SET_STORAGE_ERROR",!1);return a.end(`setStorage_${e}`),o??!1}get(e,t){const n=r.getInstance();n.start(`getStorage_${e}`,"localStorage");const a=s(()=>{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}let n=uni.getStorageSync(e);if(!n)return t;if("string"!=typeof n)return t;let s,a=n;if(a&&a.includes("="))try{const e=this.decrypt(a);e&&(a=e)}catch{}if(a&&a.includes("*"))try{a=this.decompress(a)}catch{}try{const e=JSON.parse(a);s=e&&"object"==typeof e&&"value"in e&&"timestamp"in e?e:{value:e,timestamp:Date.now()}}catch{return a}return this.isExpired(s)?(this.remove(e),t):(this.cache.set(e,s),s.value)},"localStorage","GET_STORAGE_ERROR",t);return n.end(`getStorage_${e}`),a??t}remove(e){return s(()=>!(!e||"string"!=typeof e)&&(uni.removeStorageSync(e),this.cache.delete(e),!0),"localStorage","REMOVE_STORAGE_ERROR",!1)??!1}clear(){return s(()=>(uni.clearStorageSync(),this.cache.clear(),!0),"localStorage","CLEAR_STORAGE_ERROR",!1)??!1}getInfo(){return s(()=>{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}},"localStorage","GET_STORAGE_INFO_ERROR",{keys:[],currentSize:0,limitSize:0})??{keys:[],currentSize:0,limitSize:0}}cleanExpired(){const e=r.getInstance();e.start("cleanExpiredStorage","localStorage");const t=s(()=>{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t},"localStorage","CLEAN_EXPIRED_ERROR",0);return e.end("cleanExpiredStorage"),t??0}}const O=P.getInstance();function _(e,t,n={}){return O.set(e,t,n)}function I(e,t){return O.get(e,t)}const b={name:"file",maxSize:10,allowedTypes:["jpg","jpeg","png","gif","webp"],showToast:!0,timeout:6e4,successMessage:"上传成功",failMessage:"上传失败"},C={type:"image",count:1,sizeType:["original","compressed"],sourceType:["album","camera"],extension:[],maxSize:10,showToast:!0,failMessage:"选择文件失败"};async function A(e={}){const t=r.getInstance();t.start("chooseFile","upload",{count:e.count,type:e.type});const s={...C,...e};let a=s.type;var o;("messagefile"===(o=a)?"function"==typeof uni.chooseMessageFile:"local"===o||"image"===o)||(a="image");const i=await n(()=>new Promise(e=>{const t=t=>{const n=t.errMsg||s.failMessage;s.showToast&&c(n,!1,"error"),e({success:!1,message:n,type:a})};"image"!==a&&"local"!==a?"messagefile"===a?uni.chooseMessageFile({count:s.count,type:"all",success:t=>{e({success:!0,tempFilePaths:t.tempFiles.map(e=>e.path),tempFiles:t.tempFiles,type:"messagefile"})},fail:t}):"image"===a?uni.chooseImage({count:s.count,sizeType:s.sizeType,sourceType:s.sourceType,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],s=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:s,type:"image"})},fail:t}):"local"===a&&("function"==typeof uni.chooseFile?uni.chooseFile({count:s.count,extension:s.extension,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],s=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:s,type:"local"})},fail:t}):e({success:!1,message:"当前平台不支持选择本地文件",type:a})):function(e,t){const n=document.createElement("input");n.type="file",n.multiple=e.count>1,"image"===e.type?n.accept="image/*":e.extension.length>0&&(n.accept=e.extension.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),n.onchange=s=>{const a=s.target.files;if(a&&a.length>0){const n=Array.from(a).map(e=>({path:URL.createObjectURL(e),size:e.size,name:e.name,type:e.type,file:e})),s=n.map(e=>({path:e.path,size:e.size}));t({success:!0,tempFilePaths:n.map(e=>e.path),tempFiles:s,type:e.type})}else t({success:!1,message:"用户取消选择",type:e.type});document.body.removeChild(n)},n.style.display="none",document.body.appendChild(n),n.click()}(s,e)}).then(e=>{if(!e.success||!e.tempFiles||!s.maxSize)return e;if(e.tempFiles.filter(e=>{var t,n;return!(t=e.size,(n=s.maxSize)&&t>1024*n*1024?{valid:!1,message:`文件大小不能超过 ${n}MB`}:{valid:!0}).valid}).length>0){const t=`部分文件大小超过 ${s.maxSize}MB 限制`;return s.showToast&&c(t,!1,"error"),{...e,success:!1,message:t}}return e}),"upload","CHOOSE_FILE_ERROR");return t.end("chooseFile"),i||{success:!1,message:"选择文件失败",type:a}}async function F(e,t,s){const a=r.getInstance();a.start("uploadFile","upload",{filePath:e});const o={...b,...t};if(!o.url){const e="上传地址不能为空";return o.showToast&&c(e,!1,"error"),a.end("uploadFile"),{success:!1,message:e}}const i=function(e,t){if(!e)return{valid:!1,message:"文件路径不能为空"};if(t.allowedTypes&&t.allowedTypes.length>0){const n=e.split(".").pop()?.toLowerCase();if(!n||!t.allowedTypes.includes(n))return{valid:!1,message:`不支持的文件类型,仅支持:${t.allowedTypes.join(", ")}`}}return{valid:!0}}(e,o);if(!i.valid)return o.showToast&&c(i.message,!1,"error"),a.end("uploadFile"),{success:!1,message:i.message};const u=await n(()=>new Promise(t=>{const n=uni.uploadFile({url:o.url,filePath:e,name:o.name,formData:o.formData,header:o.header,timeout:o.timeout,success:n=>{let s;try{s=JSON.parse(n.data)}catch{s=n.data}if(200===n.statusCode)o.showToast&&c(o.successMessage,!1,"success"),t({success:!0,data:s,tempFilePath:e,statusCode:n.statusCode});else{const e=`上传失败,状态码:${n.statusCode}`;o.showToast&&c(e,!1,"error"),t({success:!1,message:e,statusCode:n.statusCode})}},fail:n=>{const s=n.errMsg||o.failMessage;o.showToast&&c(s,!1,"error"),t({success:!1,message:s,tempFilePath:e})}});s&&n&&n.onProgressUpdate(e=>{s({progress:e.progress,totalBytesSent:e.totalBytesSent,totalBytesExpectedToSend:e.totalBytesExpectedToSend})})}),"upload","UPLOAD_FILE_ERROR");return a.end("uploadFile"),u||{success:!1,message:"上传文件失败"}}async function M(e,t={},n){const s=r.getInstance();s.start("chooseAndUploadFile","upload");const a=await A(t);if(!a.success||!a.tempFilePaths)return s.end("chooseAndUploadFile"),[{success:!1,message:a.message||"选择文件失败"}];const o=a.tempFilePaths.map(t=>F(t,e,n)),i=await Promise.all(o);return s.end("chooseAndUploadFile"),i}exports.ErrorHandler=t,exports.PerformanceMonitor=r,exports.UniAppToolsError=e,exports.VERSION="1.0.8",exports.batchGetStorage=function(e){const t=r.getInstance();t.start("batchGetStorage","localStorage");const n={};return e.forEach(e=>{n[e]=I(e)}),t.end("batchGetStorage"),n},exports.batchSetStorage=function(e,t={}){const n=r.getInstance();n.start("batchSetStorage","localStorage");let s=0;return Object.entries(e).forEach(([e,n])=>{_(e,n,t)&&s++}),n.end("batchSetStorage"),s},exports.chooseAndUploadFile=M,exports.chooseAndUploadImage=async function(e,t={},n){return M(e,{...t,type:"image"},n)},exports.chooseFile=A,exports.chooseImage=async function(e={}){const t=await A({...e,type:"image"});return{success:t.success,tempFilePaths:t.tempFilePaths,tempFiles:t.tempFiles,message:t.message}},exports.cleanExpiredStorage=function(){return O.cleanExpired()},exports.clearClipboard=async function(e={}){return await w("",e)},exports.clearNavigationQueue=()=>{d.clearQueue()},exports.clearStorageSync=function(e){return e?O.remove(e):O.clear()},exports.copyText=w,exports.debounce=p,exports.deepClone=u,exports.deepMerge=function(e,t){const n=r.getInstance();n.start("deepMerge","utils");const a=s(()=>{const n=u(e);return function e(t,n){for(const s in n)if(n.hasOwnProperty(s)){const a=n[s],r=t[s];a&&"object"==typeof a&&!Array.isArray(a)&&r&&"object"==typeof r&&!Array.isArray(r)?e(r,a):t[s]=u(a)}}(n,t),n},"utils","DEEP_MERGE_ERROR",e);return n.end("deepMerge"),a},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{appId:"",version:"",envVersion:"",accountInfo:null}}},exports.getCurrentPageInfo=()=>d.getCurrentPageInfo(),exports.getFileInfo=async function(e){return await n(()=>new Promise((t,n)=>{uni.getFileInfo({filePath:e,digestAlgorithm:"md5",success:e=>{const n=e;t({size:n.size,digest:n.digest})},fail:n})}),"upload","GET_FILE_INFO_ERROR")},exports.getH5UrlParams=e=>{const t=r.getInstance();t.start("getH5UrlParams","utils");const n=s(()=>{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}}),e?n.hasOwnProperty(e)?n[e]:null:n},"utils","GET_H5_URL_PARAMS_ERROR",e?null:{});return t.end("getH5UrlParams"),n},exports.getMenuButtonBoundingClientRect=x,exports.getNavHeight=v,exports.getPageStack=()=>d.getPageStack(),exports.getPlatform=T,exports.getStatusBarHeight=S,exports.getStorage=async function(e,t){return await n(()=>new Promise(n=>{n(I(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t},exports.getStorageInfo=function(){return O.getInfo()},exports.getStorageSync=I,exports.getTopNavBarHeight=()=>{try{const e=S();return{statusBarHeight:e,navHeight:v()}}catch(e){return{statusBarHeight:0,navHeight:44}}},exports.initUniAppTools=async function(e={}){const{enablePerformanceMonitor:t=!1,enableErrorHandler:n=!0,logLevel:s="warn"}=e;if(n){const{ErrorHandler:e}=await Promise.resolve().then(function(){return a}),n=e.getInstance();t&&n.onError(e=>{})}if(t){const{PerformanceMonitor:e}=await Promise.resolve().then(function(){return i}),t=e.getInstance();setInterval(()=>{t.getReport().slowest.length},6e4)}},exports.isClipboardSupported=function(){return!(!navigator.clipboard||!window.isSecureContext)},exports.isUploadSupported=function(){return"undefined"!=typeof uni&&"function"==typeof uni.chooseImage&&"function"==typeof uni.uploadFile},exports.isWechat=()=>{const e=r.getInstance();e.start("isWechat","system");const t=s(()=>{if("undefined"!=typeof navigator&&navigator.userAgent){return navigator.userAgent.toLowerCase().includes("micromessenger")}return!1},"system","IS_WECHAT_ERROR",!1);return e.end("isWechat"),t||!1},exports.measurePerformance=o,exports.mergeObjects=l,exports.navigateTo=f,exports.onCheckForUpdate=()=>{try{const e=uni.getUpdateManager();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){uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){}},exports.reLaunch=async e=>await d.reLaunch(e),exports.readClipboard=async function(e={}){const t=r.getInstance();t.start("readClipboard","clipboard");const s={...y,...e};if(navigator.clipboard&&window.isSecureContext){const e=await n(async()=>await Promise.race([navigator.clipboard.readText(),new Promise((e,t)=>setTimeout(()=>t(new Error("Read clipboard timeout")),s.timeout))]),"clipboard","READ_CLIPBOARD_ERROR");return t.end("readClipboard"),e}return s.showToast&&c("当前平台不支持读取剪贴板",!1,"error"),t.end("readClipboard"),null},exports.redirectTo=async e=>await d.redirectTo(e),exports.safeAsync=n,exports.safeNavigateTo=async(e,t=3)=>{for(let n=0;n<t;n++){if(await f(e))return!0;n<t-1&&await new Promise(e=>setTimeout(e,1e3*(n+1)))}return!1},exports.safeSync=s,exports.setPageIcon=(e,t="image/x-icon")=>s(()=>{const n=T();if(("h5"===n||"web"===n)&&"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}return!1},"system","SET_PAGE_ICON_ERROR",!1),exports.setPageTitle=e=>s(()=>{const t=T();return("h5"===t||"web"===t)&&"undefined"!=typeof document&&(document.title=e,!0)},"system","SET_PAGE_TITLE_ERROR",!1),exports.setStorage=async function(e,t,s={}){return await n(()=>new Promise(n=>{n(_(e,t,s))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1},exports.setStorageSync=_,exports.switchTab=async e=>await d.switchTab(e),exports.throttle=function(e,t,n={}){let s,a=null,r=0;const{leading:o=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();r||o||(r=c);const u=t-(c-r);return u<=0||u>t?(a&&(clearTimeout(a),a=null),r=c,s=e.apply(this,n)):!a&&i&&(a=setTimeout(()=>{r=o?Date.now():0,a=null,s=e.apply(this,n)},u)),s};return c.cancel=()=>{a&&(clearTimeout(a),a=null),r=0},c},exports.uploadFile=F,exports.useBack=m,exports.useBackDebounced=h,exports.useBackOrHome=async(e="",t={})=>{const n=r.getInstance();n.start("useBackOrHome","navigation");try{const s=getCurrentPages(),a=t.delta||1;if(s.length>a){const s=await d.navigateBack(e,t);return n.end("useBackOrHome"),s}const r=t.homePage||"pages/index/index",o=r.startsWith("/")?r:`/${r}`,i=await d.reLaunch({url:o,params:t.homeParams});return n.end("useBackOrHome"),i}catch(e){return n.end("useBackOrHome"),!1}},exports.useDeepCopyByObj=function(e,t){if("object"==typeof e&&null!==e&&!Array.isArray(e)){return l(e,u(t))}return u(t)},exports.useToast=c,exports.useWindowInfo=(e=!0)=>{const t=r.getInstance();t.start("getWindowInfo","system");const n="windowInfo";if(e){const e=E.get(n);if(e)return t.end("getWindowInfo"),e}const a=s(()=>{const t=uni.getWindowInfo();return e&&E.set(n,t),t},"system","GET_WINDOW_INFO_ERROR",null);return t.end("getWindowInfo"),a},exports.weChatOfficialAccountPayment=(e,t,n)=>{const a=r.getInstance();return a.start("weChatOfficialAccountPayment","payment"),new Promise(r=>{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){a.end("weChatOfficialAccountPayment"),"get_brand_wcpay_request:ok"===e.err_msg?(t?.(e),r(!0)):(n?.(e),r(!1))})}catch(e){a.end("weChatOfficialAccountPayment");const t={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};n?.(t),r(!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)||(a.end("weChatOfficialAccountPayment"),r(!1))})};
1
+ "use strict";class e 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 t{static instance;errorCallbacks=[];static getInstance(){return t.instance||(t.instance=new t),t.instance}onError(e){this.errorCallbacks.push(e)}handleError(t,n){const a={code:t instanceof e?t.code:"UNKNOWN_ERROR",message:t.message,module:t instanceof e?t.module:n,timestamp:t instanceof e?t.timestamp:Date.now(),stack:t.stack};this.errorCallbacks.forEach(e=>{try{e(a)}catch(e){}})}createModuleErrorHandler(t){return(n,a,s)=>{const r=new e(n,a,t);return s&&(r.stack=s.stack),this.handleError(r,t),r}}}async function n(e,n,a="ASYNC_ERROR"){try{return await e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(a,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function a(e,n,a="SYNC_ERROR",s=null){try{return e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(a,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}var s=Object.freeze({__proto__:null,ErrorHandler:t,UniAppToolsError:e,safeAsync:n,safeSync:a});class r{static instance;metrics=new Map;completedMetrics=[];maxStoredMetrics=100;static getInstance(){return r.instance||(r.instance=new r),r.instance}start(e,t,n){const a={name:e,startTime:performance.now(),module:t,metadata:n};this.metrics.set(e,a)}end(e){const t=this.metrics.get(e);return t?(t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.metrics.delete(e),this.completedMetrics.push(t),this.completedMetrics.length>this.maxStoredMetrics&&this.completedMetrics.shift(),t):null}getReport(){const e={},t={};this.completedMetrics.forEach(n=>{e[n.module]||(e[n.module]=[]),e[n.module].push(n);const a=`${n.module}.${n.name}`;t[a]||(t[a]={total:0,count:0}),t[a].total+=n.duration||0,t[a].count+=1});const n={};Object.entries(t).forEach(([e,t])=>{n[e]=t.total/t.count});const a=[...this.completedMetrics].sort((e,t)=>(t.duration||0)-(e.duration||0)).slice(0,10);return{byModule:e,slowest:a,average:n}}clear(){this.metrics.clear(),this.completedMetrics=[]}}function o(e){return function(t,n,a){const s=a.value;a.value=function(...a){const o=r.getInstance(),i=`${t.constructor.name}.${n}`;o.start(i,e,{args:a.length});try{const e=s.apply(this,a);return e instanceof Promise?e.finally(()=>{o.end(i)}):(o.end(i),e)}catch(e){throw o.end(i),e}}}}var i=Object.freeze({__proto__:null,PerformanceMonitor:r,measurePerformance:o});class c{static instance;cache=new Map;defaultTTL=3e4;static getInstance(){return c.instance||(c.instance=new c),c.instance}set(e,t,n=this.defaultTTL){this.cache.set(e,{data:t,timestamp:Date.now(),ttl:n})}get(e){const t=this.cache.get(e);return t?Date.now()-t.timestamp>t.ttl?(this.cache.delete(e),null):t.data:null}clear(){this.cache.clear()}}const u=c.getInstance(),l=()=>{let e="unknown";try{const t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:{};t&&void 0!==t.wx&&"function"==typeof t.wx.getSystemInfo?e="weixin":t&&void 0!==t.my?e="alipay":t&&void 0!==t.plus?e="app":"undefined"!=typeof window&&"undefined"!=typeof document&&(e="h5")}catch(e){}return e},p=()=>{try{return uni.getSystemInfoSync().statusBarHeight||0}catch(e){return 0}},d=()=>{try{const e=l();return"weixin"===e||"alipay"===e?uni.getMenuButtonBoundingClientRect():null}catch(e){return null}},g=()=>{try{const e=p(),t=l();if("weixin"===t||"alipay"===t){const t=d();if(t){return t.height+e}}return e+0}catch(e){return p()+0}};function m(e){return a(()=>{if(null===e||"object"!=typeof e)return e;const t=new WeakMap;return function e(n){if(null===n||"object"!=typeof n)return n;if(t.has(n))return t.get(n);if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(n instanceof Map){const a=new Map;return t.set(n,a),n.forEach((t,n)=>{a.set(e(n),e(t))}),a}if(n instanceof Set){const a=new Set;return t.set(n,a),n.forEach(t=>{a.add(e(t))}),a}if(Array.isArray(n)){const a=new Array(n.length);t.set(n,a);for(let t=0;t<n.length;t++)a[t]=e(n[t]);return a}const a=Object.create(Object.getPrototypeOf(n));t.set(n,a);const s=Object.getOwnPropertyDescriptors(n);for(const t in s){const n=s[t];void 0!==n.value&&(n.value=e(n.value)),Object.defineProperty(a,t,n)}return a}(e)},"utils","DEEP_CLONE_ERROR",e)}function h(e,t){const n=r.getInstance();n.start("mergeObjects","utils");const s=a(()=>Object.assign(e,t),"utils","MERGE_OBJECTS_ERROR",e);return n.end("mergeObjects"),s}function f(e,t,n=!1){let a,s=null;const r=function(...r){const o=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(a=e.apply(this,r))},t),o&&(a=e.apply(this,r)),a};return r.cancel=()=>{s&&(clearTimeout(s),s=null)},r}const w=(e="",t=!1,n="none",a=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:a})};class y{static instance;navigationQueue=[];isNavigating=!1;maxQueueSize=10;static getInstance(){return y.instance||(y.instance=new y),y.instance}async processQueue(){if(!this.isNavigating&&0!==this.navigationQueue.length){for(this.isNavigating=!0;this.navigationQueue.length>0;){const e=this.navigationQueue.shift();if(e)try{await e(),await new Promise(e=>setTimeout(e,100))}catch(e){}}this.isNavigating=!1}}addToQueue(e){this.navigationQueue.length>=this.maxQueueSize&&this.navigationQueue.shift(),this.navigationQueue.push(e),this.processQueue()}async navigateTo(e){const t=r.getInstance();return t.start("navigateTo","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.navigateTo({url:a,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>{t.end("navigateTo"),n(!0)},fail:e=>{t.end("navigateTo"),n(!1)}})}),"navigation","NAVIGATE_TO_ERROR");a(s??!1)})})}async redirectTo(e){const t=r.getInstance();return t.start("redirectTo","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.redirectTo({url:a,success:()=>{t.end("redirectTo"),n(!0)},fail:e=>{t.end("redirectTo"),n(!1)}})}),"navigation","REDIRECT_TO_ERROR");a(s??!1)})})}async navigateBack(e="",t={}){const a=r.getInstance();a.start("navigateBack","navigation");const s={delta:1,timeout:5e3,enableDebounce:!0,debounceWait:300,...t};return new Promise(t=>{this.addToQueue(async()=>{const r=await n(()=>new Promise(t=>{if(getCurrentPages().length<=s.delta)return void t(!1);const n=setTimeout(()=>{t(!1)},s.timeout);uni.navigateBack({delta:s.delta,success:()=>{clearTimeout(n),setTimeout(()=>{try{const n=getCurrentPages();if(n.length>0){const t=n[n.length-1];t.$vm&&"function"==typeof t.$vm.init?t.$vm.init(e):t.route}a.end("navigateBack"),t(!0)}catch(e){a.end("navigateBack"),t(!0)}},100)},fail:e=>{clearTimeout(n),a.end("navigateBack"),t(!1)}})}),"navigation","NAVIGATE_BACK_ERROR");t(r??!1)})})}async switchTab(e){const t=r.getInstance();return t.start("switchTab","navigation",{url:e}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{uni.switchTab({url:e,success:()=>{t.end("switchTab"),n(!0)},fail:e=>{t.end("switchTab"),n(!1)}})}),"navigation","SWITCH_TAB_ERROR");a(s??!1)})})}async reLaunch(e){const t=r.getInstance();return t.start("reLaunch","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.reLaunch({url:a,success:()=>{t.end("reLaunch"),n(!0)},fail:e=>{t.end("reLaunch"),n(!1)}})}),"navigation","RELAUNCH_ERROR");a(s??!1)})})}getCurrentPageInfo(){return a(()=>{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}},"navigation","GET_CURRENT_PAGE_ERROR",null)}getPageStack(){return a(()=>getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}})),"navigation","GET_PAGE_STACK_ERROR",[])??[]}clearQueue(){this.navigationQueue=[],this.isNavigating=!1}}const R=y.getInstance(),x=async(e="",t={})=>await R.navigateBack(e,t),S=f(x,300),E=async e=>await R.navigateTo(e),T={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function v(e,t={}){const s=r.getInstance();s.start("copyText","clipboard",{textLength:e.length});const o={...T,...t};if(!e||"string"!=typeof e)return o.showToast&&w("复制内容不能为空",!1,"error"),s.end("copyText"),!1;if(e.length>1e4)return o.showToast&&w("复制内容过长",!1,"error"),s.end("copyText"),!1;let i=!1;return i=await n(()=>new Promise(t=>{"undefined"==typeof uni||!uni||"function"!=typeof uni.setClipboardData?t(!1):uni.setClipboardData({data:e,success:()=>{o.showToast&&w(o.successMessage),t(!0)},fail:()=>{o.showToast&&w(o.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_NATIVE_ERROR")??!1,i=await async function(e,t){const s="undefined"!=typeof navigator&&!!navigator,r="undefined"!=typeof window&&!!window,o=s&&navigator.clipboard,i=r&&window.isSecureContext;if(o&&i){if(await n(async()=>(await Promise.race([navigator.clipboard.writeText(e),new Promise((e,n)=>setTimeout(()=>n(new Error("Clipboard API timeout")),t.timeout))]),!0),"clipboard","CLIPBOARD_API_ERROR"))return t.showToast&&w(t.successMessage),!0}return function(e,t){return a(()=>{if("undefined"==typeof document||"undefined"==typeof window)return t.showToast&&w(t.failMessage),!1;const n=document.createElement("textarea");Object.assign(n.style,{position:"fixed",top:"-9999px",left:"-9999px",width:"1px",height:"1px",padding:"0",border:"none",outline:"none",boxShadow:"none",background:"transparent",fontSize:"16px"}),n.value=e,n.setAttribute("readonly",""),n.setAttribute("contenteditable","true"),document.body.appendChild(n),n.focus(),n.select(),n.setSelectionRange(0,e.length);const a=document.execCommand("copy");return document.body.removeChild(n),a?(t.showToast&&w(t.successMessage),!0):(t.showToast&&w(t.failMessage),!1)},"clipboard","FALLBACK_COPY_ERROR",!1)??!1}(e,t)}(e,o),s.end("copyText"),i}class P{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return P.instance||(P.instance=new P),P.instance}compress(e){return e.replace(/(.)\1{2,}/g,(e,t)=>`${t}*${e.length}`)}decompress(e){return e.replace(/(.)\*(\d+)/g,(e,t,n)=>t.repeat(parseInt(n)))}encrypt(e){return btoa(encodeURIComponent(e))}decrypt(e){try{return decodeURIComponent(atob(e))}catch{return e}}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,n={}){const s=r.getInstance();s.start(`setStorage_${e}`,"localStorage");const o=a(()=>{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const a={value:t,timestamp:Date.now(),ttl:n.ttl,compressed:n.compress,encrypted:n.encrypt};let s=JSON.stringify(a);if(n.compress&&(s=this.compress(s)),n.encrypt&&(s=this.encrypt(s)),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,a),!0},"localStorage","SET_STORAGE_ERROR",!1);return s.end(`setStorage_${e}`),o??!1}get(e,t){const n=r.getInstance();n.start(`getStorage_${e}`,"localStorage");const s=a(()=>{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}let n=uni.getStorageSync(e);if(!n)return t;if("string"!=typeof n)return t;let a,s=n;if(s&&s.includes("="))try{const e=this.decrypt(s);e&&(s=e)}catch{}if(s&&s.includes("*"))try{s=this.decompress(s)}catch{}try{const e=JSON.parse(s);a=e&&"object"==typeof e&&"value"in e&&"timestamp"in e?e:{value:e,timestamp:Date.now()}}catch{return s}return this.isExpired(a)?(this.remove(e),t):(this.cache.set(e,a),a.value)},"localStorage","GET_STORAGE_ERROR",t);return n.end(`getStorage_${e}`),s??t}remove(e){return a(()=>!(!e||"string"!=typeof e)&&(uni.removeStorageSync(e),this.cache.delete(e),!0),"localStorage","REMOVE_STORAGE_ERROR",!1)??!1}clear(){return a(()=>(uni.clearStorageSync(),this.cache.clear(),!0),"localStorage","CLEAR_STORAGE_ERROR",!1)??!1}getInfo(){return a(()=>{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}},"localStorage","GET_STORAGE_INFO_ERROR",{keys:[],currentSize:0,limitSize:0})??{keys:[],currentSize:0,limitSize:0}}cleanExpired(){const e=r.getInstance();e.start("cleanExpiredStorage","localStorage");const t=a(()=>{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t},"localStorage","CLEAN_EXPIRED_ERROR",0);return e.end("cleanExpiredStorage"),t??0}}const I=P.getInstance();function O(e,t,n={}){return I.set(e,t,n)}function _(e,t){return I.get(e,t)}const C={name:"file",maxSize:10,allowedTypes:["jpg","jpeg","png","gif","webp"],showToast:!0,timeout:6e4,successMessage:"上传成功",failMessage:"上传失败"},b={type:"image",count:1,sizeType:["original","compressed"],sourceType:["album","camera"],extension:[],maxSize:10,showToast:!0,failMessage:"选择文件失败",onPartialInvalid:"fail"};function A(e,t,n){if(!e)return{valid:!1,message:"文件路径不能为空"};if(t.allowedTypes&&t.allowedTypes.length>0){const a=e.split(".").pop()?.toLowerCase(),s=t.allowedTypes.map(e=>e.toLowerCase()),r=!!n&&s.some(e=>!!e.includes("/")&&(e.endsWith("/*")?n.startsWith(e.slice(0,e.indexOf("/"))):n===e)),o=!!a&&s.some(e=>!e.includes("/")&&e.replace(/^\./,"")===a);if(!r&&!o)return{valid:!1,message:`不支持的文件类型,仅支持:${t.allowedTypes.join(", ")}`}}return{valid:!0}}async function F(e={}){const t=r.getInstance();t.start("chooseFile","upload",{count:e.count,type:e.type});const a={...b,...e};let s=a.type;var o;("messagefile"===(o=s)?"function"==typeof uni.chooseMessageFile:"local"===o||"image"===o)||(s="image");const i=await n(()=>new Promise(e=>{const t=t=>{const n=t.errMsg||a.failMessage;a.showToast&&w(n,!1,"error"),e({success:!1,message:n,type:s})};"image"!==s&&"local"!==s?"messagefile"===s?uni.chooseMessageFile({count:a.count,type:"all",success:t=>{e({success:!0,tempFilePaths:t.tempFiles.map(e=>e.path),tempFiles:t.tempFiles,type:"messagefile"})},fail:t}):"image"===s?uni.chooseImage({count:a.count,sizeType:a.sizeType,sourceType:a.sourceType,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],a=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:a,type:"image"})},fail:t}):"local"===s&&("function"==typeof uni.chooseFile?uni.chooseFile({count:a.count,extension:a.extension,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],a=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:a,type:"local"})},fail:t}):e({success:!1,message:"当前平台不支持选择本地文件",type:s})):function(e,t){const n=document.createElement("input");n.type="file",n.multiple=e.count>1,"image"===e.type?n.accept="image/*":e.extension.length>0&&(n.accept=e.extension.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),n.onchange=a=>{const s=a.target.files;if(s&&s.length>0){const n=Array.from(s).map(e=>({path:URL.createObjectURL(e),size:e.size,name:e.name,type:e.type,file:e})),a=n.map(e=>({path:e.path,size:e.size,name:e.name,type:e.type}));t({success:!0,tempFilePaths:n.map(e=>e.path),tempFiles:a,type:e.type})}else t({success:!1,message:"用户取消选择",type:e.type});document.body.removeChild(n)},n.style.display="none",document.body.appendChild(n),n.click()}(a,e)}).then(e=>{if(!e.success||!e.tempFiles)return e;const t=a.maxSize?e.tempFiles.filter(e=>{return!(t=e.size,n=a.maxSize,n&&t>1024*n*1024?{valid:!1,message:`文件大小不能超过 ${n}MB`}:{valid:!0}).valid;var t,n}):[],n="image"===a.type||a.extension.length>0,s=n?e.tempFiles.filter(e=>{const t={url:"",allowedTypes:"image"===a.type&&0===a.extension.length?["image/*"]:a.extension};return!A(e.path,t,e.type).valid}):[],r=new Set;t.forEach(e=>r.add(e.path)),s.forEach(e=>r.add(e.path));const o=Array.from(r);if(0===o.length)return e;const i=`部分文件不合规:${[a.maxSize?`大小超过 ${a.maxSize}MB`:"",n?"类型不符合要求":""].filter(Boolean).join(",")}`;if("filter"===a.onPartialInvalid){const t=e.tempFiles.filter(e=>!r.has(e.path));return{...e,tempFiles:t,tempFilePaths:t.map(e=>e.path),invalidFiles:o,message:i,success:t.length>0}}return a.showToast&&w(i,!1,"error"),{...e,success:"allow"===a.onPartialInvalid,invalidFiles:o,message:i}}),"upload","CHOOSE_FILE_ERROR");return t.end("chooseFile"),i||{success:!1,message:"选择文件失败",type:s}}async function M(e,t,a){const s=r.getInstance();s.start("uploadFile","upload",{filePath:e});const o={...C,...t};if(!o.url){const e="上传地址不能为空";return o.showToast&&w(e,!1,"error"),s.end("uploadFile"),{success:!1,message:e}}const i=A(e,o);if(!i.valid)return o.showToast&&w(i.message,!1,"error"),s.end("uploadFile"),{success:!1,message:i.message};const c=await n(()=>new Promise(t=>{const n=uni.uploadFile({url:o.url,filePath:e,name:o.name,formData:o.formData,header:o.header,timeout:o.timeout,success:n=>{let a;try{a=JSON.parse(n.data)}catch{a=n.data}if(200===n.statusCode)o.showToast&&w(o.successMessage,!1,"success"),t({success:!0,data:a,tempFilePath:e,statusCode:n.statusCode,originalResult:n});else{const e=`上传失败,状态码:${n.statusCode}`;o.showToast&&w(e,!1,"error"),t({success:!1,message:e,statusCode:n.statusCode,originalResult:n})}},fail:n=>{const a=n.errMsg||o.failMessage;o.showToast&&w(a,!1,"error"),t({success:!1,message:a,tempFilePath:e,originalResult:n})}});a&&n&&n.onProgressUpdate(e=>{a({progress:e.progress,totalBytesSent:e.totalBytesSent,totalBytesExpectedToSend:e.totalBytesExpectedToSend})})}),"upload","UPLOAD_FILE_ERROR");return s.end("uploadFile"),c||{success:!1,message:"上传文件失败"}}async function k(e,t={},n){const a=r.getInstance();a.start("chooseAndUploadFile","upload");const s=await F(t);if(!s.success||!s.tempFilePaths)return a.end("chooseAndUploadFile"),[{success:!1,message:s.message||"选择文件失败"}];const o=s.tempFilePaths.map(t=>M(t,e,n)),i=await Promise.all(o);return a.end("chooseAndUploadFile"),i}const B=()=>{const e=r.getInstance();e.start("isWechat","system");const t=a(()=>{if("undefined"!=typeof navigator&&navigator.userAgent){return navigator.userAgent.toLowerCase().includes("micromessenger")}return!1},"system","IS_WECHAT_ERROR",!1);return e.end("isWechat"),t||!1},j=()=>new Promise(e=>{if("undefined"!=typeof window&&window.wx)return void e(!0);const t=["https://res.wx.qq.com/open/js/jweixin-1.6.0.js","https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"];let n=0;const a=s=>{const r=document.createElement("script");r.src=s,r.async=!0,r.onload=()=>{e(!0)},r.onerror=()=>{n++,n<t.length?(document.head.removeChild(r),a(t[n])):(document.head.removeChild(r),e(!1))},document.head.appendChild(r)};a(t[n]),e(!1)}),D=async e=>{const t=r.getInstance();t.start("configWechatJSSDK","wechat");try{if(!B())return!1;return!!await j()&&new Promise(t=>{window.wx?(window.wx.config({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),window.wx.ready(()=>{t(!0)}),window.wx.error(e=>{t(!1)})):t(!1),t(!1)})}catch(e){return!1}finally{t.end("configWechatJSSDK")}},U=e=>{a(()=>{window.wx&&B()&&(window.wx.updateTimelineShareData?window.wx.updateTimelineShareData(e):window.wx.onMenuShareTimeline&&window.wx.onMenuShareTimeline(e))},"wechat","SHARE_TIMELINE_ERROR")},L=e=>{a(()=>{window.wx&&B()&&(window.wx.updateAppMessageShareData?window.wx.updateAppMessageShareData(e):window.wx.onMenuShareAppMessage&&window.wx.onMenuShareAppMessage(e))},"wechat","SHARE_FRIEND_ERROR")};class z{static instance;isConfigured=!1;config=null;constructor(){}static getInstance(){return z.instance||(z.instance=new z),z.instance}async init(e){return this.config=e,this.isConfigured=await D(e),this.isConfigured}isReady(){return this.isConfigured&&B()}getConfig(){return this.config}setShareData(e){this.isReady()&&(U(e),L(e))}}exports.ErrorHandler=t,exports.PerformanceMonitor=r,exports.UniAppToolsError=e,exports.VERSION="1.0.8",exports.WechatSDK=z,exports.batchGetStorage=function(e){const t=r.getInstance();t.start("batchGetStorage","localStorage");const n={};return e.forEach(e=>{n[e]=_(e)}),t.end("batchGetStorage"),n},exports.batchSetStorage=function(e,t={}){const n=r.getInstance();n.start("batchSetStorage","localStorage");let a=0;return Object.entries(e).forEach(([e,n])=>{O(e,n,t)&&a++}),n.end("batchSetStorage"),a},exports.checkWechatJSAPI=e=>new Promise(t=>{window.wx&&B()?window.wx.checkJsApi({jsApiList:e,success:e=>{t(e.checkResult||{})}}):t({}),t({})}),exports.chooseAndUploadFile=k,exports.chooseAndUploadImage=async function(e,t={},n){return k(e,{...t,type:"image"},n)},exports.chooseFile=F,exports.chooseImage=async function(e={}){const t=await F({...e,type:"image"});return{success:t.success,tempFilePaths:t.tempFilePaths,tempFiles:t.tempFiles,message:t.message}},exports.cleanExpiredStorage=function(){return I.cleanExpired()},exports.clearClipboard=async function(e={}){return await v("",e)},exports.clearNavigationQueue=()=>{R.clearQueue()},exports.clearStorageSync=function(e){return e?I.remove(e):I.clear()},exports.configWechatJSSDK=D,exports.copyText=v,exports.debounce=f,exports.deepClone=m,exports.deepMerge=function(e,t){const n=r.getInstance();n.start("deepMerge","utils");const s=a(()=>{const n=m(e);return function e(t,n){for(const a in n)if(n.hasOwnProperty(a)){const s=n[a],r=t[a];s&&"object"==typeof s&&!Array.isArray(s)&&r&&"object"==typeof r&&!Array.isArray(r)?e(r,s):t[a]=m(s)}}(n,t),n},"utils","DEEP_MERGE_ERROR",e);return n.end("deepMerge"),s},exports.extractUrlParts=function(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,a={};return t.searchParams.forEach((e,t)=>{a[t]=e}),{path:n,params:a}}catch(e){return{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{appId:"",version:"",envVersion:"",accountInfo:null}}},exports.getCurrentPageInfo=()=>R.getCurrentPageInfo(),exports.getFileInfo=async function(e){return await n(()=>new Promise((t,n)=>{uni.getFileInfo({filePath:e,digestAlgorithm:"md5",success:e=>{const n=e;t({size:n.size,digest:n.digest})},fail:n})}),"upload","GET_FILE_INFO_ERROR")},exports.getH5UrlParams=e=>{const t=r.getInstance();t.start("getH5UrlParams","utils");const n=a(()=>{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(a){n[t]=e}}),e?n.hasOwnProperty(e)?n[e]:null:n},"utils","GET_H5_URL_PARAMS_ERROR",e?null:{});return t.end("getH5UrlParams"),n},exports.getMenuButtonBoundingClientRect=d,exports.getNavHeight=g,exports.getPageStack=()=>R.getPageStack(),exports.getPlatform=l,exports.getStatusBarHeight=p,exports.getStorage=async function(e,t){return await n(()=>new Promise(n=>{n(_(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t},exports.getStorageInfo=function(){return I.getInfo()},exports.getStorageSync=_,exports.getTopNavBarHeight=()=>{try{const e=p();return{statusBarHeight:e,navHeight:g()}}catch(e){return{statusBarHeight:0,navHeight:44}}},exports.initUniAppTools=async function(e={}){const{enablePerformanceMonitor:t=!1,enableErrorHandler:n=!0,logLevel:a="warn"}=e;if(n){const{ErrorHandler:e}=await Promise.resolve().then(function(){return s}),n=e.getInstance();t&&n.onError(e=>{})}if(t){const{PerformanceMonitor:e}=await Promise.resolve().then(function(){return i}),t=e.getInstance();setInterval(()=>{t.getReport().slowest.length},6e4)}},exports.isClipboardSupported=function(){const e="undefined"!=typeof navigator&&!!navigator,t="undefined"!=typeof window&&!!window;return!!(e&&t&&navigator.clipboard&&window.isSecureContext)},exports.isUploadSupported=function(){return"undefined"!=typeof uni&&"function"==typeof uni.uploadFile},exports.isWechat=B,exports.loadWechatJSSDK=j,exports.measurePerformance=o,exports.mergeObjects=h,exports.navigateTo=E,exports.onCheckForUpdate=()=>{try{const e=uni.getUpdateManager();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){uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){}},exports.reLaunch=async e=>await R.reLaunch(e),exports.readClipboard=async function(e={}){const t=r.getInstance();t.start("readClipboard","clipboard");const a={...T,...e},s="undefined"!=typeof navigator&&!!navigator,o="undefined"!=typeof window&&!!window;if(s&&o&&navigator.clipboard&&window.isSecureContext){const e=await n(async()=>await Promise.race([navigator.clipboard.readText(),new Promise((e,t)=>setTimeout(()=>t(new Error("Read clipboard timeout")),a.timeout))]),"clipboard","READ_CLIPBOARD_ERROR");return t.end("readClipboard"),e}return a.showToast&&w("当前平台不支持读取剪贴板",!1,"error"),t.end("readClipboard"),null},exports.redirectTo=async e=>await R.redirectTo(e),exports.safeAsync=n,exports.safeNavigateTo=async(e,t=3)=>{for(let n=0;n<t;n++){if(await E(e))return!0;n<t-1&&await new Promise(e=>setTimeout(e,1e3*(n+1)))}return!1},exports.safeSync=a,exports.setPageIcon=(e,t="image/x-icon")=>a(()=>{const n=l();if(("h5"===n||"web"===n)&&"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}return!1},"system","SET_PAGE_ICON_ERROR",!1),exports.setPageTitle=e=>e&&"string"==typeof e?new Promise(t=>{try{uni.setNavigationBarTitle({title:e,success:()=>{t(!0)},fail:e=>{t(!1)}})}catch(e){t(!1)}}):Promise.resolve(!1),exports.setStorage=async function(e,t,a={}){return await n(()=>new Promise(n=>{n(O(e,t,a))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1},exports.setStorageSync=O,exports.shareToFriend=L,exports.shareToTimeline=U,exports.switchTab=async e=>await R.switchTab(e),exports.throttle=function(e,t,n={}){let a,s=null,r=0;const{leading:o=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();r||o||(r=c);const u=t-(c-r);return u<=0||u>t?(s&&(clearTimeout(s),s=null),r=c,a=e.apply(this,n)):!s&&i&&(s=setTimeout(()=>{r=o?Date.now():0,s=null,a=e.apply(this,n)},u)),a};return c.cancel=()=>{s&&(clearTimeout(s),s=null),r=0},c},exports.uploadFile=M,exports.useBack=x,exports.useBackDebounced=S,exports.useBackOrHome=async(e="",t={})=>{const n=r.getInstance();n.start("useBackOrHome","navigation");try{const a=getCurrentPages(),s=t.delta||1;if(a.length>s){const a=await R.navigateBack(e,t);return n.end("useBackOrHome"),a}const r=t.homePage||"pages/index/index",o=r.startsWith("/")?r:`/${r}`,i=await R.reLaunch({url:o,params:t.homeParams});return n.end("useBackOrHome"),i}catch(e){return n.end("useBackOrHome"),!1}},exports.useDeepCopyByObj=function(e,t){if("object"==typeof e&&null!==e&&!Array.isArray(e)){return h(e,m(t))}return m(t)},exports.useToast=w,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=(e=!0)=>{const t=r.getInstance();t.start("getWindowInfo","system");const n="windowInfo";if(e){const e=u.get(n);if(e)return t.end("getWindowInfo"),e}const s=a(()=>{const t=uni.getWindowInfo();return e&&u.set(n,t),t},"system","GET_WINDOW_INFO_ERROR",null);return t.end("getWindowInfo"),s},exports.weChatOfficialAccountPayment=(e,t,n)=>{const s=r.getInstance();return s.start("weChatOfficialAccountPayment","payment"),new Promise(r=>{a(()=>{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 a(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){s.end("weChatOfficialAccountPayment"),"get_brand_wcpay_request:ok"===e.err_msg?(t?.(e),r(!0)):(n?.(e),r(!1))})}catch(e){s.end("weChatOfficialAccountPayment");const t={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};n?.(t),r(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",a,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",a),e.attachEvent("onWeixinJSBridgeReady",a))}else a();return!0},"payment","WECHAT_PAY_ERROR",!1)||(s.end("weChatOfficialAccountPayment"),r(!1))})};
@@ -1 +1 @@
1
- class e 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 t{static instance;errorCallbacks=[];static getInstance(){return t.instance||(t.instance=new t),t.instance}onError(e){this.errorCallbacks.push(e)}handleError(t,n){const a={code:t instanceof e?t.code:"UNKNOWN_ERROR",message:t.message,module:t instanceof e?t.module:n,timestamp:t instanceof e?t.timestamp:Date.now(),stack:t.stack};this.errorCallbacks.forEach(e=>{try{e(a)}catch(e){}})}createModuleErrorHandler(t){return(n,a,s)=>{const r=new e(n,a,t);return s&&(r.stack=s.stack),this.handleError(r,t),r}}}async function n(e,n,a="ASYNC_ERROR"){try{return await e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(a,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function a(e,n,a="SYNC_ERROR",s=null){try{return e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(a,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}var s=Object.freeze({__proto__:null,ErrorHandler:t,UniAppToolsError:e,safeAsync:n,safeSync:a});class r{static instance;metrics=new Map;completedMetrics=[];maxStoredMetrics=100;static getInstance(){return r.instance||(r.instance=new r),r.instance}start(e,t,n){const a={name:e,startTime:performance.now(),module:t,metadata:n};this.metrics.set(e,a)}end(e){const t=this.metrics.get(e);return t?(t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.metrics.delete(e),this.completedMetrics.push(t),this.completedMetrics.length>this.maxStoredMetrics&&this.completedMetrics.shift(),t):null}getReport(){const e={},t={};this.completedMetrics.forEach(n=>{e[n.module]||(e[n.module]=[]),e[n.module].push(n);const a=`${n.module}.${n.name}`;t[a]||(t[a]={total:0,count:0}),t[a].total+=n.duration||0,t[a].count+=1});const n={};Object.entries(t).forEach(([e,t])=>{n[e]=t.total/t.count});const a=[...this.completedMetrics].sort((e,t)=>(t.duration||0)-(e.duration||0)).slice(0,10);return{byModule:e,slowest:a,average:n}}clear(){this.metrics.clear(),this.completedMetrics=[]}}function o(e){return function(t,n,a){const s=a.value;a.value=function(...a){const o=r.getInstance(),i=`${t.constructor.name}.${n}`;o.start(i,e,{args:a.length});try{const e=s.apply(this,a);return e instanceof Promise?e.finally(()=>{o.end(i)}):(o.end(i),e)}catch(e){throw o.end(i),e}}}}var i=Object.freeze({__proto__:null,PerformanceMonitor:r,measurePerformance:o});const c=(e="",t=!1,n="none",a=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:a})};function u(e){return a(()=>{if(null===e||"object"!=typeof e)return e;const t=new WeakMap;return function e(n){if(null===n||"object"!=typeof n)return n;if(t.has(n))return t.get(n);if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(n instanceof Map){const a=new Map;return t.set(n,a),n.forEach((t,n)=>{a.set(e(n),e(t))}),a}if(n instanceof Set){const a=new Set;return t.set(n,a),n.forEach(t=>{a.add(e(t))}),a}if(Array.isArray(n)){const a=new Array(n.length);t.set(n,a);for(let t=0;t<n.length;t++)a[t]=e(n[t]);return a}const a=Object.create(Object.getPrototypeOf(n));t.set(n,a);const s=Object.getOwnPropertyDescriptors(n);for(const t in s){const n=s[t];void 0!==n.value&&(n.value=e(n.value)),Object.defineProperty(a,t,n)}return a}(e)},"utils","DEEP_CLONE_ERROR",e)}function l(e,t){const n=r.getInstance();n.start("mergeObjects","utils");const s=a(()=>Object.assign(e,t),"utils","MERGE_OBJECTS_ERROR",e);return n.end("mergeObjects"),s}function d(e,t){const n=r.getInstance();n.start("deepMerge","utils");const s=a(()=>{const n=u(e);return function e(t,n){for(const a in n)if(n.hasOwnProperty(a)){const s=n[a],r=t[a];s&&"object"==typeof s&&!Array.isArray(s)&&r&&"object"==typeof r&&!Array.isArray(r)?e(r,s):t[a]=u(s)}}(n,t),n},"utils","DEEP_MERGE_ERROR",e);return n.end("deepMerge"),s}function g(e,t,n=!1){let a,s=null;const r=function(...r){const o=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(a=e.apply(this,r))},t),o&&(a=e.apply(this,r)),a};return r.cancel=()=>{s&&(clearTimeout(s),s=null)},r}function m(e,t,n={}){let a,s=null,r=0;const{leading:o=!0,trailing:i=!0}=n,c=function(...n){const c=Date.now();r||o||(r=c);const u=t-(c-r);return u<=0||u>t?(s&&(clearTimeout(s),s=null),r=c,a=e.apply(this,n)):!s&&i&&(s=setTimeout(()=>{r=o?Date.now():0,s=null,a=e.apply(this,n)},u)),a};return c.cancel=()=>{s&&(clearTimeout(s),s=null),r=0},c}function p(e,t){if("object"==typeof e&&null!==e&&!Array.isArray(e)){return l(e,u(t))}return u(t)}const h=e=>{const t=r.getInstance();t.start("getH5UrlParams","utils");const n=a(()=>{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(a){n[t]=e}}),e?n.hasOwnProperty(e)?n[e]:null:n},"utils","GET_H5_URL_PARAMS_ERROR",e?null:{});return t.end("getH5UrlParams"),n};class f{static instance;navigationQueue=[];isNavigating=!1;maxQueueSize=10;static getInstance(){return f.instance||(f.instance=new f),f.instance}async processQueue(){if(!this.isNavigating&&0!==this.navigationQueue.length){for(this.isNavigating=!0;this.navigationQueue.length>0;){const e=this.navigationQueue.shift();if(e)try{await e(),await new Promise(e=>setTimeout(e,100))}catch(e){}}this.isNavigating=!1}}addToQueue(e){this.navigationQueue.length>=this.maxQueueSize&&this.navigationQueue.shift(),this.navigationQueue.push(e),this.processQueue()}async navigateTo(e){const t=r.getInstance();return t.start("navigateTo","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.navigateTo({url:a,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>{t.end("navigateTo"),n(!0)},fail:e=>{t.end("navigateTo"),n(!1)}})}),"navigation","NAVIGATE_TO_ERROR");a(s??!1)})})}async redirectTo(e){const t=r.getInstance();return t.start("redirectTo","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.redirectTo({url:a,success:()=>{t.end("redirectTo"),n(!0)},fail:e=>{t.end("redirectTo"),n(!1)}})}),"navigation","REDIRECT_TO_ERROR");a(s??!1)})})}async navigateBack(e="",t={}){const a=r.getInstance();a.start("navigateBack","navigation");const s={delta:1,timeout:5e3,enableDebounce:!0,debounceWait:300,...t};return new Promise(t=>{this.addToQueue(async()=>{const r=await n(()=>new Promise(t=>{if(getCurrentPages().length<=s.delta)return void t(!1);const n=setTimeout(()=>{t(!1)},s.timeout);uni.navigateBack({delta:s.delta,success:()=>{clearTimeout(n),setTimeout(()=>{try{const n=getCurrentPages();if(n.length>0){const t=n[n.length-1];t.$vm&&"function"==typeof t.$vm.init?t.$vm.init(e):t.route}a.end("navigateBack"),t(!0)}catch(e){a.end("navigateBack"),t(!0)}},100)},fail:e=>{clearTimeout(n),a.end("navigateBack"),t(!1)}})}),"navigation","NAVIGATE_BACK_ERROR");t(r??!1)})})}async switchTab(e){const t=r.getInstance();return t.start("switchTab","navigation",{url:e}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{uni.switchTab({url:e,success:()=>{t.end("switchTab"),n(!0)},fail:e=>{t.end("switchTab"),n(!1)}})}),"navigation","SWITCH_TAB_ERROR");a(s??!1)})})}async reLaunch(e){const t=r.getInstance();return t.start("reLaunch","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.reLaunch({url:a,success:()=>{t.end("reLaunch"),n(!0)},fail:e=>{t.end("reLaunch"),n(!1)}})}),"navigation","RELAUNCH_ERROR");a(s??!1)})})}getCurrentPageInfo(){return a(()=>{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}},"navigation","GET_CURRENT_PAGE_ERROR",null)}getPageStack(){return a(()=>getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}})),"navigation","GET_PAGE_STACK_ERROR",[])??[]}clearQueue(){this.navigationQueue=[],this.isNavigating=!1}}const y=f.getInstance(),w=async(e="",t={})=>await y.navigateBack(e,t),R=async(e="",t={})=>{const n=r.getInstance();n.start("useBackOrHome","navigation");try{const a=getCurrentPages(),s=t.delta||1;if(a.length>s){const a=await y.navigateBack(e,t);return n.end("useBackOrHome"),a}const r=t.homePage||"pages/index/index",o=r.startsWith("/")?r:`/${r}`,i=await y.reLaunch({url:o,params:t.homeParams});return n.end("useBackOrHome"),i}catch(e){return n.end("useBackOrHome"),!1}},E=g(w,300),T=async e=>await y.navigateTo(e),S=async e=>await y.redirectTo(e),v=async e=>await y.switchTab(e),_=async e=>await y.reLaunch(e),P=()=>y.getCurrentPageInfo(),O=()=>y.getPageStack(),I=()=>{y.clearQueue()},b=async(e,t=3)=>{for(let n=0;n<t;n++){if(await T(e))return!0;n<t-1&&await new Promise(e=>setTimeout(e,1e3*(n+1)))}return!1},C={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function A(e,t={}){const s=r.getInstance();s.start("copyText","clipboard",{textLength:e.length});const o={...C,...t};if(!e||"string"!=typeof e)return o.showToast&&c("复制内容不能为空",!1,"error"),s.end("copyText"),!1;if(e.length>1e4)return o.showToast&&c("复制内容过长",!1,"error"),s.end("copyText"),!1;let i=!1;return i=await n(()=>new Promise(t=>{uni.setClipboardData({data:e,success:()=>{o.showToast&&c(o.successMessage),t(!0)},fail:()=>{o.showToast&&c(o.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_NATIVE_ERROR")??!1,i=await async function(e,t){if(navigator.clipboard&&window.isSecureContext){if(await n(async()=>(await Promise.race([navigator.clipboard.writeText(e),new Promise((e,n)=>setTimeout(()=>n(new Error("Clipboard API timeout")),t.timeout))]),!0),"clipboard","CLIPBOARD_API_ERROR"))return t.showToast&&c(t.successMessage),!0}return function(e,t){return a(()=>{const n=document.createElement("textarea");Object.assign(n.style,{position:"fixed",top:"-9999px",left:"-9999px",width:"1px",height:"1px",padding:"0",border:"none",outline:"none",boxShadow:"none",background:"transparent",fontSize:"16px"}),n.value=e,n.setAttribute("readonly",""),n.setAttribute("contenteditable","true"),document.body.appendChild(n),n.focus(),n.select(),n.setSelectionRange(0,e.length);const a=document.execCommand("copy");return document.body.removeChild(n),a?(t.showToast&&c(t.successMessage),!0):(t.showToast&&c(t.failMessage),!1)},"clipboard","FALLBACK_COPY_ERROR",!1)??!1}(e,t)}(e,o),s.end("copyText"),i}async function x(e={}){const t=r.getInstance();t.start("readClipboard","clipboard");const a={...C,...e};if(navigator.clipboard&&window.isSecureContext){const e=await n(async()=>await Promise.race([navigator.clipboard.readText(),new Promise((e,t)=>setTimeout(()=>t(new Error("Read clipboard timeout")),a.timeout))]),"clipboard","READ_CLIPBOARD_ERROR");return t.end("readClipboard"),e}return a.showToast&&c("当前平台不支持读取剪贴板",!1,"error"),t.end("readClipboard"),null}function F(){return!(!navigator.clipboard||!window.isSecureContext)}async function M(e={}){return await A("",e)}class k{static instance;cache=new Map;defaultTTL=3e4;static getInstance(){return k.instance||(k.instance=new k),k.instance}set(e,t,n=this.defaultTTL){this.cache.set(e,{data:t,timestamp:Date.now(),ttl:n})}get(e){const t=this.cache.get(e);return t?Date.now()-t.timestamp>t.ttl?(this.cache.delete(e),null):t.data:null}clear(){this.cache.clear()}}const z=k.getInstance(),B=(e=!0)=>{const t=r.getInstance();t.start("getWindowInfo","system");const n="windowInfo";if(e){const e=z.get(n);if(e)return t.end("getWindowInfo"),e}const s=a(()=>{const t=uni.getWindowInfo();return e&&z.set(n,t),t},"system","GET_WINDOW_INFO_ERROR",null);return t.end("getWindowInfo"),s},j=()=>{let e;return e="weixin",e="web",e="app",e="alipay",e="h5","h5"},L=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return{appId:"",version:"",envVersion:"",accountInfo:null}}},U=()=>{try{const e=uni.getUpdateManager();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){uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){}},D=()=>{try{return uni.getSystemInfoSync().statusBarHeight||0}catch(e){return 0}},N=()=>{try{const e=j();return"weixin"===e||"alipay"===e?uni.getMenuButtonBoundingClientRect():null}catch(e){return null}},$=()=>{try{const e=D(),t=j();if("weixin"===t||"alipay"===t){const t=N();if(t){return t.height+e}}return e+0}catch(e){return D()+0}},G=()=>{try{const e=D();return{statusBarHeight:e,navHeight:$()}}catch(e){return{statusBarHeight:0,navHeight:44}}},H=e=>a(()=>{const t=j();return("h5"===t||"web"===t)&&"undefined"!=typeof document&&(document.title=e,!0)},"system","SET_PAGE_TITLE_ERROR",!1),W=(e,t="image/x-icon")=>a(()=>{const n=j();if(("h5"===n||"web"===n)&&"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}return!1},"system","SET_PAGE_ICON_ERROR",!1),Q=()=>{const e=r.getInstance();e.start("isWechat","system");const t=a(()=>{if("undefined"!=typeof navigator&&navigator.userAgent){return navigator.userAgent.toLowerCase().includes("micromessenger")}return!1},"system","IS_WECHAT_ERROR",!1);return e.end("isWechat"),t||!1};class J{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return J.instance||(J.instance=new J),J.instance}compress(e){return e.replace(/(.)\1{2,}/g,(e,t)=>`${t}*${e.length}`)}decompress(e){return e.replace(/(.)\*(\d+)/g,(e,t,n)=>t.repeat(parseInt(n)))}encrypt(e){return btoa(encodeURIComponent(e))}decrypt(e){try{return decodeURIComponent(atob(e))}catch{return e}}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,n={}){const s=r.getInstance();s.start(`setStorage_${e}`,"localStorage");const o=a(()=>{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const a={value:t,timestamp:Date.now(),ttl:n.ttl,compressed:n.compress,encrypted:n.encrypt};let s=JSON.stringify(a);if(n.compress&&(s=this.compress(s)),n.encrypt&&(s=this.encrypt(s)),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,a),!0},"localStorage","SET_STORAGE_ERROR",!1);return s.end(`setStorage_${e}`),o??!1}get(e,t){const n=r.getInstance();n.start(`getStorage_${e}`,"localStorage");const s=a(()=>{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}let n=uni.getStorageSync(e);if(!n)return t;if("string"!=typeof n)return t;let a,s=n;if(s&&s.includes("="))try{const e=this.decrypt(s);e&&(s=e)}catch{}if(s&&s.includes("*"))try{s=this.decompress(s)}catch{}try{const e=JSON.parse(s);a=e&&"object"==typeof e&&"value"in e&&"timestamp"in e?e:{value:e,timestamp:Date.now()}}catch{return s}return this.isExpired(a)?(this.remove(e),t):(this.cache.set(e,a),a.value)},"localStorage","GET_STORAGE_ERROR",t);return n.end(`getStorage_${e}`),s??t}remove(e){return a(()=>!(!e||"string"!=typeof e)&&(uni.removeStorageSync(e),this.cache.delete(e),!0),"localStorage","REMOVE_STORAGE_ERROR",!1)??!1}clear(){return a(()=>(uni.clearStorageSync(),this.cache.clear(),!0),"localStorage","CLEAR_STORAGE_ERROR",!1)??!1}getInfo(){return a(()=>{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}},"localStorage","GET_STORAGE_INFO_ERROR",{keys:[],currentSize:0,limitSize:0})??{keys:[],currentSize:0,limitSize:0}}cleanExpired(){const e=r.getInstance();e.start("cleanExpiredStorage","localStorage");const t=a(()=>{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t},"localStorage","CLEAN_EXPIRED_ERROR",0);return e.end("cleanExpiredStorage"),t??0}}const V=J.getInstance();function Y(e,t,n={}){return V.set(e,t,n)}function q(e,t){return V.get(e,t)}function K(e){return e?V.remove(e):V.clear()}async function X(e,t,a={}){return await n(()=>new Promise(n=>{n(Y(e,t,a))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1}async function Z(e,t){return await n(()=>new Promise(n=>{n(q(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t}function ee(){return V.getInfo()}function te(){return V.cleanExpired()}function ne(e,t={}){const n=r.getInstance();n.start("batchSetStorage","localStorage");let a=0;return Object.entries(e).forEach(([e,n])=>{Y(e,n,t)&&a++}),n.end("batchSetStorage"),a}function ae(e){const t=r.getInstance();t.start("batchGetStorage","localStorage");const n={};return e.forEach(e=>{n[e]=q(e)}),t.end("batchGetStorage"),n}const se={name:"file",maxSize:10,allowedTypes:["jpg","jpeg","png","gif","webp"],showToast:!0,timeout:6e4,successMessage:"上传成功",failMessage:"上传失败"},re={type:"image",count:1,sizeType:["original","compressed"],sourceType:["album","camera"],extension:[],maxSize:10,showToast:!0,failMessage:"选择文件失败"};async function oe(e={}){const t=r.getInstance();t.start("chooseFile","upload",{count:e.count,type:e.type});const a={...re,...e};let s=a.type;var o;("messagefile"===(o=s)?"function"==typeof uni.chooseMessageFile:"local"===o||"image"===o)||(s="image");const i=await n(()=>new Promise(e=>{const t=t=>{const n=t.errMsg||a.failMessage;a.showToast&&c(n,!1,"error"),e({success:!1,message:n,type:s})};"image"!==s&&"local"!==s?"messagefile"===s?uni.chooseMessageFile({count:a.count,type:"all",success:t=>{e({success:!0,tempFilePaths:t.tempFiles.map(e=>e.path),tempFiles:t.tempFiles,type:"messagefile"})},fail:t}):"image"===s?uni.chooseImage({count:a.count,sizeType:a.sizeType,sourceType:a.sourceType,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],a=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:a,type:"image"})},fail:t}):"local"===s&&("function"==typeof uni.chooseFile?uni.chooseFile({count:a.count,extension:a.extension,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],a=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:a,type:"local"})},fail:t}):e({success:!1,message:"当前平台不支持选择本地文件",type:s})):function(e,t){const n=document.createElement("input");n.type="file",n.multiple=e.count>1,"image"===e.type?n.accept="image/*":e.extension.length>0&&(n.accept=e.extension.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),n.onchange=a=>{const s=a.target.files;if(s&&s.length>0){const n=Array.from(s).map(e=>({path:URL.createObjectURL(e),size:e.size,name:e.name,type:e.type,file:e})),a=n.map(e=>({path:e.path,size:e.size}));t({success:!0,tempFilePaths:n.map(e=>e.path),tempFiles:a,type:e.type})}else t({success:!1,message:"用户取消选择",type:e.type});document.body.removeChild(n)},n.style.display="none",document.body.appendChild(n),n.click()}(a,e)}).then(e=>{if(!e.success||!e.tempFiles||!a.maxSize)return e;if(e.tempFiles.filter(e=>{var t,n;return!(t=e.size,(n=a.maxSize)&&t>1024*n*1024?{valid:!1,message:`文件大小不能超过 ${n}MB`}:{valid:!0}).valid}).length>0){const t=`部分文件大小超过 ${a.maxSize}MB 限制`;return a.showToast&&c(t,!1,"error"),{...e,success:!1,message:t}}return e}),"upload","CHOOSE_FILE_ERROR");return t.end("chooseFile"),i||{success:!1,message:"选择文件失败",type:s}}async function ie(e={}){const t=await oe({...e,type:"image"});return{success:t.success,tempFilePaths:t.tempFilePaths,tempFiles:t.tempFiles,message:t.message}}async function ce(e,t,a){const s=r.getInstance();s.start("uploadFile","upload",{filePath:e});const o={...se,...t};if(!o.url){const e="上传地址不能为空";return o.showToast&&c(e,!1,"error"),s.end("uploadFile"),{success:!1,message:e}}const i=function(e,t){if(!e)return{valid:!1,message:"文件路径不能为空"};if(t.allowedTypes&&t.allowedTypes.length>0){const n=e.split(".").pop()?.toLowerCase();if(!n||!t.allowedTypes.includes(n))return{valid:!1,message:`不支持的文件类型,仅支持:${t.allowedTypes.join(", ")}`}}return{valid:!0}}(e,o);if(!i.valid)return o.showToast&&c(i.message,!1,"error"),s.end("uploadFile"),{success:!1,message:i.message};const u=await n(()=>new Promise(t=>{const n=uni.uploadFile({url:o.url,filePath:e,name:o.name,formData:o.formData,header:o.header,timeout:o.timeout,success:n=>{let a;try{a=JSON.parse(n.data)}catch{a=n.data}if(200===n.statusCode)o.showToast&&c(o.successMessage,!1,"success"),t({success:!0,data:a,tempFilePath:e,statusCode:n.statusCode});else{const e=`上传失败,状态码:${n.statusCode}`;o.showToast&&c(e,!1,"error"),t({success:!1,message:e,statusCode:n.statusCode})}},fail:n=>{const a=n.errMsg||o.failMessage;o.showToast&&c(a,!1,"error"),t({success:!1,message:a,tempFilePath:e})}});a&&n&&n.onProgressUpdate(e=>{a({progress:e.progress,totalBytesSent:e.totalBytesSent,totalBytesExpectedToSend:e.totalBytesExpectedToSend})})}),"upload","UPLOAD_FILE_ERROR");return s.end("uploadFile"),u||{success:!1,message:"上传文件失败"}}async function ue(e,t={},n){const a=r.getInstance();a.start("chooseAndUploadFile","upload");const s=await oe(t);if(!s.success||!s.tempFilePaths)return a.end("chooseAndUploadFile"),[{success:!1,message:s.message||"选择文件失败"}];const o=s.tempFilePaths.map(t=>ce(t,e,n)),i=await Promise.all(o);return a.end("chooseAndUploadFile"),i}async function le(e,t={},n){return ue(e,{...t,type:"image"},n)}function de(){return"undefined"!=typeof uni&&"function"==typeof uni.chooseImage&&"function"==typeof uni.uploadFile}async function ge(e){return await n(()=>new Promise((t,n)=>{uni.getFileInfo({filePath:e,digestAlgorithm:"md5",success:e=>{const n=e;t({size:n.size,digest:n.digest})},fail:n})}),"upload","GET_FILE_INFO_ERROR")}const me=(e,t,n)=>{const s=r.getInstance();return s.start("weChatOfficialAccountPayment","payment"),new Promise(r=>{a(()=>{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 a(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){s.end("weChatOfficialAccountPayment"),"get_brand_wcpay_request:ok"===e.err_msg?(t?.(e),r(!0)):(n?.(e),r(!1))})}catch(e){s.end("weChatOfficialAccountPayment");const t={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};n?.(t),r(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",a,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",a),e.attachEvent("onWeixinJSBridgeReady",a))}else a();return!0},"payment","WECHAT_PAY_ERROR",!1)||(s.end("weChatOfficialAccountPayment"),r(!1))})},pe="1.0.8";async function he(e={}){const{enablePerformanceMonitor:t=!1,enableErrorHandler:n=!0,logLevel:a="warn"}=e;if(n){const{ErrorHandler:e}=await Promise.resolve().then(function(){return s}),n=e.getInstance();t&&n.onError(e=>{})}if(t){const{PerformanceMonitor:e}=await Promise.resolve().then(function(){return i}),t=e.getInstance();setInterval(()=>{t.getReport().slowest.length},6e4)}}export{t as ErrorHandler,r as PerformanceMonitor,e as UniAppToolsError,pe as VERSION,ae as batchGetStorage,ne as batchSetStorage,ue as chooseAndUploadFile,le as chooseAndUploadImage,oe as chooseFile,ie as chooseImage,te as cleanExpiredStorage,M as clearClipboard,I as clearNavigationQueue,K as clearStorageSync,A as copyText,g as debounce,u as deepClone,d as deepMerge,L as getCurrentEnv,P as getCurrentPageInfo,ge as getFileInfo,h as getH5UrlParams,N as getMenuButtonBoundingClientRect,$ as getNavHeight,O as getPageStack,j as getPlatform,D as getStatusBarHeight,Z as getStorage,ee as getStorageInfo,q as getStorageSync,G as getTopNavBarHeight,he as initUniAppTools,F as isClipboardSupported,de as isUploadSupported,Q as isWechat,o as measurePerformance,l as mergeObjects,T as navigateTo,U as onCheckForUpdate,_ as reLaunch,x as readClipboard,S as redirectTo,n as safeAsync,b as safeNavigateTo,a as safeSync,W as setPageIcon,H as setPageTitle,X as setStorage,Y as setStorageSync,v as switchTab,m as throttle,ce as uploadFile,w as useBack,E as useBackDebounced,R as useBackOrHome,p as useDeepCopyByObj,c as useToast,B as useWindowInfo,me as weChatOfficialAccountPayment};
1
+ class e 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 t{static instance;errorCallbacks=[];static getInstance(){return t.instance||(t.instance=new t),t.instance}onError(e){this.errorCallbacks.push(e)}handleError(t,n){const a={code:t instanceof e?t.code:"UNKNOWN_ERROR",message:t.message,module:t instanceof e?t.module:n,timestamp:t instanceof e?t.timestamp:Date.now(),stack:t.stack};this.errorCallbacks.forEach(e=>{try{e(a)}catch(e){}})}createModuleErrorHandler(t){return(n,a,s)=>{const i=new e(n,a,t);return s&&(i.stack=s.stack),this.handleError(i,t),i}}}async function n(e,n,a="ASYNC_ERROR"){try{return await e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(a,`异步操作失败: ${e instanceof Error?e.message:String(e)}`,e),null}}function a(e,n,a="SYNC_ERROR",s=null){try{return e()}catch(e){return t.getInstance().createModuleErrorHandler(n)(a,`同步操作失败: ${e instanceof Error?e.message:String(e)}`,e),s}}var s=Object.freeze({__proto__:null,ErrorHandler:t,UniAppToolsError:e,safeAsync:n,safeSync:a});class i{static instance;metrics=new Map;completedMetrics=[];maxStoredMetrics=100;static getInstance(){return i.instance||(i.instance=new i),i.instance}start(e,t,n){const a={name:e,startTime:performance.now(),module:t,metadata:n};this.metrics.set(e,a)}end(e){const t=this.metrics.get(e);return t?(t.endTime=performance.now(),t.duration=t.endTime-t.startTime,this.metrics.delete(e),this.completedMetrics.push(t),this.completedMetrics.length>this.maxStoredMetrics&&this.completedMetrics.shift(),t):null}getReport(){const e={},t={};this.completedMetrics.forEach(n=>{e[n.module]||(e[n.module]=[]),e[n.module].push(n);const a=`${n.module}.${n.name}`;t[a]||(t[a]={total:0,count:0}),t[a].total+=n.duration||0,t[a].count+=1});const n={};Object.entries(t).forEach(([e,t])=>{n[e]=t.total/t.count});const a=[...this.completedMetrics].sort((e,t)=>(t.duration||0)-(e.duration||0)).slice(0,10);return{byModule:e,slowest:a,average:n}}clear(){this.metrics.clear(),this.completedMetrics=[]}}function r(e){return function(t,n,a){const s=a.value;a.value=function(...a){const r=i.getInstance(),o=`${t.constructor.name}.${n}`;r.start(o,e,{args:a.length});try{const e=s.apply(this,a);return e instanceof Promise?e.finally(()=>{r.end(o)}):(r.end(o),e)}catch(e){throw r.end(o),e}}}}var o=Object.freeze({__proto__:null,PerformanceMonitor:i,measurePerformance:r});class c{static instance;cache=new Map;defaultTTL=3e4;static getInstance(){return c.instance||(c.instance=new c),c.instance}set(e,t,n=this.defaultTTL){this.cache.set(e,{data:t,timestamp:Date.now(),ttl:n})}get(e){const t=this.cache.get(e);return t?Date.now()-t.timestamp>t.ttl?(this.cache.delete(e),null):t.data:null}clear(){this.cache.clear()}}const u=c.getInstance(),l=(e=!0)=>{const t=i.getInstance();t.start("getWindowInfo","system");const n="windowInfo";if(e){const e=u.get(n);if(e)return t.end("getWindowInfo"),e}const s=a(()=>{const t=uni.getWindowInfo();return e&&u.set(n,t),t},"system","GET_WINDOW_INFO_ERROR",null);return t.end("getWindowInfo"),s},d=()=>{let e="unknown";try{const t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:{};t&&void 0!==t.wx&&"function"==typeof t.wx.getSystemInfo?e="weixin":t&&void 0!==t.my?e="alipay":t&&void 0!==t.plus?e="app":"undefined"!=typeof window&&"undefined"!=typeof document&&(e="h5")}catch(e){}return e},p=()=>{try{const e=uni.getAccountInfoSync();return{appId:e.miniProgram?.appId||"",version:e.miniProgram?.version||"",envVersion:e.miniProgram?.envVersion||"",accountInfo:e}}catch(e){return{appId:"",version:"",envVersion:"",accountInfo:null}}},g=()=>{try{const e=uni.getUpdateManager();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){uni.showModal({title:"更新失败",content:"新版本下载失败,请检查网络连接或稍后重试",showCancel:!1,confirmText:"知道了"})})}catch(e){}},m=()=>{try{return uni.getSystemInfoSync().statusBarHeight||0}catch(e){return 0}},h=()=>{try{const e=d();return"weixin"===e||"alipay"===e?uni.getMenuButtonBoundingClientRect():null}catch(e){return null}},f=()=>{try{const e=m(),t=d();if("weixin"===t||"alipay"===t){const t=h();if(t){return t.height+e}}return e+0}catch(e){return m()+0}},w=()=>{try{const e=m();return{statusBarHeight:e,navHeight:f()}}catch(e){return{statusBarHeight:0,navHeight:44}}},y=e=>e&&"string"==typeof e?new Promise(t=>{try{uni.setNavigationBarTitle({title:e,success:()=>{t(!0)},fail:e=>{t(!1)}})}catch(e){t(!1)}}):Promise.resolve(!1),R=(e,t="image/x-icon")=>a(()=>{const n=d();if(("h5"===n||"web"===n)&&"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}return!1},"system","SET_PAGE_ICON_ERROR",!1);function E(e){return a(()=>{if(null===e||"object"!=typeof e)return e;const t=new WeakMap;return function e(n){if(null===n||"object"!=typeof n)return n;if(t.has(n))return t.get(n);if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(n instanceof Map){const a=new Map;return t.set(n,a),n.forEach((t,n)=>{a.set(e(n),e(t))}),a}if(n instanceof Set){const a=new Set;return t.set(n,a),n.forEach(t=>{a.add(e(t))}),a}if(Array.isArray(n)){const a=new Array(n.length);t.set(n,a);for(let t=0;t<n.length;t++)a[t]=e(n[t]);return a}const a=Object.create(Object.getPrototypeOf(n));t.set(n,a);const s=Object.getOwnPropertyDescriptors(n);for(const t in s){const n=s[t];void 0!==n.value&&(n.value=e(n.value)),Object.defineProperty(a,t,n)}return a}(e)},"utils","DEEP_CLONE_ERROR",e)}function T(e,t){const n=i.getInstance();n.start("mergeObjects","utils");const s=a(()=>Object.assign(e,t),"utils","MERGE_OBJECTS_ERROR",e);return n.end("mergeObjects"),s}function S(e,t){const n=i.getInstance();n.start("deepMerge","utils");const s=a(()=>{const n=E(e);return function e(t,n){for(const a in n)if(n.hasOwnProperty(a)){const s=n[a],i=t[a];s&&"object"==typeof s&&!Array.isArray(s)&&i&&"object"==typeof i&&!Array.isArray(i)?e(i,s):t[a]=E(s)}}(n,t),n},"utils","DEEP_MERGE_ERROR",e);return n.end("deepMerge"),s}function v(e,t,n=!1){let a,s=null;const i=function(...i){const r=n&&!s;return s&&clearTimeout(s),s=setTimeout(()=>{s=null,n||(a=e.apply(this,i))},t),r&&(a=e.apply(this,i)),a};return i.cancel=()=>{s&&(clearTimeout(s),s=null)},i}function P(e,t,n={}){let a,s=null,i=0;const{leading:r=!0,trailing:o=!0}=n,c=function(...n){const c=Date.now();i||r||(i=c);const u=t-(c-i);return u<=0||u>t?(s&&(clearTimeout(s),s=null),i=c,a=e.apply(this,n)):!s&&o&&(s=setTimeout(()=>{i=r?Date.now():0,s=null,a=e.apply(this,n)},u)),a};return c.cancel=()=>{s&&(clearTimeout(s),s=null),i=0},c}function _(e,t){if("object"==typeof e&&null!==e&&!Array.isArray(e)){return T(e,E(t))}return E(t)}const I=e=>{const t=i.getInstance();t.start("getH5UrlParams","utils");const n=a(()=>{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(a){n[t]=e}}),e?n.hasOwnProperty(e)?n[e]:null:n},"utils","GET_H5_URL_PARAMS_ERROR",e?null:{});return t.end("getH5UrlParams"),n};function O(e){try{const t=new URL(e,"http://localhost"),n=t.pathname,a={};return t.searchParams.forEach((e,t)=>{a[t]=e}),{path:n,params:a}}catch(e){return{path:"",params:{}}}}function x(e,t={}){return async(...n)=>{try{return{data:await e(...n),error:null}}catch(e){return t.onError?.(e),{data:null,error:e}}finally{t.onFinally?.()}}}const C=(e="",t=!1,n="none",a=2e3)=>{uni.showToast({title:e,icon:n,mask:t,duration:a})};class b{static instance;navigationQueue=[];isNavigating=!1;maxQueueSize=10;static getInstance(){return b.instance||(b.instance=new b),b.instance}async processQueue(){if(!this.isNavigating&&0!==this.navigationQueue.length){for(this.isNavigating=!0;this.navigationQueue.length>0;){const e=this.navigationQueue.shift();if(e)try{await e(),await new Promise(e=>setTimeout(e,100))}catch(e){}}this.isNavigating=!1}}addToQueue(e){this.navigationQueue.length>=this.maxQueueSize&&this.navigationQueue.shift(),this.navigationQueue.push(e),this.processQueue()}async navigateTo(e){const t=i.getInstance();return t.start("navigateTo","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.navigateTo({url:a,animationType:e.animationType,animationDuration:e.animationDuration,events:e.events,success:()=>{t.end("navigateTo"),n(!0)},fail:e=>{t.end("navigateTo"),n(!1)}})}),"navigation","NAVIGATE_TO_ERROR");a(s??!1)})})}async redirectTo(e){const t=i.getInstance();return t.start("redirectTo","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.redirectTo({url:a,success:()=>{t.end("redirectTo"),n(!0)},fail:e=>{t.end("redirectTo"),n(!1)}})}),"navigation","REDIRECT_TO_ERROR");a(s??!1)})})}async navigateBack(e="",t={}){const a=i.getInstance();a.start("navigateBack","navigation");const s={delta:1,timeout:5e3,enableDebounce:!0,debounceWait:300,...t};return new Promise(t=>{this.addToQueue(async()=>{const i=await n(()=>new Promise(t=>{if(getCurrentPages().length<=s.delta)return void t(!1);const n=setTimeout(()=>{t(!1)},s.timeout);uni.navigateBack({delta:s.delta,success:()=>{clearTimeout(n),setTimeout(()=>{try{const n=getCurrentPages();if(n.length>0){const t=n[n.length-1];t.$vm&&"function"==typeof t.$vm.init?t.$vm.init(e):t.route}a.end("navigateBack"),t(!0)}catch(e){a.end("navigateBack"),t(!0)}},100)},fail:e=>{clearTimeout(n),a.end("navigateBack"),t(!1)}})}),"navigation","NAVIGATE_BACK_ERROR");t(i??!1)})})}async switchTab(e){const t=i.getInstance();return t.start("switchTab","navigation",{url:e}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{uni.switchTab({url:e,success:()=>{t.end("switchTab"),n(!0)},fail:e=>{t.end("switchTab"),n(!1)}})}),"navigation","SWITCH_TAB_ERROR");a(s??!1)})})}async reLaunch(e){const t=i.getInstance();return t.start("reLaunch","navigation",{url:e.url}),new Promise(a=>{this.addToQueue(async()=>{const s=await n(()=>new Promise(n=>{let a=e.url;if(e.params&&Object.keys(e.params).length>0){const t=Object.entries(e.params).map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(t))}`).join("&");a+=(a.includes("?")?"&":"?")+t}uni.reLaunch({url:a,success:()=>{t.end("reLaunch"),n(!0)},fail:e=>{t.end("reLaunch"),n(!1)}})}),"navigation","RELAUNCH_ERROR");a(s??!1)})})}getCurrentPageInfo(){return a(()=>{const e=getCurrentPages();if(0===e.length)return null;const t=e[e.length-1];return{route:t.route||"",options:t.options||{}}},"navigation","GET_CURRENT_PAGE_ERROR",null)}getPageStack(){return a(()=>getCurrentPages().map(e=>({route:e.route||"",options:e.options||{}})),"navigation","GET_PAGE_STACK_ERROR",[])??[]}clearQueue(){this.navigationQueue=[],this.isNavigating=!1}}const A=b.getInstance(),F=async(e="",t={})=>await A.navigateBack(e,t),M=async(e="",t={})=>{const n=i.getInstance();n.start("useBackOrHome","navigation");try{const a=getCurrentPages(),s=t.delta||1;if(a.length>s){const a=await A.navigateBack(e,t);return n.end("useBackOrHome"),a}const i=t.homePage||"pages/index/index",r=i.startsWith("/")?i:`/${i}`,o=await A.reLaunch({url:r,params:t.homeParams});return n.end("useBackOrHome"),o}catch(e){return n.end("useBackOrHome"),!1}},k=v(F,300),j=async e=>await A.navigateTo(e),B=async e=>await A.redirectTo(e),L=async e=>await A.switchTab(e),z=async e=>await A.reLaunch(e),D=()=>A.getCurrentPageInfo(),U=()=>A.getPageStack(),N=()=>{A.clearQueue()},$=async(e,t=3)=>{for(let n=0;n<t;n++){if(await j(e))return!0;n<t-1&&await new Promise(e=>setTimeout(e,1e3*(n+1)))}return!1},H={showToast:!0,successMessage:"复制成功",failMessage:"复制失败",timeout:5e3};async function W(e,t={}){const s=i.getInstance();s.start("copyText","clipboard",{textLength:e.length});const r={...H,...t};if(!e||"string"!=typeof e)return r.showToast&&C("复制内容不能为空",!1,"error"),s.end("copyText"),!1;if(e.length>1e4)return r.showToast&&C("复制内容过长",!1,"error"),s.end("copyText"),!1;let o=!1;return o=await n(()=>new Promise(t=>{"undefined"==typeof uni||!uni||"function"!=typeof uni.setClipboardData?t(!1):uni.setClipboardData({data:e,success:()=>{r.showToast&&C(r.successMessage),t(!0)},fail:()=>{r.showToast&&C(r.failMessage),t(!1)}})}),"clipboard","COPY_TEXT_NATIVE_ERROR")??!1,o=await async function(e,t){const s="undefined"!=typeof navigator&&!!navigator,i="undefined"!=typeof window&&!!window,r=s&&navigator.clipboard,o=i&&window.isSecureContext;if(r&&o){if(await n(async()=>(await Promise.race([navigator.clipboard.writeText(e),new Promise((e,n)=>setTimeout(()=>n(new Error("Clipboard API timeout")),t.timeout))]),!0),"clipboard","CLIPBOARD_API_ERROR"))return t.showToast&&C(t.successMessage),!0}return function(e,t){return a(()=>{if("undefined"==typeof document||"undefined"==typeof window)return t.showToast&&C(t.failMessage),!1;const n=document.createElement("textarea");Object.assign(n.style,{position:"fixed",top:"-9999px",left:"-9999px",width:"1px",height:"1px",padding:"0",border:"none",outline:"none",boxShadow:"none",background:"transparent",fontSize:"16px"}),n.value=e,n.setAttribute("readonly",""),n.setAttribute("contenteditable","true"),document.body.appendChild(n),n.focus(),n.select(),n.setSelectionRange(0,e.length);const a=document.execCommand("copy");return document.body.removeChild(n),a?(t.showToast&&C(t.successMessage),!0):(t.showToast&&C(t.failMessage),!1)},"clipboard","FALLBACK_COPY_ERROR",!1)??!1}(e,t)}(e,r),s.end("copyText"),o}async function G(e={}){const t=i.getInstance();t.start("readClipboard","clipboard");const a={...H,...e},s="undefined"!=typeof navigator&&!!navigator,r="undefined"!=typeof window&&!!window;if(s&&r&&navigator.clipboard&&window.isSecureContext){const e=await n(async()=>await Promise.race([navigator.clipboard.readText(),new Promise((e,t)=>setTimeout(()=>t(new Error("Read clipboard timeout")),a.timeout))]),"clipboard","READ_CLIPBOARD_ERROR");return t.end("readClipboard"),e}return a.showToast&&C("当前平台不支持读取剪贴板",!1,"error"),t.end("readClipboard"),null}function Q(){const e="undefined"!=typeof navigator&&!!navigator,t="undefined"!=typeof window&&!!window;return!!(e&&t&&navigator.clipboard&&window.isSecureContext)}async function J(e={}){return await W("",e)}class q{static instance;cache=new Map;maxCacheSize=100;static getInstance(){return q.instance||(q.instance=new q),q.instance}compress(e){return e.replace(/(.)\1{2,}/g,(e,t)=>`${t}*${e.length}`)}decompress(e){return e.replace(/(.)\*(\d+)/g,(e,t,n)=>t.repeat(parseInt(n)))}encrypt(e){return btoa(encodeURIComponent(e))}decrypt(e){try{return decodeURIComponent(atob(e))}catch{return e}}isExpired(e){return!!e.ttl&&Date.now()-e.timestamp>e.ttl}set(e,t,n={}){const s=i.getInstance();s.start(`setStorage_${e}`,"localStorage");const r=a(()=>{if(!e||"string"!=typeof e)throw new Error("存储键不能为空");const a={value:t,timestamp:Date.now(),ttl:n.ttl,compressed:n.compress,encrypted:n.encrypt};let s=JSON.stringify(a);if(n.compress&&(s=this.compress(s)),n.encrypt&&(s=this.encrypt(s)),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,a),!0},"localStorage","SET_STORAGE_ERROR",!1);return s.end(`setStorage_${e}`),r??!1}get(e,t){const n=i.getInstance();n.start(`getStorage_${e}`,"localStorage");const s=a(()=>{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}let n=uni.getStorageSync(e);if(!n)return t;if("string"!=typeof n)return t;let a,s=n;if(s&&s.includes("="))try{const e=this.decrypt(s);e&&(s=e)}catch{}if(s&&s.includes("*"))try{s=this.decompress(s)}catch{}try{const e=JSON.parse(s);a=e&&"object"==typeof e&&"value"in e&&"timestamp"in e?e:{value:e,timestamp:Date.now()}}catch{return s}return this.isExpired(a)?(this.remove(e),t):(this.cache.set(e,a),a.value)},"localStorage","GET_STORAGE_ERROR",t);return n.end(`getStorage_${e}`),s??t}remove(e){return a(()=>!(!e||"string"!=typeof e)&&(uni.removeStorageSync(e),this.cache.delete(e),!0),"localStorage","REMOVE_STORAGE_ERROR",!1)??!1}clear(){return a(()=>(uni.clearStorageSync(),this.cache.clear(),!0),"localStorage","CLEAR_STORAGE_ERROR",!1)??!1}getInfo(){return a(()=>{const e=uni.getStorageInfoSync();return{keys:e.keys||[],currentSize:e.currentSize||0,limitSize:e.limitSize||0}},"localStorage","GET_STORAGE_INFO_ERROR",{keys:[],currentSize:0,limitSize:0})??{keys:[],currentSize:0,limitSize:0}}cleanExpired(){const e=i.getInstance();e.start("cleanExpiredStorage","localStorage");const t=a(()=>{const e=this.getInfo();let t=0;return e.keys.forEach(e=>{void 0===this.get(e)&&t++}),t},"localStorage","CLEAN_EXPIRED_ERROR",0);return e.end("cleanExpiredStorage"),t??0}}const V=q.getInstance();function Y(e,t,n={}){return V.set(e,t,n)}function K(e,t){return V.get(e,t)}function X(e){return e?V.remove(e):V.clear()}async function Z(e,t,a={}){return await n(()=>new Promise(n=>{n(Y(e,t,a))}),"localStorage","SET_STORAGE_ASYNC_ERROR")??!1}async function ee(e,t){return await n(()=>new Promise(n=>{n(K(e,t))}),"localStorage","GET_STORAGE_ASYNC_ERROR")??t}function te(){return V.getInfo()}function ne(){return V.cleanExpired()}function ae(e,t={}){const n=i.getInstance();n.start("batchSetStorage","localStorage");let a=0;return Object.entries(e).forEach(([e,n])=>{Y(e,n,t)&&a++}),n.end("batchSetStorage"),a}function se(e){const t=i.getInstance();t.start("batchGetStorage","localStorage");const n={};return e.forEach(e=>{n[e]=K(e)}),t.end("batchGetStorage"),n}const ie={name:"file",maxSize:10,allowedTypes:["jpg","jpeg","png","gif","webp"],showToast:!0,timeout:6e4,successMessage:"上传成功",failMessage:"上传失败"},re={type:"image",count:1,sizeType:["original","compressed"],sourceType:["album","camera"],extension:[],maxSize:10,showToast:!0,failMessage:"选择文件失败",onPartialInvalid:"fail"};function oe(e,t,n){if(!e)return{valid:!1,message:"文件路径不能为空"};if(t.allowedTypes&&t.allowedTypes.length>0){const a=e.split(".").pop()?.toLowerCase(),s=t.allowedTypes.map(e=>e.toLowerCase()),i=!!n&&s.some(e=>!!e.includes("/")&&(e.endsWith("/*")?n.startsWith(e.slice(0,e.indexOf("/"))):n===e)),r=!!a&&s.some(e=>!e.includes("/")&&e.replace(/^\./,"")===a);if(!i&&!r)return{valid:!1,message:`不支持的文件类型,仅支持:${t.allowedTypes.join(", ")}`}}return{valid:!0}}async function ce(e={}){const t=i.getInstance();t.start("chooseFile","upload",{count:e.count,type:e.type});const a={...re,...e};let s=a.type;var r;("messagefile"===(r=s)?"function"==typeof uni.chooseMessageFile:"local"===r||"image"===r)||(s="image");const o=await n(()=>new Promise(e=>{const t=t=>{const n=t.errMsg||a.failMessage;a.showToast&&C(n,!1,"error"),e({success:!1,message:n,type:s})};"image"!==s&&"local"!==s?"messagefile"===s?uni.chooseMessageFile({count:a.count,type:"all",success:t=>{e({success:!0,tempFilePaths:t.tempFiles.map(e=>e.path),tempFiles:t.tempFiles,type:"messagefile"})},fail:t}):"image"===s?uni.chooseImage({count:a.count,sizeType:a.sizeType,sourceType:a.sourceType,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],a=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:a,type:"image"})},fail:t}):"local"===s&&("function"==typeof uni.chooseFile?uni.chooseFile({count:a.count,extension:a.extension,success:t=>{const n=Array.isArray(t.tempFilePaths)?t.tempFilePaths:[t.tempFilePaths],a=(Array.isArray(t.tempFiles)?t.tempFiles:[t.tempFiles]).map((e,t)=>({path:n[t],size:e.size}));e({success:!0,tempFilePaths:n,tempFiles:a,type:"local"})},fail:t}):e({success:!1,message:"当前平台不支持选择本地文件",type:s})):function(e,t){const n=document.createElement("input");n.type="file",n.multiple=e.count>1,"image"===e.type?n.accept="image/*":e.extension.length>0&&(n.accept=e.extension.map(e=>e.startsWith(".")?e:`.${e}`).join(",")),n.onchange=a=>{const s=a.target.files;if(s&&s.length>0){const n=Array.from(s).map(e=>({path:URL.createObjectURL(e),size:e.size,name:e.name,type:e.type,file:e})),a=n.map(e=>({path:e.path,size:e.size,name:e.name,type:e.type}));t({success:!0,tempFilePaths:n.map(e=>e.path),tempFiles:a,type:e.type})}else t({success:!1,message:"用户取消选择",type:e.type});document.body.removeChild(n)},n.style.display="none",document.body.appendChild(n),n.click()}(a,e)}).then(e=>{if(!e.success||!e.tempFiles)return e;const t=a.maxSize?e.tempFiles.filter(e=>{return!(t=e.size,n=a.maxSize,n&&t>1024*n*1024?{valid:!1,message:`文件大小不能超过 ${n}MB`}:{valid:!0}).valid;var t,n}):[],n="image"===a.type||a.extension.length>0,s=n?e.tempFiles.filter(e=>{const t={url:"",allowedTypes:"image"===a.type&&0===a.extension.length?["image/*"]:a.extension};return!oe(e.path,t,e.type).valid}):[],i=new Set;t.forEach(e=>i.add(e.path)),s.forEach(e=>i.add(e.path));const r=Array.from(i);if(0===r.length)return e;const o=`部分文件不合规:${[a.maxSize?`大小超过 ${a.maxSize}MB`:"",n?"类型不符合要求":""].filter(Boolean).join(",")}`;if("filter"===a.onPartialInvalid){const t=e.tempFiles.filter(e=>!i.has(e.path));return{...e,tempFiles:t,tempFilePaths:t.map(e=>e.path),invalidFiles:r,message:o,success:t.length>0}}return a.showToast&&C(o,!1,"error"),{...e,success:"allow"===a.onPartialInvalid,invalidFiles:r,message:o}}),"upload","CHOOSE_FILE_ERROR");return t.end("chooseFile"),o||{success:!1,message:"选择文件失败",type:s}}async function ue(e={}){const t=await ce({...e,type:"image"});return{success:t.success,tempFilePaths:t.tempFilePaths,tempFiles:t.tempFiles,message:t.message}}async function le(e,t,a){const s=i.getInstance();s.start("uploadFile","upload",{filePath:e});const r={...ie,...t};if(!r.url){const e="上传地址不能为空";return r.showToast&&C(e,!1,"error"),s.end("uploadFile"),{success:!1,message:e}}const o=oe(e,r);if(!o.valid)return r.showToast&&C(o.message,!1,"error"),s.end("uploadFile"),{success:!1,message:o.message};const c=await n(()=>new Promise(t=>{const n=uni.uploadFile({url:r.url,filePath:e,name:r.name,formData:r.formData,header:r.header,timeout:r.timeout,success:n=>{let a;try{a=JSON.parse(n.data)}catch{a=n.data}if(200===n.statusCode)r.showToast&&C(r.successMessage,!1,"success"),t({success:!0,data:a,tempFilePath:e,statusCode:n.statusCode,originalResult:n});else{const e=`上传失败,状态码:${n.statusCode}`;r.showToast&&C(e,!1,"error"),t({success:!1,message:e,statusCode:n.statusCode,originalResult:n})}},fail:n=>{const a=n.errMsg||r.failMessage;r.showToast&&C(a,!1,"error"),t({success:!1,message:a,tempFilePath:e,originalResult:n})}});a&&n&&n.onProgressUpdate(e=>{a({progress:e.progress,totalBytesSent:e.totalBytesSent,totalBytesExpectedToSend:e.totalBytesExpectedToSend})})}),"upload","UPLOAD_FILE_ERROR");return s.end("uploadFile"),c||{success:!1,message:"上传文件失败"}}async function de(e,t={},n){const a=i.getInstance();a.start("chooseAndUploadFile","upload");const s=await ce(t);if(!s.success||!s.tempFilePaths)return a.end("chooseAndUploadFile"),[{success:!1,message:s.message||"选择文件失败"}];const r=s.tempFilePaths.map(t=>le(t,e,n)),o=await Promise.all(r);return a.end("chooseAndUploadFile"),o}async function pe(e,t={},n){return de(e,{...t,type:"image"},n)}function ge(){return"undefined"!=typeof uni&&"function"==typeof uni.uploadFile}async function me(e){return await n(()=>new Promise((t,n)=>{uni.getFileInfo({filePath:e,digestAlgorithm:"md5",success:e=>{const n=e;t({size:n.size,digest:n.digest})},fail:n})}),"upload","GET_FILE_INFO_ERROR")}const he=(e,t,n)=>{const s=i.getInstance();return s.start("weChatOfficialAccountPayment","payment"),new Promise(i=>{a(()=>{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 a(){try{window.WeixinJSBridge.invoke("getBrandWCPayRequest",e,function(e){s.end("weChatOfficialAccountPayment"),"get_brand_wcpay_request:ok"===e.err_msg?(t?.(e),i(!0)):(n?.(e),i(!1))})}catch(e){s.end("weChatOfficialAccountPayment");const t={err_msg:"get_brand_wcpay_request:fail",err_desc:e instanceof Error?e.message:"未知错误"};n?.(t),i(!1)}}if(void 0===window.WeixinJSBridge){const e=window.document;e.addEventListener?e.addEventListener("WeixinJSBridgeReady",a,!1):e.attachEvent&&(e.attachEvent("WeixinJSBridgeReady",a),e.attachEvent("onWeixinJSBridgeReady",a))}else a();return!0},"payment","WECHAT_PAY_ERROR",!1)||(s.end("weChatOfficialAccountPayment"),i(!1))})},fe=()=>{const e=i.getInstance();e.start("isWechat","system");const t=a(()=>{if("undefined"!=typeof navigator&&navigator.userAgent){return navigator.userAgent.toLowerCase().includes("micromessenger")}return!1},"system","IS_WECHAT_ERROR",!1);return e.end("isWechat"),t||!1},we=()=>new Promise(e=>{if("undefined"!=typeof window&&window.wx)return void e(!0);const t=["https://res.wx.qq.com/open/js/jweixin-1.6.0.js","https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"];let n=0;const a=s=>{const i=document.createElement("script");i.src=s,i.async=!0,i.onload=()=>{e(!0)},i.onerror=()=>{n++,n<t.length?(document.head.removeChild(i),a(t[n])):(document.head.removeChild(i),e(!1))},document.head.appendChild(i)};a(t[n]),e(!1)}),ye=async e=>{const t=i.getInstance();t.start("configWechatJSSDK","wechat");try{if(!fe())return!1;return!!await we()&&new Promise(t=>{window.wx?(window.wx.config({debug:e.debug||!1,appId:e.appId,timestamp:e.timestamp,nonceStr:e.nonceStr,signature:e.signature,jsApiList:e.jsApiList}),window.wx.ready(()=>{t(!0)}),window.wx.error(e=>{t(!1)})):t(!1),t(!1)})}catch(e){return!1}finally{t.end("configWechatJSSDK")}},Re=e=>new Promise(t=>{window.wx&&fe()?window.wx.checkJsApi({jsApiList:e,success:e=>{t(e.checkResult||{})}}):t({}),t({})}),Ee=e=>{a(()=>{window.wx&&fe()&&(window.wx.updateTimelineShareData?window.wx.updateTimelineShareData(e):window.wx.onMenuShareTimeline&&window.wx.onMenuShareTimeline(e))},"wechat","SHARE_TIMELINE_ERROR")},Te=e=>{a(()=>{window.wx&&fe()&&(window.wx.updateAppMessageShareData?window.wx.updateAppMessageShareData(e):window.wx.onMenuShareAppMessage&&window.wx.onMenuShareAppMessage(e))},"wechat","SHARE_FRIEND_ERROR")};class Se{static instance;isConfigured=!1;config=null;constructor(){}static getInstance(){return Se.instance||(Se.instance=new Se),Se.instance}async init(e){return this.config=e,this.isConfigured=await ye(e),this.isConfigured}isReady(){return this.isConfigured&&fe()}getConfig(){return this.config}setShareData(e){this.isReady()&&(Ee(e),Te(e))}}const ve="1.0.8";async function Pe(e={}){const{enablePerformanceMonitor:t=!1,enableErrorHandler:n=!0,logLevel:a="warn"}=e;if(n){const{ErrorHandler:e}=await Promise.resolve().then(function(){return s}),n=e.getInstance();t&&n.onError(e=>{})}if(t){const{PerformanceMonitor:e}=await Promise.resolve().then(function(){return o}),t=e.getInstance();setInterval(()=>{t.getReport().slowest.length},6e4)}}export{t as ErrorHandler,i as PerformanceMonitor,e as UniAppToolsError,ve as VERSION,Se as WechatSDK,se as batchGetStorage,ae as batchSetStorage,Re as checkWechatJSAPI,de as chooseAndUploadFile,pe as chooseAndUploadImage,ce as chooseFile,ue as chooseImage,ne as cleanExpiredStorage,J as clearClipboard,N as clearNavigationQueue,X as clearStorageSync,ye as configWechatJSSDK,W as copyText,v as debounce,E as deepClone,S as deepMerge,O as extractUrlParts,p as getCurrentEnv,D as getCurrentPageInfo,me as getFileInfo,I as getH5UrlParams,h as getMenuButtonBoundingClientRect,f as getNavHeight,U as getPageStack,d as getPlatform,m as getStatusBarHeight,ee as getStorage,te as getStorageInfo,K as getStorageSync,w as getTopNavBarHeight,Pe as initUniAppTools,Q as isClipboardSupported,ge as isUploadSupported,fe as isWechat,we as loadWechatJSSDK,r as measurePerformance,T as mergeObjects,j as navigateTo,g as onCheckForUpdate,z as reLaunch,G as readClipboard,B as redirectTo,n as safeAsync,$ as safeNavigateTo,a as safeSync,R as setPageIcon,y as setPageTitle,Z as setStorage,Y as setStorageSync,Te as shareToFriend,Ee as shareToTimeline,L as switchTab,P as throttle,le as uploadFile,F as useBack,k as useBackDebounced,M as useBackOrHome,_ as useDeepCopyByObj,C as useToast,x as useTryCatch,l as useWindowInfo,he as weChatOfficialAccountPayment};
@@ -8,12 +8,16 @@
8
8
  * @description 调用 uni.getWindowInfo() 获取当前设备的窗口相关信息,支持缓存
9
9
  */
10
10
  export declare const useWindowInfo: (useCache?: boolean) => any;
11
+ /**
12
+ * 平台类型定义
13
+ */
14
+ type PlatformType = "weixin" | "web" | "app" | "alipay" | "h5" | "unknown";
11
15
  /**
12
16
  * 获取当前运行平台
13
- * @returns 平台类型字符串 ('weixin' | 'web' | 'app' | 'alipay' | 'h5')
14
- * @description 通过条件编译判断当前代码运行的平台环境
17
+ * @returns 平台类型字符串 ('weixin' | 'web' | 'app' | 'alipay' | 'h5' | 'unknown')
18
+ * @description 通过条件编译判断当前代码运行的平台环境,并增加缓存避免重复计算
15
19
  */
16
- export declare const getPlatform: () => string;
20
+ export declare const getPlatform: () => PlatformType;
17
21
  /**
18
22
  * 获取小程序账户信息
19
23
  * @returns 小程序账户信息对象,包含appId、版本、环境等信息
@@ -66,14 +70,16 @@ export declare const getTopNavBarHeight: () => {
66
70
  navHeight: number;
67
71
  };
68
72
  /**
69
- * 修改浏览器标题
73
+ * 修改页面标题
70
74
  * @param title 新的页面标题
71
- * @description 动态修改浏览器标签页显示的标题,仅在H5/Web平台有效
75
+ * @description 动态修改页面标题,统一使用uni-app API,支持所有平台
72
76
  * @example
73
77
  * // 修改页面标题
74
78
  * setPageTitle('新的页面标题')
79
+ *
80
+ * @returns Promise<boolean> 返回设置结果
75
81
  */
76
- export declare const setPageTitle: (title: string) => boolean | null;
82
+ export declare const setPageTitle: (title: string) => Promise<boolean>;
77
83
  /**
78
84
  * 修改浏览器图标(favicon)
79
85
  * @param iconUrl 新的图标URL地址
@@ -86,9 +92,4 @@ export declare const setPageTitle: (title: string) => boolean | null;
86
92
  * setPageIcon('https://example.com/new-icon.png', 'image/png')
87
93
  */
88
94
  export declare const setPageIcon: (iconUrl: string, iconType?: string) => boolean | null;
89
- /**
90
- * 检测是否在微信浏览器中运行
91
- * @returns 是否为微信浏览器环境
92
- * @description 检测当前是否在微信浏览器中运行(不包括微信小程序)
93
- */
94
- export declare const isWechat: () => boolean;
95
+ export {};
@@ -51,6 +51,8 @@ export interface ChooseFileConfig {
51
51
  showToast?: boolean;
52
52
  /** 失败提示信息 */
53
53
  failMessage?: string;
54
+ /** 当存在不合规文件(大小/类型)时的处理策略,默认 'fail' */
55
+ onPartialInvalid?: 'fail' | 'filter' | 'allow';
54
56
  }
55
57
  /**
56
58
  * 选择图片配置接口(向后兼容)
@@ -71,6 +73,8 @@ export interface UploadResult {
71
73
  tempFilePath?: string;
72
74
  /** HTTP 状态码 */
73
75
  statusCode?: number;
76
+ /** 原始结果(便于调试与错误定位) */
77
+ originalResult?: any;
74
78
  }
75
79
  /**
76
80
  * 选择文件结果接口
@@ -84,11 +88,17 @@ export interface ChooseFileResult {
84
88
  tempFiles?: Array<{
85
89
  path: string;
86
90
  size: number;
91
+ /** 文件名(H5 可用,其他平台可能缺失) */
92
+ name?: string;
93
+ /** MIME 类型(H5 可用)或基于扩展名推断 */
94
+ type?: string;
87
95
  }>;
88
96
  /** 提示信息 */
89
97
  message?: string;
90
98
  /** 文件选择类型 */
91
99
  type: FileSelectType;
100
+ /** 不合规文件(路径列表),用于业务自行提示或过滤 */
101
+ invalidFiles?: string[];
92
102
  }
93
103
  /**
94
104
  * 选择图片结果接口(向后兼容)
@@ -59,3 +59,32 @@ export interface UrlParams {
59
59
  * @description 在 H5 环境中解析 URL 参数,支持性能监控和错误处理
60
60
  */
61
61
  export declare const getH5UrlParams: (paramName?: string) => string | null | UrlParams;
62
+ /**
63
+ * 从URL中提取页面路径和参数
64
+ * @param url 要解析的URL
65
+ * @returns 包含路径和参数的对象
66
+ * @example
67
+ * ```js
68
+ * const url = "http://example.com/path/to/page?foo=bar&baz=qux";
69
+ * const { path, params } = extractUrlParts(url);
70
+ * console.log(path); // "/path/to/page"
71
+ * console.log(params); // { foo: "bar", baz: "qux" }
72
+ * ```
73
+ */
74
+ export declare function extractUrlParts(url: string): {
75
+ path: string;
76
+ params: Record<string, string>;
77
+ };
78
+ /**
79
+ * 封装通用的 try/catch/finally 调用
80
+ * @param fn 需要被保护执行的函数,可以返回同步结果或 Promise
81
+ * @param options 可选配置项,支持错误和最终回调
82
+ * @returns 返回一个包装后的执行函数,执行结果为 Promise<{ data, error }>
83
+ */
84
+ export declare function useTryCatch<T extends (...args: any[]) => any>(fn: T, options?: {
85
+ onError?: (error: unknown) => void;
86
+ onFinally?: () => void;
87
+ }): (...args: Parameters<T>) => Promise<{
88
+ data: Awaited<ReturnType<T>> | null;
89
+ error: unknown;
90
+ }>;
@@ -0,0 +1,99 @@
1
+ interface WxConfig {
2
+ debug?: boolean;
3
+ appId: string;
4
+ timestamp: number;
5
+ nonceStr: string;
6
+ signature: string;
7
+ jsApiList: string[];
8
+ }
9
+ interface WxShareConfig {
10
+ title: string;
11
+ desc: string;
12
+ link: string;
13
+ imgUrl: string;
14
+ success?: () => void;
15
+ cancel?: () => void;
16
+ }
17
+ declare global {
18
+ interface Window {
19
+ wx?: {
20
+ config: (config: WxConfig) => void;
21
+ ready: (callback: () => void) => void;
22
+ error: (callback: (res: any) => void) => void;
23
+ checkJsApi: (config: {
24
+ jsApiList: string[];
25
+ success: (res: any) => void;
26
+ }) => void;
27
+ updateAppMessageShareData: (config: WxShareConfig) => void;
28
+ updateTimelineShareData: (config: WxShareConfig) => void;
29
+ onMenuShareTimeline: (config: WxShareConfig) => void;
30
+ onMenuShareAppMessage: (config: WxShareConfig) => void;
31
+ onMenuShareWeibo: (config: WxShareConfig) => void;
32
+ onMenuShareQZone: (config: WxShareConfig) => void;
33
+ };
34
+ }
35
+ }
36
+ /**
37
+ * 检测是否在微信浏览器中运行
38
+ * @returns 是否为微信浏览器环境
39
+ * @description 检测当前是否在微信浏览器中运行(不包括微信小程序)
40
+ */
41
+ export declare const isWechat: () => boolean;
42
+ /**
43
+ * 动态加载微信 JS-SDK
44
+ * @returns Promise<boolean> 加载是否成功
45
+ * @description 支持主备CDN地址,提升服务稳定性
46
+ */
47
+ export declare const loadWechatJSSDK: () => Promise<boolean>;
48
+ /**
49
+ * 微信 JS-SDK 配置
50
+ * @param config 配置参数
51
+ * @returns Promise<boolean> 配置是否成功
52
+ */
53
+ export declare const configWechatJSSDK: (config: WxConfig) => Promise<boolean>;
54
+ /**
55
+ * 检查微信 JS-SDK API 可用性
56
+ * @param jsApiList 需要检查的 API 列表
57
+ * @returns Promise<Record<string, boolean>> API 可用性结果
58
+ */
59
+ export declare const checkWechatJSAPI: (jsApiList: string[]) => Promise<Record<string, boolean>>;
60
+ /**
61
+ * 微信分享到朋友圈
62
+ * @param config 分享配置
63
+ */
64
+ export declare const shareToTimeline: (config: WxShareConfig) => void;
65
+ /**
66
+ * 微信分享给朋友
67
+ * @param config 分享配置
68
+ */
69
+ export declare const shareToFriend: (config: WxShareConfig) => void;
70
+ /**
71
+ * 微信 JS-SDK 工具类
72
+ */
73
+ export declare class WechatSDK {
74
+ private static instance;
75
+ private isConfigured;
76
+ private config;
77
+ private constructor();
78
+ static getInstance(): WechatSDK;
79
+ /**
80
+ * 初始化微信 JS-SDK
81
+ * @param config 配置参数
82
+ * @returns Promise<boolean>
83
+ */
84
+ init(config: WxConfig): Promise<boolean>;
85
+ /**
86
+ * 检查是否已配置
87
+ */
88
+ isReady(): boolean;
89
+ /**
90
+ * 获取配置信息
91
+ */
92
+ getConfig(): WxConfig | null;
93
+ /**
94
+ * 设置分享信息
95
+ * @param shareConfig 分享配置
96
+ */
97
+ setShareData(shareConfig: WxShareConfig): void;
98
+ }
99
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-uniapp-tools",
3
- "version": "1.0.17",
3
+ "version": "1.0.21",
4
4
  "type": "module",
5
5
  "description": "一个功能强大、性能优化的 uni-app 开发工具库,提供剪贴板、本地存储、导航、系统信息等常用功能",
6
6
  "main": "dist/my-uniapp-tools.cjs.js",
@@ -19,7 +19,13 @@
19
19
  "test": "echo \"Error: no test specified\" && exit 1",
20
20
  "dev": "node src/index.js",
21
21
  "docs:dev": "vuepress dev docs",
22
- "docs:build": "vuepress build docs"
22
+ "docs:build": "vuepress build docs",
23
+ "release:patch": "npm version patch && npm publish",
24
+ "release:minor": "npm version minor && npm publish",
25
+ "release:major": "npm version major && npm publish",
26
+ "release": "npm run release:patch",
27
+ "publish:beta": "npm version prerelease --preid=beta && npm publish --tag beta",
28
+ "publish:alpha": "npm version prerelease --preid=alpha && npm publish --tag alpha"
23
29
  },
24
30
  "keywords": [
25
31
  "uniapp",