refactor(sensors): 重构神策数据采集逻辑

- 移除了全局的 pageStayTime 变量和相关的页面停留时间采集逻辑
- 在 AD 和 Home 组件中添加了具体的神策数据采集函数
- 优化了 banner 点击事件的数据采集
- 删除了不必要的神策数据插件配置
This commit is contained in:
黄泽-huangze-天津易商数智
2025-06-18 15:15:07 +08:00
parent ec278a03b7
commit acc02c5a75
3 changed files with 53 additions and 66 deletions

View File

@@ -32,30 +32,12 @@ declare global {
}
}
// 页面停留时间
let pageStayTime = 0;
// 定义路由是否可以返回的判断
const routerCanGoBack = () => {
const position = router.options.history.state?.position;
return typeof position === 'number' && position > 0;
};
router.beforeEach((to, from, next) => {
// 离开页面的时候结束记录时间
const duration = Date.now() - pageStayTime;
pageStayTime = 0;
const collectUrl = ['/ad/', '/share/'];
console.log(`is collect page`, collectUrl.some((url) => from.path.startsWith(url)));
// 判断是否离开需要采集的页面
if (collectUrl.some((url) => from.path.startsWith(url))) {
// alert(`duration: ${duration}`);
const sensors = inject<any>('sensors');
sensors.track('pageStayTime', {
duration
});
}
if (to.meta?.title) document.title = to.meta.title as string;
if (to.query.digitalYiliToken) {
@@ -73,37 +55,8 @@ router.beforeEach((to, from, next) => {
next();
});
router.afterEach((to, from) => {
// 页面导航结束的时候开始记录时间
pageStayTime = Date.now();
});
app.use(createPinia());
app.use(router);
// 神策数据插件
app.use(sensorsData(), {
// 单页面配置,默认关闭。开启后自动监听 URL 有变化就会触发 $pageview 事件
is_track_single_page: function () {
return false;
},
scrollmap: {
// Web 视区停留
collect_url: function () {
// 需要采集的页面
const urls = ['/ad/', '/share/'];
console.log(`collect_url`, isCollectUrl(urls));
return isCollectUrl(urls);
}
},
heatmap: {
//是否开启触达图default 表示开启,自动采集 $WebStay 事件,可以设置 'not_collect' 表示关闭。
//需要 Web JS SDK 版本号大于 1.9.1
scroll_notice_map: 'default',
scroll_delay_time: 4000,
//单位秒,预置属性停留时长 event_duration 的最大值。默认5个小时也就是300分钟18000秒。
scroll_event_duration: 18000,
get_vtrack_config: true
}
});
app.use(sensorsData());
app.mount('#app');

View File

@@ -1,26 +1,40 @@
<script setup lang="ts">
import { fetchBanners } from '@/hooks/request/banner';
import { computed } from 'vue';
import { computed, inject } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const { banners } = fetchBanners();
const route = useRoute();
const bannerInfo = computed(() => {
// console.log(banners.value);
return banners.value?.find((item: any) => item.code === route.params.code);
});
// 当前是否处于分享页面
const hasShare = defineModel<boolean>('hasShare', { default: false });
// 上层注入的神策对象
const sensors = inject<any>('sensors');
function handleButtonClick() {
saTrack(bannerInfo.value);
if (!bannerInfo.value?.url) {
router.push({ name: 'intelligentGeneration' });
return;
}
window.location.href = bannerInfo.value?.url;
}
function saTrack(record: any) {
const config = {
eventName: 'ClickBanner',
properties: {
page: '落地页',
module: 'ad',
position: 'banner点击_' + record.code,
clickTime: new Date().toLocaleString().toString()
}
};
sensors.track(config.eventName, config.properties);
}
/**
* 在挂载之后重新修改 html title 内容
*/

View File

@@ -2,7 +2,7 @@
import { useRouter } from 'vue-router';
import { bannerInfo } from '@/views/AD/hooks/useAD';
import { fetchBanners } from '@/hooks/request/banner';
import { computed } from 'vue';
import { computed, inject } from 'vue';
const { banners } = fetchBanners();
@@ -17,13 +17,31 @@ const stack = defineModel<boolean>('stack', { default: true });
const bannersList = defineModel<any[]>('banners');
// 是否存在显示显示数量
const limit = defineModel<number>('limit');
// 上层注入的神策对象
const sensors = inject<any>('sensors');
function handleBannerClick(banner: any) {
// 把对应的信息给 AD 的 hooks
bannerInfo.value = banner;
saTrack(banner);
router.push({ name: 'ad', params: { code: banner.code } });
}
function saTrack(record: any) {
const config = {
eventName: 'ClickBanner',
properties: {
page: '首页',
module: 'Banner',
position: 'Banner点击',
imgID: record.code,
clickTime: new Date().toLocaleString().toString()
}
};
sensors.track(config.eventName, config.properties);
}
const currentBanners = computed(() => {
if (bannersList.value) {
return stack.value ? bannersList.value : bannersList.value?.slice(0, limit.value);
@@ -33,8 +51,9 @@ const currentBanners = computed(() => {
</script>
<template>
<div class="slider-container">
<van-swipe :autoplay="5000" indicator-color="white" v-if="stack">
<van-swipe-item v-for="banner in currentBanners" :key="banner.code" v-sa-track:banner>
<van-swipe-item v-for="banner in currentBanners" :key="banner.code">
<el-image
class="img"
:style="{ borderRadius: borderRadius + 'px' }"
@@ -55,6 +74,7 @@ const currentBanners = computed(() => {
@click="handleBannerClick(banner)"
/>
</div>
</div>
</template>
<style lang="scss" scoped>