From 2232ac4294c40cbff595928789eacabf88950175 Mon Sep 17 00:00:00 2001 From: zyronon Date: Wed, 10 Sep 2025 00:16:36 +0800 Subject: [PATCH 1/4] feat:only report errors on the official website --- index.html | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 85f6e0dc..da7a5a84 100644 --- a/index.html +++ b/index.html @@ -28,7 +28,7 @@ - + - - - From 8abbc899ec9847a191241f78c575b05b63e3e269 Mon Sep 17 00:00:00 2001 From: zyronon Date: Wed, 10 Sep 2025 21:30:42 +0800 Subject: [PATCH 2/4] fix:unsupported func --- src/hooks/article.ts | 12 ++++++------ src/hooks/dict.ts | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hooks/article.ts b/src/hooks/article.ts index 5e0d4a9f..df05be1a 100644 --- a/src/hooks/article.ts +++ b/src/hooks/article.ts @@ -75,8 +75,8 @@ export function genArticleSectionData(article: Article): number { nearSymbolPosition = 'end' } else { //TODO 可以优化成for+break - section.toReversed().map((sentenceItem, b) => { - sentenceItem.words.toReversed().map((wordItem, c) => { + section.slice().reverse().map((sentenceItem, b) => { + sentenceItem.words.slice().reverse().map((wordItem, c) => { if (wordItem.symbolPosition !== '' && nearSymbolPosition === null) { nearSymbolPosition = wordItem.symbolPosition } @@ -101,7 +101,7 @@ export function genArticleSectionData(article: Article): number { word3.nextSpace = true let addCurrent = false - sentence.words.toReversed().map((wordItem, c) => { + sentence.words.slice().reverse().map((wordItem, c) => { if (wordItem.symbolPosition === 'start' && !addCurrent) { addCurrent = true } @@ -335,8 +335,8 @@ Its none of your business, the young man said rudely. This is a private conversa nearSymbolPosition = 'end' } else { //TODO 可以优化成for+break - section.toReversed().map((sentenceItem, b) => { - sentenceItem.words.toReversed().map((wordItem, c) => { + section.slice().reverse().map((sentenceItem, b) => { + sentenceItem.words.slice().reverse().map((wordItem, c) => { if (wordItem.symbolPosition !== '' && nearSymbolPosition === null) { nearSymbolPosition = wordItem.symbolPosition } @@ -361,7 +361,7 @@ Its none of your business, the young man said rudely. This is a private conversa word3.nextSpace = true let addCurrent = false - sentence.words.toReversed().map((wordItem, c) => { + sentence.words.slice().reverse().map((wordItem, c) => { if (wordItem.symbolPosition === 'start' && !addCurrent) { addCurrent = true } diff --git a/src/hooks/dict.ts b/src/hooks/dict.ts index b390db37..fc2a737b 100644 --- a/src/hooks/dict.ts +++ b/src/hooks/dict.ts @@ -133,7 +133,7 @@ export function getCurrentStudyWord() { } //从start往前取perDay个单词,作为当前复习单词,取到0为止 - list = dict.words.slice(0, start).toReversed() + list = dict.words.slice(0, start).reverse() for (let item of list) { if (!ignoreList.includes(item.word.toLowerCase())) { if (data.review.length < perDay) { @@ -153,9 +153,9 @@ export function getCurrentStudyWord() { // 上上次更早的单词 //默认只取start之前的单词 - let candidateWords = dict.words.slice(0, start).toReversed() + let candidateWords = dict.words.slice(0, start).reverse() //但如果已完成,则滚动取值 - if (complete) candidateWords = candidateWords.concat(dict.words.slice(end).toReversed()) + if (complete) candidateWords = candidateWords.concat(dict.words.slice(end).reverse()) candidateWords = candidateWords.filter(w => !ignoreList.includes(w.word.toLowerCase())); // console.log(candidateWords.map(v => v.word)) //最终要获取的单词数量 From 5d992a47ec56de7934c183994ee51f8be8c658d2 Mon Sep 17 00:00:00 2001 From: zyronon Date: Thu, 11 Sep 2025 01:11:19 +0800 Subject: [PATCH 3/4] fix:save --- public/dicts/en/article/NCE_2.json | 2 +- src/pages/pc/article/components/TypingArticle.vue | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/public/dicts/en/article/NCE_2.json b/public/dicts/en/article/NCE_2.json index fe432cb3..cb422c10 100644 --- a/public/dicts/en/article/NCE_2.json +++ b/public/dicts/en/article/NCE_2.json @@ -758,7 +758,7 @@ "title": "Quick work", "titleTranslate": "破案“神速”", "text": "Dan Robinson has been worried all week. \nLast Tuesday he received a letter from the local police. \nIn the letter he was asked to call at the station. \nDan wondered why he was wanted by the police, \nbut he went to the station yesterday and now he is not worried anymore. \nAt the station, he was told by a smiling policeman that his bicycle had been found. \nFive days ago, the policeman told him, the bicycle was picked up in a small village four hundred miles away. \nIt is now being sent to his home by train. \nDan was most surprised when he heard the news. \nHe was amused too, because he never expected the bicycle to be found. \nIt was stolen twenty years ago when Dan was a boy of fifteen!", - "textTranslate": "丹.鲁宾逊焦虑了整整一个星期。 \n上星期二他收到当地警察局的一封信, \n要他到警察局去一趟。 \n丹奇怪警察为什么找他, \n但昨天还是去了,结果他一再担心了。 \n在警察局里,一位面带笑容的警察告诉他,他的自行车找到了。 \n那位警察对他说,那辆自行车是5天前在400英里外的一个小村里发现的, \n现在正用火车给他运回家来。 \n丹听到这个消息后,惊奇万分, \n但又感到非常好笑,因为他从未指望那辆自行车还能找到。 \n这是20年前丹还是一个15岁的孩子时被人偷走的!", + "textTranslate": "丹.鲁宾逊焦虑了整整一个星期。 \n上星期二他收到当地警察局的一封信, \n信中要求他到警察局去一趟。 \n丹奇怪警察为什么找他, \n但昨天还是去了,结果他一再担心了。 \n在警察局里,一位面带笑容的警察告诉他,他的自行车找到了。 \n那位警察对他说,那辆自行车是5天前在400英里外的一个小村里发现的, \n现在正用火车给他运回家来。 \n丹听到这个消息后,惊奇万分, \n但又感到非常好笑,因为他从未指望那辆自行车还能找到。 \n这是20年前丹还是一个15岁的孩子时被人偷走的!", "newWords": [], "textAllWords": [], "audioSrc": "/sound/article/nce2-1/Quick work.mp3", diff --git a/src/pages/pc/article/components/TypingArticle.vue b/src/pages/pc/article/components/TypingArticle.vue index af5a3625..9f94fa4d 100644 --- a/src/pages/pc/article/components/TypingArticle.vue +++ b/src/pages/pc/article/components/TypingArticle.vue @@ -368,7 +368,8 @@ function onContextMenu(e: MouseEvent, sentence: Sentence, i, j, w) { onClick: () => { sectionIndex = i sentenceIndex = j - wordIndex = w + //todo 这里有可能是符号,要处理下 + wordIndex = w + 1 stringIndex = 0 input = wrong = '' isEnd = isSpace = false @@ -442,6 +443,12 @@ function onContextMenu(e: MouseEvent, sentence: Sentence, i, j, w) { }) } }, + { + label: "有道词典", + onClick: () => { + window.open(`https://www.youdao.com/result?word=${sentence.text}&lang=en`, '_blank') + } + }, ] }); } From 4f1219956ee4330ad0a10eb697f185fe9c0d1bc2 Mon Sep 17 00:00:00 2001 From: zyronon Date: Fri, 12 Sep 2025 01:10:14 +0800 Subject: [PATCH 4/4] feat:add statistics --- src/pages/pc/article/StudyArticle.vue | 57 ++++++++++++++++++--------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/pages/pc/article/StudyArticle.vue b/src/pages/pc/article/StudyArticle.vue index 3d51437c..3de7a854 100644 --- a/src/pages/pc/article/StudyArticle.vue +++ b/src/pages/pc/article/StudyArticle.vue @@ -4,7 +4,7 @@ import {onMounted, onUnmounted, watch} from "vue"; import {useBaseStore} from "@/stores/base.ts"; import {emitter, EventKey, useEvents} from "@/utils/eventBus.ts"; import {useSettingStore} from "@/stores/setting.ts"; -import {Article, ArticleItem, ArticleWord, Dict, DictType, ShortcutKey, Word} from "@/types/types.ts"; +import {Article, ArticleItem, ArticleWord, Dict, DictType, ShortcutKey, Statistics, Word} from "@/types/types.ts"; import {useDisableEventListener, useOnKeyboardEventListener, useStartKeyboardEventListener} from "@/hooks/event.ts"; import useTheme from "@/hooks/theme.ts"; import Toast from '@/pages/pc/components/base/toast/Toast.ts' @@ -27,16 +27,12 @@ import Switch from "@/pages/pc/components/base/Switch.vue"; const store = useBaseStore() const settingStore = useSettingStore() -const statisticsStore = usePracticeStore() +const statStore = usePracticeStore() const {toggleTheme} = useTheme() let articleData = $ref({ list: [], article: getDefaultArticle(), - sectionIndex: 0, - sentenceIndex: 0, - wordIndex: 0, - stringIndex: 0, }) let showEditArticle = $ref(false) let typingArticleRef = $ref() @@ -81,6 +77,7 @@ function toggleConciseMode() { function next() { if (store.sbook.lastLearnIndex >= articleData.list.length - 1) { + store.sbook.complete = true store.sbook.lastLearnIndex = 0 //todo 这里应该弹窗 } else store.sbook.lastLearnIndex++ @@ -134,30 +131,51 @@ useStartKeyboardEventListener() useDisableEventListener(() => loading) function setArticle(val: Article) { - statisticsStore.inputWordNumber = 0 - statisticsStore.wrong = 0 - statisticsStore.total = 0 - statisticsStore.startDate = Date.now() + statStore.wrong = 0 + statStore.total = 0 + statStore.startDate = Date.now() allWrongWords = new Set() articleData.list[store.sbook.lastLearnIndex] = val articleData.article = val - articleData.sectionIndex = 0 - articleData.sentenceIndex = 0 - articleData.wordIndex = 0 - articleData.stringIndex = 0 let ignoreList = [store.allIgnoreWords, store.knownWords][settingStore.ignoreSimpleWord ? 0 : 1] articleData.article.sections.map((v, i) => { v.map((w) => { w.words.map(s => { if (!ignoreList.includes(s.word.toLowerCase()) && !s.isSymbol) { - statisticsStore.total++ + statStore.total++ } }) }) }) } +function complete() { + //todo 有空了改成实时保存 + statStore.spend = Date.now() - statStore.startDate + let data: Partial & { title: string, id: string } = { + id: articleData.article.id, + title: articleData.article.title, + spend: statStore.spend, + startDate: statStore.startDate, + total: statStore.total, + wrong: statStore.wrong, + } + let reportData = { + ...data, + name: store.sbook.name, + spend: Number(statStore.spend / 1000 / 60).toFixed(1), + custom: store.sdict.custom, + complete: store.sdict.complete, + index: store.sdict.lastLearnIndex, + s: '' + } + reportData.s = `name:${store.sbook.name},title:${store.sbook.lastLearnIndex}.${data.title},spend:${Number(statStore.spend / 1000 / 60).toFixed(1)}` + window.umami?.track('studyWordArticle', reportData) + store.sbook.statistics.push(data as any) + console.log(data, reportData) +} + function getCurrentPractice() { emitter.emit(EventKey.resetWord) let currentArticle = articleData.list[store.sbook.lastLearnIndex] @@ -195,7 +213,7 @@ function wrong(word: Word) { } if (!allWrongWords.has(word.word.toLowerCase())) { allWrongWords.add(word.word.toLowerCase()) - statisticsStore.wrong++ + statStore.wrong++ } if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === temp)) { @@ -206,7 +224,7 @@ function wrong(word: Word) { function nextWord(word: ArticleWord) { if (!store.allIgnoreWords.includes(word.word.toLowerCase()) && !word.isSymbol) { - statisticsStore.inputWordNumber++ + statStore.inputWordNumber++ } } @@ -271,7 +289,7 @@ let speedMinute = $ref(0) let timer = $ref(0) onMounted(() => { timer = setInterval(() => { - speedMinute = Math.floor((Date.now() - statisticsStore.startDate) / 1000 / 60) + speedMinute = Math.floor((Date.now() - statStore.startDate) / 1000 / 60) }, 1000) }) @@ -301,6 +319,7 @@ function play2(e) { @next="next" @nextWord="nextWord" @play="play2" + @complete="complete" :article="articleData.article" /> @@ -351,7 +370,7 @@ function play2(e) {
- {{ statisticsStore.total }} + {{ statStore.total }}