基于uni-app的埋点sdk设计
一、统计app激活状态
在App.vue 中 利用onShow生命周期验证 或者操作
onShow: function () {
uni.showToast({
title: 'onShow'
})
},
二、页面级别的统计 (进入页面、停留时长、手机系统信息、网络状态、页面路径、标题)
需要收集的数据
{
"pageType": "leavePage",
"networkType": "wifi",
"pageInfo": {
"pageUrl": "pages/index/newIndex",
"title": ""
},
"entryTime": "2024-04-10 13:18:50",
"leaveTime": "2024-04-10 13:18:51",
"nowTime": "2024-04-10 13:18:51",
"stayTime": 279,
"sysTemInfo": {
"appName": "某某app",
"appVersion": "2.1.4",
"brand": "apple",
"platform": "ios",
"system": "iOS 17.3.1"
},
"pageLoadTime": 873
}
通过混入mixins 每个页面生命周期埋点统计、编写逻辑方法
三、页面内部事件级别的统计 (各种事件信息集合eventTrack(点击、复制、下载、来源某个特定页面的操作)、 手机系统信息、网络状态、页面路径、标题)
需要收集的数据
{
"networkType": "unknown",
"pageInfo": {
"pageUrl": "pages/order/index",
"title": "订单"
},
"sysTemInfo": {
"appName": "某某app",
"appVersion": "2.1.4",
"brand": "xiaomi",
"platform": "android",
"system": "Android 12"
},
"eventTrack": { // 事件所需要的埋点字段
"eventCode": "B0004"
}
}
通过混入mixins 每个页面生命周期埋点统计、编写逻辑方法
四、具体的设计流程
1、创建 埋点sdk方法 pointCom.js
主要三个方法
myPointPage, 页面级别触发的
toDateDetail, 时间转化函数
myPointEvent, 页面内部事件触发的
详细编码
import { pagesObj } from '@/uni-config/pages.js' // 页面路由和标题的映射map
console.log(pagesObj, 'uni-config')
async function myPointPage(pageType = "", pageUrl = "") {
console.log("埋点", pageType, pageUrl);
let entryTime, leaveTime, stayTime, nowTime;
if (!pageType) return;
if (pageType == "entryPage") {
entryTime = new Date().getTime();
nowTime = new Date().getTime();
leaveTime = null;
uni.setStorageSync("entryTime", entryTime);
} else {
entryTime = uni.getStorageSync("entryTime");
leaveTime = new Date().getTime();
stayTime = leaveTime - entryTime;
nowTime = new Date().getTime();
}
uni.getNetworkType({
success: function (res) {
let networkType = res.networkType;
try {
uni.getSystemInfo({
success: function (res) {
let { appName,
appWgtVersion,
brand,
platform,
system } = res
let data = {
pageType: pageType,
networkType: networkType,
pageInfo: {
pageUrl: pageUrl,
title: pagesObj[pageUrl]
},
entryTime: toDateDetail(entryTime),
leaveTime: toDateDetail(leaveTime),
nowTime: toDateDetail(nowTime),
stayTime: stayTime,
sysTemInfo: {
appName,
appVersion: appWgtVersion,
brand,
platform,
system
},
};
if (pageType === "leavePage") {
data.pageLoadTime = uni.getStorageSync("pageLoadTime");
}
console.log('发送调用埋点接口', data)
},
fail(error) {
sysTemInfo = "null";
},
});
} catch (e) { }
},
});
}
async function myPointEvent(eventTrack = {}, pageUrl = "") {
uni.getNetworkType({
success: function (res) {
let networkType = res.networkType;
try {
uni.getSystemInfo({
success: function (res) {
let { appName,
appWgtVersion,
brand,
platform,
system } = res
let data = {
networkType: networkType,
pageInfo: {
pageUrl: pageUrl,
title: pagesObj[pageUrl]
},
sysTemInfo: {
appName,
appVersion: appWgtVersion,
brand,
platform,
system
},
eventTrack
};
console.log('myPointEvent发送调用埋点接口', data)
},
fail(error) {
sysTemInfo = "null";
},
});
} catch (e) { }
},
});
}
function toDateDetail(number) {
if (!number) return undefined;
// 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;
}
export default {
myPointPage,
toDateDetail,
myPointEvent,
};
2、创建 埋点混入的方法和生命周期 pointMixin.js
主要四个方法
eventTrack, 页面事件调用的函数
entryTrack, 页面进入调用的函数
leaveTrack, 页面离开调用的函数
pageLoadTime 页面onReady调用的函数
详细编码
import pointCom from "@/utils/pointCom.js";
export default {
data() {
return {
pointPageUrl: "", //跳转url
pageType: "", //事件类型 进入、离开
loadStartTime: "", //页面加载开始时间
};
},
onLoad() {
this.entryTrack();
},
onReady() {
this.pageLoadTime();
},
onHide() {
this.leaveTrack();
},
onUnload() {
this.leaveTrack();
},
methods: {
eventTrack(eventTrack = {}) {
console.log('eventTrack', eventTrack, this.pointPageUrl)
let pointPageUrl = getCurrentPages()[getCurrentPages().length - 1].route;
this.pointPageUrl = pointPageUrl;
pointCom.myPointEvent(eventTrack, this.pointPageUrl);
},
entryTrack() {
let loadStartTime = pointCom.toDateDetail(Number(new Date()));
let pointPageUrl = getCurrentPages()[getCurrentPages().length - 1].route;
this.pointPageUrl = pointPageUrl;
this.pageType = "entryPage";
this.loadStartTime = loadStartTime;
pointCom.myPointPage("entryPage", this.pointPageUrl);
},
pageLoadTime() {
let pageLoadTime = Number(new Date()) - new Date(this.loadStartTime).getTime()
console.log("pageLoadTime", pageLoadTime, this.loadStartTime)
uni.setStorageSync("pageLoadTime", pageLoadTime);
},
leaveTrack() {
if (this.pageType === "leavePage") return;
this.pageType = "leavePage";
pointCom.myPointPage("leavePage", this.pointPageUrl);
},
},
};
3、main.js 引入 pointMixin.js
详细编码
import pointMixin from "@/utils/pointMixin"; //配合埋点的mixin
Vue.mixin(pointMixin);
4、得到页面路由和标题的映射map
h5中可以得到标题等数据,但是app中无法获取
// 获取当前页面链接和参数
function getCurrentPageUrlWithArgs() {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const route = currentPage?.route;
const options = currentPage?.options || {};
const title = currentPage?.$holder?.navigationBarTitleText || ''
console.log(title)
let urlWithArgs = /${route}?;
for (let key in options) {
const value = options[key];
urlWithArgs += ${key}=${value}&;
}
urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1);
return {
options, //当前页面的参数
urlWithArgs, //当前页面的参数
route,
title,
};
}
app获取相关数据需要另辟蹊径
通过文件的读取和写入来实现
具体编码
const fs = require("fs-extra")
let path = require("path")
let Hjson = require("hjson")
const chokidar = require("chokidar")
let rootPath = (function () {
let e = path.resolve(__dirname, "./")
return e
})()
function creatPagesJs() {
try {
const fileContent = fs.readFileSync('./pages.json', 'utf8');
const jsonObj = Hjson.rt.parse(fileContent);
let pages = jsonObj.pages
let pagesObj = {}
pages.map(item => {
let path = item.path
let title = item?.style?.navigationBarTitleText || ''
pagesObj[path] = title
})
console.log(pagesObj, 'pagesObj')
let pstr = "export const pagesObj = " + JSON.stringify(pagesObj, null, 2);
fs.outputFileSync(
path.resolve(rootPath, "uni-config", "pages.js"),
pstr
);
} catch (err) {
console.log(err);
}
}
const watcherPagesJson = chokidar
.watch(path.resolve(__dirname, "./pages.json"))
watcherPagesJson.on("all", (event, path) => {
console.log(event, path, 'pages.json')
if (event == "change") {
creatPagesJs()
}
})
creatPagesJs();
如何调用 package.json 配置调用命令
"scripts": {
"getPages": "node getPages.js"
},
相关文章:
基于uni-app的埋点sdk设计
一、统计app激活状态 在App.vue 中 利用onShow生命周期验证 或者操作 onShow: function () { uni.showToast({ title: onShow }) }, 二、页面级别的统计 (进入页面、停留时长、手机系统信息、网络状态、页面路径、标题) 需要收集的数据 { &quo…...
Python学习笔记(三)
一、使用朴素贝叶斯制作鸢尾花数据模型 from sklearn.preprocessing import StandardScaler from sklearn.naive_bayes import MultinomialNB from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.feature_extraction…...
Python办公自动化之Excel做表自动化:全网最全,看这一篇就够了!
0 Python Excel库对比 我们先来看一下python中能操作Excel的库对比(一共九个库): 1 Python xlrd 读取 操作Excel 1.1 xlrd模块介绍 (1)什么是xlrd模块? python操作excel主要用到xlrd和xlwt这两个库&…...
【学习笔记】R语言入门与数据分析1
数据分析 数据分析的过程: 数据采集 数据存储 数据分析 数据挖掘 数据可视化 进行决策 数据挖掘 数据量大 复杂度高,容忍一定的误差限 追求相关性而非因果性 数据可视化 直观明了 R语言介绍 R是免费的(开源软件、扩展性好)…...
MyBatis-Spring整合
引入Spring之前需要了解mybatis-spring包中的一些重要类; http://www.mybatis.org/spring/zh/index.html 什么是 MyBatis-Spring? MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。 知识基础 在开始使用 MyBatis-Spring 之前&#x…...
资深亚马逊运营实战技巧:跨境电商6大选品法
1、工具选品法 比如店雷达, 通过大数据分析工具选出来利基产品或者通过工具选出来利基的市场,然后再通过分析市场来得到产品。 以女装为例,通过大数据分析,全方位对市场需求、款式、质量等进行多维度判断,其中SKU销量…...
bugku-web-需要管理员
页面源码 <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>404 Not Found</title> </head> <body> <div idmain><i> <h2>Something error:</h2…...
STM32之FreeRTOS移植
1.FreeRTOS的移植过程是将系统需要的文件和代码进行移植和裁剪,其移植的主要过程为: (1)官网上下载FreeRTOS源码:https://www.freertos.org/ (2)移植文件夹,在portable文件夹中只需…...
SpringBoot实用开发(十四)-- 消息(Message)的简单认识
目录 1.消息的概念 2.Java处理消息的标准规范 3.JMS 4.AMQP 5.MQTT 1.消息的概念 广义角度来说,消息其实就是信息,但是和信息又有所不同。信息通常被定义为一组数据,而消息除了具有数据的特征之外,还有...
【Spring Boot 源码学习】SpringApplication 的 run 方法核心流程介绍
《Spring Boot 源码学习系列》 SpringApplication 的 run 方法核心流程介绍 一、引言二、往期内容三、主要内容3.1 run 方法源码初识3.2 引导上下文 BootstrapContext3.3 系统属性【java.awt.headless】3.4 早期启动阶段3.5 准备和配置应用环境3.6 打印 Banner 信息3.7 新建应用…...
如何保证消息不丢失?——使用rabbitmq的死信队列!
如何保证消息不丢失?——使用rabbitmq的死信队列! 1、什么是死信 在 RabbitMQ 中充当主角的就是消息,在不同场景下,消息会有不同地表现。 死信就是消息在特定场景下的一种表现形式,这些场景包括: 消息被拒绝访问&am…...
html、css、京东移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示
CSDN将我上传的免费资源私自变成VIP专享资源,且作为作者的我不可修改为免费资源,不可删除,寻找客服无果,很愤怒,(我发布免费资源就是希望大家能免费一起用、一起学习),接下来继续寻找…...
头歌-机器学习 第13次实验 特征工程——共享单车之租赁需求预估
第1关:数据探索与可视化 任务描述 本关任务:编写python代码,完成一天中不同时间段的平均租赁数量的可视化功能。 相关知识 为了完成本关任务,你需要掌握: 读取数据数据探索与可视化 读取数据 数据保存在./step1/…...
Unity 2D让相机跟随角色移动
相机跟随移动 最简单的方式通过插件Cinemachine 在窗口/包管理器选择全部找到Cinemachine,导入。然后在游戏对象/Cinemachine创建2D Camera。此时层级中创建一个2D相机。选中人物拖入检查器Follow。此时相机跟随人物移动。 修改相机视口距离 在检查器中Lens下调正…...
【面试题】s += 1 和 s = s + 1的区别
文章目录 1.问题2.发现过程3.解析 1.问题 以下两个程序真的完全等同吗? short s 0; s 1; short s 0; s s 1; 2.发现过程 初看s 1 和 s s 1好像是等价的,没有什么区别。很长一段时间内我也是这么觉得,因为当时学习c语言的时候教科书…...
ARM的学习
点亮流水灯 .text .global _start _start: 使能GPIOE的外设时钟 RCC_MP_AHB4ENSETR 0x50000a28 [4]->1LDR R0,0X50000A28 指定基地址LDR R1,[R0] 将寄存器数据读取出来保存到R1中ORR R1,R1,#(0x3<<4) [4]设置为1ORR R1,R1,#(0x3<<5) [5]设置为1STR …...
Restful API接口规范(以Django为例)
Restful API接口规范(以Django为例) Restful API的接口架构风格中制定了一些规范,极大的简化了前后端对接的时间,以及增加了开发效率 安全性保证–使用https路径中带 api标识路径中带版本号数据即资源,通常使用名词操作请求方式决定操作资源…...
AI助力,程序员压力倍增?
讲动人的故事,写懂人的代码 你知道程序员现在在AI辅助编程时最头疼的事情是什么吗?就是怎么在改代码的时候保住小命。 大家都听过程序员因为工作太累导致过劳湿的事情。 无论是写新功能、修bug,还是更改系统配置,都得改代码。 现在有了AI的帮助,本应该轻松很多,为什么…...
LoRA微调
论文:LoRA: Low-Rank Adaptation of Large Language Models 实现:microsoft/LoRA: Code for loralib, an implementation of “LoRA: Low-Rank Adaptation of Large Language Models” (github.com) 摘要 自然语言处理的一个重要的开发范式包括&#…...
45.基于SpringBoot + Vue实现的前后端分离-驾校预约学习系统(项目 + 论文)
项目介绍 本站是一个B/S模式系统,采用SpringBoot Vue框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SpringBoot Vue技术的驾校预约学习系统设计与实现管理工作…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...
