diff --git a/frontend/src/components/common/DataTable.vue b/frontend/src/components/common/DataTable.vue index 2dae2d4c..52029119 100644 --- a/frontend/src/components/common/DataTable.vue +++ b/frontend/src/components/common/DataTable.vue @@ -15,7 +15,8 @@ :key="column.key" scope="col" :class="[ - 'sticky-header-cell px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-dark-400', + 'sticky-header-cell py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-dark-400', + getAdaptivePaddingClass(), { 'cursor-pointer hover:bg-gray-100 dark:hover:bg-dark-700': column.sortable }, getStickyColumnClass(column, index) ]" @@ -81,7 +82,7 @@ - +
@@ -92,7 +93,7 @@
@@ -128,7 +129,8 @@ v-for="(column, colIndex) in columns" :key="column.key" :class="[ - 'whitespace-nowrap px-6 py-4 text-sm text-gray-900 dark:text-gray-100', + 'whitespace-nowrap py-4 text-sm text-gray-900 dark:text-gray-100', + getAdaptivePaddingClass(), getStickyColumnClass(column, colIndex) ]" > @@ -165,24 +167,46 @@ const checkScrollable = () => { const checkActionsColumnWidth = () => { if (!tableWrapperRef.value) return - // 查找操作列的表头单元格 - const actionsHeader = tableWrapperRef.value.querySelector('th:has(button[title*="Expand"], button[title*="展开"])') - if (!actionsHeader) return - // 查找第一行的操作列单元格 const firstActionCell = tableWrapperRef.value.querySelector('tbody tr:first-child td:last-child') if (!firstActionCell) return - // 获取操作列内容的实际宽度 - const actionsContent = firstActionCell.querySelector('div') - if (!actionsContent) return + // 查找操作列内容的容器div + const actionsContainer = firstActionCell.querySelector('div') + if (!actionsContainer) return - // 比较内容宽度和单元格宽度 - const contentWidth = actionsContent.scrollWidth - const cellWidth = (firstActionCell as HTMLElement).clientWidth + // 临时展开以测量完整宽度 + const wasExpanded = actionsExpanded.value + actionsExpanded.value = true - // 如果内容宽度超过单元格宽度,说明需要展开 - actionsColumnNeedsExpanding.value = contentWidth > cellWidth + // 等待DOM更新 + nextTick(() => { + // 测量所有按钮的总宽度 + const buttons = actionsContainer.querySelectorAll('button') + if (buttons.length <= 2) { + actionsColumnNeedsExpanding.value = false + actionsExpanded.value = wasExpanded + return + } + + // 计算所有按钮的总宽度(包括gap) + let totalWidth = 0 + buttons.forEach((btn, index) => { + totalWidth += (btn as HTMLElement).offsetWidth + if (index < buttons.length - 1) { + totalWidth += 4 // gap-1 = 4px + } + }) + + // 获取单元格可用宽度(减去padding) + const cellWidth = (firstActionCell as HTMLElement).clientWidth - 32 // 减去左右padding + + // 如果总宽度超过可用宽度,需要展开功能 + actionsColumnNeedsExpanding.value = totalWidth > cellWidth + + // 恢复原来的展开状态 + actionsExpanded.value = wasExpanded + }) } // 监听尺寸变化 @@ -219,6 +243,7 @@ interface Props { stickyFirstColumn?: boolean stickyActionsColumn?: boolean expandableActions?: boolean + actionsCount?: number // 操作按钮总数,用于判断是否需要展开功能 } const props = withDefaults(defineProps(), { @@ -268,6 +293,12 @@ const sortedData = computed(() => { // 检查是否有可展开的操作列 const hasExpandableActions = computed(() => { + // 如果明确指定了actionsCount,使用它来判断 + if (props.actionsCount !== undefined) { + return props.expandableActions && props.columns.some((col) => col.key === 'actions') && props.actionsCount > 2 + } + + // 否则使用原来的检测逻辑 return ( props.expandableActions && props.columns.some((col) => col.key === 'actions') && @@ -312,6 +343,22 @@ const getStickyColumnClass = (column: Column, index: number) => { return classes.join(' ') } + +// 根据列数自适应调整内边距 +const getAdaptivePaddingClass = () => { + const columnCount = props.columns.length + + // 列数越多,内边距越小 + if (columnCount >= 10) { + return 'px-2' // 8px + } else if (columnCount >= 7) { + return 'px-3' // 12px + } else if (columnCount >= 5) { + return 'px-4' // 16px + } else { + return 'px-6' // 24px (原始值) + } +}