Laravel-admin创建树形分类以及分类多卡顿优化

Laravel-admin创建树形分类以及分类多卡顿优化 ,老年人记忆系列,记不住就copy一下提高效率

Homemenu.php

<?php

namespace App\Models;

use Encore\Admin\Traits\AdminBuilder;
use Illuminate\Database\Eloquent\Model;

use Encore\Admin\Traits\ModelTree;
class Homemenu extends Model
{
    //
  use ModelTree, AdminBuilder;
    protected $table = 'homemenus';
 
    protected $fillable = ['pid', 'title', 'sort'];
 
    protected $with = [
        'parent'
    ];
 
 
    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->setParentColumn('pid');  // 父ID
        $this->setOrderColumn('sort'); // 排序
        $this->setTitleColumn('title'); // 标题
    }
 
 
    // 该分类下的品牌
    public function brand()
    {
        return $this->hasMany(BrandModel::class, 'id', $this->getKeyName());
    }
 
 
    /**
     * 该分类的子分类
     */
    public function child()
    {
        return $this->hasMany(get_class($this), 'pid', $this->getKeyName());
    }
 
    /**
     * 该分类的父分类
     */
    public function parent()
    {
        return $this->hasOne(get_class($this), $this->getKeyName(), 'pid');
    }

}

HomemenuController

<?php
 
namespace App\Admin\Controllers;
 
use App\Models\Homemenu;
use Encore\Admin\Controllers\HasResourceActions;
use Encore\Admin\Layout\{Column, Row, Content};
use Encore\Admin\{Tree,Form};
use Encore\Admin\Widgets\Box;
use Illuminate\Http\RedirectResponse;
 
 
/**
 * 分类管理
 * @package App\Admin\Controllers
 */
class HomemenuController extends Content
{
    use HasResourceActions;
 
    protected $title = '分类';
 
    /**
     * 首页
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        return $content->title('分类')
            ->description('列表')
            ->row(function (Row $row){
                // 显示分类树状图
                $row->column(6, $this->treeView()->render());
 
                $row->column(6, function (Column $column){
                    $form = new \Encore\Admin\Widgets\Form();
                    $form->action(admin_url('homemenus'));
                    $form->select('pid', __('父类'))->options(Homemenu::selectOptions());
                    $form->text('title', __('分类名称'))->required();
                    $form->text('ctable', __('表名'))->required();
                    $form->image('icon', __('图片主图'))->move('/Homemenu',uniqid().".jpg");
                    $form->url('href', __('外链'));
                    $form->text('comment', __('分类描述'));
                    $form->number('sort', __('排序'))->min(0)->default(99)->help('越小越靠前');
                     $states = [
					    'on'  => ['value' => 1, 'text' => '显示', 'color' => 'success'],
					    'off' => ['value' => 0, 'text' => '隐藏', 'color' => 'default'],
					];
			        $form->switch('status', __('状态'))->default(1)->states($states);
                    $form->hidden('_token')->default(csrf_token());
                    $column->append((new Box(__('category.new'), $form))->style('success'));
                });
 
            });
    }
 
 
    /**
     * 树状视图
     * @return Tree
     */
    protected function treeView()
    {
        return  Homemenu::tree(function (Tree $tree){
            $tree->disableCreate(); // 关闭新增按钮
            $tree->branch(function ($branch) {
                return "<strong>{$branch['title']}</strong>"; // 标题添加strong标签
            });
        });
    }
 
    /**
     * 详情页
     * @param $id
     * @return RedirectResponse
     */
    public function show($id)
    {
        return redirect()->route('homemenus', ['id' => $id]);
    }
 
    /**
     * 编辑
     * @param $id
     * @param Content $content
     * @return Content
     */
    public function edit($id, Content $content)
    {
        return $content->title(__('Categories'))
            ->description(__('edit'))
            ->row($this->form()->edit($id));
    }
 
 
    /**
     * 表单
     * @return Form
     */
    public function form()
    {
        $form = new Form(new Homemenu());
        $form->tools(function (Form\Tools $tools) {
	        // $tools->disableDelete();
	        $tools->disableView();
	        // $tools->disableList();
	    });
        $form->display('id', 'ID');
        $form->select('pid', __('父类'))->options(Homemenu::selectOptions());
        $form->text('title', __('分类名称'))->required();
        $form->text('ctable', __('表名'))->required();
        $form->image('icon', __('图片主图'))->move('/Homemenu',uniqid().".jpg");
        $form->url('href', __('外链'));
        $form->text('comment', __('分类描述'));
        $form->number('sort', __('排序'))->min(0)->default(99)->help('越小越靠前');
        $states = [
		    'on'  => ['value' => 1, 'text' => '显示', 'color' => 'success'],
		    'off' => ['value' => 0, 'text' => '隐藏', 'color' => 'default'],
		];
        $form->switch('status', __('状态'))->default(1)->states($states);
        return $form;
    }
    
 
}
 

实现效果图

分类过多时卡的,超过一千条时,打开时间为五六秒

解决办法

Encore\Admin\Tree 文件最后添加;

public function renderx($table)
    {
        Admin::script($this->script());

        view()->share([
            'path'           => $this->path,
            'keyName'        => $this->model->getKeyName(),
            'branchView'     => $this->view['branch'],
            'branchCallback' => $this->branchCallback,
        ]);
        // echo("<pre>");
        // var_dump($this->variablesx($table));exit;
        
        return view($this->view['tree'], $this->variablesx($table))->render();
    }
    /**
     * Variables in tree template.
     *
     * @return array
     */
    public function variablesx($table)
    {
        
        return [
            'id'         => $this->elementId,
            'tools'      => $this->tools->render(),
            'items'      => $this->getItemsx($table),
            'useCreate'  => $this->useCreate,
            'useSave'    => $this->useSave,
            'useRefresh' => $this->useRefresh,
        ];
    }
     /**
     * Return all items of the tree.
     *
     * @return array
     */
    public function getItemsx($table)
    { 
        
        return $this->model->withQuery($this->queryCallback)->toTreex($table);
    }

