提交 e4ffc1b7 编写于 作者: M mehaotian

fix: 统计新增错误类型,优化错误输出逻辑

上级 5ad27668
......@@ -45,8 +45,7 @@
// )
// observer1.observe({
// entryTypes: ['render', 'navigation'],
// } as PerformanceObserverOptions)
// } as PerformanceObserverOptions)
// 统计上报 - 应用启动
// #ifdef APP-ANDROID || APP-IOS || WEB
// uni.report({
......
......@@ -6,23 +6,23 @@ const stat_instance = Stat.getInstance()
const lifecycle = defineMixin({
// onLaunch(options : OnLaunchOptions) { stat_instance.onLaunch(options, this) },
// @ts-ignore
onLoad() {
// @ts-ignore
onLoad() {
// @ts-ignore
stat_instance.onLoad(this)
},
// @ts-ignore
onShow() {
// @ts-ignore
onShow() {
// @ts-ignore
stat_instance.onShow(this)
},
// @ts-ignore
onHide() {
// @ts-ignore
onHide() {
// @ts-ignore
stat_instance.onHide(this)
},
// @ts-ignore
onUnload() {
// @ts-ignore
onUnload() {
// @ts-ignore
stat_instance.onUnload(this)
},
// onError(error : string) { stat_instance.onError(error) }
......@@ -30,7 +30,9 @@ const lifecycle = defineMixin({
export const uniStat = definePlugin({
install(app : VueApp, options : UTSJSONObject) {
install(app : VueApp, options : UTSJSONObject) {
// 未关联服务空间
if (Stat.no_space) return
stat_instance.init(options)
app.mixin(lifecycle)
}
......
import { Report } from "./report.uts";
import { StatType } from "./stat-type";
import { EventParams, UniStatOptions, ErrorCallback,ReportErrorCode } from '../../interface.uts'
import { EventParams, UniStatOptions, ErrorCallback, ReportErrorCode } from '../../interface.uts'
import { is_page, is_page_report, get_space, is_push_clientid, calibration } from '../utils/pageInfo.uts'
import { Config } from "../config";
export class Stat {
static __stat_instance : Stat | null = null;
static is_register : boolean = false
// 上报逻辑实例
report : Report;
// 使用单例,只初始化一次
static getInstance() : 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
}
// 获取服务空间配置信息
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
}
// 支付宝单独处理一些参数
if (space.provider == 'alipay') {
spaceData.secretKey = space.secretKey
spaceData.accessKey = space.accessKey
spaceData.spaceAppId = space.spaceAppId
}
// 初始化 uniCloud
// @ts-ignore
Report.uniCloudInstance = uniCloud.init(spaceData)
// 初始化 uniCloud
// @ts-ignore
Report.uniCloudInstance = uniCloud.init(spaceData)
} else {
if (!Stat.no_space) {
// #ifdef WEB
console.log('\x1b[31m应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间\x1b[39m')
// #endif
// #ifndef WEB
console.error('应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间')
// #endif
Stat.no_space = true
}
}
}
} else {
console.error('应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间')
}
}
// 实例化统计sdk ,要在 实例 unicloud 之后进行,避免 Report 无法拿到 uniCloud 实例
if (this.__stat_instance == null) {
this.__stat_instance = new Stat()
}
// 实例化统计sdk ,要在 实例 unicloud 之后进行,避免 Report 无法拿到 uniCloud 实例
if (this.__stat_instance == null) {
this.__stat_instance = new Stat()
}
return this.__stat_instance as Stat
}
return this.__stat_instance as Stat
}
// 当前生命周期内的页面或应用实例
appInstance ?: Page | null = null
// 当前生命周期内的页面或应用实例
appInstance ?: Page | null = null
private isHide : boolean = false
constructor() {
this.report = new Report()
}
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
/**
* 初始化插件参数
* @param {Object} options
*/
init(options : UTSJSONObject) {
// 插件挂载玩成,可以进行后续操作
Stat.is_register = true
}
/**
* 应用启动
* @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)
}
// 参数处理
Config.setOptions({ ...options } as UniStatOptions)
const uniStatConfig = Config.getOptions()
// 设置上报周期时间
this.report.eportInterval = uniStatConfig.reportInterval ?? 10
/**
* 页面隐藏或应用进入后台
* @param {ComponentPublicInstance} appInstance 应用实例
*/
onHide(appInstance : Page) {
}
/**
* 应用启动
* @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
this.isHide = true
// @ts-ignore
const mptype = is_page(appInstance)
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)
}
// 页面执行,应用需要手动调用
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 应用实例
*/
onHide(appInstance : Page) {
/**
* 卸载页面
* @param {ComponentPublicInstance} appInstance 应用实例
*/
onUnload(appInstance : Page) {
// 如果 isHide 为true 说明页面隐藏了,不走卸载逻辑,如果走卸载逻辑,isHide 必不可能是true
if (this.isHide) {
this.isHide = false
return
}
this.registerEvent(StatType.LifeCyclePageUnLoad, appInstance, null)
}
this.isHide = true
// @ts-ignore
const mptype = is_page(appInstance)
/**
* 错误
* @param {String} error 应用实例
*/
onError(error : string) {
// 单独处理错误上报
this.error(error)
}
// 页面执行,应用需要手动调用
if (mptype) {
this.registerEvent(StatType.LifeCyclePageHide, appInstance, null)
}
// const life_type = mptype == 'app' ? StatType.LifeCycleAppHide : StatType.LifeCyclePageHide
// this.registerEvent(life_type, appInstance, null)
}
/**
* 获取推送ID
*/
pushEvent(options : any) {
// TODO 具体实现
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 {ComponentPublicInstance} appInstance 应用实例
*/
onUnload(appInstance : Page) {
// 如果 isHide 为true 说明页面隐藏了,不走卸载逻辑,如果走卸载逻辑,isHide 必不可能是true
if (this.isHide) {
this.isHide = false
return
}
this.registerEvent(StatType.LifeCyclePageUnLoad, appInstance, null)
}
/**
* 注册事件
* @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
}
}
/**
* 错误
* @param {String} error 应用实例
*/
onError(error : string) {
// 单独处理错误上报
this.error(error)
}
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
}
/**
* 获取推送ID
*/
pushEvent(options : any) {
// TODO 具体实现
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)
}
}
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
}
/**
* 注册事件
* @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
}
}
if (name == 'uni-page-show') {
this.report.pageShow(options as Page)
// 61001 占位,无实际用途
fn(true, 61001 as ReportErrorCode)
return
}
error(em : string) {
// 生命周期监听,暂时无用,需要手动调用api
}
// 自定义参数上报
appEvent(name : string, options : any | null = null, fn : ErrorCallback) {
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-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
}
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
}
// 校验 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)
}
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)
}
const value = (typeof options === 'object' ? JSON.stringify(options) : options) as string
const data : EventParams = {
key: name,
value: value as string,
}
this.report.sendEventRequest(data)
}
}
......@@ -7,7 +7,6 @@ const stat = Stat.getInstance()
export const report : Report = function (options : ReportOptions) {
const name = options.name
const option = options.options
//创建一个UniError
stat.appEvent(name, option, (type : boolean, code : ReportErrorCode) => {
if (type) {
const res : ReportSuccess = {
......@@ -25,4 +24,4 @@ export const report : Report = function (options : ReportOptions) {
export { Stat } from './common/core/stat.uts'
// --- 导出统计类型 ---
export { UniStatOptions, UniStatCollectItemsOptions, ReportFail } from './interface.uts'
\ No newline at end of file
export { UniStatOptions, UniStatCollectItemsOptions, ReportFail } from './interface.uts'
......@@ -12,6 +12,10 @@ export type ReportSuccess = {
* 错误码
*/
export type ReportErrorCode =
/**
* 应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间
*/
61000 |
/**
* 统计服务尚未初始化,需在`main.uts`中引入统计插件
*/
......
......@@ -11,6 +11,10 @@ export const ReportUniErrorSubject = 'uni-report';
* @UniError
*/
export const ReportUniErrors:Map<number, string> = new Map([
/**
* 已集成uni统计,但未关联服务空间
*/
[61000, '应用已集成uni统计,但未关联服务空间,请在uniCloud目录右键关联服务空间!'],
/**
* 统计已集成,但未初始化
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册