添加统计

This commit is contained in:
zyronon
2023-08-26 17:38:20 +08:00
parent d0e81638ec
commit 997187b1f6
7 changed files with 231 additions and 159 deletions

View File

@@ -8,24 +8,52 @@ import Fireworks from "@/components/Fireworks.vue";
import BaseButton from "@/components/BaseButton.vue";
const store = useBaseStore()
function write() {
store.isDictation = true
repeat()
}
//TODO 需要判断是否已忽略
function repeat() {
store.currentDict.wordIndex = 0
store.currentWrongDict.wordList = []
store.statModalIsOpen = false
}
function next() {
store.currentDict.chapterIndex++
repeat()
}
</script>
<template>
<Modal v-model="store.dictModalIsOpen2">
<Modal v-model="store.statModalIsOpen" @close="next">
<div class="statistics">
<header>
<div class="title">新概念英语-2 第3章</div>
</header>
<div class="content">
<div class="rings">
<Ring/>
<Ring/>
<Ring style="margin-bottom: 0;"/>
<Ring
:value="store.lastStatistics.correctRate + '%'"
desc="正确率"
:percentage="store.lastStatistics.correctRate"/>
<Ring
:value="store.lastStatistics.correctNumber"
desc="正确数"
:percentage="0"
/>
<Ring
:value="store.currentDict.wordIndex"
desc="输入数"
:percentage="0"
style="margin-bottom: 0;"/>
</div>
<div class="result">
<div class="wrong-words-wrapper">
<div class="wrong-words">
<div class="word" v-for="i in 500">Yes</div>
<div class="word" v-for="i in store.currentWrongDict.wordList">{{ i.name }}</div>
</div>
</div>
@@ -47,19 +75,19 @@ const store = useBaseStore()
</div>
</div>
<div class="footer">
<BaseButton keyboard="Ctrl + Enter" >
<BaseButton keyboard="Ctrl + Enter" @click="write">
默写本章节
</BaseButton>
<BaseButton keyboard="Enter" >
<BaseButton keyboard="Enter" @click="repeat">
重复本章节
</BaseButton>
<BaseButton keyboard="Tab" >
<BaseButton keyboard="Tab" @click="next">
下一章节
</BaseButton>
</div>
</div>
</Modal>
<!-- <Fireworks v-if="store.dictModalIsOpen2"/>-->
<Fireworks v-if="store.statModalIsOpen"/>
</template>
<style scoped lang="scss">
@import "@/assets/css/style";

View File

