fix:move components,parse sentences using regular expressions
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
interface IProps {
|
||||
keyboard?: string,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
defineProps<{
|
||||
title?: string,
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
|
||||
import {nextTick, useSlots} from "vue";
|
||||
import {Sort} from "@/types/types.ts";
|
||||
import MiniDialog from "@/pages/pc/components/dialog/MiniDialog.vue";
|
||||
import MiniDialog from "@/components/dialog/MiniDialog.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {cloneDeep, debounce, reverse, shuffle} from "@/utils";
|
||||
import Input from "@/pages/pc/components/Input.vue";
|
||||
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
|
||||
import Input from "@/components/Input.vue";
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import Pagination from '@/pages/pc/components/base/Pagination.vue'
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Checkbox from "@/pages/pc/components/base/checkbox/Checkbox.vue";
|
||||
import Pagination from '@/components/base/Pagination.vue'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import Checkbox from "@/components/base/checkbox/Checkbox.vue";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
import Dialog from "@/pages/pc/components/dialog/Dialog.vue";
|
||||
import Dialog from "@/components/dialog/Dialog.vue";
|
||||
|
||||
let list = defineModel('list')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {Dict} from "@/types/types.ts";
|
||||
import Progress from '@/pages/pc/components/base/Progress.vue'
|
||||
import Checkbox from "@/pages/pc/components/base/checkbox/Checkbox.vue";
|
||||
import Progress from '@/components/base/Progress.vue'
|
||||
import Checkbox from "@/components/base/checkbox/Checkbox.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
item?: Partial<Dict>;
|
||||
@@ -3,7 +3,7 @@
|
||||
import {defineAsyncComponent, onMounted, watch} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
let settingStore = useSettingStore()
|
||||
let show = $ref(false)
|
||||
@@ -3,8 +3,8 @@
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
||||
import {watchEffect} from "vue";
|
||||
import Textarea from "@/pages/pc/components/base/Textarea.vue";
|
||||
import Toast from "@/pages/pc/components/base/toast/Toast.ts";
|
||||
import Textarea from "@/components/base/Textarea.vue";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
|
||||
interface IProps {
|
||||
value: string,
|
||||
@@ -3,7 +3,7 @@ import {computed, provide} from "vue"
|
||||
import {ShortcutKey} from "@/types/types.ts"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Close from "@/components/icon/Close.vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
let tabIndex = $ref(0)
|
||||
@@ -3,7 +3,7 @@
|
||||
import {Word} from "@/types/types.ts";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
item: Word,
|
||||
@@ -1,6 +1,6 @@
|
||||
import {createVNode, render} from 'vue'
|
||||
import ToastComponent from '@/pages/pc/components/base/toast/Toast.vue'
|
||||
import type {ToastOptions, ToastInstance, ToastService} from '@/pages/pc/components/base/toast/type.ts'
|
||||
import ToastComponent from '@/components/base/toast/Toast.vue'
|
||||
import type {ToastOptions, ToastInstance, ToastService} from '@/components/base/toast/type.ts'
|
||||
|
||||
interface ToastContainer {
|
||||
id: string
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import {useEventListener} from "@/hooks/event.ts";
|
||||
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
defineEmits(['click'])
|
||||
defineProps<{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import Input from "@/pages/pc/components/Input.vue";
|
||||
import Input from "@/components/Input.vue";
|
||||
import {Article} from "@/types/types.ts";
|
||||
import BaseList from "@/pages/pc/components/list/BaseList.vue";
|
||||
import BaseList from "@/components/list/BaseList.vue";
|
||||
import * as sea from "node:sea";
|
||||
import {watch, watchEffect} from "vue";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {watch} from "vue";
|
||||
import {DictResource} from "@/types/types.ts";
|
||||
import DictList from "@/pages/pc/components/list/DictList.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
category: string,
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import {Dict} from "@/types/types.ts";
|
||||
import Book from "@/pages/pc/components/Book.vue";
|
||||
import Book from "@/components/Book.vue";
|
||||
|
||||
defineProps<{
|
||||
list?: Partial<Dict>[],
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts" generic="T extends {id:string}">
|
||||
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Input from "@/pages/pc/components/Input.vue";
|
||||
import Input from "@/components/Input.vue";
|
||||
import {cloneDeep, throttle} from "@/utils";
|
||||
import {Article} from "@/types/types.ts";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
import {Word} from "@/types/types.ts";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import BaseList from "@/pages/pc/components/list/BaseList.vue";
|
||||
import BaseList from "@/components/list/BaseList.vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
list: Word[],
|
||||
@@ -3,8 +3,9 @@ import {cloneDeep} from "@/utils";
|
||||
import nlp from "compromise/one";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {getSentenceAllText, getSentenceAllTranslateText} from "@/hooks/translate.ts";
|
||||
import {getDefaultArticleWord} from "@/types/func.ts";
|
||||
import {getDefaultArticleWord, getDefaultWord} from "@/types/func.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
|
||||
interface KeyboardMap {
|
||||
Period: string,
|
||||
@@ -15,14 +16,6 @@ interface KeyboardMap {
|
||||
QuoteRight: string,
|
||||
}
|
||||
|
||||
export const CnKeyboardMap: KeyboardMap = {
|
||||
Period: '。',
|
||||
Comma: ',',
|
||||
Slash: '?',
|
||||
Exclamation: '!',
|
||||
QuoteLeft: '“',
|
||||
QuoteRight: '”',
|
||||
}
|
||||
export const EnKeyboardMap: KeyboardMap = {
|
||||
Period: '.',
|
||||
Comma: ',',
|
||||
@@ -33,198 +26,108 @@ export const EnKeyboardMap: KeyboardMap = {
|
||||
}
|
||||
|
||||
|
||||
function parseSentence(sentence: string) {
|
||||
// 先统一一些常见的“智能引号” -> 直引号,避免匹配问题
|
||||
sentence = sentence
|
||||
.replace(/[\u2018\u2019\u201A\u201B]/g, "'") // 各种单引号 → '
|
||||
.replace(/[\u201C\u201D\u201E\u201F]/g, '"'); // 各种双引号 → "
|
||||
|
||||
const len = sentence.length;
|
||||
const tokens = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < len) {
|
||||
const ch = sentence[i];
|
||||
|
||||
// 跳过空白(但不把空白作为 token)
|
||||
if (/\s/.test(ch)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const rest = sentence.slice(i);
|
||||
|
||||
// 1) 货币 + 数字($1,000.50 或 ¥200 或 €100.5)
|
||||
let m = rest.match(/^[\$¥€£]\d{1,3}(?:,\d{3})*(?:\.\d+)?%?/);
|
||||
if (m) {
|
||||
tokens.push({word: m[0], start: i, end: i + m[0].length, isSymbol: false});
|
||||
i += m[0].length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2) 数字/小数/百分比(100% 3.14 1,000.00)
|
||||
m = rest.match(/^\d{1,3}(?:,\d{3})*(?:\.\d+)?%?/);
|
||||
if (m) {
|
||||
tokens.push({word: m[0], start: i, end: i + m[0].length, isSymbol: false});
|
||||
i += m[0].length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 3) 带点缩写或多段缩写(U.S. U.S.A. e.g. i.e. Ph.D.)
|
||||
m = rest.match(/^[A-Za-z]+(?:\.[A-Za-z]+)+\.?/);
|
||||
if (m) {
|
||||
tokens.push({word: m[0], start: i, end: i + m[0].length, isSymbol: false});
|
||||
i += m[0].length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 4) 单词(包含撇号/连字符,如 it's, o'clock, we'll, mother-in-law)
|
||||
m = rest.match(/^[A-Za-z0-9]+(?:[\'\-][A-Za-z0-9]+)*/);
|
||||
if (m) {
|
||||
tokens.push({word: m[0], start: i, end: i + m[0].length, isSymbol: false});
|
||||
i += m[0].length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 5) 其它可视符号(标点)——单字符处理(连续标点会被循环拆为单字符)
|
||||
// 包括:.,!?;:"'()-[]{}<>/\\@#%^&*~`等非单词非空白字符
|
||||
if (/[^\w\s]/.test(ch)) {
|
||||
tokens.push({word: ch, start: i, end: i + 1, isSymbol: true});
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 6) 回退方案:把当前字符当作一个 token(防止意外丢失)
|
||||
tokens.push({word: ch, start: i, end: i + 1, isSymbol: /[^\w\s]/.test(ch)});
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// 计算 nextSpace:查看当前 token 的 end 到下一个 token 的 start 之间是否含空白
|
||||
const result = tokens.map((t, idx) => {
|
||||
const next = tokens[idx + 1];
|
||||
const between = next ? sentence.slice(t.end, next.start) : sentence.slice(t.end);
|
||||
const nextSpace = /\s/.test(between);
|
||||
return getDefaultArticleWord({word: t.word, nextSpace, isSymbol: !!t.isSymbol});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//生成文章段落数据
|
||||
export function genArticleSectionData(article: Article): number {
|
||||
let text = article.text.trim()
|
||||
|
||||
// console.log('genArticleSectionData',text)
|
||||
|
||||
let keyboardMap = EnKeyboardMap
|
||||
let sections: Sentence[][] = []
|
||||
let sectionTextList = text.split('\n\n')
|
||||
// console.log(sectionTextList);
|
||||
sectionTextList.filter(v => v).map((sectionText, i) => {
|
||||
text.split('\n\n').filter(Boolean).map((sectionText, i) => {
|
||||
let section: Sentence[] = []
|
||||
sections.push(section)
|
||||
sectionText = sectionText.trim()
|
||||
let sentenceNlpList = []
|
||||
sectionText.split('\n').map((rowSection, i) => {
|
||||
let doc = nlp(rowSection)
|
||||
let temp = {text: '', terms: []}
|
||||
doc.json().map(item => {
|
||||
temp.text += item.text
|
||||
temp.terms = temp.terms.concat(item.terms)
|
||||
})
|
||||
sentenceNlpList.push(temp)
|
||||
})
|
||||
|
||||
sentenceNlpList.map(item => {
|
||||
sectionText.trim().split('\n').filter(Boolean).map((item, i, arr) => {
|
||||
item = item.trim()
|
||||
//如果没有空格,导致修改一行一行的数据时,汇总时全没有空格了,库无法正常断句
|
||||
//所以要保证最后一个是空格,但防止用户打N个空格,就去掉再加上一个空格,只需要一个即可
|
||||
if (i < arr.length - 1) item += ' '
|
||||
let sentence: Sentence = cloneDeep({
|
||||
//他没有空格,导致修改一行一行的数据时,汇总时全没有空格了,库无法正常断句
|
||||
text: item.text + ' ',
|
||||
// text: '',
|
||||
text: item,
|
||||
translate: '',
|
||||
words: [],
|
||||
words: parseSentence(item),
|
||||
audioPosition: [0, 0],
|
||||
})
|
||||
section.push(sentence)
|
||||
|
||||
const checkQuote = (pre: string, index?: number) => {
|
||||
let nearSymbolPosition = null
|
||||
if (index === 0) {
|
||||
nearSymbolPosition = 'end'
|
||||
} else {
|
||||
//TODO 可以优化成for+break
|
||||
section.slice().reverse().map((sentenceItem, b) => {
|
||||
sentenceItem.words.slice().reverse().map((wordItem, c) => {
|
||||
if (wordItem.symbolPosition !== '' && nearSymbolPosition === null) {
|
||||
nearSymbolPosition = wordItem.symbolPosition
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let word3: ArticleWord = getDefaultArticleWord({
|
||||
word: pre,
|
||||
nextSpace: false,
|
||||
isSymbol: true,
|
||||
symbolPosition: ''
|
||||
});
|
||||
// console.log('rrr', item)
|
||||
// console.log('nearSymbolPosition', nearSymbolPosition)
|
||||
if (nearSymbolPosition === 'end' || nearSymbolPosition === null) {
|
||||
word3.symbolPosition = 'start'
|
||||
sentence.words.push(word3)
|
||||
} else {
|
||||
sentence.words[sentence.words.length - 1].nextSpace = false
|
||||
word3.symbolPosition = 'end'
|
||||
word3.nextSpace = true
|
||||
|
||||
let addCurrent = false
|
||||
sentence.words.slice().reverse().map((wordItem, c) => {
|
||||
if (wordItem.symbolPosition === 'start' && !addCurrent) {
|
||||
addCurrent = true
|
||||
}
|
||||
})
|
||||
if (addCurrent) {
|
||||
sentence.words.push(word3)
|
||||
} else {
|
||||
// 'Do you always get up so late? It'LICENSE one o'clock!' 会被断成两句
|
||||
let lastSentence = section[section.length - 2]
|
||||
lastSentence.words = lastSentence.words.concat(sentence.words)
|
||||
lastSentence.words.push(word3)
|
||||
sentence.words = []
|
||||
//这里还不能直接删除sentence,因为后面还有一个 sentence.words = sentence.words.filter(v => v.word !== 'placeholder') 的判断
|
||||
// section.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const checkSymbol = (post: string, nextSpace: boolean = true) => {
|
||||
switch (post) {
|
||||
case keyboardMap.Period:
|
||||
case keyboardMap.Comma:
|
||||
case keyboardMap.Slash:
|
||||
case keyboardMap.Exclamation:
|
||||
sentence.words[sentence.words.length - 1].nextSpace = false
|
||||
let word2 = getDefaultArticleWord({
|
||||
word: post,
|
||||
isSymbol: true,
|
||||
nextSpace
|
||||
});
|
||||
sentence.words.push(word2)
|
||||
break
|
||||
case keyboardMap.QuoteLeft:
|
||||
case ')':
|
||||
checkQuote(post)
|
||||
break
|
||||
case `.'`:
|
||||
case `!'`:
|
||||
case `?'`:
|
||||
case `,'`:
|
||||
case `*'`:
|
||||
post.split('').map(v => {
|
||||
checkSymbol(v, false)
|
||||
})
|
||||
break
|
||||
//类似于这种的“' -- ”的。需要保留空格,用了一个占位符才处理,因为每个符号都会把前面的那个字符的nextSpace改为false
|
||||
case ' ':
|
||||
// console.log('sentence', sentence)
|
||||
//遇到“The clock has stopped!' I looked at my watch.”
|
||||
//检测到stopped!' 的'时,如果前引号不在当前句,会把当前句的word合并到前一句。那么当前句的word就为空了,会报错
|
||||
//所以需要检测一下
|
||||
if (sentence.words.length) {
|
||||
sentence.words[sentence.words.length - 1].nextSpace = true
|
||||
let word3 = getDefaultArticleWord({
|
||||
word: 'placeholder',
|
||||
isSymbol: true,
|
||||
nextSpace: false,
|
||||
});
|
||||
sentence.words.push(word3)
|
||||
}
|
||||
break
|
||||
default:
|
||||
// console.log('post', post)
|
||||
//这里多半是一些奇怪的连接符之类的
|
||||
if (post.length > 1) {
|
||||
post.split('').map(v => {
|
||||
checkSymbol(v, false)
|
||||
})
|
||||
} else {
|
||||
sentence.words[sentence.words.length - 1].nextSpace = false
|
||||
let word3 = getDefaultArticleWord({
|
||||
word: post,
|
||||
isSymbol: true,
|
||||
nextSpace: false,
|
||||
});
|
||||
sentence.words.push(word3)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
item.terms.map((v, index: number) => {
|
||||
// console.log('v', v)
|
||||
if (v.text) {
|
||||
let pre: string = v.pre.trim()
|
||||
if (pre) {
|
||||
checkQuote(pre, index)
|
||||
}
|
||||
|
||||
let word = getDefaultArticleWord({word: v.text, nextSpace: true});
|
||||
sentence.words.push(word)
|
||||
|
||||
let post: string = v.post
|
||||
//判断是不是等于空,因为正常的词后面都会有个空格。这种不需要处理。
|
||||
if (post && post !== ' ') {
|
||||
checkSymbol(post.trim())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//去除空格占位符
|
||||
sentence.words = sentence.words.filter(v => v.word !== 'placeholder')
|
||||
//如果是空的,直接去掉
|
||||
if (!sentence.words.length) {
|
||||
section.pop()
|
||||
}
|
||||
})
|
||||
|
||||
// console.log('section', section)
|
||||
})
|
||||
|
||||
sections = sections.filter(sectionItem => sectionItem.length)
|
||||
sections.map((sectionItem, a) => {
|
||||
sectionItem.map((sentenceItem, b) => {
|
||||
sentenceItem.text = sentenceItem.words.reduce((previousValue: string, currentValue) => {
|
||||
previousValue += currentValue.word + (currentValue.nextSpace ? ' ' : '')
|
||||
return previousValue
|
||||
}, '')
|
||||
})
|
||||
})
|
||||
|
||||
// console.log(sections)
|
||||
sections = sections.filter(v => v.length)
|
||||
article.sections = sections
|
||||
console.log(sections)
|
||||
|
||||
let failCount = 0
|
||||
let translateList = article.textTranslate?.split('\n\n') || []
|
||||
@@ -469,7 +372,6 @@ Its none of your business, the young man said rudely. This is a private conversa
|
||||
section.pop()
|
||||
}
|
||||
})
|
||||
|
||||
// console.log(sentenceNlpList)
|
||||
})
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ export function getSentenceAllTranslateText(article: Article) {
|
||||
}
|
||||
|
||||
export function getSentenceAllText(article: Article) {
|
||||
return article.sections.map(v => v.map(s => s.text.trim()).filter(v => v).join(' \n')).filter(v => v).join(' \n\n');
|
||||
return article.sections.map(v => v.map(s => s.text).filter(v => v).join('\n')).filter(v => v).join('\n\n');
|
||||
}
|
||||
|
||||
/***
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import {_getDictDataByUrl, useNav} from "@/utils";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import {_getDictDataByUrl, cloneDeep, useNav} from "@/utils";
|
||||
import {DictResource, DictType} from "@/types/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Book from "@/pages/pc/components/Book.vue";
|
||||
import Progress from '@/pages/pc/components/base/Progress.vue';
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Book from "@/components/Book.vue";
|
||||
import Progress from '@/components/base/Progress.vue';
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import {onMounted, watch} from "vue";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
import recommendBookList from "@/assets/book-list.json";
|
||||
import {genArticleSectionData} from "@/hooks/article.ts";
|
||||
|
||||
const {nav} = useNav()
|
||||
const base = useBaseStore()
|
||||
@@ -34,6 +35,9 @@ async function init() {
|
||||
}
|
||||
|
||||
function startStudy() {
|
||||
// console.log(store.sbook.articles[1])
|
||||
// genArticleSectionData(cloneDeep(store.sbook.articles[1]))
|
||||
// return
|
||||
if (base.sbook.id) {
|
||||
if (!base.sbook.articles.length) {
|
||||
return Toast.warning('没有文章可学习!')
|
||||
@@ -4,16 +4,16 @@ import BaseButton from "@/components/BaseButton.vue";
|
||||
import {_nextTick, cloneDeep, loadJsLib} from "@/utils";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
|
||||
import List from "@/pages/pc/components/list/List.vue";
|
||||
import List from "@/components/list/List.vue";
|
||||
import {useWindowClick} from "@/hooks/event.ts";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {nanoid} from "nanoid";
|
||||
import EditArticle from "@/pages/pc/article/components/EditArticle.vue";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import EditArticle from "@/pages/article/components/EditArticle.vue";
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import {getDefaultArticle} from "@/types/func.ts";
|
||||
import BackIcon from "@/pages/pc/components/BackIcon.vue";
|
||||
import MiniDialog from "@/pages/pc/components/dialog/MiniDialog.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import MiniDialog from "@/components/dialog/MiniDialog.vue";
|
||||
import {onMounted} from "vue";
|
||||
import {Origin} from "@/config/ENV.ts";
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import BackIcon from "@/pages/pc/components/BackIcon.vue";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import ArticleList from "@/pages/pc/components/list/ArticleList.vue";
|
||||
import ArticleList from "@/components/list/ArticleList.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {Article, Dict, DictId, DictType} from "@/types/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import EditBook from "@/pages/pc/article/components/EditBook.vue";
|
||||
import EditBook from "@/pages/article/components/EditBook.vue";
|
||||
import {computed, onMounted} from "vue";
|
||||
import {_dateFormat, _getDictDataByUrl, cloneDeep, msToHourMinute, total, useNav} from "@/utils";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {useArticleOptions} from "@/hooks/dict.ts";
|
||||
import {getDefaultArticle, getDefaultDict} from "@/types/func.ts";
|
||||
import Toast from "@/pages/pc/components/base/toast/Toast.ts";
|
||||
import ArticleAudio from "@/pages/pc/article/components/ArticleAudio.vue";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
import ArticleAudio from "@/pages/article/components/ArticleAudio.vue";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import book_list from "@/assets/book-list.json";
|
||||
|
||||
@@ -185,7 +185,7 @@ const totalSpend = $computed(() => {
|
||||
<div class="font-family text-base mb-4" v-if="currentPractice.length">
|
||||
<div>学习记录:{{ msToHourMinute(total(currentPractice, 'spend'))}}</div>
|
||||
<div class="item" v-for="i in currentPractice">
|
||||
{{_dateFormat(i.startDate,'YYYY-MM-DD HH-mm')}}: {{ msToHourMinute(i.spend) }}
|
||||
{{_dateFormat(i.startDate,'YYYY/MM/DD HH-mm')}}: {{ msToHourMinute(i.spend) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="en-article-family title text-xl">
|
||||
@@ -1,14 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import {useNav} from "@/utils";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import {DictResource} from "@/types/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import Input from "@/pages/pc/components/Input.vue";
|
||||
import Input from "@/components/Input.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import DictList from "@/pages/pc/components/list/DictList.vue";
|
||||
import BackIcon from "@/pages/pc/components/BackIcon.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import book_list from "@/assets/book-list.json";
|
||||
import {computed} from "vue";
|
||||
@@ -7,25 +7,25 @@ import {useSettingStore} from "@/stores/setting.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'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import {_getDictDataByUrl, cloneDeep, msToHourMinute, msToMinute, total} from "@/utils";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {useArticleOptions} from "@/hooks/dict.ts";
|
||||
import {genArticleSectionData, usePlaySentenceAudio} from "@/hooks/article.ts";
|
||||
import {getDefaultArticle, getDefaultDict, getDefaultWord} from "@/types/func.ts";
|
||||
import TypingArticle from "@/pages/pc/article/components/TypingArticle.vue";
|
||||
import TypingArticle from "@/pages/article/components/TypingArticle.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Panel from "@/pages/pc/components/Panel.vue";
|
||||
import ArticleList from "@/pages/pc/components/list/ArticleList.vue";
|
||||
import EditSingleArticleModal from "@/pages/pc/article/components/EditSingleArticleModal.vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import ConflictNotice from "@/pages/pc/components/ConflictNotice.vue";
|
||||
import Panel from "@/components/Panel.vue";
|
||||
import ArticleList from "@/components/list/ArticleList.vue";
|
||||
import EditSingleArticleModal from "@/pages/article/components/EditSingleArticleModal.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import ConflictNotice from "@/components/ConflictNotice.vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import book_list from "@/assets/book-list.json";
|
||||
import PracticeLayout from "@/pages/pc/components/PracticeLayout.vue";
|
||||
import Switch from "@/pages/pc/components/base/Switch.vue";
|
||||
import Audio from "@/pages/pc/components/base/Audio.vue";
|
||||
import ArticleAudio from "@/pages/pc/article/components/ArticleAudio.vue";
|
||||
import PracticeLayout from "@/components/PracticeLayout.vue";
|
||||
import Switch from "@/components/base/Switch.vue";
|
||||
import Audio from "@/components/base/Audio.vue";
|
||||
import ArticleAudio from "@/pages/article/components/ArticleAudio.vue";
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -3,7 +3,7 @@ import {Article} from "@/types/types.ts";
|
||||
import {watch} from "vue";
|
||||
import {LOCAL_FILE_KEY} from "@/utils/const.ts";
|
||||
import {get} from "idb-keyval";
|
||||
import Audio from "@/pages/pc/components/base/Audio.vue";
|
||||
import Audio from "@/components/base/Audio.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
article: Article
|
||||
@@ -2,28 +2,28 @@
|
||||
|
||||
import {Article, Sentence, TranslateEngine} from "@/types/types.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import EditAbleText from "@/pages/pc/components/EditAbleText.vue";
|
||||
import EditAbleText from "@/components/EditAbleText.vue";
|
||||
import {getNetworkTranslate, getSentenceAllText, getSentenceAllTranslateText} from "@/hooks/translate.ts";
|
||||
import {genArticleSectionData, splitCNArticle2, splitEnArticle2, usePlaySentenceAudio} from "@/hooks/article.ts";
|
||||
import {_nextTick, _parseLRC, cloneDeep, last} from "@/utils";
|
||||
import {defineAsyncComponent, watch} from "vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import * as Comparison from "string-comparison"
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {getDefaultArticle} from "@/types/func.ts";
|
||||
import copy from "copy-to-clipboard";
|
||||
import {Option, Select} from "@/pages/pc/components/base/select";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import InputNumber from "@/pages/pc/components/base/InputNumber.vue";
|
||||
import {Option, Select} from "@/components/base/select";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import InputNumber from "@/components/base/InputNumber.vue";
|
||||
import {nanoid} from "nanoid";
|
||||
import {update} from "idb-keyval";
|
||||
import {LOCAL_FILE_KEY} from "@/utils/const.ts";
|
||||
import ArticleAudio from "@/pages/pc/article/components/ArticleAudio.vue";
|
||||
import BaseInput from "@/pages/pc/components/base/BaseInput.vue";
|
||||
import Textarea from "@/pages/pc/components/base/Textarea.vue";
|
||||
import ArticleAudio from "@/pages/article/components/ArticleAudio.vue";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
import Textarea from "@/components/base/Textarea.vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
interface IProps {
|
||||
article?: Article,
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
import {Dict, DictId, DictType} from "@/types/types.ts";
|
||||
import {cloneDeep} from "@/utils";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import {onMounted, reactive} from "vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import {Option, Select} from "@/pages/pc/components/base/select";
|
||||
import BaseInput from "@/pages/pc/components/base/BaseInput.vue";
|
||||
import Form from "@/pages/pc/components/base/form/Form.vue";
|
||||
import FormItem from "@/pages/pc/components/base/form/FormItem.vue";
|
||||
import {Option, Select} from "@/components/base/select";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
import Form from "@/components/base/form/Form.vue";
|
||||
import FormItem from "@/components/base/form/FormItem.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
isAdd: boolean,
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import {Article} from "@/types/types.ts";
|
||||
import {useDisableEventListener} from "@/hooks/event.ts";
|
||||
import EditArticle from "@/pages/pc/article/components/EditArticle.vue";
|
||||
import EditArticle from "@/pages/article/components/EditArticle.vue";
|
||||
import {getDefaultArticle} from "@/types/func.ts";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
interface IProps {
|
||||
article?: Article
|
||||
@@ -45,7 +45,7 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, useTemplateRef} from 'vue'
|
||||
import QuestionItem from './QuestionItem.vue'
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
|
||||
interface IProps {
|
||||
questions: Array,
|
||||
@@ -10,11 +10,11 @@ import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css'
|
||||
import ContextMenu from '@imengyu/vue3-context-menu'
|
||||
import {getTranslateText} from "@/hooks/article.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import QuestionForm from "@/pages/pc/article/components/QuestionForm.vue";
|
||||
import QuestionForm from "@/pages/article/components/QuestionForm.vue";
|
||||
import {getDefaultArticle, getDefaultWord} from "@/types/func.ts";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import TypingWord from "@/pages/pc/article/components/TypingWord.vue";
|
||||
import Space from "@/pages/pc/article/components/Space.vue";
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import TypingWord from "@/pages/article/components/TypingWord.vue";
|
||||
import Space from "@/pages/article/components/Space.vue";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
import nlp from "compromise/three";
|
||||
import {nanoid} from "nanoid";
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="tsx">
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Space from "@/pages/pc/article/components/Space.vue";
|
||||
import Space from "@/pages/article/components/Space.vue";
|
||||
//引入这个编译就报错
|
||||
// import {ArticleWord} from "@/types/types.ts";
|
||||
|
||||
@@ -4,7 +4,7 @@ import BaseButton from "@/components/BaseButton.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
let showWechatDialog = $ref(false)
|
||||
let showXhsDialog = $ref(false)
|
||||
</script>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {ShortcutKey} from "@/types/types.ts";
|
||||
import Logo from "@/pages/pc/components/Logo.vue";
|
||||
import Logo from "@/components/Logo.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import useTheme from "@/hooks/theme.ts";
|
||||
@@ -1,17 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import EditArticle from "@/pages/pc/article/components/EditArticle.vue";
|
||||
import BackIcon from "@/pages/pc/components/BackIcon.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-screen">
|
||||
<BackIcon/>
|
||||
<EditArticle class="vue"></EditArticle>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -20,17 +20,17 @@ import {useBaseStore} from "@/stores/base.ts";
|
||||
import {saveAs} from "file-saver";
|
||||
import {Origin} from "@/config/ENV.ts";
|
||||
import dayjs from "dayjs";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import {Option, Select} from "@/pages/pc/components/base/select";
|
||||
import Switch from "@/pages/pc/components/base/Switch.vue";
|
||||
import Slider from "@/pages/pc/components/base/Slider.vue";
|
||||
import RadioGroup from "@/pages/pc/components/base/radio/RadioGroup.vue";
|
||||
import Radio from "@/pages/pc/components/base/radio/Radio.vue";
|
||||
import InputNumber from "@/pages/pc/components/base/InputNumber.vue";
|
||||
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
|
||||
import Textarea from "@/pages/pc/components/base/Textarea.vue";
|
||||
import SettingItem from "@/pages/pc/setting/SettingItem.vue";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import {Option, Select} from "@/components/base/select";
|
||||
import Switch from "@/components/base/Switch.vue";
|
||||
import Slider from "@/components/base/Slider.vue";
|
||||
import RadioGroup from "@/components/base/radio/RadioGroup.vue";
|
||||
import Radio from "@/components/base/radio/Radio.vue";
|
||||
import InputNumber from "@/components/base/InputNumber.vue";
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import Textarea from "@/components/base/Textarea.vue";
|
||||
import SettingItem from "@/pages/setting/SettingItem.vue";
|
||||
import {get, set} from "idb-keyval";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<script setup lang="tsx">
|
||||
import {DictId} from "@/types/types.ts";
|
||||
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import {computed, onMounted, reactive, ref, shallowReactive} from "vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {_getDictDataByUrl, _nextTick, convertToWord, loadJsLib, useNav} from "@/utils";
|
||||
import {nanoid} from "nanoid";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseTable from "@/pages/pc/components/BaseTable.vue";
|
||||
import WordItem from "@/pages/pc/components/WordItem.vue";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
|
||||
import BackIcon from "@/pages/pc/components/BackIcon.vue";
|
||||
import BaseTable from "@/components/BaseTable.vue";
|
||||
import WordItem from "@/components/WordItem.vue";
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import EditBook from "@/pages/pc/article/components/EditBook.vue";
|
||||
import EditBook from "@/pages/article/components/EditBook.vue";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import BaseInput from "@/pages/pc/components/base/BaseInput.vue";
|
||||
import Textarea from "@/pages/pc/components/base/Textarea.vue";
|
||||
import FormItem from "@/pages/pc/components/base/form/FormItem.vue";
|
||||
import Form from "@/pages/pc/components/base/form/Form.vue";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
import Textarea from "@/components/base/Textarea.vue";
|
||||
import FormItem from "@/components/base/form/FormItem.vue";
|
||||
import Form from "@/components/base/form/Form.vue";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
import {getCurrentStudyWord} from "@/hooks/dict.ts";
|
||||
import PracticeSettingDialog from "@/pages/pc/word/components/PracticeSettingDialog.vue";
|
||||
import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {Origin} from "@/config/ENV.ts";
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import {groupBy, useNav} from "@/utils";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import {DictResource} from "@/types/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import Input from "@/pages/pc/components/Input.vue";
|
||||
import Input from "@/components/Input.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import DictList from "@/pages/pc/components/list/DictList.vue";
|
||||
import BackIcon from "@/pages/pc/components/BackIcon.vue";
|
||||
import DictGroup from "@/pages/pc/components/list/DictGroup.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import DictGroup from "@/components/list/DictGroup.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import {computed} from "vue";
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import {onMounted, provide, watch} from "vue";
|
||||
|
||||
import Statistics from "@/pages/pc/word/Statistics.vue";
|
||||
import Statistics from "@/pages/word/Statistics.vue";
|
||||
import {emitter, EventKey, useEvents} from "@/utils/eventBus.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
@@ -12,20 +12,20 @@ import useTheme from "@/hooks/theme.ts";
|
||||
import {getCurrentStudyWord, useWordOptions} from "@/hooks/dict.ts";
|
||||
import {_getDictDataByUrl, cloneDeep, shuffle} from "@/utils";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import Footer from "@/pages/pc/word/components/Footer.vue";
|
||||
import Panel from "@/pages/pc/components/Panel.vue";
|
||||
import Footer from "@/pages/word/components/Footer.vue";
|
||||
import Panel from "@/components/Panel.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import WordList from "@/pages/pc/components/list/WordList.vue";
|
||||
import TypeWord from "@/pages/pc/word/components/TypeWord.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import TypeWord from "@/pages/word/components/TypeWord.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import {getDefaultDict, getDefaultWord} from "@/types/func.ts";
|
||||
import ConflictNotice from "@/pages/pc/components/ConflictNotice.vue";
|
||||
import ConflictNotice from "@/components/ConflictNotice.vue";
|
||||
import dict_list from "@/assets/dict-list.json";
|
||||
import PracticeLayout from "@/pages/pc/components/PracticeLayout.vue";
|
||||
import PracticeLayout from "@/components/PracticeLayout.vue";
|
||||
|
||||
interface IProps {
|
||||
new: Word[],
|
||||
@@ -9,7 +9,7 @@ import dayjs from "dayjs";
|
||||
import isBetween from "dayjs/plugin/isBetween";
|
||||
import {defineAsyncComponent, watch} from "vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
dayjs.extend(isBetween);
|
||||
|
||||
@@ -3,23 +3,23 @@ import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {_getAccomplishDate, _getDictDataByUrl, useNav} from "@/utils";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import {DictResource} from "@/types/types.ts";
|
||||
import {watch} from "vue";
|
||||
import {getCurrentStudyWord} from "@/hooks/dict.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import Book from "@/pages/pc/components/Book.vue";
|
||||
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
|
||||
import Progress from '@/pages/pc/components/base/Progress.vue';
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts';
|
||||
import Book from "@/components/Book.vue";
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import Progress from '@/components/base/Progress.vue';
|
||||
import Toast from '@/components/base/toast/Toast.ts';
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
import PracticeSettingDialog from "@/pages/pc/word/components/PracticeSettingDialog.vue";
|
||||
import ChangeLastPracticeIndexDialog from "@/pages/pc/word/components/ChangeLastPracticeIndexDialog.vue";
|
||||
import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog.vue";
|
||||
import ChangeLastPracticeIndexDialog from "@/pages/word/components/ChangeLastPracticeIndexDialog.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import recommendDictList from "@/assets/recommend-dict-list.json";
|
||||
import CollectNotice from "@/pages/pc/components/CollectNotice.vue";
|
||||
import CollectNotice from "@/components/CollectNotice.vue";
|
||||
|
||||
|
||||
const store = useBaseStore()
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import BaseTable from "@/pages/pc/components/BaseTable.vue";
|
||||
import WordItem from "@/pages/pc/components/WordItem.vue";
|
||||
import BaseTable from "@/components/BaseTable.vue";
|
||||
import WordItem from "@/components/WordItem.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {defineAsyncComponent} from "vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
const model = defineModel()
|
||||
const store = useBaseStore()
|
||||
@@ -5,8 +5,8 @@ import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {ShortcutKey, StudyData} from "@/types/types.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Progress from '@/pages/pc/components/base/Progress.vue'
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import Progress from '@/components/base/Progress.vue'
|
||||
|
||||
const statisticsStore = usePracticeStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -1,19 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {_getAccomplishDays} from "@/utils";
|
||||
import Radio from "@/pages/pc/components/base/radio/Radio.vue";
|
||||
import RadioGroup from "@/pages/pc/components/base/radio/RadioGroup.vue";
|
||||
import Radio from "@/components/base/radio/Radio.vue";
|
||||
import RadioGroup from "@/components/base/radio/RadioGroup.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import Checkbox from "@/pages/pc/components/base/checkbox/Checkbox.vue";
|
||||
import Slider from "@/pages/pc/components/base/Slider.vue";
|
||||
import Checkbox from "@/components/base/checkbox/Checkbox.vue";
|
||||
import Slider from "@/components/base/Slider.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {defineAsyncComponent, watch} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Toast from "@/pages/pc/components/base/toast/Toast.ts";
|
||||
import ChangeLastPracticeIndexDialog from "@/pages/pc/word/components/ChangeLastPracticeIndexDialog.vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
import ChangeLastPracticeIndexDialog from "@/pages/word/components/ChangeLastPracticeIndexDialog.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue'))
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
const store = useBaseStore()
|
||||
const settings = useSettingStore()
|
||||
@@ -5,8 +5,8 @@ import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio, useTTsPlayAudio} from "@/hooks/sound.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {nextTick, onMounted, onUnmounted, watch} from "vue";
|
||||
import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
|
||||
import SentenceHightLightWord from "@/pages/pc/word/components/SentenceHightLightWord.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import SentenceHightLightWord from "@/pages/word/components/SentenceHightLightWord.vue";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {getDefaultWord} from "@/types/func.ts";
|
||||
import {sleep} from "@/utils";
|
||||
114
src/router.ts
114
src/router.ts
@@ -1,17 +1,16 @@
|
||||
import * as VueRouter from 'vue-router'
|
||||
import {RouteRecordRaw} from 'vue-router'
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import WordHomePage from "@/pages/pc/word/WordHomePage.vue";
|
||||
import PC from "@/pages/pc/index.vue";
|
||||
import ArticleHomePage from "@/pages/pc/article/ArticleHomePage.vue";
|
||||
import StudyArticle from "@/pages/pc/article/StudyArticle.vue";
|
||||
import DictDetail from "@/pages/pc/word/DictDetail.vue";
|
||||
import StudyWord from "@/pages/pc/word/StudyWord.vue";
|
||||
import BookDetail from "@/pages/pc/article/BookDetail.vue";
|
||||
import DictList from "@/pages/pc/word/DictList.vue";
|
||||
import BookList from "@/pages/pc/article/BookList.vue";
|
||||
import Setting from "@/pages/pc/setting/Setting.vue";
|
||||
import Home from "@/pages/pc/home/index.vue";
|
||||
import WordsPage from "@/pages/word/WordsPage.vue";
|
||||
import PC from "@/pages/index.vue";
|
||||
import ArticlesPage from "@/pages/article/ArticlesPage.vue";
|
||||
import PracticeArticles from "@/pages/article/PracticeArticles.vue";
|
||||
import DictDetail from "@/pages/word/DictDetail.vue";
|
||||
import PracticeWords from "@/pages/word/PracticeWords.vue";
|
||||
import BookDetail from "@/pages/article/BookDetail.vue";
|
||||
import DictList from "@/pages/word/DictList.vue";
|
||||
import BookList from "@/pages/article/BookList.vue";
|
||||
import Setting from "@/pages/setting/Setting.vue";
|
||||
import Home from "@/pages/home/index.vue";
|
||||
|
||||
export const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
@@ -20,25 +19,23 @@ export const routes: RouteRecordRaw[] = [
|
||||
redirect: '/',
|
||||
children: [
|
||||
{path: '/', component: Home},
|
||||
{path: 'words', component: WordHomePage},
|
||||
{path: 'words', component: WordsPage},
|
||||
{path: 'word', redirect: '/words'},
|
||||
{path: 'practice-words/:id', component: PracticeWords},
|
||||
{path: 'study-word', redirect: '/words'},
|
||||
{path: 'dict-list', component: DictList},
|
||||
{path: 'practice-words/:id', component: StudyWord},
|
||||
{path: 'study-word', redirect: '/word'},
|
||||
{path: 'dict-detail', component: DictDetail},
|
||||
|
||||
{path: 'articles', component: ArticleHomePage},
|
||||
{path: 'articles', component: ArticlesPage},
|
||||
{path: 'article', redirect: '/articles'},
|
||||
{path: 'practice-articles/:id', component: StudyArticle},
|
||||
{path: 'study-article', redirect: '/article'},
|
||||
{path: 'practice-articles/:id', component: PracticeArticles},
|
||||
{path: 'study-article', redirect: '/articles'},
|
||||
{path: 'book-detail', component: BookDetail},
|
||||
{path: 'book-list', component: BookList},
|
||||
{path: 'edit-article', component: () => import("@/pages/pc/article/EditArticlePage.vue")},
|
||||
|
||||
{path: 'setting', component: Setting},
|
||||
]
|
||||
},
|
||||
{path: '/batch-edit-article', component: () => import("@/pages/pc/article/BatchEditArticlePage.vue")},
|
||||
{path: '/batch-edit-article', component: () => import("@/pages/article/BatchEditArticlePage.vue")},
|
||||
{path: '/test', component: () => import("@/pages/test/test.vue")},
|
||||
{path: '/:pathMatch(.*)*', redirect: '/word'},
|
||||
]
|
||||
@@ -59,48 +56,47 @@ const router = VueRouter.createRouter({
|
||||
|
||||
router.beforeEach((to: any, from: any) => {
|
||||
return true
|
||||
|
||||
// console.log('beforeEach-to',to.path)
|
||||
// console.log('beforeEach-from',from.path)
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
//footer下面的5个按钮,对跳不要用动画
|
||||
let noAnimation = [
|
||||
'/pc/practice',
|
||||
'/pc/dict',
|
||||
'/mobile',
|
||||
'/'
|
||||
]
|
||||
|
||||
if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
|
||||
return true
|
||||
}
|
||||
|
||||
const toDepth = routes.findIndex(v => v.path === to.path)
|
||||
const fromDepth = routes.findIndex(v => v.path === from.path)
|
||||
// const fromDepth = routeDeep.indexOf(from.path)
|
||||
|
||||
if (toDepth > fromDepth) {
|
||||
if (to.matched && to.matched.length) {
|
||||
let def = to.matched[0].components.default
|
||||
let toComponentName = def.name ?? def.__name
|
||||
runtimeStore.updateExcludeRoutes({type: 'remove', value: toComponentName})
|
||||
// console.log('删除', toComponentName)
|
||||
// console.log('前进')
|
||||
// console.log('删除', toComponentName)
|
||||
}
|
||||
} else {
|
||||
if (from.matched && from.matched.length) {
|
||||
let def = from.matched[0].components.default
|
||||
let fromComponentName = def.name ?? def.__name
|
||||
runtimeStore.updateExcludeRoutes({type: 'add', value: fromComponentName})
|
||||
// console.log('添加', fromComponentName)
|
||||
// console.log('后退')
|
||||
}
|
||||
}
|
||||
// const runtimeStore = useRuntimeStore()
|
||||
//
|
||||
// //footer下面的5个按钮,对跳不要用动画
|
||||
// let noAnimation = [
|
||||
// '/pc/practice',
|
||||
// '/pc/dict',
|
||||
// '/mobile',
|
||||
// '/'
|
||||
// ]
|
||||
//
|
||||
// if (noAnimation.indexOf(from.path) !== -1 && noAnimation.indexOf(to.path) !== -1) {
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// const toDepth = routes.findIndex(v => v.path === to.path)
|
||||
// const fromDepth = routes.findIndex(v => v.path === from.path)
|
||||
// // const fromDepth = routeDeep.indexOf(from.path)
|
||||
//
|
||||
// if (toDepth > fromDepth) {
|
||||
// if (to.matched && to.matched.length) {
|
||||
// let def = to.matched[0].components.default
|
||||
// let toComponentName = def.name ?? def.__name
|
||||
// runtimeStore.updateExcludeRoutes({type: 'remove', value: toComponentName})
|
||||
// // console.log('删除', toComponentName)
|
||||
// // console.log('前进')
|
||||
// // console.log('删除', toComponentName)
|
||||
// }
|
||||
// } else {
|
||||
// if (from.matched && from.matched.length) {
|
||||
// let def = from.matched[0].components.default
|
||||
// let fromComponentName = def.name ?? def.__name
|
||||
// runtimeStore.updateExcludeRoutes({type: 'add', value: fromComponentName})
|
||||
// // console.log('添加', fromComponentName)
|
||||
// // console.log('后退')
|
||||
// }
|
||||
// }
|
||||
// ...
|
||||
// 返回 false 以取消导航
|
||||
return true
|
||||
// return true
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {createVNode, render} from 'vue'
|
||||
import Dialog, {ModalProps} from "@/pages/pc/components/dialog/Dialog.vue";
|
||||
import Dialog, {ModalProps} from "@/components/dialog/Dialog.vue";
|
||||
|
||||
export class MessageBox {
|
||||
static confirm(
|
||||
|
||||
@@ -8,7 +8,7 @@ import dayjs from 'dayjs'
|
||||
import axios from "axios";
|
||||
import {env} from "@/config/ENV.ts";
|
||||
import {nextTick} from "vue";
|
||||
import Toast from '@/pages/pc/components/base/toast/Toast.ts'
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import {getDefaultArticle, getDefaultDict, getDefaultWord} from "@/types/func.ts";
|
||||
import {set} from "idb-keyval";
|
||||
import book_list from "@/assets/book-list.json";
|
||||
|
||||
Reference in New Issue
Block a user