layui是一個專門為后臺而設計的一個前端框架端姚,功能強大,特別適合后端開發(fā)人員讹俊,本文以一個demo把登錄模塊和權(quán)限模塊基本原理說明垦沉,詳細的內(nèi)容可以參考layui的官方文檔,git地址
搭建項目
項目架構(gòu)是springboot+thymeleaf+layui仍劈,結(jié)構(gòu)如下圖厕倍,文件有點多,分成兩張圖
其中resources資源文件里的layui文件夾下就是layui的所有文件贩疙,內(nèi)容需要到官網(wǎng)下載讹弯,解壓后全部復制即可
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.haijunyin</groupId>
<artifactId>layuidemo-permission</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>layuidemo-permission</name>
<description>Demo project for Spring Boot</description>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除內(nèi)置容器况既,排除內(nèi)置容器導出成war包可以讓外部容器運行spring-boot項目-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
#thymelea模板配置
xspring.thymeleaf.prefi=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
#熱部署文件,頁面不產(chǎn)生緩存组民,及時更新
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
LayuidemoPermissionApplication.java
package com.haijunyin.layuidemo.permission;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 繼承SpringBootServletInitializer棒仍,因為繼承SpringBootServletInitializer是繼承WebApplicationInitializer的,而servlet容器啟動的時候
* 會將WebApplicationInitializer相關(guān)的所有子類實例化(這也是servlet3.0以上的版本提供支持)臭胜,所以我們還需要在pom.xml
* 文件中導入servlet3.0及以上的版本
*/
@ComponentScan(value = "com.haijunyin.layuidemo.permission")
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableAsync
public class LayuidemoPermissionApplication extends SpringBootServletInitializer{
@Override
public SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(LayuidemoPermissionApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(LayuidemoPermissionApplication.class, args);
}
}
admin_user_list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>layui在線調(diào)試</title>
<link rel="stylesheet" href="../layui/css/layui.css" media="all">
<style>
body{margin: 10px;}
.demo-carousel{height: 200px; line-height: 200px; text-align: center;}
</style>
</head>
<body>
<table class="layui-hide" id="demo" lay-filter="test"></table>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a>
<a class="layui-btn layui-btn-xs" lay-event="edit">編輯</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>
</script>
<div class="layui-tab layui-tab-brief" lay-filter="demo">
<ul class="layui-tab-title">
<li class="layui-this">演示說明</li>
<li>日期</li>
<li>分頁</li>
<li>上傳</li>
<li>滑塊</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-carousel" id="test1">
<div carousel-item>
<div><p class="layui-bg-green demo-carousel">在這里莫其,你將以最直觀的形式體驗 layui!</p></div>
<div><p class="layui-bg-red demo-carousel">在編輯器中可以執(zhí)行 layui 相關(guān)的一切代碼</p></div>
<div><p class="layui-bg-blue demo-carousel">你也可以點擊左側(cè)導航針對性地試驗我們提供的示例</p></div>
<div><p class="layui-bg-orange demo-carousel">如果最左側(cè)的導航的高度超出了你的屏幕</p></div>
<div><p class="layui-bg-cyan demo-carousel">你可以將鼠標移入導航區(qū)域耸三,然后滑動鼠標滾輪即可</p></div>
</div>
</div>
</div>
<div class="layui-tab-item">
<div id="laydateDemo"></div>
</div>
<div class="layui-tab-item">
<div id="pageDemo"></div>
</div>
<div class="layui-tab-item">
<div class="layui-upload-drag" id="uploadDemo">
<i class="layui-icon"></i>
<p>點擊上傳榜配,或?qū)⑽募献У酱颂?lt;/p>
</div>
</div>
<div class="layui-tab-item">
<div id="sliderDemo" style="margin: 50px 20px;"></div>
</div>
</div>
</div>
<blockquote class="layui-elem-quote layui-quote-nm layui-hide" id="footer">layui {{ layui.v }} 提供強力驅(qū)動</blockquote>
<script src="../layui/layui.js"></script>
<script>
layui.config({
version: '1545041465480' //為了更新 js 緩存,可忽略
});
layui.use(['laydate', 'laypage', 'layer', 'table', 'carousel', 'upload', 'element', 'slider'], function(){
var laydate = layui.laydate //日期
,laypage = layui.laypage //分頁
,layer = layui.layer //彈層
,table = layui.table //表格
,carousel = layui.carousel //輪播
,upload = layui.upload //上傳
,element = layui.element //元素操作
,slider = layui.slider //滑塊
//向世界問個好
layer.msg('Hello World');
//監(jiān)聽Tab切換
element.on('tab(demo)', function(data){
layer.tips('切換了 '+ data.index +':'+ this.innerHTML, this, {
tips: 1
});
});
//執(zhí)行一個 table 實例
table.render({
elem: '#demo'
,height: 420
,url: '/demo/table/user/' //數(shù)據(jù)接口
,title: '用戶表'
,page: true //開啟分頁
,toolbar: 'default' //開啟工具欄吕晌,此處顯示默認圖標,可以自定義模板临燃,詳見文檔
,totalRow: true //開啟合計行
,cols: [[ //表頭
{type: 'checkbox', fixed: 'left'}
,{field: 'id', title: 'ID', width:80, sort: true, fixed: 'left', totalRowText: '合計:'}
,{field: 'username', title: '用戶名', width:80}
,{field: 'experience', title: '積分', width: 90, sort: true, totalRow: true}
,{field: 'sex', title: '性別', width:80, sort: true}
,{field: 'score', title: '評分', width: 80, sort: true, totalRow: true}
,{field: 'city', title: '城市', width:150}
,{field: 'sign', title: '簽名', width: 200}
,{field: 'classify', title: '職業(yè)', width: 100}
,{field: 'wealth', title: '財富', width: 135, sort: true, totalRow: true}
,{fixed: 'right', width: 165, align:'center', toolbar: '#barDemo'}
]]
});
//監(jiān)聽頭工具欄事件
table.on('toolbar(test)', function(obj){
var checkStatus = table.checkStatus(obj.config.id)
,data = checkStatus.data; //獲取選中的數(shù)據(jù)
switch(obj.event){
case 'add':
layer.msg('添加');
break;
case 'update':
if(data.length === 0){
layer.msg('請選擇一行');
} else if(data.length > 1){
layer.msg('只能同時編輯一個');
} else {
layer.alert('編輯 [id]:'+ checkStatus.data[0].id);
}
break;
case 'delete':
if(data.length === 0){
layer.msg('請選擇一行');
} else {
layer.msg('刪除');
}
break;
};
});
//監(jiān)聽行工具事件
table.on('tool(test)', function(obj){ //注:tool 是工具條事件名睛驳,test 是 table 原始容器的屬性 lay-filter="對應的值"
var data = obj.data //獲得當前行數(shù)據(jù)
,layEvent = obj.event; //獲得 lay-event 對應的值
if(layEvent === 'detail'){
layer.msg('查看操作');
} else if(layEvent === 'del'){
layer.confirm('真的刪除行么', function(index){
obj.del(); //刪除對應行(tr)的DOM結(jié)構(gòu)
layer.close(index);
//向服務端發(fā)送刪除指令
});
} else if(layEvent === 'edit'){
layer.msg('編輯操作');
}
});
//執(zhí)行一個輪播實例
carousel.render({
elem: '#test1'
,width: '100%' //設置容器寬度
,height: 200
,arrow: 'none' //不顯示箭頭
,anim: 'fade' //切換動畫方式
});
//將日期直接嵌套在指定容器中
var dateIns = laydate.render({
elem: '#laydateDemo'
,position: 'static'
,calendar: true //是否開啟公歷重要節(jié)日
,mark: { //標記重要日子
'0-10-14': '生日'
,'2018-08-28': '新版'
,'2018-10-08': '神秘'
}
,done: function(value, date, endDate){
if(date.year == 2017 && date.month == 11 && date.date == 30){
dateIns.hint('一不小心就月底了呢');
}
}
,change: function(value, date, endDate){
layer.msg(value)
}
});
//分頁
laypage.render({
elem: 'pageDemo' //分頁容器的id
,count: 100 //總頁數(shù)
,skin: '#1E9FFF' //自定義選中色值
//,skip: true //開啟跳頁
,jump: function(obj, first){
if(!first){
layer.msg('第'+ obj.curr +'頁', {offset: 'b'});
}
}
});
//上傳
upload.render({
elem: '#uploadDemo'
,url: '' //上傳接口
,done: function(res){
console.log(res)
}
});
slider.render({
elem: '#sliderDemo'
,input: true //輸入框
});
//底部信息
var footerTpl = lay('#footer')[0].innerHTML;
lay('#footer').html(layui.laytpl(footerTpl).render({}))
.removeClass('layui-hide');
});
</script>
</body>
</html>
index.html,此文件是顯示菜單的主要文件
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>XXX后臺管理系統(tǒng)</title>
<link rel="stylesheet" th:href="@{layui/css/layui.css}">
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">XXX后臺管理系統(tǒng)</div>
<!-- 頭部區(qū)域(可配合layui已有的水平導航) -->
<ul class="layui-nav layui-layout-left">
<li class="layui-nav-item"><a href="">控制臺</a></li>
<li class="layui-nav-item"><a href="">商品管理</a></li>
<li class="layui-nav-item"><a href="">用戶</a></li>
<li class="layui-nav-item">
<a href="javascript:;">其它系統(tǒng)</a>
<dl class="layui-nav-child">
<dd><a href="">郵件管理</a></dd>
<dd><a href="">消息管理</a></dd>
<dd><a href="">授權(quán)管理</a></dd>
</dl>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<img src="http://t.cn/RCzsdCq" class="layui-nav-img">
<span th:text="${adminUserInfo.userName}"></span>
</a>
<dl class="layui-nav-child">
<dd><a href="">基本資料</a></dd>
<dd><a href="">安全設置</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="">退了</a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左側(cè)導航區(qū)域(可配合layui已有的垂直導航) -->
<ul class="layui-nav layui-nav-tree">
<li class="layui-nav-item" th:each="adminParentMenuInfo : ${adminUserInfo.adminParentMenuInfos}">
<a class="" href="javascript:;" th:text="${adminParentMenuInfo.parentMenuName}"></a>
<dl class="layui-nav-child" th:each="adminMenuInfo : ${adminParentMenuInfo.adminMenuInfos}">
<dd class="layui-nav">
<a href="javascript:;" th:id="${adminMenuInfo.filterId}" th:zdy-url="${adminMenuInfo.menuUrl}">
<cite th:text="${adminMenuInfo.menuName}"></cite>
</a>
</dd>
</dl>
</li>
</ul>
</div>
</div>
<div class="layui-body">
<div class="layui-tab" lay-allowClose="true" lay-filter="demo">
<ul class="layui-tab-title" id="myLayuiTab">
</ul>
<div class="layui-tab-content">
</div>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定區(qū)域 -->
? layui.com - 底部固定區(qū)域
</div>
</div>
<script th:src="@{layui/layui.js}"></script>
<script>
//JavaScript代碼區(qū)域
layui.use('element', function(){
var element = layui.element;
element.on('nav', function(data){
// console.log(this); //當前Tab標題所在的原始DOM元素
var zdyUrl = this.getAttribute("zdy-url"); //獲取url
var layId = this.getAttribute("id"); //獲取id
var title = this.getElementsByTagName("cite").item(0).textContent;
//組裝content
var content = '<iframe frameborder="0" scrolling="no" width="100%" height="100%" src="' + zdyUrl + '"></iframe>';
//判斷myLayuiTab中有沒有重復膜廊,如果有乏沸,則不添加
var documentLis = document.getElementById("myLayuiTab").getElementsByTagName("li");
var flag = false;
for(var i=0; i<documentLis.length; i++){
var documentLi = documentLis[i];
var layIdView = documentLi.getAttribute("lay-id");
if(layId == layIdView){
flag = true;
}
}
if(!flag) {
//添加
element.tabAdd('demo', {
title: title
, content: content
, id: layId
});
}
//切換
element.tabChange('demo', layId);
});
});
</script>
</body>
</html>
login.html,登錄頁
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>XXX后臺登錄</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" th:href="@{layui/css/layui.css}" media="all">
</head>
<body>
<blockquote class="layui-elem-quote layui-text">
歡迎訪問后臺管理系統(tǒng)
</blockquote>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend>登錄</legend>
</fieldset>
<form class="form-horizontal" th:action="@{/login}" method="get">
<div class="layui-form-item">
<label class="layui-form-label">輸入框</label>
<div class="layui-input-block">
<input type="text" name="userName" lay-verify="title" autocomplete="off" placeholder="用戶名" required="true" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密碼框</label>
<div class="layui-input-block">
<input type="password" name="userPwd" placeholder="請輸入密碼" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">驗證碼</label>
<div class="layui-input-block">
<input type="text" name="verifyCode" placeholder="驗證碼" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit="" lay-filter="demo1">立即提交</button>
</div>
</div>
</form>
<script th:src="@{layui/layui.js}" charset="utf-8"></script>
</body>
</html>
layui下的所有文件都是官網(wǎng)下載然后解壓的
DefineAdapter.java爪瓜,攔截器配置
package com.haijunyin.layuidemo.permission.config;
import com.haijunyin.layuidemo.permission.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class DefineAdapter implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
//登錄攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//排除不被攔截的資源
List<String> excludePaths = new ArrayList<>();
//layui的靜態(tài)文件
excludePaths.add("/layui/**");
//靜態(tài)頁面
excludePaths.add("/**/*.html");
//登錄
excludePaths.add("/");
excludePaths.add("/login");
// excludePaths.add("/error");
registry.addInterceptor(loginInterceptor).
addPathPatterns("/**").excludePathPatterns(excludePaths);
}
}
AdminController.java
package com.haijunyin.layuidemo.permission.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "admin")
public class AdminController {
@RequestMapping(value = "list",method = RequestMethod.GET)
public String list(){
return "權(quán)限List測試";
}
}
LoginController.java
package com.haijunyin.layuidemo.permission.controller;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import com.haijunyin.layuidemo.permission.services.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@Autowired
private AdminUserService adminUserService;
/**
* 設置默認打開地址http://localhost:8020的跳轉(zhuǎn)(需要在攔截器中排除)
* 1.已登錄蹬跃,跳轉(zhuǎn)到index.html,把adminUserInfo返回前端渲染
* 2.未登錄铆铆,跳轉(zhuǎn)到登錄頁
*/
@RequestMapping(value = "/",method = RequestMethod.GET)
public String index(HttpServletRequest request, ModelMap modelMap){
HttpSession session = request.getSession();
AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
if(null != adminUserInfo){
modelMap.addAttribute("adminUserInfo",adminUserInfo);
return "index";
}else{
return "login";
}
}
/**
* 登錄(需要在攔截器中排除)
* 1.已登錄蝶缀,跳轉(zhuǎn)到index.html,把adminUserInfo返回前端渲染
* 2.未登錄薄货,驗證密碼翁都,如果密碼正確,跳轉(zhuǎn)到index.html, 則把用戶信息放入session谅猾,并把adminUserInfo返回前端渲染
* 如果密碼錯誤柄慰,跳轉(zhuǎn)到login.html
*/
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(@RequestParam(value = "userName", required = false) String userName,
@RequestParam(value = "userPwd", required = false) String userPwd,
@RequestParam(value = "verifyCode", required = false) String verifyCode,
HttpServletRequest request,
ModelMap modelMap){
//先驗證session,再驗證密碼
HttpSession session = request.getSession();
AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
if(null != adminUserInfo){
modelMap.addAttribute("adminUserInfo",adminUserInfo);
return "index";
}else{
//驗證密碼
AdminUserInfo adminUserInfo0 = adminUserService.findByUserName(userName);
System.out.println("驗證登錄...userName="+userName+"userPwd="+userPwd+"verifyCode="+verifyCode);
if(adminUserInfo0.getUserPwd().equals(userPwd)){
//用戶信息放入session
System.out.println("登錄...成功..." + "用戶名:" + userName);
request.getSession().setAttribute("adminUserInfo", adminUserInfo0);
modelMap.addAttribute("adminUserInfo",adminUserInfo0);
return "index";
}else{
System.out.println("登錄...密碼輸入錯誤..." + "用戶名:" + userName);
return "login";
}
}
}
}
LoginInterceptor.java税娜,登錄攔截器坐搔,用于攔截處理登錄和為登錄狀態(tài)下的ajax請求
package com.haijunyin.layuidemo.permission.interceptor;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Service
public class LoginInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
AdminUserInfo adminUserInfo = (AdminUserInfo) session.getAttribute("adminUserInfo");
//未登錄去登錄
if(null == adminUserInfo){
//注意:這里需要寫上"/login",而不是"login"敬矩,否則重定向的地址只會替換最后一個"/"后面的字符串
response.sendRedirect("/login");
}
return true;
}
}
AdminMenuInfo.java概行,子菜單信息,權(quán)限需要真正控制的信息
package com.haijunyin.layuidemo.permission.module;
public class AdminMenuInfo {
/** 子菜單唯一ID谤绳,在頁面上面會以它做唯一區(qū)分的占锯,對應到相應子窗口的lay-id屬性 */
private String filterId;
/** 子菜單名袒哥,對應子窗口的title */
private String menuName;
/** 子菜單URL,對應子窗口的鏈接html消略,點擊子菜單后堡称,會打開一個iframe并鏈接到此url */
private String menuUrl;
public AdminMenuInfo(){
}
public AdminMenuInfo(String filterId, String menuName, String menuUrl){
this.filterId = filterId;
this.menuName = menuName;
this.menuUrl = menuUrl;
}
public String getFilterId() {
return filterId;
}
public void setFilterId(String filterId) {
this.filterId = filterId;
}
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getMenuUrl() {
return menuUrl;
}
public void setMenuUrl(String menuUrl) {
this.menuUrl = menuUrl;
}
}
AdminParentInfo.java,父菜單信息
package com.haijunyin.layuidemo.permission.module;
import java.util.List;
public class AdminParentMenuInfo {
private String parentMenuName;
private List<AdminMenuInfo> adminMenuInfos;
public AdminParentMenuInfo(){
}
public AdminParentMenuInfo(String parentMenuName, List<AdminMenuInfo> adminMenuInfos){
this.parentMenuName = parentMenuName;
this.adminMenuInfos = adminMenuInfos;
}
public String getParentMenuName() {
return parentMenuName;
}
public void setParentMenuName(String parentMenuName) {
this.parentMenuName = parentMenuName;
}
public List<AdminMenuInfo> getAdminMenuInfos() {
return adminMenuInfos;
}
public void setAdminMenuInfos(List<AdminMenuInfo> adminMenuInfos) {
this.adminMenuInfos = adminMenuInfos;
}
}
AdminUserInfo.java艺演,用戶信息却紧,用戶登陸后會放入session
package com.haijunyin.layuidemo.permission.module;
import java.util.List;
public class AdminUserInfo {
private long id;
private String userName;
private String userPwd;
private List<AdminParentMenuInfo> adminParentMenuInfos;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public List<AdminParentMenuInfo> getAdminParentMenuInfos() {
return adminParentMenuInfos;
}
public void setAdminParentMenuInfos(List<AdminParentMenuInfo> adminParentMenuInfos) {
this.adminParentMenuInfos = adminParentMenuInfos;
}
}
AdminUserService.java
package com.haijunyin.layuidemo.permission.services;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
public interface AdminUserService {
AdminUserInfo findByUserName(String userName);
}
AdminUserServiceImpl.java,用戶登陸信息加載胎撤,實際開發(fā)過程中晓殊,信息都是從數(shù)據(jù)庫中讀取的,設計用戶-角色-資源的模型結(jié)構(gòu)伤提,本文不做敘述巫俺,
package com.haijunyin.layuidemo.permission.services.impl;
import com.haijunyin.layuidemo.permission.module.AdminMenuInfo;
import com.haijunyin.layuidemo.permission.module.AdminParentMenuInfo;
import com.haijunyin.layuidemo.permission.module.AdminUserInfo;
import com.haijunyin.layuidemo.permission.services.AdminUserService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class AdminUserServiceImpl implements AdminUserService {
@Override
public AdminUserInfo findByUserName(String userName) {
AdminUserInfo userInfo = new AdminUserInfo();
userInfo.setId(1);
userInfo.setUserName("yhj");
userInfo.setUserPwd("123456");
List<AdminParentMenuInfo> adminParentMenuInfos = new ArrayList<>();
//權(quán)限管理
List<AdminMenuInfo> adminMenuInfos1 = new ArrayList<>();
AdminMenuInfo adminMenuInfo1 = new AdminMenuInfo("filter1","用戶","admin/admin_user_list.html");
adminMenuInfos1.add(adminMenuInfo1);
AdminMenuInfo adminMenuInfo2 = new AdminMenuInfo("filter2", "角色","admin/admin_role_list.html");
adminMenuInfos1.add(adminMenuInfo2);
AdminParentMenuInfo adminParentMenuInfo1 = new AdminParentMenuInfo("權(quán)限管理",adminMenuInfos1);
adminParentMenuInfos.add(adminParentMenuInfo1);
//訂單管理
List<AdminMenuInfo> adminMenuInfos2 = new ArrayList<>();
AdminMenuInfo adminMenuInfo11 = new AdminMenuInfo("filter3", "訂單列表","order/order_list.html");
adminMenuInfos2.add(adminMenuInfo11);
AdminMenuInfo adminMenuInfo22 = new AdminMenuInfo("filter4", "訂單推送","order/order_send.html");
adminMenuInfos2.add(adminMenuInfo22);
AdminParentMenuInfo adminParentMenuInfo2 = new AdminParentMenuInfo("訂單管理",adminMenuInfos2);
adminParentMenuInfos.add(adminParentMenuInfo2);
userInfo.setAdminParentMenuInfos(adminParentMenuInfos);
return userInfo;
}
}
運行結(jié)果
瀏覽器中輸入地址
http://localhost:8020/
彈出登陸頁面
輸入用戶名,密碼(123456)肿男,出現(xiàn)首頁
點擊權(quán)限管理或訂單管理介汹,出現(xiàn)子窗口信息
總結(jié)
到此,Demo結(jié)束舶沛,可以看出一個完整的登陸和權(quán)限也是不簡單的嘹承,本文只是把主干完成了,細節(jié)的東西沒用去設計如庭,比如登陸頁的校驗叹卷、驗證碼,還有權(quán)限的表設計坪它,等等骤竹,不過這些都不是問題了,后續(xù)只需要慢慢完善即可哟楷,我們通過這個Demo瘤载,已經(jīng)成功地開啟了layui的大門