怎样通过模型让 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 中文站站长
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

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