**4s维修系统管理项目总结**
一、模块介绍
1.权限模块
(1)首先配置需要用到的核心包,然后配置shiro.xml文件,在web.xml中配置一个过滤器。在shiro.xml中配置自定义权限过滤器。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--shiro的核心对象已经交给spring管理-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="itsourceRealm"/>
</bean>
<bean id="itsourceRealm" class="cn.itsources.realm.Itsource">
</bean>
<!-- shiro最核心的配置 处理请求的具体方式
注意:该bean的id对应的值必须要和代理过滤器的名字一致,否则报错-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!--如果没有认证,都跳到loginUrl对应的路径-->
<property name="loginUrl" value="/index.jsp"/>
<!--如果认证通过之后,就跳到successUrl对应的路径-->
<property name="successUrl" value="/views/success.jsp"/>
<!--如果你访问某个资源,没有权限,就跳到unauthorizedUrl对应的路径中-->
<property name="unauthorizedUrl" value="/register/login"/>
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"/>
<!--自定义过滤器-->
<property name="filters">
<map>
<entry key="itsourcePerms" >
<bean class="cn.itsources.realm.ItsourcePermissionsAuthorizationFilter"/>
</entry>
</map>
</property>
<!-- <property name="filterChainDefinitions">
<value>
<!– anon:匿名过滤器,直接放行
authc:必须认证通过后,才能放行,否则跳到loginUrl对应的路径中–>
/*与/**的区别:
/* 拦截所有的请求(只能拦截一级路径)
/a /b /c 能拦截
/a/b 不能拦截
/** 拦截所有的请求(不管多少级都能拦截)
/a /b /c 能拦截
/a/b 能拦截
/a/b/c 能拦截–>–>
/images/**=anon
/static/**=anon
/register/login=anon
/logout=logout
/register/registered=anon
/repairman/index=anon
/register/loginPhone=anon
/register/loginCode=anon
/thirdPart=anon
/code=anon
/wechat/callback=anon
/** = authc
</value>
</property>-->
</bean>
<bean id="filterChainDefinitionMapFactory" class="cn.itsources.realm.FilterChainDefinitionMapFactory"/>
<bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapFactory" factory-method="createMap"/>
</beans>
(2)Domain的设计权限表,部门表,菜单表,因为我们没有做角色表,所有我们的权限是根据员工所在的部门而获得的。
private Long id;
private String userName;
private String passWord;
private Department department;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return passWord;
}
public void setPassword(String password) {
this.passWord = password;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
private String repairmanName;
private Integer age;
private String email;
private Date jobDate;
private String phone;
private String code;
private Boolean remeberme;
private String openId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRepairmanName() {
return repairmanName;
}
public void setRepairmanName(String repairmanName) {
this.repairmanName = repairmanName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
public Date getJobDate() {
return jobDate;
}
@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setJobDate(Date jobDate) {
this.jobDate = jobDate;
}
(3)设计了一个reamlpakage专门放置动态获取权限,根据登录的用户获取了相应的权限。
package cn.itsources.realm;
import cn.itsources.domain.Permission;
import cn.itsources.service.IPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class FilterChainDefinitionMapFactory {
@Autowired
private IPermissionService permissionService;
public Map<String ,String> createMap(){
//查询出所有的权限
List<Permission> permissions=permissionService.findAll();
//创建一个map来装权限,权限对应的是url 编号,下需要一个有顺序的map
Map<String,String> map = new LinkedHashMap<>();
map.put("/images/**", "anon");
map.put("/static/**","anon");
map.put("/login", "anon");
map.put("/logout", "logout");
map.put("/register/login", "anon");
map.put("/register/registered", "anon");
map.put("/repairman/index","anon");
map.put("/register/loginPhone", "anon");
map.put("/register/loginCode", "anon");
map.put("/thirdPart","anon");
map.put("/code", "anon");
map.put("/wechat/callback", "anon");
map.put("/register/**", "anon");
map.put("/wechat/wechats", "anon");
//循环获取查询出来的权限
for (Permission permission : permissions) {
map.put(permission.getUrl(),"itsourcePerms["+permission.getSn()+"]");
}
map.put("/**","authc");
return map ;
}
}
(4)基础的创建mapper,domain的创建
(5)Service的逻辑分析
(6)登录
//获取用户名
String username = (String) token.getPrincipal();
Repairman repairman= repairmanService.findRegisterByName(username);
if(repairman==null){
return null;
}
ByteSource salt = ByteSource.Util.bytes(MD5Util.SALT);
return new SimpleAuthenticationInfo(repairman,repairman.getPassWord(),salt,getName());
}
//获取登录信息
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//获取当前的用户
Subject subject = SecurityUtils.getSubject();
if(!subject.isAuthenticated()){
subject.login(token);
}
Repairman repairman =(Repairman) subject.getPrincipal();
UserContext.setSession(repairman);
return AjaxResult.success();
} catch (UnknownAccountException e) {
e.printStackTrace();
return AjaxResult.error("账号错误");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
return AjaxResult.error("密码错误");
}catch (AuthenticationException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
return AjaxResult.error("网络繁忙");
(7)授权
//拿到当前用户
Repairman repairman = UserContext.getUser();
//获取验证对象的角色信息和权限信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取用户的权限编号
Set<Permission> permissionsSnByLoginUser = permissionService.findPermissionsSnByLoginUser();
System.out.println(permissionsSnByLoginUser);
Set<String> set = new HashSet<>();
for (Permission permission : permissionsSnByLoginUser) {
set.add(permission.getSn());
}
//获取对象的权限
info.setStringPermissions(set);
return info;
2.菜单模块
(1)Domain,mapper的设计
(2)获取当前用户
public class UserContext {
public static final String LOGIN_IN_SESSION = "loginUser";
//存值
public static void setSession(Repairman register){
//获取当前用户
Subject subject = SecurityUtils.getSubject();
subject.getSession().setAttribute(LOGIN_IN_SESSION,register);
}
//取值
public static Repairman getUser(){
Subject subject = SecurityUtils.getSubject();
return (Repairman) subject.getSession().getAttribute(LOGIN_IN_SESSION);
}
}
(3)在service中获取子菜单和父菜单的逻辑设计
//准备一个空集合装父菜单
List<Menu> parents=new ArrayList<> ();
//查询出来的数据放入子菜单
List<Menu> menus =menuMapper.findMenuByLoginUser(LoginUser.getUserName());//admin
Menu parent =null;
for (Menu menu : menus) {//循环子菜单
if(null==menu.getParentId()){
parent=menu;
parents.add(parent);
}else {
parent.getChildren().add(menu);
}
(4)跳转主页面的时候ajax动态获取菜单
3.部门模块
(1)Domain,mapper的设计,因为在部门中有权限
(2)基本的增删改查
二、心得收获
在整个项目期间,从最开始的作为组长看文档,做需求的分析,然后按照组员的实力情况,分配具体的模块。然后是需要搭建项目,在这个第一题的过程中遇到了很多的困难,循环依赖,然后骨架写错的问题。写完过后启动服务器的时候一个一个的报错然后解决。这个项目是分组开发的,所以我们要求的是各自做各自的模块,然后通过上传操作把代码放在一块。在这个合代码的过程中我们遇到了很多的问题。但是最后都被克服一一的解决了,最终合并了一份能够运行的代码。
在这个项目过程中,因为是用了mybatis所有和项目二不一样不需要去配什么多对一,多对多,直接在映射文件上面操作 就行了,刚开始的时候还不适应,需要慢慢摸索。然后有的查询不需要关联直接使用.属性就能查询出来。这样比之前方便了很多。然后在表的实际上面体现出前面挖坑,后面填坑的操作,因为前面表没有设计的很好,然后在后面用的时候就需要重新更新字段,导致后面很多的问题,属性名混乱,然后数据查询不到。所有表的设计和字段命名的规范很重要。在做权限的时候,授权的时候,查询的是所有的权限表,只有登录过后才是根据当前的用户获取对应的权限。当时在配置授权的时候我在这个上面卡了很久,最终在老师的帮助下,找到了问题所在,xml配置的时候创建bean 不能获取的时候当前的用户。因为你启动项目的时候,还没有登录的用户,所有会报错。然后查询关联对象的时候,对应的属性和列名是相当重要的,错误的时候就不能查询出来。然后我感觉我么那组最大的问题是沟通不到位的情况,有时候别人改了你的表或者domain每个你说,就会报错。然后你还不知道哪里错了,这是我们组有的问题,然后最开始我们组的表的设计不是一起商量的所以就造成了字段使用不统一的问题。在这个项目中我感觉没有用到啥新的技术,就是以前的只是,没将项目中学到的技术集合到一起这是个遗憾。如果有机会在分组开发,我会首先的了解到需求,然后分析做表的设计。沟通也是我比较大的问题,有时候明明可以说出来就解决的问题。不能做到主动和组员沟通解决问题。在后面的项目过程中能够多于和组员沟通。