feat: 将附加费报价和结算整合为同一入口的两个页签
(cherry picked from commit a83347aef3c9069df2f521df9b4cbe1096255a33)
This commit is contained in:
parent
d9646b4ac9
commit
28f99acebc
@ -324,6 +324,15 @@ class Pages extends Controller
|
||||
|
||||
abort_if(empty($sectionConfig), 403, '当前账号没有该页面权限。');
|
||||
|
||||
// Keep the old direct URL working after settlement becomes a tab.
|
||||
if ($section === 'courier-payables' && $page === 'courier-surcharge-settlement') {
|
||||
return redirect()->route('business.pages.show', array_merge(request()->query(), [
|
||||
'section' => $section,
|
||||
'page' => 'courier-surcharge',
|
||||
'tab' => 'settlement',
|
||||
]));
|
||||
}
|
||||
|
||||
$pages = collect($sectionConfig['pages'] ?? []);
|
||||
|
||||
if ($pages->isEmpty()) {
|
||||
@ -390,6 +399,18 @@ class Pages extends Controller
|
||||
}
|
||||
|
||||
if ($tab === null) {
|
||||
if ($page === 'courier-surcharge') {
|
||||
$activeTab = $tabs->first();
|
||||
|
||||
return view('business.pages.show', $this->viewData(
|
||||
$sectionConfig,
|
||||
$pageConfig,
|
||||
$tabs,
|
||||
$activeTab,
|
||||
$this->resolveContent($page, $activeTab['slug']),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->redirectToPage($sectionConfig, $pageConfig);
|
||||
}
|
||||
|
||||
@ -2645,7 +2666,7 @@ class Pages extends Controller
|
||||
'online-daifa-price' => $this->contentForOnlineDaifaPrice(),
|
||||
'product-costs' => $this->contentForProductCosts(),
|
||||
'financial-analysis' => $this->contentForFinancialAnalysis(),
|
||||
'courier-surcharge' => $this->contentForCourierSurcharge(),
|
||||
'courier-surcharge' => $this->contentForCourierSurcharge($tab),
|
||||
'freight-difference', 'other-surcharge-summary', 'return-fee' => $this->contentForCourierPayableSummary($page),
|
||||
'shipping-data' => $this->contentForShippingData(),
|
||||
'return-pickup-management' => $this->contentForReturnPickupManagement(),
|
||||
@ -3644,24 +3665,26 @@ class Pages extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
protected function contentForCourierSurcharge(): array
|
||||
protected function contentForCourierSurcharge(?string $tab = null): array
|
||||
{
|
||||
$clean = static fn (mixed $value, int $length = 60): string => mb_substr(trim((string) $value), 0, $length);
|
||||
$quoteInput = $tab === 'settlement' ? [] : request()->query();
|
||||
$filters = [
|
||||
'keyword' => $clean(request('keyword', ''), 40),
|
||||
'courier' => $clean(request('courier', ''), 40),
|
||||
'type' => $clean(request('type', ''), 40),
|
||||
'mode' => $clean(request('mode', ''), 40),
|
||||
'scope' => $clean(request('scope', ''), 20),
|
||||
'reconciler' => $clean(request('reconciler', ''), 40),
|
||||
'supplier' => $clean(request('supplier', ''), 191),
|
||||
'status' => $clean(request('status', ''), 20),
|
||||
'keyword' => $clean($quoteInput['keyword'] ?? '', 40),
|
||||
'courier' => $clean($quoteInput['courier'] ?? '', 40),
|
||||
'type' => $clean($quoteInput['type'] ?? '', 40),
|
||||
'mode' => $clean($quoteInput['mode'] ?? '', 40),
|
||||
'scope' => $clean($quoteInput['scope'] ?? '', 20),
|
||||
'reconciler' => $clean($quoteInput['reconciler'] ?? '', 40),
|
||||
'supplier' => $clean($quoteInput['supplier'] ?? '', 191),
|
||||
'status' => $clean($quoteInput['status'] ?? '', 20),
|
||||
];
|
||||
$data = $this->courierSurchargeQuotes->pageData($filters);
|
||||
$auditReady = $this->courierSurchargeAudits->ready();
|
||||
|
||||
return [
|
||||
'view' => 'business.pages.courier-payables.courier-surcharge',
|
||||
'view' => 'business.pages.courier-payables.courier-surcharge-workspace',
|
||||
'courierSurchargeActiveTab' => $tab ?? 'quotes',
|
||||
'courierSurchargeRows' => $data['rows'],
|
||||
'courierSurchargeFilters' => $filters,
|
||||
'courierSurchargeSummary' => $data['summary'],
|
||||
|
||||
@ -712,7 +712,14 @@ $navigation = [
|
||||
['slug' => 'compensation-details', 'title' => '赔偿明细'],
|
||||
['slug' => 'advance-details', 'title' => '借支明细'],
|
||||
['slug' => 'other-adjustments', 'title' => '其他扣款补款'],
|
||||
['slug' => 'courier-surcharge', 'title' => '附加费报价维护'],
|
||||
[
|
||||
'slug' => 'courier-surcharge',
|
||||
'title' => '附加费报价维护',
|
||||
'tabs' => [
|
||||
['slug' => 'quotes', 'title' => '附加费报价'],
|
||||
['slug' => 'settlement', 'title' => '附加费结算'],
|
||||
],
|
||||
],
|
||||
['slug' => 'payable-cloud-warehouse-vehicle-fee', 'title' => '应付云仓车费'],
|
||||
['slug' => 'courier-payables-report', 'title' => '快递应付表'],
|
||||
['slug' => 'freight-difference', 'title' => '运费差'],
|
||||
|
||||
@ -0,0 +1,201 @@
|
||||
@php
|
||||
$rows = $courierSurchargeSettlementRows ?? collect();
|
||||
$columns = [
|
||||
['key' => 'courier_name', 'label' => '快递名称', 'fixed' => 'true'],
|
||||
['key' => 'waybill', 'label' => '单号'],
|
||||
['key' => 'platform_product_id', 'label' => '平台商品ID'],
|
||||
['key' => 'product_code', 'label' => '商品编码'],
|
||||
['key' => 'shop_name', 'label' => '店铺名称'],
|
||||
['key' => 'online_order_no', 'label' => '线上订单号'],
|
||||
['key' => 'length', 'label' => '长'],
|
||||
['key' => 'width', 'label' => '宽'],
|
||||
['key' => 'height', 'label' => '高'],
|
||||
['key' => 'volume', 'label' => '体积'],
|
||||
['key' => 'inspection_type', 'label' => '查件类型'],
|
||||
['key' => 'inspection_original', 'label' => '查件原件'],
|
||||
['key' => 'return_waybill_no', 'label' => '退回单号'],
|
||||
['key' => 'settlement_weight', 'label' => '结算重量'],
|
||||
['key' => 'settlement_amount', 'label' => '结算金额', 'fixed' => 'end'],
|
||||
];
|
||||
$filterValue = static fn (string $key): string => trim((string) request()->query($key, ''));
|
||||
$displayValue = static function (mixed $value, string $key): string {
|
||||
if ($value === null || $value === '') {
|
||||
return '—';
|
||||
}
|
||||
|
||||
if ($key === 'settlement_amount' && is_numeric($value)) {
|
||||
return number_format((float) $value, 2, '.', '');
|
||||
}
|
||||
|
||||
return (string) $value;
|
||||
};
|
||||
@endphp
|
||||
|
||||
<section class="surcharge-settlement-page" aria-label="附加费结算">
|
||||
<style>
|
||||
.surcharge-settlement-page {
|
||||
--settlement-ink: var(--vip-content-ink, #171717);
|
||||
--settlement-muted: var(--vip-content-muted, #595959);
|
||||
--settlement-accent: var(--vip-content-accent-dark, #856632);
|
||||
--settlement-soft: var(--vip-content-accent-soft, #f7f0de);
|
||||
--settlement-border: var(--vip-border, #d8d2c7);
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
min-width: 0;
|
||||
color: var(--settlement-ink);
|
||||
font-family: "JetBrains Mono", "Microsoft YaHei", "PingFang SC", monospace;
|
||||
font-size: .8125rem;
|
||||
}
|
||||
|
||||
.surcharge-settlement-page *,
|
||||
.surcharge-settlement-page *::before,
|
||||
.surcharge-settlement-page *::after { box-sizing: border-box; }
|
||||
.surcharge-settlement-page > * { min-width: 0; }
|
||||
|
||||
.settlement-notice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: .65rem;
|
||||
padding: .75rem 1rem;
|
||||
border: 1px solid #d7c39d;
|
||||
border-radius: .65rem;
|
||||
background: #fffaf0;
|
||||
color: #6a5129;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.settlement-notice .material-icons-outlined { color: var(--settlement-accent); font-size: 1.15rem; }
|
||||
.settlement-notice strong { color: var(--settlement-ink); }
|
||||
|
||||
.settlement-summary {
|
||||
display: grid;
|
||||
grid-template-columns: 1.35fr repeat(3, minmax(8rem, 1fr));
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--settlement-border);
|
||||
border-radius: .75rem;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.settlement-summary__intro,
|
||||
.settlement-summary__metric { min-width: 0; padding: 1rem 1.15rem; }
|
||||
.settlement-summary__intro { display: flex; align-items: center; gap: .75rem; }
|
||||
.settlement-summary__icon { display: grid; flex: none; width: 2.4rem; height: 2.4rem; place-items: center; border-radius: .6rem; background: var(--settlement-soft); color: var(--settlement-accent); }
|
||||
.settlement-summary__title { font-size: .95rem; font-weight: 700; }
|
||||
.settlement-summary__subtitle { margin-top: .2rem; color: var(--settlement-muted); font-size: .72rem; }
|
||||
.settlement-summary__metric { border-left: 1px solid var(--settlement-border); }
|
||||
.settlement-summary__label { color: var(--settlement-muted); font-size: .72rem; }
|
||||
.settlement-summary__value { margin-top: .25rem; font-size: 1.1rem; font-weight: 700; font-variant-numeric: tabular-nums; }
|
||||
|
||||
.settlement-filter-bar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(10rem, 1fr));
|
||||
gap: .7rem;
|
||||
align-items: end;
|
||||
padding: 1rem 1.15rem;
|
||||
border: 1px solid var(--settlement-border);
|
||||
border-radius: .75rem;
|
||||
background: #fffdf8;
|
||||
}
|
||||
|
||||
.settlement-field { display: grid; gap: .3rem; min-width: 0; }
|
||||
.settlement-field label { color: var(--settlement-muted); font-size: .72rem; font-weight: 600; }
|
||||
.settlement-field input,
|
||||
.settlement-field select {
|
||||
width: 100%;
|
||||
height: 2.2rem;
|
||||
min-width: 0;
|
||||
padding: 0 .6rem;
|
||||
border: 1px solid var(--settlement-border);
|
||||
border-radius: .45rem;
|
||||
background: #fff;
|
||||
color: var(--settlement-ink);
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.settlement-field input:focus,
|
||||
.settlement-field select:focus { border-color: var(--settlement-accent); outline: none; box-shadow: 0 0 0 3px rgba(133, 102, 50, .18); }
|
||||
.settlement-actions { display: flex; flex-wrap: wrap; gap: .45rem; align-items: end; }
|
||||
.settlement-button { display: inline-flex; align-items: center; justify-content: center; gap: .35rem; min-height: 2.2rem; padding: 0 .75rem; border: 1px solid var(--settlement-border); border-radius: .45rem; background: #fff; color: var(--settlement-ink); font: inherit; font-weight: 600; text-decoration: none; white-space: nowrap; cursor: pointer; }
|
||||
.settlement-button--primary { border-color: var(--settlement-accent); background: var(--settlement-accent); color: #fff; }
|
||||
.settlement-button .material-icons-outlined { font-size: 1rem; }
|
||||
|
||||
.settlement-table-surface { overflow: visible; border: 1px solid var(--settlement-border); border-radius: .75rem; background: #fff; }
|
||||
.settlement-table-head { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: .75rem 1rem; padding: .85rem 1.15rem; border-bottom: 1px solid var(--settlement-border); }
|
||||
.settlement-table-title { display: flex; align-items: center; gap: .45rem; font-size: .9rem; font-weight: 700; }
|
||||
.settlement-table-title .material-icons-outlined { color: var(--settlement-accent); font-size: 1.1rem; }
|
||||
.settlement-table-hint { color: var(--settlement-muted); font-size: .72rem; }
|
||||
.settlement-table-meta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .6rem 1rem; padding: .65rem 1.15rem; border-bottom: 1px solid var(--settlement-border); background: #fffdf8; color: var(--settlement-muted); font-size: .72rem; }
|
||||
.settlement-table-meta strong { color: var(--settlement-ink); }
|
||||
.settlement-table-scroll { max-height: min(62vh, 42rem); overflow: auto; overscroll-behavior: contain; scrollbar-gutter: stable both-edges; }
|
||||
.settlement-table { width: max-content; min-width: 100%; border-collapse: separate; border-spacing: 0; font-size: .75rem; }
|
||||
.settlement-table th,
|
||||
.settlement-table td { min-width: 7.5rem; padding: .62rem .7rem; border-right: 1px solid var(--settlement-border); border-bottom: 1px solid var(--settlement-border); text-align: left; vertical-align: top; white-space: nowrap; }
|
||||
.settlement-table th { background: var(--settlement-soft); font-weight: 700; }
|
||||
.settlement-table th[data-finance-fixed="true"],
|
||||
.settlement-table td[data-finance-fixed="true"] { background: #fffdf8; }
|
||||
.settlement-table th[data-finance-fixed="end"],
|
||||
.settlement-table td[data-finance-fixed="end"] { background: #fffdf8; }
|
||||
.settlement-table td { overflow: hidden; text-overflow: ellipsis; }
|
||||
.settlement-table .settlement-empty td { min-width: 22rem; padding: 3rem 1rem; text-align: center; color: var(--settlement-muted); white-space: normal; }
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.settlement-summary { grid-template-columns: 1fr 1fr; }
|
||||
.settlement-summary__intro { grid-column: 1 / -1; }
|
||||
.settlement-summary__metric:nth-child(2) { border-left: 0; }
|
||||
.settlement-filter-bar { grid-template-columns: repeat(2, minmax(10rem, 1fr)); }
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.settlement-summary { grid-template-columns: 1fr; }
|
||||
.settlement-summary__metric { border-left: 0; border-top: 1px solid var(--settlement-border); }
|
||||
.settlement-filter-bar { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="settlement-notice" role="status">
|
||||
<span class="material-icons-outlined" aria-hidden="true">info</span>
|
||||
<div>等待接入结算数据;确认数据来源后,将按附加费报价规则计算。</div>
|
||||
</div>
|
||||
|
||||
<div class="settlement-summary" aria-label="附加费结算概览">
|
||||
<div class="settlement-summary__intro"><span class="settlement-summary__icon material-icons-outlined" aria-hidden="true">calculate</span><div><div class="settlement-summary__title">附加费结算</div><div class="settlement-summary__subtitle">结算标准读取附加费报价维护</div></div></div>
|
||||
<div class="settlement-summary__metric"><div class="settlement-summary__label">当前明细</div><div class="settlement-summary__value">{{ $rows->count() }}</div></div>
|
||||
<div class="settlement-summary__metric"><div class="settlement-summary__label">结算金额</div><div class="settlement-summary__value">待接入</div></div>
|
||||
<div class="settlement-summary__metric"><div class="settlement-summary__label">数据状态</div><div class="settlement-summary__value">待确认来源</div></div>
|
||||
</div>
|
||||
|
||||
<form class="settlement-filter-bar" method="GET" action="{{ route('business.pages.show', ['section' => 'courier-payables', 'page' => 'courier-surcharge', 'tab' => 'settlement']) }}" aria-label="附加费结算筛选">
|
||||
<div class="settlement-field"><label for="settlement-courier">快递名称</label><input id="settlement-courier" type="search" name="courier_name" value="{{ $filterValue('courier_name') }}" placeholder="输入快递名称"></div>
|
||||
<div class="settlement-field"><label for="settlement-waybill">单号</label><input id="settlement-waybill" type="search" name="waybill" value="{{ $filterValue('waybill') }}" placeholder="输入单号"></div>
|
||||
<div class="settlement-field"><label for="settlement-shop">店铺名称</label><input id="settlement-shop" type="search" name="shop_name" value="{{ $filterValue('shop_name') }}" placeholder="输入店铺名称"></div>
|
||||
<div class="settlement-field"><label for="settlement-online-order">线上订单号</label><input id="settlement-online-order" type="search" name="online_order_no" value="{{ $filterValue('online_order_no') }}" placeholder="输入线上订单号"></div>
|
||||
<div class="settlement-field"><label for="settlement-inspection">查件类型</label><select id="settlement-inspection" name="inspection_type"><option value="">全部查件类型</option></select></div>
|
||||
<div class="settlement-field"><label for="settlement-status">结算状态</label><select id="settlement-status" name="status"><option value="">全部状态</option><option value="待接入" @selected($filterValue('status') === '待接入')>待接入</option><option value="已计算" @selected($filterValue('status') === '已计算')>已计算</option></select></div>
|
||||
<div class="settlement-actions"><button class="settlement-button settlement-button--primary" type="submit"><span class="material-icons-outlined" aria-hidden="true">search</span>查询</button><a class="settlement-button" href="{{ route('business.pages.show', ['section' => 'courier-payables', 'page' => 'courier-surcharge', 'tab' => 'settlement']) }}"><span class="material-icons-outlined" aria-hidden="true">refresh</span>重置</a></div>
|
||||
</form>
|
||||
|
||||
<div class="settlement-table-surface" data-finance-table-surface>
|
||||
<div class="settlement-table-head"><div><div class="settlement-table-title"><span class="material-icons-outlined" aria-hidden="true">table_view</span>附加费结算明细</div><div class="settlement-table-hint">快递名称和结算金额固定显示,其余字段可在“列设置”中调整。</div></div><div class="finance-table-controls" data-finance-controls><span class="settlement-table-hint">列设置按当前用户和本页面保存</span></div></div>
|
||||
<div class="settlement-table-meta"><span>当前筛选结果:<strong>{{ $rows->count() }}</strong> 条</span><span>报价匹配和金额计算将在确认数据来源后接入</span></div>
|
||||
<div class="settlement-table-scroll finance-table-scroll-owner">
|
||||
<table class="settlement-table" data-finance-table data-finance-table-name="courier-surcharge-settlement" data-finance-table-key="{{ auth()->id() }}:{{ company_id() }}:courier-payables:courier-surcharge:settlement:details" aria-label="附加费结算明细">
|
||||
<thead><tr>
|
||||
@foreach ($columns as $column)
|
||||
<th scope="col" data-finance-column-key="{{ $column['key'] }}" data-finance-fixed="{{ $column['fixed'] ?? '' }}" data-export-field="{{ $column['key'] }}">{{ $column['label'] }}</th>
|
||||
@endforeach
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
@forelse ($rows as $row)
|
||||
<tr>
|
||||
@foreach ($columns as $column)
|
||||
<td data-finance-column-key="{{ $column['key'] }}" data-export-value="{{ $displayValue(data_get($row, $column['key']), $column['key']) }}">{{ $displayValue(data_get($row, $column['key']), $column['key']) }}</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@empty
|
||||
<tr class="settlement-empty is-empty"><td colspan="{{ count($columns) }}"><span class="material-icons-outlined" aria-hidden="true">hourglass_empty</span><div>页面已就绪,等待接入附加费结算数据。</div></td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -0,0 +1,63 @@
|
||||
@php
|
||||
$surchargeTabUrls = collect(['quotes', 'settlement'])->mapWithKeys(fn ($tab) => [
|
||||
$tab => route('business.pages.show', ['section' => 'courier-payables', 'page' => 'courier-surcharge', 'tab' => $tab]),
|
||||
])->all();
|
||||
@endphp
|
||||
<div data-surcharge-workspace>
|
||||
<div data-surcharge-panel="quotes" @if ($courierSurchargeActiveTab !== 'quotes') hidden @endif>
|
||||
@include('business.pages.courier-payables.courier-surcharge')
|
||||
</div>
|
||||
<div data-surcharge-panel="settlement" @if ($courierSurchargeActiveTab !== 'settlement') hidden @endif>
|
||||
@include('business.pages.courier-payables.courier-surcharge-settlement')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
const root = document.querySelector('[data-surcharge-workspace]');
|
||||
const content = root.closest('.business-content-section');
|
||||
const navigation = content.parentElement.querySelector('.business-tab-bar');
|
||||
const links = [...navigation.querySelectorAll('a')];
|
||||
const panels = [...root.querySelectorAll('[data-surcharge-panel]')];
|
||||
const title = document.querySelector('[data-page-title-first] h1');
|
||||
const documentTitle = document.title;
|
||||
const initialTitle = @json($courierSurchargeActiveTab === 'settlement' ? '附加费结算' : '附加费报价');
|
||||
const urls = @json($surchargeTabUrls);
|
||||
const keyFor = (link) => Object.keys(urls).find(key => new URL(urls[key]).pathname === new URL(link.href).pathname);
|
||||
const savedUrls = { ...urls };
|
||||
let active = @json($courierSurchargeActiveTab);
|
||||
savedUrls[active] = location.href;
|
||||
|
||||
function select(key, push = true) {
|
||||
if (!Object.hasOwn(urls, key)) return;
|
||||
if (push) savedUrls[active] = location.href;
|
||||
active = key;
|
||||
panels.forEach(panel => { panel.hidden = panel.dataset.surchargePanel !== key; });
|
||||
links.forEach(link => {
|
||||
const selected = keyFor(link) === key;
|
||||
link.classList.toggle('is-active', selected);
|
||||
if (selected) link.setAttribute('aria-current', 'page');
|
||||
else link.removeAttribute('aria-current');
|
||||
});
|
||||
const label = key === 'settlement' ? '附加费结算' : '附加费报价';
|
||||
if (title) title.textContent = label;
|
||||
content.setAttribute('aria-label', label);
|
||||
document.title = documentTitle.replace(initialTitle, label);
|
||||
if (push) history.pushState({}, '', savedUrls[key]);
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}
|
||||
|
||||
links.forEach(link => link.addEventListener('click', event => {
|
||||
if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
|
||||
const key = keyFor(link);
|
||||
if (!key) return;
|
||||
event.preventDefault();
|
||||
if (key !== active) select(key);
|
||||
}));
|
||||
window.addEventListener('popstate', () => {
|
||||
const key = Object.keys(urls).find(key => new URL(urls[key]).pathname === location.pathname) || 'quotes';
|
||||
select(key, false);
|
||||
savedUrls[key] = location.href;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@ -31,7 +31,8 @@ class CourierSurchargePageTest extends FeatureTestCase
|
||||
'page' => 'courier-surcharge',
|
||||
]))
|
||||
->assertOk()
|
||||
->assertSeeText('附加费报价维护')
|
||||
->assertSeeText('附加费报价')
|
||||
->assertSee('aria-label="附加费报价维护"', false)
|
||||
->assertSeeText('正式维护数据')
|
||||
->assertSeeText('报价规则列表')
|
||||
->assertSeeText('管理附加费类型')
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Business;
|
||||
|
||||
use App\Models\Auth\Permission;
|
||||
use Tests\Feature\FeatureTestCase;
|
||||
|
||||
class CourierSurchargeSettlementPageTest extends FeatureTestCase
|
||||
{
|
||||
public function test_page_renders_requested_settlement_columns_without_fake_rows(): void
|
||||
{
|
||||
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
|
||||
|
||||
$this->loginAs()->get(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge',
|
||||
'tab' => 'settlement',
|
||||
]))->assertOk()
|
||||
->assertSee('data-surcharge-panel="quotes" hidden', false)
|
||||
->assertSeeText('附加费结算')
|
||||
->assertSeeText('页面已就绪,等待接入附加费结算数据。')
|
||||
->assertSee('data-finance-table-name="courier-surcharge-settlement"', false)
|
||||
->assertSee('data-finance-fixed="true"', false)
|
||||
->assertSee('data-finance-fixed="end"', false)
|
||||
->assertSeeText('快递名称')
|
||||
->assertSeeText('平台商品ID')
|
||||
->assertSeeText('查件原件')
|
||||
->assertSeeText('退回单号')
|
||||
->assertSeeText('结算重量')
|
||||
->assertSeeText('结算金额');
|
||||
}
|
||||
|
||||
public function test_settlement_filters_are_preserved_in_the_form(): void
|
||||
{
|
||||
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
|
||||
|
||||
$this->loginAs()->get(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge',
|
||||
'tab' => 'settlement',
|
||||
'courier_name' => '测试快递',
|
||||
'waybill' => '001234',
|
||||
'shop_name' => '测试店铺',
|
||||
'online_order_no' => 'SO-001',
|
||||
'status' => '待接入',
|
||||
]))->assertOk()
|
||||
->assertSee('value="测试快递"', false)
|
||||
->assertSee('value="001234"', false)
|
||||
->assertSee('value="测试店铺"', false)
|
||||
->assertSee('value="SO-001"', false)
|
||||
->assertSee('value="待接入" selected', false)
|
||||
->assertViewHas('content', fn (array $content) => $content['courierSurchargeFilters']['status'] === '');
|
||||
}
|
||||
|
||||
public function test_quote_page_exposes_quote_and_settlement_tabs(): void
|
||||
{
|
||||
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
|
||||
|
||||
$this->loginAs()->get(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge',
|
||||
]))->assertOk()
|
||||
->assertSeeText('附加费报价')
|
||||
->assertSeeText('附加费结算')
|
||||
->assertSee('data-surcharge-panel="settlement" hidden', false)
|
||||
->assertSee(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge',
|
||||
'tab' => 'quotes',
|
||||
]), false)
|
||||
->assertSee(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge',
|
||||
'tab' => 'settlement',
|
||||
]), false);
|
||||
}
|
||||
|
||||
public function test_old_settlement_page_url_redirects_to_settlement_tab(): void
|
||||
{
|
||||
$this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
|
||||
|
||||
$this->loginAs()->get(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge-settlement',
|
||||
'waybill' => '0000123456789',
|
||||
]))->assertRedirect(route('business.pages.show', [
|
||||
'section' => 'courier-payables',
|
||||
'page' => 'courier-surcharge',
|
||||
'tab' => 'settlement',
|
||||
'waybill' => '0000123456789',
|
||||
]));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user