style: compact order profit fixed columns

This commit is contained in:
renshen 2026-10-30 15:16:09 +08:00
parent e98bcfc409
commit 40fea77d77
2 changed files with 93 additions and 21 deletions

View File

@ -59,11 +59,16 @@
'matched_bill_fee', 'source_row_count',
]);
$fixedColumns = [
'shop_name' => '0',
'online_order_no' => '16rem',
'internal_order_no' => '26rem',
'shop_name' => ['left' => '0rem', 'width' => '13rem'],
'online_order_no' => ['left' => '13rem', 'width' => '9rem'],
'internal_order_no' => ['left' => '22rem', 'width' => '6rem'],
'detail' => ['left' => '28rem', 'width' => '4.75rem'],
];
$detailFixedLeft = '34rem';
$fixedColumnStyle = static fn (string $field): string => sprintf(
'left: %1$s; width: %2$s; min-width: %2$s; max-width: %2$s;',
$fixedColumns[$field]['left'],
$fixedColumns[$field]['width'],
);
@endphp
<div class="upstream-data-page upstream-data-page--spaced">
@ -71,17 +76,7 @@
<style>
.order-profit-table { min-width: 290rem; }
.order-profit-table [data-field="shop_name"],
.order-profit-table [data-export-field="shop_name"] { width: 16rem; min-width: 16rem; max-width: 16rem; }
.order-profit-table [data-field="online_order_no"],
.order-profit-table [data-export-field="online_order_no"] { width: 10rem; min-width: 10rem; max-width: 10rem; }
.order-profit-table [data-field="internal_order_no"],
.order-profit-table [data-export-field="internal_order_no"] { width: 8rem; min-width: 8rem; max-width: 8rem; }
.order-profit-table [data-field="detail"],
.order-profit-table [data-export-field="detail"] {
width: 6rem;
min-width: 6rem;
max-width: 6rem;
.order-profit-table [data-order-profit-fixed-key="detail"] {
box-shadow: 2px 0 0 var(--vip-border, #d8d2c7);
}
.order-profit-note {
@ -183,14 +178,16 @@
@endif
<div class="upstream-data-table-scroll">
<table id="order-profit-table" class="upstream-data-table order-profit-table"
aria-label="订单利润" data-finance-table-name="订单利润">
aria-label="订单利润" data-finance-table-name="订单利润"
data-order-profit-autofit-fixed>
<thead>
<tr>
@foreach ($columns as $field => $header)
<th data-field="{{ $field }}"
@if (isset($fixedColumns[$field]))
data-finance-fixed="true"
style="left: {{ $fixedColumns[$field] }};"
data-order-profit-fixed-key="{{ $field }}"
style="{{ $fixedColumnStyle($field) }}"
@endif
@class([
'is-number' => isset($numberFields[$field]),
@ -198,7 +195,8 @@
])>{{ $header }}</th>
@if ($field === 'internal_order_no')
<th data-field="detail" data-finance-fixed="true"
style="left: {{ $detailFixedLeft }};">明细</th>
data-order-profit-fixed-key="detail"
style="{{ $fixedColumnStyle('detail') }}">明细</th>
@endif
@endforeach
</tr>
@ -217,7 +215,8 @@
data-export-field="{{ $field }}"
@if (isset($fixedColumns[$field]))
data-finance-fixed="true"
style="left: {{ $fixedColumns[$field] }};"
data-order-profit-fixed-key="{{ $field }}"
style="{{ $fixedColumnStyle($field) }}"
@endif
@class([
'is-number' => isset($numberFields[$field]),
@ -233,7 +232,8 @@
</td>
@if ($field === 'internal_order_no')
<td data-export-field="detail" data-finance-fixed="true"
style="left: {{ $detailFixedLeft }};">
data-order-profit-fixed-key="detail"
style="{{ $fixedColumnStyle('detail') }}">
<button type="button" class="order-profit-detail-button"
data-order-profit-detail="{{ $detailId }}"
aria-expanded="false">查看</button>
@ -321,6 +321,76 @@
<script>
(() => {
const fitOrderProfitFixedColumns = () => {
const table = document.querySelector('table[data-order-profit-autofit-fixed]');
if (!table) return;
const cells = Array.from(table.querySelectorAll(
'thead th[data-order-profit-fixed-key], '
+ 'tbody > tr:not(.order-profit-detail-row):not(.is-empty) > td[data-order-profit-fixed-key]',
));
const widths = new Map();
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
const minimumWidths = {
shop_name: rootFontSize * 8,
online_order_no: rootFontSize * 8,
internal_order_no: rootFontSize * 6,
detail: rootFontSize * 4.75,
};
cells.forEach((cell) => {
const key = cell.dataset.orderProfitFixedKey;
if (!key) return;
const style = getComputedStyle(cell);
const horizontalSpacing = [
style.paddingLeft,
style.paddingRight,
style.borderLeftWidth,
style.borderRightWidth,
].reduce((total, value) => total + (parseFloat(value) || 0), 0);
const detailButton = cell.querySelector('.order-profit-detail-button');
let contentWidth = 0;
if (detailButton) {
contentWidth = detailButton.getBoundingClientRect().width;
} else {
const range = document.createRange();
range.selectNodeContents(cell);
contentWidth = range.getBoundingClientRect().width;
}
const measuredWidth = Math.ceil(contentWidth + horizontalSpacing + 2);
widths.set(key, Math.max(widths.get(key) || 0, measuredWidth, minimumWidths[key] || 0));
});
let left = 0;
const orderedKeys = Array.from(table.tHead?.rows?.[0]?.cells || [])
.map((cell) => cell.dataset.orderProfitFixedKey)
.filter(Boolean);
orderedKeys.forEach((key) => {
const width = widths.get(key);
if (!width) return;
cells
.filter((cell) => cell.dataset.orderProfitFixedKey === key)
.forEach((cell) => {
cell.style.width = `${width}px`;
cell.style.minWidth = `${width}px`;
cell.style.maxWidth = `${width}px`;
cell.style.left = `${left}px`;
});
left += width;
});
};
const scheduleFixedColumnFit = () => {
window.requestAnimationFrame(() => window.requestAnimationFrame(fitOrderProfitFixedColumns));
};
scheduleFixedColumnFit();
document.fonts?.ready.then(scheduleFixedColumnFit).catch(() => {});
window.addEventListener('resize', scheduleFixedColumnFit, { passive: true });
document.querySelectorAll('[data-order-profit-detail]').forEach((button) => {
if (button.dataset.bound === 'true') return;
button.dataset.bound = 'true';

View File

@ -120,7 +120,9 @@ class OrderProfitPageTest extends FeatureTestCase
->assertSeeText('743208893')
->assertSeeTextInOrder(['内部单号', '明细', '订单时间'])
->assertSee('data-finance-fixed="true"', false)
->assertSee('style="left: 34rem;"', false)
->assertSee('data-order-profit-autofit-fixed', false)
->assertSee('data-order-profit-fixed-key="detail"', false)
->assertSee('style="left: 28rem; width: 4.75rem; min-width: 4.75rem; max-width: 4.75rem;"', false)
->assertSee('data-order-profit-detail', false)
->assertSee('data-finance-table-name="订单利润"', false)
->assertSee('is-column-hidden', false)