You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.5 KiB
183 lines
5.5 KiB
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
|
|
import { useRouter } from "vue-router";
|
|
import {
|
|
computedUsersAPI,
|
|
useAiGodAPI,
|
|
updateStayTimeAPI,
|
|
addUsageAPI,
|
|
} from "@/api/AIxiaocaishen";
|
|
|
|
export function useProjectTracking(projectRoutes) {
|
|
const router = useRouter();
|
|
const entryTime = ref(Date.now());
|
|
const isInProject = ref(true);
|
|
const hasRecordedEntry = ref(
|
|
sessionStorage.getItem("hasRecordedEntry") === "true"
|
|
);
|
|
// const parentUrl = window.parent.location.href
|
|
// console.log('Link平台地址:', parentUrl)
|
|
|
|
let isPageRefreshing = false; // 标志位:是否刷新页面
|
|
|
|
// 记录用户进入项目的时间
|
|
const recordEntryTime = () => {
|
|
if (hasRecordedEntry.value) {
|
|
return;
|
|
}
|
|
|
|
entryTime.value = Date.now();
|
|
const date = new Date(entryTime.value);
|
|
const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1)
|
|
.toString()
|
|
.padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")} ${date
|
|
.getHours()
|
|
.toString()
|
|
.padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}:${date
|
|
.getSeconds()
|
|
.toString()
|
|
.padStart(2, "0")}`;
|
|
sessionStorage.setItem("projectEntryTime", formattedDate);
|
|
sessionStorage.setItem("hasRecordedEntry", "true");
|
|
isInProject.value = true;
|
|
hasRecordedEntry.value = true;
|
|
|
|
const token = localStorage.getItem("localToken");
|
|
if (token) {
|
|
const result = useAiGodAPI({
|
|
token: token,
|
|
});
|
|
console.log(result);
|
|
// const result2 = addUsageAPI({
|
|
// token: token,
|
|
// })
|
|
// console.log(result2);
|
|
} else {
|
|
console.log("没有token");
|
|
}
|
|
console.log("记录首次进入时间:", formattedDate);
|
|
};
|
|
|
|
// 发送追踪数据到后端
|
|
const sendTrackingData = async () => {
|
|
if (!isInProject.value) return;
|
|
|
|
const storedEntryTime = sessionStorage.getItem("projectEntryTime");
|
|
if (!storedEntryTime) {
|
|
console.warn("未找到存储的进入时间,取消发送跟踪数据");
|
|
return;
|
|
}
|
|
|
|
let timestamp;
|
|
try {
|
|
timestamp = new Date(storedEntryTime.replace(" ", "T")).getTime();
|
|
if (isNaN(timestamp)) throw new Error("无效日期");
|
|
} catch (error) {
|
|
console.error("解析存储的进入时间时出错:", error);
|
|
return;
|
|
}
|
|
|
|
const exitTime = Date.now();
|
|
const duration = Math.floor((exitTime - timestamp) / 1000);
|
|
const localToken = localStorage.getItem("localToken");
|
|
console.log("进入项目的时间", storedEntryTime);
|
|
console.log("停留时间", duration);
|
|
|
|
const params = {
|
|
stayTime: duration,
|
|
// loginTime: storedEntryTime,
|
|
token: localToken,
|
|
};
|
|
|
|
if (localToken) {
|
|
try {
|
|
const res = await updateStayTimeAPI(params);
|
|
console.log("跟踪数据已发送:", res);
|
|
sessionStorage.removeItem("projectEntryTime");
|
|
sessionStorage.removeItem("hasRecordedEntry");
|
|
isInProject.value = false;
|
|
hasRecordedEntry.value = false;
|
|
} catch (error) {
|
|
console.error("发送跟踪数据失败:", error);
|
|
}
|
|
}
|
|
};
|
|
|
|
// 页面可见性变化时触发
|
|
const handleVisibilityChange = () => {
|
|
// console.log(window.location.pathname.includes('duobaoqibing'), '路径是否包含了页面不可见触发')
|
|
// if (window.location.pathname.includes('duobaoqibing')) {
|
|
// console.log('在 searchCode.html 页面,不发送数据')
|
|
// return
|
|
// }
|
|
if (document.visibilityState === "hidden") {
|
|
console.log("页面不可见,用户可能离开或切换标签页");
|
|
sendTrackingData();
|
|
}
|
|
};
|
|
|
|
// 页面关闭或刷新时触发
|
|
const handleBeforeUnload = (event) => {
|
|
// console.log(window.location.pathname)
|
|
// console.log(
|
|
// window.location.pathname.includes('duobaoqibing'),
|
|
// '路径是否包含了页面关闭了啦啦啦啦啦啦触发'
|
|
// )
|
|
// if (window.location.pathname.includes('duobaoqibing')) {
|
|
// console.log('在 searchCode.html 页面,不发送数据')
|
|
// return
|
|
// }
|
|
if (isPageRefreshing) {
|
|
console.log('页面刷新,不触发数据发送')
|
|
return
|
|
}
|
|
|
|
console.log("页面即将关闭或跳转");
|
|
sendTrackingData();
|
|
};
|
|
|
|
const handleRefreshDetection = () => {
|
|
isPageRefreshing = true;
|
|
};
|
|
|
|
// 监听路由变化
|
|
watch(
|
|
() => router.currentRoute.value.path,
|
|
(newPath) => {
|
|
const isProjectRoute = projectRoutes.some((route) =>
|
|
newPath.startsWith(route)
|
|
);
|
|
let isProjectRouteName = projectRoutes[0];
|
|
console.log(isProjectRouteName);
|
|
// 判断是否是 searchCode.html 的访问
|
|
const isSearchCodePage =
|
|
window.location.pathname.includes("duobaoqibing");
|
|
if (!isProjectRoute && !isSearchCodePage) {
|
|
console.log("离开项目路由:", newPath);
|
|
sendTrackingData();
|
|
} else if (isProjectRouteName && !hasRecordedEntry.value) {
|
|
console.log("首次进入项目路由:", newPath);
|
|
recordEntryTime();
|
|
}
|
|
}
|
|
);
|
|
|
|
// 添加事件监听
|
|
onMounted(() => {
|
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
window.addEventListener("unload", handleRefreshDetection);
|
|
});
|
|
|
|
// 移除事件监听
|
|
onBeforeUnmount(() => {
|
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
window.removeEventListener("unload", handleRefreshDetection);
|
|
});
|
|
|
|
return {
|
|
entryTime,
|
|
isInProject,
|
|
sendTrackingData,
|
|
};
|
|
}
|