This commit is contained in:
2026-08-04 21:11:56 +08:00
parent 5cb1ca307d
commit db8774627e
2 changed files with 23 additions and 14 deletions
@@ -180,11 +180,14 @@ describe('InboundOrdersView', () => {
const tabButtons = tabList.findAll('[role="tab"]')
const queryToolbar = wrapper.findComponent(QueryToolbar)
expect(tabList.attributes('aria-label')).toBe('入库单处理状态')
expect(tabList.element.parentElement?.classList.contains('table-toolbar')).toBe(true)
expect(tabList.element.closest('.table-toolbar')).not.toBeNull()
expect(queryToolbar.element.compareDocumentPosition(tabList.element) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
expect(tabButtons).toHaveLength(5)
expect(wrapper.find('.table-toolbar').text()).toContain('共 1 条 · 所属企业 全部客户')
expect(wrapper.find('.table-toolbar').text()).toContain('刷新')
const toolbarRows = wrapper.find('.table-toolbar').element.children
expect(toolbarRows[0].classList.contains('table-tabs-row')).toBe(true)
expect(toolbarRows[1].classList.contains('table-action-row')).toBe(true)
expect(wrapper.find('.table-action-row').text()).toContain('共 1 条 · 所属企业 全部客户')
expect(wrapper.find('.table-action-buttons').text()).toContain('刷新')
expect(wrapper.text()).not.toContain('全部入库单')
expect(tabButtons[0].attributes('aria-selected')).toBe('true')
expect(tabButtons[0].attributes('tabindex')).toBe('0')
@@ -387,12 +387,16 @@ onBeforeUnmount(() => { disposed = true; loadRequestId += 1; detailRequestId +=
<LoadErrorState v-if="loadError" class="inbound-load-error" :message="loadError.message" title="入库单暂时无法加载" @retry="loadInbounds"><template #details><ApiErrorMeta :details="loadError" /></template></LoadErrorState>
<section v-else class="surface-panel table-panel" :aria-busy="loading">
<header class="table-toolbar">
<nav class="inbound-tabs" role="tablist" aria-label="入库单处理状态">
<button v-for="(item, index) in tabs" :key="item.value || 'all'" type="button" role="tab" class="inbound-tab" :class="{ 'is-active': tab === item.value }" :aria-selected="tab === item.value" :tabindex="tab === item.value ? 0 : -1" :title="item.description" @click="tab = item.value" @keydown="handleTabKeydown($event, index)">{{ item.label }}</button>
</nav>
<div class="table-toolbar-actions">
<div class="table-tabs-row">
<nav class="inbound-tabs" role="tablist" aria-label="入库单处理状态">
<button v-for="(item, index) in tabs" :key="item.value || 'all'" type="button" role="tab" class="inbound-tab" :class="{ 'is-active': tab === item.value }" :aria-selected="tab === item.value" :tabindex="tab === item.value ? 0 : -1" :title="item.description" @click="tab = item.value" @keydown="handleTabKeydown($event, index)">{{ item.label }}</button>
</nav>
</div>
<div class="table-action-row">
<span class="result-summary">共 {{ result.total }} 条 · 所属企业 {{ selectedCustomerName }}</span>
<el-button :loading="loading" @click="loadInbounds"><RefreshCw :size="16" />刷新</el-button>
<div class="table-action-buttons">
<el-button :loading="loading" @click="loadInbounds"><RefreshCw :size="16" />刷新</el-button>
</div>
</div>
</header>
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="result.records" :columns="columns" :loading="loading" :total="result.total" :page-sizes="[20, 50, 100]" row-key="id" :empty-text="listEmptyText" aria-label="入库单列表">
@@ -447,7 +451,7 @@ onBeforeUnmount(() => { disposed = true; loadRequestId += 1; detailRequestId +=
<style scoped>
.inbound-orders-page { min-width: 0; }
.inbound-tabs { display: flex; max-width: 100%; min-width: 0; overflow-x: auto; padding: 4px; border: 1px solid var(--cc-border); border-radius: 8px; background: #f7f9fc; scrollbar-width: none; }
.inbound-tabs { display: flex; width: max-content; max-width: 100%; min-width: 0; overflow-x: auto; padding: 4px; border: 1px solid var(--cc-border); border-radius: 8px; background: #f7f9fc; scrollbar-width: none; }
.inbound-tabs::-webkit-scrollbar { display: none; }
.inbound-tab { min-height: 44px; flex: 0 0 auto; padding: 8px 18px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--cc-muted); cursor: pointer; font-size: 13px; line-height: 1.4; white-space: nowrap; transition: background-color .16s ease, border-color .16s ease, color .16s ease, box-shadow .16s ease; }
.inbound-tab:hover { background: #fff; color: var(--cc-primary); }
@@ -457,10 +461,12 @@ onBeforeUnmount(() => { disposed = true; loadRequestId += 1; detailRequestId +=
.inbound-query-toolbar { border-radius: 8px; }
.row-actions { display: flex; align-items: center; gap: 2px; white-space: nowrap; }
.row-actions :deep(.el-button) { margin-left: 0; }
.table-toolbar { display: flex; min-width: 0; align-items: center; justify-content: space-between; gap: 16px; min-height: 68px; padding: 10px 14px; border-bottom: 1px solid var(--cc-border); }
.table-toolbar-actions { display: flex; flex: 0 0 auto; align-items: center; gap: 14px; }
.table-toolbar { display: grid; min-width: 0; border-bottom: 1px solid var(--cc-border); }
.table-tabs-row { min-width: 0; padding: 10px 14px; }
.table-action-row { display: flex; min-width: 0; min-height: 56px; align-items: center; justify-content: space-between; gap: 16px; padding: 8px 14px; border-top: 1px solid var(--cc-border); background: #fbfcfe; }
.table-action-buttons { display: flex; min-width: 0; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.result-summary { color: var(--cc-muted); font-size: 12px; white-space: nowrap; }
.table-toolbar :deep(.el-button) { min-height: 40px; margin-left: 0; }
.table-action-buttons :deep(.el-button) { min-height: 40px; margin-left: 0; }
.primary-cell, .status-stack { display: grid; min-width: 0; justify-items: start; gap: 4px; }
.primary-cell strong, .primary-cell span, .status-stack span, .status-stack small { overflow-wrap: anywhere; }
.primary-cell span, .status-stack span, .status-stack small { color: var(--cc-muted); font-size: 12px; }
@@ -469,6 +475,6 @@ onBeforeUnmount(() => { disposed = true; loadRequestId += 1; detailRequestId +=
.detail-error strong { color: var(--cc-danger); font-size: 15px; }
.detail-error p { margin: 7px 0; color: var(--cc-text); font-size: 13px; }
.detail-error :deep(.el-button) { margin-top: 14px; }
@media (max-width: 900px) { .table-toolbar { align-items: stretch; flex-direction: column; } .inbound-tabs { width: 100%; } .table-toolbar-actions { justify-content: space-between; } }
@media (max-width: 720px) { .inbound-tab { padding-inline: 14px; } .table-toolbar { padding: 10px; } .table-toolbar-actions { gap: 10px; } .result-summary { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .table-toolbar :deep(.el-button) { min-height: 44px; } }
@media (max-width: 900px) { .inbound-tabs { width: 100%; } }
@media (max-width: 720px) { .inbound-tab { padding-inline: 14px; } .table-tabs-row { padding: 10px; } .table-action-row { min-height: 0; align-items: stretch; flex-direction: column; gap: 10px; padding: 10px; } .table-action-buttons { justify-content: flex-start; } .result-summary { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .table-action-buttons :deep(.el-button) { min-height: 44px; } }
</style>