提交 cfe12ceb 编写于 作者: M mehaotian

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

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