返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期

AdminLTE菜单

上节我们把布局页,也有的临时的菜单,但是菜单不是应该动态加载的么?,所以我们这节来写菜单.首先我们看一下AdminLTE源码里面的菜单以及结构.

  <aside class="main-sidebar">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar user panel -->
<div class="user-panel">
<div class="pull-left image">
<img src="dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
</div>
<div class="pull-left info">
<p>Alexander Pierce</p>
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- search form -->
<form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search...">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
<!-- /.search form -->
<!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu">
<li class="header">MAIN NAVIGATION</li>
<li class="active treeview">
<a href="#">
<i class="fa fa-dashboard"></i> <span>Dashboard</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li class="active"><a href="index.html"><i class="fa fa-circle-o"></i> Dashboard v1</a></li>
<li><a href="index2.html"><i class="fa fa-circle-o"></i> Dashboard v2</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-files-o"></i>
<span>Layout Options</span>
<span class="pull-right-container">
<span class="label label-primary pull-right"></span>
</span>
</a>
<ul class="treeview-menu">
<li><a href="pages/layout/top-nav.html"><i class="fa fa-circle-o"></i> Top Navigation</a></li>
<li><a href="pages/layout/boxed.html"><i class="fa fa-circle-o"></i> Boxed</a></li>
<li><a href="pages/layout/fixed.html"><i class="fa fa-circle-o"></i> Fixed</a></li>
<li><a href="pages/layout/collapsed-sidebar.html"><i class="fa fa-circle-o"></i> Collapsed Sidebar</a></li>
</ul>
</li>
<li>
<a href="pages/widgets.html">
<i class="fa fa-th"></i> <span>Widgets</span>
<span class="pull-right-container">
<small class="label pull-right bg-green">new</small>
</span>
</a>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-pie-chart"></i>
<span>Charts</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="pages/charts/chartjs.html"><i class="fa fa-circle-o"></i> ChartJS</a></li>
<li><a href="pages/charts/morris.html"><i class="fa fa-circle-o"></i> Morris</a></li>
<li><a href="pages/charts/flot.html"><i class="fa fa-circle-o"></i> Flot</a></li>
<li><a href="pages/charts/inline.html"><i class="fa fa-circle-o"></i> Inline charts</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-laptop"></i>
<span>UI Elements</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="pages/UI/general.html"><i class="fa fa-circle-o"></i> General</a></li>
<li><a href="pages/UI/icons.html"><i class="fa fa-circle-o"></i> Icons</a></li>
<li><a href="pages/UI/buttons.html"><i class="fa fa-circle-o"></i> Buttons</a></li>
<li><a href="pages/UI/sliders.html"><i class="fa fa-circle-o"></i> Sliders</a></li>
<li><a href="pages/UI/timeline.html"><i class="fa fa-circle-o"></i> Timeline</a></li>
<li><a href="pages/UI/modals.html"><i class="fa fa-circle-o"></i> Modals</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-edit"></i> <span>Forms</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="pages/forms/general.html"><i class="fa fa-circle-o"></i> General Elements</a></li>
<li><a href="pages/forms/advanced.html"><i class="fa fa-circle-o"></i> Advanced Elements</a></li>
<li><a href="pages/forms/editors.html"><i class="fa fa-circle-o"></i> Editors</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-table"></i> <span>Tables</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="pages/tables/simple.html"><i class="fa fa-circle-o"></i> Simple tables</a></li>
<li><a href="pages/tables/data.html"><i class="fa fa-circle-o"></i> Data tables</a></li>
</ul>
</li>
<li>
<a href="pages/calendar.html">
<i class="fa fa-calendar"></i> <span>Calendar</span>
<span class="pull-right-container">
<small class="label pull-right bg-red"></small>
<small class="label pull-right bg-blue"></small>
</span>
</a>
</li>
<li>
<a href="pages/mailbox/mailbox.html">
<i class="fa fa-envelope"></i> <span>Mailbox</span>
<span class="pull-right-container">
<small class="label pull-right bg-yellow"></small>
<small class="label pull-right bg-green"></small>
<small class="label pull-right bg-red"></small>
</span>
</a>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-folder"></i> <span>Examples</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="pages/examples/invoice.html"><i class="fa fa-circle-o"></i> Invoice</a></li>
<li><a href="pages/examples/profile.html"><i class="fa fa-circle-o"></i> Profile</a></li>
<li><a href="pages/examples/login.html"><i class="fa fa-circle-o"></i> Login</a></li>
<li><a href="pages/examples/register.html"><i class="fa fa-circle-o"></i> Register</a></li>
<li><a href="pages/examples/lockscreen.html"><i class="fa fa-circle-o"></i> Lockscreen</a></li>
<li><a href="pages/examples/404.html"><i class="fa fa-circle-o"></i> Error</a></li>
<li><a href="pages/examples/500.html"><i class="fa fa-circle-o"></i> Error</a></li>
<li><a href="pages/examples/blank.html"><i class="fa fa-circle-o"></i> Blank Page</a></li>
<li><a href="pages/examples/pace.html"><i class="fa fa-circle-o"></i> Pace Page</a></li>
</ul>
</li>
<li class="treeview">
<a href="#">
<i class="fa fa-share"></i> <span>Multilevel</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="#"><i class="fa fa-circle-o"></i> Level One</a></li>
<li>
<a href="#"><i class="fa fa-circle-o"></i> Level One
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="#"><i class="fa fa-circle-o"></i> Level Two</a></li>
<li>
<a href="#"><i class="fa fa-circle-o"></i> Level Two
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><a href="#"><i class="fa fa-circle-o"></i> Level Three</a></li>
<li><a href="#"><i class="fa fa-circle-o"></i> Level Three</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#"><i class="fa fa-circle-o"></i> Level One</a></li>
</ul>
</li>
<li><a href="documentation/index.html"><i class="fa fa-book"></i> <span>Documentation</span></a></li>
<li class="header">LABELS</li>
<li><a href="#"><i class="fa fa-circle-o text-red"></i> <span>Important</span></a></li>
<li><a href="#"><i class="fa fa-circle-o text-yellow"></i> <span>Warning</span></a></li>
<li><a href="#"><i class="fa fa-circle-o text-aqua"></i> <span>Information</span></a></li>
</ul>
</section>
<!-- /.sidebar -->
</aside>

