save
This commit is contained in:
@@ -99,6 +99,15 @@ a {
|
||||
border-radius: 10rem;
|
||||
}
|
||||
|
||||
|
||||
/* 火狐美化滚动条 */
|
||||
* {
|
||||
scrollbar-color: $second #f3f4f9;
|
||||
/* 滑块颜色 滚动条背景颜色 */
|
||||
scrollbar-width: thin;
|
||||
/* 滚动条宽度有三种:thin、auto、none */
|
||||
}
|
||||
|
||||
footer {
|
||||
box-sizing: content-box;
|
||||
height: $footer-height;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {saveAs} from 'file-saver';
|
||||
import {watch} from "vue";
|
||||
import {Article, DefaultArticle, Sentence, TranslateEngine, TranslateType} from "@/types.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
@@ -54,12 +54,14 @@ watch(() => props.article, n => {
|
||||
if (article.textCustomTranslate.trim()) {
|
||||
if (!article.textCustomTranslateIsFormat) {
|
||||
let r = getSplitTranslateText(article.textCustomTranslate)
|
||||
if (r) article.textCustomTranslate = r
|
||||
ElMessage({
|
||||
message: '检测到本地翻译未格式化,已自动格式',
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
})
|
||||
if (r) {
|
||||
article.textCustomTranslate = r
|
||||
ElMessage({
|
||||
message: '检测到本地翻译未格式化,已自动格式化',
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,31 +242,9 @@ function save(option: 'save' | 'next', mute: boolean = false) {
|
||||
saveTemp()
|
||||
}
|
||||
|
||||
function changeTranslateType() {
|
||||
if (article.text.trim()) {
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
if (article.textCustomTranslate.trim()) {
|
||||
renewSectionTranslates(article, article.textCustomTranslate)
|
||||
} else {
|
||||
renewSectionTexts(article)
|
||||
}
|
||||
}
|
||||
if (article.useTranslateType === TranslateType.network) {
|
||||
if (article.textNetworkTranslate.trim()) {
|
||||
renewSectionTranslates(article, article.textNetworkTranslate)
|
||||
} else {
|
||||
renewSectionTexts(article)
|
||||
}
|
||||
}
|
||||
if (article.useTranslateType === TranslateType.none) {
|
||||
renewSectionTexts(article)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectArticle(item: Article) {
|
||||
article = cloneDeep(item)
|
||||
if (!article?.sections?.length){
|
||||
if (!article?.sections?.length) {
|
||||
renewSections()
|
||||
}
|
||||
console.log('article', article)
|
||||
@@ -277,6 +257,22 @@ function add() {
|
||||
article = cloneDeep(DefaultArticle)
|
||||
}
|
||||
|
||||
//TODO
|
||||
function importData() {
|
||||
|
||||
}
|
||||
|
||||
function exportData() {
|
||||
let data = {
|
||||
name: base.currentEditDict.name,
|
||||
articles: base.currentEditDict.articles,
|
||||
url: base.currentEditDict.url,
|
||||
statistics: location.origin + base.currentEditDict.statistics,
|
||||
}
|
||||
|
||||
let blob = new Blob([JSON.stringify(data, null, 2)], {type: "text/plain;charset=utf-8"});
|
||||
saveAs(blob, `${data.name}.json`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -298,8 +294,8 @@ function add() {
|
||||
</template>
|
||||
</List>
|
||||
<div class="footer">
|
||||
<BaseButton>导入</BaseButton>
|
||||
<BaseButton>导出</BaseButton>
|
||||
<BaseButton @click="importData">导入</BaseButton>
|
||||
<BaseButton @click="exportData">导出</BaseButton>
|
||||
<BaseButton @click="add">新增</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
@@ -337,7 +333,7 @@ function add() {
|
||||
<span>标题:</span>
|
||||
<el-radio-group
|
||||
v-model="article.useTranslateType"
|
||||
@change="changeTranslateType"
|
||||
@change="renewSections"
|
||||
>
|
||||
<el-radio-button :label="TranslateType.custom">本地翻译</el-radio-button>
|
||||
<el-radio-button :label="TranslateType.network">网络翻译</el-radio-button>
|
||||
@@ -490,6 +486,7 @@ function add() {
|
||||
display: flex;
|
||||
gap: $space;
|
||||
padding: $space;
|
||||
padding-top: 10rem;
|
||||
//opacity: 0;
|
||||
}
|
||||
|
||||
@@ -561,7 +558,7 @@ function add() {
|
||||
.sentence {
|
||||
margin-bottom: 20rem;
|
||||
|
||||
&:last-child{
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ function delItem(item: T) {
|
||||
|
||||
.list-wrapper {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
overflow: overlay;
|
||||
padding-right: 5rem;
|
||||
|
||||
.search {
|
||||
|
||||
@@ -5,258 +5,258 @@ import {emitter, EventKey} from "@/utils/eventBus.ts"
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
|
||||
export interface State {
|
||||
newWordDict: Dict,
|
||||
skipWordDict: Dict,
|
||||
wrongWordDict: Dict,
|
||||
dict: Dict,
|
||||
myDicts: Dict[],
|
||||
current: {
|
||||
dictType: DictType,
|
||||
index: number,
|
||||
editIndex: number,
|
||||
repeatNumber: number,
|
||||
},
|
||||
simpleWords: string[],
|
||||
sideIsOpen: boolean,
|
||||
load: boolean
|
||||
newWordDict: Dict,
|
||||
skipWordDict: Dict,
|
||||
wrongWordDict: Dict,
|
||||
dict: Dict,
|
||||
myDicts: Dict[],
|
||||
current: {
|
||||
dictType: DictType,
|
||||
index: number,
|
||||
editIndex: number,
|
||||
repeatNumber: number,
|
||||
},
|
||||
simpleWords: string[],
|
||||
sideIsOpen: boolean,
|
||||
load: boolean
|
||||
}
|
||||
|
||||
export const useBaseStore = defineStore('base', {
|
||||
state: (): State => {
|
||||
return {
|
||||
newWordDict: {
|
||||
name: '生词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.newDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
skipWordDict: {
|
||||
name: '简单词',
|
||||
sort: Sort.normal,
|
||||
type: DictType.skipDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
wrongWordDict: {
|
||||
name: '错词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.wrongDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
// dict: {
|
||||
// name: '新概念英语-2',
|
||||
// sort: Sort.normal,
|
||||
// type: DictType.innerDict,
|
||||
// originWords: [],
|
||||
// articles: [],
|
||||
// words: [],
|
||||
// chapterWordNumber: 15,
|
||||
// chapterWords: [],
|
||||
// chapterIndex: 0,
|
||||
// chapterWordIndex: 0,
|
||||
// statistics: [],
|
||||
// url: '/dicts/NCE_2.json',
|
||||
// },
|
||||
dict: {
|
||||
name: '新概念英语-2',
|
||||
sort: Sort.normal,
|
||||
type: DictType.publicArticle,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '/articles/NCE_2.json',
|
||||
},
|
||||
myDicts: [
|
||||
{
|
||||
name: '新概念英语-2',
|
||||
sort: Sort.normal,
|
||||
type: DictType.publicArticle,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '/articles/NCE_2.json',
|
||||
}
|
||||
],
|
||||
current: {
|
||||
dictType: DictType.publicArticle,
|
||||
index: 0,
|
||||
editIndex: 0,
|
||||
repeatNumber: 0,
|
||||
},
|
||||
sideIsOpen: false,
|
||||
simpleWords: [
|
||||
'a', 'an', 'of', 'and',
|
||||
'i', 'my', 'you', 'your',
|
||||
'me', 'am', 'is', 'do', 'are',
|
||||
'what', 'who', 'where', 'how', 'no', 'yes',
|
||||
'not', 'did', 'were', 'can', 'could', 'it',
|
||||
'the', 'to'
|
||||
],
|
||||
load: false
|
||||
state: (): State => {
|
||||
return {
|
||||
newWordDict: {
|
||||
name: '生词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.newDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
skipWordDict: {
|
||||
name: '简单词',
|
||||
sort: Sort.normal,
|
||||
type: DictType.skipDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
wrongWordDict: {
|
||||
name: '错词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.wrongDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
// dict: {
|
||||
// name: '新概念英语-2',
|
||||
// sort: Sort.normal,
|
||||
// type: DictType.innerDict,
|
||||
// originWords: [],
|
||||
// articles: [],
|
||||
// words: [],
|
||||
// chapterWordNumber: 15,
|
||||
// chapterWords: [],
|
||||
// chapterIndex: 0,
|
||||
// chapterWordIndex: 0,
|
||||
// statistics: [],
|
||||
// url: '/dicts/NCE_2.json',
|
||||
// },
|
||||
dict: {
|
||||
name: '新概念英语-2',
|
||||
sort: Sort.normal,
|
||||
type: DictType.publicArticle,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '/articles/NCE_2.json',
|
||||
},
|
||||
myDicts: [
|
||||
{
|
||||
name: '新概念英语-2',
|
||||
sort: Sort.normal,
|
||||
type: DictType.publicArticle,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '/articles/NCE_2.json',
|
||||
}
|
||||
],
|
||||
current: {
|
||||
dictType: DictType.publicArticle,
|
||||
index: 0,
|
||||
editIndex: 0,
|
||||
repeatNumber: 0,
|
||||
},
|
||||
sideIsOpen: false,
|
||||
simpleWords: [
|
||||
'a', 'an', 'of', 'and',
|
||||
'i', 'my', 'you', 'your',
|
||||
'me', 'am', 'is', 'do', 'are',
|
||||
'what', 'who', 'where', 'how', 'no', 'yes',
|
||||
'not', 'did', 'were', 'can', 'could', 'it',
|
||||
'the', 'to'
|
||||
],
|
||||
load: false
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase())
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase())
|
||||
},
|
||||
skipWordNamesWithSimpleWords: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
|
||||
},
|
||||
isArticle(state: State): boolean {
|
||||
return [
|
||||
DictType.publicArticle,
|
||||
DictType.customArticle
|
||||
].includes(state.current.dictType)
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.current.dictType) {
|
||||
case DictType.newDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipDict:
|
||||
return state.skipWordDict
|
||||
case DictType.wrongDict:
|
||||
return state.wrongWordDict
|
||||
case DictType.publicDict:
|
||||
case DictType.publicArticle:
|
||||
case DictType.customDict:
|
||||
case DictType.customArticle:
|
||||
return this.myDicts[this.current.index]
|
||||
}
|
||||
},
|
||||
currentEditDict(): Dict {
|
||||
return this.myDicts[this.current.editIndex]
|
||||
},
|
||||
wordIndex(state: State): number {
|
||||
return this.currentDict.wordIndex
|
||||
},
|
||||
chapter(state: State): Word[] {
|
||||
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
//TODO 废弃
|
||||
word(state: State): Word {
|
||||
return {trans: [], name: '', usphone: '', ukphone: '',}
|
||||
},
|
||||
dictTitle(state: State) {
|
||||
let title = this.currentDict.name
|
||||
if ([DictType.publicDict, DictType.customDict].includes(this.current.dictType)) {
|
||||
title += ` 第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
return title
|
||||
skipWordNamesWithSimpleWords: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
|
||||
},
|
||||
isArticle(state: State): boolean {
|
||||
return [
|
||||
DictType.publicArticle,
|
||||
DictType.customArticle
|
||||
].includes(state.current.dictType)
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.current.dictType) {
|
||||
case DictType.newDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipDict:
|
||||
return state.skipWordDict
|
||||
case DictType.wrongDict:
|
||||
return state.wrongWordDict
|
||||
case DictType.publicDict:
|
||||
case DictType.publicArticle:
|
||||
case DictType.customDict:
|
||||
case DictType.customArticle:
|
||||
return this.myDicts[this.current.index]
|
||||
}
|
||||
},
|
||||
currentEditDict(): Dict {
|
||||
return this.myDicts[this.current.editIndex]
|
||||
},
|
||||
wordIndex(state: State): number {
|
||||
return this.currentDict.wordIndex
|
||||
},
|
||||
chapter(state: State): Word[] {
|
||||
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
//TODO 废弃
|
||||
word(state: State): Word {
|
||||
return {trans: [], name: '', usphone: '', ukphone: '',}
|
||||
},
|
||||
dictTitle(state: State) {
|
||||
let title = this.currentDict.name
|
||||
if ([DictType.publicDict, DictType.customDict].includes(this.current.dictType)) {
|
||||
title += ` 第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
return title
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
}
|
||||
// console.log('this/', this)
|
||||
},
|
||||
async init() {
|
||||
let configStr = localStorage.getItem(SaveDictKey)
|
||||
if (configStr) {
|
||||
let obj: State = JSON.parse(configStr)
|
||||
// this.setState(obj)
|
||||
}
|
||||
|
||||
if ([
|
||||
DictType.newDict,
|
||||
DictType.wrongDict,
|
||||
DictType.skipDict,
|
||||
].includes(this.current.dictType)) {
|
||||
|
||||
} else {
|
||||
if ([
|
||||
DictType.publicDict,
|
||||
DictType.customDict,
|
||||
].includes(this.current.dictType)) {
|
||||
if (!this.currentDict.originWords.length) {
|
||||
let r = await fetch(`${this.currentDict.url}`)
|
||||
r.json().then(v => {
|
||||
this.currentDict.originWords = cloneDeep(v)
|
||||
this.currentDict.words = cloneDeep(v)
|
||||
this.currentDict.chapterWords = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
}
|
||||
// console.log('this/', this)
|
||||
},
|
||||
async init() {
|
||||
let configStr = localStorage.getItem(SaveDictKey)
|
||||
if (configStr) {
|
||||
let obj: State = JSON.parse(configStr)
|
||||
// this.setState(obj)
|
||||
}
|
||||
|
||||
if ([
|
||||
DictType.newDict,
|
||||
DictType.wrongDict,
|
||||
DictType.skipDict,
|
||||
].includes(this.current.dictType)) {
|
||||
|
||||
} else {
|
||||
if ([
|
||||
DictType.publicDict,
|
||||
DictType.customDict,
|
||||
].includes(this.current.dictType)) {
|
||||
if (!this.currentDict.originWords.length) {
|
||||
let r = await fetch(`${this.currentDict.url}`)
|
||||
r.json().then(v => {
|
||||
this.currentDict.originWords = cloneDeep(v)
|
||||
this.currentDict.words = cloneDeep(v)
|
||||
this.currentDict.chapterWords = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if ([
|
||||
DictType.publicArticle,
|
||||
DictType.customArticle,
|
||||
].includes(this.current.dictType)) {
|
||||
if (!this.currentDict.articles.length) {
|
||||
let r = await fetch(`${this.currentDict.url}`)
|
||||
r.json().then((v: any[]) => {
|
||||
this.currentDict.articles = cloneDeep(v.map(v => {
|
||||
v.id = uuidv4()
|
||||
return v
|
||||
}))
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
saveStatistics(statistics: Statistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, chapterIndex: number = dict.chapterIndex, chapterWordIndex: number = dict.chapterWordNumber) {
|
||||
this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
|
||||
this.current.dictType = dict.type
|
||||
if ([DictType.newDict,
|
||||
DictType.skipDict,
|
||||
DictType.wrongDict].includes(dict.type)) {
|
||||
this[dict.type].chapterIndex = chapterIndex
|
||||
this[dict.type].chapterWordIndex = chapterWordIndex
|
||||
} else {
|
||||
this.dict = cloneDeep(dict)
|
||||
if (dict.originWords.length) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
let v = await r.json()
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapters = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
}
|
||||
this.dict.chapterIndex = chapterIndex
|
||||
this.dict.chapterWordIndex = chapterWordIndex
|
||||
}
|
||||
emitter.emit(EventKey.resetWord)
|
||||
if ([
|
||||
DictType.publicArticle,
|
||||
DictType.customArticle,
|
||||
].includes(this.current.dictType)) {
|
||||
if (!this.currentDict.articles.length) {
|
||||
let r = await fetch(`${this.currentDict.url}`)
|
||||
r.json().then((v: any[]) => {
|
||||
this.currentDict.articles = cloneDeep(v.map(v => {
|
||||
v.id = uuidv4()
|
||||
return v
|
||||
}))
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
saveStatistics(statistics: Statistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, chapterIndex: number = dict.chapterIndex, chapterWordIndex: number = dict.chapterWordNumber) {
|
||||
this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
|
||||
this.current.dictType = dict.type
|
||||
if ([DictType.newDict,
|
||||
DictType.skipDict,
|
||||
DictType.wrongDict].includes(dict.type)) {
|
||||
this[dict.type].chapterIndex = chapterIndex
|
||||
this[dict.type].chapterWordIndex = chapterWordIndex
|
||||
} else {
|
||||
this.dict = cloneDeep(dict)
|
||||
if (dict.originWords.length) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
let v = await r.json()
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapters = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
}
|
||||
this.dict.chapterIndex = chapterIndex
|
||||
this.dict.chapterWordIndex = chapterWordIndex
|
||||
}
|
||||
emitter.emit(EventKey.resetWord)
|
||||
}
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user