Dcatadmin后台开发流程

之前开发都是依赖代码生成器,这次规范一下流程,保持优雅

2024-06-09 09:24:52   2025-02-09 23:52:41   PHP   195 views  

 

php artisan make:model Product -mf

打开设计并修改database/migrations /_create_banner_table.php文件

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateBannersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('banners', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title')->comment('标题名称');
            $table->string('image_path')->comment('图片路径'); // image_path不能为空
            $table->tinyInteger('type')->default(0)->comment('跳转类别 0不跳转 1链接(src) 2详情(description)'); // type不能为空用于切换显示跳转外链src或者展示详情description
            $table->string('src')->nullable()->comment('跳转链接'); // 根据需要设置是否可以为空,例如:外部链接或内部路径
            $table->text('description')->nullable()->comment('跳转详情');
            $table->integer('display_order')->default(0)->comment('排序');
            $table->boolean('is_active')->default(true)->comment('是否启用');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('banners');
    }
}

修改app/Models/Banner.php模型文件

<?php

namespace App\Models;

use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;

class Banner extends Model implements Sortable
{
    //HasDateTimeFormatter 继承后格式化created_at和updated_at时间格式
    //SortableTrait为表格开启可排序功能
    use HasFactory,HasDateTimeFormatter,SortableTrait;
    protected $fillable = [
        'title', 'description', 'image_path', 'is_active',
        'type', 'src', 'display_order'
    ];
    protected $casts = [
        'is_active' => 'boolean', // is_active 是一个布尔类型的字段
        'display_order' => 'integer',
    ];

    protected $sortable = [
        // 设置排序字段名称
        'order_column_name' => 'display_order',
        // 是否在创建时自动排序,此参数建议设置为true
        'sort_when_creating' => true,
    ];

    // 定义常量
    const TYPE_NO_REDIRECT = 0;
    const TYPE_REDIRECT_URL = 1;
    const TYPE_REDIRECT_DETAIL = 2;

    // 映射常量到中文描述
    private static $typeMapping = [
        self::TYPE_NO_REDIRECT => '不跳转',
        self::TYPE_REDIRECT_URL => '跳转URL',
        self::TYPE_REDIRECT_DETAIL => '跳转详情',
    ];

    // 添加一个方法来返回type的中文描述redirect_type_description
    public function getRedirectTypeDescription()
    {
        return self::$typeMapping[$this->type] ?? '未知类型';
    }

    //访问器根据类型修改完整图片链接
    public function getImagePathAttribute($value)
    {
        $appUrl = rtrim(config('app.url'), '/');
        // 检查是否有域名
        if (strpos($value, 'http://') !== 0 && strpos($value, 'https://') !== 0) {
            // 如果没有域名,则用 config('app.url') 拼接
            $image = $appUrl . '/uploads/' . ltrim($value, '/');
        }

        return $value;
    }
}

执行迁移

php artisan migrate

代码生成器生成数据仓库控制器翻译文件

file

app/Admin/routes.php添加

.
.
.
//注意 laravel版本不同resource有微小差别
$router->resource('banners', 'BannerController');
.
.
.

添加菜单

file

新增权限

file

绑定到角色

file

修改翻译文件(resource/lang/zh_CN/banner.php)

<?php 
return [
    'labels' => [
        'Banner' => '轮播图',
        'banner' => '轮播图',
    ],
    'fields' => [
        'title' => '标题名称',
        'image_path' => '图片',
        'type' => '跳转类别',
        'src' => '跳转链接',
        'description' => '跳转详情',
        'display_order' => '排序',
        'is_active' => '是否启用',
    ],
    'options' => [
    ],
];

修改控制器(app/Admin/Controllers/BannerController.php)

<?php

namespace App\Admin\Controllers;

use App\Admin\Repositories\Banner;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Show;
use Dcat\Admin\Http\Controllers\AdminController;

class BannerController extends AdminController
{
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        return Grid::make(new Banner(), function (Grid $grid) {
            //搜索按display_order排序
            $grid->model()->orderBy('display_order');
            $grid->column('id')->sortable();
            $grid->column('title');
            $grid->column('image_path','展示图片')->image();
            $grid->column('type')->display(function ($value){
                // $this 在这里指向的是当前的模型实例
                // 调用模型中的方法获取中文描述
                return $this->getRedirectTypeDescription();
            });
            //表格排序
            $grid->display_order->orderable();
            $grid->column('is_active')->switch();
            $grid->column('created_at');
            $grid->column('updated_at')->sortable();
            //隐藏详情按钮
            $grid->disableViewButton();
            //隐藏筛选按钮
            $grid->disableFilterButton();
            //筛选器
            $grid->filter(function (Grid\Filter $filter) {
                $filter->padding('0px', '20px', '0px', '20px');
                // 展开过滤器
                $filter->expand();
                // 更改为 panel 布局
                $filter->panel();
                $filter->equal('id')->width(2);
                $filter->like('title', '标题名称')->width(2);
                $filter->between('created_at')->width(3)->datetime();
                $filter->between('updated_at')->width(3)->datetime();
            });
            $grid->selector(function (Grid\Tools\Selector $selector) {
                $selector->select('type', '跳转类别', [
                    0 => '不跳转',
                    1 => '跳转链接',
                    2 => '跳转详情'
                ]);
                $selector->select('is_active', '是否启用', [
                    0 => '否',
                    1 => '是',
                ]);
            });
        });
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     *
     * @return Show
     */
    protected function detail($id)
    {
        return Show::make($id, new Banner(), function (Show $show) {
            $show->field('id');
            $show->field('title');
            $show->field('image_path');
            $show->field('type');
            $show->field('src');
            $show->field('description');
            $show->field('display_order');
            $show->field('is_active');
            $show->field('created_at');
            $show->field('updated_at');
        });
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        return Form::make(new Banner(), function (Form $form) {
            $form->display('id');
            //文本
            $form->text('title')->required();
            //图片自动上传
            $form->image('image_path')->autoUpload()->required()->removable(false)->retainable();
            //表单字段动态显示 单选组件
            $form->radio('type')
                //值为1时显示链接
                ->when(1, function (Form $form) {
                    $form->url('src');
                })
                //值为2时显示富文本
                ->when(2, function (Form $form) {
                    $form->editor('description');
                })
                ->options([
                    0 => '不跳转',
                    1 => '跳转链接',
                    2 => '跳转详情',
                ])
                ->default(0);

            //开关
            $form->switch('is_active')
                ->customFormat(function ($v) {
                    return $v == 1 ? 1 : 0;
                })
                ->saving(function ($v) {
                    return $v ? 1 : 0;
                });

            $form->saving(function (Form $form) {
                //根据type动态验证
                // 获取 radio 的值
                $type = $form->input('type');

                // 根据 radio 的值动态验证
                if ($type == 1 && !$form->input('src')) {
                    $form->response()->error('链接是必填项');
                    return false;
                }

                if ($type == 2 && !$form->input('description')) {
                    $form->response()->error('详情是必填项');
                    return false;
                }
            });

            $form->display('created_at');
            $form->display('updated_at');
            //隐藏查看按钮
            $form->disableViewButton();
        });
    }
}

最后完成

file
file
file
file