CaiWuXiTong/app/Business/CourierPayableSummaryFilter.php

121 lines
3.8 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Business;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
class CourierPayableSummaryFilter
{
/** @return array{date:string,person:string,courier:string,keyword:string} */
public function fromRequest(Request $request): array
{
$clean = static function (string $key, int $maxLength) use ($request): string {
$value = $request->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<int, mixed> $rows
* @param list<string> $headers
* @param array{date:string,person:string,courier:string,keyword:string} $filters
* @return Collection<int, mixed>
*/
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<string> $headers */
public function dateColumnIndex(array $headers): ?int
{
return $this->columnIndex($headers, ['日期', '结算月份', '结算月', '月份']);
}
/** @param list<string> $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;
}
}