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 = ' ')
{
$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;
}
修改后打开时间为一到两秒。