动吧旅游项目 首页菜单动态化实现 part8

背景
用户希望在登陆以后基于权限的不同,在首页左侧呈现不同的菜单,如何实现呢?(可以采用同步或者异步请求)
初步分析
基于登陆用户id,查询用户对应的菜单信息然后进行呈现
原理应用分析
方案实现上可以基于同步或异步查询然后进行菜单数据呈现。
最终解决方案
用户登陆以后,基于用户登陆id查询用户对应的一级菜单,二级菜单然后存储到指定作用域,当进入系统首页后基于thymeleaf呈现用户菜单。
Vo类的定义
基于用户需求将查询到的一级菜单以及一级菜单对应的二级菜单查询出来,并进行封装。

package com.cy.pj.sys.pojo;

import java.io.Serializable;
import java.util.List;

import lombok.Data;


@Data
public class SysUserMenu implements Serializable{
	 
	private static final long serialVersionUID = 9102750322205839251L;
	private Integer id;
	private String name;
	private String url;
	private List<SysUserMenu> childs;

}

Dao接口实现
在SysMenuDao中添加方法,代码如下

  /**

         * 基于菜单获取菜单信息

         * @param menuIds

         * @return

         */

        List<SysUserMenuVo> findMenusByIds(

@Param("menuIds")List<Integer> menuIds);

在SysMenuMapper.xml文件中添加如下映射元素:


<select id="findMenusByIds" 

            resultMap="sysUserMenuVo">

           select p.id,p.name,p.url,c.id cid,c.name cname,c.url curl

           from sys_menus p join sys_menus c

           on c.parentId=p.id

           <where>

           <foreach collection="menuIds"

                    open="("

                    close=")"

                    separator="or"

                    item="menuId">

               c.id=#{menuId}

           </foreach>

           and p.parentId is null

           </where>

 </select>
<resultMap type="com.cy.pj.sys.vo.SysUserMenu" id="sysUserMenuVo">

               <!-- 一级菜单映射 -->

               <id  property="id" column="id"/>

               <result property="name" column="name"/>

               <result property="url" column="url"/>

               <!-- 二级菜单映射 -->

               <collection property="childs" ofType="com.cy.pj.sys.vo.SysUserMenuVo">

                   <id  property="id" column="cid"/>

                   <result property="name" column="cname"/>

                   <result property="url" column="curl"/>

               </collection>

         </resultMap>

在SysMenuService接口及实现类中定义如下方法,代码如下

  @Override

        public List<SysUserMenuVo> findUserMenusByUserId(Integer id) {

                //1.对用户id进行判断

                //2.基于用户id查找用户对应的角色id

                List<Integer> roleIds=

         sysUserRoleDao.findRoleIdsByUserId(id);

                //3.基于角色id获取角色对应的菜单信息,并进行封装.

                List<Integer> menuIds=

                sysRoleMenuDao.findMenuIdsByRoleIds(

 roleIds.toArray(new Integer[] {}));

                //4.基于菜单id获取用户对应的菜单信息并返回

                return sysMenuDao.findMenusByIds(menuIds);

        }

修改PageController中的doIndexUI方法

 @RequestMapping("doIndexUI")

         public String doIndexUI(Model model) {

                SysUser user=ShiroUtils.getUser();

                model.addAttribute("username", user.getUsername());

                List<SysUserMenuVo> userMenus=

                sysUserService.findUserMenusByUserId(user.getId());

                model.addAttribute("userMenus",userMenus);

                return "starter";

         }

将如下代码替换starter.html中Sidebar Menu对应的位置。

 <ul class="sidebar-menu" data-widget="tree">

        <li class="header">HEADER</li>

        <li class="treeview"  th:each="m:${userMenus}">

          <a href="#"><i class="fa fa-link"></i> 

          <span>[[${m.name}]]</span>

            <span class="pull-right-container">

                <i class="fa fa-angle-left pull-right"></i>

              </span>

          </a>

          <ul class="treeview-menu">

            <li th:each="c:${m.childs}">

                <a th:onclick="javascript:doLoadRS([[${c.url}]])">[[${c.name}]]</a>

            </li>

          </ul>

        </li>

      </ul>