DTO设计

对,用ul标签和li标签包装起来的树.其实菜单都是树形结构,既然是树,那就涉及到父子结构,所以我们表就要有父菜单id,还要菜单名字,既然是菜单,要有菜单的连接,菜单是否启用,创建时间等.首先根据我们想到字段我们来设计dto

using Abp.AutoMapper;
using Abp.Domain.Entities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace JCmsErp.Meuns
{
/// <summary>
/// 菜单
/// </summary>
[Serializable]
[AutoMapFrom(typeof(Meun))]
public class MeunDto
{ /// <summary>
/// id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 父模块Id
/// </summary>
public int? ParentId { get; set; }
/// <summary>
/// 名称
/// </summary>
[Required]
[StringLength()]
public string Name { get; set; }
/// <summary>
/// 链接地址
/// </summary>
[Required]
[StringLength()]
public string LinkUrl { get; set; } /// <summary>
/// 是否是菜单
/// </summary>
public bool IsMenu { get; set; }
/// <summary>
/// 模块编号
/// </summary>
public int Code { get; set; }
/// <summary>
/// 描述
/// </summary>
[StringLength()]
public string Description { get; set; }
/// <summary>
/// 是否激活
/// </summary>
public bool Enabled { get; set; } public DateTime UpdateDate { get; set; } //public virtual MeunDto ParentModule { get; set; }
//public List<MeunDto> ChildModules { get; private set; }
public List<MeunDto> children { get; set; }
}
}

数据表

有了dto,我们就可以根据dto设计表结构

生成sql语句.

USE [JCmsErp];
GO SET ANSI_NULLS ON;
GO SET QUOTED_IDENTIFIER ON;
GO CREATE TABLE [dbo].[Modules]
(
[Id] [INT] IDENTITY(1, 1)
NOT NULL ,
[ParentId] [INT] NULL ,
[Name] [NVARCHAR](20) NOT NULL ,
[LinkUrl] [NVARCHAR](50) NOT NULL ,
[IsMenu] [BIT] NOT NULL ,
[Code] [INT] NOT NULL ,
[Description] [NVARCHAR](100) NULL ,
[Enabled] [BIT] NOT NULL ,
[UpdateDate] [DATETIME] NOT NULL ,
CONSTRAINT [PK_dbo.Modules] PRIMARY KEY CLUSTERED ( [Id] ASC )
WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY]
)
ON [PRIMARY]; GO

