|
@@ -91,8 +91,39 @@ class Menu
|
|
|
$menuWithDotNotation = [];
|
|
$menuWithDotNotation = [];
|
|
|
|
|
|
|
|
foreach ($this->configMenu as $item) {
|
|
foreach ($this->configMenu as $item) {
|
|
|
- if (strpos(request()->url(), route($item['route'])) !== false) {
|
|
|
|
|
- $this->currentKey = $item['key'];
|
|
|
|
|
|
|
+ // 验证菜单项必须有必要的字段
|
|
|
|
|
+ if (!isset($item['key']) || !isset($item['name']) || !isset($item['route'])) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 安全获取路由参数
|
|
|
|
|
+ $routeParameters = $item['route_parameters'] ?? [];
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否有路由参数
|
|
|
|
|
+ if (!empty($routeParameters)) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $url = route($item['route'], $routeParameters);
|
|
|
|
|
+ if (strpos(request()->url(), $url) !== false) {
|
|
|
|
|
+ $this->currentKey = $item['key'];
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ // 如果路由生成失败,回退到原来的逻辑
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (strpos(request()->url(), route($item['route'])) !== false) {
|
|
|
|
|
+ $this->currentKey = $item['key'];
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (\Exception $e2) {
|
|
|
|
|
+ // 忽略错误
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (strpos(request()->url(), route($item['route'])) !== false) {
|
|
|
|
|
+ $this->currentKey = $item['key'];
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ // 忽略错误
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$menuWithDotNotation[$item['key']] = $item;
|
|
$menuWithDotNotation[$item['key']] = $item;
|
|
@@ -101,19 +132,29 @@ class Menu
|
|
|
$menu = Arr::undot(Arr::dot($menuWithDotNotation));
|
|
$menu = Arr::undot(Arr::dot($menuWithDotNotation));
|
|
|
|
|
|
|
|
foreach ($menu as $menuItemKey => $menuItem) {
|
|
foreach ($menu as $menuItemKey => $menuItem) {
|
|
|
|
|
+ // 验证顶级菜单项
|
|
|
|
|
+ if (!is_array($menuItem) || !isset($menuItem['key'])) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$subMenuItems = $this->processSubMenuItems($menuItem);
|
|
$subMenuItems = $this->processSubMenuItems($menuItem);
|
|
|
|
|
|
|
|
|
|
+ // 安全解析路由参数
|
|
|
|
|
+ $routeParameters = $this->parseRouteParameters($menuItem['route_parameters'] ?? []);
|
|
|
|
|
+
|
|
|
$this->addItem(new MenuItem(
|
|
$this->addItem(new MenuItem(
|
|
|
key: $menuItemKey,
|
|
key: $menuItemKey,
|
|
|
name: trans($menuItem['name']),
|
|
name: trans($menuItem['name']),
|
|
|
route: $menuItem['route'],
|
|
route: $menuItem['route'],
|
|
|
- sort: $menuItem['sort'],
|
|
|
|
|
- icon: $menuItem['icon'],
|
|
|
|
|
|
|
+ sort: $menuItem['sort'] ?? 0,
|
|
|
|
|
+ icon: $menuItem['icon'] ?? '',
|
|
|
children: $subMenuItems,
|
|
children: $subMenuItems,
|
|
|
|
|
+ routeParameters: $routeParameters,
|
|
|
));
|
|
));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Process sub menu items.
|
|
* Process sub menu items.
|
|
|
*/
|
|
*/
|
|
@@ -121,21 +162,60 @@ class Menu
|
|
|
{
|
|
{
|
|
|
return collect($menuItem)
|
|
return collect($menuItem)
|
|
|
->sortBy('sort')
|
|
->sortBy('sort')
|
|
|
- ->filter(fn ($value) => is_array($value))
|
|
|
|
|
|
|
+ ->filter(fn ($value, $key) => is_array($value) && isset($value['key']))
|
|
|
->map(function ($subMenuItem) {
|
|
->map(function ($subMenuItem) {
|
|
|
|
|
+ // 确保子菜单项有必要的字段
|
|
|
|
|
+ if (!isset($subMenuItem['key']) || !isset($subMenuItem['name']) || !isset($subMenuItem['route'])) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$subSubMenuItems = $this->processSubMenuItems($subMenuItem);
|
|
$subSubMenuItems = $this->processSubMenuItems($subMenuItem);
|
|
|
|
|
|
|
|
|
|
+ // 安全解析子菜单的路由参数
|
|
|
|
|
+ $routeParameters = $this->parseRouteParameters($subMenuItem['route_parameters'] ?? []);
|
|
|
|
|
+
|
|
|
return new MenuItem(
|
|
return new MenuItem(
|
|
|
key: $subMenuItem['key'],
|
|
key: $subMenuItem['key'],
|
|
|
name: trans($subMenuItem['name']),
|
|
name: trans($subMenuItem['name']),
|
|
|
route: $subMenuItem['route'],
|
|
route: $subMenuItem['route'],
|
|
|
- sort: $subMenuItem['sort'],
|
|
|
|
|
- icon: $subMenuItem['icon'],
|
|
|
|
|
|
|
+ sort: $subMenuItem['sort'] ?? 0,
|
|
|
|
|
+ icon: $subMenuItem['icon'] ?? '',
|
|
|
children: $subSubMenuItems,
|
|
children: $subSubMenuItems,
|
|
|
|
|
+ routeParameters: $routeParameters,
|
|
|
);
|
|
);
|
|
|
- });
|
|
|
|
|
|
|
+ })
|
|
|
|
|
+ ->filter(); // 过滤掉 null 值
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Parse route parameters from various formats.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param mixed $parameters
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ private function parseRouteParameters($parameters): array
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($parameters)) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果已经是数组,直接返回
|
|
|
|
|
+ if (is_array($parameters)) {
|
|
|
|
|
+ // 过滤空值
|
|
|
|
|
+ return array_values(array_filter($parameters));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是 JSON 字符串,解码
|
|
|
|
|
+ if (is_string($parameters)) {
|
|
|
|
|
+ $decoded = json_decode($parameters, true);
|
|
|
|
|
+ if (is_array($decoded)) {
|
|
|
|
|
+ return array_values(array_filter($decoded));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
/**
|
|
/**
|
|
|
* Get current active menu.
|
|
* Get current active menu.
|
|
|
*/
|
|
*/
|