diff --git a/public/static/plugs/lay-module/layuimini/layuimini.css b/public/static/plugs/lay-module/layuimini/layuimini.css
index 46ece0a..4d0a0ff 100644
--- a/public/static/plugs/lay-module/layuimini/layuimini.css
+++ b/public/static/plugs/lay-module/layuimini/layuimini.css
@@ -1022,4 +1022,9 @@
.layuimini-star.layuimini-star-active {
color: #ffb800;
+}
+
+/* 面板打开期间收起「更多」hover 下拉(临时类由 openModulePanel/closeModulePanel 维护) */
+.layuimini-header-more-panelopen > .layui-nav-child {
+ display: none !important;
}
\ No newline at end of file
diff --git a/public/static/plugs/lay-module/layuimini/miniMenu.js b/public/static/plugs/lay-module/layuimini/miniMenu.js
index cfe3c6b..1596b48 100644
--- a/public/static/plugs/lay-module/layuimini/miniMenu.js
+++ b/public/static/plugs/lay-module/layuimini/miniMenu.js
@@ -8,6 +8,9 @@
// 菜单数据缓存(renderMultiModule 入口保存,收藏过滤与面板渲染复用;保存原 menuList 引用)
menuData: [],
+ // 顶部「全部模块」面板 layer index(null=面板未打开)
+ modulePanelIndex: null,
+
/**
* 菜单初始化
* @param options.menuList 菜单数据信息
@@ -238,6 +241,26 @@
miniMenu.syncHeaderActiveState();
},
+ /**
+ * 头部模块 DOM 重排:头部 li 显示顺序跟随 sortModules(收藏置顶+原序回填),「更多」li 常驻末尾
+ * 星标收藏切换后调用实现头部即时重排;移动 li 不改类名,激活态/折叠态由后续 relayout 重算
+ */
+ reorderHeaderMenu: function () {
+ var $headerMenu = $('.layuimini-menu-header-pc');
+ var $more = $headerMenu.children('.layuimini-header-more');
+ if (!$headerMenu.length || !$more.length) {
+ return;
+ }
+ var sortedMenuList = miniMenu.sortModules(miniMenu.menuData);
+ var moreEl = $more[0];
+ miniMenu.each(sortedMenuList, function (index, menu) {
+ var li = document.getElementById('multi_module_' + miniMenu.menuData.indexOf(menu) + 'HeaderId');
+ if (li) {
+ $headerMenu[0].insertBefore(li, moreEl); //依次前插到「更多」li 之前,形成排序后顺序
+ }
+ });
+ },
+
/**
* 头部模块宽度自适应折叠重算:累计宽度超出可用宽度的模块收纳进「更多」下拉
*/
@@ -300,6 +323,64 @@
}
},
+ /**
+ * 顶部「全部模块」面板打开:menuData 经 sortModules 平铺为 tile(收藏置顶+回填序)
+ */
+ openModulePanel: function () {
+ var me = this;
+ var favorites = me.getFavorites();
+ var sortedMenuList = me.sortModules(me.menuData);
+ var tileHtml = '';
+ me.each(sortedMenuList, function (index, menu) {
+ // data-header-id 按 menuList 原下标映射(排序只影响显示顺序,与头部 li id 分配规则一致);不带 data-menu,避免与 [data-menu] 委托双触发
+ var originalIndex = me.menuData.indexOf(menu);
+ var starActive = favorites.indexOf(menu.title) !== -1 ? ' layuimini-star-active' : '';
+ var icon = menu.icon ? menu.icon : '';
+ tileHtml += '
' +
+ '
' +
+ '
' + menu.title + '
' +
+ '
' +
+ '
';
+ });
+ // 配色继承:非透明头部主题时同步头部背景/字色到面板根容器;透明主题(rgba(0,0,0,0))保留 CSS 白底深字兜底
+ var panelStyle = '';
+ var headerEl = $('.layui-header').first()[0];
+ if (headerEl) {
+ var headerStyle = getComputedStyle(headerEl);
+ if (headerStyle.backgroundColor !== 'rgba(0, 0, 0, 0)') {
+ panelStyle = ' style="background-color:' + headerStyle.backgroundColor + ';color:' + headerStyle.color + ';"';
+ }
+ }
+ // 打开期间收起「更多」hover 下拉,避免遮罩后方残留展开外观(关闭时移除)
+ $('.layuimini-header-more').addClass('layuimini-header-more-panelopen');
+ me.modulePanelIndex = layer.open({
+ type: 1,
+ title: '全部模块',
+ anim: 2,
+ offset: 't',
+ area: ['100%', 'auto'],
+ shade: 0.2,
+ shadeClose: true,
+ closeBtn: 0,
+ content: '',
+ end: function () {
+ me.closeModulePanel(); //遮罩/切tile等 layer 原生关闭路径统一走清理
+ }
+ });
+ },
+
+ /**
+ * 顶部面板关闭:幂等(end 回调重入时 index 已置 null,重复调用安全)
+ */
+ closeModulePanel: function () {
+ var index = miniMenu.modulePanelIndex;
+ miniMenu.modulePanelIndex = null;
+ if (index) {
+ layer.close(index);
+ }
+ $('.layuimini-header-more').removeClass('layuimini-header-more-panelopen');
+ },
+
/**
* 轻量防抖:delay 内重复触发只执行最后一次
*/
@@ -404,6 +485,41 @@
setTimeout(miniMenu.relayoutHeaderMenu, 260); //左侧布局带 .2s 过渡,同步测量会读到中间值,等过渡结束再重算
layer.close(loading);
});
+
+ /**
+ * 顶部「全部模块」面板:委托绑定一次即可(tile/星标均为动态 DOM,重渲染无需重绑)
+ */
+ if (!miniMenu._panelListenerBound) {
+ miniMenu._panelListenerBound = true;
+ // 打开/切换面板:「更多」li 自身不带 data-menu,stopPropagation 隔离其他 body 委托
+ $('body').on('click', '.layuimini-header-more > a', function (e) {
+ e.stopPropagation();
+ if (miniMenu.modulePanelIndex) {
+ miniMenu.closeModulePanel();
+ } else {
+ miniMenu.openModulePanel();
+ }
+ });
+ // ESC 关闭面板(layui layer 原生不支持 ESC,自实现;仅在面板存在时响应,不影响其他弹层)
+ $(document).on('keydown', function (e) {
+ if (e.keyCode === 27 && miniMenu.modulePanelIndex) {
+ miniMenu.closeModulePanel();
+ }
+ });
+ // tile 主体点击:触发真实头部 li(可见或折叠隐藏均可),走 [data-menu] 委托完整链路后关闭面板
+ $('body').on('click', '.layuimini-module-panel-item', function () {
+ $('#' + $(this).attr('data-header-id')).trigger('click');
+ layer.close(miniMenu.modulePanelIndex);
+ });
+ // 星标点击:切换收藏 → 头部即时重排(重排序+折叠重算)→ 就地更新星标类名(面板保持打开,支持连续操作)
+ $('body').on('click', '.layuimini-module-panel-item .layuimini-star', function (e) {
+ e.stopPropagation(); //阻断冒泡,避免同时触发 tile 的切模块点击
+ var isAdd = miniMenu.toggleFavorite($(this).closest('.layuimini-module-panel-item').attr('data-title'));
+ miniMenu.reorderHeaderMenu();
+ miniMenu.relayoutHeaderMenu();
+ $(this).toggleClass('layuimini-star-active', isAdd);
+ });
+ }
},
};