首页 > 解决方案 > Laravel - 存储上传/操作状态的最佳实践是什么?比如上传头像

问题描述

假设有一个应用程序可以通知用户他们的待处理或完成操作的状态,那么解决这个问题的最佳方法是什么。

例如,提示用户上传个人资料图片(如果他们尚未上传)和/或通知他们操作已完成。

一种方法是使用 user 表中的 upload_status 字段,但这是处理此问题的最佳方法吗?

标签: phplaraveluser-interfaceeloquentrelationship

解决方案


使用用户表不允许用户有多个待上传。除此之外,该解决方案感觉不规范。但是,一个简单的解决方案是Session

路线/api.php

Route::post('upload', [ UploadController::class, 'upload' ]);
Route::get('upload-status/{upload}', [ UploadController::class, 'uploadStatus' ]);

app\Http\Controllers\UploadController.php ( require spatie/async)

use Spatie\Async\Pool;

class UploadController extends Controller
{
    public function upload(Request $request)
    {
        $sessionKey = 'upload-'.Auth::id().'-'.time();
        Session::set($sessionKey, 'pending');

        $pool[] = async(function () use ($i) {
            // upload magic
        })->then(function (int $output) use($sessionKey) {
            Session::set($sessionKey, 'done');
        })->catch(function ($exception) {
            Session::set($sessionKey, 'failed');
        });

        return $sessionKey
    }

    public function uploadStatus(string $upload)
    {
        return Session::get($upload);
    }
}

没有测试代码。这就是我开始的方式(或多或少的伪代码)。但也许它有帮助。


或者,这是一个客户端解决方案:

const xhr = new XMLHttpRequest();

// listen for `load` event
xhr.onload = () => {
    console.log(`The transfer is completed: ${xhr.status} ${xhr.response}`);
};

// listen for `error` event
xhr.onerror = () => {
    console.error('Download failed.');
}

// listen for `abort` event
xhr.onabort = () => {
    console.error('Download cancelled.');
}

// listen for `progress` event
xhr.onprogress = (event) => {
    // event.loaded returns how many bytes are downloaded
    // event.total returns the total number of bytes
    // event.total is only available if server sends `Content-Length` header
    console.log(`Upload ${event.loaded} of ${event.total} bytes`);
}

// open and send request
xhr.open('POST', '{{ url('upload') }}');
xhr.send();

如果你想使用axios,你可以使用这个:

axios.post('{{ url('upload') }}', data, {
  onUploadProgress: progressEvent => {
    let percentCompleted = Math.floor((progressEvent.loaded * 100) / progressEvent.total);
    // do whatever you like with the percentage complete
    // maybe dispatch an action that will update a progress bar or something
  })
        .then(response => console.log(response));

推荐阅读