Model层代码:
public class SystemMenu
{
/// <summary>
/// 功能ID编号
/// </summary>
public int Id { get; set; }
/// <summary>
/// 上级功能的编号
/// </summary>
public int? ParentID { get; set; }
/// <summary>
/// 功能名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 功能目标地址
/// </summary>
public string Url { get; set; }
/// <summary>
/// 功能图标
/// </summary>
public string IconClassName { get; set; }
/// <summary>
/// 功能排序
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// 上级功能
/// </summary>
public virtual SystemMenu Parent { get; set; }
/// <summary>
/// 子功能项
/// </summary>
public virtual ICollection<SystemMenu> SubMenus { get; set; } = new HashSet<SystemMenu>();
}
EFDbcontext写法:
modelBuilder.Entity<CQIE.LMS.Models.SystemMenu>(entity =>
{
entity.Property(c => c.Id).ValueGeneratedOnAdd();
//映射父子结构
entity.HasMany(c => c.SubMenus).WithOne(c => c.Parent).HasForeignKey(c => c.ParentID).OnDelete(DeleteBehavior.Restrict);
});
通过菜单的SubMneus可以获取子菜单项,这样当我们用递归遍历菜单时就可以通过父菜单遍历子菜单。
递归生成一条菜单json数据:
public class jsona
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public virtual ICollection<jsona> SubMenus { get; set; } = new HashSet<jsona>();
}
public List<SystemMenu> GetAllSystemMenus()
{
var query = m_Manager.Ctx.SystemMenus;
return query.ToList();
}
private static SystemMenu GenerateEntityNode(List<SystemMenu> list, int id)
{
// 主菜单的id
SystemMenu entity = list.Where(p => p.Id == id).FirstOrDefault();
entity.Parent = null;
if (entity == null)//跳出循环
{
return entity;
}
// 查询子菜单
//entity.SubMenus = list.Where(p => p.ParentID == id).ToList();
entity.SubMenus = (from s in list
where s.ParentID == id
select s).ToList();
// 对子菜单进行递归
foreach (var item in entity.SubMenus)
{
GenerateEntityNode(list, item.Id);
}
return entity;
}
var s = _systemMenu.GetAllSystemMenus();
SystemMenu entity = GenerateEntityNode(s, id);//id一般为主菜单的ParentId
//转换json数据
string json = JsonConvert.SerializeObject(entity, Formatting.Indented);
jsona jsona = new jsona();
var sdf = JsonConvert.DeserializeObject(json, jsona.GetType());//把JSON对象转换
string stustrjson = '[' + JsonConvert.SerializeObject(sdf) + ']';
ViewData["MenuJSON"] = stustrjson;//通过动态类型视图把json数据传送到前端
菜单递归生成
通过此种方法可以生成一个树形结构的菜单;
<div id="tree" ></div>
<input id="Menu" style="display:none" value=@ViewData["MenuJSON"] />
//递归生成菜单
let arr = JSON.parse($("#Menu").val());
function addElement(arr, father) {
for (let i = 0; i < arr.length; i++) {
let div = document.createElement('ol')
div.innerHTML = '<li style="display:flex" ><input type="checkbox" checked /><div οnclick="FetchOperation(' + arr[i].Id + ')">' + arr[i].Name + '</div></li>'
if (arr[i].SubMenus) {
addElement(arr[i].SubMenus, div)
}
}
}
let menu = document.querySelector('#tree');
addElement(arr, menu);