class cmappClass { public authCallBack : any ; public authType : number ; public authTypeObj : Array < any > ; public environmentInfo : any = { userAgent : null , isMiniprogram : ! window , isElectron : 0 , isWeixin : 0 , isWechat : 0 , isWxwork : 0 , isDevtools : 0 , isApp : 0 , isHvoi : 0 , isWebview : 0 , appType : 0 } ; public innerAudioContext : any ; constructor ( ) { this . authType = 0 ; this . authTypeObj = [ { type : 'scope.userLocation' , title : '温馨提示' , content : '需要获取您的位置信息' , ts : '未授权微信获取位置' , } , { type : 'scope.werun' , title : '温馨提示' , content : '需要获取您的运动信息' , ts : '未授权微信获取步数' , } , { type : 'scope.camera' , title : '温馨提示' , content : '需要获取您的系统相机' , ts : '未授权微信获取相机' , } , ] ; } getUniApi ( uniApi , config = { } ) { let isSuccess = 0 ; return new Promise ( ( resolve , reject ) => { const callback = { ... config , success ( res ) { isSuccess = 1 ; resolve ( { isSuccess , res , } ) ; } , fail ( res ) { reject ( { isSuccess , res , } ) ; } , } ; uniApi ( callback ) ; } ) ; } isApp ( ) { return window && window . plus || false ; } setStorage ( key , value , type = 'uni' ) { if ( type === 'plus' ) { this . isApp ( ) && window . plus . storage . setItem ( key , value ) || window . localStorage . setItem ( key , value ) ; return ; } uni . setStorageSync ( key , value ) ; } getStorage ( key , type = 'uni' ) { if ( type === 'plus' ) { return this . isApp ( ) && window . plus . storage . getItem ( key ) || window . localStorage . getItem ( key ) || '' ; } return uni . getStorageSync ( key ) || '' ; } removeStorage ( key , type = 'uni' ) { if ( key ) { if ( type === 'plus' ) { this . isApp ( ) && window . plus . storage . removeItem ( key ) || window . localStorage . removeItem ( key ) ; return ; } uni . removeStorageSync ( key ) ; } else { window && window . localStorage . clear ( ) ; uni . clearStorageSync ( ) ; } } updateLS ( k , timeKey , s , func ) { const cmapp = this ; const nd = new Date ( ) . valueOf ( ) ; const kid = cmapp . getStorage ( k ) ; const time = cmapp . getStorage ( timeKey ) ; let id = 1 ; if ( kid && time && nd - time >= 1000 * 60 * s ) { cmapp . removeStorage ( k ) ; id = 0 ; } if ( typeof func === 'function' ) { func ( id ) ; } } getSearchValue ( name , path = '' ) { let reg = new RegExp ( name + '=([^&]*)(&|$)' , 'i' ) ; const params = path || ( ! this . environmentInfo . isMiniprogram && window . location . href || '' ) ; reg = params . substr ( 1 ) . match ( reg ) ; const value = reg != null ? reg [ 1 ] : null ; return value ; } getQuery ( $vue , key ) { const route = '_route' ; let query = $vue . $mp && $vue . $mp . query || null ; const query2 = $vue [ route ] && $vue [ route ] . query || null ; const query3 = $vue . __page__ && $vue . __page__ . options || null ; query = query || query2 || query3 ; if ( key === 'query' ) { return query || '' ; } const value2 = ! this . environmentInfo . isMiniprogram && window . location . href . includes ( `${ key }=` ) && this . getSearchValue ( key ) || '' ; return query && query [ key ] || value2 || '' ; } getSelectorInfo ( selector ) { return new Promise ( ( resolve ) => { const query = uni . createSelectorQuery ( ) ; query . select ( selector ) . boundingClientRect ( ) ; query . selectViewport ( ) . scrollOffset ( ) ; query . exec ( ( res ) => { resolve ( res ) ; } ) ; } ) ; } getDivMatrix ( m ) { const d1 = 180 ; const d2 = 360 ; const aa = Math . round ( d1 * Math . asin ( m [ 0 ] ) / Math . PI ) ; const bb = Math . round ( d1 * Math . acos ( m [ 1 ] ) / Math . PI ) ; const cc = Math . round ( d1 * Math . asin ( m [ 2 ] ) / Math . PI ) ; const dd = Math . round ( d1 * Math . acos ( m [ 3 ] ) / Math . PI ) ; let deg = 0 ; if ( aa === bb || - aa === bb ) { deg = dd ; } else if ( - aa + bb === d1 ) { deg = d1 + cc ; } else if ( aa + bb === d1 ) { deg = d2 - cc || d2 - dd ; } return deg >= d2 ? 0 : deg ; } param selector getDivDeg ( selector ) { const $cmapp = this ; return new Promise ( ( resolve , reject ) => { uni . createSelectorQuery ( ) . select ( selector ) . fields ( { dataset : true , size : true , scrollOffset : true , properties : [ 'scrollX' , 'scrollY' ] , computedStyle : [ 'animation' , 'transform' ] , context : true , } , async function ( res ) { if ( res . transform ) { const transform = res . transform ; const matrix = transform . split ( ',' ) ; if ( matrix && matrix . length > 0 ) { matrix [ 0 ] = matrix [ 0 ] . split ( '(' ) . pop ( ) ; const deg = await $cmapp . getDivMatrix ( matrix ) ; resolve ( deg ) ; } else { reject ( 0 ) ; } } else { reject ( 0 ) ; } } ) . exec ( ) ; } ) ; } update ( ) { const cmapp = this ; const updateManager = uni . getUpdateManager ( ) ; updateManager . onCheckForUpdate ( ( res ) => { console . log ( res . hasUpdate ) ; } ) ; updateManager . onUpdateReady ( function ( ) { cmapp . removeStorage ( '' ) ; const a = { title : '新版本更新中..' , icon : 'none' , } ; uni . showToast ( a ) ; updateManager . applyUpdate ( ) ; } ) ; updateManager . onUpdateFailed ( ( ) => { } ) ; } param url param navigateType jumpTo ( url , navigateType , isAuth = 'no' ) { if ( ! url && navigateType !== 'navigateBack' ) { console . log ( isAuth ) ; return ; } switch ( navigateType ) { case 'switchTab' : uni . switchTab ( { url : url } ) ; break ; case 'reLaunch' : uni . reLaunch ( { url : url } ) ; break ; case 'navigateBack' : uni . navigateBack ( ) ; break ; case 'navigateTo' : uni . navigateTo ( { url : url } ) ; break ; case 'redirectTo' : uni . redirectTo ( { url : url } ) ; break ; case 'yes' : uni . redirectTo ( { url : url } ) ; break ; default : uni . navigateTo ( { url : url } ) ; break ; } } /**
     * 统一点击方法 cmapp.isToAuth
     // 对应 以下参数 func，当类型function时授权之后返回到上一页执行一次func
     */ isToAuth ( page , navigateType , func ) { const cmapp = this ; const wxinfo = cmapp . getStorage ( 'userInfo' ) ; const nb = 'navigateBack' ; let nt = navigateType ; if ( wxinfo && wxinfo . openid ) { if ( nt === nb && typeof func === 'function' ) { func ( ) ; return ; } cmapp . jumpTo ( page , navigateType ) ; } else { if ( nt === nb && typeof func === 'function' ) { cmapp . authCallBack = func ; } if ( ! nt ) { nt = 'redirectTo' ; } const shareUrl = encodeURIComponent ( page ) ; const authUrl = `/pages/index?shareUrl=${ shareUrl }&navigateType=${ nt }` ; cmapp . jumpTo ( authUrl , 'navigateTo' ) ; } } /**
     * 执行cmapp.isToAuth中参数func的方法
     * 需要在执行了cmapp.isToAuth方法时的页面onShow中加 this.$cmapp.getAuthCallBack();
     */ getAuthCallBack ( ) { const cmapp = this ; const isCallBack = cmapp . getStorage ( 'isCallBack' ) ; if ( typeof cmapp . authCallBack === 'function' && isCallBack && isCallBack === 'yes' ) { cmapp . authCallBack ( ) ; cmapp . authCallBack = '' ; cmapp . removeStorage ( 'isCallBack' ) ; } else if ( isCallBack === 'yes' ) { cmapp . authCallBack = '' ; cmapp . removeStorage ( 'isCallBack' ) ; } } /**
     小程序登录获取code
     */ getCode ( ) { let code = null ; return new Promise ( ( resolve , reject ) => { uni . login ( { success : async ( res ) => { if ( res . code ) { code = res . code ; } resolve ( code ) ; } , fail : async ( ) => { reject ( code ) ; } , } ) ; } ) ; } param key param func1 param func2 returns { Promise < void > } async checkLogin ( key , func1 , func2 ) { const cmapp = this ; const storageValue = cmapp . getStorage ( key ) ; if ( storageValue ) { await func1 ( ) ; } else { await func2 ( ) ; } } param t param code param func returns { Promise < void > } async getOpenid ( $vue , code ) { const cmapp = this ; return new Promise ( async ( resolve ) => { const responseData = await $vue . $uniAjax . http ( $vue . $api . sign . getUserId , { apptype : $vue . $config . project . type , plat : $vue . $config . platform , code : code , } , { method : 'POST' , } ) ; const openid = responseData . isSuccess && responseData . data && responseData . data . list && responseData . data . list . openid || null ; openid && cmapp . setStorage ( 'openid' , openid ) ; ! openid && cmapp . removeStorage ( 'openid' ) ; resolve ( openid ) ; } ) ; } param t param info param func returns { Promise < void > } saveUserInfo ( t , info , func ) { const cmapp = this ; info . platform = t . $config . platform ; info . apptype = t . $config . project . type ; info . openid = info . openid ? info . openid : t . $cmapp . getStorage ( 'openid' ) ; t . $uniAjax . http ( t . $api . sign . saveUserInfo , info , { method : 'POST' , } , ( isSuc , res ) => { t . $store . dispatch ( 'setUserInfo' , info ) ; cmapp . setStorage ( 'userInfo' , info ) ; let d = null ; if ( isSuc ) { d = res . data ; } if ( typeof func === 'function' ) { func ( d ) ; } } , 'no' ) ; } param t param isTs authToPage ( t , isTs = 'no' , time ) { const cmapp = this ; let url = `/pages/${ t . $config . project . type }/index` ; const shareUrl = cmapp . getStorage ( 'shareUrl' ) ; if ( shareUrl ) { url = decodeURIComponent ( shareUrl ) ; } if ( t . navigateType === 'navigateBack' ) { cmapp . setStorage ( 'isCallBack' , 'yes' ) ; } if ( isTs === 'no' ) { cmapp . jumpTo ( url , t . navigateType ) ; return ; } let timeOut = 2000 ; if ( time ) { timeOut = time ; } setTimeout ( ( ) => { cmapp . jumpTo ( url , t . navigateType ) ; } , timeOut ) ; } param query param k returns { Promise < void > } getUrlParams ( t , query , k ) { const cmapp = this ; if ( query && query [ k ] ) { cmapp . setStorage ( k , decodeURIComponent ( query [ k ] ) ) ; } else { cmapp . removeStorage ( k ) ; } } param t param isAuth param query param func returns { Promise < void > } async noAuthIndex ( t , isAuth = 'no' , query , func ) { const cmapp = this ; uni . showLoading ( { title : '数据加载中..' } ) ; await cmapp . getUrlParams ( t , query , 'scene' ) ; await cmapp . getUrlParams ( t , query , 'shareId' ) ; await cmapp . getUrlParams ( t , query , 'shareUrl' ) ; await cmapp . getUrlParams ( t , query , 'returnUrl' ) ; if ( query && query . navigateType ) { t . navigateType = query . navigateType ; } const d = async ( ) => { uni . hideLoading ( ) ; t . isLoadEnd = 1 ; let shareUrl = cmapp . getStorage ( 'shareUrl' ) ; const userInfo = cmapp . getStorage ( 'userInfo' ) ; if ( userInfo ) { t . $store . dispatch ( 'setUserInfo' , userInfo ) ; await t . $cmapp . saveUserInfo ( t , userInfo ) ; } if ( isAuth === 'yes' ) { if ( userInfo && shareUrl ) { cmapp . authToPage ( t , 'no' ) ; return ; } if ( typeof func === 'function' ) { func ( ) ; } return ; } if ( shareUrl ) { shareUrl = decodeURIComponent ( shareUrl ) ; cmapp . jumpTo ( shareUrl , query . navigateType || '' ) ; } if ( typeof func === 'function' ) { func ( ) ; } } ; cmapp . checkLogin ( 'openid' , ( ) => { d ( ) ; } , async ( ) => { cmapp . getCode ( ) . then ( ( code ) => { cmapp . getOpenid ( t , code ) . then ( ( ) => { d ( ) ; } ) ; } ) ; } ) ; } /**
     * PopWin.vue关闭窗口
     */ closePop ( t , time = 1 , func ) { setTimeout ( ( ) => { t . popIsShow = 'no' ; if ( typeof func === 'function' ) { func ( ) ; } } , time * 1000 ) ; } param t param d param sharePage param shareIndex param shareTitle param shareUrl returns { { path : ( * | string ) , title : ( string | * ) } } setShareMessage ( t , d ) { const cmapp = this ; let path = d . sharePage ; const userInfo = cmapp . getStorage ( 'userInfo' ) ; if ( ! userInfo ) { path = d . shareIndex ? `${ d . shareIndex }` : `/pages/${ t . $config . project . dir }/index` ; } path += path . includes ( '?' ) ? '&' : '?' ; path += `shareId=${ cmapp . getStorage ( 'openid' ) ? cmapp . getStorage ( 'openid' ) : '' }` ; path += `&scene=${ cmapp . getStorage ( 'scene' ) ? cmapp . getStorage ( 'scene' ) : '' }` ; if ( d . shareUrl ) { path += `&shareUrl=${ encodeURIComponent ( d . shareUrl ) }` ; } const title = d . shareTitle ? `${ d . shareTitle }` : t . $config . project . name ; return { title : title , path : path , } ; } /**
     * 支付宝 设置主题颜色
     */ setNavigationBarColor ( ) { const bgColor = '#1890FF' ; const txtColor = '#FFFFFF' ; uni . setNavigationBarColor ( { frontColor : txtColor , backgroundColor : bgColor , animation : { duration : 400 , timingFunc : 'easeIn' , } , } ) ; } notFound ( ) { uni . onPageNotFound ( ( res ) => { uni . showToast ( { title : '页面出错，自动到首页' , icon : 'none' , } ) ; let q = '' ; if ( res . query && res . query . scene ) { const scene = decodeURIComponent ( res . query . scene ) ; q = `?scene=${ scene }` ; } setTimeout ( ( ) => { uni . redirectTo ( { url : `/pages/index${ q }` } ) ; } , 2000 ) ; } ) ; } param path param url param type goToWindow ( url , type ) { this . setStorage ( 'h5url' , url ) ; this . jumpTo ( '/pages/common/h5' , '' , '' ) ; const w = window ; if ( type === 'email' ) { w . location = `mailto:${ url }` ; return ; } w . location = url ; uni . showToast ( { title : '请打开aiplat.com查看' , icon : 'none' , } ) ; } tsCity ( cityName ) { const lastStr = cityName . substr ( cityName . length - 1 ) ; const filterWords = [ '市' , '区' , '县' ] ; if ( filterWords . includes ( lastStr ) && cityName . length > 2 ) { cityName = cityName . slice ( 0 , - 1 ) ; } return cityName ; } lessThan10 ( num ) { return num < 10 ? `0${ num }` : num ; } nowTime ( type , dateTime , format , isMillisecond ) { let nowTime = null ; let value = null ; if ( dateTime ) { nowTime = new Date ( dateTime ) ; } else { nowTime = new Date ( ) ; } if ( type === 0 ) { const v = nowTime . valueOf ( ) / 1000 ; if ( isMillisecond ) { return nowTime . valueOf ( ) ; } value = parseInt ( v , 10 ) ; } else { const y = nowTime . getFullYear ( ) ; const m = this . lessThan10 ( nowTime . getMonth ( ) + 1 ) ; const d = this . lessThan10 ( nowTime . getDate ( ) ) ; const h = this . lessThan10 ( nowTime . getHours ( ) ) ; const m2 = this . lessThan10 ( nowTime . getMinutes ( ) ) ; const s = this . lessThan10 ( nowTime . getSeconds ( ) ) ; switch ( format ) { case 1 : value = `${ y }-${ m }-${ d } ${ h }:${ m2 }:${ s }` ; break ; case 2 : value = `${ y }/${ m }/${ d } ${ h }:${ m2 }:${ s }` ; break ; case 3 : value = `${ y }/${ m }/${ d }` ; break ; case 4 : value = `${ y }/${ m }` ; break ; case 5 : value = `${ m }/${ d }` ; break ; case 6 : value = `${ y }-${ m }-${ d }` ; break ; case 7 : value = `${ y }-${ m }` ; break ; case 8 : value = `${ m }-${ d }` ; break ; case 9 : value = `${ h }:${ m2 }:${ s }` ; break ; case 10 : value = `${ y }年${ m }月${ d }日` ; break ; case 11 : value = `${ y }-${ m }-${ d } ${ h }:${ m2 }` ; break ; case 12 : value = `${ y }/${ m }/${ d } ${ h }:${ m2 }` ; break ; case 13 : value = `${ y }年${ m }月${ d }日 ${ h }:${ m2 }` ; break ; default : value = `${ y }-${ m }-${ d }` ; break ; } } return value ; } /**
     * 倒计时(进度条显示的时间)
     */ countDownTime ( time , type , isFan ) { let nowTime = new Date ( ) . valueOf ( ) ; let jdt = 0 ; const arr = [ 3600 , 24 , 60 , 10 ] ; let time2 = time ; if ( isFan ) { const a = nowTime ; nowTime = time2 ; time2 = a ; } if ( time2 && time2 > nowTime ) { const v1 = ( time2 - nowTime ) / ( arr [ 3 ] * arr [ 3 ] * arr [ 3 ] ) ; const n = parseInt ( v1 , arr [ 3 ] ) ; const v2 = n / ( arr [ 0 ] * arr [ 1 ] ) ; const day = parseInt ( v2 , arr [ 3 ] ) ; const v3 = ( ( n - day * arr [ 0 ] * arr [ 1 ] ) / arr [ 0 ] ) ; const hour = parseInt ( v3 , arr [ 3 ] ) ; const v4 = ( ( n - day * arr [ 0 ] * arr [ 1 ] - hour * arr [ 0 ] ) / arr [ 2 ] ) ; const minutes = parseInt ( v4 , arr [ 3 ] ) ; const seconds = n - day * arr [ 0 ] * arr [ 1 ] - hour * arr [ 0 ] - minutes * arr [ 2 ] ; jdt = `${ day }天${ hour }时${ minutes }分${ seconds }秒` ; if ( day <= 0 ) { if ( type === 1 ) { jdt = `${ hour }时${ minutes }分${ seconds }秒` ; } if ( hour <= 0 && type === 2 ) { jdt = `${ minutes }分${ seconds }秒` ; } } if ( type === 3 ) { jdt = { day : day , hour : hour , minutes : minutes , seconds : seconds , } ; } } return jdt ; } checkMobile ( value ) { let reg = '^[1][3,4,5,6,7,8,9][0-9]{9}$' ; const regExp = new RegExp ( reg ) ; return regExp . test ( value ) ; } isIllegalMobile ( value , txt = '手机号码' ) { let message = [ `${ txt }正确` , `请输入11位${ txt }` , `${ txt }必须为11位数字` , `${ txt }格式为1(3~9)开头` ] ; let illegalId = 0 ; if ( ! value || value . length !== 11 ) { illegalId = 1 ; } else if ( ! this . checkWord ( value , 1 ) ) { illegalId = 2 ; } else if ( ! this . checkMobile ( value ) ) { illegalId = 3 ; } return { illegalId , message : message [ illegalId ] , } ; } param v param type returns { * } checkWord ( value , type ) { let reg = '^[A-Za-z\u4e00-\u9fa5]+$' ; switch ( type ) { case 1 : reg = '^[0-9]+$' ; break ; case 2 : reg = '^[0-9.]+$' ; break ; case 3 : reg = '^[\u4e00-\u9fa5]+$' ; break ; case 4 : reg = '^[A-Za-z]+$' ; break ; case 5 : reg = '^[A-Z]+$' ; break ; case 6 : reg = '^[a-z]+$' ; break ; case 7 : reg = '^[A-Za-z0-9.\u4e00-\u9fa5]+$' ; case 8 : reg = '^[0-9-]+$' ; break ; default : break ; } const regExp = new RegExp ( reg ) ; return regExp . test ( value ) ; } openWxSetting ( func , func2 ) { const cmapp = this ; const a = { success ( ) { cmapp . openWxAuth ( 0 , func , func2 ) ; } , fail ( ) { func2 ( func ) ; } , } ; uni . openSetting ( a ) ; } openWxAuth ( type , func , func2 ) { const cmapp = this ; uni . authorize ( { scope : cmapp . authTypeObj [ cmapp . authType ] . type , success ( res ) { if ( res . data [ cmapp . authTypeObj [ cmapp . authType ] . type ] === 'ok' ) { func ( 0 , func ) ; } else { func2 ( func ) ; } func2 ( func ) ; } , fail ( ) { if ( type === 1 ) { uni . hideLoading ( ) ; uni . showModal ( { title : cmapp . authTypeObj [ cmapp . authType ] . title , content : cmapp . authTypeObj [ cmapp . authType ] . content , success ( res ) { if ( res . confirm ) { cmapp . openWxSetting ( func , func2 ) ; } else if ( res . cancel ) { if ( typeof func === 'function' ) { func ( 1 ) ; } } } , } ) ; } else { func2 ( func ) ; } } , } ) ; } param func param func2 checkWxUserAuth ( func , func2 ) { const cmapp = this ; uni . getSetting ( { success ( res ) { const a = res . authSetting [ cmapp . authTypeObj [ cmapp . authType ] . type ] !== undefined && res . authSetting [ cmapp . authTypeObj [ cmapp . authType ] . type ] !== true ; const b = res . authSetting [ cmapp . authTypeObj [ cmapp . authType ] . type ] === undefined ; const c = JSON . stringify ( res . authSetting ) === '{}' ; let aa = a ; aa = aa || c ; if ( aa ) { cmapp . openWxAuth ( 1 , func , func2 ) ; } else if ( b ) { func2 ( func ) ; } else { func ( 0 , func ) ; } } , } ) ; } getWebGeo ( t , localGeo , func ) { const cmapp = this ; const keyId = Math . round ( Math . random ( ) * ( t . $config . map . keys . length - 1 ) ) ; const d = { location : `${ localGeo . latitude },${ localGeo . longitude }` , ak : t . $config . map . keys [ keyId ] , output : 'json' , coordtype : 'gcj02ll' , latest_admin : 1 , } ; uni . request ( { url : t . $config . map . host + t . $config . map . apis . geocoder , data : d , method : 'GET' , header : { 'content-type' : 'application/json' , } , success : async function ( res ) { if ( res . data && res . data . status === 0 ) { const result = { ... res . data . result } ; const lg = result . addressComponent ; lg . cityName = cmapp . tsCity ( lg . city ) ; lg . lng = localGeo . longitude ; lg . lat = localGeo . latitude ; cmapp . setStorage ( 'localGeo' , lg ) ; } if ( typeof func === 'function' ) { func ( ) ; } } , fail : async ( ) => { if ( typeof func === 'function' ) { func ( ) ; } } , } ) ; } getLocation ( func ) { uni . getLocation ( { type : 'wgs84' , success ( res ) { const localGeo = { longitude : res . longitude , latitude : res . latitude , } ; if ( typeof func === 'function' ) { func ( 2 , localGeo ) ; } } , fail ( ) { if ( typeof func === 'function' ) { func ( 1 ) ; } } , } ) ; } showLoad ( t , type ) { if ( ! t . showLoad || t . showLoad !== 'no' ) { if ( type === 1 ) { uni . showLoading ( { title : '数据加载中..' , } ) ; return ; } if ( type === 0 ) { uni . hideLoading ( ) ; } } } checkLocalGeo ( t , func3 ) { const cmapp = this ; cmapp . showLoad ( t , 1 ) ; cmapp . authType = 0 ; cmapp . checkWxUserAuth ( function ( id , authData ) { if ( id === 1 ) { cmapp . showLoad ( t , 0 ) ; func3 ( ) ; } else if ( id === 2 ) { cmapp . getWebGeo ( t , authData , ( ) => { cmapp . showLoad ( t , 0 ) ; func3 ( ) ; } ) ; } else { const localGeo = cmapp . getStorage ( 'localGeo' ) ; if ( ! localGeo || ( localGeo && ! localGeo . lng ) ) { cmapp . getLocation ( authData ) ; } else { cmapp . showLoad ( t , 0 ) ; func3 ( ) ; } } } , cmapp . getLocation ) ; } param $vue animationReset ( $vue ) { const animation = uni . createAnimation ( { duration : 100 , } ) ; animation . rotate ( 0 ) . step ( ) ; $vue . animationData = animation . export ( ) ; } param $vue param animationAngle param maxRun param duration param callback animationShake ( $vue , animationAngle = - 10 , maxRun = 6 , duration = 500 , callback ) { const $cmapp = this ; const animationRun = uni . createAnimation ( { duration : duration , timingFunction : 'ease' , } ) ; animationRun . rotate ( animationAngle ) . step ( ) ; $vue . animationData = animationRun . export ( ) ; let num = 0 ; const thisShake = setInterval ( ( ) => { num += 1 ; if ( num > maxRun || $vue . animationEnd ) { $vue . animationEnd = false ; $cmapp . animationReset ( $vue ) ; clearInterval ( thisShake ) ; if ( typeof callback === 'function' ) { callback ( ) ; } return ; } animationAngle = - animationAngle ; animationRun . rotate ( animationAngle ) . step ( ) ; $vue . animationData = animationRun . export ( ) ; } , duration + 5 ) ; } param title param icon param duration showToast ( title = '网络出错了' , icon = 'none' , duration = 2000 , position = 'center' ) { return new Promise ( ( resolve ) => { const params = { title , icon , duration , position , mask : true , complete : ( res ) => { setTimeout ( ( ) => { resolve ( res ) ; } , duration ) ; } } ; uni . showToast ( params ) ; } ) ; } param audioUrl param autoplay toPlayAudio ( audioUrl , autoplay = true ) { const $cmapp = this ; return new Promise ( ( resolve , reject ) => { if ( this . innerAudioContext ) { this . innerAudioContext . destroy ( ) ; } this . innerAudioContext = uni . createInnerAudioContext ( ) ; this . innerAudioContext . autoplay = autoplay ; this . innerAudioContext . src = audioUrl ; this . innerAudioContext . play ( ) ; this . innerAudioContext . onPlay ( ( ) => { this . showToast ( '播放成功' ) ; resolve ( { isSuccess : 1 , message : '播放成功' , errCode : 0 , innerAudioContext : $cmapp . innerAudioContext } ) ; } ) ; this . innerAudioContext . onError ( ( responseData ) => { this . showToast ( '播放失败' ) ; reject ( { isSuccess : 0 , message : responseData , errCode : 0 , innerAudioContext : this . innerAudioContext } ) ; } ) ; this . innerAudioContext . onEnded ( ( ) => { this . innerAudioContext . destroy ( ) ; this . showToast ( '播放已结束' ) ; } ) ; this . innerAudioContext . onStop ( ( responseData ) => { this . showToast ( '播放已停止' ) ; } ) ; } ) ; } param isCanvas param id param filePath param callback saveImageToPhotosAlbum ( isCanvas = 'no' , id , filePath , callback ) { const $cmapp = this ; uni . showLoading ( { title : '保存中..' } ) ; let toast = '保存失败' ; const save = ( path ) => { uni . saveImageToPhotosAlbum ( { filePath : path , success ( ) { uni . hideLoading ( ) ; toast = '保存成功' ; $cmapp . showToast ( toast ) ; setTimeout ( ( ) => { if ( typeof callback === 'function' ) { callback ( ) ; } } , 2000 ) ; } , fail ( ) { uni . hideLoading ( ) ; $cmapp . showToast ( toast ) ; } , } ) ; } ; if ( isCanvas === 'no' ) { save ( filePath ) ; return ; } uni . canvasToTempFilePath ( { canvasId : id , success ( responseData ) { save ( responseData . tempFilePath ) ; } , fail ( ) { uni . hideLoading ( ) ; $cmapp . showToast ( toast ) ; } , } ) ; } param ctx param lineheight param bytelength param text param startleft param starttop canvasTextAutoLine ( ctx , lineheight , bytelength , text , startleft , starttop ) { const getTrueLength = ( str ) => { const length = str . length ; let truelen = 0 ; for ( let x = 0 ; x < length ; x ++ ) { if ( str . charCodeAt ( x ) > 128 ) { truelen += 2 ; } else { truelen += 1 ; } } return truelen ; } ; const cutString = ( str , leng ) => { const len = str . length ; let tlen = len ; let nlen = 0 ; for ( let x = 0 ; x < len ; x ++ ) { if ( str . charCodeAt ( x ) > 128 ) { if ( nlen + 2 < leng ) { nlen += 2 ; } else { tlen = x ; break ; } } else { console . log ( ) ; if ( nlen + 1 < leng ) { nlen += 1 ; } else { tlen = x ; break ; } } } return tlen ; } ; for ( let i = 1 ; getTrueLength ( text ) > 0 ; i ++ ) { const tl = cutString ( text , bytelength ) ; ctx . fillText ( text . substr ( 0 , tl ) . replace ( /^\s+|\s+$/ , '' ) , startleft , ( i - 1 ) * lineheight + starttop ) ; text = text . substr ( tl ) ; } } param url param url2 param callback backTo ( url , url2 ) { const currentPages = getCurrentPages ( ) ; const isCurrentPage = currentPages . filter ( ( x ) => x . route === url ) ; return new Promise ( ( resolve ) => { if ( isCurrentPage && isCurrentPage . length > 0 ) { const page = currentPages . length - currentPages . indexOf ( isCurrentPage [ 0 ] ) - 1 ; uni . navigateBack ( { delta : page , } ) ; if ( url2 ) { setTimeout ( ( ) => { uni . navigateTo ( { url : url2 , } ) ; } , 100 ) ; } } resolve ( ) ; } ) ; } openLocation ( latitude , longitude , name , address ) { latitude = parseFloat ( latitude ) ; longitude = parseFloat ( longitude ) ; this . getUniApi ( uni . openLocation , { latitude , longitude , scale : 18 , name , address , } ) . then ( ( responseData ) => { console . log ( responseData ) ; } ) . catch ( ( responseData ) => { console . log ( responseData ) ; } ) ; } onAccelerometerChange ( $vue , url ) { this . getUniApi ( uni . getSystemInfo ) . then ( ( ) => { uni . onAccelerometerChange ( ( e ) => { const pages = getCurrentPages ( ) ; const currentPage = pages [ pages . length - 1 ] ; if ( currentPage . route === url ) { currentPage . $vm . onAccelerometerChange ( e ) ; } } ) ; } ) . catch ( ( responseData ) => { console . log ( responseData ) ; } ) ; } scrollTo ( scrollTop , duration , selector ) { return new Promise < void > ( ( resolve ) => { const params = { scrollTop : scrollTop || 0 , duration : duration || 999 , selector : selector || '' , complete : ( ) => { resolve ( ) ; } } ; uni . pageScrollTo ( params ) ; } ) ; } eventListener ( type , eventName , func ) { if ( ! eventName ) { return ; } if ( type === 'dispatchEvent' ) { const event = new Event ( eventName ) ; event && window . dispatchEvent ( event ) ; return ; } window . addEventListener ( eventName , func ) ; } showInfo ( title , content , showCancel , cancelText , confirmText , confirmColor , completeFunction ) { if ( ! content ) { return ; } uni . showModal ( { title : title || '温馨提示' , content : content , showCancel : showCancel || false , cancelText : cancelText || '取消' , confirmText : confirmText || '确定' , confirmColor : confirmColor || '#ff8b15' , complete : ( res ) => { completeFunction && completeFunction ( res ) ; } } ) ; } getAppType ( ) { if ( ! window ) { return 'miniprogram' ; } const userAgent = window . navigator . userAgent . toLowerCase ( ) ; if ( userAgent && /(android)/i . test ( userAgent ) ) { return 'android' ; } else if ( userAgent && /(iphone|ipad|ipod|ios)/i . test ( userAgent ) ) { return 'ios' ; } else if ( userAgent && /(mobile|micromessenger)/i . test ( userAgent ) ) { return 'mobile' ; } return 'pc' ; } async setEnvironmentInfo ( $vue ) { this . environmentInfo . isMiniprogram = ! window ; this . environmentInfo . isWebview = this . getQuery ( $vue , 'isWebview' ) ? 1 : 0 ; this . environmentInfo . appType = this . getAppType ( ) ; this . environmentInfo . isApp = 1 ; const weixinType = this . getQuery ( $vue , 'weixinType' ) || this . getStorage ( 'weixinType' ) ; if ( weixinType ) { this . setStorage ( 'weixinType' , weixinType ) ; } this . environmentInfo . userAgent = window . navigator . userAgent . toLowerCase ( ) ; this . environmentInfo . isElectron = this . environmentInfo . userAgent . includes ( 'electron' ) ? 1 : 0 ; this . environmentInfo . isWeixin = this . environmentInfo . userAgent . includes ( 'micromessenger' ) ? 1 : 0 ; this . environmentInfo . isWxwork = this . environmentInfo . userAgent . includes ( 'wxwork' ) ? 1 : 0 ; this . environmentInfo . isWechat = ( this . environmentInfo . isWeixin && ! this . environmentInfo . isWxwork ) || this . environmentInfo . userAgent . includes ( 'wechat' ) ? 1 : 0 ; this . environmentInfo . isDevtools = this . environmentInfo . userAgent . includes ( 'wechatdevtools' ) ? 1 : 0 ; this . environmentInfo . isApp = this . environmentInfo . userAgent . includes ( 'html5plus' ) ? 1 : 0 ; const hvoi = this . environmentInfo . userAgent . includes ( 'huawei' ) || this . environmentInfo . userAgent . includes ( 'vivo' ) || this . environmentInfo . userAgent . includes ( 'oppo' ) || this . environmentInfo . userAgent . includes ( 'iphone' ) ; this . environmentInfo . isHvoi = hvoi ? 1 : 0 ; if ( weixinType === 'wechat' ) { this . environmentInfo . isWechat = 1 ; this . environmentInfo . isWxwork = 0 ; } if ( weixinType === 'wxwork' ) { this . environmentInfo . isWechat = 0 ; this . environmentInfo . isWxwork = 1 ; } $vue . $forceUpdate ( ) ; } } export default cmappClass ;