首页 > 解决方案 > 如何通过 Laravel 中的 API 捕获 ShouldQueue 导入的失败和错误

问题描述

通过这些过程,我可以上传 Big Excel 文件中包含的数据,如果队列中有任何验证问题,它将跳过并上传剩余的文件。但我不知道如何通过 API 获取这些验证错误。我尝试if ($import->failures()->isNotEmpty())了检查是否有任何我知道不起作用的错误的方法。建议我获得这些验证错误的最佳方法。

在我的 ImportController

public function import(Request $request)
{
    $rules = [
        'file' => 'required|mimes:xlsx,xls',
        'type' => 'filled|string|not_in:null',
    ];
    $validator = Validator::make($request->all(), $rules);
    if ($validator->fails()) {
        $errors = $validator->errors();
        return response()->json($errors, 404);
    }
    
    $type = $request->input('type');
    $file = $request->file;
    $fileName = time() . '--u-' . auth()->user()->id . '.' .$file->extension();
    $location = $file->storeAs('importFile/applicationFile' , $fileName);
    $import = new ApplicationImport;
    $import->import($location);
    if ($import->failures()->isNotEmpty()) {
        return response()->json(['response' => 'Imported! And have some errors!', 'errors' => 
        $import->failures()],  404);                  
    }
    return response()->json(['response' => 'File send to queue! Worker will import it.'],  200);

}

在 ApplicationImport 上(使用 Maatwebsite\Excel)

namespace App\Imports;

use App\Models\Application;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\Importable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\SkipsFailures;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class ApplicationImport implements ToModel, WithHeadingRow, WithValidation, WithBatchInserts, WithChunkReading, ShouldQueue, SkipsOnFailure
{
    use Importable, SkipsFailures;

    public function rules(): array
    {
        return [
            '*.title'                   => ['required', 'string', 'max:100', 'unique:applications'],
            '*.user_id'                 => ['required', 'numeric'],
            '*.company_id'              => ['required', 'numeric'],
            '*.course_id'               => ['required', 'numeric'],
            '*.coursetype_id'           => ['required', 'numeric'],
            '*.institution_id'          => ['required', 'numeric'],
            '*.status_id'               => ['required', 'numeric'],
            '*.internal_ref'            => ['required', 'string', 'max:255'],
            '*.external_ref'            => ['required', 'string', 'max:255'],
            '*.intake_month'            => ['required', 'string', 'max:255'],
            '*.intake_year'             => ['required', 'numeric', 'min:4'],
            '*.tution_fee'              => ['required', 'numeric'],
            '*.administration_charge'   => ['required', 'numeric'],
            '*.created_by'              => ['required', 'numeric']
        ];
    }
    
    public function genUID()
    {
        $app_uid = 'USR-' . mt_rand(10000000, 99999999);
        if ($this->uidNumberExists($app_uid)) {
            return $this->genUID();
        } else {
            return $app_uid;
        }
    }
    public function uidNumberExists($app_uid)
    {
        return Application::Where('uid', $app_uid)->exists();
    }
    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new Application([
            'uid' => $this->genUID(),
            'title' => $row['title'],
            'user_id' => $row['user_id'],
            'company_id' => $row['company_id'],
            'course_id' => $row['course_id'],
            'coursetype_id' => $row['coursetype_id'],
            'institution_id' => $row['institution_id'],
            'status_id' => $row['status_id'],
            'internal_ref' => $row['internal_ref'],
            'external_ref' => $row['external_ref'],
            'intake_month' => $row['intake_month'],
            'intake_year' => $row['intake_year'],
            'tution_fee' => $row['tution_fee'],
            'administration_charge' => $row['administration_charge'],
            'created_by' => $row['created_by'],
        ]);
    }
    
    public function batchSize(): int
    {
        return 1000;
    }
    
    public function chunkSize(): int
    {
        return 1000;
    }
}

标签: excellaravelapimaatwebsite-excel

解决方案


您应该将控制器代码移动到可能出现故障的队列/作业中,然后如果您正在使用,您可以通过 Pusher 访问。如果您没有在 import 中实现 shouldQueue ,那么您可能会遇到失败。


推荐阅读