Эх сурвалжийг харах

Перенос экспорта в jobs

Alexander Musikhin 2 жил өмнө
parent
commit
91e72928e2

+ 1 - 0
.gitignore

@@ -3,6 +3,7 @@
 /www/assets
 /www/hot
 /www/storage
+/www/exported
 /storage/*.key
 /vendor
 ~$*

+ 7 - 30
app/Http/Controllers/ExportController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Jobs\GenerateDocxJob;
 use App\Models\Product;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Log;
@@ -12,8 +13,6 @@ class ExportController extends Controller
         $ids = json_decode($request->ids,true);
         $products = Product::query()->whereIn('id', $ids)->orderBy('series', 'asc')->get();
 
-        $my_template = new \PhpOffice\PhpWord\TemplateProcessor(storage_path('templates/template_maf.docx'));
-
         $vars_for_template = [];
         $i = 1;
         foreach ($products as $product){
@@ -36,8 +35,6 @@ class ExportController extends Controller
                     break;
             }
 
-
-
             $vars_for_template = array_merge($vars_for_template, [
                 'series#' . $i        => $product->series,
                 'product_group#' .$i  => $product->product_group,
@@ -51,35 +48,15 @@ class ExportController extends Controller
             $i++;
         }
 
-//        dd($vars_for_template);
-        $my_template->cloneBlock('product_block', count($products), true, true, $vars_for_template);
-
-        foreach ($vars_for_template as $k => $v){
-            $file = public_path() . '/' . env('IMAGES_PATH') . '/' . $v;
-            if(str_starts_with($k, 'image') && file_exists($file) && $v !== ''){
-                $my_template->setImageValue($k, ['path' => $file, 'width' => 270, 'height' => 180]);
-            } else {
-                $my_template->setValue($k, $v);
-            }
-
-        }
-
-
-//        dd($vars_for_template);
+        // prepared vars - run job
 
+        $filename = 'export_' . date('YmdHis') . '.docx';
+        $job = GenerateDocxJob::dispatch($vars_for_template, count($products), $filename);
 
+        Log::notice('Created job. Execution time: ' . microtime(true) - LARAVEL_START);
 
-        $file = 'Наш_Двор_' . date('YmdHis') . '.docx';
-        header("Content-Description: File Transfer");
-        header('Content-Disposition: attachment; filename="' . $file . '"');
-        header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
-        header('Content-Transfer-Encoding: binary');
-        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-        header('Expires: 0');
-        ob_clean();
-        $my_template->saveAs("php://output");
-        Log::notice('Execution time: ' . microtime(true) - LARAVEL_START);
+        $data['filename'] = $filename;
+        return view('products.wait', $data);
 
-        exit();
     }
 }

+ 1 - 0
app/Http/Middleware/managerAuthMiddleware.php

@@ -29,6 +29,7 @@ class managerAuthMiddleware
         $user = session('user', false);
 //        dd($user);
         if (!isset($user['id'])) {
+            if(!isset($_COOKIE['ci_session'])) return false;
             $opts = array(
                 'http' => array(
                     'method' => "GET",

+ 69 - 0
app/Jobs/GenerateDocxJob.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Jobs;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldBeUnique;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Facades\Log;
+use PhpOffice\PhpWord\TemplateProcessor;
+
+class GenerateDocxJob implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    protected $vars;
+    protected $prod_count;
+    protected $filename;
+
+    /**
+     * Create a new job instance.
+     *
+     * @return void
+     */
+    public function __construct($vars, $count_products, $filename)
+    {
+        $this->vars =$vars;
+        $this->prod_count = $count_products;
+        $this->filename = $filename;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        $tmpfile = public_path('exported/docx/' . $this->filename . '.txt');
+
+        $my_template = new TemplateProcessor(storage_path('templates/template_maf.docx'));
+        $my_template->cloneBlock('product_block', $this->prod_count, true, true, $this->vars);
+
+        $i = 0;
+        $total = count($this->vars);
+
+        foreach ($this->vars as $k => $v){
+            $file = public_path() . '/' . env('IMAGES_PATH') . '/' . $v;
+            if(str_starts_with($k, 'image') && file_exists($file) && $v !== ''){
+                $my_template->setImageValue($k, ['path' => $file, 'width' => 270, 'height' => 180]);
+            } else {
+                $my_template->setValue($k, $v);
+            }
+
+            if(($i++ % 10) == 0) {
+                $f = fopen($tmpfile, 'w+');
+                $percent = $i / ($total / 100);
+                fwrite($f, $percent);
+                fclose($f);
+            }
+        }
+
+        $my_template->saveAs(public_path('exported/docx/') . $this->filename);
+        unlink($tmpfile);
+        Log::notice('Generation finished: ' . $i . ' / ' . $total . '  Execution time: ' . microtime(true) - LARAVEL_START);
+    }
+}

