This commit is contained in:
Zyronon
2025-12-17 10:29:07 +08:00
parent 6eb15e180a
commit f23cc79a98
12 changed files with 173 additions and 156 deletions

View File

@@ -1,6 +1,6 @@
<script setup lang="tsx">
import { nextTick, onMounted, useSlots } from "vue";
import { nextTick, useSlots } from "vue";
import { Sort } from "@/types/types.ts";
import MiniDialog from "@/components/dialog/MiniDialog.vue";
import BaseIcon from "@/components/BaseIcon.vue";
@@ -16,6 +16,7 @@ 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
@@ -26,7 +27,6 @@ const props = withDefaults(defineProps<{
del?: Function
batchDel?: Function
add?: Function
request?: Function
total: number
}>(), {
loading: true,
@@ -36,19 +36,16 @@ const props = withDefaults(defineProps<{
importLoading: false,
del: () => void 0,
add: () => void 0,
request: () => void 0,
batchDel: () => void 0
})
const emit = defineEmits<{
add: []
click: [val: {
item: any,
index: number
}],
importData: [e: Event]
exportData: []
sort: [type: Sort,pageNo: number,pageSize: number]
}>()
let listRef: any = $ref()
@@ -71,15 +68,22 @@ 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(() => {
return !!selectIds.length
})
function toggleSelect(item) {
let rIndex = selectIds.findIndex(v => v === item.id)
if (rIndex > -1) {
@@ -93,10 +97,11 @@ function toggleSelectAll() {
if (selectAll) {
selectIds = []
} else {
selectIds = list2.map(v => v.id)
selectIds = currentList.map(v => v.id)
}
}
let searchKey = $ref('')
let showSortDialog = $ref(false)
let showSearchInput = $ref(false)
let showImportDialog = $ref(false)
@@ -104,10 +109,13 @@ let showImportDialog = $ref(false)
const closeImportDialog = () => showImportDialog = false
function sort(type: Sort) {
if ([Sort.reverse, Sort.random].includes(type)) {
emit('sort', type,params.pageNo,params.pageSize)
}else{
emit('sort', type,1,params.total)
if (type === Sort.reverse) {
Toast.success('已翻转排序')
list.value = reverse(cloneDeep(list.value))
}
if (type === Sort.random) {
Toast.success('已随机排序')
list.value = shuffle(cloneDeep(list.value))
}
showSortDialog = false
}
@@ -118,8 +126,7 @@ function handleBatchDel() {
}
function handlePageNo(e) {
params.pageNo = e
getData()
pageNo = e
scrollToTop()
}
@@ -128,52 +135,8 @@ const s = useSlots()
defineExpose({
scrollToBottom,
scrollToItem,
closeImportDialog,
getData
closeImportDialog
})
let list2 = $ref([])
let loading2 = $ref(false)
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
console.log('params',params);
let {list, total} = await props.request(params)
console.log('list',list)
list2 = list
params.total = total
loading2 = false
}
onMounted(async () => {
getData()
})
defineRender(
() => {
const d = (item) => <Checkbox
@@ -190,8 +153,8 @@ defineRender(
<div class="flex gap-4">
<BaseInput
clearable
modelValue={params.searchKey}
onUpdate:modelValue={debounce(e => search(e), 500)}
modelValue={searchKey}
onUpdate:modelValue={debounce(e => searchKey = e)}
class="flex-1"
autofocus>
{{
@@ -200,17 +163,17 @@ defineRender(
/>
}}
</BaseInput>
<BaseButton onClick={cancelSearch}>取消</BaseButton>
<BaseButton onClick={() => (showSearchInput = false, searchKey = '')}>取消</BaseButton>
</div>
) : (
<div class="flex justify-between">
<div class="flex gap-2 items-center">
<Checkbox
disabled={!list2.length}
disabled={!currentList.length}
onChange={() => toggleSelectAll()}
modelValue={selectAll}
size="large"/>
<span>{selectIds.length} / {params.total}</span>
<span>{selectIds.length} / {list.value.length}</span>
</div>
<div class="flex gap-2 relative">
@@ -238,19 +201,19 @@ defineRender(
{props.exportLoading ? <IconEosIconsLoading/> : <IconPhExportLight/>}
</BaseIcon>
<BaseIcon
onClick={() => emit('add')}
onClick={props.add}
title="添加单词">
<IconFluentAdd20Regular/>
</BaseIcon>
<BaseIcon
disabled={!list2.length}
disabled={!currentList.length}
title="改变顺序"
onClick={() => showSortDialog = !showSortDialog}
>
<IconFluentArrowSort20Regular/>
</BaseIcon>
<BaseIcon
disabled={!list2.length}
disabled={!currentList.length}
onClick={() => showSearchInput = !showSearchInput}
title="搜索">
<IconFluentSearch20Regular/>
@@ -263,12 +226,10 @@ defineRender(
<div class="mini-row-title">
列表顺序设置
</div>
<div class="flex flex-col gap2 btn-no-margin">
<BaseButton onClick={() => sort(Sort.reverse)}>翻转当前页</BaseButton>
<BaseButton onClick={() => sort(Sort.reverseAll)}>翻转所有</BaseButton>
<div class="line"></div>
<BaseButton onClick={() => sort(Sort.random)}>随机当前页</BaseButton>
<BaseButton onClick={() => sort(Sort.randomAll)}>随机所有</BaseButton>
<div class="mini-row">
<BaseButton size="small" onClick={() => sort(Sort.reverse)}>翻转
</BaseButton>
<BaseButton size="small" onClick={() => sort(Sort.random)}>随机</BaseButton>
</div>
</MiniDialog>
</div>
@@ -278,15 +239,15 @@ defineRender(
</div>
}
{
loading2 ?
props.loading ?
<div class="h-full w-full center text-4xl">
<IconEosIconsLoading color="gray"/>
</div>
: list2.length ? (
: currentList.length ? (
<>
<div class="flex-1 overflow-auto"
ref={e => listRef = e}>
{list2.map((item, index) => {
{currentList.map((item, index) => {
return (
<div class="list-item-wrapper"
key={item.word}
@@ -299,13 +260,13 @@ defineRender(
{
props.showPagination && <div class="flex justify-end">
<Pagination
currentPage={params.pageNo}
currentPage={pageNo}
onUpdate:current-page={handlePageNo}
pageSize={params.pageSize}
onUpdate:page-size={(e) => params.pageSize = e}
pageSize={pageSize}
onUpdate:page-size={(e) => pageSize = e}
pageSizes={[20, 50, 100, 200]}
layout="prev, pager, next, total"
total={params.total}/>
layout="prev, pager, next"
total={props.total}/>
</div>
}
</>
@@ -347,4 +308,6 @@ defineRender(
}
)
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
</style>

View File

@@ -1,6 +1,6 @@
<script setup lang="tsx">
import { nextTick, useSlots } from "vue";
import { nextTick, onMounted, useSlots } from "vue";
import { Sort } from "@/types/types.ts";
import MiniDialog from "@/components/dialog/MiniDialog.vue";
import BaseIcon from "@/components/BaseIcon.vue";
@@ -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
@@ -27,6 +26,7 @@ const props = withDefaults(defineProps<{
del?: Function
batchDel?: Function
add?: Function
request?: Function
total: number
}>(), {
loading: true,
@@ -36,16 +36,19 @@ const props = withDefaults(defineProps<{
importLoading: false,
del: () => void 0,
add: () => void 0,
request: () => void 0,
batchDel: () => void 0
})
const emit = defineEmits<{
add: []
click: [val: {
item: any,
index: number
}],
importData: [e: Event]
exportData: []
sort: [type: Sort,pageNo: number,pageSize: number]
}>()
let listRef: any = $ref()
@@ -68,22 +71,15 @@ 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(() => {
return !!selectIds.length
})
function toggleSelect(item) {
let rIndex = selectIds.findIndex(v => v === item.id)
if (rIndex > -1) {
@@ -97,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)
@@ -109,13 +104,10 @@ let showImportDialog = $ref(false)
const closeImportDialog = () => showImportDialog = false
function sort(type: Sort) {
if (type === Sort.reverse) {
Toast.success('已翻转排序')
list.value = reverse(cloneDeep(list.value))
}
if (type === Sort.random) {
Toast.success('已随机排序')
list.value = shuffle(cloneDeep(list.value))
if ([Sort.reverse, Sort.random].includes(type)) {
emit('sort', type,params.pageNo,params.pageSize)
}else{
emit('sort', type,1,params.total)
}
showSortDialog = false
}
@@ -126,7 +118,8 @@ function handleBatchDel() {
}
function handlePageNo(e) {
pageNo = e
params.pageNo = e
getData()
scrollToTop()
}
@@ -135,8 +128,52 @@ const s = useSlots()
defineExpose({
scrollToBottom,
scrollToItem,
closeImportDialog
closeImportDialog,
getData
})
let list2 = $ref([])
let loading2 = $ref(false)
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
console.log('params',params);
let {list, total} = await props.request(params)
console.log('list',list)
list2 = list
params.total = total
loading2 = false
}
onMounted(async () => {
getData()
})
defineRender(
() => {
const d = (item) => <Checkbox
@@ -153,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>
{{
@@ -163,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">
@@ -201,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/>
@@ -226,10 +263,12 @@ defineRender(
<div class="mini-row-title">
列表顺序设置
</div>
<div class="mini-row">
<BaseButton size="small" onClick={() => sort(Sort.reverse)}>翻转
</BaseButton>
<BaseButton size="small" onClick={() => sort(Sort.random)}>随机</BaseButton>
<div class="flex flex-col gap2 btn-no-margin">
<BaseButton onClick={() => sort(Sort.reverse)}>翻转当前页</BaseButton>
<BaseButton onClick={() => sort(Sort.reverseAll)}>翻转所有</BaseButton>
<div class="line"></div>
<BaseButton onClick={() => sort(Sort.random)}>随机当前页</BaseButton>
<BaseButton onClick={() => sort(Sort.randomAll)}>随机所有</BaseButton>
</div>
</MiniDialog>
</div>
@@ -239,15 +278,15 @@ defineRender(
</div>
}
{
props.loading ?
loading2 ?
<div class="h-full w-full center text-4xl">
<IconEosIconsLoading color="gray"/>
</div>
: currentList.length ? (
: list2.length ? (
<>
<div class="flex-1 overflow-auto"
ref={e => listRef = e}>
{currentList.map((item, index) => {
{list2.map((item, index) => {
return (
<div class="list-item-wrapper"
key={item.word}
@@ -260,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={props.total}/>
layout="prev, pager, next, total"
total={params.total}/>
</div>
}
</>
@@ -308,6 +347,4 @@ defineRender(
}
)
</script>
<style scoped lang="scss">
</style>
<style scoped lang="scss"></style>

View File

@@ -89,7 +89,7 @@ watch(() => props.modelValue, n => {
// console.log('n', n)
if (n) {
id = Date.now()
runtimeStore.modalList.push({id, close})
runtimeStore.modalList.push({ id, close })
zIndex = 999 + runtimeStore.modalList.length
visible = true
} else {
@@ -101,7 +101,7 @@ onMounted(() => {
if (props.modelValue === undefined) {
visible = true
id = Date.now()
runtimeStore.modalList.push({id, close})
runtimeStore.modalList.push({ id, close })
zIndex = 999 + runtimeStore.modalList.length
}
})
@@ -175,7 +175,7 @@ async function cancel() {
<div class="right">
<BaseButton type="info" @click="cancel">{{ cancelButtonText }}</BaseButton>
<BaseButton
id="dialog-ok"
id="dialog-ok"
:loading="confirmButtonLoading"
@click="ok">{{ confirmButtonText }}
</BaseButton>
@@ -292,7 +292,8 @@ $header-height: 4rem;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.3rem 1.3rem 1rem;
padding: var(--modal-padding);
padding-bottom: 0;
border-radius: $radius $radius 0 0;
.title {
@@ -315,7 +316,7 @@ $header-height: 4rem;
display: flex;
&.padding {
padding: .2rem 1.6rem 1.6rem;
padding: .2rem var(--modal-padding);
}
.content {
@@ -327,7 +328,7 @@ $header-height: 4rem;
.modal-footer {
display: flex;
justify-content: space-between;
padding: var(--space);
padding: var(--modal-padding);
}
}
}