import {
reportUrl } from '@/utils/conf.js'
import {
getJsonHead } from '@/utils/header.js'
import request from '@/utils/request.js'
import Taro,{
getCurrentInstance} from '@tarojs/taro'
const maxlength = 1 //最大上传数据, 当本地存有10条数据的时候才开始上报,1即每次手收集到数据就上报
// 是否验证会员以及已经登录的开关
const MEMBER_VALIDATION = true;
let statArr = []
/*
* 埋点数据处理
*/
function checkMinmum() {
return maxlength === 1
}
// 字符串前补充字符
function padStart(target, targetLength, padString) {
targetLength = targetLength >> 0 //数字向下取整,并且不为数字转为0
padString = String(typeof padString !== 'undefined' ? padString : ' ')
if (target.length > targetLength) {
return String(target)
} else {
targetLength = targetLength - target.length
if (targetLength > padString.length) {
const repeatLength = targetLength / padString.length
for (let i = 0; i < repeatLength; i++) {
padString += padString
}
}
return padString.slice(0, targetLength) + String(target)
}
}
// 字符串数据前补充0
const fillZero = (num) => {
try {
return num ? padStart(num.toString(), 2, '0') : ''
} catch (e) {
return ''
}
}
// 过滤数据并且对数据操作,整理出上传数据
const filterData = (data) => {
const memberId = Taro.getStorageSync('memberId')
// params是通用数据,就是每次上报都会收集的数据,例如用户id,openid
// 需要的通用数据都可以在这里加
let params = {
uid: memberId ? memberId : null
}
let paramsData = {
}
// 对传入的data中的index键值补充前缀0
for (let [k, v] of Object.entries(data)) {
if (v) {
paramsData[k] = k === 'index' ? fillZero(v) : v
}
}
paramsData = Object.assign(params, paramsData)
Object.keys(paramsData).forEach((i) => !paramsData[i] && delete paramsData[i])
return paramsData
}
function getStorageDataStatus(data) {
const paramsData = filterData(data);
// 本地储存
statArr = Taro.getStorageSync('statArr') || []
statArr.push(paramsData)
if (statArr.length <= maxlength) {
// console.info(`%c stat:${JSON.stringify(params)}`, 'color: #EE00EE')
Taro.setStorageSync('statArr', statArr)
}
return statArr.length === maxlength
}
// 判断是否会员登录
function validateMemberSwitch() {
if (!MEMBER_VALIDATION) return true;
const userInfo = Taro.getStorageSync('memberInfo') || null
const isRegistered = userInfo && userInfo.openid && userInfo.mobile;
if (isRegistered) {
return true;
}
return false;
}
/**
* 上报数据
* @param {Object} base base.url, 必传,上报的接口名,不传调用会中止。
* base.immediate. immediate默认为false,为true的时候直接上报(即上报当前缓存的全部数据,相当于手动取消maxLength机制),不会经过10条才上报的条件阈值(阈值为1时没有必要设置)
* @param {Object} params 上报数据
* 例子
* statReport({ url: 'wowcolour_10001.txt' }, { num: 1, str: 'test' })
* statReport({ url }, { index, skuId });
* statReport({ url, immediate: true });立即上传全部本地数据
* 谨记,statReport必须在调用堆栈的最后调用,即,加入调用函数,要在函数的最后一步执行,例如
* function test() {
* xxx其他逻辑
* statReport({ url }, { skuId })
* }
*/
export const statReport = ({
url = '', immediate = false } = {
} , params = {
}) => {
// url不传,即无法上报
if (!url) {
return false }
try {
params.uuid = uuid(32, 64)
params.timestamp = new Date().getTime()
const isValid = validateMemberSwitch();
// console.info(isValid, 333);
if (!isValid) {
return false
}
// 判断是否每次上传
const isEvery = checkMinmum()
// 如果是
if (isEvery) {
const data = filterData(params);
requestReport(data, {
url })
} else {
// 否则本地储存数据,按阈值上传
const isValid = !immediate ? getStorageDataStatus(params) : true
if (isValid) {
const reportData = Taro.getStorageSync('statArr')
Taro.removeStorageSync('statArr')
if (Array.isArray(reportData)) {
requestReport(reportData, {
url })
}
}
}
} catch (e) {
console.info(e)
}
}
function requestReport(reportData, {
url = '' } = {
}) {
console.info(reportData, 333);
// 如果来源时场景值,将缓存launchOptions中的isReport改为true
if (reportData && reportData.sourceFormScene) {
let launchOptions = Taro.getStorageSync('launchOptions')
launchOptions.isReport = true
Taro.setStorageSync('launchOptions', launchOptions)
delete reportData.sourceFormScene
}
request({
header: getJsonHead(),
// 这里的url仅作为展示用,wow的埋点可能会新建服务, 接口可能会变
url: `${
reportUrl}/data/watch/${
url}`,
data: reportData,
success: function (res) {
},
fail: function (err) {
console.info(`%c stat:fail`, 'color: #EE00EE')
}
}).catch(e => {
// console.info(e);
})
}
function uuid(len, radix) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = [], i;
radix = radix || chars.length;
if (len) {
// Compact form
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
} else {
// rfc4122, version 4 form
var r;
// rfc4122 requires these characters
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
// Fill in random data. At i==19 set the high bits of clock sequence as
// per rfc4122, sec. 4.1.5
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random()*16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}
小程序埋点工具类
猜你喜欢
转载自blog.csdn.net/jstljspservlet/article/details/115702130
今日推荐
周排行