diff --git a/package.json b/package.json index bfb472ca70a7ad250a96f9fe5012f37a06482a19..41587ee3c1d7c67b351a3eec958307e28d90a73a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@kangc/v-md-editor": "^2.3.18", + "@opensig/open-analytics": "^0.0.9", "axios": "^1.6.8", "element-plus": "^2.3.4", "js-base64": "^3.7.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9a3c9ed4aa488ccc892bacbfdc704186817b38f..89adf13f1738579735ef7551eb9e624db7312eb8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,9 @@ importers: '@kangc/v-md-editor': specifier: ^2.3.18 version: 2.3.18(@vue/compiler-sfc@3.3.4)(vue@3.3.4) + '@opensig/open-analytics': + specifier: ^0.0.9 + version: 0.0.9 axios: specifier: ^1.6.8 version: 1.6.8 @@ -389,6 +392,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@opensig/open-analytics@0.0.9': + resolution: {integrity: sha512-D+4VWxgBc1ABsQjWEjWfBfoBQ4PQbc1lNZeEYpQXkTJLLFcj6nSa+LwcYZFXtZdGz9dzOhhbwRwXv66WFw2qJw==} + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -2516,6 +2522,10 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + ua-parser-js@1.0.40: + resolution: {integrity: sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==} + hasBin: true + uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} @@ -2630,6 +2640,10 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -2706,6 +2720,9 @@ packages: vue@3.3.4: resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + web-vitals@4.2.4: + resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} + web-worker@1.3.0: resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} @@ -3119,6 +3136,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + '@opensig/open-analytics@0.0.9': + dependencies: + ua-parser-js: 1.0.40 + uuid: 10.0.0 + web-vitals: 4.2.4 + '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 @@ -5391,6 +5414,8 @@ snapshots: typescript@4.9.5: {} + ua-parser-js@1.0.40: {} + uc.micro@1.0.6: {} ufo@1.1.2: {} @@ -5530,6 +5555,8 @@ snapshots: util-deprecate@1.0.2: {} + uuid@10.0.0: {} + uuid@9.0.1: {} uvu@0.5.6: @@ -5600,6 +5627,8 @@ snapshots: '@vue/server-renderer': 3.3.4(vue@3.3.4) '@vue/shared': 3.3.4 + web-vitals@4.2.4: {} + web-worker@1.3.0: {} webpack-chain@4.12.1: diff --git a/src/api/api-analytics.ts b/src/api/api-analytics.ts new file mode 100644 index 0000000000000000000000000000000000000000..2fcdae9fdb7ee3b1e939b552fa631d6f7b936ace --- /dev/null +++ b/src/api/api-analytics.ts @@ -0,0 +1,7 @@ +import { request } from '@/shared/axios'; + +export function reportAnalytics(data: Record) { + return request.post('/api-dsapi/query/track/openeuler', data, { + $doException: false, + }); +} diff --git a/src/main.ts b/src/main.ts index 927292315e3493b635b2e4e6f225e914cd50b7dd..7911140dc2fa3347f27dd1d24532e2df9fe59d78 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ import Prism from 'prismjs'; import App from './App.vue'; import OpenDesign from 'opendesign'; +import { enableOA, reportPerformance } from './shared/analytics'; VueMarkdownEditor.use(vuepressTheme, { Prism, @@ -25,4 +26,7 @@ app.use(OpenDesign); app.use(router); app.use(VueMarkdownEditor); +enableOA(); +reportPerformance(); + app.mount('#app'); diff --git a/src/routers/index.ts b/src/routers/index.ts index d1c09e3b2014bcc997e2c39aada6fd5f3843f924..77059dbb2005f572fab0aa6bacb4ef71d5bbc7d9 100644 --- a/src/routers/index.ts +++ b/src/routers/index.ts @@ -1,5 +1,6 @@ import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; -import { useLangStore } from '@/stores'; +import { useLangStore, usePrevPageUrl } from '@/stores'; +import { reportPV } from '@/shared/analytics'; export const routes: RouteRecordRaw[] = [ { path: '/', redirect: '/zh/issues' }, @@ -33,9 +34,20 @@ export const router = createRouter({ }, }); -router.beforeEach((to) => { +router.beforeEach((to, from) => { // 设置语言 const langStore = useLangStore(); const lang = to.fullPath.includes('en') ? 'en' : 'zh'; langStore.lang = lang; + + if (from.path === '/') { + return; + } + usePrevPageUrl().url = window.location.href; +}); + +router.afterEach((to, from) => { + if (to.path !== from.path) { + reportPV(usePrevPageUrl().url); + } }); diff --git a/src/shared/analytics.ts b/src/shared/analytics.ts new file mode 100644 index 0000000000000000000000000000000000000000..91108474f92172b3208ac22e1acf6a6b9406f50a --- /dev/null +++ b/src/shared/analytics.ts @@ -0,0 +1,58 @@ +import { + OpenAnalytics, + OpenEventKeys, + getClientInfo, +} from '@opensig/open-analytics'; +import { reportAnalytics } from '@/api/api-analytics'; + +export const oa = new OpenAnalytics({ + appKey: 'openEuler', + request: (data) => { + reportAnalytics(data); + }, +}); + +export const enableOA = () => { + oa.setHeader(getClientInfo()); + oa.enableReporting(true); +}; + +export const disableOA = () => { + oa.enableReporting(false); +}; + +export const reportPV = ($referrer?: string) => { + oa.report(OpenEventKeys.PV, $referrer ? () => ({ $referrer }) : undefined); +}; + +export const reportPerformance = () => { + oa.report(OpenEventKeys.LCP); + oa.report(OpenEventKeys.INP); + oa.report(OpenEventKeys.PageBasePerformance); +}; + +export const oaReport = async >( + event: string, + eventData?: T | ((...opt: any[]) => Promise | T), + $service = 'quickissue', + options?: { + immediate?: boolean; + eventOptions?: any; + } +) => { + let data: T | undefined; + if (eventData) { + data = + typeof eventData === 'function' + ? await (eventData as (...opt: any[]) => Promise | T)() + : eventData; + } + await oa.report( + event, + () => ({ + $service, + ...data, + }), + options + ); +}; diff --git a/src/stores/index.ts b/src/stores/index.ts index a7aa0a79b82ac25d0f7eb0f290352db7d3fa1a44..e34602921d09e1d18f67d1d6d6dfc0d6edf70c58 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -30,3 +30,9 @@ export const useLabelColor = defineStore('color', { }, }, }); + +export const usePrevPageUrl = defineStore('analytics', { + state: () => ({ + url: '', + }), +}); diff --git a/src/views/submit-issue/SubmitIssue.vue b/src/views/submit-issue/SubmitIssue.vue index 71ab313833c13743cb835cb6c3efaa11ece04fe6..5bd71b533635c669e0fd81ea2f8a0d1357167313 100644 --- a/src/views/submit-issue/SubmitIssue.vue +++ b/src/views/submit-issue/SubmitIssue.vue @@ -38,6 +38,7 @@ import type { FormInstance, TabsPaneContext } from 'element-plus'; import IconGitee from '~icons/app/icon-gitee.svg'; import IconDown from '~icons/app/icon-pulldown.svg'; import IconSearch from '~icons/app/icon-search.svg'; +import { oaReport } from '@/shared/analytics'; interface TypesList { id: number; @@ -216,6 +217,10 @@ async function goGitee(verify: FormInstance | undefined) { verify.validate(async (res: boolean) => { if (res) { const url = `${giteeUrl}/${issueData.repo}/issues/new?title=${issueData.title}&issue%5Bissue_type_id%5D=${issueData.issue_type_id}`; + oaReport('toGiteeCreateIssue', { + $utm_source: 'quick_issue', + jump_url: url, + }); window.open(url); } }); @@ -260,6 +265,11 @@ function handelCreatIssue( createIssue(parmes).then(async (res) => { if (res.code === 200) { const jump_url = `${giteeUrl}/${issueData.repo}/issues/${res.data.number}`; + oaReport('noGiteeCreateIssue', { + $utm_source: 'quick_issue', + jump_url, + quick_issue_email: parmes.email, + }); if (isGoGitee) { window.open(jump_url); }