Encore\Admin\Traits\ModelTree 文件最后添加

/**
     * Get options for Select field in form.
     *
     * @param \Closure|null $closure
     * @param string        $rootText
     *
     * @return array
     */
    public static function selectOptionsx($table,\Closure $closure = null, $rootText = 'ROOT')
    {
        $options = (new static())->withQuery($closure)->buildSelectOptionsx($table);

        return collect($options)->prepend($rootText, 0)->all();
        
    }
    /**
     * Build options of select field in form.
     *
     * @param array  $nodes
     * @param int    $parentId
     * @param string $prefix
     * @param string $space
     *
     * @return array
     */
     
    protected function buildSelectOptionsx($table,array $nodes = [], $parentId = 0, $prefix = '', $space = '&nbsp;')
    {
        $prefix = $prefix ?: '┝'.$space;

        $options = [];

        if (empty($nodes)) {
            $nodes = $this->allNodesx($table);
        }

        foreach ($nodes as $index => $node) {
            if ($node[$this->parentColumn] == $parentId) {
                $node[$this->titleColumn] = $prefix.$space.$node[$this->titleColumn];

                $childrenPrefix = str_replace('┝', str_repeat($space, 6), $prefix).'┝'.str_replace(['┝', $space], '', $prefix);

                $children = $this->buildSelectOptions($nodes, $node[$this->getKeyName()], $childrenPrefix);

                $options[$node[$this->getKeyName()]] = $node[$this->titleColumn];

                if ($children) {
                    $options += $children;
                }
            }
        }

        return $options;
    }
    /**
     * Get all elements.
     *
     * @return mixed
     */
    public function allNodesx($table)
    {
        $orderColumn = DB::getQueryGrammar()->wrap($this->orderColumn);
        $byOrder = $orderColumn.' = 0,'.$orderColumn;

        $self = new static();

        if ($this->queryCallback instanceof \Closure) {
            $self = call_user_func($this->queryCallback, $self);
        }

        // return $self->orderByRaw($byOrder)->get()->toArray();
        $res=\DB::table($table)->orderByRaw($byOrder)->get(['id','pid','title','sort'])->toArray();
        
        return $res=json_decode(json_encode($res),true);
    }
    /**
     * Format data to tree like array.
     *
     * @return array
     */
    public function toTreex($table)
    {
       
        return $this->buildNestedArrayx($table);
    }

    /**
     * Build Nested array.
     *
     * @param array $nodes
     * @param int   $parentId
     *
     * @return array
     */
    protected function buildNestedArrayx($table, array $nodes = [], $parentId = 0)
    {
        $branch = [];
         
        if (empty($nodes)) {
            $nodes = $this->allNodesx($table);
        }
         
        foreach ($nodes as $node) {
            if ($node[$this->parentColumn] == $parentId) {
                $children = $this->buildNestedArrayx($table,$nodes, $node[$this->getKeyName()]);

                if ($children) {
                    $node['children'] = $children;
                }

                $branch[] = $node;
            }
        }
        
        return $branch;
    }

Homemenu.php 替换index方法

/**
     * 首页
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        return $content->title('分类')
            ->description('列表')
            ->row(function (Row $row){
                // 显示分类树状图
                $row->column(6, $this->treeView()->renderx('homemenus'));
 
                $row->column(6, function (Column $column){
                    $form = new \Encore\Admin\Widgets\Form();
                    //$form->action(admin_url('homemenus'));
                    $form->select('pid', __('父类'))->options(Homemenu::selectOptionsx('homemenus'));
                    $form->text('title', __('分类名称'))->required();
                    $form->text('ctable', __('表名'))->required();
                    $form->image('icon', __('图片主图'))->move('/Homemenu',uniqid().".jpg");
                    $form->url('href', __('外链'));
                    $form->text('comment', __('分类描述'));
                    $form->number('sort', __('排序'))->min(0)->default(99)->help('越小越靠前');
                     $states = [
					    'on'  => ['value' => 1, 'text' => '显示', 'color' => 'success'],
					    'off' => ['value' => 0, 'text' => '隐藏', 'color' => 'default'],
					];
			        $form->switch('status', __('状态'))->default(1)->states($states);
                    $form->hidden('_token')->default(csrf_token());
                    $column->append((new Box(__('category.new'), $form))->style('success'));
                });
 
            });
    }

替换form方法

/**
     * 表单
     * @return Form
     */
    public function form()
    {
        $form = new Form(new Homemenu());
        $form->tools(function (Form\Tools $tools) {
	        // $tools->disableDelete();
	        $tools->disableView();
	        // $tools->disableList();
	    });
        $form->display('id', 'ID');
        $form->select('pid', __('父类'))->options(Homemenu::selectOptionsx('homemenus'));
        $form->text('title', __('分类名称'))->required();
        $form->text('ctable', __('表名'))->required();
        $form->image('icon', __('图片主图'))->move('/Homemenu',uniqid().".jpg");
        $form->url('href', __('外链'));
        $form->text('comment', __('分类描述'));
        $form->number('sort', __('排序'))->min(0)->default(99)->help('越小越靠前');
        $states = [
		    'on'  => ['value' => 1, 'text' => '显示', 'color' => 'success'],
		    'off' => ['value' => 0, 'text' => '隐藏', 'color' => 'default'],
		];
        $form->switch('status', __('状态'))->default(1)->states($states);
        return $form;
    }
    

修改后打开时间为一到两秒。

0 评论
内联反馈
查看所有评论