+ 36 - 0
database/migrations/2023_02_03_094852_create_jobs_table.php

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('jobs', function (Blueprint $table) {
+            $table->bigIncrements('id');
+            $table->string('queue')->index();
+            $table->longText('payload');
+            $table->unsignedTinyInteger('attempts');
+            $table->unsignedInteger('reserved_at')->nullable();
+            $table->unsignedInteger('available_at');
+            $table->unsignedInteger('created_at');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('jobs');
+    }
+};

+ 3 - 0
resources/views/layouts/app.blade.php

@@ -52,6 +52,9 @@
                             {{ $user['sname'] }} {{ $user['fname'] }} {{ $user['tname'] }}
                             (логин: {{ $user['username'] }})
                         </li>
+                        <li class="nav-item ms-3">
+                            <a href="{{ route('logout') }}" class="">Выход</a>
+                        </li>
                     </ul>
                 </div>
             </div>

+ 32 - 0
resources/views/products/wait.blade.php

@@ -0,0 +1,32 @@
+@extends('layouts.app')
+
+@section('content')
+    <div class="container">
+        <div class="row">
+            <div class="col-12 text-center mt-5 fs-1">
+                <span id="percent">XX</span>%
+            </div>
+        </div>
+
+        <div class="progress" role="progressbar" aria-label="Basic example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
+            <div class="progress-bar" style="width: 0%"></div>
+        </div>
+
+    </div>
+
+    <script>
+        function check_export(){
+            let url = '/exported/docx/{{ $filename }}.txt';
+            fetch(url)
+                .then(response => response.text())
+                .then(percent => console.log(percent));
+        }
+
+        setInterval(check_export(), 1000);
+
+
+    </script>
+
+
+@endsection
+

+ 9 - 1
routes/web.php

@@ -1,7 +1,10 @@
 <?php
 
+use App\Http\Controllers\ExportController;
 use App\Http\Controllers\ProductController;
+use Illuminate\Support\Facades\Redirect;
 use Illuminate\Support\Facades\Route;
+use Illuminate\Support\Facades\Session;
 
 /*
 |--------------------------------------------------------------------------
@@ -23,6 +26,11 @@ Route::middleware('mgrauth')->group(function (){
     Route::post('/save_product', [ProductController::class, 'save_product'])->name('save_product');
     Route::post('/update_image/{id}', [ProductController::class, 'update_image'])->name('update_image');
     Route::post('/select_export', [ProductController::class, 'select_export'])->name('select_export');
-    Route::post('/export_docx', [\App\Http\Controllers\ExportController::class, 'export_docx'])->name('export_docx');
+    Route::post('/export_docx', [ExportController::class, 'export_docx'])->name('export_docx');
 });
 
+Route::get('logout', function (){
+    Session::forget('user');
+    return Redirect::to('http://manager.stroyprofit.com/logout');
+})->name('logout');
+

BIN
storage/templates/template_maf.docx