I need to show to my user during an Ajax request the status of the same divided into 6 steps Ex.
1° : Gerando arquiv 2° : Arquivo Gerado 3°: Conectando FTP 4º: Conexão realizada 5º: Enviando arquivo 6º : Arquivo enviado
I need to show to my user during an Ajax request the status of the same divided into 6 steps Ex.
1° : Gerando arquiv 2° : Arquivo Gerado 3°: Conectando FTP 4º: Conexão realizada 5º: Enviando arquivo 6º : Arquivo enviado
Proof of Concept
It's just an example of how it could be implemented (not for use in production)
Note: Lavarel 5.6 using Queues
Routes
//dar início a processamento
Route::get('/processar', 'ProcessarArquivoController@processar');
//obter percentagem de acabamento
Route::get('/estadoprocesso/{processo}', 'ProcessarArquivoController@estado');
Controller
You have only two methods one to start the process the second to check the process state (percentage)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Processo;
use App\Jobs\ProcessarArquivo;
class ProcessarArquivoController extends Controller
{
/**
* Inicia um processo enviando Processo para uma Queue
* Devolve o modelo do processo em JSON
* @return JSON
*/
public function processar()
{
$processo = new Processo();
$processo->percentagem = 5;
$processo->save();
ProcessarArquivo::dispatch($processo);
return response()->json($processo, 200);
}
/**
* Devolve o modelo do processo em JSON
* @return JSON
*/
public function estado(Processo $processo)
{
return response()->json($processo, 200);
}
}
Job
The process to be performed by Queue, does nothing the sleep is just not to run instantaneously, in case it could be file conversion, upload by ftp, etc.
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Processo;
class ProcessarArquivo implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $processo;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Processo $processo)
{
$this->processo = $processo;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
sleep(2);//executar algo
$this->processo->percentagem = 20;
$this->processo->save();
sleep(2);//executar algo
$this->processo->percentagem = 30;
$this->processo->save();
sleep(2);//executar algo
$this->processo->percentagem = 40;
$this->processo->save();
sleep(2);//executar algo
$this->processo->percentagem = 50;
$this->processo->save();
sleep(2);//executar algo
$this->processo->arquivo_enviado = 100;
$this->processo->save();
}
}
Migration
Process execution control table, just one example
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Processo extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('processos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('percentagem')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
Front End Page Bootstrap + jQuery Just an example.
<!doctype html>
<html lang="en">
<head>
<title>POC</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
</head>
<body>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<div class="container-fluid">
<p>Progresso</p>
<div class="card">
<div class="card-body">
<h4 class="card-title">Processamento</h4>
<div class="row">
<div class="col-12">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0"
id="progresso" aria-valuemax="100" style="width: 0%"></div>
</div>
</div>
</div>
<div class="row mt-5">
<div class="col-12">
<a name="" id="processar" class="btn btn-success" role="button">Processar ficheiro</a>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('#processar').click(function () {
console.log('A iniciar processo...');
$.getJSON('/processararquivo', function (data) {
var id = data.id;
window.progresso = setInterval(function () {
obterEstado(id)
}, 1000)
});
});
});
function obterEstado(id) {
$.getJSON('/estadoarquivo/' + id, function (data) {
console.log('A verificar processo: ' + data.id);
$("#progresso").css('width', data.percentagem + '%');
if (data.percentagem == 100) {
console.log('A finalizar processo: ' + data.id);
clearInterval(window.progresso);
}
})
}
</script>
</body>
</html>