uni-ticket-system/node_modules/@dcloudio/uni-stat/dist/uni-cloud-stat.es.js

1596 lines
37 KiB
JavaScript
Raw Normal View History

2023-12-05 02:11:10 +00:00
/**
* 获取系统信息
*/
const sys = uni.getSystemInfoSync();
// 访问开始即启动小程序访问结束结分为进入后台超过5min、在前台无任何操作超过30min、在新的来源打开小程序
const STAT_VERSION = process.env.UNI_COMPILER_VERSION;
const STAT_URL = 'https://tongji.dcloud.io/uni/stat';
const STAT_H5_URL = 'https://tongji.dcloud.io/uni/stat.gif';
const PAGE_PVER_TIME = 1800; // 页面在前台无操作结束访问时间 单位s
const APP_PVER_TIME = 300; // 应用在后台结束访问时间 单位s
const OPERATING_TIME = 10; // 数据上报时间 单位s
const DIFF_TIME = 60 * 1000 * 60 * 24;
const appid = process.env.UNI_APP_ID; // 做应用隔离
const dbSet = (name, value) => {
let data = uni.getStorageSync('$$STAT__DBDATA:'+appid) || {};
if (!data) {
data = {};
}
data[name] = value;
uni.setStorageSync('$$STAT__DBDATA:'+appid, data);
};
const dbGet = (name) => {
let data = uni.getStorageSync('$$STAT__DBDATA:'+appid) || {};
if (!data[name]) {
let dbdata = uni.getStorageSync('$$STAT__DBDATA:'+appid);
if (!dbdata) {
dbdata = {};
}
if (!dbdata[name]) {
return undefined
}
data[name] = dbdata[name];
}
return data[name]
};
const dbRemove = (name) => {
let data = uni.getStorageSync('$$STAT__DBDATA:'+appid) || {};
if (data[name]) {
delete data[name];
uni.setStorageSync('$$STAT__DBDATA:'+appid, data);
} else {
data = uni.getStorageSync('$$STAT__DBDATA:'+appid);
if (data[name]) {
delete data[name];
uni.setStorageSync('$$STAT__DBDATA:'+appid, data);
}
}
};
// 获取 manifest.json 中统计配置
const uniStatisticsConfig = process.env.UNI_STATISTICS_CONFIG;
let statConfig = {
appid: process.env.UNI_APP_ID,
};
let titleJsons = {};
let debug = !!process.env.UNI_STAT_DEBUG || false;
// #ifdef VUE3
titleJsons = process.env.UNI_STAT_TITLE_JSON;
// #endif
// #ifndef VUE3
// eslint-disable-next-line no-restricted-globals
const pagesTitle = require('uni-pages?{"type":"style"}').default;
let pagesData = pagesTitle.pages;
for (let i in pagesData) {
const style = pagesData[i];
const titleText =
// MP
style.navigationBarTitleText ||
// ali
style.defaultTitle ||
// H5 || App
style.navigationBar?.titleText ||
'';
if (titleText) {
titleJsons[i] = titleText;
}
}
// #endif
// TODO 在云函数中获取,暂时注释
const UUID_KEY = '__DC_STAT_UUID';
const UUID_VALUE = '__DC_UUID_VALUE';
function getUuid() {
let uuid = '';
if (get_platform_name() === 'n') {
try {
uuid = plus.runtime.getDCloudId();
} catch (e) {
uuid = '';
}
return uuid
}
try {
uuid = uni.getStorageSync(UUID_KEY);
} 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
}
const get_uuid = (statData) => {
// 有可能不存在 deviceId一般不存在就是出bug了就自己生成一个
return sys.deviceId || getUuid()
};
/**
* 获取老版的 deviceid ,兼容以前的错误 deviceid
* @param {*} statData
* @returns
*/
const get_odid = (statData) => {
let odid = '';
if (get_platform_name() === 'n') {
try {
odid = plus.device.uuid;
} catch (e) {
odid = '';
}
return odid
}
return sys.deviceId || getUuid()
};
/**
* 获取配置信息 appid
*/
const stat_config = statConfig;
const get_sgin = (statData) => {
let arr = Object.keys(statData);
let sortArr = arr.sort();
let sgin = {};
let sginStr = '';
for (var i in sortArr) {
sgin[sortArr[i]] = statData[sortArr[i]];
sginStr += sortArr[i] + '=' + statData[sortArr[i]] + '&';
}
return {
sign: '',
options: sginStr.substr(0, sginStr.length - 1),
}
};
const get_encodeURIComponent_options = (statData) => {
let data = {};
for (let prop in statData) {
data[prop] = encodeURIComponent(statData[prop]);
}
return data
};
/**
* 获取当前平台
* 移动端 : 'n',
* h5 : 'h5',
* 微信 : 'wx',
* 阿里 : 'ali',
* 百度 : 'bd',
* 头条 : 'tt',
* qq : 'qq',
* 快应用 : 'qn',
* 快手 : 'ks',
* 飞书 : 'lark',
* 快应用 : 'qw',
* 钉钉 : 'dt'
*/
const get_platform_name = () => {
// 苹果审核代码中禁止出现 alipay 字样 ,需要特殊处理一下
const aliArr = ['y', 'a', 'p', 'mp-ali'];
const platformList = {
app: 'n',
'app-plus': 'n',
h5: 'h5',
'mp-weixin': 'wx',
[aliArr.reverse().join('')]: 'ali',
'mp-baidu': 'bd',
'mp-toutiao': 'tt',
'mp-qq': 'qq',
'quickapp-native': 'qn',
'mp-kuaishou': 'ks',
'mp-lark': 'lark',
'quickapp-webview': 'qw',
};
if (platformList[process.env.VUE_APP_PLATFORM] === 'ali') {
if (my && my.env) {
const clientName = my.env.clientName;
if (clientName === 'ap') return 'ali'
if (clientName === 'dingtalk') return 'dt'
// TODO 缺少 ali 下的其他平台
}
}
return platformList[process.env.VUE_APP_PLATFORM]
};
/**
* 获取小程序 appid
*/
const get_pack_name = () => {
let packName = '';
if (get_platform_name() === 'wx' || get_platform_name() === 'qq') {
// 兼容微信小程序低版本基础库
if (uni.canIUse('getAccountInfoSync')) {
packName = uni.getAccountInfoSync().miniProgram.appId || '';
}
}
if (get_platform_name() === 'n') ;
return packName
};
/**
* 应用版本
*/
const get_version = () => {
return get_platform_name() === 'n' ? plus.runtime.version : ''
};
/**
* 获取渠道
*/
const get_channel = () => {
const platformName = get_platform_name();
let channel = '';
if (platformName === 'n') {
channel = plus.runtime.channel;
}
return channel
};
/**
* 获取小程序场景值
* @param {Object} options 页面信息
*/
const get_scene = (options) => {
const platformName = get_platform_name();
let scene = '';
if (options) {
return options
}
if (platformName === 'wx') {
scene = uni.getLaunchOptionsSync().scene;
}
return scene
};
/**
* 获取页面url不包含参数
*/
const get_route$1 = (pageVm) => {
let _self = pageVm || get_page_vm();
if (get_platform_name() === 'bd') {
let mp_route = _self.$mp && _self.$mp.page && _self.$mp.page.is;
let scope_route = _self.$scope && _self.$scope.is;
return mp_route || scope_route || ''
} else {
return (
_self.route ||
(_self.$scope && _self.$scope.route) ||
(_self.$mp && _self.$mp.page.route)
)
}
};
/**
* 获取页面url, 包含参数
*/
const get_page_route = (pageVm) => {
// 从 app 进入应用 ,没有 $page ,获取不到路由 ,需要获取页面 尝试从 getCurrentPages 获取也页面实例
// FIXME 尽量不使用 getCurrentPages ,大部分获取路由是从 onHide 获取 ,这时可以获取到,如果是 onload ,则可能获取不到,比如 百度
let page = pageVm && (pageVm.$page || (pageVm.$scope && pageVm.$scope.$page));
let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE');
if (!page) return lastPageRoute || ''
// 如果找不到 fullPath 就取 route 的值
return page.fullPath === '/' ? page.route : page.fullPath || page.route
};
/**
* 获取页面实例
*/
const get_page_vm = () => {
let pages = getCurrentPages();
let $page = pages[pages.length - 1];
if (!$page) return null
return $page.$vm
};
/**
* 获取页面类型
*/
const get_page_types = (self) => {
// XXX 百度有问题 ,获取的都是 componet ,等待修复
if (
self.mpType === 'page' ||
self.$mpType === 'page' ||
(self.$mp && self.$mp.mpType === 'page') ||
self.$options.mpType === 'page'
) {
return 'page'
}
if (
self.mpType === 'app' ||
self.$mpType === 'app' ||
(self.$mp && self.$mp.mpType === 'app') ||
self.$options.mpType === 'app'
) {
return 'app'
}
return null
};
/**
* 处理上报参数
* @param {Object} 需要处理的数据
*/
const handle_data = (statData) => {
let firstArr = [];
let contentArr = [];
let lastArr = [];
for (let i in statData) {
const rd = statData[i];
rd.forEach((elm) => {
let newData = '';
{
newData = elm;
}
if (i === 0) {
firstArr.push(newData);
} else if (i === 3) {
lastArr.push(newData);
} else {
contentArr.push(newData);
}
});
}
firstArr.push(...contentArr, ...lastArr);
// 参数需要处理成字符串,方便上传
return JSON.stringify(firstArr)
};
/**
* 自定义事件参数校验
*/
const calibration = (eventName, options) => {
// login 、 share 、pay_success 、pay_fail 、register 、title
if (!eventName) {
console.error(`uni.report Missing [eventName] parameter`);
return true
}
if (typeof eventName !== 'string') {
console.error(
`uni.report [eventName] Parameter type error, it can only be of type String`
);
return true
}
if (eventName.length > 255) {
console.error(
`uni.report [eventName] Parameter length cannot be greater than 255`
);
return true
}
if (typeof options !== 'string' && typeof options !== 'object') {
console.error(
'uni.report [options] Parameter type error, Only supports String or Object type'
);
return true
}
if (typeof options === 'string' && options.length > 255) {
console.error(
`uni.report [options] Parameter length cannot be greater than 255`
);
return true
}
if (eventName === 'title' && typeof options !== 'string') {
console.error(
`uni.report [eventName] When the parameter is title, the [options] parameter can only be of type String`
);
return true
}
};
const get_page_name = (routepath) => {
return (titleJsons && titleJsons[routepath]) || ''
};
const Report_Data_Time = 'Report_Data_Time';
const Report_Status = 'Report_Status';
const is_report_data = () => {
return new Promise((resolve, reject) => {
let start_time = '';
let end_time = new Date().getTime();
let diff_time = DIFF_TIME;
let report_status = 1;
try {
start_time = uni.getStorageSync(Report_Data_Time);
report_status = uni.getStorageSync(Report_Status);
} catch (e) {
start_time = '';
report_status = 1;
}
if (report_status === '') {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time);
uni.setStorageSync(Report_Status, enable);
if (enable === 1) {
resolve();
}
});
return
}
if (report_status === 1) {
resolve();
}
if (!start_time) {
uni.setStorageSync(Report_Data_Time, end_time);
start_time = end_time;
}
if (end_time - start_time > diff_time) {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time);
uni.setStorageSync(Report_Status, enable);
});
}
})
};
const requestData = (done) => {
const appid = process.env.UNI_APP_ID;
let formData = {
usv: STAT_VERSION,
conf: JSON.stringify({
ak: appid,
}),
};
uni.request({
url: STAT_URL,
method: 'GET',
data: formData,
success: (res) => {
const { data } = res;
if (data.ret === 0) {
typeof done === 'function' &&
done({
enable: data.enable,
});
}
},
fail: (e) => {
let report_status_code = 1;
try {
report_status_code = uni.getStorageSync(Report_Status);
} catch (e) {
report_status_code = 1;
}
if (report_status_code === '') {
report_status_code = 1;
}
typeof done === 'function' &&
done({
enable: report_status_code,
});
},
});
};
/**
* 获取uniCloud服务空间配置
* @returns {Object}
*/
const uni_cloud_config = () => {
return process.env.UNI_STAT_UNI_CLOUD || {}
};
/**
* 获取服务空间
* @param {*} config
* @returns
*/
const get_space = (config) => {
const uniCloudConfig = uni_cloud_config();
const { spaceId, provider, clientSecret } = uniCloudConfig;
const space_type = ['tcb', 'tencent', 'aliyun'];
const is_provider = space_type.indexOf(provider) !== -1;
const is_aliyun = provider === 'aliyun' && spaceId && clientSecret;
const is_tcb = (provider === 'tcb' || provider === 'tencent') && spaceId;
if (is_provider && (is_aliyun || is_tcb)) {
return uniCloudConfig
} else {
if (config && config.spaceId) {
return config
}
}
return null
};
/**
* 是否开启 debug 模式
*/
const is_debug = debug;
/**
* 日志输出
* @param {*} data
*/
const log = (data, type) => {
let msg_type = '';
switch (data.lt) {
case '1':
msg_type = '应用启动';
break
case '3':
msg_type = '应用进入后台';
break
case '11':
msg_type = '页面切换';
break
case '21':
msg_type = '事件触发';
break
case '31':
msg_type = '应用错误';
break
case '101':
msg_type = 'PUSH';
break
}
// #ifdef APP
// 在 app 中,日志转为 字符串
if (typeof data === 'object') {
data = JSON.stringify(data);
}
// #endif
if (type) {
console.log(`=== 统计队列数据上报 ===`);
console.log(data);
console.log(`=== 上报结束 ===`);
return
}
if (msg_type) {
console.log(`=== 统计数据采集:${msg_type} ===`);
console.log(data);
console.log(`=== 采集结束 ===`);
}
};
/**
* 获取上报时间间隔
* @param {*} defaultTime 默认上报间隔时间 单位s
*/
const get_report_Interval = (defaultTime) => {
let time = uniStatisticsConfig.reportInterval;
// 如果上报时间配置为0 相当于立即上报
if (Number(time) === 0) return 0
time = time || defaultTime;
let reg = /(^[1-9]\d*$)/;
// 如果不是整数,则默认为上报间隔时间
if (!reg.test(time)) return defaultTime
return Number(time)
};
/**
* 获取隐私协议配置
*/
const is_push_clientid = () => {
if (uniStatisticsConfig.collectItems) {
const ClientID = uniStatisticsConfig.collectItems.uniPushClientID;
return typeof ClientID === 'boolean' ? ClientID : false
}
return false
};
/**
* 是否上报页面数据
* @returns
*/
const is_page_report = ()=>{
if(uniStatisticsConfig.collectItems){
const statPageLog = uniStatisticsConfig.collectItems.uniStatPageLog;
// 如果字段不存在返回 true , 如果是boolean 值按原值返回,如果是其他类型 返回false
if(statPageLog === undefined) return true
return typeof statPageLog === 'boolean' ? statPageLog : true
}
return true
};
/**
* 是否已处理设备 DeviceId
* 如果值为 1 则表示已处理
*/
const IS_HANDLE_DEVECE_ID = 'is_handle_device_id';
const is_handle_device = () => {
let isHandleDevice = dbGet(IS_HANDLE_DEVECE_ID) || '';
dbSet(IS_HANDLE_DEVECE_ID, '1');
return isHandleDevice === '1'
};
// 首次访问时间
const FIRST_VISIT_TIME_KEY = '__first__visit__time';
// 最后访问时间
const LAST_VISIT_TIME_KEY = '__last__visit__time';
/**
* 获取当前时间
*/
const get_time = () => {
return parseInt(new Date().getTime() / 1000)
};
/**
* 获取首次访问时间
*/
const get_first_visit_time = () => {
const timeStorge = dbGet(FIRST_VISIT_TIME_KEY);
let time = 0;
if (timeStorge) {
time = timeStorge;
} else {
time = get_time();
dbSet(FIRST_VISIT_TIME_KEY, time);
// 首次访问需要 将最后访问时间置 0
dbRemove(LAST_VISIT_TIME_KEY);
}
return time
};
/**
* 最后访问时间
*/
const get_last_visit_time = () => {
const timeStorge = dbGet(LAST_VISIT_TIME_KEY);
let time = 0;
if (timeStorge) {
time = timeStorge;
}
dbSet(LAST_VISIT_TIME_KEY, get_time());
return time
};
// 页面停留时间记录key
const PAGE_RESIDENCE_TIME = '__page__residence__time';
let First_Page_Residence_Time = 0;
let Last_Page_Residence_Time = 0;
/**
* 设置页面停留时间
*/
const set_page_residence_time = () => {
First_Page_Residence_Time = get_time();
dbSet(PAGE_RESIDENCE_TIME, First_Page_Residence_Time);
return First_Page_Residence_Time
};
/**
* 获取页面停留时间
*/
const get_page_residence_time = () => {
Last_Page_Residence_Time = get_time();
First_Page_Residence_Time = dbGet(PAGE_RESIDENCE_TIME);
return Last_Page_Residence_Time - First_Page_Residence_Time
};
/**
* 获取总访问次数
*/
const TOTAL_VISIT_COUNT = '__total__visit__count';
const get_total_visit_count = () => {
const timeStorge = dbGet(TOTAL_VISIT_COUNT);
let count = 1;
if (timeStorge) {
count = timeStorge;
count++;
}
dbSet(TOTAL_VISIT_COUNT, count);
return count
};
const FIRST_TIME = '__first_time';
/**
* 设置页面首次访问时间用户获取页面/应用停留时常
*/
const set_first_time = () => {
// 获取当前时间 ,以下代码获取到是毫秒级时间戳 实际上用到是秒级时间戳所以需要除以1000
// const time = new Date().getTime()
let time = get_time();
const timeStorge = dbSet(FIRST_TIME,time);
return timeStorge
};
/**
* 获取最后一次时间 暂时用不到直接获取当前时间即可
*/
// export const get_last_time = () => {
// let time = new Date().getTime()
// Set__Last__Time = time
// return time
// }
/**
* 获取页面 \ 应用停留时间
*/
const get_residence_time = (type) => {
let residenceTime = 0;
const first_time = dbGet(FIRST_TIME);
const last_time = get_time();
if (first_time !== 0) {
residenceTime = last_time - first_time;
}
// 将毫秒级时间戳转换为秒级时间戳,因为直接获取的是秒级时间戳,所以不需要转换
// residenceTime = parseInt(residenceTime / 1000)
residenceTime = residenceTime < 1 ? 1 : residenceTime;
if (type === 'app') {
let overtime = residenceTime > APP_PVER_TIME ? true : false;
return {
residenceTime,
overtime,
}
}
if (type === 'page') {
let overtime = residenceTime > PAGE_PVER_TIME ? true : false;
return {
residenceTime,
overtime,
}
}
return {
residenceTime,
}
};
const eport_Interval = get_report_Interval(OPERATING_TIME);
// 统计数据默认值
let statData = {
uuid: get_uuid(), // 设备标识
ak: stat_config.appid, // uni-app 应用 Appid
p: sys.platform === 'android' ? 'a' : 'i', // 手机系统
ut: get_platform_name(), // 平台类型
mpn: get_pack_name(), // 原生平台包名、小程序 appid
usv: STAT_VERSION, // 统计 sdk 版本
v: get_version(), // 应用版本仅app
ch: get_channel(), // 渠道信息
cn: '', // 国家
pn: '', // 省份
ct: '', // 城市
t: get_time(), // 上报数据时的时间戳
tt: '',
brand: sys.brand || '', // 手机品牌
md: sys.model, // 手机型号
sv: sys.system.replace(/(Android|iOS)\s/, ''), // 手机系统版本
mpsdk: sys.SDKVersion || '', // x程序 sdk version
mpv: sys.version || '', // 小程序平台版本 ,如微信、支付宝
lang: sys.language, // 语言
pr: sys.pixelRatio, // pixelRatio 设备像素比
ww: sys.windowWidth, // windowWidth 可使用窗口宽度
wh: sys.windowHeight, // windowHeight 可使用窗口高度
sw: sys.screenWidth, // screenWidth 屏幕宽度
sh: sys.screenHeight, // screenHeight 屏幕高度
};
class Report {
constructor() {
// 页面实例
this.self = '';
// 进入应用标识
this.__licationShow = false;
// 离开应用标识
this.__licationHide = false;
// 统计默认值
this.statData = statData;
// 标题默认值
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
};
// 页面参数
this._query = {};
// 页面最后停留页面的 url
// this._lastPageRoute = ''
// 注册拦截器
let registerInterceptor = typeof uni.addInterceptor === 'function';
if (registerInterceptor) {
this.addInterceptorInit();
this.interceptLogin();
this.interceptShare(true);
this.interceptRequestPayment();
}
}
addInterceptorInit() {
let self = this;
uni.addInterceptor('setNavigationBarTitle', {
invoke(args) {
self._navigationBarTitle.page = args.title;
},
});
}
interceptLogin() {
let self = this;
uni.addInterceptor('login', {
complete() {
self._login();
},
});
}
interceptShare(type) {
let self = this;
if (!type) {
self._share();
return
}
uni.addInterceptor('share', {
success() {
self._share();
},
fail() {
self._share();
},
});
}
interceptRequestPayment() {
let self = this;
uni.addInterceptor('requestPayment', {
success() {
self._payment('pay_success');
},
fail() {
self._payment('pay_fail');
},
});
}
_login() {
this.sendEventRequest(
{
key: 'login',
},
0
);
}
_share() {
this.sendEventRequest(
{
key: 'share',
},
0
);
}
_payment(key) {
this.sendEventRequest(
{
key,
},
0
);
}
/**
* 进入应用触发
*/
applicationShow() {
// 通过 __licationHide 判断保证是进入后台后在次进入应用,避免重复上报数据
if (this.__licationHide) {
const time = get_residence_time('app');
// 需要判断进入后台是否超过时限 ,默认是 30min ,是的话需要执行进入应用的上报
if (time.overtime) {
let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE');
let options = {
path: lastPageRoute,
scene: this.statData.sc,
cst: 2,
};
this.sendReportRequest(options);
}
// 状态重置
this.__licationHide = false;
}
}
/**
* 离开应用触发
* @param {Object} self
* @param {Object} type
*/
applicationHide(self, type) {
if (!self) {
// 表示应用切换到后台 ,此时需要从页面栈获取页面实例
self = get_page_vm();
}
// 进入应用后台保存状态,方便进入前台后判断是否上报应用数据
this.__licationHide = true;
const time = get_residence_time();
const route = get_page_route(self);
uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route);
this.sendHideRequest(
{
urlref: route,
urlref_ts: time.residenceTime,
},
type
);
// 更新页面首次访问时间
set_first_time();
}
/**
* 进入页面触发
*/
pageShow(self) {
// 清空值 ,初始化 ,避免污染后面的上报数据
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
};
const route = get_page_route(self);
const routepath = get_route$1(self);
this._navigationBarTitle.config = get_page_name(routepath);
// 表示应用触发 ,页面切换不触发之后的逻辑
if (this.__licationShow) {
// 更新页面首次访问时间
set_first_time();
// this._lastPageRoute = route
uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route);
this.__licationShow = false;
return
}
const time = get_residence_time('page');
// 停留时间
if (time.overtime) {
let options = {
path: route,
scene: this.statData.sc,
cst: 3,
};
this.sendReportRequest(options);
}
// 更新页面首次访问时间
set_first_time();
}
/**
* 离开页面触发
*/
pageHide(self) {
if (!this.__licationHide) {
const time = get_residence_time('page');
let route = get_page_route(self);
let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE');
if (!lastPageRoute) {
lastPageRoute = route;
}
uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route);
this.sendPageRequest({
url: route,
urlref: lastPageRoute,
urlref_ts: time.residenceTime,
});
// this._lastPageRoute = route
return
}
}
/**
* 发送请求,应用维度上报
* @param {Object} options 页面信息
* @param {Boolean} type 是否立即上报
*/
sendReportRequest(options, type) {
this._navigationBarTitle.lt = '1';
this._navigationBarTitle.config = get_page_name(options.path);
let is_opt = options.query && JSON.stringify(options.query) !== '{}';
let query = is_opt ? '?' + JSON.stringify(options.query) : '';
const last_time = get_last_visit_time();
// 非老用户
if(last_time !== 0 || !last_time){
const odid = get_odid();
// 2.0 处理规则
{
const have_device = is_handle_device();
// 如果没有上报过设备信息 ,则需要上报设备信息
if(!have_device) {
this.statData.odid = odid;
}
}
}
Object.assign(this.statData, {
lt: '1',
url: options.path + query || '',
t: get_time(),
sc: get_scene(options.scene),
fvts: get_first_visit_time(),
lvts: last_time,
tvc: get_total_visit_count(),
// create session type 上报类型 1 应用进入 2.后台30min进入 3.页面30min进入
cst: options.cst || 1,
});
if (get_platform_name() === 'n') {
this.getProperty(type);
} else {
this.getNetworkInfo(type);
}
}
/**
* 发送请求,页面维度上报
* @param {Object} opt
*/
sendPageRequest(opt) {
let { url, urlref, urlref_ts } = opt;
this._navigationBarTitle.lt = '11';
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
p: this.statData.p,
lt: '11',
ut: this.statData.ut,
url,
tt: this.statData.tt,
urlref,
urlref_ts,
ch: this.statData.ch,
usv: this.statData.usv,
t: get_time(),
};
this.request(options);
}
/**
* 进入后台上报数据
* @param {Object} opt
* @param {Object} type
*/
sendHideRequest(opt, type) {
let { urlref, urlref_ts } = opt;
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
p: this.statData.p,
lt: '3',
ut: this.statData.ut,
urlref,
urlref_ts,
ch: this.statData.ch,
usv: this.statData.usv,
t: get_time(),
};
this.request(options, type);
}
/**
* 自定义事件上报
*/
sendEventRequest({ key = '', value = '' } = {}) {
let routepath = '';
try {
routepath = get_route$1();
} catch (error) {
const launch_options = dbGet('__launch_options');
routepath = launch_options.path;
}
this._navigationBarTitle.config = get_page_name(routepath);
this._navigationBarTitle.lt = '21';
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
p: this.statData.p,
lt: '21',
ut: this.statData.ut,
url: routepath,
ch: this.statData.ch,
e_n: key,
e_v: typeof value === 'object' ? JSON.stringify(value) : value.toString(),
usv: this.statData.usv,
t: get_time(),
};
this.request(options);
}
sendPushRequest(options, cid) {
let time = get_time();
const statData = {
lt: '101',
cid: cid,
t: time,
ut: this.statData.ut,
};
// debug 打印打点信息
if (is_debug) {
log(statData);
}
const stat_data = handle_data({
101: [statData],
});
let optionsData = {
usv: STAT_VERSION, //统计 SDK 版本号
t: time, //发送请求时的时间戮
requests: stat_data,
};
// XXX 安卓需要延迟上报 ,否则会有未知错误,需要验证处理
if (get_platform_name() === 'n' && this.statData.p === 'a') {
setTimeout(() => {
this.sendRequest(optionsData);
}, 200);
return
}
this.sendRequest(optionsData);
}
/**
* 获取wgt资源版本
*/
getProperty(type) {
plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
this.statData.v = wgtinfo.version || '';
this.getNetworkInfo(type);
});
}
/**
* 获取网络信息
*/
getNetworkInfo(type) {
uni.getNetworkType({
success: (result) => {
this.statData.net = result.networkType;
this.getLocation(type);
},
});
}
/**
* 获取位置信息
*/
getLocation(type) {
if (stat_config.getLocation) {
uni.getLocation({
type: 'wgs84',
geocode: true,
success: (result) => {
if (result.address) {
this.statData.cn = result.address.country;
this.statData.pn = result.address.province;
this.statData.ct = result.address.city;
}
this.statData.lat = result.latitude;
this.statData.lng = result.longitude;
this.request(this.statData, type);
},
});
} else {
this.statData.lat = 0;
this.statData.lng = 0;
this.request(this.statData, type);
}
}
/**
* 发送请求
* @param {Object} data 上报数据
* @param {Object} type 类型
*/
request(data, type) {
let time = get_time();
const title = this._navigationBarTitle;
Object.assign(data, {
ttn: title.page,
ttpj: title.config,
ttc: title.report,
});
let uniStatData = dbGet('__UNI__STAT__DATA') || {};
if (!uniStatData[data.lt]) {
uniStatData[data.lt] = [];
}
// 加入队列
uniStatData[data.lt].push(data);
dbSet('__UNI__STAT__DATA', uniStatData);
let page_residence_time = get_page_residence_time();
// debug 打印打点信息
if (is_debug) {
log(data);
}
// 判断时候到达上报时间 ,默认 10 秒上报
if (page_residence_time < eport_Interval && !type) return
// 时间超过,重新获取时间戳
set_page_residence_time();
const stat_data = handle_data(uniStatData);
let optionsData = {
usv: STAT_VERSION, //统计 SDK 版本号
t: time, //发送请求时的时间戮
requests: stat_data,
};
// 重置队列
dbRemove('__UNI__STAT__DATA');
// XXX 安卓需要延迟上报 ,否则会有未知错误,需要验证处理
if (get_platform_name() === 'n' && this.statData.p === 'a') {
setTimeout(() => {
this.sendRequest(optionsData);
}, 200);
return
}
this.sendRequest(optionsData);
}
getIsReportData() {
return is_report_data()
}
/**
* 数据上报
* @param {Object} optionsData 需要上报的数据
*/
sendRequest(optionsData) {
{
if (!uni.__stat_uniCloud_space) {
console.error(
'应用未关联服务空间统计上报失败请在uniCloud目录右键关联服务空间.'
);
return
}
const uniCloudObj = uni.__stat_uniCloud_space.importObject(
'uni-stat-receiver',
{
customUI: true,
}
);
uniCloudObj
.report(optionsData)
.then(() => {
if (is_debug) {
log(optionsData, true);
}
})
.catch((err) => {
if (is_debug) {
console.warn('=== 统计上报错误');
console.error(err);
}
});
}
}
/**
* h5 请求
*/
imageRequest(data) {
this.getIsReportData().then(() => {
let image = new Image();
let options = get_sgin(get_encodeURIComponent_options(data)).options;
image.src = STAT_H5_URL + '?' + options;
if (is_debug) {
log(data, true);
}
});
}
sendEvent(key, value) {
// 校验 type 参数
if (calibration(key, value)) return
if (key === 'title') {
this._navigationBarTitle.report = value;
return
}
this.sendEventRequest(
{
key,
value: typeof value === 'object' ? JSON.stringify(value) : value,
},
1
);
}
}
class Stat extends Report {
static getInstance() {
if (!uni.__stat_instance) {
uni.__stat_instance = new Stat();
}
// 2.0 init 服务空间
{
let space = get_space(uniCloud.config);
if (!uni.__stat_uniCloud_space) {
// 判断不为空对象
if (space && Object.keys(space).length !== 0) {
let spaceData = {
provider: space.provider,
spaceId: space.spaceId,
clientSecret: space.clientSecret,
};
if (space.endpoint) {
spaceData.endpoint = space.endpoint;
}
uni.__stat_uniCloud_space = uniCloud.init(spaceData);
// console.log(
// '=== 当前绑定的统计服务空间spaceId' +
// uni.__stat_uniCloud_space.config.spaceId
// )
} else {
console.error('应用未关联服务空间请在uniCloud目录右键关联服务空间');
}
}
}
return uni.__stat_instance
}
constructor() {
super();
}
/**
* 获取推送id
*/
pushEvent(options) {
const ClientID = is_push_clientid();
if (uni.getPushClientId && ClientID) {
uni.getPushClientId({
success: (res) => {
const cid = res.cid || false;
// 只有获取到才会上传
if (cid) {
this.sendPushRequest(options, cid);
}
},
});
}
}
/**
* 进入应用
* @param {Object} options 页面参数
* @param {Object} self 当前页面实例
*/
launch(options, self) {
// 初始化页面停留时间 start
set_page_residence_time();
this.__licationShow = true;
dbSet('__launch_options', options);
// 应用初始上报参数为1
options.cst = 1;
this.sendReportRequest(options, true);
}
load(options, self) {
this.self = self;
this._query = options;
}
appHide(self) {
this.applicationHide(self, true);
}
appShow(self) {
this.applicationShow(self);
}
show(self) {
this.self = self;
if (get_page_types(self) === 'page') {
const isPageReport = is_page_report();
if (isPageReport) {
this.pageShow(self);
}
}
// #ifdef VUE3
if (get_platform_name() === 'h5' || get_platform_name() === 'n') {
if (get_page_types(self) === 'app') {
this.appShow();
}
}
// #endif
// #ifndef VUE3
if (get_page_types(self) === 'app') {
this.appShow();
}
// #endif
}
hide(self) {
this.self = self;
if (get_page_types(self) === 'page') {
const isPageReport = is_page_report();
if (isPageReport) {
this.pageHide(self);
}
}
// #ifdef VUE3
if (get_platform_name() === 'h5' || get_platform_name() === 'n') {
if (get_page_types(self) === 'app') {
this.appHide();
}
}
// #endif
// #ifndef VUE3
if (get_page_types(self) === 'app') {
this.appHide();
}
// #endif
}
error(em) {
// 开发工具内不上报错误
// if (this._platform === 'devtools') {
// if (process.env.NODE_ENV === 'development') {
// console.info('当前运行环境为开发者工具,不上报数据。')
// return
// }
// }
let emVal = '';
if (!em.message) {
emVal = JSON.stringify(em);
} else {
emVal = em.stack;
}
let route = '';
try {
route = get_route();
} catch (e) {
// 未获取到页面路径
route = '';
}
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
p: this.statData.p,
lt: '31',
url: route,
ut: this.statData.ut,
ch: this.statData.ch,
mpsdk: this.statData.mpsdk,
mpv: this.statData.mpv,
v: this.statData.v,
em: emVal,
usv: this.statData.usv,
t: parseInt(new Date().getTime() / 1000),
};
this.request(options);
}
}
var Stat$1 = Stat;
const stat = Stat$1.getInstance();
// 用于判断是隐藏页面还是卸载页面
let isHide = false;
const lifecycle = {
onLaunch(options) {
// 进入应用上报数据
stat.launch(options, this);
// 上报push推送id
stat.pushEvent(options);
},
onLoad(options) {
stat.load(options, this);
// 重写分享,获取分享上报事件
if (this.$scope && this.$scope.onShareAppMessage) {
let oldShareAppMessage = this.$scope.onShareAppMessage;
this.$scope.onShareAppMessage = function (options) {
stat.interceptShare(false);
return oldShareAppMessage.call(this, options)
};
}
},
onShow() {
isHide = false;
stat.show(this);
},
onHide() {
isHide = true;
stat.hide(this);
},
onUnload() {
if (isHide) {
isHide = false;
return
}
stat.hide(this);
},
onError(e) {
stat.error(e);
},
};
// 加载统计代码
function load_stat() {
// #ifdef VUE3
uni.onCreateVueApp((app) => {
app.mixin(lifecycle);
uni.report = function (type, options) {
stat.sendEvent(type, options);
};
});
if (get_platform_name() !== 'h5' && get_platform_name() !== 'n') {
uni.onAppHide(() => {
stat.appHide(get_page_vm());
});
uni.onAppShow(() => {
stat.appShow(get_page_vm());
});
}
// #endif
// #ifndef VUE3
// eslint-disable-next-line no-restricted-globals
const Vue = require('vue')
;(Vue.default || Vue).mixin(lifecycle);
uni.report = function (type, options) {
stat.sendEvent(type, options);
};
// #endif
}
function main() {
if (is_debug) {
{
// #ifndef APP-NVUE
console.log('=== uni统计开启,version:2.0 ===');
// #endif
}
load_stat();
} else {
if (process.env.NODE_ENV === 'development') {
uni.report = function (type, options) {};
} else {
load_stat();
}
}
}
main();