From 28a62434d29f1dc8c14d5b5f9e538caf9d4f129e Mon Sep 17 00:00:00 2001 From: WuYongJie <549727955@qq.com> Date: Tue, 11 Aug 2026 12:22:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E5=90=88=E5=B9=B6=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E4=BA=AC=E4=B8=9C=E9=92=B1=E5=8C=85=E8=B4=A6=E5=8D=95=20(#26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 接入京东充值与消耗账单,修复快照冷启动、刷新依赖、日期边界与标签局部切换。 --- app/Http/Controllers/Business/Pages.php | 76 +++++++ .../Repositories/JdWalletBillRepository.php | 187 ++++++++++++++++ .../Services/JianSunSnapshotRefresher.php | 28 +++ .../views/business/marketing-account-bills.js | 206 ++++++++++++++++++ .../partials/embedded-table.blade.php | 148 +++++++++++++ resources/views/business/pages/show.blade.php | 66 +++--- scripts/build-frontend.ps1 | 2 + .../MarketingAccountBillsTabsTest.php | 71 +++++- .../JdWalletBillRepositoryTest.php | 81 +++++++ .../JianSunSnapshotRefresherTest.php | 138 ++++++++++++ webpack.mix.js | 1 + 11 files changed, 971 insertions(+), 33 deletions(-) create mode 100644 modules/EcommerceFinance/Repositories/JdWalletBillRepository.php create mode 100644 resources/assets/js/views/business/marketing-account-bills.js create mode 100644 resources/views/banking/marketing_jd_wallet_bills/partials/embedded-table.blade.php create mode 100644 tests/Unit/EcommerceFinance/JdWalletBillRepositoryTest.php diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php index dde88efc..f9505b87 100644 --- a/app/Http/Controllers/Business/Pages.php +++ b/app/Http/Controllers/Business/Pages.php @@ -16,6 +16,7 @@ use Illuminate\Support\Collection; use Modules\EcommerceFinance\Repositories\AlibabaBillRepository; use Modules\EcommerceFinance\Repositories\EdgeBandingRepository; use Modules\EcommerceFinance\Repositories\InventoryRepository; +use Modules\EcommerceFinance\Repositories\JdWalletBillRepository; use Modules\EcommerceFinance\Repositories\PinduoduoSpreadBillRepository; use Modules\EcommerceFinance\Repositories\ProductPriceRepository; use Modules\EcommerceFinance\Repositories\RawBoardPayablesRepository; @@ -939,6 +940,81 @@ class Pages extends Controller ]; } + // 京东钱包 - 按附件表1分别展示充值账单和消耗账单,数据来自 JianSun 上游只读表。 + if ($tab === 'jd-wallet') { + $request = request(); + $ledger = $request->query('jd_ledger') === 'consumption' ? 'consumption' : 'recharge'; + $storeName = mb_substr(trim((string) $request->query('store_name')), 0, 191); + $fromDate = $this->dateFilter($request->query('from')); + $toDate = $this->dateFilter($request->query('to')); + $page = max(1, (int) $request->query('page', 1)); + $pageSize = min(max((int) setting('default.list_limit', 25), 1), 100); + $filters = [ + 'store_name' => $storeName !== '' ? $storeName : null, + 'from' => $fromDate !== '' ? $fromDate : null, + 'to' => $toDate !== '' ? $toDate : null, + ]; + $repository = app(JdWalletBillRepository::class); + $cache = $this->upstreamCaches->forSource('jiansun'); + $scopePrefix = 'jd-wallet-bills.' . $ledger; + $errors = []; + $remember = function (string $scope, array $parameters, callable $resolver, mixed $fallback) use ($cache, &$errors): mixed { + try { + return $cache->remember($scope, $parameters, $resolver); + } catch (ServiceUnavailableHttpException $exception) { + $errors[] = $exception->getMessage(); + } catch (Throwable $exception) { + report($exception); + $errors[] = '京东账单数据暂时无法读取,请稍后重试。'; + } + + return $fallback; + }; + + // 三项分别读取,确保生产冷启动时一次请求就能登记列表、汇总和选项, + // 同时保留已经命中的共享快照,不因另一项暂缺而清空整页。 + $result = $remember( + $scopePrefix . '.list', + ['filters' => $filters, 'page' => $page, 'limit' => $pageSize], + fn () => $ledger === 'consumption' + ? $repository->paginateConsumption($filters['store_name'], $filters['from'], $filters['to'], $page, $pageSize) + : $repository->paginateRecharge($filters['store_name'], $filters['from'], $filters['to'], $page, $pageSize), + ['rows' => [], 'total' => 0], + ); + $summary = $remember( + $scopePrefix . '.summary', + ['filters' => $filters], + fn () => $ledger === 'consumption' + ? $repository->summaryConsumption($filters['store_name'], $filters['from'], $filters['to']) + : $repository->summaryRecharge($filters['store_name'], $filters['from'], $filters['to']), + ['amount_total' => 0, 'balance_total' => 0, 'count' => 0], + ); + $shopOptions = $remember( + 'jd-wallet-bills.options', + [], + fn () => $repository->shopOptions(), + [], + ); + + return [ + 'view' => 'banking.marketing_jd_wallet_bills.partials.embedded-table', + 'ledger' => $ledger, + 'bills' => new LengthAwarePaginator( + Collection::make($result['rows'] ?? []), + (int) ($result['total'] ?? 0), + $pageSize, + $page, + ['path' => $request->url(), 'query' => $request->query()], + ), + 'filters' => $filters, + 'summary' => $summary, + 'shopOptions' => $shopOptions, + 'error' => $errors === [] + ? null + : implode(' ', array_values(array_unique(array_filter($errors)))), + ]; + } + return [ 'view' => 'banking.marketing_account_bills.partials.embedded-table', 'platform' => $tab, diff --git a/modules/EcommerceFinance/Repositories/JdWalletBillRepository.php b/modules/EcommerceFinance/Repositories/JdWalletBillRepository.php new file mode 100644 index 00000000..77d9f126 --- /dev/null +++ b/modules/EcommerceFinance/Repositories/JdWalletBillRepository.php @@ -0,0 +1,187 @@ +query = $factory->forSource(self::SOURCE); + } + + /** @return string[] */ + public function shopOptions(): array + { + $rows = $this->query->select( + "SELECT TOP (500) shopName FROM (SELECT shopName FROM " . self::RECHARGE_TABLE + . " UNION SELECT shopName FROM " . self::CONSUMPTION_TABLE + . ") shops WHERE shopName IS NOT NULL AND LTRIM(RTRIM(shopName)) <> '' ORDER BY shopName" + ); + + return array_values(array_map( + static fn (array $row): string => (string) ($row['shopName'] ?? ''), + $rows, + )); + } + + /** @return array{rows: array>, total: int} */ + public function paginateRecharge( + ?string $shopName = null, + ?string $fromDate = null, + ?string $toDate = null, + int $page = 1, + int $pageSize = 25, + ): array { + return $this->paginate(self::RECHARGE_TABLE, $this->rechargeWhere($shopName, $fromDate, $toDate), $page, $pageSize, [ + 'id', 'shopName', 'amount', 'balanceAmount', 'orderTypeName', 'pk', + 'createDate', 'updateTime', 'statusName', 'remark', + ], 'createDate', 'id', fn (array $row): array => $this->normalizeRecharge($row)); + } + + /** @return array{rows: array>, total: int} */ + public function paginateConsumption( + ?string $shopName = null, + ?string $fromDate = null, + ?string $toDate = null, + int $page = 1, + int $pageSize = 25, + ): array { + return $this->paginate(self::CONSUMPTION_TABLE, $this->consumptionWhere($shopName, $fromDate, $toDate), $page, $pageSize, [ + 'id', 'shopName', 'amount', 'balanceAmount', 'orderTypeName', 'creatTime', 'settleTime', 'pk', + 'invoiceApplyTypeName', + ], 'creatTime', 'id', fn (array $row): array => $this->normalizeConsumption($row)); + } + + /** @return array{amount_total: float, balance_total: float, count: int} */ + public function summaryRecharge(?string $shopName = null, ?string $fromDate = null, ?string $toDate = null): array + { + return $this->summary(self::RECHARGE_TABLE, $this->rechargeWhere($shopName, $fromDate, $toDate)); + } + + /** @return array{amount_total: float, balance_total: float, count: int} */ + public function summaryConsumption(?string $shopName = null, ?string $fromDate = null, ?string $toDate = null): array + { + return $this->summary(self::CONSUMPTION_TABLE, $this->consumptionWhere($shopName, $fromDate, $toDate)); + } + + /** @param array{sql:string,bindings:array} $where */ + private function paginate(string $table, array $where, int $page, int $pageSize, array $fields, string $dateField, string $idField, callable $normalize): array + { + $page = max(1, $page); + $pageSize = min(max(1, $pageSize), 100); + $total = (int) $this->query->scalar('SELECT COUNT(*) FROM ' . $table . ' src' . $where['sql'], $where['bindings']); + + if ($total === 0) { + return ['rows' => [], 'total' => 0]; + } + + $start = (($page - 1) * $pageSize) + 1; + $end = $page * $pageSize; + $select = implode(', ', array_map(static fn (string $field): string => 'src.' . $field, $fields)); + $sql = 'SELECT * FROM (' + . 'SELECT ' . $select . ', ROW_NUMBER() OVER (ORDER BY src.' . $dateField . ' DESC, src.' . $idField . ' DESC) AS rn ' + . 'FROM ' . $table . ' src' . $where['sql'] + . ') AS t WHERE t.rn BETWEEN ? AND ? ORDER BY t.rn'; + $rows = $this->query->select($sql, array_merge($where['bindings'], [$start, $end])); + + return ['rows' => array_map($normalize, $rows), 'total' => $total]; + } + + /** @param array{sql:string,bindings:array} $where */ + private function summary(string $table, array $where): array + { + $row = $this->query->first( + 'SELECT COALESCE(SUM(ABS(amount)), 0) AS amount_total, COALESCE(SUM(balanceAmount), 0) AS balance_total, COUNT(*) AS cnt FROM ' + . $table . ' src' . $where['sql'], + $where['bindings'], + ) ?? []; + + return [ + 'amount_total' => round((float) ($row['amount_total'] ?? 0), 2), + 'balance_total' => round((float) ($row['balance_total'] ?? 0), 2), + 'count' => (int) ($row['cnt'] ?? 0), + ]; + } + + /** @return array{sql:string,bindings:array} */ + private function rechargeWhere(?string $shopName, ?string $fromDate, ?string $toDate): array + { + return $this->dateWhere('src.createDate', $shopName, $fromDate, $toDate); + } + + /** @return array{sql:string,bindings:array} */ + private function consumptionWhere(?string $shopName, ?string $fromDate, ?string $toDate): array + { + return $this->dateWhere('src.creatTime', $shopName, $fromDate, $toDate); + } + + /** @return array{sql:string,bindings:array} */ + private function dateWhere(string $dateField, ?string $shopName, ?string $fromDate, ?string $toDate): array + { + $conditions = []; + $bindings = []; + if ($shopName !== null && $shopName !== '') { + $conditions[] = 'src.shopName = ?'; + $bindings[] = $shopName; + } + if ($fromDate !== null && preg_match('/^\d{4}-\d{2}-\d{2}$/', $fromDate) === 1) { + $conditions[] = $dateField . ' >= ?'; + $bindings[] = $fromDate . ' 00:00:00'; + } + if ($toDate !== null && preg_match('/^\d{4}-\d{2}-\d{2}$/', $toDate) === 1) { + $conditions[] = $dateField . ' < DATEADD(day, 1, CAST(? AS date))'; + $bindings[] = $toDate; + } + + return ['sql' => $conditions === [] ? '' : ' WHERE ' . implode(' AND ', $conditions), 'bindings' => $bindings]; + } + + private function normalizeRecharge(array $row): array + { + return [ + 'id' => (string) ($row['id'] ?? $row['pk'] ?? ''), + 'store_name' => (string) ($row['shopName'] ?? ''), + 'amount' => round((float) ($row['amount'] ?? 0), 2), + 'balance' => round((float) ($row['balanceAmount'] ?? 0), 2), + 'transaction_type' => (string) ($row['orderTypeName'] ?? ''), + 'order_number' => (string) ($row['pk'] ?? ''), + 'recharge_time' => (string) ($row['createDate'] ?? ''), + 'arrival_time' => (string) ($row['updateTime'] ?? ''), + 'serial_number' => (string) ($row['id'] ?? $row['pk'] ?? ''), + 'status' => (string) ($row['statusName'] ?? ''), + 'notes' => (string) ($row['remark'] ?? ''), + ]; + } + + private function normalizeConsumption(array $row): array + { + $amount = abs((float) ($row['amount'] ?? 0)); + + return [ + 'id' => (string) ($row['id'] ?? $row['pk'] ?? ''), + 'store_name' => (string) ($row['shopName'] ?? ''), + 'amount' => round($amount, 2), + 'balance' => round((float) ($row['balanceAmount'] ?? 0), 2), + 'transaction_type' => (string) ($row['orderTypeName'] ?? ''), + 'investment_date' => (string) ($row['creatTime'] ?? ''), + 'settlement_date' => (string) ($row['settleTime'] ?? ''), + 'serial_number' => (string) ($row['pk'] ?? $row['id'] ?? ''), + 'notes' => (string) ($row['invoiceApplyTypeName'] ?? ''), + ]; + } +} diff --git a/modules/EcommerceFinance/Services/JianSunSnapshotRefresher.php b/modules/EcommerceFinance/Services/JianSunSnapshotRefresher.php index c0a38bbe..3a9f8a28 100644 --- a/modules/EcommerceFinance/Services/JianSunSnapshotRefresher.php +++ b/modules/EcommerceFinance/Services/JianSunSnapshotRefresher.php @@ -8,6 +8,7 @@ use Modules\EcommerceFinance\Repositories\AlibabaBillRepository; use Modules\EcommerceFinance\Repositories\EdgeBandingRepository; use Modules\EcommerceFinance\Repositories\GoodsReconciliationRepository; use Modules\EcommerceFinance\Repositories\InventoryRepository; +use Modules\EcommerceFinance\Repositories\JdWalletBillRepository; use Modules\EcommerceFinance\Repositories\PinduoduoSpreadBillRepository; use Modules\EcommerceFinance\Repositories\ProductPriceRepository; use Modules\EcommerceFinance\Repositories\RawBoardPayablesRepository; @@ -32,6 +33,7 @@ class JianSunSnapshotRefresher implements UpstreamSnapshotRefresher private readonly TmallTaobaoSpreadBillRepository $taobaoAlipay, private readonly SupplierPayableRepository $supplier, private readonly SupplierPayableReportRepository $supplierPayableReports, + private readonly JdWalletBillRepository $jdWallet, ) { } @@ -112,6 +114,32 @@ class JianSunSnapshotRefresher implements UpstreamSnapshotRefresher ), 'pinduoduo-bills.options' => $this->pinduoduo->storeOptions(), + 'jd-wallet-bills.recharge.list' => $this->jdWallet->paginateRecharge( + $storeName, + $fromDate, + $toDate, + $page, + $limit, + ), + 'jd-wallet-bills.recharge.summary' => $this->jdWallet->summaryRecharge( + $storeName, + $fromDate, + $toDate, + ), + 'jd-wallet-bills.consumption.list' => $this->jdWallet->paginateConsumption( + $storeName, + $fromDate, + $toDate, + $page, + $limit, + ), + 'jd-wallet-bills.consumption.summary' => $this->jdWallet->summaryConsumption( + $storeName, + $fromDate, + $toDate, + ), + 'jd-wallet-bills.options' => $this->jdWallet->shopOptions(), + 'taobao-alipay-bills.list' => $this->taobaoAlipay->paginate( $storeName, $fromDate, diff --git a/resources/assets/js/views/business/marketing-account-bills.js b/resources/assets/js/views/business/marketing-account-bills.js new file mode 100644 index 00000000..8a301b5f --- /dev/null +++ b/resources/assets/js/views/business/marketing-account-bills.js @@ -0,0 +1,206 @@ +/** + * 营销账户账单页面的服务端局部导航。 + * + * 链接始终保留完整 href 作为渐进增强回退;普通左键操作只替换当前 + * 工作区并同步 History,避免平台标签、京东账单类型、筛选和分页触发整页刷新。 + */ +(function () { + const workspaceSelector = '[data-marketing-account-bills-workspace]'; + const pagePathMarker = '/workspace/billing-transactions/marketing-account-bills'; + let activeRequest = null; + + function currentWorkspace() { + return document.querySelector(workspaceSelector); + } + + function isSupportedUrl(url) { + const target = new URL(url, window.location.origin); + + return target.origin === window.location.origin + && target.pathname.indexOf(pagePathMarker) !== -1; + } + + function updateHeader(nextDocument) { + const currentHeader = document.querySelector('[data-page-title-first]'); + const nextHeader = nextDocument.querySelector('[data-page-title-first]'); + + if (currentHeader && nextHeader) { + currentHeader.innerHTML = nextHeader.innerHTML; + } + + if (nextDocument.title) { + document.title = nextDocument.title; + } + } + + function setLoading(workspace, loading) { + const status = workspace.querySelector('[data-marketing-account-bills-status]'); + + if (loading) { + workspace.setAttribute('aria-busy', 'true'); + if (status) { + status.textContent = '正在加载账单数据'; + } + } else { + workspace.removeAttribute('aria-busy'); + } + } + + function showError(workspace, url) { + const error = workspace.querySelector('[data-marketing-account-bills-navigation-error]'); + const status = workspace.querySelector('[data-marketing-account-bills-status]'); + + setLoading(workspace, false); + + if (status) { + status.textContent = '账单内容加载失败'; + } + + if (error) { + const retry = error.querySelector('[data-marketing-account-bills-retry]'); + error.hidden = false; + if (retry) { + retry.href = url; + } + } + } + + function initialiseInsertedContent(workspace) { + if (window.Alpine && typeof window.Alpine.initTree === 'function') { + window.Alpine.initTree(workspace); + } + } + + async function navigate(url, options) { + const settings = Object.assign({ pushState: true, focus: null }, options || {}); + const workspace = currentWorkspace(); + + if (!workspace || !isSupportedUrl(url)) { + return false; + } + + if (activeRequest) { + activeRequest.abort(); + } + + const request = new AbortController(); + activeRequest = request; + setLoading(workspace, true); + + try { + const response = await window.fetch(url, { + credentials: 'same-origin', + headers: { + Accept: 'text/html', + 'X-Requested-With': 'XMLHttpRequest', + }, + signal: request.signal, + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const html = await response.text(); + const nextDocument = new DOMParser().parseFromString(html, 'text/html'); + const nextWorkspace = nextDocument.querySelector(workspaceSelector); + + if (!nextWorkspace) { + throw new Error('目标页面缺少营销账单工作区'); + } + + const importedWorkspace = document.importNode(nextWorkspace, true); + workspace.replaceWith(importedWorkspace); + initialiseInsertedContent(importedWorkspace); + updateHeader(nextDocument); + + const target = new URL(url, window.location.origin); + const relativeUrl = `${target.pathname}${target.search}${target.hash}`; + + if (settings.pushState && relativeUrl !== `${window.location.pathname}${window.location.search}${window.location.hash}`) { + window.history.pushState({ marketingAccountBills: true }, '', relativeUrl); + } + + if (settings.focus) { + const focusTarget = importedWorkspace.querySelector(settings.focus); + if (focusTarget) { + window.requestAnimationFrame(() => focusTarget.focus({ preventScroll: true })); + } + } + + return true; + } catch (error) { + if (error.name !== 'AbortError') { + showError(workspace, url); + } + + return false; + } finally { + if (activeRequest === request) { + activeRequest = null; + } + } + } + + document.addEventListener('click', (event) => { + const link = event.target.closest( + `${workspaceSelector} .business-tab-link, ` + + `${workspaceSelector} [data-jd-wallet-navigation], ` + + `${workspaceSelector} .jd-wallet-pagination a` + ); + + if (!link + || link.hasAttribute('data-marketing-account-bills-full-page') + || event.button !== 0 + || event.metaKey + || event.ctrlKey + || event.shiftKey + || event.altKey + || link.target === '_blank' + ) { + return; + } + + if (!isSupportedUrl(link.href)) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + const focusSelector = link.classList.contains('marketing-bills-subtab') + ? '.marketing-bills-subtab.is-active' + : '.business-tab-link.is-active'; + + navigate(link.href, { focus: focusSelector }); + }, true); + + document.addEventListener('submit', (event) => { + const form = event.target.closest(`${workspaceSelector} [data-jd-wallet-filter]`); + + if (!form) { + return; + } + + event.preventDefault(); + const target = new URL(form.action, window.location.origin); + + new FormData(form).forEach((value, key) => { + const normalized = String(value).trim(); + if (normalized === '') { + target.searchParams.delete(key); + } else { + target.searchParams.set(key, normalized); + } + }); + + target.searchParams.delete('page'); + navigate(target.href, { focus: '#jd-filter-store' }); + }, true); + + window.addEventListener('popstate', () => { + if (currentWorkspace() && isSupportedUrl(window.location.href)) { + navigate(window.location.href, { pushState: false }); + } + }); +}()); diff --git a/resources/views/banking/marketing_jd_wallet_bills/partials/embedded-table.blade.php b/resources/views/banking/marketing_jd_wallet_bills/partials/embedded-table.blade.php new file mode 100644 index 00000000..39825cc3 --- /dev/null +++ b/resources/views/banking/marketing_jd_wallet_bills/partials/embedded-table.blade.php @@ -0,0 +1,148 @@ + + + +@php + $ledger = $ledger ?? 'recharge'; + $filters = $filters ?? ['store_name' => '', 'from' => '', 'to' => '']; + $summary = $summary ?? ['amount_total' => 0, 'balance_total' => 0, 'count' => 0]; + $shopOptions = is_array($shopOptions ?? null) ? $shopOptions : []; + $amountWan = (float) ($summary['amount_total'] ?? 0) / 10000; + $balanceWan = (float) ($summary['balance_total'] ?? 0) / 10000; + $isConsumption = $ledger === 'consumption'; + $currentUrl = request()->url(); +@endphp + +
+ + +
+
+
{{ $isConsumption ? '消耗金额合计' : '充值金额合计' }}(万元)
+
{{ number_format($amountWan, 2) }}
+
+
+
余额合计(万元)
+
{{ number_format($balanceWan, 2) }}
+
+
+
账单笔数
+
{{ number_format((int) ($summary['count'] ?? 0)) }}
+
+
+ + @if (! empty($error)) + + @endif + +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + 清除 +
+
共匹配 {{ $bills->total() }} 条
+
+
+ +
+ + + @if ($isConsumption) + + @else + + @endif + + + @forelse ($bills as $bill) + + @if ($isConsumption) + + @else + + @endif + + @empty + + @endforelse + +
店铺名称金额(元)余额(元)交易类型投放日期结算日期流水号店铺名称金额(元)余额(元)交易类型商户订单号充值时间到账时间流水号状态备注
{{ $bill['store_name'] }}{{ number_format($bill['amount'], 2) }}{{ number_format($bill['balance'], 2) }}{{ $bill['transaction_type'] }}{{ $bill['investment_date'] }}{{ $bill['settlement_date'] }}{{ $bill['serial_number'] }}{{ $bill['store_name'] }}{{ number_format($bill['amount'], 2) }}{{ number_format($bill['balance'], 2) }}{{ $bill['transaction_type'] }}{{ $bill['order_number'] }}{{ $bill['recharge_time'] }}{{ $bill['arrival_time'] }}{{ $bill['serial_number'] }}{{ $bill['status'] }}{{ \Illuminate\Support\Str::limit($bill['notes'], 20) }}
当前筛选条件下没有账单,可调整筛选条件后重新查询。
+
+ + @unless ($bills->isEmpty()) +
+ @endunless +
diff --git a/resources/views/business/pages/show.blade.php b/resources/views/business/pages/show.blade.php index 302737ca..c3bed1be 100644 --- a/resources/views/business/pages/show.blade.php +++ b/resources/views/business/pages/show.blade.php @@ -1,23 +1,23 @@ +@php + $isMarketingAccountBillsPage = ($section['slug'] ?? null) === 'billing-transactions' + && ($page['slug'] ?? null) === 'marketing-account-bills'; + $marketingAccountTabTitles = [ + 'taobao-wechat' => 'Alibaba', + 'jd-wallet' => '京东', + ]; + $activeContentTitle = $activeTab['title'] ?? ($page['title'] ?? $section['title']); + + if ($isMarketingAccountBillsPage && isset($marketingAccountTabTitles[$activeTab['slug'] ?? null])) { + $activeContentTitle = $marketingAccountTabTitles[$activeTab['slug']]; + } +@endphp + - {{ $activeTab['title'] ?? ($page['title'] ?? $section['title']) }} + {{ $activeContentTitle }} - @php - $isMarketingAccountBillsPage = ($section['slug'] ?? null) === 'billing-transactions' - && ($page['slug'] ?? null) === 'marketing-account-bills'; - $activeContentTitle = $activeTab['title'] ?? ($page['title'] ?? $section['title']); - - if ($isMarketingAccountBillsPage && ($activeTab['slug'] ?? null) === 'taobao-wechat') { - $activeContentTitle = 'Alibaba'; - } - - if ($isMarketingAccountBillsPage && ($activeTab['slug'] ?? null) === 'jd-wallet') { - $activeContentTitle = '京东'; - } - @endphp - -
$isMarketingAccountBillsPage, - ])> +
$isMarketingAccountBillsPage, + ]) + @if ($isMarketingAccountBillsPage) data-marketing-account-bills-workspace @endif + > + @if ($isMarketingAccountBillsPage) +

+ + @endif @if (is_string(session('success')))
{{ session('success') }}
@endif @@ -410,15 +420,9 @@