feat: 添加埋点
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/logo.jpg"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Type Words</title>
|
||||
<script defer src="https://cloud.umami.is/script.js" data-website-id="160308c9-7900-4b1d-a0b1-c3b25a9530f6"></script>
|
||||
<script>
|
||||
;(function () {
|
||||
var src = '//cdn.jsdelivr.net/npm/eruda';
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
"tesseract.js": "^4.1.4",
|
||||
"unplugin-element-plus": "^0.10.0",
|
||||
"vue": "^3.5.17",
|
||||
"vue-activity-calendar": "^1.2.2",
|
||||
"vue-router": "^4.5.1",
|
||||
"vue-virtual-scroller": "2.0.0-beta.8"
|
||||
},
|
||||
|
||||
8
src/global.d.ts
vendored
8
src/global.d.ts
vendored
@@ -1,5 +1,3 @@
|
||||
import {cloneDeep} from "@/utils"
|
||||
|
||||
export {}
|
||||
|
||||
declare global {
|
||||
@@ -8,6 +6,12 @@ declare global {
|
||||
|
||||
json(v: any, space: number): void
|
||||
}
|
||||
|
||||
interface Window {
|
||||
umami: {
|
||||
track(name:string,data?:any):void
|
||||
}
|
||||
}
|
||||
}
|
||||
console.json = function (v: any, space = 0) {
|
||||
const json = JSON.stringify(
|
||||
|
||||
@@ -37,8 +37,15 @@ function startStudy() {
|
||||
if (!base.sbook.articles.length) {
|
||||
return ElMessage.warning('没有文章可学习!')
|
||||
}
|
||||
window.umami.track('startStudyArticle', {
|
||||
name: base.sbook.name,
|
||||
index: base.sbook.lastLearnIndex,
|
||||
custom: base.sbook.custom,
|
||||
complete: base.sbook.complete,
|
||||
})
|
||||
nav('/study-article')
|
||||
} else {
|
||||
window.umami.track('no-book')
|
||||
ElMessage.warning('请先选择一本书籍')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {Icon} from '@iconify/vue'
|
||||
import {ActivityCalendar} from "vue-activity-calendar";
|
||||
import "vue-activity-calendar/style.css";
|
||||
import {useRouter} from "vue-router";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Dialog from "@/pages/pc/components/dialog/Dialog.vue";
|
||||
import {_dateFormat, _getAccomplishDate, _getAccomplishDays, _getDictDataByUrl, useNav} from "@/utils";
|
||||
import {_getAccomplishDate, _getAccomplishDays, _getDictDataByUrl, useNav} from "@/utils";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import {DictResource} from "@/types/types.ts";
|
||||
import {onMounted, watch} from "vue";
|
||||
@@ -50,8 +48,16 @@ function startStudy() {
|
||||
if (!store.sdict.words.length) {
|
||||
return ElMessage.warning('没有单词可学习!')
|
||||
}
|
||||
window.umami.track('startStudyDict', {
|
||||
name: store.sdict.name,
|
||||
index: store.sdict.lastLearnIndex,
|
||||
perDayStudyNumber: store.sdict.perDayStudyNumber,
|
||||
custom: store.sdict.custom,
|
||||
complete: store.sdict.complete,
|
||||
})
|
||||
nav('study-word', {}, currentStudy)
|
||||
} else {
|
||||
window.umami.track('no-dict')
|
||||
ElMessage.warning('请先选择一本词典')
|
||||
}
|
||||
}
|
||||
@@ -107,50 +113,6 @@ function toggleSelect(item) {
|
||||
}
|
||||
}
|
||||
|
||||
// 统计所有词典的学习日期
|
||||
const allStudyDays = $computed(() => {
|
||||
const dateCountMap = new Map<string, { count: number, spend: number }>();
|
||||
store.word.bookList.forEach(dict => {
|
||||
if (Array.isArray(dict.statistics)) {
|
||||
dict.statistics.forEach(stat => {
|
||||
// 格式化为 'YYYY-MM-DD'
|
||||
const date = _dateFormat(stat.startDate, 'YYYY-MM-DD');
|
||||
if (!date) return;
|
||||
// spend 直接累加原始毫秒数
|
||||
const spend = Number(stat.spend || stat.speed) || 0;
|
||||
if (!dateCountMap.has(date)) {
|
||||
dateCountMap.set(date, {count: 1, spend});
|
||||
} else {
|
||||
const v = dateCountMap.get(date)!;
|
||||
v.count += 1;
|
||||
v.spend += spend;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// 转为 [{ date, count, spend }]
|
||||
return Array.from(dateCountMap.entries()).map(([date, {count, spend}]) => ({date, count, spend}));
|
||||
});
|
||||
|
||||
function clickActivityEvent(e) {
|
||||
// e.date 是 'YYYY-MM-DD'
|
||||
const day = allStudyDays.find(item => item.date === e.date);
|
||||
if (day) {
|
||||
// 这里将毫秒转为分钟和小时
|
||||
const min = Math.round(day.spend / 1000 / 60);
|
||||
let msg = '';
|
||||
if (min < 60) {
|
||||
msg = ` 学习了${min}分钟`;
|
||||
} else {
|
||||
const hour = (min / 60).toFixed(1);
|
||||
msg = ` 学习了${min}分钟(约${hour}小时)`;
|
||||
}
|
||||
ElMessage.success(e.date + msg);
|
||||
} else {
|
||||
ElMessage.info('当天无学习记录');
|
||||
}
|
||||
}
|
||||
|
||||
const progressTextLeft = $computed(() => {
|
||||
if (store.sdict.complete) return '已学完,进入总复习阶段'
|
||||
return '已学习' + store.currentStudyProgress + '%'
|
||||
@@ -168,8 +130,9 @@ const progressTextRight = $computed(() => {
|
||||
<div class="card flex gap-10">
|
||||
<div class="flex-1 flex flex-col gap-2">
|
||||
<div class="flex">
|
||||
<div class="bg-third px-3 h-14 rounded-md flex items-center " >
|
||||
<span @click="goDictDetail(store.sdict)" class="text-xl font-bold cursor-pointer">{{ store.sdict.name || '请选择词典开始学习' }}</span>
|
||||
<div class="bg-third px-3 h-14 rounded-md flex items-center ">
|
||||
<span @click="goDictDetail(store.sdict)"
|
||||
class="text-xl font-bold cursor-pointer">{{ store.sdict.name || '请选择词典开始学习' }}</span>
|
||||
<BaseIcon title="切换词典"
|
||||
:icon="store.sdict.name ? 'gg:arrows-exchange' : 'fluent:add-20-filled'"
|
||||
class="ml-4"
|
||||
@@ -248,23 +211,6 @@ const progressTextRight = $computed(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
已学习 <span class="text-3xl">{{ allStudyDays.length }}</span> 天
|
||||
</div>
|
||||
<div class="center">
|
||||
<ActivityCalendar :data="allStudyDays"
|
||||
:width="40"
|
||||
:height="7"
|
||||
:cellLength="16"
|
||||
:cellInterval="8"
|
||||
:fontSize="12"
|
||||
:showLevelFlag="true"
|
||||
:showWeekDayFlag="true"
|
||||
:clickEvent="clickActivityEvent"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog v-model="show" title="每日目标" :footer="true" @ok="changePerDayStudyNumber">
|
||||
<div class="target-modal color-main">
|
||||
<div class="center text-2xl gap-2">
|
||||
|
||||
Reference in New Issue
Block a user