query($key, ''); if (! is_scalar($value)) { return ''; } return mb_substr(trim((string) $value), 0, $maxLength); }; return [ 'date' => $clean('date', 50), 'person' => $clean('person', 100), 'courier' => $clean('courier', 100), 'keyword' => $clean('keyword', 191), ]; } /** @param array{date:string,person:string,courier:string,keyword:string} $filters */ public function hasFilters(array $filters): bool { return collect($filters)->contains(static fn (string $value): bool => $value !== ''); } /** * @param Collection $rows * @param list $headers * @param array{date:string,person:string,courier:string,keyword:string} $filters * @return Collection */ public function apply(Collection $rows, array $headers, array $filters): Collection { if (! $this->hasFilters($filters)) { return $rows; } $dateColumn = $this->columnIndex($headers, ['日期', '结算月份', '结算月', '月份']); $personColumn = $this->columnIndex($headers, ['负责人', '责任人']); $courierColumn = $this->columnIndex($headers, ['快递公司', '快递名称', '快递名', '快递']); return $rows->filter(function (mixed $row) use ($filters, $dateColumn, $personColumn, $courierColumn): bool { if (! is_array($row)) { return false; } if (! $this->columnMatches($row, $dateColumn, $filters['date']) || ! $this->columnMatches($row, $personColumn, $filters['person']) || ! $this->columnMatches($row, $courierColumn, $filters['courier'])) { return false; } if ($filters['keyword'] === '') { return true; } foreach ($row as $value) { if ($this->contains($value, $filters['keyword'])) { return true; } } return false; }); } /** @param list $headers */ public function dateColumnIndex(array $headers): ?int { return $this->columnIndex($headers, ['日期', '结算月份', '结算月', '月份']); } /** @param list $headers */ private function columnIndex(array $headers, array $aliases): ?int { $normalizedAliases = array_map( static fn (string $alias): string => mb_strtolower(preg_replace('/[\\s ]+/u', '', $alias) ?? $alias), $aliases, ); foreach ($headers as $index => $header) { $normalizedHeader = mb_strtolower(preg_replace('/[\\s ]+/u', '', trim((string) $header)) ?? trim((string) $header)); if (in_array($normalizedHeader, $normalizedAliases, true)) { return (int) $index; } } return null; } private function columnMatches(array $row, ?int $column, string $needle): bool { if ($needle === '') { return true; } return $column !== null && $this->contains($row[$column] ?? '', $needle); } private function contains(mixed $value, string $needle): bool { if (! is_scalar($value) && ! $value instanceof \Stringable) { return false; } return mb_stripos((string) $value, $needle, 0, 'UTF-8') !== false; } }