@@ -3,12 +3,13 @@
<svg height="100%" width="100%">
<circle class="circle-full" cx="45rem" cy="45rem" r="40rem" fill="none" stroke-width="8rem"
stroke-linecap="round"></circle>
<circle ref="circleEl" class="circle-detail" cx="45rem" cy="45rem" r="40rem" fill="none" stroke-width="8rem"
<circle v-if="props.percentage" ref="circleEl" class="circle-detail" cx="45rem" cy="45rem" r="40rem" fill="none"
stroke-width="8rem"
stroke-linecap="round"
stroke-dasharray="0,10000"></circle>
</svg>
<span class="value">remark</span>
<span class="desc">dfadf</span>
<span class="value">{{ props.value }}</span>
<span class="desc">{{ props.desc }}</span>
</div>
</template>
<script setup lang="ts">
@@ -16,6 +17,8 @@ import {onMounted} from "vue"
const props = withDefaults(defineProps<{
percentage?: number,
value: string | number,
desc: string,
}>(), {
percentage: 90,
})
@@ -23,9 +26,11 @@ const props = withDefaults(defineProps<{
const circleEl = $ref(null)
onMounted(() => {
let circleLength = Math.floor(2 * Math.PI * 40);
let val = Number(props.percentage.toFixed(0));
circleEl.setAttribute("stroke-dasharray", "" + circleLength * val / 100 + "rem,10000");
if (props.percentage) {
let circleLength = Math.floor(2 * Math.PI * 40);
let val = Number(props.percentage.toFixed(0));
circleEl.setAttribute("stroke-dasharray", "" + circleLength * val / 100 + "rem,10000");
}
})
</script>
<style scoped lang="scss">

View File

@@ -92,18 +92,18 @@ function changeDict(dict: Dict, i: number) {
<div class="page0">
<header>
<a href="" target="_blank"></a>
<div class="dict-name">总词数{{ store.wrongDict.wordList.length }}</div>
<div class="dict-name">总词数{{ store.allWrongDict.wordList.length }}</div>
</header>
<WordList
class="word-list"
@change="(e:number) => store.changeDict(store.wrongDict,-1,e)"
@change="(e:number) => store.changeDict(store.allWrongDict,-1,e)"
:isActive="store.sideIsOpen && tabIndex === 2"
:list="store.wrongDict.wordList"
:activeIndex="store.wrongDict.wordIndex"/>
<footer v-if="store.currentDictType !== DictType.wrongDict && store.wrongDict.wordList.length">
:list="store.allWrongDict.wordList"
:activeIndex="store.allWrongDict.wordIndex"/>
<footer v-if="store.currentDictType !== DictType.allWrongDict && store.allWrongDict.wordList.length">
<PopConfirm
:title="`确认切换?`"
@confirm="store.changeDict(store.wrongDict)"
@confirm="store.changeDict(store.allWrongDict)"
>
<BaseButton>
切换

View File

@@ -37,12 +37,16 @@ const store = useBaseStore()
const showFeedbackModal = $ref(false)
const showSettingModal = $ref(false)
const showDictModal = $ref(false)
function t() {
console.log('t')
}
</script>
<template>
<header :class="!store.setting.showToolbar && 'hide'">
<div class="info" @click="showDictModal = true">
{{ store.currentDict.name }} {{ store.currentDict.chapterIndex + 1}}
{{ store.currentDict.name }} {{ store.currentDict.chapterIndex + 1 }}
</div>
<div class="options">
<Tooltip title="切换主题">
@@ -65,8 +69,8 @@ const showDictModal = $ref(false)
</Tooltip>
<Tooltip title="开关默写模式">
<IconWrapper>
<IconEye></IconEye>
<IconEyeSlash></IconEyeSlash>
<IconEyeSlash v-if="store.isDictation" @click="store.isDictation = false"></IconEyeSlash>
<IconEye v-else @click="store.isDictation = true"></IconEye>
</IconWrapper>
</Tooltip>
<Tooltip title="开关释义显示">
@@ -91,7 +95,7 @@ const showDictModal = $ref(false)
<IconCog6Tooth @click="showSettingModal = true"></IconCog6Tooth>
</IconWrapper>
</Tooltip>
<div class="my-button" @click="store.dictModalIsOpen2 = true">ok</div>
<div class="my-button" @click="store.statModalIsOpen = true">ok</div>
<Tooltip title="单词本">
<menu-fold class="menu" @click="store.sideIsOpen = !store.sideIsOpen"

View File

@@ -33,7 +33,6 @@ import {
let input = $ref('')
let wrong = $ref('')
let showFullWord = $ref(false)
let isDictation = $ref(true)
let activeIndex = $ref(-1)
const store = useBaseStore()
@@ -73,10 +72,11 @@ watch(store.$state, (n) => {
function next() {
if (store.currentDict.wordIndex === store.chapter.length - 1) {
if (store.currentDict.chapterIndex !== store.currentDict.chapterList.length - 1) {
store.currentDict.wordIndex = 0
store.currentDict.chapterIndex++
// store.currentDict.wordIndex = 0
store.currentDict.wordIndex++
// store.currentDict.chapterIndex++
console.log('这一章节完了')
wrongWord = []
store.statModalIsOpen = true
} else {
console.log('这本书完了')
return
@@ -98,16 +98,19 @@ function next() {
next()
}
wrong = input = ''
store.lastStatistics.correctNumber = store.currentDict.wordIndex - wrongWord.length
store.lastStatistics.correctRate = Math.trunc(((store.currentDict.wordIndex - wrongWord.length) / (store.currentDict.wordIndex)) * 100)
if (store.currentDict.wordIndex) {
store.lastStatistics.correctNumber = store.currentDict.wordIndex - store.currentWrongDict.wordList.length
store.lastStatistics.correctRate = Math.trunc(((store.currentDict.wordIndex - store.currentWrongDict.wordList.length) / (store.currentDict.wordIndex)) * 100)
} else {
store.lastStatistics.correctRate = -1
store.lastStatistics.correctNumber = -1
}
}
function onKeyUp(e: KeyboardEvent) {
showFullWord = false
}
let wrongWord = $ref([])
async function onKeyDown(e: KeyboardEvent) {
//TODO 还有横杠
if ((e.keyCode >= 65 && e.keyCode <= 90) || e.code === 'Space') {
@@ -117,13 +120,13 @@ async function onKeyDown(e: KeyboardEvent) {
wrong = ''
playKeySound()
} else {
if (!store.wrongDict.wordList.find((v: Word) => v.name === store.word.name)) {
store.wrongDict.wordList.push(store.word)
if (!store.allWrongDict.wordList.find((v: Word) => v.name === store.word.name)) {
store.allWrongDict.wordList.push(store.word)
}
if (!wrongWord.find((v: string) => v === store.word.name)) {
wrongWord.push(store.word.name)
if (!store.currentWrongDict.wordList.find((v: Word) => v.name === store.word.name)) {
store.currentWrongDict.wordList.push(store.word)
}
store.lastStatistics.correctRate = Math.trunc(((store.currentDict.wordIndex + 1 - wrongWord.length) / (store.currentDict.wordIndex + 1)) * 100)
store.lastStatistics.correctRate = Math.trunc(((store.currentDict.wordIndex + 1 - store.currentWrongDict.wordList.length) / (store.currentDict.wordIndex + 1)) * 100)
wrong = letter
playKeySound()
playBeep()
@@ -195,7 +198,7 @@ function format(val: number, suffix: string = '') {
<div class="word" :class="wrong&&'is-wrong'">
<span class="input" v-if="input">{{ input }}</span>
<span class="wrong" v-if="wrong">{{ wrong }}</span>
<template v-if="isDictation">
<template v-if="store.isDictation">
<span class="letter" v-if="!showFullWord"
@mouseenter="showFullWord = true">{{ restWord.split('').map(v => '_').join('') }}</span>
<span class="letter" v-else @mouseleave="showFullWord = false">{{ restWord }}</span>
@@ -228,26 +231,21 @@ function format(val: number, suffix: string = '') {
:stroke-width="8"
:show-text="false"/>
<div class="stat">
<div class="row">
<div class="num">{{ store.lastStatistics.endDate }}</div>
<div class="line"></div>
<div class="name">时间</div>
</div>
<div class="row">
<div class="num">{{ store.currentDict.wordIndex }}</div>
<div class="line"></div>
<div class="name">输入数</div>
</div>
<div class="row">
<div class="num">{{ format(store.lastStatistics.correctRate, '%') }}</div>
<div class="line"></div>
<div class="name">正确率</div>
</div>
<div class="row">
<div class="num">{{ format(store.lastStatistics.correctNumber) }}</div>
<div class="line"></div>
<div class="name">正确数</div>
</div>
<div class="row">
<div class="num">{{ format(store.lastStatistics.correctRate, '%') }}</div>
<div class="line"></div>
<div class="name">正确率</div>
</div>
</div>
</div>
<div class="progress">
@@ -295,7 +293,7 @@ function format(val: number, suffix: string = '') {
letter-spacing: 5rem;
.input {
color: rgba(74, 222, 128, 0.8);
color: rgb(22, 163, 74);
}
.wrong {
@@ -340,7 +338,7 @@ function format(val: number, suffix: string = '') {
flex-direction: column;
align-items: center;
gap: 10rem;
width: 50rem;
width: 80rem;
.line {
height: 1px;
@@ -361,7 +359,7 @@ function format(val: number, suffix: string = '') {
.progress {
width: var(--toolbar-width);
padding:0 10rem;
padding: 0 10rem;
box-sizing: border-box;
position: fixed;
bottom: 30rem;

View File

@@ -41,11 +41,11 @@ export const useBaseStore = defineStore('base', {
dictStatistics: [],
chapterWordNumber: 15
},
wrongDict: {
type: DictType.wrongDict,
allWrongDict: {
type: DictType.allWrongDict,
sort: Sort.normal,
name: '已忽略',
description: '已忽略',
name: '错词本',
description: '错词本',
category: '',
tags: [],
url: '',
@@ -59,6 +59,30 @@ export const useBaseStore = defineStore('base', {
dictStatistics: [],
chapterWordNumber: 15
},
currentWrongDict: {
type: DictType.currentWrongDict,
sort: Sort.normal,
name: '当前错词本',
description: '错词本',
category: '',
tags: [],
url: '',
length: -1,
language: 'en',
languageCategory: 'en',
wordList: [],
chapterList: [],
chapterIndex: 0,
wordIndex: 0,
dictStatistics: [],
statistics: {
startDate: Date.now(),//开始日期
endDate: -1,
correctRate: -1,
correctNumber: -1
},
chapterWordNumber: 15
},
dict: {
type: DictType.inner,
sort: Sort.normal,
@@ -86,8 +110,10 @@ export const useBaseStore = defineStore('base', {
},
oldDicts: [],
currentDictType: DictType.inner,
lastDictType: DictType.inner,
sideIsOpen: false,
dictModalIsOpen2: false,
isDictation: true,
statModalIsOpen: false,
setting: {
showToolbar: true,
show: false,
@@ -108,23 +134,29 @@ export const useBaseStore = defineStore('base', {
return state.newWordDict
case DictType.skipWordDict:
return state.skipWordDict
case DictType.wrongDict:
return state.wrongDict
case DictType.allWrongDict:
return state.allWrongDict
case DictType.inner:
case DictType.custom:
return state.dict
}
},
chapter(): Word[] {
wordIndex(state: State): number {
return this.currentDict.wordIndex
},
chapter(state: State): Word[] {
return this.currentDict.chapterList[this.currentDict.chapterIndex] ?? []
},
word(): Word {
word(state: State): Word {
return this.chapter[this.currentDict.wordIndex] ?? {
trans: [],
name: ''
}
},
lastStatistics(): Statistics {
lastStatistics(state: State): Statistics {
if (state.currentDictType === DictType.currentWrongDict) {
return state.currentWrongDict.statistics
}
if (this.currentDict.dictStatistics.length) {
let stat = this.currentDict.dictStatistics[this.currentDict.dictStatistics.length - 1]
if (stat.statistics.length) {
@@ -177,7 +209,7 @@ export const useBaseStore = defineStore('base', {
console.log('changeDict', dict)
if ([DictType.newWordDict,
DictType.skipWordDict,
DictType.wrongDict].includes(dict.type)) {
DictType.allWrongDict].includes(dict.type)) {
this.currentDictType = dict.type
this[dict.type].chapterList = [this[dict.type].wordList]
this[dict.type].chapterIndex = 0

View File

@@ -1,22 +1,22 @@
export type Config = {
newWords: Word[],
skipWords: Word[],
skipWordNames: string[],
dict: string,
currentDict: {
wordList: Word[],
chapterList: Word[][],
name: string,
desc: string
}
chapterIndex: number,
wordIndex: number,
newWords: Word[],
skipWords: Word[],
skipWordNames: string[],
dict: string,
currentDict: {
wordList: Word[],
chapterList: Word[][],
name: string,
desc: string
}
chapterIndex: number,
wordIndex: number,
}
export type Word = {
"name": string,
"usphone": string,
"ukphone": string,
"trans": string[]
"name": string,
"usphone": string,
"ukphone": string,
"trans": string[]
}
export const SaveKey = 'bb-word-config'
@@ -30,121 +30,126 @@ export type LanguageCategoryType = 'en' | 'ja' | 'de' | 'code'
export type DictionaryResource = {
id: string
name: string
description: string
category: string
tags: string[]
url: string
length: number
language: LanguageType
languageCategory: LanguageCategoryType
//override default pronunciation when not undefined
defaultPronIndex?: number
id: string
name: string
description: string
category: string
tags: string[]
url: string
length: number
language: LanguageType
languageCategory: LanguageCategoryType
//override default pronunciation when not undefined
defaultPronIndex?: number
}
export type Dictionary = {
id: string
name: string
description: string
category: string
tags: string[]
url: string
length: number
language: LanguageType
languageCategory: LanguageCategoryType
// calculated in the store
chapterCount: number
//override default pronunciation when not undefined
defaultPronIndex?: number
id: string
name: string
description: string
category: string
tags: string[]
url: string
length: number
language: LanguageType
languageCategory: LanguageCategoryType
// calculated in the store
chapterCount: number
//override default pronunciation when not undefined
defaultPronIndex?: number
}
export type PronunciationConfig = {
name: string
pron: PronunciationType
name: string
pron: PronunciationType
}
export type LanguagePronunciationMapConfig = {
defaultPronIndex: number
pronunciation: PronunciationConfig[]
defaultPronIndex: number
pronunciation: PronunciationConfig[]
}
export type LanguagePronunciationMap = {
[key in LanguageType]: LanguagePronunciationMapConfig
[key in LanguageType]: LanguagePronunciationMapConfig
}
export type SoundResource = {
key: string
name: string
filename: string
key: string
name: string
filename: string
}
export interface DictJson {
name: string,
description: string,
category: string,
tags: string[],
url: string,
length: number,
language: string,
languageCategory: string,
name: string,
description: string,
category: string,
tags: string[],
url: string,
length: number,
language: string,
languageCategory: string,
}
export enum DictType {
newWordDict = 'newWordDict',
skipWordDict = 'skipWordDict',
wrongDict = 'wrongDict',
inner = 'inner',
custom = 'custom',
newWordDict = 'newWordDict',
skipWordDict = 'skipWordDict',
allWrongDict = 'allWrongDict',
currentWrongDict = 'currentWrongDict',
inner = 'inner',
custom = 'custom',
}
export interface Dict extends DictJson {
sort: Sort,
type: DictType,
wordList: Word[],
chapterList: Word[][],
chapterIndex: number,
wordIndex: number,
chapterWordNumber: number,
dictStatistics: DictStatistics[]
sort: Sort,
type: DictType,
wordList: Word[],
chapterList: Word[][],
chapterIndex: number,
wordIndex: number,
chapterWordNumber: number,
dictStatistics: DictStatistics[],
statistics?: Statistics
}
export interface DictStatistics {
startDate: number,//开始日期
endDate: number//结束日期
chapterWordNumber: number//章节单词数量
statistics: Array<Statistics>
startDate: number,//开始日期
endDate: number//结束日期
chapterWordNumber: number//章节单词数量
statistics: Array<Statistics>
}
export interface Statistics {
startDate: number,//开始日期
endDate: number//结束日期
correctRate: number//正确率
correctNumber: number//正确数
startDate: number,//开始日期
endDate: number//结束日期
correctRate: number//正确率
correctNumber: number//正确数
}
export enum Sort {
normal = 0,
random = 1,
reverse = 2
normal = 0,
random = 1,
reverse = 2
}
export interface State {
newWordDict: Dict,
skipWordDict: Dict,
wrongDict: Dict,
dict: Dict,
oldDicts: Dict[],
currentDictType: DictType
sideIsOpen: boolean,
dictModalIsOpen2: boolean,
setting: {
showToolbar: boolean,
show: boolean,
value1: boolean,
value2: number,
value3: number,
value4: boolean,
}
newWordDict: Dict,
skipWordDict: Dict,
allWrongDict: Dict,
currentWrongDict: Dict,
dict: Dict,
oldDicts: Dict[],
currentDictType: DictType,
lastDictType: DictType,
sideIsOpen: boolean,
statModalIsOpen: boolean,
isDictation: boolean,
setting: {
showToolbar: boolean,
show: boolean,
value1: boolean,
value2: number,
value3: number,
value4: boolean,
}
}