Develop dictionary management function
This commit is contained in:
@@ -32,7 +32,6 @@
|
||||
"pinia": "^2.1.6",
|
||||
"sentence-splitter": "^4.2.1",
|
||||
"tesseract.js": "^4.1.1",
|
||||
"uuid": "^9.0.1",
|
||||
"vue": "^3.3.4",
|
||||
"vue-activity-calendar": "^1.2.2",
|
||||
"vue-i18n": "9",
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -53,9 +53,6 @@ dependencies:
|
||||
tesseract.js:
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.2
|
||||
uuid:
|
||||
specifier: ^9.0.1
|
||||
version: 9.0.1
|
||||
vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.3.4
|
||||
@@ -4957,11 +4954,6 @@ packages:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: true
|
||||
|
||||
/uuid@9.0.1:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
requiresBuild: true
|
||||
|
||||
@@ -43,7 +43,7 @@ function toggle() {
|
||||
autosize
|
||||
autofocus
|
||||
type="textarea"
|
||||
:input-style="`color:black;font-size: 16rem;`"
|
||||
:input-style="`color: var(--color-font-1);font-size: 16rem;`"
|
||||
/>
|
||||
<div class="options">
|
||||
<BaseButton @click="toggle">取消</BaseButton>
|
||||
@@ -62,7 +62,7 @@ function toggle() {
|
||||
<style scoped lang="scss">
|
||||
.edit-text {
|
||||
margin-top: 10rem;
|
||||
color: black;
|
||||
color: var(--color-font-1);
|
||||
|
||||
.options {
|
||||
margin-top: 10rem;
|
||||
|
||||
@@ -10,17 +10,22 @@ import List from "@/components/list/List.vue";
|
||||
import Dialog from "@/components/dialog/Dialog.vue";
|
||||
import EditArticle from "@/components/article/EditArticle.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useDisableEventListener} from "@/hooks/event.ts";
|
||||
import {useDisableEventListener, useWindowClick} from "@/hooks/event.ts";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {nanoid} from "nanoid";
|
||||
import {syncMyDictList} from "@/hooks/dict.ts";
|
||||
import MiniDialog from "@/components/dialog/MiniDialog.vue";
|
||||
|
||||
const emit = defineEmits<{
|
||||
importData: [val: Event]
|
||||
exportData: [val: string]
|
||||
}>()
|
||||
const base = useBaseStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
let article = $ref<Article>(cloneDeep(DefaultArticle))
|
||||
let show = $ref(false)
|
||||
let showImportBtn = $ref(true)
|
||||
let editArticleRef: any = $ref()
|
||||
let listEl: any = $ref()
|
||||
|
||||
@@ -100,102 +105,6 @@ async function add() {
|
||||
}
|
||||
}
|
||||
|
||||
function importData(e: Event) {
|
||||
showImportBtn = false
|
||||
let file = e.target.files[0]
|
||||
let reader = new FileReader();//新建一个FileReader
|
||||
reader.readAsText(file, "UTF-8");//读取文件
|
||||
reader.onload = function (evt) { //读取完文件之后会回来这里
|
||||
let fileString = evt.target.result; // 读取文件内容
|
||||
// console.log('fileString', fileString)
|
||||
try {
|
||||
let obj: any = JSON.parse(fileString)
|
||||
console.log('obj', obj)
|
||||
if (!obj?.name) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error('请填写词典名称!')
|
||||
} else {
|
||||
if (base.myDictList.find(v => v.name === obj.name)) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error('词典名称已存在!')
|
||||
}
|
||||
}
|
||||
if (!obj?.articles) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error('请填写文章!')
|
||||
}
|
||||
if (!obj?.articles instanceof Array) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error('请填写文章!')
|
||||
}
|
||||
for (let i = 0; i < obj.articles.length; i++) {
|
||||
let item = obj.articles[i]
|
||||
if (!item?.title) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error(`请填写第${i + 1}篇文章名称!`)
|
||||
}
|
||||
if (!item?.text) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error(`请填写第${i + 1}篇文章正文!`)
|
||||
}
|
||||
if (item?.useTranslateType === 'custom') {
|
||||
if (!item?.textCustomTranslate) {
|
||||
showImportBtn = true
|
||||
return ElMessage.error(`请填写第${i + 1}篇文章 翻译 正文!`)
|
||||
}
|
||||
}
|
||||
|
||||
if (!obj.articles[i]?.titleTranslate) obj.articles[i].titleTranslate = ''
|
||||
if (!obj.articles[i]?.textFormat) obj.articles[i].textFormat = ''
|
||||
if (!obj.articles[i]?.textCustomTranslate) obj.articles[i].textCustomTranslate = ''
|
||||
if (!obj.articles[i]?.newWords) obj.articles[i].newWords = []
|
||||
if (!obj.articles[i]?.textCustomTranslateIsFormat) obj.articles[i].textCustomTranslateIsFormat = false
|
||||
if (!obj.articles[i]?.useTranslateType) obj.articles[i].useTranslateType = 'none'
|
||||
if (!obj.articles[i]?.textAllWords) obj.articles[i].textAllWords = []
|
||||
if (!obj.articles[i]?.sections) obj.articles[i].sections = []
|
||||
obj.articles[i].id = nanoid(6)
|
||||
}
|
||||
obj.sort = Sort.normal
|
||||
obj.type = DictType.customArticle
|
||||
obj.originWords = []
|
||||
obj.words = []
|
||||
obj.chapterWords = []
|
||||
obj.chapterWordNumber = 0
|
||||
obj.chapterIndex = 0
|
||||
obj.chapterWordIndex = 0
|
||||
obj.url = ''
|
||||
if (!obj.statistics) obj.statistics = []
|
||||
|
||||
ElMessage.success({
|
||||
message: '导入成功,已切换到',
|
||||
duration: 5000
|
||||
})
|
||||
base.myDictList.push(obj)
|
||||
runtimeStore.editDict = cloneDeep(runtimeStore.editDict)
|
||||
showImportBtn = true
|
||||
} catch (e) {
|
||||
showImportBtn = true
|
||||
ElMessage.error('文件解析失败,报错原因:' + e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function exportData() {
|
||||
let data = {
|
||||
name: runtimeStore.editDict.name,
|
||||
articles: cloneDeep(runtimeStore.editDict.articles).map(v => {
|
||||
delete v.sections
|
||||
delete v.id
|
||||
return v
|
||||
}),
|
||||
url: location.origin + runtimeStore.editDict.url,
|
||||
statistics: runtimeStore.editDict.statistics,
|
||||
}
|
||||
|
||||
let blob = new Blob([JSON.stringify(data, null, 2)], {type: "text/plain;charset=utf-8"});
|
||||
saveAs(blob, `${data.name}.json`);
|
||||
}
|
||||
|
||||
function saveArticle(val: Article): boolean {
|
||||
console.log('saveArticle', val)
|
||||
if (val.id) {
|
||||
@@ -211,13 +120,14 @@ function saveArticle(val: Article): boolean {
|
||||
}
|
||||
val.id = nanoid(6)
|
||||
runtimeStore.editDict.articles.push(val)
|
||||
setTimeout(()=>{
|
||||
setTimeout(() => {
|
||||
listEl.scrollBottom()
|
||||
})
|
||||
}
|
||||
article = cloneDeep(val)
|
||||
//TODO 保存完成后滚动到对应位置
|
||||
ElMessage.success('保存成功!')
|
||||
syncMyDictList(runtimeStore.editDict)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -227,6 +137,9 @@ function saveAndNext(val: Article) {
|
||||
}
|
||||
}
|
||||
|
||||
let showExport = $ref(false)
|
||||
useWindowClick(() => showExport = false)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -256,12 +169,32 @@ function saveAndNext(val: Article) {
|
||||
正在添加新文章...
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="import" v-if="showImportBtn">
|
||||
<BaseButton>导入</BaseButton>
|
||||
<input type="file" accept="application/json" @change="importData">
|
||||
<div class="import">
|
||||
<BaseButton size="small">导入</BaseButton>
|
||||
<input type="file"
|
||||
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
@change="e => emit('importData',e)">
|
||||
</div>
|
||||
<BaseButton @click="exportData">导出</BaseButton>
|
||||
<BaseButton @click="add">新增</BaseButton>
|
||||
<div class="export"
|
||||
style="position: relative"
|
||||
@click.stop="null">
|
||||
<BaseButton size="small" @click="showExport = true">导出</BaseButton>
|
||||
<MiniDialog
|
||||
v-model="showExport"
|
||||
style="width: 80rem;bottom: calc(100% + 10rem);top:unset;"
|
||||
>
|
||||
<div class="mini-row-title">
|
||||
导出选项
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<BaseButton size="small" @click="emit('exportData',{type:'all',data:[]})">全部文章</BaseButton>
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<BaseButton size="small" @click="emit('exportData',{type:'chapter',data:article})">当前章节</BaseButton>
|
||||
</div>
|
||||
</MiniDialog>
|
||||
</div>
|
||||
<BaseButton size="small" @click="add">新增</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
<EditArticle
|
||||
|
||||
@@ -148,7 +148,6 @@ async function cancel() {
|
||||
:class="[
|
||||
fullScreen?'full':'window'
|
||||
]"
|
||||
@click.stop="null"
|
||||
>
|
||||
<Tooltip title="关闭">
|
||||
<Icon @click="close"
|
||||
|
||||
@@ -20,6 +20,7 @@ import MiniDialog from "@/components/dialog/MiniDialog.vue";
|
||||
import * as XLSX from "xlsx";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {syncMyDictList} from "@/hooks/dict.ts";
|
||||
import {useWindowClick} from "@/hooks/event.ts";
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -30,6 +31,7 @@ let isEditDict = $ref(false)
|
||||
let showExport = $ref(false)
|
||||
let loading = $ref(false)
|
||||
let listRef = $ref()
|
||||
useWindowClick(() => showExport = false)
|
||||
|
||||
const isPinDict = $computed(() => {
|
||||
return [DictType.collect, DictType.wrong, DictType.simple].includes(runtimeStore.editDict.type)
|
||||
@@ -186,15 +188,16 @@ function importData(e: any) {
|
||||
reader.readAsBinaryString(file);
|
||||
}
|
||||
|
||||
function exportData(type: string) {
|
||||
function exportData(val: { type: string, data?: Article }) {
|
||||
const {type, data} = val
|
||||
let list = []
|
||||
let filename = ''
|
||||
if (type === 'chapter') {
|
||||
if (chapterIndex === -1) {
|
||||
if (!data.id) {
|
||||
return ElMessage.error('请选择文章')
|
||||
}
|
||||
list = [article]
|
||||
filename = runtimeStore.editDict.name + `-第${chapterIndex + 1}章`
|
||||
list = [data]
|
||||
filename = runtimeStore.editDict.name + `-${data.title}`
|
||||
} else {
|
||||
list = runtimeStore.editDict.articles
|
||||
filename = runtimeStore.editDict.name
|
||||
@@ -256,10 +259,10 @@ defineExpose({getDictDetail})
|
||||
导出选项
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<BaseButton size="small" @click="exportData('all')">全部文章</BaseButton>
|
||||
<BaseButton size="small" @click="exportData({type:'all',data:[]})">全部文章</BaseButton>
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<BaseButton size="small" @click="exportData('chapter')">当前章节</BaseButton>
|
||||
<BaseButton size="small" @click="exportData({type:'chapter',data:article})">当前章节</BaseButton>
|
||||
</div>
|
||||
</MiniDialog>
|
||||
</div>
|
||||
@@ -334,7 +337,9 @@ defineExpose({getDictDetail})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<EditBatchArticleModal/>
|
||||
<EditBatchArticleModal
|
||||
@export-data="exportData"
|
||||
@import-data="importData"/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user