当点击对应的菜单元素时,其事件处理函数如下:

 <script type="text/javascript">

         function doLoadRS(url){

                 $("#mainContentId").load(url);

         }

   </script>

引入模板
在这里插入图片描述

<html xmlns:th="http://www.thymeleaf.org">

控制层访问拦截实现
背景
最近项目业务上有新的需求,要求系统登陆操作要有时间限制。
初步分析
对于类似需求的实现,可采用过滤器,SpringMVC拦截器,AOP等进行实现。对于过滤器而言一般主要应用在项目中共性的过滤,AOP需要依托于动态代理以及切面对象性能方面相对较差,所以最终选择使用Spring MVC拦截器进行实现。
原理应用分析
Spring MVC中的拦截器基于回调机制,可以在目标方法执行之前,先进行业务检测,满足条件则放行,不满足条件则进行拦截,拦截器原理分析如下图所示:
在这里插入图片描述
第一步:拦截器定义,关键代码如下:
第一种实现方案:

package com.cy.pj.common.web;

/**

 * Spring MVC中拦截器

 * @author Administrator

 */

public class TimeAccessInterceptor

        implements HandlerInterceptor {

        /**

         * preHandle在控制层目标方法执行之前执行

         */

        @Override

        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

                        throws Exception {

                System.out.println("preHandler()");

                //获取java中的日历对象

                Calendar c=Calendar.getInstance();

                c.set(Calendar.HOUR_OF_DAY, 6);

                c.set(Calendar.MINUTE, 0);

                c.set(Calendar.SECOND, 0);

                long start=c.getTimeInMillis();

                c.set(Calendar.HOUR_OF_DAY,24);

                long end=c.getTimeInMillis();

                long cTime=System.currentTimeMillis();

                if(cTime<start||cTime>end)

                throw new ServiceException("不在访问时间之内");

                return true;

        }

}

第二种实现方案:

public class TimeAccessInterceptor implements HandlerInterceptor{
	 @Override

     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

                     throws Exception {

             System.out.println("preHandler()");
             
             Calendar c1=Calendar.getInstance();
             int hour1=c1.get(Calendar.HOUR_OF_DAY);
             if(hour1<=9||hour1>=18)
            	 throw new ServiceException("不在登陆时间以内9:00-18:00");
             //获取java中的日历对象
               return true;

        }

}  

第二步:拦截器配置,关键代码如下

package com.cy.pj.common.config;

@Configuration

public class SpringWebConfig implements WebMvcConfigurer{//web.xml


         //配置spring mvc 拦截器

         @Override

         public void addInterceptors(InterceptorRegistry registry) {

                 registry.addInterceptor(new TimeAccessInterceptor())

                         .addPathPatterns("/user/doLogin");

         }

}

项目打包策略及实现
jar包方式实现(推荐)

假如使用的是sts,可直接对项目进行maven install操作,然后在项目target目录中找到对应的jar包,在当前目录下执行java -jar project-a.jar即可(假如project-a.jar为打包好的jar文件)

说明:可以在打包时跳过测试类,打开pom.xml,在properties元素中添加跳过测试元素(true),代码如下:

<properties>

                <java.version>1.8</java.version>

                <skipTests>true</skipTests>

        </properties>

war包方式实现(了解)
第一步:修改pom.xml,将打包方式修改为war:

<packaging>war</packaging>

第二步:添加依赖

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-tomcat</artifactId>

    <scope>provided</scope>

</dependency>

修改启动类

@SpringBootApplication

public class Application extends SpringBootServletInitializer{

        @Override

        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

                return application.sources(Application.class);

        }

        public static void main(String[] args) {

                SpringApplication.run(Application.class, args);

        }

}


第三步:对项目进行maven install操作

第四步:将项目target目录下生成的war包拷贝到指定tomcat的webapps目录,启动tomcat测试运行,例如

http://localhost:8080/CGB-DB-SYS-V1.04-0.0.1-SNAPSHOT/doIndexUI

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
知识点:
1.LocalDateTime
在这里插入图片描述
2.自动打包
在这里插入图片描述
文件运行
在这里插入图片描述

3.pageHelper使用
segmentfault
github中pageHelper
3.1添加依赖:
在这里插入图片描述
3.2注释掉SysLogDao中:
在这里插入图片描述
3.3去掉service层方法调用部分
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值