费用优化

This commit is contained in:
2026-10-26 13:43:08 +08:00
parent 090431b409
commit 18a78e5508
74 changed files with 3339 additions and 116 deletions
+9 -2
View File
@@ -423,10 +423,10 @@ describe('DataTable column preferences', () => {
expect(wrapper.get('.data-table__toolbar-end').text()).toBe('辅助操作')
})
it('uses a compact right-aligned toolbar when no leading content is provided', () => {
it('uses a compact toolbar and can join filters without duplicating actions or column settings', async () => {
const wrapper = shallowMount(DataTable, {
props: { data: [], columns: configurableColumns, preferenceKey: 'orders-table', columnSettingsMode: 'show' },
slots: { 'toolbar-actions': '<button>新增订单</button>' },
slots: { 'toolbar-actions': '<button>新增订单</button>', filters: '<input aria-label="搜索" />' },
global: {
provide: { [UI_PREFERENCE_SCOPE as symbol]: computed(() => 'user-1') },
stubs: {
@@ -443,6 +443,13 @@ describe('DataTable column preferences', () => {
expect(wrapper.find('.data-table__toolbar-start').exists()).toBe(false)
expect(wrapper.get('.data-table__toolbar-actions').classes()).toContain('has-business-actions')
expect(wrapper.get('.data-table__business-actions').text()).toBe('新增订单')
expect(wrapper.find('.data-table__toolbar .data-table__filters').exists()).toBe(false)
await wrapper.setProps({ toolbarPlacement: 'filters' })
expect(wrapper.get('.data-table__toolbar').classes()).toContain('has-inline-filters')
expect(wrapper.get('.data-table__toolbar .data-table__filters input').attributes('aria-label')).toBe('搜索')
expect(wrapper.findAll('.data-table__filters')).toHaveLength(1)
expect(wrapper.findAll('button[aria-label="列设置"]')).toHaveLength(1)
expect(wrapper.get('.data-table__business-actions').text()).toBe('新增订单')
})
it('keeps business actions in a separate mobile-wrappable group from column settings', () => {
+23 -3
View File
@@ -79,6 +79,7 @@ const props = withDefaults(defineProps<{
maxHeight?: string | number
preferenceKey?: string
columnSettingsMode?: 'auto' | 'show' | 'hide'
toolbarPlacement?: 'top' | 'filters'
border?: boolean
stripe?: boolean
appearance?: 'default' | 'integrated'
@@ -90,6 +91,7 @@ const props = withDefaults(defineProps<{
pageSizes: () => [10, 20, 50, 100],
maxHeight: 'calc(100vh - 300px)',
columnSettingsMode: 'auto',
toolbarPlacement: 'top',
border: true,
stripe: true,
appearance: 'default',
@@ -337,11 +339,12 @@ function setPage(value: number) {
<template>
<div class="data-table" :class="{ 'data-table--integrated': appearance === 'integrated' }">
<div
v-if="$slots['toolbar-start'] || $slots['toolbar-actions'] || preferenceEnabled || $slots['toolbar-end']"
v-if="$slots['toolbar-start'] || $slots['toolbar-actions'] || preferenceEnabled || $slots['toolbar-end'] || (toolbarPlacement === 'filters' && $slots.filters)"
class="data-table__toolbar"
:class="{ 'is-compact': !$slots['toolbar-start'] }"
:class="{ 'is-compact': !$slots['toolbar-start'], 'has-inline-filters': toolbarPlacement === 'filters' && $slots.filters }"
>
<div v-if="$slots['toolbar-start']" class="data-table__toolbar-start"><slot name="toolbar-start" /></div>
<div v-if="toolbarPlacement === 'filters' && $slots.filters" class="data-table__filters"><slot name="filters" /></div>
<div class="data-table__toolbar-actions" :class="{ 'has-business-actions': $slots['toolbar-actions'] }">
<div v-if="$slots['toolbar-actions']" class="data-table__business-actions"><slot name="toolbar-actions" /></div>
<div v-if="preferenceEnabled || $slots['toolbar-end']" class="data-table__utility-actions">
@@ -362,7 +365,7 @@ function setPage(value: number) {
</div>
</div>
</div>
<div v-if="$slots.filters" class="data-table__filters"><slot name="filters" /></div>
<div v-if="$slots.filters && toolbarPlacement !== 'filters'" class="data-table__filters"><slot name="filters" /></div>
<div v-if="hasRegion('notices')" class="data-table__notices"><slot name="notices" /></div>
<div v-if="resultsVisible && hasRegion('before-results')" class="data-table__summary"><slot name="before-results" /></div>
<div v-if="$slots.state" class="data-table__state"><slot name="state" /></div>
@@ -580,4 +583,21 @@ function setPage(value: number) {
.data-table--integrated .data-table__filters :deep(.surface-panel) { border: 0; border-radius: 0; box-shadow: none; }
.data-table--integrated .data-table__filters :deep(.integrated-query-group) { display: grid; min-width: 0; gap: 0; }
.data-table--integrated .data-table__filters :deep(.integrated-query-group > .el-radio-group) { padding: 12px 20px 0; }
/* 筛选与操作共用一行,字段设置靠右,避免独占一行留白。 */
.data-table > .data-table__toolbar.has-inline-filters {
align-items: center;
flex-wrap: nowrap;
min-height: 0;
margin-bottom: var(--cc-list-query-gap, 16px);
padding: 16px 20px;
border-bottom: 1px solid var(--list-card-border, var(--cc-border));
background: var(--list-card-muted-bg, #f7f9fc);
}
.data-table__toolbar.has-inline-filters > .data-table__filters { flex: 1 1 0; min-width: 0; }
.data-table__toolbar.has-inline-filters > .data-table__filters :deep(.query-toolbar) { padding: 0; border: 0; background: transparent; }
.data-table__toolbar.has-inline-filters > .data-table__toolbar-actions { margin-left: auto; }
@media (max-width: 720px) {
.data-table > .data-table__toolbar.has-inline-filters { align-items: stretch; flex-direction: column; }
.data-table__toolbar.has-inline-filters > .data-table__filters { flex-basis: auto; }
}
</style>