model

有了dto和表,我们就可以设计model

using Abp.Domain.Entities;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace JCmsErp.Meuns
{
public class Meun : Entity<int>
{
public int? ParentId { get; set; }
[Required]
[StringLength()]
public string Name { get; set; }
[Required]
[StringLength()]
public string LinkUrl { get; set; }
[StringLength()]
public string Description { get; set; }
public bool IsMenu { get; set; }
public int Code { get; set; }
public bool Enabled { get; set; } public DateTime UpdateDate { get; set; } }
}

首先我们在JCmsErp.EntityFramework的JCmsErpDbContext的OnModelCreating方法添加如下代码

  modelBuilder.Entity<Meun>().ToTable("[dbo].[Modules]");

JCmsErpDbContext方法下添加如下代码:

   public virtual IDbSet<Meun> Modules { get; set; }

MeunService递归

有了以上的基础,我们才能创建接口IMeunService和服务MeunService,这里还没涉及到菜单的curd,所以我们只需建一个关于select方法就行.

既然是父子结构就会涉及到递归.

然后我们LayoutController控制器引入接口调用MeunService的GetMeunList方法就完整的菜单了,我在数据库插入一部分数据.

LayoutController处理

看下LayoutController代码:

        private readonly IMeunService _iMeunService;
public LayoutController(IMeunService iMeunService) {
_iMeunService = iMeunService;
}
List<MeunDto> modules = new List<MeunDto>(); public ActionResult _LeftSideMenus()
{
MeunViewModel model = new MeunViewModel();
List<MeunDto> modules = _iMeunService.GetMeunList();
model._LPBasicSet = modules;
return PartialView("_LeftSideMenus", model);
}

ViewModel

试图肯定不能用AdminLTE为我们提供的默认的菜单啊,需要我们改造一下.对了需要添加一个ViewModel

我已经添加好了

using JCmsErp.Meuns;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace JCmsErp.Web.Areas.Common.Models
{
public class MeunViewModel
{
public List<MeunDto> _LPBasicSet = new List<MeunDto>();
public List<MeunDto> LPBasicSet
{
get { return _LPBasicSet; }
set { _LPBasicSet = value; }
}
}
}

看下试图代码:

@model JCmsErp.Web.Areas.Common.Models.MeunViewModel
@{
Layout = null;
} <aside class="main-sidebar">
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<!-- Sidebar user panel (optional) -->
<div class="user-panel">
<div class="pull-left image">
<img src="~/Scripts/AdminLTE-2.1.1/AdminLTE-2.1.1/dist/img/user2-160x160.jpg" class="img-circle" alt="User Image">
</div>
<div class="pull-left info">
<p>Alexander Pierce</p>
<!-- Status -->
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
</div>
</div>
<!-- search form (Optional) -->
<form action="#" method="get" class="sidebar-form">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search...">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</form>
<!-- /.search form -->
<!-- Sidebar Menu -->
<ul class="sidebar-menu">
<li class="active"><a href="/Common/Home/Index"><i class="fa fa-home"></i> <span>主页</span></a></li> @foreach (var item in Model.LPBasicSet)
{
<li class="treeview">
<a href="#">
<i class="fa fa-windows"></i> <span>@item.Name</span>
<i class="fa fa-angle-left pull-right"></i>
</a> <ul class="treeview-menu">
@{
foreach (var child in item.children)
{
<li><a href="@Url.Content(@child.LinkUrl)">@child.Name</a></li>
}
} </ul>
</li> }
</ul><!-- /.sidebar-menu -->
<!-- /.sidebar-menu -->
</section>
<!-- /.sidebar -->
</aside>

这里只需要foreach一下输出就可以了.需要注意的是关于AdminLTE的app.min.js的应用,开始我也不清楚,数据F12出来了,但是树死活点击不开,后来折腾了半天是这个js没有引用.

  <script src="~/Scripts/AdminLTE-2.1.1/AdminLTE-2.1.1/dist/js/app.min.js"></script>

至此,菜单完毕.

返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期

