123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- import { Report } from "./report.uts";
- import { StatType } from "./stat-type";
- import { EventParams, UniStatOptions, ErrorCallback, ReportErrorCode } from '../../interface.uts'
- import { is_page, is_page_report, get_space, is_push_clientid, calibration,get_crash_logs } from '../utils/pageInfo.uts'
- import { Config } from "../config";
- export class Stat {
- static __stat_instance : Stat | null = null;
- static is_register : boolean = false
- static no_space : boolean = false
- // 上报逻辑实例
- report : Report;
- // 使用单例,只初始化一次
- static getInstance() : Stat {
- // 获取服务空间配置信息
- let space = get_space(uniCloud.config)
- if (Report.uniCloudInstance == null) {
- // 判断不为空对象
- if (space != null) {
- // 重新构造 uniCloud
- let spaceData : UniCloudInitOptions = {
- provider: space.provider,
- spaceId: space.spaceId,
- clientSecret: space.clientSecret,
- }
- const endpoint = space.endpoint
- if (endpoint != null) {
- spaceData.endpoint = space.endpoint
- }
- // 支付宝单独处理一些参数
- if (space.provider == 'alipay') {
- spaceData.secretKey = space.secretKey
- spaceData.accessKey = space.accessKey
- spaceData.spaceAppId = space.spaceAppId
- }
- // 初始化 uniCloud
- // @ts-ignore
- Report.uniCloudInstance = uniCloud.init(spaceData)
- } else {
- if (!Stat.no_space) {
- // #ifdef APP-IOS
- console.error('应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间')
- // #endif
- // #ifndef APP-IOS
- console.log("\u001b[31m应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间\u001b[0m")
- // #endif
- Stat.no_space = true
- }
- }
- }
- // 实例化统计sdk ,要在 实例 unicloud 之后进行,避免 Report 无法拿到 uniCloud 实例
- if (this.__stat_instance == null) {
- this.__stat_instance = new Stat()
- }
- return this.__stat_instance as Stat
- }
- // 当前生命周期内的页面或应用实例
- appInstance ?: Page | null = null
- private isHide : boolean = false
- constructor() {
- this.report = new Report()
- }
- /**
- * 初始化插件参数
- * @param {Object} options
- */
- init(options : UTSJSONObject) {
- // 插件挂载玩成,可以进行后续操作
- Stat.is_register = true
- // 参数处理
- Config.setOptions({ ...options } as UniStatOptions)
- const uniStatConfig = Config.getOptions()
- // 设置上报周期时间
- this.report.eportInterval = uniStatConfig.reportInterval ?? 10
- // #ifdef APP
- // 获取崩溃日志
- get_crash_logs((logs)=>{
- this.registerEvent(StatType.Crash, null, logs)
- })
- // #endif
- }
- /**
- * 应用启动
- * @param {OnLaunchOptions} options 应用参数
- * @param {ComponentPublicInstance} appInstance 应用实例
- */
- // options : OnLaunchOptions, appInstance : ComponentPublicInstance
- onLaunch(options : OnLaunchOptions, appInstance : ComponentPublicInstance) {
- // 注册事件 onLaunch ,需要手动触发
- // this.registerEvent(StatType.LifeCycleLaunch, appInstance, options as any)
- }
- /**
- * 页面加载
- * @param {ComponentPublicInstance} appInstance 应用实例
- */
- onLoad(appInstance : Page) {
- this.registerEvent(StatType.LifeCycleLoad, appInstance)
- }
- /**
- * 显示页面或应用进入前台
- * @param {ComponentPublicInstance} appInstance 应用实例
- */
- onShow(appInstance : Page) {
- this.isHide = false
- // @ts-ignore
- const mptype = is_page(appInstance)
- // 页面执行,应用需要手动调用
- if (mptype) {
- this.registerEvent(StatType.LifeCyclePageShow, appInstance, null)
- }
- // const life_type = mptype == 'app' ? StatType.LifeCycleAppShow : StatType.LifeCyclePageShow
- // this.registerEvent(life_type, appInstance, null)
- }
- /**
- * 页面隐藏或应用进入后台
- * @param {ComponentPublicInstance} appInstance 应用实例
- */
- onHide(appInstance : Page) {
- this.isHide = true
- // @ts-ignore
- const mptype = is_page(appInstance)
- // 页面执行,应用需要手动调用
- if (mptype) {
- this.registerEvent(StatType.LifeCyclePageHide, appInstance, null)
- }
- // const life_type = mptype == 'app' ? StatType.LifeCycleAppHide : StatType.LifeCyclePageHide
- // this.registerEvent(life_type, appInstance, null)
- }
- /**
- * 卸载页面
- * @param {ComponentPublicInstance} appInstance 应用实例
- */
- onUnload(appInstance : Page) {
- // 如果 isHide 为true 说明页面隐藏了,不走卸载逻辑,如果走卸载逻辑,isHide 必不可能是true
- if (this.isHide) {
- this.isHide = false
- return
- }
- this.registerEvent(StatType.LifeCyclePageUnLoad, appInstance, null)
- }
- /**
- * 错误
- * @param {String} error 应用实例
- */
- onError(error : string) {
- // 单独处理错误上报
- this.error(error)
- }
- /**
- * 获取推送ID
- */
- // pushEvent(options : any) {
- // // TODO uni x 暂不支持,如需要开启,请放开注释
- // const ClientID = is_push_clientid()
- // if (ClientID) {
- // uni.getPushClientId({
- // success: (res) => {
- // const cid = res.cid
- // // 只有获取到才会上传
- // // if (cid != null) {
- // this.report.sendPushRequest(options, cid)
- // // }
- // },
- // } as GetPushClientIdOptions)
- // }
- // }
- /**
- * 注册事件
- * @param {number} EventType 事件类型
- * @param {Page} appInstance 当前页面实例
- * @param {UTSJSONObject} options 应用参数
- */
- registerEvent(EventType : number, appInstance : Page | null, options : any | null = null, error : any | null = '') {
- this.appInstance = appInstance
- // 是否要上报页面数据
- const isPageReport = is_page_report()
- switch (EventType) {
- case StatType.LifeCycleLaunch:
- // 使用非空断言,options在这里肯定非空
- this.report.launch(options!)
- // this.pushEvent(options)
- break
- case StatType.LifeCycleAppShow:
- // TODO 目前只兼容 web 和 app ,小程序等平台需要调用 api onAppHide
- this.report.appShow()
- break
- case StatType.LifeCycleAppHide:
- this.report.appHide(true)
- break
- case StatType.LifeCycleLoad:
- break
- case StatType.LifeCyclePageShow:
- if (isPageReport) {
- this.report.pageShow(appInstance!)
- }
- break
- case StatType.LifeCyclePageHide:
- if (isPageReport) {
- this.report.pageHide(appInstance!)
- }
- break
- case StatType.LifeCyclePageUnLoad:
- if (isPageReport) {
- this.report.pageHide(appInstance!)
- }
- break
- case StatType.LifeCycleError:
- if (error != null) {
- this.report.appError(error)
- }
- break
- case StatType.Crash:
- this.report.appCrash(options as string[])
- break
- }
- }
- error(em : string) {
- // 生命周期监听,暂时无用,需要手动调用api
- }
- // 自定义参数上报
- appEvent(name : string, options : any | null = null, fn : ErrorCallback) {
- if (Stat.no_space) {
- fn(false, 61000 as ReportErrorCode)
- return
- }
- if (!Stat.is_register) {
- fn(false, 61001 as ReportErrorCode)
- return
- }
- // const names = ['uni-app-launch', 'uni-app-show', 'uni-app-hide', 'uni-app-error']
- // if (names.indexOf(name) <= -1) {
- // // console.error('uniStatReport 事件名不存在,请检查!');
- // fn(false, 'uniStatReport 事件名不存在,请检查!')
- // return
- // }
- if (name == 'uni-app-launch' && options == null) {
- fn(false, 61002 as ReportErrorCode)
- return
- }
- if (name == 'uni-app-launch') {
- this.registerEvent(StatType.LifeCycleLaunch, null, options)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- return
- }
- if (name == 'uni-app-show') {
- this.registerEvent(StatType.LifeCycleAppShow, null, null)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- return
- }
- if (name == 'uni-app-hide') {
- this.registerEvent(StatType.LifeCycleAppHide, null, null)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- return
- }
- if (name == 'uni-page-show') {
- this.report.pageShow(options as Page)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- return
- }
- if (name == 'uni-page-hide') {
- this.report.pageHide(options as Page)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- return
- }
- if (name == 'uni-app-error') {
- this.registerEvent(StatType.LifeCycleError, null, null, options)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- return
- }
- // 校验 type 参数
- const is_calibration = calibration(name, options)
- if (is_calibration != null) {
- fn(false, is_calibration)
- return
- }
- if (name === 'title') {
- this.report._navigationBarTitle.report = (options as string)
- }
- const value = (typeof options === 'object' ? JSON.stringify(options) : options) as string
- const data : EventParams = {
- key: name,
- value: value as string,
- }
- this.report.sendEventRequest(data)
- // 61001 占位,无实际用途
- fn(true, 61001 as ReportErrorCode)
- }
- }
|