mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-11-10 04:50:50 +08:00
新增全部模块顶部面板与星标收藏
This commit is contained in:
@@ -1022,4 +1022,9 @@
|
|||||||
|
|
||||||
.layuimini-star.layuimini-star-active {
|
.layuimini-star.layuimini-star-active {
|
||||||
color: #ffb800;
|
color: #ffb800;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 面板打开期间收起「更多」hover 下拉(临时类由 openModulePanel/closeModulePanel 维护) */
|
||||||
|
.layuimini-header-more-panelopen > .layui-nav-child {
|
||||||
|
display: none !important;
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,9 @@
|
|||||||
// 菜单数据缓存(renderMultiModule 入口保存,收藏过滤与面板渲染复用;保存原 menuList 引用)
|
// 菜单数据缓存(renderMultiModule 入口保存,收藏过滤与面板渲染复用;保存原 menuList 引用)
|
||||||
menuData: [],
|
menuData: [],
|
||||||
|
|
||||||
|
// 顶部「全部模块」面板 layer index(null=面板未打开)
|
||||||
|
modulePanelIndex: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单初始化
|
* 菜单初始化
|
||||||
* @param options.menuList 菜单数据信息
|
* @param options.menuList 菜单数据信息
|
||||||
@@ -238,6 +241,26 @@
|
|||||||
miniMenu.syncHeaderActiveState();
|
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 += '<div class="layuimini-module-panel-item" data-header-id="multi_module_' + originalIndex + 'HeaderId" data-title="' + menu.title + '">' +
|
||||||
|
'<i class="' + icon + '"></i>' +
|
||||||
|
'<div>' + menu.title + '</div>' +
|
||||||
|
'<span class="layuimini-star fa fa-star-o' + starActive + '"></span>' +
|
||||||
|
'</div>';
|
||||||
|
});
|
||||||
|
// 配色继承:非透明头部主题时同步头部背景/字色到面板根容器;透明主题(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: '<div class="layuimini-module-panel"' + panelStyle + '><div class="layuimini-module-panel-grid">' + tileHtml + '</div></div>',
|
||||||
|
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 内重复触发只执行最后一次
|
* 轻量防抖:delay 内重复触发只执行最后一次
|
||||||
*/
|
*/
|
||||||
@@ -404,6 +485,41 @@
|
|||||||
setTimeout(miniMenu.relayoutHeaderMenu, 260); //左侧布局带 .2s 过渡,同步测量会读到中间值,等过渡结束再重算
|
setTimeout(miniMenu.relayoutHeaderMenu, 260); //左侧布局带 .2s 过渡,同步测量会读到中间值,等过渡结束再重算
|
||||||
layer.close(loading);
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user