2.7 Laravel Admin树形模型树页面-分类页

# 表结构
# 图片分类表
CREATE TABLE `ph_images_category` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `pid` int(11) DEFAULT '0' COMMENT '父级id,0为一级分类',
  `name` varchar(20) DEFAULT NULL COMMENT '分类名称',
  `cover_url` varchar(255) DEFAULT NULL COMMENT '分类封面图片',
  `sort` smallint(5) DEFAULT '100' COMMENT '分类排序 越小越靠前',
  `created_at` timestamp NULL DEFAULT NULL COMMENT '添加时间',
  `updated_at` timestamp NULL DEFAULT NULL COMMENT '修改时间',
  `deleted_at` timestamp NULL DEFAULT NULL COMMENT '删除时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='图片分类表';

 

用到框架的 mode-tree 树形组件:https://laravel-admin.org/docs/zh/1.x/model-tree

 

 

1、创建模型、控制器、菜单

参照 2.5 节中的步骤,这里跳过

 

 

2、修改模型

组件的3个默认字段是:

parent_id   - integer

order        - integer

title        - string

 

如果和默认字段一样,可以不重新指定字段

# 修改如下
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use DateTimeInterface;
use Encore\Admin\Traits\ModelTree;
class ImagesCategory extends Model
{
    use HasFactory;
    use SoftDeletes;
    use ModelTree; // 使用数据模型树
    // 数据库 mysql_api 中的表
    protected $connection = 'mysql_api';
    protected $table = "images_category";
    /**
     * 为数组 / JSON 序列化准备日期。
     *
     * @param  \DateTimeInterface  $date
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }
    /**
     * 指定数据模型数的关联字段
    */
    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->setParentColumn('pid');
        $this->setOrderColumn('sort');
        $this->setTitleColumn('name');
    }
}

 

3、修改控制器

