refactor: 字典项布局重构(未完成)
This commit is contained in:
parent
2de9cd2334
commit
2569e1da0d
@ -9,20 +9,50 @@ import { cn } from '@vben/utils';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
ExportOutlined,
|
||||
PlusOutlined,
|
||||
SyncOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { Card, Empty, Input, Popconfirm, Space } from 'ant-design-vue';
|
||||
import {
|
||||
Empty,
|
||||
Input,
|
||||
Modal,
|
||||
Popconfirm,
|
||||
Space,
|
||||
Spin,
|
||||
Tooltip,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import { dictTypeList, dictTypeRemove } from '#/api/system/dict/dict-type';
|
||||
import {
|
||||
dictTypeExport,
|
||||
dictTypeList,
|
||||
dictTypeRemove,
|
||||
refreshDictTypeCache,
|
||||
} from '#/api/system/dict/dict-type';
|
||||
import { commonDownloadExcel } from '#/utils/file/download';
|
||||
|
||||
import { emitter } from '../mitt';
|
||||
import dictTypeModal from './dict-type-modal.vue';
|
||||
|
||||
const dictList = ref<DictType[]>([]);
|
||||
onMounted(async () => {
|
||||
const loading = ref(false);
|
||||
|
||||
async function loadData(reset = false) {
|
||||
loading.value = true;
|
||||
|
||||
if (reset) {
|
||||
currentRowId.value = '';
|
||||
emitter.emit('rowClick', '');
|
||||
searchValue.value = '';
|
||||
}
|
||||
|
||||
const resp = await dictTypeList();
|
||||
dictList.value = resp.rows;
|
||||
});
|
||||
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
onMounted(loadData);
|
||||
|
||||
const [DictTypeModal, modalApi] = useVbenModal({
|
||||
connectedComponent: dictTypeModal,
|
||||
@ -43,6 +73,24 @@ async function handleDelete(row: DictType) {
|
||||
// TODO: 刷新表格
|
||||
}
|
||||
|
||||
function handleDownloadExcel() {
|
||||
commonDownloadExcel(dictTypeExport, '字典类型数据');
|
||||
}
|
||||
|
||||
function handleRefreshCache() {
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确认刷新字典类型缓存吗?',
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
onOk: async () => {
|
||||
await refreshDictTypeCache();
|
||||
// TODO: 刷新表格
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const currentRowId = ref<null | number | string>(null);
|
||||
function handleRowClick(row: DictType) {
|
||||
currentRowId.value = row.dictId;
|
||||
@ -54,63 +102,105 @@ const searchResultList = computed(() => {
|
||||
if (!searchValue.value) {
|
||||
return dictList.value;
|
||||
}
|
||||
return dictList.value.filter((item) =>
|
||||
const names = dictList.value.filter((item) =>
|
||||
item.dictName.includes(searchValue.value),
|
||||
);
|
||||
const types = dictList.value.filter((item) =>
|
||||
item.dictType.includes(searchValue.value),
|
||||
);
|
||||
return [...new Set([...names, ...types])];
|
||||
});
|
||||
|
||||
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Card :class="cn('w-[400px]')" title="字典项列表">
|
||||
<template #extra>
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'bg-background flex h-[calc(100vh-120px)] w-[360px] flex-col overflow-y-hidden',
|
||||
'rounded-lg',
|
||||
)
|
||||
"
|
||||
>
|
||||
<div :class="cn('flex items-center justify-between', 'border-b px-4 py-2')">
|
||||
<span class="font-semibold">字典项列表</span>
|
||||
<Space>
|
||||
<a-button :icon="h(PlusOutlined)" @click="handleAdd" />
|
||||
<Tooltip title="刷新缓存">
|
||||
<a-button :icon="h(SyncOutlined)" @click="handleRefreshCache" />
|
||||
</Tooltip>
|
||||
<Tooltip :title="$t('pages.common.export')">
|
||||
<a-button :icon="h(ExportOutlined)" @click="handleDownloadExcel" />
|
||||
</Tooltip>
|
||||
<Tooltip :title="$t('pages.common.add')">
|
||||
<a-button :icon="h(PlusOutlined)" @click="handleAdd" />
|
||||
</Tooltip>
|
||||
</Space>
|
||||
</template>
|
||||
<Input
|
||||
placeholder="搜索字典项名称"
|
||||
v-model:value="searchValue"
|
||||
allow-clear
|
||||
/>
|
||||
<div
|
||||
v-if="searchResultList.length > 0"
|
||||
class="mt-4 flex cursor-pointer flex-col overflow-y-auto"
|
||||
>
|
||||
<div
|
||||
:class="
|
||||
cn('flex items-center justify-between rounded-lg px-2 py-1', {
|
||||
'bg-[#ccc]': item.dictId === currentRowId,
|
||||
})
|
||||
"
|
||||
v-for="item in searchResultList"
|
||||
:key="item.dictId"
|
||||
@click="handleRowClick(item)"
|
||||
>
|
||||
<div>
|
||||
<span>{{ item.dictName }}</span>
|
||||
<span class="ml-2 text-sm text-[#666]">{{ item.dictType }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 text-sm">
|
||||
<EditOutlined class="text-primary" @click.stop="handleEdit(item)" />
|
||||
<Popconfirm
|
||||
placement="left"
|
||||
:title="`确认删除 [${item.dictName}]?`"
|
||||
@confirm="handleDelete(item)"
|
||||
>
|
||||
<DeleteOutlined class="text-destructive" @click.stop="" />
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Empty class="mt-4" v-else />
|
||||
<div class="flex flex-1 flex-col overflow-y-hidden p-4">
|
||||
<Input
|
||||
placeholder="搜索字典项名称/类型"
|
||||
v-model:value="searchValue"
|
||||
allow-clear
|
||||
>
|
||||
<template #addonAfter>
|
||||
<Tooltip title="重置/刷新">
|
||||
<SyncOutlined @click="loadData(true)" />
|
||||
</Tooltip>
|
||||
</template>
|
||||
</Input>
|
||||
<div
|
||||
v-if="searchResultList.length > 0"
|
||||
class="mt-4 flex cursor-pointer flex-col overflow-y-auto"
|
||||
>
|
||||
<Spin :spinning="loading">
|
||||
<div
|
||||
:class="
|
||||
cn(
|
||||
'flex items-center justify-between rounded-lg px-2 py-2',
|
||||
{
|
||||
'bg-accent-hover': item.dictId === currentRowId,
|
||||
},
|
||||
'border-b',
|
||||
)
|
||||
"
|
||||
v-for="item in searchResultList"
|
||||
:key="item.dictId"
|
||||
@click="handleRowClick(item)"
|
||||
>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<span class="font-medium">{{ item.dictName }}</span>
|
||||
<span
|
||||
class="min-w-0 text-ellipsis whitespace-nowrap text-sm text-[#666]"
|
||||
>
|
||||
{{ item.dictType }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 text-sm">
|
||||
<EditOutlined
|
||||
class="text-primary"
|
||||
@click.stop="handleEdit(item)"
|
||||
/>
|
||||
<Popconfirm
|
||||
placement="left"
|
||||
:title="`确认删除 [${item.dictName}]?`"
|
||||
@confirm="handleDelete(item)"
|
||||
>
|
||||
<DeleteOutlined class="text-destructive" @click.stop="" />
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
<Empty
|
||||
:image="emptyImage"
|
||||
class="mt-4"
|
||||
v-if="searchResultList.length === 0"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-t px-4 py-3">
|
||||
共 {{ searchResultList.length }} 条数据
|
||||
</div>
|
||||
<DictTypeModal />
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.ant-card-body) {
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user