快递应付子目录移入终版横向工作区 (#172)

This commit is contained in:
renshen 2026-09-12 16:58:05 +08:00
parent 25e1b7461a
commit e594bdc456
3 changed files with 106 additions and 2 deletions

View File

@ -108,7 +108,7 @@ class ShowInAdmin
: $this->sortByTitleLength($section['pages'] ?? []);
$order = ($sectionIndex + 1) * 10;
if (empty($pages) || $section['slug'] === 'supplier-payables') {
if (empty($pages) || in_array($section['slug'], ['supplier-payables', 'courier-payables'], true)) {
$menu->route(
'business.pages.show',
$section['title'],

View File

@ -0,0 +1,102 @@
@php
$courierSection = collect(\App\Utilities\SidebarPermissions::navigationFor(user()))->firstWhere('slug', 'courier-payables');
$courierPages = $courierSection['pages'] ?? [];
@endphp
<div data-courier-final>
<nav class="business-tab-bar courier-final-tabs" aria-label="快递应付子功能">
@foreach ($courierPages as $item)
<a class="business-tab-link" data-courier-tab="{{ $item['slug'] }}"
href="{{ route('business.pages.show', ['section' => 'courier-payables', 'page' => $item['slug']]) }}">{{ $item['title'] }}</a>
@endforeach
</nav>
<div role="status" aria-live="polite" data-courier-status></div>
<button type="button" class="business-tab-link" data-courier-retry hidden>重新加载</button>
@if (empty($courierPages))
<div class="biz-empty">当前账号没有可访问的快递应付子功能。</div>
@endif
<div data-courier-frames></div>
</div>
<style>
.courier-final-tabs { flex-wrap:wrap; gap:4px 16px; min-height:34px; padding:0 16px; margin-bottom:12px; }
.courier-final-tabs .business-tab-link { min-height:34px; font-size:12px; color:var(--vip-content-muted, #595959); }
.courier-final-tabs .is-active { color:var(--vip-content-accent-dark, #856632); }
[data-courier-frames] iframe { width:100%; height:calc(100vh - 260px); min-height:400px; border:0; }
[data-courier-frames] iframe[hidden] { display:none; }
[data-courier-retry][hidden] { display:none!important; }
</style>
@push('body_end')
<script>
(() => {
const root = document.querySelector('[data-courier-final]');
if (!root) return;
const links = [...root.querySelectorAll('[data-courier-tab]')];
const frames = new Map();
const status = root.querySelector('[data-courier-status]');
const retry = root.querySelector('[data-courier-retry]');
let selected;
function select(link, push = true, reload = false) {
if (!link) return;
selected = link;
retry.hidden = true;
links.forEach(item => {
item.classList.toggle('is-active', item === link);
if (item === link) item.setAttribute('aria-current', 'page');
else item.removeAttribute('aria-current');
});
frames.forEach(frame => frame.hidden = true);
let frame = frames.get(link.dataset.courierTab);
if (!frame || reload) {
if (frame) frame.remove();
frame = document.createElement('iframe');
frame.title = link.textContent.trim();
frame.src = link.href;
frame.style.visibility = 'hidden';
status.textContent = '正在加载…';
const fail = () => {
frame.dataset.failed = '1';
if (selected === link) {
status.textContent = '页面加载失败或登录已过期,请重试。';
retry.hidden = false;
}
};
const timeout = setTimeout(fail, 45000);
frame.addEventListener('error', fail);
frame.addEventListener('load', () => {
clearTimeout(timeout);
try {
const doc = frame.contentDocument;
const content = doc.querySelector('#app');
if (!content) { fail(); return; }
// Preserve each page's own scripts, forms and routes in its document.
const style = doc.createElement('style');
style.textContent = '.js-menu,body>.container,#header [data-page-title-first]{display:none!important} #panel{margin:0!important;padding:0!important} #main-body>.container{margin:0!important;padding:0!important;width:100%!important} #header{padding:0!important;margin:0!important}';
doc.head.appendChild(style);
frame.style.visibility = 'visible';
delete frame.dataset.failed;
if (selected === link) { status.textContent = ''; retry.hidden = true; }
} catch (_) { fail(); }
});
root.querySelector('[data-courier-frames]').appendChild(frame);
frames.set(link.dataset.courierTab, frame);
} else {
status.textContent = frame.dataset.failed ? '页面加载失败,请重试。' : '';
retry.hidden = !frame.dataset.failed;
}
frame.hidden = false;
if (push) {
const url = new URL(location.href);
url.searchParams.set('view', link.dataset.courierTab);
history.pushState({}, '', url);
}
}
links.forEach(link => link.addEventListener('click', event => {
if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
event.preventDefault(); select(link);
}));
retry.addEventListener('click', () => select(selected, false, true));
const restore = () => select(links.find(link => link.dataset.courierTab === new URL(location.href).searchParams.get('view')) || links[0], false);
window.addEventListener('popstate', restore);
restore();
})();
</script>
@endpush

View File

@ -621,7 +621,9 @@
}
@endphp
@if (!empty($content) && !empty($content['view']))
@if ($section['slug'] === 'courier-payables-final')
@include('business.pages.courier-payables.final-workspace')
@elseif (!empty($content) && !empty($content['view']))
<section class="business-content-section" aria-label="{{ $activeContentTitle }}">
@include($content['view'], $content)
</section>