feat: 增加表头操作功能,支持动态控制操作按钮显示;优化银行卡信息展示
This commit is contained in:
@@ -18,6 +18,7 @@ export default defineConfig(
|
|||||||
ignores: ['/^icon-/']
|
ignores: ['/^icon-/']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
'vue/no-duplicate-attr-inheritance': 'off',
|
||||||
'unocss/order-attributify': 'off'
|
'unocss/order-attributify': 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ interface Props {
|
|||||||
itemAlign?: NaiveUI.Align;
|
itemAlign?: NaiveUI.Align;
|
||||||
disabledDelete?: boolean;
|
disabledDelete?: boolean;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
operations?: {
|
||||||
|
add?: boolean;
|
||||||
|
refresh?: boolean;
|
||||||
|
delete?: boolean;
|
||||||
|
columns?: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<Props>();
|
defineProps<Props>();
|
||||||
@@ -43,27 +49,34 @@ function refresh() {
|
|||||||
<slot name="prefix"></slot>
|
<slot name="prefix"></slot>
|
||||||
<div class="space-x-5">
|
<div class="space-x-5">
|
||||||
<slot name="default">
|
<slot name="default">
|
||||||
<NButton size="small" ghost type="primary" @click="add">
|
<NButton v-if="operations?.add" size="small" ghost type="primary" @click="add">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-ic-round-plus class="text-icon" />
|
<icon-ic-round-plus class="text-icon" />
|
||||||
</template>
|
</template>
|
||||||
{{ $t('common.add') }}
|
{{ $t('common.add') }}
|
||||||
</NButton>
|
</NButton>
|
||||||
|
|
||||||
<NButton size="small" ghost type="error" :disabled="disabledDelete" @click="batchDelete">
|
<NButton
|
||||||
|
v-if="operations?.delete"
|
||||||
|
size="small"
|
||||||
|
ghost
|
||||||
|
type="error"
|
||||||
|
:disabled="disabledDelete"
|
||||||
|
@click="batchDelete"
|
||||||
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-ic-round-delete class="text-icon" />
|
<icon-ic-round-delete class="text-icon" />
|
||||||
</template>
|
</template>
|
||||||
{{ $t('common.batchDelete') }}
|
{{ $t('common.batchDelete') }}
|
||||||
</NButton>
|
</NButton>
|
||||||
</slot>
|
</slot>
|
||||||
<NButton size="small" @click="refresh">
|
<NButton v-if="operations?.refresh" size="small" @click="refresh">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-mdi-refresh class="text-icon" :class="{ 'animate-spin': loading }" />
|
<icon-mdi-refresh class="text-icon" :class="{ 'animate-spin': loading }" />
|
||||||
</template>
|
</template>
|
||||||
{{ $t('common.refresh') }}
|
{{ $t('common.refresh') }}
|
||||||
</NButton>
|
</NButton>
|
||||||
<TableColumnSetting v-model:columns="columns" />
|
<TableColumnSetting v-if="operations?.columns" v-model:columns="columns" />
|
||||||
</div>
|
</div>
|
||||||
<slot name="suffix"></slot>
|
<slot name="suffix"></slot>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import type { ComponentInstance } from 'vue';
|
||||||
|
import { getCurrentInstance, onMounted, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import type { DataTableColumns, PaginationProps } from 'naive-ui';
|
import type { DataTableColumns, NDataTable, PaginationProps } from 'naive-ui';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import {
|
import {
|
||||||
type TableBaseColumns,
|
type TableBaseColumns,
|
||||||
@@ -22,10 +23,23 @@ const props = withDefaults(
|
|||||||
fetchData: TableFetchData;
|
fetchData: TableFetchData;
|
||||||
columns: TableBaseColumns;
|
columns: TableBaseColumns;
|
||||||
showHeaderOperation?: boolean;
|
showHeaderOperation?: boolean;
|
||||||
|
headerOperations?: {
|
||||||
|
add?: boolean;
|
||||||
|
refresh?: boolean;
|
||||||
|
delete?: boolean;
|
||||||
|
columns?: boolean;
|
||||||
|
};
|
||||||
filterColumns?: TableFilterColumns;
|
filterColumns?: TableFilterColumns;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
filterColumns: () => []
|
showHeaderOperation: true,
|
||||||
|
filterColumns: () => [],
|
||||||
|
headerOperations: () => ({
|
||||||
|
add: true,
|
||||||
|
refresh: true,
|
||||||
|
delete: false,
|
||||||
|
columns: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -43,6 +57,7 @@ const pagination = ref<PaginationProps>({
|
|||||||
showSizePicker: true,
|
showSizePicker: true,
|
||||||
pageSizes: [10, 20, 50, 100]
|
pageSizes: [10, 20, 50, 100]
|
||||||
});
|
});
|
||||||
|
const vm = getCurrentInstance()!;
|
||||||
|
|
||||||
async function loadData(query?: Record<string, any>) {
|
async function loadData(query?: Record<string, any>) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -87,14 +102,22 @@ function handleUpdateColumns(columns: TableColumnCheck[]) {
|
|||||||
|
|
||||||
dataTableColumns.value = sortedColumns as DataTableColumns;
|
dataTableColumns.value = sortedColumns as DataTableColumns;
|
||||||
}
|
}
|
||||||
|
function tableRef(exposed: any) {
|
||||||
|
vm.exposed = {
|
||||||
|
reload: loadData,
|
||||||
|
...exposed
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadData();
|
loadData();
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
interface Expose extends ComponentInstance<typeof NDataTable> {
|
||||||
reload: loadData
|
reload: typeof loadData;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
defineExpose({} as Expose);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -104,6 +127,7 @@ defineExpose({
|
|||||||
<div class="rounded-lg bg-white p-5 space-y-5 dark:bg-white/10">
|
<div class="rounded-lg bg-white p-5 space-y-5 dark:bg-white/10">
|
||||||
<TableHeaderOperation
|
<TableHeaderOperation
|
||||||
v-if="showHeaderOperation"
|
v-if="showHeaderOperation"
|
||||||
|
:operations="headerOperations"
|
||||||
:columns="headerTableColumns"
|
:columns="headerTableColumns"
|
||||||
@update:columns="handleUpdateColumns"
|
@update:columns="handleUpdateColumns"
|
||||||
@add="emit('add')"
|
@add="emit('add')"
|
||||||
@@ -116,7 +140,7 @@ defineExpose({
|
|||||||
</TableHeaderOperation>
|
</TableHeaderOperation>
|
||||||
|
|
||||||
<NDataTable
|
<NDataTable
|
||||||
:row-key="row => (row as any).id"
|
:ref="tableRef"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:scroll-x="2000"
|
:scroll-x="2000"
|
||||||
:columns="dataTableColumns"
|
:columns="dataTableColumns"
|
||||||
@@ -125,6 +149,7 @@ defineExpose({
|
|||||||
:bordered="false"
|
:bordered="false"
|
||||||
:on-update:page="handlePageChange"
|
:on-update:page="handlePageChange"
|
||||||
:on-update:page-size="handlePageSizeChange"
|
:on-update:page-size="handlePageSizeChange"
|
||||||
|
v-bind="$attrs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTemplateRef } from 'vue';
|
import { useTemplateRef } from 'vue';
|
||||||
import { NDatePicker, useDialog, useMessage } from 'naive-ui';
|
import { useDialog, useMessage } from 'naive-ui';
|
||||||
import { client, safeClient } from '@/service/api';
|
import { client, safeClient } from '@/service/api';
|
||||||
import type { TableBaseColumns, TableFetchData, TableInst } from '@/components/table';
|
import type { TableBaseColumns, TableFetchData, TableFilterColumns, TableInst } from '@/components/table';
|
||||||
|
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
@@ -24,29 +24,21 @@ const columns: TableBaseColumns = [
|
|||||||
title: 'ID',
|
title: 'ID',
|
||||||
key: 'userId'
|
key: 'userId'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
key: 'accountName'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '银行卡名称',
|
title: '银行卡名称',
|
||||||
key: 'bankName'
|
key: 'bankName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '银行卡号',
|
title: '银行编号',
|
||||||
key: 'bankCode'
|
key: 'bankCode'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '账户名',
|
title: '风险等级',
|
||||||
key: 'accountName'
|
key: 'riskStatus'
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'maskAccountNumber',
|
|
||||||
key: 'maskAccountNumber'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'country',
|
|
||||||
key: 'country'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'branchName',
|
|
||||||
key: 'branchName'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
@@ -57,6 +49,7 @@ const columns: TableBaseColumns = [
|
|||||||
{
|
{
|
||||||
contentText: '编辑',
|
contentText: '编辑',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
|
ghost: true,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
tableInst.value?.reload();
|
tableInst.value?.reload();
|
||||||
}
|
}
|
||||||
@@ -65,7 +58,6 @@ const columns: TableBaseColumns = [
|
|||||||
contentText: '删除',
|
contentText: '删除',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
ghost: true,
|
ghost: true,
|
||||||
size: 'small',
|
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
dialog.create({
|
dialog.create({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
@@ -94,15 +86,20 @@ const filterColumns: TableFilterColumns = [
|
|||||||
key: 'bankName'
|
key: 'bankName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '银行卡号',
|
title: '银行编号',
|
||||||
key: 'bankCode',
|
key: 'bankCode'
|
||||||
component: NDatePicker
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TableBase ref="tableInst" :columns="columns" :filter-columns="filterColumns" :fetch-data="fetchData" />
|
<TableBase
|
||||||
|
ref="tableInst"
|
||||||
|
show-header-operation
|
||||||
|
:columns="columns"
|
||||||
|
:filter-columns="filterColumns"
|
||||||
|
:fetch-data="fetchData"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="css" scoped></style>
|
<style lang="css" scoped></style>
|
||||||
|
|||||||
Reference in New Issue
Block a user