怎样通过模型让 Filament Table 消费外部 API 数据

介绍

有时,我们使用 Filament Table 时数据源并非来自于数据库表。本文将展示如何从外部数据源(JSON API)获取数据提供给模型使用。

配置

安装 calebporzio/sushi 包:

composer require calebporzio/sushi

新建 Product 模型和 Product Resource:

php artisan make:model Product
php artisan make:filament-resource Product --simple --view

将 Sushi trait 添加到 Product 模型。你可以执行 getRows() 方法从外部源获取数据。

//app\Models\Product.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Sushi\Sushi;

class Product extends Model
{
    use Sushi;

    /**
     * Model Rows
     *
     * @return void
     */
    public function getRows()
    {
        //API
        $products = Http::get('https://dummyjson.com/products')->json();

        //filtering some attributes
        $products = Arr::map($products['products'], function ($item) {
            return Arr::only($item,
                [
                    'id',
                    'title',
                    'description',
                    'price',
                    'rating',
                    'brand',
                    'category',
                    'thumbnail',
                ]
            );
        });

        return $products;
    }
}

你可以在 Product Resource 文件中创建表单字段和表格字段:

表单字段:

//app\Filament\Resources\ProductResource.php

use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;

public static function form(Form $form): Form
{
    return $form
        ->schema([

            //title
            TextInput::make('title'),

            //brand
            TextInput::make('brand'),

            //category
            TextInput::make('category'),

            //description
            RichEditor::make('description'),

            //price
            TextInput::make('price')
                ->prefix('$'),

            //rating
            TextInput::make('rating')
                ->numeric(),
        ]);
}

表格字段:

//app\Filament\Resources\ProductResource.php

use Filament\Tables\Columns\BadgeColumn;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Columns\TextColumn;

...
->columns([

    //thumbnail
    ImageColumn::make('thumbnail')
        ->label('Image')
        ->rounded(),

    //title
    TextColumn::make('title')
        ->searchable()
        ->sortable()
        ->weight('medium')
        ->alignLeft(),

    //brand
    TextColumn::make('brand')
        ->searchable()
        ->sortable()
        ->color('secondary')
        ->alignLeft(),

    //category
    TextColumn::make('category')
        ->sortable()
        ->searchable(),

    //description
    TextColumn::make('description')
        ->sortable()
        ->searchable()
        ->limit(30),

    //price
    BadgeColumn::make('price')
        ->colors(['secondary'])
        ->prefix('$')
        ->sortable()
        ->searchable(),

    //rating
    BadgeColumn::make('rating')
    ->colors([
        'danger' => static fn ($state): bool => $state <= 3,
        'warning' => static fn ($state): bool => $state > 3 && $state <= 4.5,
        'success' => static fn ($state): bool => $state > 4.5,
    ])
    ->sortable()
    ->searchable(),

])

表格过滤器:

//app\Filament\Resources\ProductResource.php

use Filament\Tables\Filters\SelectFilter;

...
->filters([

    //brand
    SelectFilter::make('brand')
        ->multiple()
        ->options(Product::select('brand')
            ->distinct()
            ->get()
            ->pluck('brand', 'brand')
        ),

    //category
    SelectFilter::make('category')
        ->multiple()
        ->options(Product::select('category')
            ->distinct()
            ->get()
            ->pluck('category', 'category')
        ),
])

如你所见,API 是只读的。你可以隐藏一些Action按钮:

//app\Filament\Resources\ProductResource.php

...
->actions([
    Tables\Actions\ViewAction::make(),
    //Tables\Actions\EditAction::make(),
    //Tables\Actions\DeleteAction::make(),
])
->bulkActions([
    //Tables\Actions\DeleteBulkAction::make(),
])
//app\Filament\Resources\ProductResource\Pages\ManageProducts.php
protected function getActions(): array
{
    return [
        //Actions\CreateAction::make(),
    ];
}

现在可以到 /admin/products 中访问 Product 资源了!

点此查看更多 Filament 详情

本作品采用《CC 协议》,转载必须注明作者和本文链接
Laravel Filament 中文站站长
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!