feat:save

This commit is contained in:
zyronon
2025-07-22 00:14:51 +08:00
parent 60c0273e15
commit ba1dbdfbb1
10 changed files with 81 additions and 132 deletions

View File

@@ -71,11 +71,11 @@ let selectAll = $computed(() => {
})
function toggleSelect(item) {
let rIndex = selectIds.findIndex(v => v === item.word)
let rIndex = selectIds.findIndex(v => v === item.id)
if (rIndex > -1) {
selectIds.splice(rIndex, 1)
} else {
selectIds.push(item.word)
selectIds.push(item.id)
}
}
@@ -83,7 +83,7 @@ function toggleSelectAll() {
if (selectAll) {
selectIds = []
} else {
selectIds = currentList.map(v => v.word)
selectIds = currentList.map(v => v.id)
}
}
@@ -118,7 +118,7 @@ const s = useSlots()
defineRender(
() => {
const d = (item) => <el-checkbox
modelValue={selectIds.includes(item.word)}
modelValue={selectIds.includes(item.id)}
onChange={() => toggleSelect(item)}
size="large"/>

View File

@@ -7,6 +7,11 @@ defineProps<{
quantifier?: string
isAdd: boolean
showCheckbox?: boolean
checked?: boolean
}>()
defineEmits<{
check: []
}>()
</script>
@@ -19,7 +24,10 @@ defineProps<{
<div class="text-sm line-clamp-3" v-opacity="item.name !== item.description">{{ item?.description }}</div>
</div>
<div class="absolute bottom-4 right-4">{{ item?.length }}{{ quantifier }}</div>
<el-checkbox v-if="showCheckbox" class="absolute left-3 bottom-2"/>
<el-checkbox v-if="showCheckbox"
:model-value="checked"
@click.stop="$emit('check')"
class="absolute left-3 bottom-2"/>
</template>
<div v-else class="center h-full">
<Icon

View File

@@ -1,5 +1,5 @@
<script setup lang="tsx">
import {getDefaultWord} from "@/types";
import {getDefaultDict, getDefaultWord} from "@/types";
import type {Word} from "@/types";
import BasePage from "@/pages/pc/components/BasePage.vue";
@@ -17,7 +17,7 @@ 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 {_nextTick} from "@/utils";
import {_getDictDataByUrl, _nextTick} from "@/utils";
const runtimeStore = useRuntimeStore()
const base = useBaseStore()
@@ -270,9 +270,18 @@ const showBookDetail = computed(() => {
onMounted(() => {
if (route.query?.isAdd) {
isAdd = true
runtimeStore.editDict = getDefaultDict()
} else {
if (!runtimeStore.editDict.id) {
router.push("/word")
} else {
if (!runtimeStore.editDict.words.length && !runtimeStore.editDict.custom) {
loading = true
_getDictDataByUrl(runtimeStore.editDict).then(r => {
loading = false
runtimeStore.editDict = r
})
}
}
}
})
@@ -282,7 +291,12 @@ function formClose() {
else router.back()
}
function addMyStudyList() {
async function addMyStudyList() {
base.word.bookList.slice(3).map(v => {
if (!v.custom) {
v.words = []
}
})
let rIndex = base.word.bookList.findIndex(v => v.name === runtimeStore.editDict.name)
if (rIndex > -1) {
base.word.studyIndex = rIndex

View File

@@ -8,7 +8,7 @@ import BaseIcon from "@/components/BaseIcon.vue";
import Dialog from "@/pages/pc/components/dialog/Dialog.vue";
import {_getAccomplishDate, _getAccomplishDays, _getDictDataByUrl, useNav} from "@/utils";
import BasePage from "@/pages/pc/components/BasePage.vue";
import {Dict, DictResource} from "@/types.ts";
import {Dict, DictResource, getDefaultDict} from "@/types.ts";
import {onMounted} from "vue";
import {getCurrentStudyWord} from "@/hooks/dict.ts";
import {EventKey, useEvent} from "@/utils/eventBus.ts";
@@ -16,6 +16,7 @@ import DictListPanel from "@/pages/pc/components/DictListPanel.vue";
import {cloneDeep} from "lodash-es";
import {useRuntimeStore} from "@/stores/runtime.ts";
import Book from "@/pages/pc/components/Book.vue";
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
const store = useBaseStore()
const router = useRouter()
@@ -74,19 +75,39 @@ function selectDict(e) {
getDictDetail(e.dict)
}
async function goDictDetail2(val: Dict) {
runtimeStore.editDict = cloneDeep(val)
nav('dict-detail', {})
}
async function getDictDetail(val: DictResource) {
let r = await _getDictDataByUrl(val)
runtimeStore.editDict = cloneDeep(r)
runtimeStore.editDict = getDefaultDict(val)
nav('dict-detail', {})
}
let dictListRef = $ref<any>()
let isMultiple = $ref(false)
let selectIds = $ref([])
function handleBatchDel() {
selectIds.forEach(id => {
let r = store.word.bookList.findIndex(v => v.id === id)
if (r !== -1) {
if (store.word.studyIndex === r) {
store.word.studyIndex = -1
}
if (store.word.studyIndex > r) {
store.word.studyIndex--
}
store.word.bookList.splice(r, 1)
}
})
ElMessage.success("删除成功!")
}
function toggleSelect(item) {
let rIndex = selectIds.findIndex(v => v === item.id)
if (rIndex > -1) {
selectIds.splice(rIndex, 1)
} else {
selectIds.push(item.id)
}
}
</script>
@@ -162,8 +183,22 @@ let dictListRef = $ref<any>()
<div class="card flex flex-col">
<div class="flex justify-between">
<div class="title">我的词典</div>
<div class="flex gap-4">
<div class="color-blue cursor-pointer" v-if="store.word.bookList.length > 3">管理词典</div>
<div class="flex gap-4 items-center">
<PopConfirm title="确认删除所有选中词典?"
@confirm="handleBatchDel"
v-if="selectIds.length"
>
<BaseIcon
class="del"
title="删除"
icon="solar:trash-bin-minimalistic-linear"/>
</PopConfirm>
<div class="color-blue cursor-pointer" v-if="store.word.bookList.length > 3"
@click="isMultiple = !isMultiple;selectIds = []"
>{{ isMultiple ? '取消' : '管理词典' }}
</div>
<div class="color-blue cursor-pointer" @click="nav('dict-detail', {isAdd: true})">创建个人词典</div>
</div>
</div>
@@ -171,8 +206,11 @@ let dictListRef = $ref<any>()
<Book :is-add="false"
quantifier="个词"
:item="item"
v-for="item in store.word.bookList"
@click="goDictDetail2(item)"/>
:checked="selectIds.includes(item.id)"
@check="() => toggleSelect(item)"
:show-checkbox="isMultiple && j>=3"
v-for="(item,j) in store.word.bookList"
@click="getDictDetail(item)"/>
<Book :is-add="true"
@click="dictListRef.startSearch()"/>
</div>

View File

@@ -288,7 +288,7 @@ export function _parseLRC(lrc: string): { start: number, end: number, text: stri
return parsed;
}
export async function _getDictDataByUrl(val: DictResource) {
export async function _getDictDataByUrl(val: DictResource): Promise<Dict> {
let dictResourceUrl = `./dicts/${val.language}/word/${val.url}`.replace('.json', '_v2.json');
let s = await getDictFile(dictResourceUrl)
let words = cloneDeep(s.map(v => {