From 2bedb72fb751e68db96404249c440127c482637a Mon Sep 17 00:00:00 2001 From: shanshi <3316401569@qq.com> Date: Sat, 24 Oct 2026 19:19:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=B4=A2=E5=8A=A1=E5=8F=B0=E8=B4=A6):=20?= =?UTF-8?q?=E6=B3=95=E4=BA=BA=E7=AD=9B=E9=80=89=E6=98=BE=E7=A4=BA=E8=B4=A6?= =?UTF-8?q?=E6=88=B7=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Business/FinanceLedger.php | 42 +++++++++-- .../FinanceLedgerAccountKeepTodoTest.php | 74 +++++++++++++++++++ 2 files changed, 110 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Business/FinanceLedger.php b/app/Http/Controllers/Business/FinanceLedger.php index 188933cf..0aabfda1 100644 --- a/app/Http/Controllers/Business/FinanceLedger.php +++ b/app/Http/Controllers/Business/FinanceLedger.php @@ -363,9 +363,22 @@ class FinanceLedger extends Controller if (isset($textFilterColumns[$headerFilterColumn])) { $query->where($textFilterColumns[$headerFilterColumn], 'like', '%' . $headerFilterValue . '%'); } elseif ($headerFilterColumn === 'legal_representative') { - $matchingCompanies = collect($legalRepresentatives) - ->filter(static fn ($name): bool => str_contains((string) $name, $headerFilterValue)) - ->keys() + $legalFilterValue = trim((string) preg_replace('/[((]\d+[))]\s*$/u', '', $headerFilterValue)); + $allCompanyNames = $headerOptionRows + ->pluck('company_name') + ->map(static fn ($name): string => trim((string) $name)) + ->filter() + ->unique() + ->values(); + $matchingEmptyValues = in_array($legalFilterValue, ['__empty__', '未填写'], true); + $matchingCompanies = $allCompanyNames + ->filter(static function ($companyName) use ($legalRepresentatives, $legalFilterValue, $matchingEmptyValues): bool { + $representative = trim((string) ($legalRepresentatives[$companyName] ?? '')); + + return $matchingEmptyValues + ? $representative === '' + : str_contains($representative, $legalFilterValue); + }) ->all(); if ($matchingCompanies === []) { $query->whereRaw('1 = 0'); @@ -436,6 +449,12 @@ class FinanceLedger extends Controller } } + $legalRepresentativeCountSource = in_array($headerFilterColumn, ['', 'legal_representative'], true) + ? $headerOptionRows->pluck('company_name') + : (clone $query) + ->reorder() + ->select('accounts.company_name') + ->pluck('accounts.company_name'); $summaryQuery = clone $query; $summary = [ 'count' => (clone $query)->count(), @@ -541,12 +560,23 @@ class FinanceLedger extends Controller }; $hasEmpty = static fn (string $column): bool => $headerOptionRows ->contains(static fn ($row): bool => trim((string) ($row->{$column} ?? '')) === ''); + $legalRepresentativeCounts = $legalRepresentativeCountSource->countBy( + static fn ($companyName): string => trim((string) ($legalRepresentatives[trim((string) $companyName)] ?? '')), + ); + $legalRepresentativeOptions = []; + if (($legalRepresentativeCounts[''] ?? 0) > 0) { + $legalRepresentativeOptions[] = '未填写(' . $legalRepresentativeCounts[''] . ')'; + } + $legalRepresentativeCounts + ->except(['']) + ->sortKeys(SORT_NATURAL | SORT_FLAG_CASE) + ->each(static function ($count, $name) use (&$legalRepresentativeOptions): void { + $legalRepresentativeOptions[] = $name . '(' . $count . ')'; + }); $keepHeaderOptions = [ 'company_name' => $headerOptionValues($headerOptionRows->pluck('company_name'), $hasEmpty('company_name')), 'account_short' => $headerOptionValues($headerOptionRows->pluck('account_short'), $hasEmpty('account_short')), - 'legal_representative' => $headerOptionValues(array_values($legalRepresentatives), $headerOptionRows->contains( - static fn ($row): bool => trim((string) ($legalRepresentatives[trim((string) $row->company_name)] ?? '')) === '', - )), + 'legal_representative' => $legalRepresentativeOptions, 'account_type' => $headerOptionValues($typeOptions, true), 'account_status' => $headerOptionValues(array_values(FinanceLedgerAccountStatus::OPTIONS)), 'account_no' => $headerOptionValues($headerOptionRows->pluck('account_no'), $hasEmpty('account_no')), diff --git a/tests/Feature/Business/FinanceLedgerAccountKeepTodoTest.php b/tests/Feature/Business/FinanceLedgerAccountKeepTodoTest.php index d88cb3b3..fbadddb4 100644 --- a/tests/Feature/Business/FinanceLedgerAccountKeepTodoTest.php +++ b/tests/Feature/Business/FinanceLedgerAccountKeepTodoTest.php @@ -303,6 +303,80 @@ class FinanceLedgerAccountKeepTodoTest extends FeatureTestCase $this->assertSame(['排序账户甲', '排序账户乙'], $sort('current_progress', 'desc')); } + public function test_legal_representative_filter_options_show_account_counts(): void + { + $connection = DB::connection('business_mirror'); + $connection->table('fin_accounts')->insert([ + [ + 'company_name' => '法人计数公司甲', + 'account_short' => '法人计数甲一', + 'account_type' => '网商银行', + 'company_plan' => '保留', + 'account_should_keep' => '否', + ], + [ + 'company_name' => '法人计数公司甲', + 'account_short' => '法人计数甲二', + 'account_type' => '公户', + 'company_plan' => '保留', + 'account_should_keep' => '否', + ], + [ + 'company_name' => '法人计数公司乙', + 'account_short' => '法人计数乙', + 'account_type' => '网商银行', + 'company_plan' => '保留', + 'account_should_keep' => '否', + ], + ]); + $connection->table('ops_fys_company_info')->insert([ + 'Id' => 31, + 'businessLicenseName' => '法人计数公司甲', + 'legalRepresentative' => '王法人', + ]); + + $optionsResponse = $this->loginAs()->get($this->keepTasksUrl())->assertOk(); + preg_match( + '/(.*?)<\/datalist>/su', + $optionsResponse->getContent(), + $legalRepresentativeOptions, + ); + $legalRepresentativeOptions = $legalRepresentativeOptions[1] ?? ''; + $this->assertStringContainsString('value="王法人(2)"', $legalRepresentativeOptions); + $this->assertStringContainsString('value="未填写(1)"', $legalRepresentativeOptions); + $this->assertStringNotContainsString('__empty__', $legalRepresentativeOptions); + + $typeFilteredResponse = $this->loginAs()->get($this->keepTasksUrl([ + 'keep_filter_column' => 'account_type', + 'keep_filter_value' => '网商银行', + ]))->assertOk(); + preg_match( + '/(.*?)<\/datalist>/su', + $typeFilteredResponse->getContent(), + $typeFilteredLegalOptions, + ); + $typeFilteredLegalOptions = $typeFilteredLegalOptions[1] ?? ''; + $this->assertStringContainsString('value="王法人(1)"', $typeFilteredLegalOptions); + $this->assertStringContainsString('value="未填写(1)"', $typeFilteredLegalOptions); + $this->assertStringNotContainsString('王法人(2)', $typeFilteredLegalOptions); + + $this->loginAs()->get($this->keepTasksUrl([ + 'keep_filter_column' => 'legal_representative', + 'keep_filter_value' => '王法人(2)', + ]))->assertOk() + ->assertSee('data-keep-account="法人计数甲一"', false) + ->assertSee('data-keep-account="法人计数甲二"', false) + ->assertDontSee('data-keep-account="法人计数乙"', false); + + $this->loginAs()->get($this->keepTasksUrl([ + 'keep_filter_column' => 'legal_representative', + 'keep_filter_value' => '未填写(1)', + ]))->assertOk() + ->assertSee('data-keep-account="法人计数乙"', false) + ->assertDontSee('data-keep-account="法人计数甲一"', false) + ->assertDontSee('data-keep-account="法人计数甲二"', false); + } + public function test_keep_tasks_header_filters_apply_with_typeahead_options(): void { $connection = DB::connection('business_mirror'); -- 2.47.2