wip
This commit is contained in:
@@ -16,7 +16,6 @@ import Dialog from "@/components/dialog/Dialog.vue";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
import { Host } from "@/config/env.ts";
|
||||
|
||||
let list = defineModel('list')
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
loading?: boolean
|
||||
@@ -42,6 +41,7 @@ const props = withDefaults(defineProps<{
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
add: []
|
||||
click: [val: {
|
||||
item: any,
|
||||
index: number
|
||||
@@ -73,13 +73,6 @@ function scrollToItem(index: number) {
|
||||
|
||||
let pageNo = $ref(1)
|
||||
let pageSize = $ref(50)
|
||||
let currentList = $computed(() => {
|
||||
if (searchKey) {
|
||||
return list.value.filter(v => v.word.includes(searchKey))
|
||||
}
|
||||
if (!props.showPagination) return list.value
|
||||
return list.value.slice((pageNo - 1) * pageSize, (pageNo - 1) * pageSize + pageSize)
|
||||
})
|
||||
|
||||
let selectIds = $ref([])
|
||||
let selectAll = $computed(() => {
|
||||
@@ -100,11 +93,10 @@ function toggleSelectAll() {
|
||||
if (selectAll) {
|
||||
selectIds = []
|
||||
} else {
|
||||
selectIds = currentList.map(v => v.id)
|
||||
selectIds = list2.map(v => v.id)
|
||||
}
|
||||
}
|
||||
|
||||
let searchKey = $ref('')
|
||||
let showSortDialog = $ref(false)
|
||||
let showSearchInput = $ref(false)
|
||||
let showImportDialog = $ref(false)
|
||||
@@ -112,17 +104,10 @@ let showImportDialog = $ref(false)
|
||||
const closeImportDialog = () => showImportDialog = false
|
||||
|
||||
function sort(type: Sort) {
|
||||
if (type === Sort.reverse) {
|
||||
emit('sort', type,pageNo,pageSize)
|
||||
}
|
||||
if (type === Sort.random) {
|
||||
emit('sort', type,pageNo,pageSize)
|
||||
}
|
||||
if (type === Sort.reverseAll) {
|
||||
emit('sort', type,1,total2)
|
||||
}
|
||||
if (type === Sort.randomAll) {
|
||||
emit('sort', type,1,total2)
|
||||
if ([Sort.reverse, Sort.random].includes(type)) {
|
||||
emit('sort', type,params.pageNo,params.pageSize)
|
||||
}else{
|
||||
emit('sort', type,1,params.total)
|
||||
}
|
||||
showSortDialog = false
|
||||
}
|
||||
@@ -133,7 +118,7 @@ function handleBatchDel() {
|
||||
}
|
||||
|
||||
function handlePageNo(e) {
|
||||
pageNo = e
|
||||
params.pageNo = e
|
||||
getData()
|
||||
scrollToTop()
|
||||
}
|
||||
@@ -150,14 +135,37 @@ defineExpose({
|
||||
|
||||
let list2 = $ref([])
|
||||
let loading2 = $ref(false)
|
||||
let total2 = $ref(0)
|
||||
|
||||
let params = $ref({
|
||||
pageNo: 1,
|
||||
pageSize: 50,
|
||||
total: 0,
|
||||
sortType: null,
|
||||
searchKey: ''
|
||||
})
|
||||
|
||||
function search(key: string) {
|
||||
console.log('key',key)
|
||||
if(!params.searchKey) {
|
||||
params.pageNo = 1
|
||||
}
|
||||
params.searchKey = key
|
||||
getData()
|
||||
}
|
||||
|
||||
function cancelSearch() {
|
||||
params.searchKey = ''
|
||||
showSearchInput = false
|
||||
getData()
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
loading2 = true
|
||||
let {list, total} = await props.request({ pageNo, pageSize })
|
||||
console.log('list2',list2)
|
||||
console.log('params',params);
|
||||
let {list, total} = await props.request(params)
|
||||
console.log('list',list)
|
||||
list2 = list
|
||||
total2 = total
|
||||
params.total = total
|
||||
loading2 = false
|
||||
}
|
||||
|
||||
@@ -182,8 +190,8 @@ defineRender(
|
||||
<div class="flex gap-4">
|
||||
<BaseInput
|
||||
clearable
|
||||
modelValue={searchKey}
|
||||
onUpdate:modelValue={debounce(e => searchKey = e)}
|
||||
modelValue={params.searchKey}
|
||||
onUpdate:modelValue={debounce(e => search(e), 500)}
|
||||
class="flex-1"
|
||||
autofocus>
|
||||
{{
|
||||
@@ -192,17 +200,17 @@ defineRender(
|
||||
/>
|
||||
}}
|
||||
</BaseInput>
|
||||
<BaseButton onClick={() => (showSearchInput = false, searchKey = '')}>取消</BaseButton>
|
||||
<BaseButton onClick={cancelSearch}>取消</BaseButton>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-between">
|
||||
<div class="flex gap-2 items-center">
|
||||
<Checkbox
|
||||
disabled={!currentList.length}
|
||||
disabled={!list2.length}
|
||||
onChange={() => toggleSelectAll()}
|
||||
modelValue={selectAll}
|
||||
size="large"/>
|
||||
<span>{selectIds.length} / {list.value.length}</span>
|
||||
<span>{selectIds.length} / {params.total}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 relative">
|
||||
@@ -230,19 +238,19 @@ defineRender(
|
||||
{props.exportLoading ? <IconEosIconsLoading/> : <IconPhExportLight/>}
|
||||
</BaseIcon>
|
||||
<BaseIcon
|
||||
onClick={props.add}
|
||||
onClick={() => emit('add')}
|
||||
title="添加单词">
|
||||
<IconFluentAdd20Regular/>
|
||||
</BaseIcon>
|
||||
<BaseIcon
|
||||
disabled={!currentList.length}
|
||||
disabled={!list2.length}
|
||||
title="改变顺序"
|
||||
onClick={() => showSortDialog = !showSortDialog}
|
||||
>
|
||||
<IconFluentArrowSort20Regular/>
|
||||
</BaseIcon>
|
||||
<BaseIcon
|
||||
disabled={!currentList.length}
|
||||
disabled={!list2.length}
|
||||
onClick={() => showSearchInput = !showSearchInput}
|
||||
title="搜索">
|
||||
<IconFluentSearch20Regular/>
|
||||
@@ -259,7 +267,7 @@ defineRender(
|
||||
<BaseButton onClick={() => sort(Sort.reverse)}>翻转当前页</BaseButton>
|
||||
<BaseButton onClick={() => sort(Sort.reverseAll)}>翻转所有</BaseButton>
|
||||
<div class="line"></div>
|
||||
<BaseButton onClick={() => sort(Sort.reverse)}>随机当前页</BaseButton>
|
||||
<BaseButton onClick={() => sort(Sort.random)}>随机当前页</BaseButton>
|
||||
<BaseButton onClick={() => sort(Sort.randomAll)}>随机所有</BaseButton>
|
||||
</div>
|
||||
</MiniDialog>
|
||||
@@ -291,13 +299,13 @@ defineRender(
|
||||
{
|
||||
props.showPagination && <div class="flex justify-end">
|
||||
<Pagination
|
||||
currentPage={pageNo}
|
||||
currentPage={params.pageNo}
|
||||
onUpdate:current-page={handlePageNo}
|
||||
pageSize={pageSize}
|
||||
onUpdate:page-size={(e) => pageSize = e}
|
||||
pageSize={params.pageSize}
|
||||
onUpdate:page-size={(e) => params.pageSize = e}
|
||||
pageSizes={[20, 50, 100, 200]}
|
||||
layout="prev, pager, next"
|
||||
total={total2}/>
|
||||
layout="prev, pager, next, total"
|
||||
total={params.total}/>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
|
||||
@@ -5,6 +5,7 @@ import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import BaseList from "@/components/list/BaseList.vue";
|
||||
import { usePlayWordAudio } from "@/hooks/sound.ts";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import WordItem from "@/components/WordItem.vue";
|
||||
|
||||
withDefaults(defineProps<{
|
||||
list: Word[],
|
||||
@@ -33,16 +34,12 @@ function scrollToItem(index: number) {
|
||||
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
|
||||
defineExpose({scrollToBottom, scrollToItem})
|
||||
defineExpose({ scrollToBottom, scrollToItem })
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseList
|
||||
ref="listRef"
|
||||
@click="(e:any) => emit('click',e)"
|
||||
:list="list"
|
||||
v-bind="$attrs">
|
||||
<BaseList ref="listRef" @click="(e: any) => emit('click', e)" :list="list" v-bind="$attrs">
|
||||
<template v-slot:prefix="{ item, index }">
|
||||
<slot name="prefix" :item="item" :index="index"></slot>
|
||||
</template>
|
||||
@@ -55,14 +52,10 @@ defineExpose({scrollToBottom, scrollToItem})
|
||||
</div>
|
||||
<div class="item-sub-title flex flex-col gap-2" v-if="item.trans.length && showTranslate">
|
||||
<div v-for="v in item.trans">
|
||||
<Tooltip
|
||||
v-if="v.cn.length > 30"
|
||||
:key="item.word"
|
||||
:title="v.pos + ' ' + v.cn"
|
||||
>
|
||||
<span>{{ v.pos + ' ' + v.cn.slice(0, 30) + '...' }}</span>
|
||||
<Tooltip v-if="v.cn.length > 30" :key="item.word" :title="v.pos + ' ' + v.cn">
|
||||
<span>{{ v.pos + ' ' + v.cn.slice(0, 30) + '...' }}</span>
|
||||
</Tooltip>
|
||||
<span v-else>{{ v.pos + ' ' + v.cn }}</span>
|
||||
<span v-else>{{ v.pos + ' ' + v.cn }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="log-item">
|
||||
<div class="mb-2">
|
||||
<div>
|
||||
<div>日期:2025/12/15</div>
|
||||
<div>内容:修复在黑暗模式下,翻译颜色不正确;支持中文符号输入</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="log-item">
|
||||
<div class="mb-2">
|
||||
<div>
|
||||
|
||||
@@ -440,37 +440,39 @@ watch(() => loading, (val) => {
|
||||
}, 500)
|
||||
})
|
||||
|
||||
let pageNo = $ref(1)
|
||||
let pageSize = $ref(50)
|
||||
let list2 = $ref([])
|
||||
|
||||
async function requestList({ pageNo, pageSize }) {
|
||||
async function requestList({ pageNo, pageSize, searchKey }) {
|
||||
if (AppEnv.CAN_REQUEST) {
|
||||
|
||||
} else {
|
||||
return {
|
||||
list: list2.slice((pageNo - 1) * pageSize, (pageNo - 1) * pageSize + pageSize),
|
||||
total: list2.length
|
||||
let list = list2
|
||||
let total = list2.length
|
||||
if (searchKey.trim()) {
|
||||
list = list2.filter(v => v.word.toLowerCase().includes(searchKey.trim().toLowerCase()))
|
||||
total = list.length
|
||||
}
|
||||
list = list.slice((pageNo - 1) * pageSize, (pageNo - 1) * pageSize + pageSize)
|
||||
return { list, total }
|
||||
}
|
||||
}
|
||||
|
||||
function sort(type: Sort, pageNo: number, pageSize: number) {
|
||||
debugger
|
||||
|
||||
console.log('sort', type)
|
||||
if ([Sort.reverse, Sort.random].includes(type)) {
|
||||
function onSort(type: Sort, pageNo: number, pageSize: number) {
|
||||
if (AppEnv.CAN_REQUEST) {
|
||||
} else {
|
||||
let fun = reverse
|
||||
if ([Sort.reverse, Sort.reverseAll].includes(type)) {
|
||||
fun = reverse
|
||||
} else if ([Sort.random, Sort.randomAll].includes(type)) {
|
||||
fun = shuffle
|
||||
}
|
||||
list2 = list2.slice(0, pageSize * (pageNo - 1))
|
||||
.concat(reverse(list2.slice(pageSize * (pageNo - 1), pageSize * (pageNo - 1) + pageSize)))
|
||||
.concat(list2.slice(pageSize * (pageNo - 1) + pageSize))
|
||||
} else if ([Sort.reverseAll, Sort.randomAll].includes(type)) {
|
||||
list2 = list2.slice(0, pageSize * (pageNo - 1))
|
||||
.concat(shuffle(list2.slice(pageSize * (pageNo - 1), pageSize * (pageNo - 1) + pageSize)))
|
||||
.concat(fun(list2.slice(pageSize * (pageNo - 1), pageSize * (pageNo - 1) + pageSize)))
|
||||
.concat(list2.slice(pageSize * (pageNo - 1) + pageSize))
|
||||
runtimeStore.editDict.words = list2
|
||||
Toast.success('操作成功')
|
||||
tableRef.value.getData()
|
||||
}
|
||||
runtimeStore.editDict.words = list2
|
||||
Toast.success('已排序成功')
|
||||
tableRef.value.getData()
|
||||
}
|
||||
|
||||
|
||||
@@ -513,7 +515,6 @@ defineRender(() => {
|
||||
<div class="flex flex-1 overflow-hidden content-area">
|
||||
<div class={`word-list-section ${isMob && isOperate && activeTab !== 'list' ? 'mobile-hidden' : ''}`}>
|
||||
<BaseTable
|
||||
sort={sort}
|
||||
ref={tableRef}
|
||||
class="h-full"
|
||||
request={requestList}
|
||||
@@ -523,7 +524,8 @@ defineRender(() => {
|
||||
onUpdate:list={e => list = e}
|
||||
del={delWord}
|
||||
batchDel={batchDel}
|
||||
add={addWord}
|
||||
onSort={onSort}
|
||||
onAdd={addWord}
|
||||
onImportData={importData}
|
||||
onExportData={exportData}
|
||||
exportLoading={exportLoading}
|
||||
|
||||
@@ -473,23 +473,6 @@ export async function loadJsLib(key: string, url: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function loadJsLib2(key: string, url: string, module: boolean = false) {
|
||||
if (window[key]) return window[key];
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
if (module) {
|
||||
script.type = 'module'
|
||||
}
|
||||
script.src = url;
|
||||
script.onload = () => {
|
||||
console.log('key', key)
|
||||
resolve(window[key])
|
||||
};
|
||||
script.onerror = () => reject(key + ' 加载失败')
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
export function total(arr, key) {
|
||||
return arr.reduce((a, b) => {
|
||||
a += b[key];
|
||||
|
||||
Reference in New Issue
Block a user