From a55e4ce805cd6a59f1da68bf792aa14ed4bd2c9a Mon Sep 17 00:00:00 2001 From: augushong Date: Sat, 10 Oct 2026 13:19:03 +0000 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=B4=E9=83=A8=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=94=B6=E8=97=8F=E5=AD=98=E5=82=A8=E4=B8=8E=E7=BD=AE?= =?UTF-8?q?=E9=A1=B6=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugs/lay-module/layuimini/miniMenu.js | 101 ++++++++++++++++-- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/public/static/plugs/lay-module/layuimini/miniMenu.js b/public/static/plugs/lay-module/layuimini/miniMenu.js index 1b71952..ede2b93 100644 --- a/public/static/plugs/lay-module/layuimini/miniMenu.js +++ b/public/static/plugs/lay-module/layuimini/miniMenu.js @@ -5,6 +5,9 @@ var miniMenu = { + // 菜单数据缓存(renderMultiModule 入口保存,收藏过滤与面板渲染复用;保存原 menuList 引用) + menuData: [], + /** * 菜单初始化 * @param options.menuList 菜单数据信息 @@ -102,6 +105,82 @@ leftMenusHtml = me.compileMenuContainer({ id: options.parentMenuId, className: options.leftMenuCheckDefault, children: leftMenusHtml }); return leftMenusHtml; }, + /** + * 头部模块收藏存储适配层(以 title 为唯一标识,未来可整体替换为后端实现) + */ + getFavorites: function () { + var favorites = []; + try { + favorites = JSON.parse(localStorage.getItem('layuiminiHeaderModuleFavorites')); + } catch (e) { + favorites = []; + } + if (!Array.isArray(favorites)) { + return []; + } + // 与当前菜单 title 求交集,过滤已失效项,保持存储顺序 + var valid = []; + miniMenu.each(miniMenu.menuData || [], function (index, menu) { + valid.push(menu.title); + }); + var result = []; + miniMenu.each(favorites, function (index, title) { + if (valid.indexOf(title) !== -1) { + result.push(title); + } + }); + return result; + }, + + /** + * 写回收藏列表 + */ + setFavorites: function (list) { + localStorage.setItem('layuiminiHeaderModuleFavorites', JSON.stringify(list || [])); + }, + + /** + * 是否已收藏 + */ + isFavorite: function (title) { + return miniMenu.getFavorites().indexOf(title) !== -1; + }, + + /** + * 切换收藏状态,返回切换后的新状态(true=已收藏) + */ + toggleFavorite: function (title) { + var favorites = miniMenu.getFavorites(); + var isAdd = favorites.indexOf(title) === -1; + if (isAdd) { + favorites.push(title); + } else { + favorites.splice(favorites.indexOf(title), 1); + } + miniMenu.setFavorites(favorites); + return isAdd; + }, + + /** + * 头部模块排序:收藏组在前(组内保持菜单原序),未收藏组回填在后(保持菜单原序) + * 返回新数组、不修改入参;multi_module_N 下标仍按原 menuList 索引分配,仅排序显示顺序 + * 注:收藏以 title 为唯一标识,顶级模块重名视为同一收藏(同时置顶/同时取消)—— + * 框架菜单管理实际不产生重名顶级模块,此为已文档化假设而非保证 + */ + sortModules: function (menuList) { + var favorites = miniMenu.getFavorites(); + var sorted = []; + var backfill = []; + miniMenu.each(menuList || [], function (index, menu) { + if (favorites.indexOf(menu.title) !== -1) { + sorted.push(menu); + } else { + backfill.push(menu); + } + }); + return sorted.concat(backfill); + }, + /** * 多模块 * @param menuList 菜单数据 @@ -110,16 +189,18 @@ renderMultiModule: function (menuList, menuChildOpen) { menuList = menuList || []; var me = this; + miniMenu.menuData = menuList; //入口保存,注意为原数组引用 + var sortedMenuList = this.sortModules(menuList); //头部显示顺序:收藏置顶+原序回填,仅排序不改下标映射 + var firstMenu = 'multi_module_' + menuList.indexOf(sortedMenuList[0]); //排序后首模块,首屏一致性锚点 var headerMenuHtml = '', - + leftMenuHtml = '', - leftMenuCheckDefault = 'layui-this', childOpenClass = '', headerMenuCheckDefault = 'layui-this'; if (menuChildOpen) childOpenClass = ' layui-nav-itemed'; - var headerMenuHtml = this.each(menuList, function (index, val) { //顶部菜单渲染 - var menu = 'multi_module_' + index; + var headerMenuHtml = this.each(sortedMenuList, function (index, val) { //顶部菜单渲染(按排序后顺序编译,data-menu 仍按原 menuList 下标映射) + var menu = 'multi_module_' + menuList.indexOf(val); var id = menu + "HeaderId"; var topMenuItemHtml = ""; topMenuItemHtml = me.compileMenu({ @@ -131,15 +212,17 @@ target: "", children: "" }); - leftMenuHtml += me.renderLeftMenu(val.child, { + headerMenuCheckDefault = ""; + return topMenuItemHtml; + }).join(""); + leftMenuHtml = this.each(menuList, function (index, val) { //左侧菜单累积与 ul#multi_module_N 分配保持原 menuList 顺序(收藏只影响头部与面板显示顺序) + var menu = 'multi_module_' + index; + var leftMenuCheckDefault = (menu === firstMenu) ? 'layui-this' : 'layui-hide'; //默认可见 ul=排序后首模块,与头部激活项首屏一致 + return me.renderLeftMenu(val.child, { parentMenuId: menu, childOpenClass: childOpenClass, leftMenuCheckDefault: leftMenuCheckDefault }); - - headerMenuCheckDefault = ""; - leftMenuCheckDefault = "layui-hide"; - return topMenuItemHtml; }).join(""); $('.layui-layout-body').addClass('layuimini-multi-module'); //多模块标识 $('.layuimini-menu-header-pc').html(headerMenuHtml); //电脑