php的智能树结构
在 formatSelect 方法中:
添加了 $prefixes 参数,用于跟踪上层的前缀状态
使用了 Unicode 字符来绘制树形结构:
├─ 表示中间的节点
└─ 表示最后一个节点
│ 表示垂直连接线
表示空白填充
一级分类保持无前缀
二级及以上分类根据是否是最后一个节点使用不同符号
通过 $prefixes 数组维护每一层的连接线状态
<?php
namespace app\controller;
use think\facade\Db;
class CategoryController extends Controller
{
public function index()
{
$list = Db::name('category')
->field('id,pid,title')
->order('id', 'asc')
->select()
->toArray();
$categorys = $this->buildTree($list);
$categoryList = $this->formatSelect($categorys, 0, 1);
$category_id = input('category_id', 0);
$this->assign([
'categorys' => $categoryList,
'category_id' => $category_id
]);
return $this->fetch();
}
private function buildTree($list, $pid = 0)
{
$tree = [];
foreach ($list as $item) {
if ($item['pid'] == $pid) {
$children = $this->buildTree($list, $item['id']);
if ($children) {
$item['children'] = $children;
}
$tree[] = $item;
}
}
return $tree;
}
private function formatSelect($tree, $level = 0, $selectableLevel = 1, $prefixes = [])
{
$result = [];
$total = count($tree);
foreach ($tree as $index => $item) {
$isLast = ($index == $total - 1);
// 计算当前层级的前缀
if ($level == 0) {
$prefix = ''; // 一级分类不加前缀
} else {
// 使用美观的树形结构符号
$currentPrefix = $isLast ? '└─ ' : '├─ ';
$parentPrefix = implode('', $prefixes);
$prefix = $parentPrefix . $currentPrefix;
// 为子节点准备新的前缀数组
$newPrefixes = array_merge($prefixes, [$isLast ? ' ' : '│ ']);
}
$result[$item['id']] = [
'title' => $prefix . $item['title'],
'selectable' => ($level < $selectableLevel - 1) ? false : true
];
if (isset($item['children'])) {
$children = $this->formatSelect(
$item['children'],
$level + 1,
$selectableLevel,
$level == 0 ? [] : $newPrefixes
);
$result = array_merge($result, $children);
}
}
return $result;
}
}
模版代码:
<select name="category_id" class="form-control">
<option value="0">请选择分类</option>
{foreach $categorys $cid=>$item}
<option value="{$cid}"
{if !$item.selectable}disabled{/if}
{if $category_id == $cid}selected{/if}>
{$item.title}
</option>
{/foreach}
</select>