fix: 营销账户账单启用日期范围筛选 #674
@ -65,10 +65,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setupBillDatePickers(scope) {
|
||||
if (!scope || !window.CaiWuDatePicker) {
|
||||
return;
|
||||
}
|
||||
|
||||
scope.querySelectorAll('[data-marketing-bill-date-filter]').forEach((form) => {
|
||||
window.CaiWuDatePicker.setup(form);
|
||||
|
||||
const from = form.elements.namedItem('from');
|
||||
const to = form.elements.namedItem('to');
|
||||
if (from && to) {
|
||||
[from, to].forEach((input) => {
|
||||
input.addEventListener('change', () => to.setCustomValidity(''));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initialiseInsertedContent(workspace) {
|
||||
if (window.Alpine && typeof window.Alpine.initTree === 'function') {
|
||||
window.Alpine.initTree(workspace);
|
||||
}
|
||||
|
||||
setupBillDatePickers(workspace);
|
||||
}
|
||||
|
||||
async function navigate(url, options) {
|
||||
@ -176,6 +196,27 @@
|
||||
}, true);
|
||||
|
||||
document.addEventListener('submit', (event) => {
|
||||
const workspace = currentWorkspace();
|
||||
const dateFilter = workspace
|
||||
? event.target.closest(`${workspaceSelector} [data-marketing-bill-date-filter]`)
|
||||
: null;
|
||||
|
||||
if (dateFilter) {
|
||||
const from = dateFilter.elements.namedItem('from');
|
||||
const to = dateFilter.elements.namedItem('to');
|
||||
if (from && to) {
|
||||
to.setCustomValidity('');
|
||||
if (String(from.value || '') !== ''
|
||||
&& String(to.value || '') !== ''
|
||||
&& String(from.value) > String(to.value)) {
|
||||
event.preventDefault();
|
||||
to.setCustomValidity('结束日期不能早于开始日期');
|
||||
to.reportValidity();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const form = event.target.closest(`${workspaceSelector} [data-jd-wallet-filter]`);
|
||||
|
||||
if (!form) {
|
||||
@ -198,6 +239,12 @@
|
||||
navigate(target.href, { focus: '#jd-filter-store' });
|
||||
}, true);
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => setupBillDatePickers(document));
|
||||
} else {
|
||||
setupBillDatePickers(document);
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', () => {
|
||||
if (currentWorkspace() && isSupportedUrl(window.location.href)) {
|
||||
navigate(window.location.href, { pushState: false });
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<form method="GET" action="{{ request()->url() }}" class="mb-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3">
|
||||
<form method="GET" action="{{ request()->url() }}" class="mb-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3" data-marketing-bill-date-filter>
|
||||
<div class="flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
<label for="alibaba-filter-shop" class="mb-1 block text-xs font-medium text-gray-600">店铺名称</label>
|
||||
@ -89,14 +89,12 @@
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="alibaba-filter-from" class="mb-1 block text-xs font-medium text-gray-600">交易时间 起</label>
|
||||
<input id="alibaba-filter-from" type="date" name="from" value="{{ $filters['from'] ?? '' }}" class="alibaba-bill-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="alibaba-filter-to" class="mb-1 block text-xs font-medium text-gray-600">交易时间 止</label>
|
||||
<input id="alibaba-filter-to" type="date" name="to" value="{{ $filters['to'] ?? '' }}" class="alibaba-bill-control" />
|
||||
</div>
|
||||
@include('business.pages.partials.marketing-bill-date-range', [
|
||||
'idPrefix' => 'alibaba-filter',
|
||||
'fieldLabel' => '交易时间',
|
||||
'fromValue' => $filters['from'] ?? '',
|
||||
'toValue' => $filters['to'] ?? '',
|
||||
])
|
||||
<div class="flex items-end gap-2">
|
||||
<button type="submit" class="alibaba-bill-primary"><span class="material-icons text-base" aria-hidden="true">search</span>查询</button>
|
||||
<a href="{{ request()->url() }}" class="alibaba-bill-secondary"><span class="material-icons text-base" aria-hidden="true">clear</span>清除</a>
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="GET" action="{{ $currentUrl }}" class="jd-wallet-filter" data-jd-wallet-filter>
|
||||
<form method="GET" action="{{ $currentUrl }}" class="jd-wallet-filter" data-jd-wallet-filter data-marketing-bill-date-filter>
|
||||
<input type="hidden" name="jd_ledger" value="{{ $ledger }}" />
|
||||
<div class="flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
@ -110,14 +110,12 @@
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="jd-filter-from" class="mb-1 block text-xs font-medium text-gray-600">账单日期 起</label>
|
||||
<input id="jd-filter-from" type="date" name="from" value="{{ $filters['from'] ?? '' }}" class="jd-wallet-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="jd-filter-to" class="mb-1 block text-xs font-medium text-gray-600">账单日期 止</label>
|
||||
<input id="jd-filter-to" type="date" name="to" value="{{ $filters['to'] ?? '' }}" class="jd-wallet-control" />
|
||||
</div>
|
||||
@include('business.pages.partials.marketing-bill-date-range', [
|
||||
'idPrefix' => 'jd-filter',
|
||||
'fieldLabel' => '账单日期',
|
||||
'fromValue' => $filters['from'] ?? '',
|
||||
'toValue' => $filters['to'] ?? '',
|
||||
])
|
||||
<div class="flex items-end gap-2">
|
||||
<button type="submit" class="jd-wallet-button jd-wallet-button-primary"><span class="material-icons text-base" aria-hidden="true">search</span>查询</button>
|
||||
<a href="{{ $currentUrl }}?jd_ledger={{ $ledger }}" data-jd-wallet-navigation class="jd-wallet-button jd-wallet-button-secondary"><span class="material-icons text-base" aria-hidden="true">clear</span>清除</a>
|
||||
|
||||
@ -96,7 +96,8 @@
|
||||
], static fn ($value) => $value !== '');
|
||||
@endphp
|
||||
<form method="GET" action="{{ request()->url() }}"
|
||||
class="mb-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3">
|
||||
class="mb-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3"
|
||||
data-marketing-bill-date-filter>
|
||||
<div class="flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
<label for="pdd-filter-store" class="mb-1 block text-xs font-medium text-gray-600">店铺名称</label>
|
||||
@ -117,16 +118,12 @@
|
||||
<option value="expense" @selected($currentFlowType === 'expense')>支出</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="pdd-filter-from" class="mb-1 block text-xs font-medium text-gray-600">费用时间 起</label>
|
||||
<input id="pdd-filter-from" type="date" name="from" value="{{ $currentFrom }}"
|
||||
class="bill-filter-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="pdd-filter-to" class="mb-1 block text-xs font-medium text-gray-600">费用时间 止</label>
|
||||
<input id="pdd-filter-to" type="date" name="to" value="{{ $currentTo }}"
|
||||
class="bill-filter-control" />
|
||||
</div>
|
||||
@include('business.pages.partials.marketing-bill-date-range', [
|
||||
'idPrefix' => 'pdd-filter',
|
||||
'fieldLabel' => '费用时间',
|
||||
'fromValue' => $currentFrom,
|
||||
'toValue' => $currentTo,
|
||||
])
|
||||
<div class="flex items-end gap-2">
|
||||
<button type="submit"
|
||||
class="bill-filter-primary">
|
||||
|
||||
@ -88,7 +88,8 @@
|
||||
], static fn ($value) => $value !== '');
|
||||
@endphp
|
||||
<form method="GET" action="{{ request()->url() }}"
|
||||
class="mb-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3">
|
||||
class="mb-4 rounded-lg border border-gray-200 bg-gray-50 px-4 py-3"
|
||||
data-marketing-bill-date-filter>
|
||||
<div class="flex flex-wrap items-end gap-4">
|
||||
<div>
|
||||
<label for="tb-filter-store" class="mb-1 block text-xs font-medium text-gray-600">店铺名称</label>
|
||||
@ -109,16 +110,12 @@
|
||||
<option value="expense" @selected($currentFlowType === 'expense')>支出</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="tb-filter-from" class="mb-1 block text-xs font-medium text-gray-600">交易日期 起</label>
|
||||
<input id="tb-filter-from" type="date" name="from" value="{{ $currentFrom }}"
|
||||
class="bill-filter-control" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="tb-filter-to" class="mb-1 block text-xs font-medium text-gray-600">交易日期 止</label>
|
||||
<input id="tb-filter-to" type="date" name="to" value="{{ $currentTo }}"
|
||||
class="bill-filter-control" />
|
||||
</div>
|
||||
@include('business.pages.partials.marketing-bill-date-range', [
|
||||
'idPrefix' => 'tb-filter',
|
||||
'fieldLabel' => '交易日期',
|
||||
'fromValue' => $currentFrom,
|
||||
'toValue' => $currentTo,
|
||||
])
|
||||
<div class="flex items-end gap-2">
|
||||
<button type="submit" class="bill-filter-primary">
|
||||
<span class="material-icons text-base" aria-hidden="true">search</span>
|
||||
|
||||
@ -192,6 +192,8 @@
|
||||
}
|
||||
|
||||
function setupDatePicker(picker) {
|
||||
if (picker.dataset.datePickerReady === 'true') { return; }
|
||||
picker.dataset.datePickerReady = 'true';
|
||||
var input = picker.querySelector('[data-date-input]');
|
||||
var panel = picker.querySelector('[data-date-calendar]');
|
||||
var toggle = picker.querySelector('[data-date-toggle]');
|
||||
|
||||
@ -0,0 +1,91 @@
|
||||
@php
|
||||
$idPrefix = $idPrefix ?? 'marketing-bill';
|
||||
$fromId = $idPrefix . '-from';
|
||||
$toId = $idPrefix . '-to';
|
||||
$fromName = $fromName ?? 'from';
|
||||
$toName = $toName ?? 'to';
|
||||
$fieldLabel = $fieldLabel ?? '交易日期';
|
||||
$fromLabel = $fromLabel ?? ($fieldLabel . ' 起');
|
||||
$toLabel = $toLabel ?? ($fieldLabel . ' 止');
|
||||
$fromValue = (string) ($fromValue ?? '');
|
||||
$toValue = (string) ($toValue ?? '');
|
||||
@endphp
|
||||
|
||||
<style>
|
||||
.marketing-bill-date-range {
|
||||
flex: 1 1 22rem;
|
||||
min-width: 18rem;
|
||||
}
|
||||
|
||||
.marketing-bill-date-range__label {
|
||||
display: block;
|
||||
margin-bottom: 0.25rem;
|
||||
color: #595959;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.marketing-bill-date-range .upstream-data-date-range {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.marketing-bill-date-range .upstream-data-date input {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
border: 1px solid var(--vip-border, #d8d2c7);
|
||||
background: #ffffff;
|
||||
color: #171717;
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.marketing-bill-date-range .upstream-data-date__pick {
|
||||
height: 34px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="marketing-bill-date-range">
|
||||
<span class="marketing-bill-date-range__label">{{ $fieldLabel }}</span>
|
||||
<div class="upstream-data-date-range">
|
||||
<span class="upstream-data-date" data-date-picker>
|
||||
<input
|
||||
id="{{ $fromId }}"
|
||||
type="text"
|
||||
name="{{ $fromName }}"
|
||||
value="{{ $fromValue }}"
|
||||
readonly
|
||||
autocomplete="off"
|
||||
placeholder="开始日期"
|
||||
aria-label="{{ $fromLabel }}"
|
||||
data-date-input
|
||||
>
|
||||
<button type="button" class="upstream-data-date__clear" data-date-clear hidden aria-label="清除{{ $fromLabel }}">
|
||||
<span class="material-icons-outlined" aria-hidden="true">close</span>
|
||||
</button>
|
||||
<button type="button" class="upstream-data-date__pick" data-date-toggle aria-label="选择{{ $fromLabel }}">
|
||||
<span class="material-icons-outlined" aria-hidden="true">calendar_today</span>
|
||||
</button>
|
||||
<div class="upstream-data-calendar" role="dialog" aria-label="{{ $fromLabel }}日历" data-date-calendar hidden></div>
|
||||
</span>
|
||||
<b class="upstream-data-date-range__sep">至</b>
|
||||
<span class="upstream-data-date" data-date-picker>
|
||||
<input
|
||||
id="{{ $toId }}"
|
||||
type="text"
|
||||
name="{{ $toName }}"
|
||||
value="{{ $toValue }}"
|
||||
readonly
|
||||
autocomplete="off"
|
||||
placeholder="结束日期"
|
||||
aria-label="{{ $toLabel }}"
|
||||
data-date-input
|
||||
>
|
||||
<button type="button" class="upstream-data-date__clear" data-date-clear hidden aria-label="清除{{ $toLabel }}">
|
||||
<span class="material-icons-outlined" aria-hidden="true">close</span>
|
||||
</button>
|
||||
<button type="button" class="upstream-data-date__pick" data-date-toggle aria-label="选择{{ $toLabel }}">
|
||||
<span class="material-icons-outlined" aria-hidden="true">calendar_today</span>
|
||||
</button>
|
||||
<div class="upstream-data-calendar" role="dialog" aria-label="{{ $toLabel }}日历" data-date-calendar hidden></div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -1022,6 +1022,9 @@
|
||||
@elseif ($sectionView)
|
||||
@include($sectionView)
|
||||
@elseif (!empty($content) && !empty($content['view']))
|
||||
@if ($isMarketingAccountBillsPage)
|
||||
@include('business.pages.partials.date-range-picker')
|
||||
@endif
|
||||
<section class="business-content-section" aria-label="{{ $activeContentTitle }}">
|
||||
@include($content['view'], $content)
|
||||
</section>
|
||||
|
||||
@ -354,7 +354,12 @@ class MarketingAccountBillsTabsTest extends FeatureTestCase
|
||||
->assertOk()
|
||||
->assertDontSeeText('抖音账户')
|
||||
->assertDontSeeText('得物账户')
|
||||
->assertDontSeeText('唯品会账户');
|
||||
->assertDontSeeText('唯品会账户')
|
||||
->assertSee('data-marketing-bill-date-filter', false)
|
||||
->assertSee('data-date-picker', false)
|
||||
->assertSee('id="tb-filter-from"', false)
|
||||
->assertSee('name="from"', false)
|
||||
->assertSeeText('开始日期');
|
||||
|
||||
$page = collect(config('business_navigation'))
|
||||
->firstWhere('slug', 'billing-transactions')['pages'];
|
||||
@ -400,7 +405,10 @@ class MarketingAccountBillsTabsTest extends FeatureTestCase
|
||||
->assertOk()
|
||||
->assertSeeText('导出')
|
||||
->assertSee(e(route('business.pages.export', $parameters)), false)
|
||||
->assertSee('aria-label="导出当前筛选结果"', false);
|
||||
->assertSee('aria-label="导出当前筛选结果"', false)
|
||||
->assertSee('data-marketing-bill-date-filter', false)
|
||||
->assertSee('id="pdd-filter-from"', false)
|
||||
->assertSee('data-date-picker', false);
|
||||
}
|
||||
|
||||
public function testPinduoduoBillsExportUsesTheCurrentMirrorFilters(): void
|
||||
@ -595,7 +603,10 @@ class MarketingAccountBillsTabsTest extends FeatureTestCase
|
||||
->assertSee('aria-label="导出当前筛选结果"', false)
|
||||
->assertDontSeeText('投放日期')
|
||||
->assertSee('data-jd-wallet-panel', false)
|
||||
->assertSee('data-jd-wallet-navigation', false);
|
||||
->assertSee('data-jd-wallet-navigation', false)
|
||||
->assertSee('data-marketing-bill-date-filter', false)
|
||||
->assertSee('id="jd-filter-from"', false)
|
||||
->assertSee('data-date-picker', false);
|
||||
|
||||
$this->loginAs()
|
||||
->get(route('business.pages.show', array_merge($base, ['jd_ledger' => 'consumption'])))
|
||||
@ -608,6 +619,30 @@ class MarketingAccountBillsTabsTest extends FeatureTestCase
|
||||
->assertDontSeeText('充值时间');
|
||||
}
|
||||
|
||||
public function testMarketingAccountBillFormsUseTheSharedCalendarDateRange(): void
|
||||
{
|
||||
foreach ([
|
||||
'banking/marketing_taobao_alipay_bills/partials/embedded-table.blade.php',
|
||||
'banking/marketing_alibaba_bills/partials/embedded-table.blade.php',
|
||||
'banking/marketing_pinduoduo_bills/partials/embedded-table.blade.php',
|
||||
'banking/marketing_jd_wallet_bills/partials/embedded-table.blade.php',
|
||||
] as $view) {
|
||||
$this->assertStringContainsString(
|
||||
"@include('business.pages.partials.marketing-bill-date-range'",
|
||||
file_get_contents(resource_path('views/' . $view)),
|
||||
);
|
||||
}
|
||||
|
||||
$this->assertStringContainsString(
|
||||
"@include('business.pages.partials.date-range-picker')",
|
||||
file_get_contents(resource_path('views/business/pages/show.blade.php')),
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
'setupBillDatePickers(workspace);',
|
||||
file_get_contents(resource_path('assets/js/views/business/marketing-account-bills.js')),
|
||||
);
|
||||
}
|
||||
|
||||
public function testJdWalletColdStartRegistersEveryRequiredSnapshotScope(): void
|
||||
{
|
||||
$this->allowMarketingAccountBillsPage();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user