let view; let app = null; function getAppWrap() { if(app == null) app = getApp(); return app; } function init() { const app = getAppWrap(); app.globalData.debuggerLogData = []; app.globalData.debuggerNetworkLogData = []; app.globalData.debuggerErrLogData = []; uni.$on('debugger-view-closed', () => { if(view) view.show(); }); uni.$on('debugger-view-opened', () => { if(view) view.hide(); }); uni.$on('debugger-view-close', () => { if(view) view.close(); }); } //====================== //调试器使用方法 function addNetworkLog(info, options, data) { const app = getAppWrap(); if(app.globalData.debuggerNetworkLogData.length > 512) app.globalData.debuggerNetworkLogData.shift(); app.globalData.debuggerNetworkLogData.push({ info, options, data }); uni.$emit('debugger-refresh-network'); } function addAppErr(err) { const app = getAppWrap(); if(app.globalData.debuggerErrLogData.length > 128) app.globalData.debuggerErrLogData.shift(); app.globalData.debuggerErrLogData.push({ err: err.toString(), stack: err.stack }); uni.$emit('debugger-refresh-app-err'); } function addVueError(err, vm, info) { const app = getAppWrap(); if(app.globalData.debuggerErrLogData.length > 128) app.globalData.debuggerErrLogData.shift(); app.globalData.debuggerErrLogData.push({ err: err.toString(), stack: err.stack + '\n' + info }); uni.$emit('debugger-refresh-vue-err'); } function addLog(info) { const app = getAppWrap(); let removeFirst = false; if(app.globalData.debuggerLogData.length > 768) { app.globalData.debuggerLogData.shift(); removeFirst = true; } app.globalData.debuggerLogData.push(info); uni.$emit('debugger-refresh-log', removeFirst); } export const debuggerModule = { addNetworkLog, addAppErr, addVueError, addLog, }; //====================== //调试器初始化方法 function pad(num, n) { let strNum = num.toString(); let len = strNum.length; while (len < n) { strNum = "0" + strNum; len++; } return strNum; } function getNowTimeString() { const d = new Date(); return pad(d.getHours(), 2) + ':' + pad(d.getMinutes(), 2) + ':' + pad(d.getSeconds(), 2); } function installConsoleHook() { console.log('installConsoleHook'); if(debuggerModule) { let console_log = console.log let console_error = console.error let console_info = console.info let console_warn = console.warn console.log = function(...arg) { debuggerModule.addLog({ time: getNowTimeString(), type: 'log', objects: arg }); console_log(...arg) } console.error = function(...arg) { debuggerModule.addLog({ time: getNowTimeString(), type: 'error', objects: arg }); console_error(...arg) } console.info = function(...arg) { debuggerModule.addLog({ time: getNowTimeString(), type: 'info', objects: arg }); console_info(...arg) } console.warn = function(...arg) { debuggerModule.addLog({ time: getNowTimeString(), type: 'warn', objects: arg }); console_warn(...arg) } } } function installRequestHook() { /* 拦截请求 */ uni.addInterceptor('request', { invoke(args) { // request 触发前拼接 url const addInterceptorRequestData = { data: args.data, method: args.method || 'GET', sourceUrl: args.url, url: args.url, status: 0, } let _complete = args.complete; args.complete = function(e) { _complete && _complete(e) addInterceptorRequestData.status = e.statusCode addNetworkLog( addInterceptorRequestData, args, e.data ); } }, }) } function createView() { const ss = uni.getStorageSync('noNorDebuggerFloating'); if(ss == 'yes') return; if(plus.nativeObj) { let page = {}, onType = false view = new plus.nativeObj.View('HF', { bottom: '0px', left: '60%', height: '40px', width: '40px', }); view.drawRect({ color: '#FF4A46', radius: '20px' }, { top: '0px', left: '0px', width: '100%', height: '100%' }); view.drawText('调试', { top: '0px', left: '0px', width: '100%', height: '100%' }, { size: '16px', color: '#FFFFFF' }); view.addEventListener("touchstart", (touch) => { page = touch }) view.addEventListener("touchmove", (touch) => { if ((touch.pageY - 20 > 0 && touch.pageX - 50 > 0) && (Math.abs(touch.pageX - page.pageX) > 20 || Math.abs(touch.pageY - page.pageY) > 20)) { view.setStyle({ top: (touch.pageY - 20) + 'px', left: (touch.pageX - 50) + 'px' }) onType = true } else { onType = false } }) view.addEventListener("click", (e) => { !onType && showDebuggerWindow() }) view.show(); view.setStyle({ top: '500px', left: '0px' }) } else { console.warn('IMDebuggerWindow: 当前环境不支持添加全局悬浮窗,您需要手动开启调试窗口'); } } /** * 显示调试器窗口 */ export function showDebuggerWindow() { uni.navigateTo({ url: '/uni_modules/imengyu-IMDebuggerWindow/pages/debugger', animationType: 'none', }) view.hide(); } /** * 获取调试器是否已经安装 */ export function debuggerEnabled() { return getApp().globalData._debuggerEnabled; } /** * 安装调试器 * @param {type} options 自定义参数 */ export function installDebugger(options) { init(); if(options.showGlobalFloatWindow) createView(); installConsoleHook(); if(options.enableRequestInterceptor) installRequestHook(); getApp().globalData._debuggerEnabled = true; }