uniapp 数据统计,数据埋点,自定义事件埋点封装

1,948 阅读1分钟

本博文实现了uniapp的数据统计埋点的封装,可以自动统计页面的PV, UV,页面停留时长,不需要在每个页面的生命周期写统计(tabBar 的页面除外,tabBar 页面需要添加自定义事件)
使用说明:
1.需要在APP.vue 初始化进入时间缓存 ,示例:
onLaunch: function() {
if (!uni.getStorageSync('entryTime')) {
uni.setStorageSync('entryTime', new Date().getTime())
}
},

2.在 tabBar 页面加载和离开的生命周期手动统计
this.$common.Init.call(this);
// 统计自定义事件触发埋点
this.myMta('show')

3.修改mtaUrl 和 appId。

 

实现思路:重写unaipp的路由,在调用路由跳转的时候触发页面PV,UV,停留时长的信息统计,因为tabBar 不会触发路由跳转的API,所以需要在其中的页面用自定义事件手动添加上。

 

下面上代码:

main.js


import nav from "@/util/navRoute.js";
Vue.prototype.$navTo = nav;

页面跳转统一用我封装的API,示例:

this.$navTo.navigateTo({
	url: '/pages/test/test'
})

common.js

import Mta from "@/util/myMta.js";

function Init(e) {
	this.myMta = (...ev) => {
		Mta.myMta(...ev)
	}
}

navRoute.js


import Mta from "@/util/myMta.js";
var nav = {
	navigateTo: ({
		url
	}) => {
		var link = getCurrentPages()[getCurrentPages().length - 1].route;
		Mta.myMta('leaveStr', link)
		console.log('navigateTo', link,'-',url)
		uni.navigateTo({
			url: url,
			success: function(res) {
				Mta.myMta('entryStr', url)
			}
		});
	},
	redirectTo: ({
		url
	}) => {
		var link = getCurrentPages()[getCurrentPages().length - 1].route;
		Mta.myMta('leaveStr', link)
		console.log('redirectTo', link,'-',url)
		uni.redirectTo({
			url: url,
			success: function(res) {
				Mta.myMta('entryStr', url)
			}
		});
	},
	reLaunch: ({
		url
	}) => {
		var link = getCurrentPages()[getCurrentPages().length - 1].route;
		Mta.myMta('leaveStr', link)
		console.log('reLaunch', link,'-',url)
		uni.reLaunch({
			url: url,
			success: function(res) {
				Mta.myMta('entryStr', url)
			}
		});
	},
	switchTab: ({
		url
	}) => {
		var link = getCurrentPages()[getCurrentPages().length - 1].route;
		Mta.myMta('leaveStr', link)
		console.log('switchTab', link,'-',url)
		uni.switchTab({
			url: url,
			success: function(res) {
				Mta.myMta('entryStr', url)
			}
		});
	},
	navigateBack: ({
		num
	}) => {
		var link = getCurrentPages()[getCurrentPages().length - 1].route;
		Mta.myMta('leaveStr', link)
		console.log('navigateBack', link,'-',num)
		uni.navigateBack({
			delta: num
		});
	}

}
export default { ...nav
};

myMta.js

const mtaUrl = 'https://cxxx.cn/commonapi/system/saveRecordLog'
const appId = 'test';


