[Human] chore(project): 初始化导入 91dj H5 客户端项目代码

从本地工程首次入库;.npmrc(含私有 npm 源 token)与 tsbuildinfo 已加入 .gitignore,不随仓库提交。
This commit is contained in:
谢宇宁
2026-10-08 14:22:35 +07:00
commit eada71e211
1421 changed files with 144498 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
import { EventName } from './eventDefs';
import { track } from '@/plugins/tracker';
export interface AdImpressionType {
page_key?: string;
page_name?: string;
ad_type?: string;
}
export function setAdImpression(
El: HTMLElement,
advList: Types.App.AdsInfoListItem[],
impression: AdImpressionType,
batchType?: string,
) {
// 已曝光去重(避免同广告组件重复上报)
let hasReported = false;
// 监听广告是否在可视区域在进行上报
const setupObserver = () => {
if (!El) return;
const newObserver = new IntersectionObserver(
(entries) => {
const entry = entries[0];
if (entry.isIntersecting && !hasReported) {
triggerReport();
newObserver.disconnect();
}
},
{ threshold: 0.3 },
);
// 首次加载已在可视区域上报一次
requestAnimationFrame(() => {
// vat-tabs类型验证是否进行首屏上报,其余检测均首屏上报
if (!isInActiveTab()) return;
const rect = El.getBoundingClientRect();
const inView = rect.top < window.innerHeight * 0.7 && rect.bottom > window.innerHeight * 0.3;
if (inView && !hasReported) {
triggerReport();
newObserver.disconnect();
}
});
newObserver.observe(El);
};
const isInActiveTab = () => {
let currentPane = El.closest('.van-tabs__content');
if (!currentPane) return true; // 不在 tabs 中,允许直接上报
// 从广告所在的这一层开始,一层一层往上判断
while (currentPane) {
const tabs = currentPane.closest('.van-tabs') as Element;
if (!tabs) break; // 到顶层 tabs 了
// 找本层 tabs 的 nav
const nav = tabs.querySelector(':scope > .van-tabs__wrap > .van-tabs__nav');
if (!nav) return true; // 没有 nav,说明这层不是使用的可切换 tab
// 获取本层所有 tab
const tabList = Array.from(nav.querySelectorAll('.van-tab'));
// 找本层选中 tab
const activeTab = tabList.find((tab) => tab.getAttribute('aria-selected') === 'true');
if (!activeTab) return false;
const activeId = activeTab.getAttribute('aria-controls');
if (!activeId) return false;
// 在当前 tabs-content 下找对应的 swipe-item
const swipeItems = Array.from(
tabs.querySelectorAll(':scope > .van-tabs__content > .van-swipe > .van-swipe__track > .van-swipe-item'),
);
const matchedItem = swipeItems.find((item) => item.id === activeId);
if (!matchedItem) return false;
// 判断 active swipe-item 是否是当前可见项
if (matchedItem.getAttribute('aria-hidden') === 'true') {
return false; // 未显示,不首屏上报
}
// 判断广告是否属于这一层选中的 tab 范围内
// 当前广告所在 pane 必须在 matchedItem 里面
if (!matchedItem.contains(El)) {
return false;
}
// 下一层:往上继续递归检测
currentPane = tabs.closest('.van-tabs__content');
}
return true; // 所有层都 valid,允许上报
};
//广告展示页面埋点
const triggerReport = () => {
hasReported = true;
if (advList.length) {
const adIds = advList.map((i) => i.id).join(',');
if (batchType == 'payload') {
track([
{
event: EventName.AdImpression,
ad_slot_key: String(advList[0].position),
ad_slot_name: advList[0].positionName,
ad_id: adIds,
creative_id: '',
page_key: impression.page_key,
page_name: impression.page_name,
ad_type: impression.ad_type,
},
]);
} else {
track({
event: EventName.AdImpression,
ad_slot_key: String(advList[0].position),
ad_slot_name: advList[0].positionName,
ad_id: adIds,
creative_id: '',
page_key: impression.page_key,
page_name: impression.page_name,
ad_type: impression.ad_type,
});
}
}
};
return {
setupObserver,
};
}