import { OnLaunchOptionsWithCst, RouteParams, StatDefault, ReportErrorCode } from '../../interface.uts' import { STAT_VERSION, sys, sysAppBase, Config } from '../config.uts' // import Config from '../config.uts' import { get_time } from './pageTime.uts' import { dbGet, dbSet } from './db.uts' import { Serialize, IsNumber } from './index.uts' const APPID = sys.appId const RUNTIME_VERSION = sys.appVersion /** * 获取uuid */ export const get_uuid = () : string => { // 有可能不存在 deviceId(一般不存在就是出bug了),就自己生成一个 // 目前 deviceId 肯定存在所以不用生成 // const uuid : string = sys.deviceId ?? getUuid() return sys.deviceId } /** * 获取老版的 deviceid ,兼容以前的错误 deviceid */ export const get_odid = () : string => { // let odid : string // if (get_platform_name() === 'n') { // try { // odid = plus.device.uuid // } catch (e) { // odid = '' // } // return odid // } // odid = sys.deviceId ?? getUuid() // TODO 需要获取老版本的uuid ,目前无法获取,只返回 deviceId return sys.deviceId } /** * 获取当前平台 * 移动端 : 'n', * h5 : 'h5', * 微信 : 'wx', * 阿里 : 'ali', * 百度 : 'bd', * 头条 : 'tt', * qq : 'qq', * 快应用 : 'qn', * 快手 : 'ks', * 飞书 : 'lark', * 快应用 : 'qw', * 钉钉 : 'dt' */ export const get_platform_name = () : string => { let platformList = { 'app': 'n', 'app-plus': 'n', 'h5': 'h5', 'web': 'web', 'mp-weixin': 'wx', 'mp-baidu': 'bd', 'mp-toutiao': 'tt', 'mp-qq': 'qq', 'quickapp-native': 'qn', 'mp-kuaishou': 'ks', 'mp-lark': 'lark', 'quickapp-webview': 'qw', } // 苹果审核代码中禁止出现 alipay 字样 ,需要特殊处理一下 const aliArr = ['y', 'a', 'p', 'mp-ali'] const aliKey = aliArr.reverse().join('') platformList[aliKey] = 'ali' const platform = sys.uniPlatform // TODO 兼容子平台 // if (platformList[process.env.VUE_APP_PLATFORM] === 'ali') { // if (my && my.env) { // const clientName = my.env.clientName // if (clientName === 'ap') return 'ali' // if (clientName === 'dingtalk') return 'dt' // // TODO 缺少 ali 下的其他平台 // } // } return platformList[platform] as string } /** * 获取原生包名,或小程序 appid */ export const get_pack_name = () : string => { let packName = '' if (get_platform_name() === 'n') { if (sys.osName == 'android') { packName = sysAppBase.packageName ?? '' } if (sys.osName == 'ios') { packName = sysAppBase.bundleId ?? '' } } return packName } /** * 应用版本 */ export const get_version = () : string => { return RUNTIME_VERSION } /** * 获取渠道 */ export const get_channel = () : string => { const platformName = get_platform_name() let channel : string = '' if (platformName === 'n') { channel = sysAppBase.channel ?? '' } // if (platformName === 'wx') { // // TODO 需要调研小程序二维码渠道如何获取; // } return channel } /** * 获取小程序场景值 */ export const get_scene = (options : OnLaunchOptionsWithCst) : number => { // const platformName = get_platform_name() let scene = 1001 if (options.scene != null) { return options.scene ?? 1001 } // if (platformName == 'wx') { // // @ts-ignore // scene = uni.getLaunchOptionsSync()?.scene ?? 1001 // } return scene } /** * 是否获取 page 页面 * @param {VueComponent} appInstance 页面实例 */ // @ts-ignore export const is_page = (appInstance : ComponentPublicInstance) : Boolean => { // #ifdef WEB || APP-IOS || MP-WEIXIN const type = appInstance?.$mpType ?? 'page' return type == 'page' ? true : false // #endif // #ifndef WEB || APP-IOS || MP-WEIXIN // 其他平台没有 $mpType ,只有页面触发 return true // #endif } /** * 获取页面标题 * @param {String} routepath 页面路由 */ export const get_page_name = (routepath : string) : string => { let page = get_page_vm() if (page == null) return '' let route : string // #ifdef MP-WEIXIN route = (page.$scope && page.$scope.route) ?? "" // #endif // #ifndef MP-WEIXIN route = page.route // #endif if (route != routepath) { const pages = getCurrentPages() // 如果传入路由与当前页面不同,则从页面栈找一个,如果找不到返回空 let page_now = pages.find((p) : boolean => p.route == routepath) if (page_now == null) { return '' } // @ts-ignore page = page_now.vm! } let titleText : string // #ifdef MP-WEIXIN // @ts-ignore const title_json = process.env.UNI_STAT_TITLE_JSON titleText = title_json[route] ?? '' // #endif // #ifndef MP-WEIXIN // @ts-ignore const pageStyle = (page.$page as UniPage).getPageStyle() titleText = (pageStyle['navigationBarTitleText'] as string) // #endif return titleText as string } /** * 获取页面实例 */ export const get_page_vm = () : Page | null => { let pages = getCurrentPages() if (pages.length == 0) { return null } let page = pages[pages.length - 1] // TODO 正常来说,调用当前方法的地方只在 生命周期内,数组内最少会有一个页面,所以理论上是不存在获取不到的情况的 // @ts-ignore return page.vm } /** * 获取页面url,不包含参数 * @param {ComponentPublicInstance} page 页面实例 */ export function get_route(page : Page | null = null) : RouteParams { let _self = page ?? get_page_vm() if (_self == null) { const data : RouteParams = { path: '', fullpath: '' } return data } let url_params : string let options : any // #ifdef MP-WEIXIN options = _self.$scope.options // #endif // #ifndef MP-WEIXIN options = _self.options // #endif // TODO 条件编译处理参数问题,安卓上 options返回的是map,需要处理成 utsobject // #ifdef APP-ANDROID const opts = new UTSJSONObject(options) // TODO 上报页面参数需要处理 url_params = Serialize(opts) // #endif // #ifndef APP-ANDROID // @ts-ignore url_params = Serialize(options) // #endif let params = '' // 如果参数只有 ?则说明没有参数 if (url_params != '?') { params = url_params } // 兼容不同小程序下的不同取值 let route : string // #ifdef MP-WEIXIN route = (_self.$scope && _self.$scope.route) ?? "" // #endif // #ifndef MP-WEIXIN route = _self.route // #endif const data : RouteParams = { path: route, fullpath: route + params } return data } /** * 获取页面url, 包含参数 ,暂时不用,合并到 get_route * @param {ComponentPublicInstance} page 页面实例 */ export function get_page_route(page : Page | null = null) : string { let _self = page ?? get_page_vm() let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE') if (_self == null) { return lastPageRoute ?? '' } // 如果找不到 fullPath 就取 route 的值 // TODO 取完整路径,目前最新为 optiosn 为携带参数,需要手动序列化 // return page.fullPath === '/' ? page.route : page.fullPath || page.route return _self.route } /** * 是否上报页面数据 * @returns */ export const is_page_report = () : boolean => { const uniStatConfig = Config.getOptions(); const collectItems = uniStatConfig.collectItems; if (collectItems != null) { const statPageLog = collectItems.uniStatPageLog if (statPageLog == null) return true return typeof statPageLog == 'boolean' ? statPageLog : true } return true } /** * 是否已处理设备 DeviceId * 如果值为 1 则表示已处理 */ const IS_HANDLE_DEVECE_ID = 'is_handle_device_id' export const is_handle_device = () : boolean => { let isHandleDevice = dbGet(IS_HANDLE_DEVECE_ID) ?? '' dbSet(IS_HANDLE_DEVECE_ID, '1') return isHandleDevice === '1' } /** * 获取上报数据默认值 */ export const get_default_data = () : StatDefault => { let statData : StatDefault = { uuid: get_uuid(), ak: APPID, p: sys.osName == 'android' ? 'a' : 'i', ut: get_platform_name(), mpn: get_pack_name(), usv: STAT_VERSION, v: RUNTIME_VERSION, ch: get_channel(), cn: '', pn: '', ct: '', t: get_time(), tt: '', brand: sys.deviceBrand, md: sys.deviceModel, sv: sys.osVersion.replace(/(Android|iOS)\s/, ''), mpsdk: sys.SDKVersion, mpv: sys.uniCompilerVersionCode.toString(), // mpv: '', lang: sys.osLanguage, pr: sys.devicePixelRatio, ww: sys.windowWidth, wh: sys.windowHeight, sw: sys.screenWidth, sh: sys.screenHeight, lat: '', lng: '', net: '', odid: '' } return statData } /** * 获取上报时间间隔 * @param {*} defaultTime 默认上报间隔时间 单位s */ export const get_report_Interval = (defaultTime : number) : number => { const uniStatConfig = Config.getOptions() let time = uniStatConfig.reportInterval // let reg = /(^[1-9]\d*$)/ // 如果不是整数,则默认为上报间隔时间 // if (!reg.test(time)) return defaultTime if (!IsNumber(time)) return defaultTime // 如果上报时间配置为0 相当于立即上报 if (time == 0) return 0 // time = time ?? defaultTime return time as number } /** * 获取uniCloud服务空间配置 * @returns {Object} */ export const uni_cloud_config = () : UniCloudInitOptions | null => { // TODO 当前版本暂时不使用 // return process.env.UNI_STAT_UNI_CLOUD || {} return null } /** * 获取服务空间 * @param {*} config * @returns */ export const get_space = (config : UniCloudInitOptions) : UniCloudInitOptions | null => { const uniCloudConfig = uni_cloud_config() if (uniCloudConfig == null) { // #ifdef APP-ANDROID if (config.spaceId != '') { return config } // #endif // #ifndef APP-ANDROID if (config?.spaceId != '') { return config } // #endif return null } let spaceId = uniCloudConfig.spaceId let provider = uniCloudConfig.provider let clientSecret = uniCloudConfig.clientSecret let secretKey = uniCloudConfig.secretKey let accessKey = uniCloudConfig.accessKey const space_type = ['tcb', 'tencent', 'aliyun', 'alipay'] // @ts-ignore const is_space_id = spaceId != '' const is_provider = space_type.indexOf(provider) != -1 const is_aliyun = provider == 'aliyun' && is_space_id && clientSecret != null const is_tcb = (provider == 'tcb' || provider === 'tencent') && is_space_id const is_alipay = provider == 'alipay' && is_space_id && secretKey != null && accessKey != null if (is_provider && (is_aliyun || is_tcb || is_alipay)) { return uniCloudConfig } return null } /** * 获取隐私协议配置 */ export const is_push_clientid = () : boolean => { const uniStatConfig = Config.getOptions() const collectItems = uniStatConfig.collectItems if (collectItems != null) { const ClientID = collectItems.uniPushClientID ?? false return typeof ClientID == 'boolean' ? ClientID : false } return false } /** * 自定义事件参数校验 */ export const calibration = (eventName : string, options : any | null) : ReportErrorCode | null => { // login 、 share 、pay_success 、pay_fail 、register 、title if (eventName == '') { // console.error(`uni.report Missing [eventName] parameter`) return 61003 } if (typeof eventName != 'string') { // console.error( // `uni.report [eventName] Parameter type error, it can only be of type String` // ) return 61004 } if (eventName.length > 255) { // console.error( // `uni.report [eventName] Parameter length cannot be greater than 255` // ) return 61005 } if (typeof options != 'string' && typeof options != 'object') { // console.error( // 'uni.report [options] Parameter type error, Only supports String or Object type' // ) return 61006 } if (typeof options == 'string' && (options as string).length > 255) { // console.error( // `uni.report [options] Parameter length cannot be greater than 255` // ) return 61007 } if (eventName == 'title' && typeof options != 'string') { // console.error( // `uni.report [eventName] When the parameter is title, the [options] parameter can only be of type String` // ) return 61008 } return null }