# 需求
- 主页菜单列表改为动态呈现方式
(不同用户登录,看到的菜单是不一样的!)
# 实现
服务端设计
- step01:设计
VO
对象 (SysUserMenuVo
)
@
需要的资源:id、name、url
--- 基于此对象,封装用户菜单信息(用户访问权限的菜单)
public class SysUserMenuVo implements 序列化接口{
UID....
private Integer id ;
private String name ;
private String url ;
private List<SysUserMenuVo> childs
}
- step02:设计
Dao
中的方法(SysMenuDao.Dao.findUserMenus(Integer[] menuIds)
)
--- 基于指定菜单id - 查询登录用户的菜单信息
List<SysUserMenuVo> findUserMenus(@Param("menuIds") Integer[] menuIds) //@Param("menuIds")
难点:只查1级菜单、2级菜单
<! 查询用户对应的菜单信息 >
<select id="findUserMenus" resultMap="sysUserMenuVo">
select p.id pi, p.name pname , p.url purl , c.id , c.name , c.url
from sys_menus p join sys_menus c
on c.parentId = p.id
<where> <!-- where 自动把and 去掉 -->
<foreach collection="array" separator="or" item="menuId">
(c.id=#(menuId))
</foreach>
and p.parentId is null
</where>
</select>
<resultMap type="com.cy.pj.sys.vo.SysUserMenuVo" id="sysUserMenuVo">
<id property="id" column="pid" />
<result property="name" column="pname" />
<result property="url" column="purl" />
<collection property="childs" ofType="com.cy.pj.sys.vo.SysUserMenuVo">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="url" column="url" />
</collection>
</resultMap>
- step03:设计
Service
的方法(SysMenuService.findUserMenus(userid)
)
@Autowired
private SysUserRoleDao sysUserRoleDao ;
public List<SysUserMenuVo> findUserMenus(Integer userId) {
//1.参数校验
//2.获取用户对应的角色id
List<Integer> roleIds = SysUserRoleDao.findRoleIdsByUserId(userId);
//3.基于角色id获取对应菜单id并校验
List<Integer> menuIds = SysRoleMenuDao.findMenuIdsByRoleIds(roleIds.toArray(new Integer[])) ;
//4. 基于菜单id获取菜单信息
List<SysUserMenuVo> list = SysMenuDao.findUserMenus(menuIds.toArray(new Integer[]))
return list;
}
- step04:设计
Controller
中的方法(PageController.doIndexUI(Model model)
)
public String doIndexUI(Model model ){
...
用model 传递 返回的信息
...
}
客户端设计
基于 thymeleaf
模板引擎中的标签对用户的菜单信息进行呈现
<li class="treeview" th:each="um:${userMenus}">
...
<span>
[[${um.name}]]
</span>
...
<ul class="treeview-menu">
<li th:each="c:${um.childs}">
<a th:onclick="javascript:doLoadUrl([[${c.url}]])">[[${c.name}]]</a>
</li>
</ul>
</li>
....
<script> function doLoadUrl(url) { $("#mainContentId").load(url); } </script>
# 2. 需求:限定登录时间(允许的时间范围之内可以登录,其他不可以)
技术分析:方案实现(AOP,Spring MVC 中的***,Filter)
本次方案:基于Spring MVC 中的 HandlerInterceptor 对象实现
# 实现
step01:编写 TimeAccessInterceptor
类(实现 HandlerInterceptor
接口)
我们的 web
包中添加…
public class TimeAccessInterceptor implements HandlerInterceptor {
Spring MVC中的***定义,基于此对象实现对登录操作的时间访问限制
DispatcherServlet --> TimeAccessInterceptor --> XxxController
(Handler)
此方***在后端控制方法执行前执行
↓
@Override
public boolean preHandle( ... ) throws Exception {
1.定义允许访问的时间范围
Calendar c = Calendar.getInstance() ; //日历对象
c.set(Calendar.HOUR_OF_DAY , 9) ;
c.set(Calendar.MINUTE , 0 ) ;
c.set(Calendar.SECOND , 0 );
long start = c.getTimeInMillis() ; // 起始访问时间
c.set(Calendar.HOUR_OF_DAY , 16) ;
long end = c.getTimeInMillis() ;
2.获取当前进行业务判定
long currentTime = System.currentTimeMills() ;
if(start < currentTime && end > currentTime ) {
return true ; //false 表示拒绝对后面的 Handler(Controller)的执行,true表示放行
}
throw new ServiceException("请在固定时间登录");
}
}
step02:配置 TimeAccessInterceptor
对象(定义 SpringWebConfig
配置类,在此类中进行配置)
@Configuration
public class SpringWebConfig implements WebMvcConfigurer { /* 提供了一些web注册方法 */
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TimeAccessInterceptor())
.addPathPatterns("/user/doLogin"); //设置
}
}