// +---------------------------------------------------------------------- namespace ywxapp\library; use ywxapp\model\BackendPower; /** * 模板/皮肤管理的后台菜单入口维护器(幂等)。 * * 背景:Template 控制器(模板中心 / 界面设置)属于内置模块,但历史上没有向 * backend_power 写入入口,导致这两张页面在后台左侧菜单里不可达。 * 本类补上这个缺口——按 name 查重,存在则跳过,可安全重复执行。 * * 菜单结构(顶级「界面」目录 + 两个子菜单): * 界面(目录 template, route='/template') * ├─ 模板中心(template:index -> template/index) * └─ 界面设置(template:setting -> template/setting) * * 说明:install.sql 里初始数据的 route 一律是相对后台 app 的路径(如 navbar/index), * 这里保持一致。老站点在后台点一次「同步菜单」即可补入口,无需重装。 * * @author ywxapp */ class TemplateMenu { /** 顶级目录的权限标识 */ public const ROOT = 'template'; /** * 子菜单定义:name / title / route / icon / sort */ public static function items(): array { return [ [ 'name' => 'template:index', 'title' => '模板中心', 'route' => 'template/index', 'icon' => 'layui-icon layui-icon-template', 'sort' => 1, ], [ 'name' => 'template:setting', 'title' => '界面设置', 'route' => 'template/setting', 'icon' => 'layui-icon layui-icon-theme', 'sort' => 2, ], ]; } /** * 幂等补建菜单入口。 * * @return array [ok, created, message] */ public static function sync(): array { try { $root = BackendPower::where('name', self::ROOT)->find(); if (empty($root)) { BackendPower::create([ 'pid' => 0, 'title' => '界面', 'name' => self::ROOT, 'type' => 1, 'route' => '/template', 'icon' => 'layui-icon layui-icon-template', 'sort' => 5, 'status' => 1, 'addon' => null, ]); $root = BackendPower::where('name', self::ROOT)->find(); } if (empty($root)) { return ['ok' => false, 'created' => 0, 'message' => '顶级目录创建失败']; } $pid = (int) $root->id; $created = 0; foreach (self::items() as $item) { $exists = BackendPower::where('name', $item['name'])->find(); if (! empty($exists)) { continue; // 幂等:已存在跳过 } BackendPower::create([ 'pid' => $pid, 'title' => $item['title'], 'name' => $item['name'], 'type' => 2, 'route' => $item['route'], 'icon' => $item['icon'], 'sort' => $item['sort'], 'status' => 1, 'addon' => null, ]); $created++; } return [ 'ok' => true, 'created' => $created, 'message' => $created > 0 ? "已补建 {$created} 个菜单项" : '菜单入口已存在,无需重复创建', ]; } catch (\Throwable $e) { // 表不存在(未安装)等情况不能影响页面 return ['ok' => false, 'created' => 0, 'message' => '同步失败:' . $e->getMessage()]; } } /** * 菜单入口是否已就绪(用于决定是否提示管理员点「同步」)。 */ public static function exists(): bool { try { return (bool) BackendPower::where('name', self::ROOT)->count(); } catch (\Throwable $e) { return true; // 查不到(未安装)就不提示 } } }