提交 17c60ea2 编写于 作者: M mehaotian

fix: 统计兼容微信小程序

上级 5c7a9554
......@@ -47,7 +47,7 @@
// entryTypes: ['render', 'navigation'],
// } as PerformanceObserverOptions)
// 统计上报 - 应用启动
// #ifdef APP-ANDROID || APP-IOS || WEB
// #ifdef APP-ANDROID || APP-IOS || WEB || MP-WEIXIN
uni.report({
name: 'uni-app-launch',
options: res,
......@@ -87,7 +87,7 @@
setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App Show')
// #ifdef APP-ANDROID || APP-IOS || WEB
// #ifdef APP-ANDROID || APP-IOS || WEB || MP-WEIXIN
// 统计上报 - 应用显示
uni.report({
name: 'uni-app-show',
......@@ -104,7 +104,7 @@
setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide')
// #ifdef APP-ANDROID || APP-IOS || WEB
// #ifdef APP-ANDROID || APP-IOS || WEB || MP-WEIXIN
// 统计上报 - 应用进入后台
uni.report({
name: 'uni-app-hide',
......@@ -141,7 +141,7 @@
// #endif
onError(err : any) {
// console.log('App onError', err)
// #ifdef APP-ANDROID || APP-IOS || WEB
// #ifdef APP-ANDROID || APP-IOS || WEB || MP-WEIXIN
// 统计上报 - 应用发生错误
uni.report({
name: 'uni-app-error',
......
// 仅测试 console.log 时机问题
import './test-main-console.uts'
// #ifdef APP-ANDROID || APP-IOS || WEB
// #ifdef APP-ANDROID || APP-IOS || WEB || MP-WEIXIN
import { uniStat } from '@/uni_modules/uni-stat/plugin.uts'
// #endif
import App from './App.uvue'
......@@ -19,7 +19,7 @@ const uniStatOptions = {
export function createApp() {
const app = createSSRApp(App)
// #ifdef APP-ANDROID || APP-IOS || WEB
// #ifdef APP-ANDROID || APP-IOS || WEB || MP-WEIXIN
app.use(uniStat, uniStatOptions)
// #endif
// app.mixin({
......
## 1.0.4(2024-12-12)
- 新增 自HBuilderX 4.41+ 起支持微信小程序
## 1.0.3(2024-11-18)
- 优化 uni统计兼容性问题
## 1.0.2(2024-11-18)
- 优化 uni统计兼容性问题
## 1.0.1(2024-11-18)
- 修改兼容性
## 1.0.0(2024-11-18)
- 新增 uni统计 for uni-app x
{
"id": "uni-stat",
"displayName": "uni-stat",
"version": "1.0.0",
"description": "uni-stat",
"displayName": "uni统计 for uni-app x",
"version": "1.0.4",
"description": "uni统计的uni-app x 版本",
"keywords": [
"uni-stat"
],
"repository": "",
"uni-stat",
"统计",
"uni统计"
],
"repository": "https://gitcode.net/dcloud/uni-api",
"engines": {
"HBuilderX": "^3.6.8"
"HBuilderX": "^4.33"
},
"dcloudext": {
"type": "uts",
......@@ -24,9 +26,9 @@
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
"ads": "",
"data": "采集页面路由\n采集页面停留时长\n采集常用设备信息",
"permissions": ""
},
"npmurl": ""
},
......@@ -47,46 +49,51 @@
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u",
"alipay": "u"
"tcb": "y",
"aliyun": "y",
"alipay": "y"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
"vue2": "n",
"vue3": "y"
},
"App": {
"app-android": "u",
"app-ios": "u"
},
"app-android": {
"minVersion": "24"
},
"app-ios": {
"minVersion": "9"
},
"app-harmony": "n"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
"微信": "n",
"阿里": "n",
"百度": "n",
"字节跳动": "n",
"QQ": "n",
"钉钉": "n",
"快手": "n",
"飞书": "n",
"京东": "n"
},
"快应用": {
"华为": "u",
"联盟": "u"
"华为": "n",
"联盟": "n"
}
}
}
......
......@@ -4,7 +4,7 @@
>
> uni统计for uni-app x需要单独下载使用,无需在 manifest.json 中配置开关,只需在前端代码中配置即可。
>
> 依赖 `Hbuilder X Alpha版 4.32+`。
> 依赖 `Hbuilder X Alpha版 4.33+`。
uni统计`uni-app x`版本,[使用教程](https://uniapp.dcloud.net.cn/uni-stat-uniappx)
uni统计 for `uni-app x` [使用教程](https://uniapp.dcloud.net.cn/uni-stat-uniappx)
......@@ -22,7 +22,7 @@ class CloudObjectToDo extends InternalUniCloudCloudObjectCaller {
export class Report {
/* uniCloud 实例 */
/* uniCloud 实例 */
// @ts-ignore
static uniCloudInstance : UniCloud | null = null
/**进入应用标识*/
......@@ -44,7 +44,7 @@ export class Report {
constructor() {
this.statData = get_default_data()
// 注册拦截器
// 注册拦截器
// @ts-ignore
let registerInterceptor = typeof uni.addInterceptor === 'function'
if (registerInterceptor) {
......@@ -59,13 +59,13 @@ export class Report {
* 拦截 setNavigationBarTitle 事件
*/
interceptSetNavBar() {
let self = this
let self = this
// @ts-ignore
uni.addInterceptor('setNavigationBarTitle', {
uni.addInterceptor('setNavigationBarTitle', {
// @ts-ignore
invoke(args : SetNavigationBarTitleOptions) {
self._navigationBarTitle.page = args.title
},
},
// @ts-ignore
} as Interceptor)
}
......@@ -74,12 +74,12 @@ export class Report {
* 拦截 login 事件
*/
interceptLogin() {
let self = this
let self = this
// @ts-ignore
uni.addInterceptor('login', {
complete() {
self._login()
},
},
// @ts-ignore
} as Interceptor)
}
......@@ -88,17 +88,17 @@ export class Report {
if (!type) {
self._share()
return
}
}
// @ts-ignore
uni.addInterceptor('share', {
complete() {
self._share()
}
}
// @ts-ignore
} as Interceptor)
}
interceptRequestPayment() {
let self = this
let self = this
// @ts-ignore
uni.addInterceptor('requestPayment', {
success() {
......@@ -106,7 +106,7 @@ export class Report {
},
fail() {
self._payment('pay_fail')
},
},
// @ts-ignore
} as Interceptor)
}
......@@ -155,11 +155,16 @@ export class Report {
// ...options,
// cst: ReprotCstType.AppNormal
// }
let request_option : OnLaunchOptionsWithCst = {
let request_option : OnLaunchOptionsWithCst = {
// @ts-ignore
path: (options as OnLaunchOptions).path,
cst: ReprotCstType.AppNormal
}
// #ifdef MP-WEIXIN
// TODO 安卓没有 scene ,需要补一个
// @ts-ignore
request_option.scene = (options as OnLaunchOptions).scene
// #endif
// 上报数据
this.sendAppRequest(request_option, true)
......@@ -224,7 +229,7 @@ export class Report {
/**
* 进入页面触发
* @param {Page } self 当前页面实例
*/
*/
// @ts-ignore
pageShow(self : Page) {
// 初始化,标题数据。清空值,避免污染后面的上报数据
......@@ -264,7 +269,7 @@ export class Report {
/**
* 离开页面触发
* @param {ComponentPublicInstance } self 当前页面实例
*/
*/
// @ts-ignore
pageHide(self : Page) {
// 如果进入后台则不触发后续 页面隐藏的逻辑
......@@ -292,7 +297,7 @@ export class Report {
appError(em : any) {
let errmsg : string
// #ifdef APP-ANDROID
// #ifdef APP-ANDROID
// @ts-ignore
if (em instanceof Exception) {
errmsg = em.message ?? ''
......@@ -339,6 +344,8 @@ export class Report {
// TODO ,此处处理的值有问题,
// 如果页面有参数 需要上传如:/xxx/xxx?{xx:xx,xxx:xxx} 格式的值
let query = is_opt ? '?' + JSON.stringify(options.query) : ''
// 获取首次访问时间
const first_time = get_first_visit_time()
// 获取应用最后访问时间
const last_time = get_last_visit_time()
// 非老用户
......@@ -350,14 +357,12 @@ export class Report {
if (!have_device) {
this.statData.odid = odid
}
}
this.statData.lt = ReportType.AppStart
this.statData.url = options.path + query
this.statData.t = get_time()
this.statData.sc = get_scene(options)
this.statData.fvts = get_first_visit_time()
this.statData.fvts = first_time
this.statData.lvts = last_time
this.statData.tvc = get_total_visit_count()
this.statData.cst = options.cst ?? ReprotCstType.AppNormal
......@@ -440,13 +445,13 @@ export class Report {
const dataStr = JSON.stringify(statData)
// #ifdef WEB
// #ifdef WEB
// @ts-ignore
let uniStatData = JSON.parse(dataStr) as Map<string, StatDefault[]>
let uniStatData = JSON.parse(dataStr) as Map<string, StatDefault[]>
// @ts-ignore
uniStatData = new Map(Object.entries(uniStatData))
// #endif
// #ifndef WEB
// #ifndef WEB
// @ts-ignore
let uniStatData = JSON.parse<Map<string, StatDefault[]>>(dataStr)
......@@ -564,10 +569,10 @@ export class Report {
if (statConfig.debug!) {
// 待上传消息对列
console.log(`=== 统计待上传队列数据 ===`)
// console.log(`=== 统计待上传队列数据 ===`)
const statJSON = Map2Json(uniStatData)
console.log(statJSON)
console.log(`=== 采集结束 ===`)
console.log('=== 统计待上传队列数据 :', statJSON)
// console.log(`=== 采集结束 ===`)
}
......@@ -594,14 +599,14 @@ export class Report {
// 数据上报
const app = Report.uniCloudInstance!
// #ifdef APP-ANDROID
// #ifdef APP-ANDROID
// @ts-ignore
const uniCloudObj = app.importObject('uni-stat-receiver', {
customUI: true,
customUI: true,
// @ts-ignore
} as UniCloudImportObjectOptions, UTSAndroid.getJavaClass(CloudObjectToDo))
// #endif
// #ifndef APP-ANDROID
// #ifndef APP-ANDROID
// @ts-ignore
const uniCloudObj = app.importObject(
'uni-stat-receiver',
......@@ -616,15 +621,15 @@ export class Report {
.report(options)
.then(() => {
if (statConfig.debug!) {
console.log(`=== 统计队列数据上报 ===`)
console.log(options)
console.log(`=== 上报结束 ===`)
console.log(`=== 统计队列数据上报 :`, options)
// console.log(options)
// console.log(`=== 上报结束 ===`)
}
})
.catch((err : any | null) => {
console.log('=== 统计上报错误 ===')
console.error(err)
console.log(`=== 上报结束 ===`)
console.log('=== 统计上报错误 :', JSON.stringify(err))
// console.error(err)
// console.log(`=== 上报结束 ===`)
})
}
......
......@@ -109,7 +109,6 @@ export class Stat {
this.isHide = false
// @ts-ignore
const mptype = is_page(appInstance)
// 页面执行,应用需要手动调用
if (mptype) {
this.registerEvent(StatType.LifeCyclePageShow, appInstance, null)
......
const APPID = uni.getSystemInfoSync().appId
const APPID = uni.getSystemInfoSync().appId
export function dbSet<T>(name : string, value : T) {
let data = uni.getStorageSync('$$STAT__DBDATA:' + APPID)
let newData = {} as UTSJSONObject
if (data != null && typeof data == 'object') {
newData = data as UTSJSONObject
}
newData[name] = value
uni.setStorageSync('$$STAT__DBDATA:' + APPID, newData)
}
newData[name] = value
uni.setStorageSync('$$STAT__DBDATA:' + APPID, newData)
}
export function dbGet<T>(name : string) : T | null {
let data = uni.getStorageSync('$$STAT__DBDATA:' + APPID)
if (data == null) return null
if (typeof data != 'object') return null
const newData = data as UTSJSONObject
const newData = data as UTSJSONObject
return newData[name] as T
}
export function dbRemove(name : string) {
let data = uni.getStorageSync('$$STAT__DBDATA:' + APPID)
if(data == '') {
data = {}
}
if (data == '') {
data = {}
}
if (data != null) {
let newData = data as UTSJSONObject
if (newData[name] != null) {
......
// AppShowReportParams, AppHideReportParams, PageReportParams,
import { StatDefault } from '../../interface.uts'
// AppShowReportParams, AppHideReportParams, PageReportParams,
import { StatDefault } from '../../interface.uts'
import { AppShowParamsKeys, AppHideParamsKeys, PageShowParamsKeys, PushParamsKeys, EventParamsKeys,ErrorParamsKeys } from '../core/stat-type.uts'
import { AppShowParamsKeys, AppHideParamsKeys, PageShowParamsKeys, PushParamsKeys, EventParamsKeys, ErrorParamsKeys } from '../core/stat-type.uts'
/**
* 序列化url参数
......@@ -81,16 +81,16 @@ export function Log(data : StatDefault, type : Boolean = false) {
}
if (type) {
console.log(`=== 统计队列数据上报 ===`)
console.log(logData)
console.log(`=== 上报结束 ===`)
console.log(`=== 统计队列数据上报 :`, logData)
// console.log(logData)
// console.log(`=== 上报结束 ===`)
return
}
if (msg_type != '') {
console.log(`=== 统计数据采集:${msg_type} ===`)
console.log(logData)
console.log(`=== 采集结束 ===`)
console.log(`=== 统计数据采集:${msg_type} :`,logData)
// console.log(logData)
// console.log(`=== 采集结束 ===`)
}
}
......@@ -155,7 +155,7 @@ function getEventData(lt : string, elm : StatDefault) : any {
let data : any = {}
switch (lt) {
case '1'://应用启动
data = FilterParam(AppShowParamsKeys, elm)
data = FilterParam(AppShowParamsKeys, elm)
break
case '3': // 应用进入后台
data = FilterParam(AppHideParamsKeys, elm)
......@@ -166,13 +166,13 @@ function getEventData(lt : string, elm : StatDefault) : any {
case '21': // 事件触发
data = FilterParam(EventParamsKeys, elm)
break
case '31': // 应用错误
case '31': // 应用错误
data = FilterParam(ErrorParamsKeys, elm)
break
case '101': // PUSH
data = FilterParam(PushParamsKeys, elm)
break
}
}
return data
}
\ No newline at end of file
......@@ -7,40 +7,6 @@ import { Serialize, IsNumber } from './index.uts'
const APPID = sys.appId
const RUNTIME_VERSION = sys.appVersion
// const UUID_KEY = '__DC_STAT_UUID'
// const UUID_VALUE = '__DC_UUID_VALUE'
/**
* 生成uuid,一般用不到
*/
// function getUuid() : string {
// let uuid : string
// if (get_platform_name() === 'n') {
// try {
// uuid = sys.deviceId
// } catch (e) {
// uuid = ''
// }
// return uuid
// }
// try {
// uuid = uni.getStorageSync(UUID_KEY) as string
// } catch (e) {
// uuid = UUID_VALUE
// }
// if (uuid != '') {
// uuid = Date.now() + '' + Math.floor(Math.random() * 1e7)
// try {
// uni.setStorageSync(UUID_KEY, uuid)
// } catch (e) {
// uni.setStorageSync(UUID_KEY, UUID_VALUE)
// }
// }
// return uuid
// }
/**
* 获取uuid
......@@ -163,35 +129,17 @@ export const get_channel = () : string => {
/**
* 获取小程序场景值
*/
export const get_scene = (_ : OnLaunchOptionsWithCst) : number => {
// TODO 场景值获取有问题 ,暂时硬编码,需要修改
// options : OnLaunchOptionsWithCst
export const get_scene = (options : OnLaunchOptionsWithCst) : number => {
// const platformName = get_platform_name()
// let scene = ''
// if (options) {
// return options
// }
// if (platformName === 'wx') {
// scene = uni.getLaunchOptionsSync().scene
let scene = 1001
if (options.scene != null) {
return options.scene ?? 1001
}
// if (platformName == 'wx') {
// // @ts-ignore
// scene = uni.getLaunchOptionsSync()?.scene ?? 1001
// }
// return scene
// return options.scene as number
return 1001
}
/**
* 获取页面类型
* @param {VueComponent} appInstance 页面实例
*/
// @ts-ignore
export const get_page_types = (appInstance : ComponentPublicInstance) : string => {
// TODO 暂时无法获取是否应用还是页面,写的硬编码,只支持页面调用
// #ifdef WEB || APP-IOS
return appInstance?.$mpType ?? 'page'
// #endif
// #ifndef WEB
return 'page'
// #endif
return scene
}
/**
......@@ -200,15 +148,14 @@ export const get_page_types = (appInstance : ComponentPublicInstance) : string =
*/
// @ts-ignore
export const is_page = (appInstance : ComponentPublicInstance) : Boolean => {
// #ifdef WEB ||APP-IOS
// #ifdef WEB || APP-IOS || MP-WEIXIN
const type = appInstance?.$mpType ?? 'page'
return type == 'page' ? true : false
// #endif
// #ifndef WEB
// #ifndef WEB || APP-IOS || MP-WEIXIN
// 其他平台没有 $mpType ,只有页面触发
return true
// #endif
}
......@@ -218,10 +165,16 @@ export const is_page = (appInstance : ComponentPublicInstance) : Boolean => {
*/
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 (page.route != routepath) {
if (route != routepath) {
const pages = getCurrentPages()
// 如果传入路由与当前页面不同,则从页面栈找一个,如果找不到返回空
let page_now = pages.find((p) : boolean => p.route == routepath)
......@@ -231,11 +184,19 @@ export const get_page_name = (routepath : string) : string => {
// @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()
const titleText = pageStyle['navigationBarTitleText'] ?? ''
titleText = (pageStyle['navigationBarTitleText'] as string)
// #endif
return titleText as string
}
/**
......@@ -267,23 +228,39 @@ export function get_route(page : Page | null = null) : RouteParams {
}
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(_self.options)
const opts = new UTSJSONObject(options)
// TODO 上报页面参数需要处理
let url_params = Serialize(opts)
url_params = Serialize(opts)
// #endif
// #ifndef APP-ANDROID
// @ts-ignore
let url_params = Serialize(_self.options)
url_params = Serialize(options)
// #endif
let params = ''
// 如果参数只有 ?则说明没有参数
if (url_params != '?') {
params = url_params
}
let route = _self.route
// 兼容不同小程序下的不同取值
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,
......@@ -394,15 +371,13 @@ export const get_report_Interval = (defaultTime : number) : number => {
return time as number
}
/**
* 获取uniCloud服务空间配置
* @returns {Object}
*/
export const uni_cloud_config = () : UniCloudInitOptions | null => {
// TODO 当前版本暂时不使用
// return process.env.UNI_STAT_UNI_CLOUD || {}
// const custemUnicloudConfig: = {}
return null
}
......
......@@ -59,11 +59,12 @@ export const get_first_visit_time = () : number => {
*/
export const get_last_visit_time = () : number => {
const timeStorge = dbGet<number>(LAST_VISIT_TIME_KEY)
let time = 0
let time = 0
if (timeStorge != null && timeStorge != 0) {
time = timeStorge as number
}
dbSet(LAST_VISIT_TIME_KEY, get_time())
}
dbSet(LAST_VISIT_TIME_KEY, get_time())
return time
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册