1. 程式人生 > >ABP+AdminLTE+Bootstrap Table許可權管理系統第十節--AdminLTE模板選單處理

ABP+AdminLTE+Bootstrap Table許可權管理系統第十節--AdminLTE模板選單處理

 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">4</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">3</small> <small class="label pull-right bg-blue">17</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">12</small> <small class="label pull-right bg-green">16</small> <small class="label pull-right bg-red">5</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> 404 Error</a></li> <li><a href="pages/examples/500.html"><i class="fa fa-circle-o"></i> 500 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>
View Code

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(20)]
        public string Name { get; set; }
        /// <summary>
        /// 連結地址
        /// </summary>
        [Required]
        [StringLength(50)]
        public string LinkUrl { get; set; }

        /// <summary>
        /// 是否是選單
        /// </summary>
        public bool IsMenu { get; set; }
        /// <summary>
        /// 模組編號
        /// </summary>
        public int Code { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        [StringLength(100)]
        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(20)]
        public string Name { get; set; }
        [Required]
        [StringLength(50)]
        public string LinkUrl { get; set; }
        [StringLength(100)]
        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<