fix: 更新搜索栏展示问题,以及销售订单的一些问题。

This commit is contained in:
c
2026-03-18 15:30:04 +08:00
parent 88aef44583
commit bf83b5e3b6
8 changed files with 181 additions and 85 deletions

View File

@@ -21,6 +21,11 @@ const props = defineProps({
});
const emit = defineEmits<Emits>();
const tableMainRef = ref<InstanceType<typeof TableMain> | null>(null);
const tableHeaderEl = ref<HTMLElement | null>(null);
const tableMainHostEl = ref<HTMLElement | null>(null);
const headerBaseHeight = ref(0);
const headerExtraOffset = ref(0);
const tableMainHeight = ref(0);
const page = ref(1);
const pageSize = ref(30);
const total = ref(0);
@@ -62,6 +67,15 @@ const handleExpandChange = (row: any, expandedRows: any[]) => {
emit("expand-change", row, expandedRows);
};
const recomputeTableHeight = () => {
if (!tableMainHostEl.value) return;
const top = tableMainHostEl.value.getBoundingClientRect().top;
// 预留一点底部空隙,避免贴边导致分页视觉上“出屏”
const paddingBottom = 12;
const h = Math.floor(window.innerHeight - top - paddingBottom);
tableMainHeight.value = Math.max(240, h);
};
defineExpose({
reload: loadData,
tableMainRef,
@@ -73,31 +87,59 @@ defineExpose({
},
});
onMounted(loadData);
onMounted(async () => {
await loadData();
await nextTick();
if (tableHeaderEl.value) {
headerBaseHeight.value = tableHeaderEl.value.getBoundingClientRect().height;
}
recomputeTableHeight();
if (tableHeaderEl.value && "ResizeObserver" in window) {
const ro = new ResizeObserver(entries => {
const h = entries[0]?.contentRect?.height ?? 0;
headerExtraOffset.value = Math.max(0, Math.round(h - headerBaseHeight.value));
// 表头换行会影响 TableMain 的 top需要同步重算可用高度
requestAnimationFrame(recomputeTableHeight);
});
ro.observe(tableHeaderEl.value);
onBeforeUnmount(() => ro.disconnect());
}
window.addEventListener("resize", recomputeTableHeight);
onBeforeUnmount(() => window.removeEventListener("resize", recomputeTableHeight));
});
</script>
<template>
<TableHeader
v-if="searchers !== undefined"
:searchers="searchers"
:tool-buttons="toolButtons"
v-model:searcher-params="searcherParams"
:search-click="searchClick"
>
<template #tool-button><slot name="tool-button"></slot></template>
</TableHeader>
<TableMain
ref="tableMainRef"
:data="tableData"
:total="total"
:update-page="updatePage"
v-model:page="page"
v-model:page-size="pageSize"
:expand-row-keys="expandRowKeys"
:row-key="rowKey"
@expand-change="handleExpandChange"
>
<template #columns><slot name="columns"></slot></template>
</TableMain>
<div ref="tableHeaderEl">
<TableHeader
v-if="searchers !== undefined"
:searchers="searchers"
:tool-buttons="toolButtons"
v-model:searcher-params="searcherParams"
:search-click="searchClick"
>
<template #tool-button><slot name="tool-button"></slot></template>
</TableHeader>
</div>
<div ref="tableMainHostEl">
<TableMain
ref="tableMainRef"
:data="tableData"
:total="total"
:update-page="updatePage"
:container-height="tableMainHeight"
:extra-offset="headerExtraOffset"
v-model:page="page"
v-model:page-size="pageSize"
:expand-row-keys="expandRowKeys"
:row-key="rowKey"
@expand-change="handleExpandChange"
>
<template #columns><slot name="columns"></slot></template>
</TableMain>
</div>
</template>
<style scoped>

View File

@@ -15,16 +15,19 @@ const searcherParams = defineModel<Record<string, string>>("searcherParams");
</script>
<template>
<div class="table-header">
<SearchBar
:searchers="searchers"
:search-click="searchClick"
v-model:searcher-params="searcherParams"
:reset-click="resetClick"
/>
<!-- <TableToolBar class="table-tool-bar" :tool-buttons="toolButtons" /> -->
<div>
<slot name="tool-button"></slot>
<div class="table-header__search">
<SearchBar
:searchers="searchers"
:search-click="searchClick"
v-model:searcher-params="searcherParams"
:reset-click="resetClick"
>
<template #after-actions>
<slot name="tool-button"></slot>
</template>
</SearchBar>
</div>
<!-- <TableToolBar class="table-tool-bar" :tool-buttons="toolButtons" /> -->
</div>
</template>
<style>
@@ -32,9 +35,15 @@ const searcherParams = defineModel<Record<string, string>>("searcherParams");
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: flex-start;
margin-bottom: 10px;
}
.table-header__search {
flex: 1 1 auto;
min-width: 260px;
}
.table-tool-bar {
padding-left: 10px;
}

View File

@@ -17,6 +17,16 @@ defineProps({
type: Function,
required: true,
},
// 由父组件按实际视口计算的可用高度px。传了则优先生效。
containerHeight: {
type: Number,
default: 0,
},
// 表头等区域换行导致高度变化时的额外偏移量px
extraOffset: {
type: Number,
default: 0,
},
// 新增:透传给 el-table 的展开行 key 列表
expandRowKeys: {
type: Array as PropType<(string | number)[]>,
@@ -49,7 +59,15 @@ defineExpose({
});
</script>
<template>
<div style="display: flex; flex-direction: column; height: calc(100vh - 157px); overflow: hidden">
<div
:style="{
display: 'flex',
flexDirection: 'column',
height:
containerHeight && containerHeight > 0 ? `${containerHeight}px` : `calc(100vh - ${157 + (extraOffset || 0)}px)`,
overflow: 'hidden',
}"
>
<div style="flex: 1; overflow: hidden">
<el-table
ref="tableRef"

View File

@@ -41,6 +41,7 @@ function reset() {
<el-date-picker
v-model="searcherParams[searcher.name]"
v-if="searcher.type === 'date-range-pick'"
class="searcher"
type="daterange"
range-separator="-"
:start-placeholder="$t('_prop.common.startdate')"
@@ -48,24 +49,43 @@ function reset() {
value-format="YYYY-MM-DD"
></el-date-picker>
</div>
<el-button v-if="searchClick !== undefined" :icon="Search" type="primary" @click="searchButtonClick">
{{ $t("_button.search") }}
</el-button>
<el-button v-if="searchClick !== undefined" :icon="Refresh" @click="reset">{{ $t("_button.reset") }}</el-button>
<div class="search-actions" v-if="searchClick !== undefined">
<el-button :icon="Search" type="primary" @click="searchButtonClick">
{{ $t("_button.search") }}
</el-button>
<el-button :icon="Refresh" @click="reset">{{ $t("_button.reset") }}</el-button>
<slot name="after-actions"></slot>
</div>
</div>
</template>
<style>
.search-bar {
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: flex-start;
padding-right: 20px;
}
.searcher-box {
padding-right: 5px;
padding-left: 5px;
box-sizing: border-box;
flex: 0 1 400px;
min-width: 240px;
max-width: 400px;
}
.searcher {
width: 400px;
box-sizing: border-box;
width: 100%;
}
.search-actions {
box-sizing: border-box;
display: flex;
flex: 0 0 auto;
gap: 10px;
align-items: center;
padding-left: 5px;
}
</style>