From 0d4df8e65d082cf0aa8b7893ab562b20204547f3 Mon Sep 17 00:00:00 2001 From: shanshi <3316401569@qq.com> Date: Wed, 21 Oct 2026 17:03:01 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A2=E5=8A=A1=E5=8F=B0=E8=B4=A6=EF=BC=9A?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E9=87=91=E9=A2=9D=E6=8C=89=E4=B8=87=E5=85=83?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E5=B9=B6=E5=A2=9E=E5=8A=A0=E4=BD=99=E9=A2=9D?= =?UTF-8?q?=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/FinanceLedgerPageData.php | 9 +++ .../pages/financial-ledger/ledger.blade.php | 57 +++++++++++-- .../FinanceLedgerAccountStatusTest.php | 81 ++++++++++++++++++- 3 files changed, 140 insertions(+), 7 deletions(-) diff --git a/modules/EcommerceFinance/View/FinanceLedgerPageData.php b/modules/EcommerceFinance/View/FinanceLedgerPageData.php index 56c540f8..f9ad2be5 100644 --- a/modules/EcommerceFinance/View/FinanceLedgerPageData.php +++ b/modules/EcommerceFinance/View/FinanceLedgerPageData.php @@ -147,6 +147,15 @@ class FinanceLedgerPageData }); } + $balanceRange = trim((string) request('accounts_balance', '')); + if ($balanceRange === '0-5') { + $query->where('current_balance', '>=', 0)->where('current_balance', '<', 50000); + } elseif ($balanceRange === '5-20') { + $query->where('current_balance', '>=', 50000)->where('current_balance', '<', 200000); + } elseif ($balanceRange === '20-plus') { + $query->where('current_balance', '>=', 200000); + } + $summaryQuery = clone $query; $summary = [ 'count' => (clone $query)->count(), diff --git a/resources/views/business/pages/financial-ledger/ledger.blade.php b/resources/views/business/pages/financial-ledger/ledger.blade.php index 92e221e5..2948fa5e 100644 --- a/resources/views/business/pages/financial-ledger/ledger.blade.php +++ b/resources/views/business/pages/financial-ledger/ledger.blade.php @@ -17,8 +17,40 @@ request('accounts_status'), request('accounts_region'), request('accounts_type'), + request('accounts_balance'), ], static fn ($value): bool => trim((string) $value) !== '')); $money = static fn ($value): string => $value === null || $value === '' ? '' : number_format((float) $value, 2); + $moneyWan = static function ($value): string { + if ($value === null || trim((string) $value) === '') { + return ''; + } + + $text = trim((string) $value); + $parts = preg_split('/\s*\/\s*/', $text); + if (! is_array($parts) || count($parts) > 2) { + return $text; + } + + $converted = []; + foreach ($parts as $part) { + $normalized = str_replace([',', ' '], '', $part); + if (! is_numeric($normalized)) { + return $text; + } + $converted[] = number_format((float) $normalized / 10000, 2); + } + + return implode(' / ', $converted); + }; + $moneyYuanTitle = static function ($value): string { + if ($value === null || trim((string) $value) === '') { + return ''; + } + + $normalized = str_replace([',', ' '], '', trim((string) $value)); + + return is_numeric($normalized) ? number_format((float) $normalized, 2) . ' 元' : trim((string) $value); + }; $date = static fn ($value): string => $value ? \Illuminate\Support\Carbon::parse($value)->format('Y-m-d') : ''; $ledgerPageUrl = route('business.pages.show', ['section' => 'financial-operations', 'page' => 'ledger']); $tabUrl = static fn (string $tab): string => $ledgerPageUrl . '?' . http_build_query(['tab' => $tab]); @@ -208,6 +240,7 @@
+
@if ($activeAccountFilterCount > 0) 筛选中{{ $activeAccountFilterCount }} @endif @@ -229,13 +262,13 @@
账户数{{ number_format((int) ($ledgerAccountSummary['count'] ?? 0)) }}
-
可用金额合计{{ $money($ledgerAccountSummary['balance'] ?? 0) }}
- 不可用金额合计{{ $money($ledgerAccountSummary['blocked'] ?? 0) }} +
可用金额合计(万元){{ $moneyWan($ledgerAccountSummary['balance'] ?? 0) }}
+ 不可用金额合计(万元){{ $moneyWan($ledgerAccountSummary['blocked'] ?? 0) }}
金额口径正常计可用,异常计不可用
- + @forelse ($ledgerAccounts as $row) @@ -289,7 +322,7 @@ @endif - + @empty @@ -972,6 +1005,11 @@ const currentCell = row?.querySelector('[data-account-current-balance]'); const currentAmount = Number(currentCell?.dataset.accountCurrentBalance || 0); const currentText = currentCell?.textContent?.trim() || '0.00'; + const currentAmountWan = currentAmount / 10000; + const currentYuanTitle = currentCell?.title || currentAmount.toLocaleString('zh-CN', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) + ' 元'; const nextNormal = value === 'normal'; const previousNormal = previous === 'normal'; const availableCell = row?.querySelector('[data-account-available-amount]'); @@ -980,24 +1018,31 @@ if (availableCell) availableCell.textContent = nextNormal ? currentText : '0.00'; if (blockedCell) blockedCell.textContent = nextNormal ? '0.00' : currentText; if (dailyAvailableCell) dailyAvailableCell.textContent = nextNormal ? currentText : '0.00'; + if (availableCell) availableCell.title = nextNormal ? currentYuanTitle : '0.00 元'; + if (blockedCell) blockedCell.title = nextNormal ? '0.00 元' : currentYuanTitle; + if (dailyAvailableCell) dailyAvailableCell.title = nextNormal ? currentYuanTitle : '0.00 元'; if (nextNormal !== previousNormal) { const formatSummaryAmount = (amount) => amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2, }); - const adjustSummary = (card, delta) => { + const adjustSummary = (card, displayDelta, yuanDelta) => { const valueNode = card?.querySelector('b'); if (!valueNode) return; const current = Number(valueNode.textContent.replace(/,/g, '')) || 0; - valueNode.textContent = formatSummaryAmount(Math.max(0, current + delta)); + valueNode.textContent = formatSummaryAmount(Math.max(0, current + displayDelta)); + const currentYuan = Number((valueNode.title || '').replace(/[^\d.-]/g, '')) || 0; + valueNode.title = formatSummaryAmount(Math.max(0, currentYuan + yuanDelta)) + ' 元'; }; adjustSummary( page.querySelector('[data-ledger-summary-available]'), + nextNormal ? currentAmountWan : -currentAmountWan, nextNormal ? currentAmount : -currentAmount, ); adjustSummary( page.querySelector('[data-ledger-summary-blocked]'), + nextNormal ? -currentAmountWan : currentAmountWan, nextNormal ? -currentAmount : currentAmount, ); } diff --git a/tests/Feature/Business/FinanceLedgerAccountStatusTest.php b/tests/Feature/Business/FinanceLedgerAccountStatusTest.php index d841d14a..06032d7b 100644 --- a/tests/Feature/Business/FinanceLedgerAccountStatusTest.php +++ b/tests/Feature/Business/FinanceLedgerAccountStatusTest.php @@ -94,6 +94,10 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase ->assertSee('name="accounts_status"', false) ->assertSee('name="accounts_region"', false) ->assertSee('name="accounts_type"', false) + ->assertSee('name="accounts_balance"', false) + ->assertSee('0-5万') + ->assertSee('5-20万') + ->assertSee('20万以上') ->assertSee('data-account-type', false) ->assertSee('data-account-plan', false) ->assertSee('data-account-keep', false) @@ -124,10 +128,11 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase ->assertSee('恢复默认') ->assertSee('可用金额合计') ->assertSee('不可用金额合计') + ->assertSee('可用金额合计(万元)') ->assertSee('href="' . $this->unavailableBalancesUrl() . '"', false) ->assertSee('查看账户异常待办') ->assertSee('正常计可用,异常计不可用') - ->assertSee('', false) + ->assertSee('', false) ->assertSee('data-ledger-summary-available', false) ->assertSee('data-account-current-balance="321.45"', false) ->assertSee('data-account-available-amount', false) @@ -137,6 +142,80 @@ class FinanceLedgerAccountStatusTest extends FeatureTestCase ->assertSee('value="normal" selected', false); } + public function test_account_balance_filter_uses_non_overlapping_ranges(): void + { + DB::connection('business_mirror')->table('fin_accounts')->insert([ + ['company_name' => '余额筛选公司', 'account_short' => '余额-负数', 'current_balance' => -1], + ['company_name' => '余额筛选公司', 'account_short' => '余额-0', 'current_balance' => 0], + ['company_name' => '余额筛选公司', 'account_short' => '余额-49999', 'current_balance' => 49999.99], + ['company_name' => '余额筛选公司', 'account_short' => '余额-50000', 'current_balance' => 50000], + ['company_name' => '余额筛选公司', 'account_short' => '余额-199999', 'current_balance' => 199999.99], + ['company_name' => '余额筛选公司', 'account_short' => '余额-200000', 'current_balance' => 200000], + ]); + + $this->loginAs()->get(route('business.pages.show', [ + 'company_id' => $this->company->id, + 'section' => 'financial-operations', + 'page' => 'ledger', + 'accounts_balance' => '0-5', + ])) + ->assertOk() + ->assertSee('data-account-short="余额-0"', false) + ->assertSee('data-account-short="余额-49999"', false) + ->assertDontSee('data-account-short="余额-负数"', false) + ->assertDontSee('data-account-short="余额-50000"', false) + ->assertSee('value="0-5" selected', false); + + $this->loginAs()->get(route('business.pages.show', [ + 'company_id' => $this->company->id, + 'section' => 'financial-operations', + 'page' => 'ledger', + 'accounts_balance' => '5-20', + ])) + ->assertOk() + ->assertSee('data-account-short="余额-50000"', false) + ->assertSee('data-account-short="余额-199999"', false) + ->assertDontSee('data-account-short="余额-49999"', false) + ->assertDontSee('data-account-short="余额-200000"', false); + + $this->loginAs()->get(route('business.pages.show', [ + 'company_id' => $this->company->id, + 'section' => 'financial-operations', + 'page' => 'ledger', + 'accounts_balance' => '20-plus', + ])) + ->assertOk() + ->assertSee('data-account-short="余额-200000"', false) + ->assertDontSee('data-account-short="余额-199999"', false); + } + + public function test_account_table_monetary_columns_are_displayed_in_ten_thousands(): void + { + DB::connection('business_mirror')->table('fin_accounts') + ->where('account_short', '测试账户') + ->update([ + 'current_balance' => 123456.78, + 'daily_available' => 120000, + 'blocked_amount' => 3456.78, + 'single_limit' => '200000/10000', + 'daily_limit' => 300000, + 'monthly_limit' => 400000, + 'yearly_limit' => 500000, + 'raise_target' => 50000, + ]); + + $this->loginAs()->get($this->pageUrl()) + ->assertOk() + ->assertSee('当前余额(万元)') + ->assertSee('单笔限额(万元)') + ->assertSee('title="123,456.78 元"', false) + ->assertSee('>12.35', false) + ->assertSee('>12.00', false) + ->assertSee('>0.35', false) + ->assertSee('>20.00 / 1.00', false) + ->assertSee('>5.00', false); + } + public function test_unavailable_balance_tasks_page_is_separate_and_only_lists_blocked_accounts(): void { $connection = DB::connection('business_mirror'); -- 2.47.2
公司名称账户简称账户类型账户状态地区账号开户行开户城市/网点公司规划账户是否保留后4位单笔限额日限额月限额年限额当前余额可用金额不可用金额每日可出预计出清天数提额目标提额状态提额动作已做动作下一步备注责任人
公司名称账户简称账户类型账户状态地区账号开户行开户城市/网点公司规划账户是否保留后4位单笔限额(万元)日限额(万元)月限额(万元)年限额(万元)当前余额(万元)可用金额(万元)不可用金额(万元)每日可出(万元)预计出清天数提额目标(万元)提额状态提额动作已做动作下一步备注责任人
{{ $row->account_last4 }}{{ $row->single_limit }}{{ $row->daily_limit }}{{ $row->monthly_limit }}{{ $row->yearly_limit }}{{ $money($row->current_balance) }}{{ $money($row->daily_available) }}{{ $money($row->blocked_amount) }}{{ $money($row->daily_available) }}{{ $row->clearing_days !== null ? number_format((float) $row->clearing_days, 2) : '' }}{{ $row->raise_target }}{{ $row->raise_status }}{{ $row->raise_actions }}{{ $row->done_actions }}{{ $row->next_action }}{{ $row->remark }}{{ $row->owner }}{{ $row->account_last4 }}{{ $moneyWan($row->single_limit) }}{{ $moneyWan($row->daily_limit) }}{{ $moneyWan($row->monthly_limit) }}{{ $moneyWan($row->yearly_limit) }}{{ $moneyWan($row->current_balance) }}{{ $moneyWan($row->daily_available) }}{{ $moneyWan($row->blocked_amount) }}{{ $moneyWan($row->daily_available) }}{{ $row->clearing_days !== null ? number_format((float) $row->clearing_days, 2) : '' }}{{ $moneyWan($row->raise_target) }}{{ $row->raise_status }}{{ $row->raise_actions }}{{ $row->done_actions }}{{ $row->next_action }}{{ $row->remark }}{{ $row->owner }}
没有匹配的账户数据。
当前余额可用金额不可用金额当前余额(万元)可用金额(万元)不可用金额(万元)