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

135 lines
5.2 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services\Nasa;
use App\Models\Nasa\Navigation as NasaNavigation;
use Illuminate\Support\Collection;
class NavigationService
{
public function aGetInfo($sCurrentPermissionSlug): array
{
// 1. 获取当前高亮的菜单节点
$oCurrentMenu = NasaNavigation::where("sPermissionSlug", $sCurrentPermissionSlug)
->available()
->first();
if (!$oCurrentMenu) {
return [
"aTopMenus" => $this->aGetTopMenus(),
"aSubMenus" => [],
"aTabMenus" => [],
"aMenuPath" => [],
];
}
$aTopMenus = $this->aGetTopMenus();
// 2. 获取面包屑的原始集合(链条顺序依然是:[一级, 二级, 三级...]
$cMenuPathCollection = $oCurrentMenu->cGetAncestorsAndSelf();
// ================= 核心修改:利用 keyBy 将 sComponentType 作为键 =================
// 它会自动将数组转换为:['TOP_BAR' => [...], 'LEFT_MENU' => [...]] 的高内聚结构
$aMenuPath = $cMenuPathCollection->keyBy('sComponentType')->toArray();
// ==============================================================================
// 3. 提取一级根节点(注意:集合 keyBy 后内部指针会变,所以我们从原集合中安全 get(0) 获取一级)
$oRootMenu = $cMenuPathCollection->first();
$aSubMenus = [];
$aTabMenus = [];
if ($oRootMenu) {
// 拉出该顶级菜单下的所有无限级子树
$oRootMenuWithTree = NasaNavigation::with('childrenRecursive')
->where('id', $oRootMenu->id)
->first();
if ($oRootMenuWithTree && $oRootMenuWithTree->childrenRecursive) {
// 【二级侧边栏逻辑】:保持原样
$aSubMenus = $oRootMenuWithTree->childrenRecursive
->transform(function (NasaNavigation $oSubMenu) {
$oSubMenu->sUrl = $oSubMenu->sGetFinalUrl();
return $oSubMenu;
})
->groupBy('sGroup')
->toArray();
// ================= 三级 Tab 菜单解析优化 =================
// 以前是通过 ->get(1) 硬编码拿二级。现在既然改了结构,
// 我们可以直接通过你定义的二级类型键(假设叫 TYPE_SIDE_BAR请根据你 Model 里的常量自行替换)安全捞取
$oLevel2Menu = $cMenuPathCollection->firstWhere('sComponentType', NasaNavigation::TYPE_SIDEBAR_MENU);
if ($oLevel2Menu) {
// 去子树内存里捞出这个二级节点
$oCurrentLevel2InTree = $oRootMenuWithTree->childrenRecursive
->firstWhere('id', $oLevel2Menu->id);
if ($oCurrentLevel2InTree && $oCurrentLevel2InTree->childrenRecursive->isNotEmpty()) {
$aTabMenus = $oCurrentLevel2InTree->childrenRecursive
->transform(function (NasaNavigation $oTabMenu) {
$oTabMenu->sUrl = $oTabMenu->sGetFinalUrl();
return $oTabMenu;
})
->toArray();
}
}
}
}
return [
"aTopMenus" => $aTopMenus,
"aSubMenus" => $aSubMenus,
"aTabMenus" => $aTabMenus,
"aMenuPath" => $aMenuPath, // 这里的键已经是你的组件类型字符串了
];
}
/**
* 获取全局顶级大区 (TOP_BAR)
*/
public function aGetTopMenus(): array
{
return NasaNavigation::with('childrenRecursive') // 一口气拉出无限级树结构,只有 2-3 条 SQL
->where('iParentId', 0)
->where('sComponentType', NasaNavigation::TYPE_TOP_BAR)
->available()
->orderBy('iSort', 'asc')
->get()
->transform(function (NasaNavigation $oMenu) {
// 让顶级菜单自己去递归嗅探最底层的有效 URL
$oMenu->sUrl = $oMenu->sGetFinalUrl();
return $oMenu;
})
->groupBy('sGroup')
->toArray();
}
/**
* 抓取侧边栏业务菜单树
*/
public function aGetSubMenus($iParentId): Array
{
return NasaNavigation::where('iParentId', $iParentId)
->where('sComponentType', NasaNavigation::TYPE_SIDEBAR_MENU)
->available()
->orderBy('iSort', 'asc')
->get()
->map(function ($oMenu) {
// 将模型转成数组
$aMenu = $oMenu->toArray();
// 🎯 核心防空伞:动态算好 sUrl有就给没有就给空字符串 ''
$aMenu['sUrl'] = \Illuminate\Support\Facades\Route::has($oMenu->sPermissionSlug)
? route($oMenu->sPermissionSlug)
: '';
return $aMenu;
})
->groupBy('sGroup')
->toArray();
}
}