//  埋点通用接口
// triggerType: 必传 类型 entryStr(进入) || leaveStr(离开) || String:自定义事件描述
// pageUrl:非必传,页面路径,不穿默认获取当前路径
async function myMta(triggerType = "", pageUrl = '') {
	
	console.log('埋点', triggerType, pageUrl)
	
	let entryTime, leaveTime,stayTime,sceneType,params;
	// entryTime 进入页面时间
	// leaveTime 离开页面时间
	// stayTime  停留时长
	// sceneType 渠道类型   1 线上渠道用户数    2 线下渠道用户数   3 非扫描二维码用户数
	
	if (!triggerType) return
	if (triggerType == 'entryStr') {
		entryTime = new Date().getTime();
		leaveTime = null;
		uni.setStorageSync('entryTime',entryTime)
	} else {
		entryTime = uni.getStorageSync('entryTime');
		leaveTime = new Date().getTime();
		stayTime = leaveTime-entryTime;
	}
	
	// 获取页面路径及参数
	const urlArgs = getCurrentPageUrlWithArgs();
	if (!pageUrl) {
		leaveTime = new Date().getTime();
		if (urlArgs.indexOf("?") != -1) {
			let url, result, reqDataString;
			pageUrl = urlArgs.split("?")[0];
			url = urlArgs.split("?")[1];
			result = url.replace(/&/g, '","').replace(/=/g, '":"');
			reqDataString = '{"' + result + '"}';
			params = JSON.parse(reqDataString);
		} else {
			pageUrl = urlArgs;
		}
	}
	
	wx.getNetworkType({
		success: function(res) {
			let networkType = res.networkType;
			let token,openid;
			try {
				let scene = JSON.parse(wx.getStorageSync("userInfo")).scene;
				token = JSON.parse(wx.getStorageSync("userToken")).tk || "暂无:token";
				if (!scene) {
					sceneType = 3
				} else {
					sceneType = (scene !== '02be37d9cfbf45f9aa1013180c80bfe0') ? 1 : 2;
				}
			} catch (e) {}
			var data = {
				token: token,
				openid: token,
				scene: sceneType,
				triggerType: triggerType,
				networkType: networkType,
				pageInfo: {
					pageUrl: pageUrl,
					url: urlArgs,
					...params,
				},
				entryTime: toDateDetail(entryTime),
				leaveTime: toDateDetail(leaveTime),
				stayTime: stayTime,
				sysTemInfo: wx.getStorageSync("sysTemInfo"),
			}
			wx.request({
				url: mtaUrl,
				data: data,
				method: "POST",
				header: {
					"content-type": "application/json",
					"appId": appId,
					// "appId": "const_wywplus",
					"appToken": "mkgame?" + chars(),
				},
				success(res) {
					if (res.data.code == 200) {} else {
						console.error('请求失败')
					}
				},
				fail: (ret) => {
					console.error(ret);
				}

			})

		}
	})
}


// 获取当前页面链接和参数
function getCurrentPageUrlWithArgs() {
	const pages = getCurrentPages();
	const currentPage = pages[pages.length - 1];
	const url = currentPage.route;
	const options = currentPage.options;
	let urlWithArgs = `/${url}?`;
	for (let key in options) {
		const value = options[key];
		urlWithArgs += `${key}=${value}&`;
	}
	urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1);
	return urlWithArgs;
}

function chars() {
	let chars = "0123456789";
	/****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
	let maxPos = chars.length;
	let code = "";
	for (let i = 0; i < 6; i++) {
		code += chars.charAt(Math.floor(Math.random() * maxPos));
	}
	return code;
}
function toDateDetail(number) {
	if(!number)return '';
	// var n = number * 1000
	var date = new Date(number);
	var Y = date.getFullYear() + "-";
	var M =
		(date.getMonth() + 1 < 10 ?
			"0" + (date.getMonth() + 1) :
			date.getMonth() + 1) + "-";
	var D = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
	var h = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
	var mm = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
	var s = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
	return Y + "" + M + "" + D + " " + h + ":" + mm + ":" + s;
}

/**
 *   appId            ->      小程序ID             类型:String
 *   appToken         ->      自定义               类型:String
 *   token            ->      当前用户token        类型:String
 *   openid           ->      当前用户openid       类型:String
 *   triggerType      ->      事件类型             类型:String
 *   pageInfo {       ->      当前页面信息         类型:Object
 *     pageUrl:       ->      不带参数             类型:String
 *     url:           ->      带参数               类型:String
 *     ...params      ->      当前页面所有参数       类型:Object
 *   }
 *   entryTime        ->      进入页面时间          类型:Number
 *   leaveTime        ->      离开当前页面时间      类型:Number
 *   stayTime         ->      停留时长             类型:Number   单位:ms
 *   sysTemInfo       ->      设备信息             类型:Object
 */

export default {
	myMta
};