ABP+AdminLTE+Bootstrap Table权限管理系统第十节--AdminLTE模板菜单处理的更多相关文章

  1. ABP+AdminLTE+Bootstrap Table权限管理系统第五节--WBEAPI及SwaggerUI

    一,Web API ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没 ...

  2. ABP+AdminLTE+Bootstrap Table权限管理系统第六节--abp控制器扩展及json封装

    一,控制器AbpController 说完了Swagger ui 我们再来说一下abp对控制器的处理和json的封装. 首先我们定义一个控制器,在新增控制器的时候,控制器会自动继承自AbpContro ...

  3. ABP+AdminLTE+Bootstrap Table权限管理系统第十一节--bootstrap table之用户管理列表

    这张开始bootstrap table,引入项目有两种方法,一种是直接去官网下载 地址:http://bootstrap-table.wenzhixin.net.cn/ 另一种是Nuget引入. 然后 ...

  4. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及abp封装的Javascript函数库

    经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这里算是前面几节的一个初次试水. 首先我们数据库已经有的相应的数据. 模型和DTO已经建好,所以我们直接在服务 ...

  5. ABP+AdminLTE+Bootstrap Table权限管理系统第十一节--Bootstrap Table用户管理列表以及Module Zero之用户管理

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 用户实体 用户实体代表应用的一个用户,它派生自AbpUser类,如下所示: public class User : ...

  6. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及几种abp封装的Javascript函数库

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期         简介 经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这 ...

  7. ABP+AdminLTE+Bootstrap Table权限管理系统第六节--abp控制器扩展及json封装以及6种处理时间格式化的方法

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 一,控制器AbpController 说完了Swagger ui 我们再来说一下abp对控制器的处理和json的封 ...

  8. ABP+AdminLTE+Bootstrap Table权限管理系统第四节--仓储,服务,服务接口及依赖注入

    在ABP框架中,仓储,服务,这块算是最为重要一块之一了.ABP框架提供了创建和组装模块的基础,一个模块能够依赖于另一个模块,一个程序集可看成一个模块, 一个模块可以通过一个类来定义这个模块,而给定义这 ...

  9. ABP+AdminLTE+Bootstrap Table权限管理系统一期

       学而时习之,不亦说乎,温顾温知新,可以为师矣. 这也是算是一种学习的方法和态度吧,经常去学习和总结,在博客园看了很多大神的文章,写下一点对于ABP(ABP是“ASP.NET Boilerplat ...

随机推荐

  1. 在Linux与Windows上获取当前堆栈信息

    在编写稳定可靠的软件服务时经常用到输出堆栈信息,以便用户/开发者获取准确的运行信息.常用在日志输出,错误报告,异常检测. 在Linux有比较简便的函数获取堆栈信息: #include <stdi ...

  2. jrebel配置热部署参数

    jrebel配置热部署参数: -noverify -agentpath:D:/jrebel/lib/jrebel64.dll -Drebel.dirs=E:/workspace/item/src/ma ...

  3. 我眼中的ASP.NET Core之微服务

    ### 前言 前几天在博客园看到有园友在分享关于微软的一个微服务架构的示例程序,想必大家都已经知道了,那就是[eShopOnContainers](https://github.com/dotnet- ...

  4. Example001使用window对象打开窗口

    <!--实例001使用window对象打开窗口--> <script> <!--使用window对象打开窗口的语法格式如下--> <!--window.ope ...

  5. 遇到looper之类关于消息循环的

    原因大概是因为无法创建消息循环,这时候要考虑函数是否要在主线程或者不在主线程中进行,改一下即可

  6. Python使用QRCode生成二维码

    PIL和QRCode下载地址: http://www.pythonware.com/products/pil/ https://pypi.python.org/pypi/qrcode/5.1 #你可能 ...

  7. Asp.Net MVC-01-起步

    创建第一个MVC程序 我们先创建一个ASP.NET Web程序 模板选择MVC,因为不想使用默认的身份认证我们点击更改身份认证并选择不进行身份认证. 创建的项目结构如下: 配置与初始化 Web配置文件 ...

  8. Watson Conversation Service Implementation Methodology

    Watson Conversation Service Implementation Methodology In order to implement the WCS successfully. Y ...

  9. RabbitMQ系列教程之六:远程过程调用(RPC)

    远程过程调用(Remote Proceddure call[RPC])(本实例都是使用的Net的客户端,使用C#编写)  在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务.  ...

  10. Django学习(三)---Models(ORM框架)

    1) Django 中Models是与数据库相关的,与数据库相关的代码一般写在 models.py中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在sett ...