81 lines
2.7 KiB
PHP
81 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Nasa;
|
|
|
|
use App\Models\Nasa\Navigation as NasaNavigation;
|
|
|
|
class NavigationService
|
|
{
|
|
/**
|
|
* 获取全通用无限级菜单及当前激活上下文
|
|
*/
|
|
public function aGetInfo(string $sCurrentPermissionSlug): array
|
|
{
|
|
// 1. 抓取当前激活的节点
|
|
$oCurrentMenu = NasaNavigation::where("sPermissionSlug", $sCurrentPermissionSlug)
|
|
->available()
|
|
->first();
|
|
|
|
// 2. 空白防御:如果路由不存在于菜单配置中,仅渲染全局根树
|
|
if (!$oCurrentMenu) {
|
|
return [
|
|
"aMenuTree" => $this->aGetGlobalTree(),
|
|
"aMenuPath" => [],
|
|
];
|
|
}
|
|
|
|
// 3. 计算面包屑/溯源链 (链条顺序:[一级, 二级, 三级...])
|
|
$cMenuPathCollection = $oCurrentMenu->cGetAncestorsAndSelf();
|
|
|
|
// 保持匈牙利命名法及纯数组输出,用 iId 或 sPermissionSlug 作为键,彻底停用组件类型做键
|
|
$aMenuPath = $cMenuPathCollection->keyBy('iId')->toArray();
|
|
|
|
// 4. 获取完整的全局树(包含各级孩子节点)
|
|
$aMenuTree = $this->aGetGlobalTree();
|
|
|
|
return [
|
|
"aMenuTree" => $aMenuTree, // 全量的无限级树状数据,交由前端去递归渲染或按层级拆解
|
|
"aMenuPath" => $aMenuPath, // 当前激活的整条链路,前端用来做多级高亮匹配
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 抓取完整的全局无限级菜单树 (支持无限层级拓展)
|
|
*/
|
|
public function aGetGlobalTree(): array
|
|
{
|
|
return NasaNavigation::with('childrenRecursive')
|
|
->where('iParentId', 0) // 从最顶层根节点开始往下拉
|
|
->available()
|
|
->orderBy('iSort', 'asc')
|
|
->get()
|
|
->map(function (NasaNavigation $oMenu) {
|
|
return $this->aFormatMenuNode($oMenu);
|
|
})
|
|
->toArray();
|
|
}
|
|
|
|
/**
|
|
* 内部递归格式化节点:解耦并动态计算每一个节点的最终有效 URL
|
|
*/
|
|
private function aFormatMenuNode(NasaNavigation $oMenu): array
|
|
{
|
|
// 将当前模型转为基础数组
|
|
$aMenu = $oMenu->toArray();
|
|
|
|
// 动态计算 URL 职责收拢
|
|
$aMenu['sUrl'] = $oMenu->sGetFinalUrl();
|
|
|
|
// 核心:如果存在递归子集,递归往下格式化,实现无限级兼容
|
|
if ($oMenu->relationLoaded('childrenRecursive') && $oMenu->childrenRecursive->isNotEmpty()) {
|
|
$aMenu['children_recursive'] = $oMenu->childrenRecursive
|
|
->map(function (NasaNavigation $oChildMenu) {
|
|
return $this->aFormatMenuNode($oChildMenu);
|
|
})
|
|
->toArray();
|
|
}
|
|
|
|
return $aMenu;
|
|
}
|
|
}
|