1.字典表(sys_dict)
作用:用于存放多组值不变的基础数据,只对系统提供查询功能.
*记录的新增、更新、删除都是通过手动进行操作.
*其中dict_code为dict_title的编码,相同dict_title的记录为同一组基础数据,每组基础数据下又有多对dict_value与dict_name.
*每组基础数据可以根据实际的业务需求在程序中创建对应的枚举类(value和name属性).
2.系统配置表(sys_config)
作用:用于存放系统的配置项,某些业务逻辑需要根据配置项的值来做出相应的处理.
*记录的新增、删除都是通过手动进行操作.
*在系统配置页面中查询配置项并修改配置项的值.
*
*可以创建一个枚举类存放模块ID,创建常量类存放config_code.
3.地域表(sys_area)
作用:用于存放省市区地域数据,一般只对系统提供查询功能.
*
*在页面中通过多级联动选择地域,调用根据父编码查询记录的API(首次查询父编码为0的记录表示顶层节点)
4.RBAC
用户表(sys_user)
角色表(sys_role)
菜单表(sys_menu)
*若使用Shiro安全管理框架,则在实现Realm的doGetAuthorizationInfo()方法中,通过用户的Principal查询用户拥有的Role以及Permission各存放到Set集合中返回给SecurityManager,在Controller中通过注解或XML配置的方式设置资源必须拥有指定的role或permission时才能访问.
*登录接口校验成功后需要返回用户的个人信息以及拥有的角色给前端进行页面元素的控制.
用户角色关联表(sys_user_role)
*其中user_id和role_id为联合主键,可以保证一个用户不会存在相同的角色.
*当在页面查看用户拥有的角色时,调用后台API通过用户ID查询用户拥有的角色以及系统所有的角色,后台进行双重遍历,当用户拥有目标角色时flag设置为ture,供前端checkbox渲染.
*当在页面为用户新增或移除角色时,调用后台API传递选中的角色实体,后台可以删除用户拥有的所有角色再进行批量入库或者相对当前用户判断新增和删除了哪些角色再进行分步SQL操作.
角色菜单关联表(sys_role_menu)
*其中role_id和menu_id为联合主键,可以保证一个角色不会存在相同的权限.
*当在页面查看角色拥有的权限时,调用后台API通过角色ID查询角色拥有的权限以及系统所有的权限,后台进行双重遍历,当角色拥有目标权限时flag设置为ture,供前端checkbox渲染.
*当在页面为角色新增或移除权限时,调用后台API传递选中的权限实体,后台可以删除角色拥有的所有权限再进行批量入库或者相对当前角色判断新增和删除了哪些权限再进行分步SQL操作.
5.机构表(sys_office)
作用:用于存放公司的组织架构关系(适用于集团)
*新增记录时前端需要传递新增的机构信息以及父机构ID,后台将会根据父ID查询机构实体,获取其所有的父ID,构造本次新增机构实体的所有父ID,最终进行入库操作.
*删除记录时前端需要传递要删除的机构ID,后台将删除本机构及其所有子机构,只要所有的父ID中包含要删除的机构ID则也应被删除.
6.系统操作日志(sys_log)
*系统操作日志功能一般会进行日志的输出以及数据的入库.
*
*利用拦截器的afterCompletion方法实现系统操作日志(在请求被响应之后调用)
1.通过afterCompletion方法的handler参数获取访问控制层对应方法的Method对象,通过反射获取标注在控制层方法的@RequirePermissions注解中的value属性,再通过此属性从菜单表中获取对应的操作名称.
2.通过afterCompletion方法的HttpServletRequest参数的getRemoteAddress()方法获取客户端远程IP、getHeader()方法获取HTTP请求头中的user-agent参数、getRequestURI()方法获取请求URL、getParameterMap()方法获取请求体中的参数、getMethod()方法获取HTTP请求方法.
3.通过判断afterCompletion方法的Exception参数是否为空来确定此处请求是否成功,若Exception参数不为空则获取异常中的信息保存进库中.
*afterCompletion方法中应使用异步的方式新建一个线程进行日志的记录.
*使用拦截器实现系统操作日志功能的好处是可以通过HttpServletReqeust实体获取更多关于客户端的信息,缺点是不易扩展,只能通过键值对的形式获取请求参数.
*利用Spring AOP的环绕通知实现系统操作日志.
1.切入点为Service层中的业务方法.
2.当Service层中的方法执行前将会进入切面中的环绕通知方法,可以通过ProceedingJoinPoint的getArgs()方法获取连接点的参数集,在此时可以根据记录ID查询数据库中变更前的记录实体.
3.执行ProceedingJoinPoint的process()方法调用连接点,方法的返回值为连接点的返回值,若执行成功且无异常则可以判断变更前和变更后哪些属性发生了变化,最后进行入库操作.
*可以直接在连接点的前后简单的把入参和返回值进行打印.
*使用AOP实现日志的好处是不影响原有的代码结构、可以很容易的得到方法执行的参数和返回值、易扩展,可以配置不同的切入点来做不同的逻辑处理,缺点是不能获取更多关于客户端的信息.