2025年12月28日 星期日

利用 laravel 12 做一個類似Google Drive 的作品-檔案上傳下載


零、目標:
1.專案目標:
   A.環境準備
   B.建立 Laravel 專案 + 登入系統
   C.建立資料庫(資料夾 / 檔案)
   D.資料夾 CRUD
   E.檔案上傳 / 下載
   F.檔案列表(像 Google Drive)
   G.分享連結
   H.權限與安全
2.目前目標:
   E.檔案上傳 / 下載+F.檔案列表(像 Google Drive)
       a.上傳檔案到指定資料夾
       b.在資料夾中看到[資料夾+檔案]混合列表
       c.下載檔案
       d.檔案真實存到 storage

一、建立 File Model + Migration
    1.指令:php artisan make:model File -m
    2.編輯 database/migrations/xxxx_create_files_table.php
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('folder_id')->nullable()
  ->constrained('folders')->cascadeOnDelete();
$table->string('name');          // 原始檔名
$table->string('path');          // 儲存路徑
$table->unsignedBigInteger('size');
    如下圖:
    3.指令:php artisan migrate

二、File Model
    1.編輯 app/models/File.php
    protected $fillable = [
        'user_id',
        'folder_id',
        'name',
        'path',
        'size',
    ];
    public function folder(){
        return $this->belongsTo(Folder::class);
    }
    如下圖:

三、建立 FileController
    1.指令:php artisan make:controller FileController
    2.編輯 app/Http/Controllers/FileController.php
use App\Models\File;
use App\Models\Folder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
    public function store(Request $request){
        $request->validate([
            'file' => 'required|file|max:10240', // 10MB
        ]);
        $uploaded = $request->file('file');
        $path = $uploaded->store('files', 'public');
        File::create([
            'user_id' => Auth::id(),
            'folder_id' => $request->folder_id,
            'name' => $uploaded->getClientOriginalName(),
            'path' => $path,
            'size' => $uploaded->getSize(),
        ]);
        return back();
    }

    public function download(File $file){
        abort_if($file->user_id !== Auth::id(), 403);
        return Storage::disk('public')->download($file->path, $file->name);
    }

    如下圖:

四、設定路由
    1. 編輯 routes/web.php
use App\Http\Controllers\FileController;
    // File
    Route::post('/files', [FileController::class, 'store'])->name('files.store');
    Route::get('/files/{file}/download', [FileController::class, 'download'])
        ->name('files.download');

    如下圖

五、顯示檔案(修改 folders.show)
    1.編輯 FolderController@show
use App\Models\File;
    與
// File
$files = File::where('folder_id', $folder->id)->get();
return view('folders.show', compact('folder', 'subFolders','files'));
    如下圖

六、修改畫面:上傳+檔案列表
    1.編輯 resources/views/folders/show.blade.php
      {{-- 上傳表單 --}}
        <form method="POST" action="{{ route('files.store') }}" enctype="multipart/form-data" class="mb-4">
            @csrf
            <input type="hidden" name="folder_id" value="{{ $folder->id }}">
            <input type="file" name="file">
            <button class="bg-green-600 text-white px-4 py-2 rounded">
                上傳檔案
            </button>
        </form>

        {{-- 檔案列表 --}}
        <h2 class="font-semibold mb-2">檔案</h2>

        <ul class="space-y-2">
            @forelse($files as $file)
                <li class="border p-3 rounded flex justify-between">
                    📄 {{ $file->name }}
                    <a href="{{ route('files.download', $file) }}"
                    class="text-blue-600 hover:underline">
                    下載
                    </a>
                </li>
                @empty
                <li class="text-gray-400">尚無檔案</li>
            @endforelse
        </ul>
    如下圖

七、建立 storage 連結(必要)
    1.指令:php artisan storage:link

八、測試流程
    1.點擊某資料夾
    2.上傳檔案
    3.看到檔案列表
    4.點[下載]成功


沒有留言:

張貼留言

利用 laravel 12 做一個類似Google Drive 的作品-權限與安全

相關系列文章: 1. 利用 laravel 12 做一個類似Google Drive 的作品-使用者系統 2. 利用 laravel 12 做一個類似Google Drive 的作品-資料夾系統 3. 利用 laravel 12 做一個類似Google Drive 的作品-巢狀資...