<?php
namespace App\Admin\Controllers;
use App\Models\ImagesCategory;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Show;
use Encore\Admin\Tree;
use Encore\Admin\Layout\Column;
use Encore\Admin\Layout\Row;
class ImagesCategoryController extends AdminController
{
    /**
     * Title for current resource.
     *
     * @var string
     */
    protected $title = '图片分类';
    /**
     * Make a grid builder.
     *  这个没用了
     * @return Grid
     */
    protected function grid()
    {
        $grid = new Grid(new ImagesCategory());
        $grid->column('id', __('Id'));
        $grid->column('pid', __('ImagesCategoryPid'));
        $grid->column('name', __('ImagesCategoryName'));
        $grid->column('cover_url', __('Cover url'))->image('',150,150);
        $grid->column('sort', __('Sort'));
        $grid->column('created_at', __('Created at'));
        $grid->column('updated_at', __('Updated at'));
        $grid->column('deleted_at', __('Deleted at'));
        $grid->filter(function ($filter) {
            // 范围过滤器,调用模型的`onlyTrashed`方法,查询出被软删除的数据。
            $filter->scope('trashed', '回收站')->onlyTrashed();
        });
        return $grid;
    }
    /**
     * Index interface.
     * 这里重写首页实现树状结构
     *
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->header($this->title)
            ->description('列表')->row(function (Row $row) {
                // 左侧显示树形分类
                $tree = new Tree(new ImagesCategory());
                $tree->disableCreate();// 禁用新增按钮
                // 修改返回结构
                $tree->branch(function ($branch) {
                    if ($branch['cover_url']){
                        $src = config('filesystems.disks.admin.url') . '/' . $branch['cover_url'] ;
                        $logo = "<img src='$src' style='max-width:30px;max-height:30px;border-radius: 100%;' class='img'/>";
                    }else{
                        $logo = '';
                    }
                    return "{$branch['id']} - {$branch['name']} $logo";
                });
                $row->column(4, $tree);
                //  右侧显示新增框
                $row->column(8, function (Column $column) {
                    $column->append( $this->form() );
                });
            });


    }


    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(ImagesCategory::findOrFail($id));
        $show->field('id', __('Id'));
        $show->field('pid', __('ImagesCategoryPid'));
        $show->field('name', __('ImagesCategoryName'));
        $show->field('cover_url', __('Cover url'))->image('',200,200);
        $show->field('sort', __('Sort'));
        $show->field('created_at', __('Created at'));
        $show->field('updated_at', __('Updated at'));
        $show->field('deleted_at', __('Deleted at'));
        return $show;
    }
    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $form = new Form(new ImagesCategory());
        $form->select('pid', __('ImagesCategoryPid'))->options(ImagesCategory::selectOptions());// 使用数据模型树,用于选择父级
        $form->text('name', __('ImagesCategoryName'))->required();
        // 以合适比例裁剪成300x300,更多使用方法 http://image.intervention.io/api/fit
        $form->image('cover_url', __('Cover url'))->removable()->fit(300);
        $form->number('sort', __('Sort'))->default(100);
        $form->setAction(admin_base_path('images-categories'));// 设置post数据到当前页,页面接收到会执行插入操作
        $form->header()->disableList();// 移除跳转列表按钮
        return $form;
    }
}

 

现在大致功能已经完成,可实现分类拖拽然后保存等操作。

 

 

但是现在的表是用到软删除的,发现树形列表里并没有回收站这个功能,下面自己拓展一下。

 

 

4、自定义工具

先定义工具类app/Admin/Extensions/Tools/CategoryRecycle.php:

<?php
namespace App\Admin\Extensions\Tools;
use Encore\Admin\Admin;
use Encore\Admin\Grid\Tools\AbstractTool;
use Illuminate\Support\Facades\Request;
/*
 * 分类回收站按钮工具类
 * */
class CategoryRecycle extends AbstractTool
{
    protected function script()
    {
        $url = Request::fullUrlWithQuery(['category_recycle' => '_category_recycle_']);
        return <<<EOT
$('input:radio.category_recycle').change(function () {
    var url = "$url".replace('_category_recycle_', $(this).val());
    $.pjax({container:'#pjax-container', url: url });
});
EOT;
    }
    public function render()
    {
        Admin::script($this->script());
        $options = [
            'default'   => '默认',
            'd'     => '回收站',
        ];
        return view('admin.tools.category_recycle', compact('options'));
    }
}

视图 admin.tools.category_recycle 文件为resources/views/admin/tools/category_recycle.blade.php:

<div class="btn-group" data-toggle="buttons">
    @foreach($options as $option => $label)
        <label class="btn btn-default btn-sm {{ \Request::get('category_recycle', 'default') == $option ? 'active' : '' }}">
            <input type="radio" class="category_recycle" value="{{ $option }}">{{$label}}
        </label>
    @endforeach
</div>

 

控制器修改如下:

主要修改了tree获取数据的查询条件

<?php
namespace App\Admin\Controllers;
use App\Admin\Extensions\Tools\CategoryRecycle;
use App\Models\ImagesCategory;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Show;
use Encore\Admin\Tree;
use Encore\Admin\Layout\Column;
use Encore\Admin\Layout\Row;
use Illuminate\Support\Facades\Request;
class ImagesCategoryController extends AdminController
{
    /**
     * Title for current resource.
     *
     * @var string
     */
    protected $title = '图片分类';
    /**
     * Make a grid builder.
     *  这个没用了
     * @return Grid
     */
//    protected function grid()
//    {
//        $grid = new Grid(new ImagesCategory());
//
//        $grid->column('id', __('Id'));
//        $grid->column('pid', __('ImagesCategoryPid'));
//        $grid->column('name', __('ImagesCategoryName'));
//        $grid->column('cover_url', __('Cover url'))->image('',150,150);
//        $grid->column('sort', __('Sort'));
//        $grid->column('created_at', __('Created at'));
//        $grid->column('updated_at', __('Updated at'));
//        $grid->column('deleted_at', __('Deleted at'));
//        $grid->filter(function ($filter) {
//            // 范围过滤器,调用模型的`onlyTrashed`方法,查询出被软删除的数据。
//            $filter->scope('trashed', '回收站')->onlyTrashed();
//        });
//        return $grid;
//    }
    /**
     * Index interface.
     * 这里重写首页实现树状结构
     *
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->header($this->title)
            ->description('列表')->row(function (Row $row) {
                // 左侧显示树形分类
                $tree = new Tree(new ImagesCategory());
                // 添加查询条件
                $tree->query(function ($model){
                    if (Request::get('category_recycle')=='d'){
                        $model = $model->onlyTrashed();
                    }
                   return $model;
                });
                $tree->disableCreate();// 禁用新增按钮
                // 添加回收站按钮组
                $tree->tools(function ($tools){
                    $tools->add((new CategoryRecycle())->render());
                });
                // 修改返回结构
                $tree->branch(function ($branch) {
                    if ($branch['cover_url']){
                        $src = config('filesystems.disks.admin.url') . '/' . $branch['cover_url'] ;
                        $logo = "<img src='$src' style='max-width:30px;max-height:30px;border-radius: 100%;' class='img'/>";
                    }else{
                        $logo = '';
                    }
                    return "{$branch['id']} - {$branch['name']} $logo";
                });
                $row->column(4, $tree);
                //  右侧显示新增框
                $row->column(8, function (Column $column) {
                    $column->append( $this->form() );
                });
            });


    }


    /**
     * Make a show builder.
     *
     * @param mixed $id
     * @return Show
     */
    protected function detail($id)
    {
        $show = new Show(ImagesCategory::findOrFail($id));
        $show->field('id', __('Id'));
        $show->field('pid', __('ImagesCategoryPid'));
        $show->field('name', __('ImagesCategoryName'));
        $show->field('cover_url', __('Cover url'))->image('',200,200);
        $show->field('sort', __('Sort'));
        $show->field('created_at', __('Created at'));
        $show->field('updated_at', __('Updated at'));
        $show->field('deleted_at', __('Deleted at'));
        return $show;
    }
    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $form = new Form(new ImagesCategory());
        $form->select('pid', __('ImagesCategoryPid'))->options(ImagesCategory::selectOptions());// 使用数据模型树,用于选择父级
        $form->text('name', __('ImagesCategoryName'))->required();
        // 以合适比例裁剪成300x300,更多使用方法 http://image.intervention.io/api/fit
        $form->image('cover_url', __('Cover url'))->removable()->fit(300);
        $form->number('sort', __('Sort'))->default(100);
        // 只有index页面要使用这个,不然编辑页面不会在action的url里传编辑的id
        if(!preg_match('/edit/',Request::path())){
            $form->setAction(admin_base_path('images-categories'));// 设置post数据到当前页,页面接收到会执行插入操作
        }
        $form->header()->disableList();// 移除跳转列表按钮
        return $form;
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以下省略。。。


最近弄了几个站,留个外链
ITM游戏资源
ITM资源

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值