diff --git a/app/Business/UpstreamBusinessInformation.php b/app/Business/UpstreamBusinessInformation.php index 7a073679..898742ff 100644 --- a/app/Business/UpstreamBusinessInformation.php +++ b/app/Business/UpstreamBusinessInformation.php @@ -68,11 +68,19 @@ class UpstreamBusinessInformation private function shopInfoFlowPage(int $page, int $perPage): array { try { - return app(\Modules\EcommerceFinance\Repositories\ShopInfoFlowMirrorRepository::class)->paginate( + $repository = app(\Modules\EcommerceFinance\Repositories\ShopInfoFlowMirrorRepository::class); + $filters = $this->pageFilters('financial-risk-control', 'process-statistics'); + $payload = $repository->paginate( $page, $perPage, - $this->pageFilters('financial-risk-control', 'process-statistics'), + $filters, ); + request()->attributes->set( + 'process-statistics.current-approvers', + $repository->currentApproverOptions($filters), + ); + + return $payload; } catch (\RuntimeException $exception) { report($exception); diff --git a/modules/EcommerceFinance/Repositories/ShopInfoFlowMirrorRepository.php b/modules/EcommerceFinance/Repositories/ShopInfoFlowMirrorRepository.php index fff01789..9229726d 100644 --- a/modules/EcommerceFinance/Repositories/ShopInfoFlowMirrorRepository.php +++ b/modules/EcommerceFinance/Repositories/ShopInfoFlowMirrorRepository.php @@ -116,6 +116,37 @@ class ShopInfoFlowMirrorRepository return ['data' => $rows, 'total' => $total]; } + /** @param array $filters + * @return list + */ + public function currentApproverOptions(array $filters = []): array + { + if (! $this->ready()) { + return []; + } + + $connection = $this->mirror->connection(); + $form = $this->datasets->get(self::FORM_DATASET)->targetTable(); + $flow = $this->datasets->get(self::FLOW_DATASET)->targetTable(); + unset($filters['current_approver']); + + $query = $connection->table($form . ' as f') + ->leftJoin($flow . ' as o', 'o.flowId', '=', 'f.flowId') + ->whereNotNull('o.approver') + ->where('o.approver', '!=', ''); + $this->applyFilters($query, $filters); + + return $query + ->pluck('o.approver') + ->flatMap(static fn (mixed $value): array => preg_split('/[,,]/u', (string) $value, -1, PREG_SPLIT_NO_EMPTY) ?: []) + ->map(static fn (mixed $value): string => trim((string) $value)) + ->filter(static fn (string $value): bool => $value !== '') + ->unique() + ->sort(static fn (string $left, string $right): int => strnatcasecmp($left, $right)) + ->values() + ->all(); + } + /** @param array $filters */ private function applyFilters(Builder $query, array $filters): void { diff --git a/resources/views/business/pages/partials/directory-table.blade.php b/resources/views/business/pages/partials/directory-table.blade.php index 405318ee..78ede8ba 100644 --- a/resources/views/business/pages/partials/directory-table.blade.php +++ b/resources/views/business/pages/partials/directory-table.blade.php @@ -1921,6 +1921,12 @@ default => [], }; $directoryMultiSelectFields = array_keys($directoryMultiSelectOptions); + $directoryQuerySuggestionOptions = match (($section['slug'] ?? '') . '/' . ($page['slug'] ?? '')) { + 'financial-risk-control/process-statistics' => [ + 'current_approver' => (array) request()->attributes->get('process-statistics.current-approvers', []), + ], + default => [], + }; $directoryColumnNames = collect($directoryFields)->pluck('name')->all(); $requestedDirectoryColumns = array_values(array_intersect( array_filter(explode(',', (string) request('columns', ''))), @@ -2033,7 +2039,7 @@ @endforeach @else - + @endif @@ -2088,7 +2094,7 @@ @endforeach @else - + @endif @@ -3717,11 +3723,19 @@ if (!list) return; const key = field.dataset.directoryQueryField; const needle = value.trim().toLocaleLowerCase(); + let serverOptions = []; + try { + serverOptions = JSON.parse(field.querySelector('[data-directory-server-options]')?.dataset.directoryServerOptions || '[]') || []; + } catch (_) { + serverOptions = []; + } const candidates = key === 'related_people' ? rows().flatMap((row) => ['legal_representative', 'shareholders', 'supervisor', 'billing_officer'] .map((column) => (row.querySelector(`[data-column-key="${column}"]`)?.textContent || '').trim())) : rows().map((row) => fieldValues(row, key)); - const values = [...new Set(candidates.filter((item) => item && item !== '—' && (!needle || item.toLocaleLowerCase().includes(needle))))].slice(0, 8); + const values = [...new Set([...serverOptions, ...candidates].filter( + (item) => item && item !== '—' && (!needle || String(item).toLocaleLowerCase().includes(needle)), + ))].slice(0, 8); list.innerHTML = values.map((item) => `
  • `).join(''); list.hidden = values.length === 0; list.querySelectorAll('button').forEach((button) => button.addEventListener('click', () => { diff --git a/tests/Unit/EcommerceFinance/ShopInfoFlowMirrorRepositoryTest.php b/tests/Unit/EcommerceFinance/ShopInfoFlowMirrorRepositoryTest.php index 95859a2c..123c4dd4 100644 --- a/tests/Unit/EcommerceFinance/ShopInfoFlowMirrorRepositoryTest.php +++ b/tests/Unit/EcommerceFinance/ShopInfoFlowMirrorRepositoryTest.php @@ -139,6 +139,46 @@ class ShopInfoFlowMirrorRepositoryTest extends TestCase $this->assertSame(0, $this->repository->paginate(1, 10, ['flow_id' => '不存在'])['total']); } + public function test_current_approver_options_include_all_rows_matching_other_filters(): void + { + $db = DB::connection('business_mirror'); + foreach ([ + [10, 'approver-1', '查查'], + [11, 'approver-2', '玉兔'], + [12, 'approver-3', '查查,常仪'], + ] as [$id, $flowId, $approver]) { + $this->insertApplication( + $id, + $flowId, + 10, + '京东', + '审批人测试' . $id, + 'ERP-审批人测试' . $id, + '申请人' . $id, + '2026-10-05 09:00:00', + ); + $db->table('oa_flow_flow')->insert([ + 'Id' => $id, + 'flowId' => $flowId, + 'flowType' => 10, + 'flowStatus' => 1, + 'subject' => '[店铺关店-审批人测试' . $id . ']', + 'approver' => $approver, + 'updateTime' => '2026-10-05 10:00:00', + ]); + } + + $options = $this->repository->currentApproverOptions([ + 'flow_type' => ['店铺关店'], + 'current_approver' => '玉兔', + ]); + + $this->assertEqualsCanonicalizing(['查查', '玉兔', '常仪'], $options); + $this->assertSame(['审核人A'], $this->repository->currentApproverOptions([ + 'flow_type' => ['店铺变更'], + ])); + } + public function test_it_groups_waiting_time_by_days_and_filters_selected_day_buckets(): void { Carbon::setTestNow('2026-11-05 12:00:00');