fix: 修复财务台账日期筛选无法选择 (#923)

This commit is contained in:
shanshi 2026-11-06 10:49:43 +08:00
parent d04ed7c94d
commit 8a06b2bcc2
2 changed files with 60 additions and 8 deletions

View File

@ -221,6 +221,13 @@
.ledger-field label { color:var(--vip-content-muted, #595959); font-size:.7rem; font-weight:600; }
.ledger-field input, .ledger-field select { height:2.15rem; padding:0 .6rem; border:1px solid var(--vip-border, #D8D2C7); border-radius:.45rem; background:#fff; color:var(--vip-content-ink, #171717); font:inherit; }
.ledger-field input:focus, .ledger-field select:focus { border-color:var(--vip-content-accent-dark, #856632); outline:none; box-shadow:0 0 0 3px rgba(133,102,50,.16); }
.ledger-date-control { display:flex; align-items:stretch; min-width:0; }
.ledger-date-control input { flex:1 1 auto; width:auto; min-width:0; border-radius:.45rem 0 0 .45rem; cursor:pointer; }
.ledger-date-control input:focus { position:relative; z-index:1; }
.ledger-date-control__button { display:inline-grid; flex:none; place-items:center; width:2.15rem; height:2.15rem; padding:0; border:1px solid var(--vip-content-accent-dark, #856632); border-left:0; border-radius:0 .45rem .45rem 0; background:var(--vip-content-accent-soft, #F7F0DE); color:var(--vip-content-accent-dark, #856632); cursor:pointer; }
.ledger-date-control__button:hover { background:#efe4c8; }
.ledger-date-control__button:focus-visible { position:relative; z-index:2; outline:none; box-shadow:0 0 0 3px rgba(133,102,50,.18); }
.ledger-date-control__button .material-icons-outlined { font-size:1rem; }
.ledger-field--account-filter { min-width:16rem; }
.ledger-filter-combobox { position:relative; display:flex; align-items:center; width:100%; }
.ledger-filter-combobox input { width:100%; padding-right:2.25rem; }
@ -1004,8 +1011,8 @@
<section class="ledger-panel" id="ledger-panel-flows" role="tabpanel" data-ledger-panel="flows" @if ($activeTab !== 'flows') hidden @endif>
<form class="ledger-toolbar" method="GET" action="{{ $tabUrl('flows') }}">
<input type="hidden" name="tab" value="flows">
<div class="ledger-field"><label for="flows-from">日期起</label><input id="flows-from" type="date" name="flows_from" value="{{ $flowPeriod['from'] ?? '' }}"></div>
<div class="ledger-field"><label for="flows-to">日期止</label><input id="flows-to" type="date" name="flows_to" value="{{ $flowPeriod['to'] ?? '' }}"></div>
<div class="ledger-field"><label for="flows-from">日期起</label><div class="ledger-date-control" data-ledger-date-control><input id="flows-from" type="date" name="flows_from" value="{{ $flowPeriod['from'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择每日流水开始日期" title="选择开始日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-field"><label for="flows-to">日期止</label><div class="ledger-date-control" data-ledger-date-control><input id="flows-to" type="date" name="flows_to" value="{{ $flowPeriod['to'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择每日流水结束日期" title="选择结束日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-field"><label for="flows-company">公司</label><input id="flows-company" name="flows_company" value="{{ request('flows_company') }}" placeholder="公司名称"></div>
<div class="ledger-field"><label for="flows-account">账户简称</label><input id="flows-account" name="flows_account" list="ledger-account-list" value="{{ request('flows_account') }}" placeholder="输入或选择"></div>
<div class="ledger-actions"><button class="ledger-btn primary" type="submit"><span class="material-icons-outlined">search</span>查询</button><a class="ledger-btn" href="{{ $tabUrl('flows') }}"><span class="material-icons-outlined">refresh</span>重置</a></div>
@ -1067,8 +1074,8 @@
</div>
</div>
<div class="ledger-field"><label for="txns-source">来源</label><select id="txns-source" name="txns_source"><option value="">全部</option>@foreach ($sourceLabels as $key => $label)<option value="{{ $key }}" @selected(request('txns_source') === $key)>{{ $label }}</option>@endforeach</select></div>
<div class="ledger-field"><label for="txns-from">日期起</label><input id="txns-from" type="date" name="txns_from" value="{{ $transactionPeriod['from'] ?? '' }}"></div>
<div class="ledger-field"><label for="txns-to">日期止</label><input id="txns-to" type="date" name="txns_to" value="{{ $transactionPeriod['to'] ?? '' }}"></div>
<div class="ledger-field"><label for="txns-from">日期起</label><div class="ledger-date-control" data-ledger-date-control><input id="txns-from" type="date" name="txns_from" value="{{ $transactionPeriod['from'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择动账明细开始日期" title="选择开始日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-field"><label for="txns-to">日期止</label><div class="ledger-date-control" data-ledger-date-control><input id="txns-to" type="date" name="txns_to" value="{{ $transactionPeriod['to'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择动账明细结束日期" title="选择结束日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-actions"><button class="ledger-btn primary" type="submit"><span class="material-icons-outlined">search</span>查询</button><a class="ledger-btn" href="{{ $transactionViewResetUrl }}"><span class="material-icons-outlined">refresh</span>重置</a></div>
</form>
<div class="ledger-summary" data-ledger-transaction-summary><div class="ledger-summary__item"><span>明细笔数</span><b data-ledger-transaction-summary-count>{{ number_format((int) ($ledgerTransactionSummary['count'] ?? 0)) }}</b></div><div class="ledger-summary__item"><span>收入合计</span><b data-ledger-transaction-summary-income>{{ $money($ledgerTransactionSummary['income'] ?? 0) }}</b></div><div class="ledger-summary__item"><span>支出合计</span><b data-ledger-transaction-summary-expense>{{ $money($ledgerTransactionSummary['expense'] ?? 0) }}</b></div><div class="ledger-summary__item"><span>净额</span><b data-ledger-transaction-summary-net>{{ $money(($ledgerTransactionSummary['income'] ?? 0) - ($ledgerTransactionSummary['expense'] ?? 0)) }}</b></div></div>
@ -1208,8 +1215,8 @@
</div>
<form class="ledger-toolbar" method="GET" action="{{ $tabUrl('mapping') }}">
<input type="hidden" name="tab" value="mapping">
<div class="ledger-field"><label for="mapping-from">日期起</label><input id="mapping-from" type="date" name="mapping_from" value="{{ $mappingPeriod['from'] ?? '' }}"></div>
<div class="ledger-field"><label for="mapping-to">日期止</label><input id="mapping-to" type="date" name="mapping_to" value="{{ $mappingPeriod['to'] ?? '' }}"></div>
<div class="ledger-field"><label for="mapping-from">日期起</label><div class="ledger-date-control" data-ledger-date-control><input id="mapping-from" type="date" name="mapping_from" value="{{ $mappingPeriod['from'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择账户映射开始日期" title="选择开始日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-field"><label for="mapping-to">日期止</label><div class="ledger-date-control" data-ledger-date-control><input id="mapping-to" type="date" name="mapping_to" value="{{ $mappingPeriod['to'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择账户映射结束日期" title="选择结束日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-field"><label for="mapping-source">来源</label><select id="mapping-source" name="mapping_source"><option value="">全部</option>@foreach (($mapping['sources'] ?? []) as $source)<option value="{{ $source }}" @selected(request('mapping_source') === $source)>{{ $sourceLabels[$source] ?? $source }}</option>@endforeach</select></div>
<div class="ledger-field" style="min-width:15rem"><label for="mapping-q">原始值/账户简称</label><input id="mapping-q" name="mapping_q" value="{{ request('mapping_q') }}" placeholder="搜索"></div>
<div class="ledger-field" style="min-width:auto"><label>&nbsp;</label><label style="display:flex;align-items:center;gap:.4rem;height:2.15rem"><input type="checkbox" name="mapping_unmapped" value="1" @checked(request()->boolean('mapping_unmapped'))> 只看未映射</label></div>
@ -1260,8 +1267,8 @@
<section class="ledger-panel" id="ledger-panel-sources" role="tabpanel" data-ledger-panel="sources" @if ($activeTab !== 'sources') hidden @endif>
<form class="ledger-toolbar" method="GET" action="{{ $tabUrl('sources') }}">
<input type="hidden" name="tab" value="sources">
<div class="ledger-field"><label for="sources-from">日期起</label><input id="sources-from" type="date" name="sources_from" value="{{ $sourcePeriod['from'] ?? '' }}"></div>
<div class="ledger-field"><label for="sources-to">日期止</label><input id="sources-to" type="date" name="sources_to" value="{{ $sourcePeriod['to'] ?? '' }}"></div>
<div class="ledger-field"><label for="sources-from">日期起</label><div class="ledger-date-control" data-ledger-date-control><input id="sources-from" type="date" name="sources_from" value="{{ $sourcePeriod['from'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择数据来源开始日期" title="选择开始日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-field"><label for="sources-to">日期止</label><div class="ledger-date-control" data-ledger-date-control><input id="sources-to" type="date" name="sources_to" value="{{ $sourcePeriod['to'] ?? '' }}" data-ledger-date-input><button class="ledger-date-control__button" type="button" aria-label="选择数据来源结束日期" title="选择结束日期" data-ledger-date-picker><span class="material-icons-outlined" aria-hidden="true">calendar_today</span></button></div></div>
<div class="ledger-actions"><button class="ledger-btn primary" type="submit"><span class="material-icons-outlined">search</span>查询</button><a class="ledger-btn" href="{{ $tabUrl('sources') }}"><span class="material-icons-outlined">refresh</span>重置</a></div>
</form>
<div class="ledger-note" style="line-height:1.8">
@ -1622,6 +1629,23 @@
}
};
const openLedgerDatePicker = (input) => {
if (!input) return;
input.focus({ preventScroll: true });
if (typeof input.showPicker === 'function') {
try {
input.showPicker();
} catch (error) { /* 已打开时不重复触发 */ }
}
};
page.querySelectorAll('[data-ledger-date-control]').forEach((control) => {
const input = control.querySelector('[data-ledger-date-input]');
const button = control.querySelector('[data-ledger-date-picker]');
if (!input || !button) return;
input.addEventListener('click', () => openLedgerDatePicker(input));
button.addEventListener('click', () => openLedgerDatePicker(input));
});
const manualTransactionTrigger = page.querySelector('[data-ledger-manual-trigger]');
const manualTransactionDraft = page.querySelector('[data-ledger-manual-draft]');
const manualTransactionForm = page.querySelector('[data-ledger-manual-form]');

View File

@ -155,6 +155,34 @@ class FinanceLedgerHeaderControlsTest extends FeatureTestCase
}
}
public function test_financial_ledger_date_filters_have_calendar_buttons(): void
{
$html = $this->loginAs()->get($this->pageUrl())->assertOk()->getContent();
$this->assertSame(8, preg_match_all('/<button\b[^>]*data-ledger-date-picker/', $html));
foreach ([
'flows-from',
'flows-to',
'txns-from',
'txns-to',
'mapping-from',
'mapping-to',
'sources-from',
'sources-to',
] as $inputId) {
$this->assertSame(
1,
preg_match(
'/<div class="ledger-date-control" data-ledger-date-control><input id="'
. preg_quote($inputId, '/')
. '"[^>]*data-ledger-date-input><button[^>]*data-ledger-date-picker>/',
$html,
),
$inputId . ' 应提供可点击的日历按钮',
);
}
}
public function test_shop_ledger_header_labels_and_column_order(): void
{
$html = $this->loginAs()->get($this->pageUrl())->assertOk()->getContent();