feat(al): update select aritlce
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
getNetworkTranslate,
|
||||
getSentenceAllText,
|
||||
getSentenceAllTranslateText,
|
||||
updateLocalSentenceTranslate
|
||||
updateLocalSentenceTranslate, updateSections
|
||||
} from "@/hooks/translate.ts";
|
||||
import * as copy from "copy-to-clipboard";
|
||||
import {getSplitTranslateText, splitEnArticle} from "@/hooks/article.ts";
|
||||
@@ -39,24 +39,29 @@ useEsc(() => {
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (article.text.trim()) {
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
if (article.textCustomTranslate.trim()) {
|
||||
if (!article.textCustomTranslateIsFormat) {
|
||||
let r = getSplitTranslateText(article.textCustomTranslate)
|
||||
if (r) article.textCustomTranslate = r
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSentenceTranslate()
|
||||
})
|
||||
|
||||
function updateSections() {
|
||||
let {text, sections} = splitEnArticle(article.article)
|
||||
article.article = text
|
||||
article.sections = sections
|
||||
}
|
||||
|
||||
async function startNetworkTranslate() {
|
||||
if (!article.title.trim()) {
|
||||
return ElMessage.error('请填写标题!')
|
||||
}
|
||||
if (!article.article.trim()) {
|
||||
if (!article.text.trim()) {
|
||||
return ElMessage.error('请填写正文!')
|
||||
}
|
||||
updateSections()
|
||||
article.networkTranslate = ''
|
||||
updateSections(article)
|
||||
article.textNetworkTranslate = ''
|
||||
//注意!!!
|
||||
//这里需要用异步,因为watch了article.networkTranslate,改变networkTranslate了之后,会重新设置article.sections
|
||||
//导致getNetworkTranslate里面拿到的article.sections是废弃的值
|
||||
@@ -71,35 +76,38 @@ async function startNetworkTranslate() {
|
||||
|
||||
function saveSentenceTranslate(sentence: Sentence, val: string) {
|
||||
sentence.translate = val
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
article.customTranslate = getSentenceAllTranslateText(article)
|
||||
} else {
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
article.textCustomTranslate = getSentenceAllTranslateText(article)
|
||||
}
|
||||
if (article.useTranslateType === TranslateType.network) {
|
||||
article.textNetworkTranslate = getSentenceAllTranslateText(article)
|
||||
}
|
||||
}
|
||||
|
||||
function saveSentenceText(sentence: Sentence, val: string) {
|
||||
sentence.text = val
|
||||
article.article = getSentenceAllText(article)
|
||||
article.text = getSentenceAllText(article)
|
||||
updateSentenceTranslate()
|
||||
}
|
||||
|
||||
function updateSentenceTranslate() {
|
||||
if (article.article.trim()) {
|
||||
updateSections()
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
} else {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
if (article.text.trim()) {
|
||||
updateSections(article)
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
updateLocalSentenceTranslate(article, article.textCustomTranslate)
|
||||
}
|
||||
if (article.useTranslateType === TranslateType.network) {
|
||||
updateLocalSentenceTranslate(article, article.textNetworkTranslate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appendTranslate(str: string) {
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
article.customTranslate += str
|
||||
} else {
|
||||
article.networkTranslate += str
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
article.textCustomTranslate += str
|
||||
}
|
||||
if (article.useTranslateType === TranslateType.network) {
|
||||
article.textNetworkTranslate += str
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,65 +142,67 @@ function save() {
|
||||
if (!article.title.trim()) {
|
||||
return ElMessage.error('请填写标题!')
|
||||
}
|
||||
if (!article.article.trim()) {
|
||||
if (!article.text.trim()) {
|
||||
return ElMessage.error('请填写正文!')
|
||||
}
|
||||
|
||||
const saveTemp = ()=>{
|
||||
article.translateSplit = true
|
||||
const saveTemp = () => {
|
||||
article.textCustomTranslateIsFormat = true
|
||||
emit('close')
|
||||
emit('save', cloneDeep(article))
|
||||
}
|
||||
|
||||
if (article.translateType === TranslateType.network) {
|
||||
if (!article.networkTranslate.trim()) {
|
||||
if (article.useTranslateType === TranslateType.network) {
|
||||
if (!article.textNetworkTranslate.trim()) {
|
||||
return ElMessageBox.confirm('您选择了“网络翻译”,但译文内容却为空白,是否修改为“不需要翻译”并保存?', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
article.translateType = TranslateType.none
|
||||
article.useTranslateType = TranslateType.none
|
||||
saveTemp()
|
||||
}).catch(() => void 0)
|
||||
}
|
||||
}
|
||||
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
if (!article.customTranslate.trim()) {
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
if (!article.textCustomTranslate.trim()) {
|
||||
return ElMessageBox.confirm('您选择了“本地翻译”,但译文内容却为空白,是否修改为“不需要翻译”并保存?', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
article.translateType = TranslateType.none
|
||||
article.useTranslateType = TranslateType.none
|
||||
saveTemp()
|
||||
}).catch(() => void 0)
|
||||
}
|
||||
}
|
||||
|
||||
saveTemp()
|
||||
}
|
||||
|
||||
watch(() => article.customTranslate, (str: string) => {
|
||||
watch(() => article.textCustomTranslate, (str: string) => {
|
||||
updateSentenceTranslate()
|
||||
})
|
||||
|
||||
watch(() => article.networkTranslate, (str: string) => {
|
||||
watch(() => article.textNetworkTranslate, (str: string) => {
|
||||
updateSentenceTranslate()
|
||||
})
|
||||
|
||||
watch(() => article.translateType, () => {
|
||||
if (article.article.trim()) {
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
if (article.customTranslate.trim()) {
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
watch(() => article.useTranslateType, () => {
|
||||
if (article.text.trim()) {
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
if (article.textCustomTranslate.trim()) {
|
||||
updateLocalSentenceTranslate(article, article.textCustomTranslate)
|
||||
} else {
|
||||
updateSections()
|
||||
updateSections(article)
|
||||
}
|
||||
} else {
|
||||
if (article.networkTranslate.trim()) {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
}
|
||||
if (article.useTranslateType === TranslateType.custom) {
|
||||
if (article.textNetworkTranslate.trim()) {
|
||||
updateLocalSentenceTranslate(article, article.textNetworkTranslate)
|
||||
} else {
|
||||
updateSections()
|
||||
updateSections(article)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +229,7 @@ watch(() => article.translateType, () => {
|
||||
<div class="item basic">
|
||||
<div class="label">正文:</div>
|
||||
<textarea
|
||||
v-model="article.article"
|
||||
v-model="article.text"
|
||||
@input="updateSentenceTranslate"
|
||||
:readonly="![100,0].includes(progress)"
|
||||
type="textarea"
|
||||
@@ -234,7 +244,7 @@ watch(() => article.translateType, () => {
|
||||
<div class="item">
|
||||
<div class="label">
|
||||
<span>标题:</span>
|
||||
<el-radio-group v-model="article.translateType">
|
||||
<el-radio-group v-model="article.useTranslateType">
|
||||
<el-radio-button :label="TranslateType.custom">本地翻译</el-radio-button>
|
||||
<el-radio-button :label="TranslateType.network">网络翻译</el-radio-button>
|
||||
<el-radio-button :label="TranslateType.none">不需要翻译</el-radio-button>
|
||||
@@ -251,7 +261,7 @@ watch(() => article.translateType, () => {
|
||||
<div class="item basic">
|
||||
<div class="label">
|
||||
<span>正文:</span>
|
||||
<div class="translate-item" v-if="article.translateType === TranslateType.network">
|
||||
<div class="translate-item" v-if="article.useTranslateType === TranslateType.network">
|
||||
<el-progress :percentage="progress"
|
||||
:duration="30"
|
||||
:striped="progress !== 100"
|
||||
@@ -278,8 +288,8 @@ watch(() => article.translateType, () => {
|
||||
</div>
|
||||
</div>
|
||||
<textarea
|
||||
v-if="article.translateType === TranslateType.custom"
|
||||
v-model="article.customTranslate"
|
||||
v-if="article.useTranslateType === TranslateType.custom"
|
||||
v-model="article.textCustomTranslate"
|
||||
:readonly="![100,0].includes(progress)"
|
||||
@blur="onBlur"
|
||||
@focus="onFocus"
|
||||
@@ -289,8 +299,8 @@ watch(() => article.translateType, () => {
|
||||
>
|
||||
</textarea>
|
||||
<textarea
|
||||
v-if="article.translateType === TranslateType.network"
|
||||
v-model="article.networkTranslate"
|
||||
v-if="article.useTranslateType === TranslateType.network"
|
||||
v-model="article.textNetworkTranslate"
|
||||
@blur="onBlur"
|
||||
@focus="onFocus"
|
||||
type="textarea"
|
||||
|
||||
@@ -12,10 +12,11 @@ import Statistics from "@/components/Practice/Statistics.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus";
|
||||
import {useSettingStore} from "@/stores/setting";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {Article, DefaultArticle} from "@/types.ts";
|
||||
import {Article, DefaultArticle, TranslateType} from "@/types.ts";
|
||||
import AddArticle from "@/components/Practice/AddArticle.vue";
|
||||
import {useEventListener, useStartKeyboardEventListener} from "@/hooks/event.ts";
|
||||
import {useStartKeyboardEventListener} from "@/hooks/event.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {updateLocalSentenceTranslate, updateSections} from "@/hooks/translate.ts";
|
||||
|
||||
const practiceStore = usePracticeStore()
|
||||
const store = useBaseStore()
|
||||
@@ -23,7 +24,7 @@ const settingStore = useSettingStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
let showEditArticle = $ref(false)
|
||||
let editArticle = $ref(cloneDeep(DefaultArticle))
|
||||
let editArticle = $ref<Article>(cloneDeep(DefaultArticle))
|
||||
|
||||
watch(practiceStore, () => {
|
||||
if (practiceStore.inputNumber < 1) {
|
||||
@@ -56,13 +57,59 @@ watch(() => store.load, n => {
|
||||
|
||||
function getCurrentPractice() {
|
||||
if (store.isArticle) {
|
||||
let article: Article = cloneDeep(store.currentDict.articles[store.currentDict.chapterIndex])
|
||||
console.log('article', article)
|
||||
if (article?.translateSplit) {
|
||||
articleData.article = article
|
||||
let tempArticle = {...DefaultArticle, ...store.currentDict.articles[store.currentDict.chapterIndex]}
|
||||
console.log('article', tempArticle)
|
||||
if (tempArticle.sections.length) {
|
||||
articleData.article = tempArticle
|
||||
} else {
|
||||
editArticle = {...DefaultArticle, ...article}
|
||||
showEditArticle = true
|
||||
if (tempArticle.useTranslateType === TranslateType.none) {
|
||||
updateSections(tempArticle)
|
||||
articleData.article = tempArticle
|
||||
} else {
|
||||
if (tempArticle.useTranslateType === TranslateType.custom) {
|
||||
if (tempArticle.textCustomTranslate.trim()) {
|
||||
if (tempArticle.textCustomTranslateIsFormat) {
|
||||
updateSections(tempArticle)
|
||||
updateLocalSentenceTranslate(tempArticle, tempArticle.textCustomTranslate)
|
||||
articleData.article = tempArticle
|
||||
} else {
|
||||
//说明有本地翻译,但是没格式化成一行一行的
|
||||
ElMessageBox.confirm('', '检测到存在本地翻译,但未格式化,是否进行编辑?', {
|
||||
confirmButtonText: '去编辑',
|
||||
cancelButtonText: '不需要翻译',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
editArticle = tempArticle
|
||||
showEditArticle = true
|
||||
}).catch(() => {
|
||||
updateSections(tempArticle)
|
||||
tempArticle.useTranslateType = TranslateType.none
|
||||
articleData.article = tempArticle
|
||||
})
|
||||
}
|
||||
} else {
|
||||
//没有本地翻译
|
||||
ElMessageBox.confirm('', '没有本地翻译,是否进行编辑?', {
|
||||
confirmButtonText: '去编辑',
|
||||
cancelButtonText: '不需要翻译',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
editArticle = tempArticle
|
||||
showEditArticle = true
|
||||
}).catch(() => {
|
||||
updateSections(tempArticle)
|
||||
tempArticle.useTranslateType = TranslateType.none
|
||||
articleData.article = tempArticle
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (tempArticle.useTranslateType === TranslateType.network) {
|
||||
updateSections(tempArticle)
|
||||
updateLocalSentenceTranslate(tempArticle, tempArticle.textNetworkTranslate)
|
||||
articleData.article = tempArticle
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wordData.words = cloneDeep(store.chapter)
|
||||
@@ -96,8 +143,10 @@ function next() {
|
||||
repeat()
|
||||
}
|
||||
|
||||
function saveArticle(article) {
|
||||
function saveArticle(article: Article) {
|
||||
console.log('a', article)
|
||||
showEditArticle = false
|
||||
articleData.article = article
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -29,7 +29,7 @@ export const EnKeyboardMap: KeyboardMap = {
|
||||
|
||||
export function splitEnArticle(text: string, lang: string = 'en', keyboardMap: KeyboardMap = EnKeyboardMap): {
|
||||
sections: Sentence[][],
|
||||
text: string
|
||||
newText: string
|
||||
} {
|
||||
let sections: Sentence[][] = []
|
||||
let section: Sentence[] = []
|
||||
@@ -41,6 +41,9 @@ export function splitEnArticle(text: string, lang: string = 'en', keyboardMap: K
|
||||
section.push(sentence)
|
||||
sections.push(section)
|
||||
let word = cloneDeep({...DefaultArticleWord, name: '', nextSpace: true});
|
||||
|
||||
//去除头和尾部的空格
|
||||
text = text.trim()
|
||||
//加\n用于添加最后一段
|
||||
text += '\n'
|
||||
text = text.replaceAll(`‘`, '"')
|
||||
@@ -169,7 +172,7 @@ export function splitEnArticle(text: string, lang: string = 'en', keyboardMap: K
|
||||
})
|
||||
})
|
||||
return {
|
||||
text,
|
||||
newText: text,
|
||||
sections
|
||||
}
|
||||
}
|
||||
@@ -185,6 +188,8 @@ export function splitCNArticle(article: string, lang: string = 'cn', keyboardMap
|
||||
section.push(sentence)
|
||||
sections.push(section)
|
||||
let word = cloneDeep({...DefaultArticleWord, name: '', nextSpace: true});
|
||||
//去除头和尾部的空格
|
||||
article = article.trim()
|
||||
//加\n用于添加最后一段
|
||||
article += '\n'
|
||||
// console.log('articles', articles)
|
||||
|
||||
@@ -5,48 +5,48 @@ import {getSplitTranslateText, splitEnArticle} from "@/hooks/article.ts";
|
||||
import {Translator} from "@opentranslate/translator/src/translator.ts";
|
||||
|
||||
export function updateLocalSentenceTranslate(article: Article, translate: string) {
|
||||
if (translate.trim()) {
|
||||
let articleTranslate = translate.split('\n')
|
||||
// console.log('articleTranslate', articleTranslate)
|
||||
let count = 0
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
try {
|
||||
sentence.translate = articleTranslate[count]
|
||||
} catch (e) {
|
||||
console.log('没有对应的翻译', sentence.text)
|
||||
}
|
||||
count++
|
||||
}
|
||||
count++
|
||||
if (translate.trim()) {
|
||||
let articleTranslate = translate.split('\n')
|
||||
// console.log('articleTranslate', articleTranslate)
|
||||
let count = 0
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
try {
|
||||
sentence.translate = articleTranslate[count]
|
||||
} catch (e) {
|
||||
console.log('没有对应的翻译', sentence.text)
|
||||
}
|
||||
count++
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getSentenceAllTranslateText(article: Article) {
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
if (w.translate) {
|
||||
str += w.translate + '\n'
|
||||
}
|
||||
})
|
||||
str += '\n'
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
if (w.translate) {
|
||||
str += w.translate + '\n'
|
||||
}
|
||||
})
|
||||
return str
|
||||
str += '\n'
|
||||
})
|
||||
return str
|
||||
}
|
||||
|
||||
export function getSentenceAllText(article: Article) {
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
str += w.text
|
||||
})
|
||||
str += '\n'
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
str += w.text
|
||||
})
|
||||
return str
|
||||
str += '\n'
|
||||
})
|
||||
return str
|
||||
}
|
||||
|
||||
/***
|
||||
@@ -57,162 +57,168 @@ export function getSentenceAllText(article: Article) {
|
||||
* @param progressCb 进度回调
|
||||
* */
|
||||
export async function getNetworkTranslate(
|
||||
article: Article,
|
||||
translateEngine: TranslateEngine,
|
||||
allShow: boolean = false,
|
||||
progressCb?: (val: number) => void
|
||||
article: Article,
|
||||
translateEngine: TranslateEngine,
|
||||
allShow: boolean = false,
|
||||
progressCb?: (val: number) => void
|
||||
) {
|
||||
if (article.networkTranslate) {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
} else {
|
||||
let translator: Translator
|
||||
if (translateEngine === TranslateEngine.Baidu) {
|
||||
translator = new Baidu({
|
||||
axios: axiosInstance as any,
|
||||
config: {
|
||||
appid: "20230910001811857",
|
||||
key: "Xxe_yftQR3K3Ue43NQMC"
|
||||
}
|
||||
}) as any
|
||||
}
|
||||
|
||||
|
||||
if (translator) {
|
||||
if (!article.titleTranslate) {
|
||||
translator.translate(article.title, 'en', 'zh-CN').then(r => {
|
||||
article.titleTranslate = r.trans.paragraphs[0]
|
||||
})
|
||||
}
|
||||
|
||||
let promiseList = []
|
||||
let retryCount = 0
|
||||
let retryCountMap = new Map()
|
||||
|
||||
const translate = async (sentence: Sentence) => {
|
||||
try {
|
||||
let r = await translator.translate(sentence.text, 'en', 'zh-CN')
|
||||
if (r) {
|
||||
const cb = () => {
|
||||
sentence.translate = r.trans.paragraphs[0]
|
||||
if (!allShow) {
|
||||
//一次显示所有,顺序会乱
|
||||
article.networkTranslate += sentence.translate + '\n'
|
||||
}
|
||||
}
|
||||
return Promise.resolve(cb)
|
||||
} else {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
} catch (e) {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
}
|
||||
|
||||
let total = 0
|
||||
let index = 0
|
||||
article.sections.map(v => total += v.length)
|
||||
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
let promise = translate(sentence)
|
||||
if (allShow) {
|
||||
promiseList.push(promise)
|
||||
} else {
|
||||
retryCountMap.set(sentence.text, 0)
|
||||
let errResult: any
|
||||
let cb = await promise.catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
|
||||
while (errResult) {
|
||||
let count = retryCountMap.get(sentence.text)
|
||||
if (count > 2) break
|
||||
cb = await errResult().catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
retryCountMap.set(sentence.text, count + 1)
|
||||
}
|
||||
if (cb) cb()
|
||||
index++
|
||||
if (progressCb) {
|
||||
progressCb(Math.floor((index / total) * 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (promiseList.length) {
|
||||
let timer = -1
|
||||
let progress = 0
|
||||
if (progressCb) {
|
||||
timer = setInterval(() => {
|
||||
progress++
|
||||
if (progress > 90) {
|
||||
return clearInterval(timer)
|
||||
}
|
||||
progressCb(progress)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
return new Promise(async resolve => {
|
||||
let cbs = []
|
||||
do {
|
||||
if (retryCount > 2) {
|
||||
return resolve(true)
|
||||
}
|
||||
let results = await Promise.allSettled(promiseList)
|
||||
promiseList = []
|
||||
results.map(results => {
|
||||
if (results.status === 'fulfilled') {
|
||||
cbs.push(results.value)
|
||||
} else {
|
||||
promiseList.push(results.reason())
|
||||
}
|
||||
})
|
||||
retryCount++
|
||||
} while (promiseList.length)
|
||||
cbs.map(v => v())
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
|
||||
if (progressCb) {
|
||||
clearInterval(timer)
|
||||
progress = 100
|
||||
progressCb(100)
|
||||
}
|
||||
resolve(true)
|
||||
})
|
||||
} else {
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
}
|
||||
if (article.textNetworkTranslate) {
|
||||
updateLocalSentenceTranslate(article, article.textNetworkTranslate)
|
||||
} else {
|
||||
let translator: Translator
|
||||
if (translateEngine === TranslateEngine.Baidu) {
|
||||
translator = new Baidu({
|
||||
axios: axiosInstance as any,
|
||||
config: {
|
||||
appid: "20230910001811857",
|
||||
key: "Xxe_yftQR3K3Ue43NQMC"
|
||||
}
|
||||
}) as any
|
||||
}
|
||||
|
||||
|
||||
if (translator) {
|
||||
if (!article.titleTranslate) {
|
||||
translator.translate(article.title, 'en', 'zh-CN').then(r => {
|
||||
article.titleTranslate = r.trans.paragraphs[0]
|
||||
})
|
||||
}
|
||||
|
||||
let promiseList = []
|
||||
let retryCount = 0
|
||||
let retryCountMap = new Map()
|
||||
|
||||
const translate = async (sentence: Sentence) => {
|
||||
try {
|
||||
let r = await translator.translate(sentence.text, 'en', 'zh-CN')
|
||||
if (r) {
|
||||
const cb = () => {
|
||||
sentence.translate = r.trans.paragraphs[0]
|
||||
if (!allShow) {
|
||||
//一次显示所有,顺序会乱
|
||||
article.textNetworkTranslate += sentence.translate + '\n'
|
||||
}
|
||||
}
|
||||
return Promise.resolve(cb)
|
||||
} else {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
} catch (e) {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
}
|
||||
|
||||
let total = 0
|
||||
let index = 0
|
||||
article.sections.map(v => total += v.length)
|
||||
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
let promise = translate(sentence)
|
||||
if (allShow) {
|
||||
promiseList.push(promise)
|
||||
} else {
|
||||
retryCountMap.set(sentence.text, 0)
|
||||
let errResult: any
|
||||
let cb = await promise.catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
|
||||
while (errResult) {
|
||||
let count = retryCountMap.get(sentence.text)
|
||||
if (count > 2) break
|
||||
cb = await errResult().catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
retryCountMap.set(sentence.text, count + 1)
|
||||
}
|
||||
if (cb) cb()
|
||||
index++
|
||||
if (progressCb) {
|
||||
progressCb(Math.floor((index / total) * 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (promiseList.length) {
|
||||
let timer = -1
|
||||
let progress = 0
|
||||
if (progressCb) {
|
||||
timer = setInterval(() => {
|
||||
progress++
|
||||
if (progress > 90) {
|
||||
return clearInterval(timer)
|
||||
}
|
||||
progressCb(progress)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
return new Promise(async resolve => {
|
||||
let cbs = []
|
||||
do {
|
||||
if (retryCount > 2) {
|
||||
return resolve(true)
|
||||
}
|
||||
let results = await Promise.allSettled(promiseList)
|
||||
promiseList = []
|
||||
results.map(results => {
|
||||
if (results.status === 'fulfilled') {
|
||||
cbs.push(results.value)
|
||||
} else {
|
||||
promiseList.push(results.reason())
|
||||
}
|
||||
})
|
||||
retryCount++
|
||||
} while (promiseList.length)
|
||||
cbs.map(v => v())
|
||||
article.textNetworkTranslate = getSentenceAllTranslateText(article)
|
||||
|
||||
if (progressCb) {
|
||||
clearInterval(timer)
|
||||
progress = 100
|
||||
progressCb(100)
|
||||
}
|
||||
resolve(true)
|
||||
})
|
||||
} else {
|
||||
article.textNetworkTranslate = getSentenceAllTranslateText(article)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function updateSections(article: Article) {
|
||||
let {newText, sections} = splitEnArticle(article.text)
|
||||
article.text = newText
|
||||
article.sections = sections
|
||||
}
|
||||
|
||||
export function test(article: Article) {
|
||||
if (article?.translateSplit) {
|
||||
if (!article.sections?.length) {
|
||||
if (article?.textCustomTranslateIsFormat) {
|
||||
if (!article.sections?.length) {
|
||||
|
||||
}
|
||||
} else {
|
||||
if (article.translateType !== undefined) {
|
||||
if (article.translateType) {
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
} else {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
}
|
||||
} else {
|
||||
// article.sections = splitEnArticle(article.article)
|
||||
if (article.customTranslate) {
|
||||
article.customTranslate = getSplitTranslateText(article.customTranslate)
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
article.translateType = TranslateType.custom
|
||||
} else {
|
||||
article.networkTranslate = getSplitTranslateText(article.networkTranslate)
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
article.translateType = TranslateType.network
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (article.useTranslateType !== undefined) {
|
||||
if (article.useTranslateType) {
|
||||
updateLocalSentenceTranslate(article, article.textCustomTranslate)
|
||||
} else {
|
||||
updateLocalSentenceTranslate(article, article.textNetworkTranslate)
|
||||
}
|
||||
} else {
|
||||
// article.sections = splitEnArticle(article.article)
|
||||
if (article.textCustomTranslate) {
|
||||
article.textCustomTranslate = getSplitTranslateText(article.textCustomTranslate)
|
||||
updateLocalSentenceTranslate(article, article.textCustomTranslate)
|
||||
article.useTranslateType = TranslateType.custom
|
||||
} else {
|
||||
article.textNetworkTranslate = getSplitTranslateText(article.textNetworkTranslate)
|
||||
updateLocalSentenceTranslate(article, article.textCustomTranslate)
|
||||
article.useTranslateType = TranslateType.network
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/types.ts
30
src/types.ts
@@ -115,35 +115,35 @@ export interface Sentence {
|
||||
}
|
||||
|
||||
export enum TranslateType {
|
||||
custom = 0,
|
||||
network = 1,
|
||||
none = 2
|
||||
custom = 'custom',
|
||||
network = 'network',
|
||||
none = 'none'
|
||||
}
|
||||
|
||||
export interface Article {
|
||||
title: string,
|
||||
titleTranslate: string,
|
||||
article: string,
|
||||
customTranslate: string,
|
||||
networkTranslate: string,
|
||||
translateSplit: boolean,//翻译是否分割
|
||||
text: string,
|
||||
textCustomTranslate: string,
|
||||
textCustomTranslateIsFormat: boolean,//翻译是否格式化
|
||||
textNetworkTranslate: string,
|
||||
newWords: Word[],
|
||||
articleAllWords: string[],
|
||||
textAllWords: string[],
|
||||
sections: Sentence[][],
|
||||
translateType: TranslateType
|
||||
useTranslateType: TranslateType
|
||||
}
|
||||
|
||||
export const DefaultArticle: Article = {
|
||||
title: '',
|
||||
titleTranslate: '',
|
||||
article: '',
|
||||
customTranslate: '',
|
||||
networkTranslate: '',
|
||||
translateSplit: false,
|
||||
text: '',
|
||||
textCustomTranslate: '',
|
||||
textNetworkTranslate: '',
|
||||
textCustomTranslateIsFormat: false,
|
||||
newWords: [],
|
||||
articleAllWords: [],
|
||||
textAllWords: [],
|
||||
sections: [],
|
||||
translateType: TranslateType.network
|
||||
useTranslateType: TranslateType.network
|
||||
}
|
||||
|
||||
export interface Dict {
|
||||
|
||||
Reference in New Issue
Block a user