dd/app/Services/Nasa/NavigationService_v2.php
2026-06-14 15:46:45 +08:00

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;
}
}