CaiWuXiTong/app/Jobs/Common/InventoryReportExport.php
2026-09-26 03:21:14 +08:00

77 lines
2.5 KiB
PHP

<?php
namespace App\Jobs\Common;
use App\Abstracts\JobShouldQueue;
use App\Notifications\Common\ExportFailed;
use Illuminate\Support\Facades\File;
use Modules\EcommerceFinance\Repositories\ThirdPartyWarehouseStorageMirrorRepository;
use Throwable;
class InventoryReportExport extends JobShouldQueue
{
/** A complete month can exceed the web request and default queue timeout. */
public int $timeout = 600;
public int $tries = 1;
public function __construct(
protected $user,
protected array $filters,
protected array $columns,
protected string $file_name,
) {
$this->onQueue('exports');
}
public function handle(ThirdPartyWarehouseStorageMirrorRepository $repository): void
{
$path = storage_path('app/temp/' . $this->file_name);
File::ensureDirectoryExists(dirname($path));
try {
$csv = fopen($path, 'wb');
if ($csv === false) {
throw new \RuntimeException('无法创建进销存报表导出文件。');
}
fputs($csv, chr(0xEF) . chr(0xBB) . chr(0xBF));
fputcsv($csv, array_column($this->columns, 'label'));
foreach ($repository->exportMonthlyInventoryReportRows($this->filters) as $row) {
fputcsv($csv, array_map(function (array $column) use ($row): mixed {
$value = data_get($row, $column['name']);
return $column['name'] === 'product_code'
? $this->csvIdentifier($value)
: (($column['kind'] ?? null) === 'integer'
? ($value === null || $value === '' ? '' : $value)
: $this->csvText($value));
}, $this->columns));
}
fclose($csv);
dispatch(new CreateMediableForExport($this->user, $this->file_name, '进销存报表'));
} catch (Throwable $exception) {
if (isset($csv) && is_resource($csv)) {
fclose($csv);
}
@unlink($path);
report($exception);
$this->user->notify(new ExportFailed($exception->getMessage()));
throw $exception;
}
}
private function csvIdentifier(mixed $value): string
{
$text = trim((string) ($value ?? ''));
return $text === '' ? '' : "'" . $text;
}
private function csvText(mixed $value): string
{
return trim((string) ($value ?? ''));
}
}