php轻松实现无限极分类功能
本文的 todo 都是需要自行修改的
应用场景
如:
- 面包屑导航
- 分类(如:商品分类、课程分类、城市)
- 文件夹
数据表设计
code字段是为了方便筛选
// todo 表名需要更换
CREATE TABLE `表名` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(11) unsigned NOT NULL DEFAULT '0',
`name` varchar(191) COLLATE utf8_unicode_ci NOT NULL COMMENT '名称',
`code` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'code码:上级code+本级id+pid',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='XXX';
数据表数据
无限极分类的列表处理逻辑
因为是demo,所以都整合到一个function了,请自行拆分
public function getList()
{
// todo 先查询出数据表的所有数据 data
$data = Model::get();
// 处理数据
$source = [];
foreach ($data as $v) {
$source[] = [
'id' => $v->id,
'pid' => $v->pid,
'name' => $v->name,
'code' => $v->code
];
}
// 生成tree数据
$pk = 'id'; //主键标记字段
$pid = 'pid'; //parent标记字段
$child = 'children';//child标记字段
$root = 0;
$list = $source //要转换的二维结果集
$tree = [];
if (is_array($list)) {
//创建基于主键的数组引用
$refer = array();
foreach ($list as $key => $data) {
$refer[$data[$pk]] = &$list[$key];
//判断是否存在parent
$parantId = $data[$pid];
if ($root == $parantId) {
$tree[] = &$list[$key];
} else {
if (isset($refer[$parantId])) {
$parent = &$refer[$parantId];
$parent[$child][] = &$list[$key];
}
}
}
}
return response()->json([
'code' => '1',
'msg' => 'success,
'data' => $tree
]);
}
api返回格式
{
"code": 1,
"msg": "success",
"data": [
{
"id": 1,
"pid": 0,
"name": "北京",
"code": "10",
"children": [
{
"id": 2,
"pid": 1,
"name": "昌平",
"code": "1021",
"children": [
{
"id": 3,
"pid": 2,
"name": "回龙观",
"code": "102132",
"children": [
{
"id": 4,
"pid": 3,
"name": "金域华府",
"code": "10213243"
},
{
"id": 8,
"pid": 3,
"name": "融泽家园",
"code": "10213283"
}
]
},
{
"id": 5,
"pid": 2,
"name": "龙泽",
"code": "102152",
"children": [
{
"id": 7,
"pid": 5,
"name": "龙华园",
"code": "10215275"
},
{
"id": 9,
"pid": 5,
"name": "龙泽苑",
"code": "10215295"
}
]
}
]
},
{
"id": 6,
"pid": 1,
"name": "朝阳",
"code": "1061"
}
]
}
]
}
拼装无限极分类name
拼装的字符串实例:
- 北京/昌平/回龙观
- 北京/昌平
public function getData()
{
// 以code为key的分类信息
$codeList = [];
// 先查询出数据表的所有数据 list
$list = Model::get();
foreach ($list as $v) {
$codeList[$v['code']] = $v;
}
// todo $data 其它列表数据
foreach($data as &$v) {
// todo child需要自己拼装
$child = [
'pid' => 1,
'name' => '昌平'
];
if ($child['pid'] && $child['name']) {
$deptName = $this->getDeptName($departmentList, $child);
} else {
$deptName = $child['name'] ?? '-';
}
$v['str'] = $deptName;
}
}
/**
* 拼接组织架构字符串
* @param $data []
* @param $child []
* @return mixed
* User: WXiangQian
*/
public function getDeptName($data, $child)
{
$pid = $child['pid'];
if ($child['pid'] == 0) {
return $child['name'];
}
foreach ($data as $k => $v) {
if ($child['pid'] == $v['id']) {
// todo 暂时用 / 去拼接的,也可以用 - 自定义
$child['name'] = $v['name'] . '/' . $child['name'];
$child['pid'] = $v['pid'];
unset($data[$k]);
}
}
// 未找到数据,则返回 “-” 数据
if ($pid == $child['pid']) {
return '-';
}
return $this->getDeptName($data, $child);
}
实现效果图
php轻松实现无限极分类功能就简单到这了,期待你的关注👍