├── .gitignore ├── DockerFile ├── README.md ├── manage-authentication ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── dingjn │ └── manage │ └── autentication │ └── config │ ├── config │ ├── JwtAuthenticationTokenFilter.java │ └── SecurityConfig.java │ ├── controller │ └── JwtAuthController.java │ ├── mapper │ └── MyUserDetailsServiceMapper.java │ ├── model │ ├── JwtProperties.java │ └── MyUserDetails.java │ ├── service │ ├── JwtAuthService.java │ ├── MyRBACService.java │ └── MyUserDetailService.java │ └── util │ └── JwtTokenUtil.java ├── manage-common ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── dingjn │ └── manage │ └── common │ ├── exception │ ├── CustomException.java │ └── CustomExceptionType.java │ ├── response │ ├── ResponseCode.java │ └── ServerResponse.java │ └── util │ ├── DataTree.java │ └── DataTreeUtil.java ├── manage-model ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── dingjn │ └── manage │ └── model │ ├── dto │ ├── SysUserDTO.java │ └── SysUserRoleDTO.java │ ├── node │ ├── SysApi.java │ ├── SysApiNode.java │ ├── SysMenu.java │ ├── SysMenuNode.java │ ├── SysOrg.java │ ├── SysOrgNode.java │ └── SysUser.java │ └── vo │ ├── PermVO.java │ ├── SysRoleVO.java │ └── SysUserVO.java ├── manage-persistence ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── dingjn │ └── manage │ └── persistence │ ├── entity │ ├── SysApi.java │ ├── SysConfig.java │ ├── SysDict.java │ ├── SysMenu.java │ ├── SysOrg.java │ ├── SysRole.java │ ├── SysRoleApi.java │ ├── SysRoleMenu.java │ ├── SysUser.java │ └── SysUserRole.java │ └── mapper │ ├── SysApiMapper.java │ ├── SysConfigMapper.java │ ├── SysDictMapper.java │ ├── SysMenuMapper.java │ ├── SysOrgMapper.java │ ├── SysRoleApiMapper.java │ ├── SysRoleMapper.java │ ├── SysRoleMenuMapper.java │ ├── SysUserMapper.java │ ├── SysUserRoleMapper.java │ └── xml │ ├── SysApiMapper.xml │ ├── SysConfigMapper.xml │ ├── SysDictMapper.xml │ ├── SysMenuMapper.xml │ ├── SysOrgMapper.xml │ ├── SysRoleApiMapper.xml │ ├── SysRoleMapper.xml │ ├── SysRoleMenuMapper.xml │ ├── SysUserMapper.xml │ └── SysUserRoleMapper.xml ├── manage-service ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── dingjn │ └── manage │ └── service │ ├── SysApiService.java │ ├── SysMenuService.java │ ├── SysOrgService.java │ ├── SysRoleService.java │ ├── SysUserService.java │ └── impl │ ├── SysApiServiceImpl.java │ ├── SysMenuServiceImpl.java │ ├── SysOrgServiceImpl.java │ ├── SysRoleServiceImpl.java │ └── SysUserServiceImpl.java ├── manage-web ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── dingjn │ │ │ └── manage │ │ │ └── web │ │ │ ├── ManageWebApplication.java │ │ │ ├── config │ │ │ ├── CorsConfig.java │ │ │ ├── GlobalExcepitonHandler.java │ │ │ ├── GlobalRequestAdvice.java │ │ │ └── MybatisPlusConfig.java │ │ │ └── controller │ │ │ ├── SysApiController.java │ │ │ ├── SysMenuController.java │ │ │ ├── SysOrgController.java │ │ │ ├── SysRoleController.java │ │ │ └── SysUserController.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── dingjn │ └── manage │ └── web │ ├── BinarySearchTest.java │ ├── EntityGenerator.java │ ├── ManageWebApplicationTests.java │ ├── SolveTest.java │ └── UserMapperTest.java ├── pom.xml ├── sql └── vuemanage.sql └── vue-manage-front ├── .babelrc ├── .gitignore ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── index.html ├── src ├── App.vue ├── api │ ├── index.js │ └── system.js ├── assets │ └── logo.png ├── components │ ├── Home.vue │ ├── Login.vue │ ├── layout │ │ ├── LayoutMenu.vue │ │ ├── MultiTree.vue │ │ └── TreeSelect.vue │ └── system │ │ ├── FirstPage.vue │ │ ├── SysApi.vue │ │ ├── SysMenu.vue │ │ ├── SysOrg.vue │ │ ├── SysRole.vue │ │ └── SysUser.vue ├── lib │ ├── request.js │ └── utils.js ├── main.js ├── router │ └── index.js └── store │ └── index.js └── static └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | target/ 3 | *.iml 4 | .DS_Store -------------------------------------------------------------------------------- /DockerFile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | 3 | COPY *.jar /vuemanage.jar 4 | 5 | CMD ["--server.port=8080"] 6 | 7 | EXPOSE 8080 8 | 9 | ENTRYPOINT ["java","-jar","/vuemanage.jar"] 10 | 11 | CMD echo "---end---" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 项目介绍 2 | 3 | **一个基于SpringBoot + Vue + Element UI 开发的权限管理系统** 4 | 5 | - 角色权限精确到菜单、接口访问 6 | - 前后端通过jwt进行认证状态管理 7 | - 持续更新... 8 | 9 | ## 技术栈 10 | 11 | - 后端:SpringBoot、SpringSecurity+jwt、MyBatisPlus 12 | - 前端:Vue-cli、Vuex、ElementUI 13 | 14 | ## 项目截图 15 | 16 | ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfvkfm46hxj31ky0u0e84.jpg) 17 | 18 | ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfvkgf1y94j31km0u0n5n.jpg) 19 | 20 | ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfvkh4e9nkj31ko0u044w.jpg) 21 | 22 | ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfvkhh99nbj31ko0u0doq.jpg) 23 | 24 | ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfvkhye127j31ks0u0k1g.jpg) 25 | 26 | ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfvkjmf6c4j31kz0u0tjm.jpg) 27 | -------------------------------------------------------------------------------- /manage-authentication/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | com.dingjn 7 | vue-manage 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 认证鉴权模块 12 | manage-authentication 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-security 18 | 19 | 20 | 21 | com.dingjn 22 | manage-persistence 23 | 1.0-SNAPSHOT 24 | 25 | 26 | 27 | io.jsonwebtoken 28 | jjwt 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-configuration-processor 34 | true 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-autoconfigure 39 | 40 | 41 | 42 | com.dingjn 43 | manage-common 44 | 1.0-SNAPSHOT 45 | 46 | 47 | org.springframework 48 | spring-web 49 | 50 | 51 | org.springframework 52 | spring-context 53 | 54 | 55 | org.springframework.security 56 | spring-security-core 57 | 58 | 59 | org.springframework.security 60 | spring-security-web 61 | 62 | 63 | 64 | javax.servlet 65 | javax.servlet-api 66 | provided 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-compiler-plugin 76 | 77 | 8 78 | 8 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/config/JwtAuthenticationTokenFilter.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.config; 2 | 3 | 4 | import com.dingjn.manage.autentication.config.model.JwtProperties; 5 | import com.dingjn.manage.autentication.config.service.MyUserDetailService; 6 | import com.dingjn.manage.autentication.config.util.JwtTokenUtil; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | import org.springframework.security.core.userdetails.UserDetails; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.web.filter.OncePerRequestFilter; 13 | 14 | import javax.annotation.Resource; 15 | import javax.servlet.FilterChain; 16 | import javax.servlet.ServletException; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | import java.io.IOException; 20 | 21 | /** 22 | * JWT令牌授权过滤器 23 | * 1.判断令牌的有效性 24 | * 2.根据令牌为该用户授权可以访问的资源 25 | */ 26 | @Component 27 | public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { 28 | 29 | @Resource 30 | private JwtProperties jwtProperties; 31 | 32 | 33 | @Resource 34 | private JwtTokenUtil jwtTokenUtil; 35 | 36 | 37 | @Resource 38 | private MyUserDetailService myUserDetailService; 39 | 40 | private JwtAuthenticationTokenFilter() { 41 | } 42 | 43 | public JwtAuthenticationTokenFilter(JwtProperties jwtProperties, 44 | JwtTokenUtil jwtTokenUtil, 45 | MyUserDetailService myUserDetailService) { 46 | this.jwtProperties = jwtProperties; 47 | this.jwtTokenUtil = jwtTokenUtil; 48 | this.myUserDetailService = myUserDetailService; 49 | } 50 | 51 | @Override 52 | protected void doFilterInternal(HttpServletRequest request, 53 | HttpServletResponse response, 54 | FilterChain filterChain) 55 | throws ServletException, IOException { 56 | 57 | //1.获取前端传递Tokean 58 | String jwtToken = request.getHeader(jwtProperties.getHeader()); 59 | //2.判断Token是否为空 60 | if (!StringUtils.isEmpty(jwtToken)) { 61 | //3.解析token,获取到用户的username 62 | String username = jwtTokenUtil.getUsernameFromToken(jwtToken); 63 | 64 | if (username != null && 65 | SecurityContextHolder.getContext().getAuthentication() == null) { 66 | //4.根据username查询用户的信息 67 | UserDetails userDetails = myUserDetailService.loadUserByUsername(username); 68 | //5.判断token是否有效 69 | if (jwtTokenUtil.validateToken(jwtToken, userDetails)) { 70 | //6.给使用该JWT令牌的用户进行授权 71 | UsernamePasswordAuthenticationToken authenticationToken 72 | = new UsernamePasswordAuthenticationToken( 73 | userDetails, null, userDetails.getAuthorities()); 74 | SecurityContextHolder.getContext().setAuthentication(authenticationToken); 75 | } 76 | } 77 | } 78 | //如果token为空直接放行 79 | filterChain.doFilter(request, response); 80 | } 81 | } -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.config; 2 | 3 | import com.dingjn.manage.autentication.config.service.MyUserDetailService; 4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.security.authentication.AuthenticationManager; 9 | import org.springframework.security.config.BeanIds; 10 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 14 | import org.springframework.security.crypto.password.PasswordEncoder; 15 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 16 | 17 | import javax.annotation.Resource; 18 | 19 | /** 20 | * @Auther: dingjn 21 | * @Desc: SpringSecurity 配置 22 | */ 23 | @Configuration //配置类,会被Spring扫描 24 | @Order(1) //越小越先执行 25 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 26 | 27 | @Resource 28 | private MyUserDetailService myUserDetailService; 29 | 30 | @Resource 31 | private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; 32 | 33 | /** 34 | * 配置资源访问权限. 35 | */ 36 | @Override 37 | protected void configure(HttpSecurity http) throws Exception { 38 | http.csrf().disable() 39 | .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) 40 | .authorizeRequests() 41 | .antMatchers("/authentication", "/refreshtoken").permitAll(); //不需要认证就能访问的接口 42 | 43 | //全局控制接口Api的访问权限 44 | http.authorizeRequests().anyRequest() 45 | .access("@rabcService.hasPermission(request,authentication)"); 46 | } 47 | 48 | 49 | @Bean 50 | public PasswordEncoder passwordEncoder() { 51 | return new BCryptPasswordEncoder(); 52 | } 53 | 54 | /** 55 | * 配置用户信息数据源以及密码加密器. 56 | */ 57 | @Override 58 | public void configure(AuthenticationManagerBuilder auth) throws Exception { 59 | auth.userDetailsService(myUserDetailService) 60 | .passwordEncoder(passwordEncoder()); 61 | } 62 | 63 | 64 | /** 65 | * 注入AuthenticationManager. 66 | * 因为使用的jwt,所以需要手动调用AuthenticationManager去认证用户信息. 67 | */ 68 | @Override 69 | @Bean(name = BeanIds.AUTHENTICATION_MANAGER) 70 | @ConditionalOnMissingBean(AuthenticationManager.class) 71 | public AuthenticationManager authenticationManagerBean() throws Exception { 72 | return super.authenticationManagerBean(); 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/controller/JwtAuthController.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.controller; 2 | 3 | import com.dingjn.manage.autentication.config.service.JwtAuthService; 4 | import com.dingjn.manage.common.exception.CustomExceptionType; 5 | import com.dingjn.manage.common.response.ServerResponse; 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.Map; 12 | 13 | /** 14 | * @Auther: dingjn 15 | * @Desc: 登录认证Controller 16 | */ 17 | @CrossOrigin 18 | @RestController 19 | public class JwtAuthController { 20 | 21 | @Resource 22 | private JwtAuthService jwtAuthService; 23 | 24 | @PostMapping("/authentication") 25 | public ServerResponse authentication(@RequestBody Map map) { 26 | //获取用户名和密码 27 | String username = map.get("username"); 28 | String password = map.get("password"); 29 | 30 | //校验用户名和密码 31 | if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { 32 | return ServerResponse.error(CustomExceptionType.USER_INPUT_ERROR, 33 | "用户名或密码不能为空"); 34 | } 35 | //登录返回token 36 | return ServerResponse.success(jwtAuthService.login(username, password)); 37 | } 38 | 39 | 40 | /** 41 | * 刷新JWT令牌 42 | */ 43 | @RequestMapping(value = "/refreshtoken") 44 | public ServerResponse refresh(@RequestHeader("JWTHeaderName") String token) { 45 | return ServerResponse.success(jwtAuthService.refreshToken(token)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/mapper/MyUserDetailsServiceMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.mapper; 2 | 3 | import com.dingjn.manage.autentication.config.model.MyUserDetails; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.apache.ibatis.annotations.Select; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @Auther: dingjn 11 | * @Desc: 用户信息Mapper 12 | */ 13 | public interface MyUserDetailsServiceMapper { 14 | 15 | /** 16 | * 根据userID查询用户信息. 17 | */ 18 | @Select("SELECT username,password,enabled\n" + 19 | "FROM sys_user u\n" + 20 | "WHERE u.username = #{userId} or u.phone = #{userId}") 21 | MyUserDetails findByUserName(@Param("userId") String userId); 22 | 23 | /** 24 | * 根据userID查询用户角色列表. 25 | */ 26 | @Select("SELECT role_code\n" + 27 | "FROM sys_role r\n" + 28 | "LEFT JOIN sys_user_role ur ON r.id = ur.role_id\n" + 29 | "LEFT JOIN sys_user u ON u.id = ur.user_id\n" + 30 | "WHERE u.username = #{userId} or u.phone = #{userId}") 31 | List findRoleByUserName(@Param("userId") String userId); 32 | 33 | 34 | /** 35 | * 根据用户角色查询用户菜单权限. 36 | */ 37 | @Select({ 38 | "" 48 | }) 49 | List findMenuByRoleCodes(@Param("roleCodes") List roleCodes); 50 | 51 | 52 | /** 53 | * 根据用户角色查询用户接口访问权限. 54 | */ 55 | @Select({ 56 | "" 66 | }) 67 | List findApiByRoleCodes(@Param("roleCodes") List roleCodes); 68 | 69 | } -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/model/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.model; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @Auther: dingjn 11 | * @Desc: jwt的相关配置 12 | */ 13 | @Data 14 | @Component 15 | @ConfigurationProperties(prefix = "manage.jwt") 16 | public class JwtProperties { 17 | 18 | //JWT密钥 19 | private String secret; 20 | //JWT有效时间 21 | private Long expiration; 22 | //前端向后端传递JWT时使用HTTP的header名称 23 | private String header; 24 | //允许哪些域对本服务的跨域请求 25 | private List corsAllowedOrigins; 26 | //允许哪些HTTP方法跨域 27 | private List corsAllowedMethods; 28 | //是否关闭csrf跨站攻击防御功能 29 | private Boolean csrfDisabled = true; 30 | //是否使用默认的JWTAuthController 31 | private Boolean useDefaultController = true; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/model/MyUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.model; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | 6 | import java.util.Collection; 7 | 8 | 9 | /** 10 | * 用户信息 11 | * 这里的用户信息是包括权限集合等信息的,后面需要进行校验,和数据库的不是一个. 12 | */ 13 | public class MyUserDetails implements UserDetails { 14 | 15 | String password; //密码 16 | String username; //用户名 17 | boolean accountNonExpired; //是否没过期 18 | boolean accountNonLocked; //是否没被锁定 19 | boolean credentialsNonExpired; //是否没过期 20 | boolean enabled; //账号是否可用 21 | Collection authorities; //用户的权限集合 22 | 23 | public Collection getAuthorities() { 24 | return authorities; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public String getUsername() { 32 | return username; 33 | } 34 | 35 | public boolean isAccountNonExpired() { 36 | return true; 37 | } 38 | 39 | public boolean isAccountNonLocked() { 40 | return true; 41 | } 42 | 43 | public boolean isCredentialsNonExpired() { 44 | return true; 45 | } 46 | 47 | public boolean isEnabled() { 48 | return enabled; 49 | } 50 | 51 | public void setPassword(String password) { 52 | this.password = password; 53 | } 54 | 55 | public void setUsername(String username) { 56 | this.username = username; 57 | } 58 | 59 | public void setAccountNonExpired(boolean accountNonExpired) { 60 | this.accountNonExpired = accountNonExpired; 61 | } 62 | 63 | public void setAccountNonLocked(boolean accountNonLocked) { 64 | this.accountNonLocked = accountNonLocked; 65 | } 66 | 67 | public void setCredentialsNonExpired(boolean credentialsNonExpired) { 68 | this.credentialsNonExpired = credentialsNonExpired; 69 | } 70 | 71 | public void setEnabled(boolean enabled) { 72 | this.enabled = enabled; 73 | } 74 | 75 | public void setAuthorities(Collection authorities) { 76 | this.authorities = authorities; 77 | } 78 | } -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/service/JwtAuthService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.service; 2 | 3 | import com.dingjn.manage.autentication.config.util.JwtTokenUtil; 4 | import com.dingjn.manage.common.exception.CustomException; 5 | import com.dingjn.manage.common.exception.CustomExceptionType; 6 | import org.springframework.security.authentication.AuthenticationManager; 7 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.AuthenticationException; 10 | import org.springframework.security.core.context.SecurityContextHolder; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | import org.springframework.stereotype.Service; 13 | 14 | import javax.annotation.Resource; 15 | 16 | /** 17 | * @Auther: dingjn 18 | * @Desc: jwt认证Service 19 | */ 20 | @Service 21 | public class JwtAuthService { 22 | @Resource 23 | private AuthenticationManager authenticationManager; 24 | 25 | @Resource 26 | private MyUserDetailService myUserDetailService; 27 | 28 | @Resource 29 | private JwtTokenUtil jwtTokenUtil; 30 | 31 | /** 32 | * 登录 33 | * @return 返回token,以后请求携带token进行验证. 34 | */ 35 | public String login(String username, String password) { 36 | try { 37 | //1.构建Token凭证 38 | UsernamePasswordAuthenticationToken token = 39 | new UsernamePasswordAuthenticationToken(username, password); 40 | //2.对Token进行认证,返回认证主体 41 | Authentication authentication = authenticationManager.authenticate(token); 42 | //3.将主体加载到上下文中,下次会从上下文获取认证状态,避免重复认证 43 | SecurityContextHolder.getContext().setAuthentication(authentication); 44 | } catch (AuthenticationException e) { 45 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "用户名或密码输入错误"); 46 | } 47 | //4.返回用户信息 48 | UserDetails userDetails = myUserDetailService.loadUserByUsername(username); 49 | //5.生成token 50 | return jwtTokenUtil.generateToken(userDetails, null); 51 | } 52 | 53 | 54 | /** 55 | * 刷新token. 56 | * 成功返回新的token,失败返回null. 57 | * 如果返回的是null,说明前端传过来的token不存在了,前端可以根据这个接口进行做访问是跳转登录页面还是其他. 58 | */ 59 | public String refreshToken(String oldToken){ 60 | if(!jwtTokenUtil.isTokenExpired(oldToken)){ 61 | return jwtTokenUtil.refreshToken(oldToken); 62 | } 63 | return null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/service/MyRBACService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.service; 2 | 3 | import com.dingjn.manage.autentication.config.model.JwtProperties; 4 | import org.springframework.security.core.Authentication; 5 | import org.springframework.security.core.GrantedAuthority; 6 | import org.springframework.security.core.authority.AuthorityUtils; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.util.AntPathMatcher; 10 | 11 | import javax.annotation.Resource; 12 | import javax.servlet.http.HttpServletRequest; 13 | import java.util.List; 14 | 15 | 16 | /** 17 | * @Auther: dingjn 18 | * @Desc: 全局进行权限控制,判断用户访问某个url有没有权限 19 | */ 20 | @Component("rabcService") 21 | public class MyRBACService { 22 | 23 | /** 24 | * 判断某用户是否具有该request资源的访问权限 25 | */ 26 | public boolean hasPermission(HttpServletRequest request, Authentication authentication) { 27 | 28 | //1。获取当前用户信息 29 | Object principal = authentication.getPrincipal(); 30 | 31 | //2.判断当前用户属不属于UserDetails,也就是他有没有认证通过 32 | if (principal instanceof UserDetails) { 33 | //3.获取请求的Url 34 | List authorityList = 35 | AuthorityUtils.commaSeparatedStringToAuthorityList(request.getRequestURI()); 36 | UserDetails userDetails = ((UserDetails) principal); 37 | 38 | //4.userDetails.getAuthorities()获取用户的权限列表,判断是否包含请求的url 39 | return userDetails.getAuthorities().contains(authorityList.get(0)); 40 | } 41 | 42 | return false; 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/service/MyUserDetailService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.service; 2 | 3 | import com.dingjn.manage.autentication.config.mapper.MyUserDetailsServiceMapper; 4 | import com.dingjn.manage.autentication.config.model.MyUserDetails; 5 | import org.springframework.security.core.authority.AuthorityUtils; 6 | import org.springframework.security.core.userdetails.UserDetails; 7 | import org.springframework.security.core.userdetails.UserDetailsService; 8 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.stereotype.Service; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | /** 17 | * @Auther: dingjn 18 | * @Desc: 动态加载用户信息,用户登录后会先访问这个接口拿到用户信息,然后再去认证 19 | */ 20 | @Component 21 | public class MyUserDetailService implements UserDetailsService { 22 | @Resource 23 | private MyUserDetailsServiceMapper myUserDetailsServiceMapper; 24 | 25 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 26 | 27 | //1.加载基础用户信息 28 | MyUserDetails myUserDetails = myUserDetailsServiceMapper.findByUserName(username); 29 | 30 | //2.加载用户角色列表 31 | List roleCodes = myUserDetailsServiceMapper.findRoleByUserName(username); 32 | 33 | if (roleCodes!=null&&roleCodes.size() > 0) { 34 | //3.通过用户角色列表加载用户的资源权限列表 35 | List authorties = myUserDetailsServiceMapper.findApiByRoleCodes(roleCodes); 36 | //4.角色是一个特殊的权限,SpringSecurity规定对于角色需要加上ROLE_前缀 37 | roleCodes = roleCodes.stream() 38 | .map(rc -> "ROLE_" + rc) 39 | .collect(Collectors.toList()); 40 | 41 | authorties.addAll(roleCodes); 42 | 43 | //5.将用户权限列表赋给用户信息 44 | myUserDetails.setAuthorities( 45 | AuthorityUtils.commaSeparatedStringToAuthorityList( 46 | String.join(",", authorties) 47 | ) 48 | ); 49 | } 50 | return myUserDetails; 51 | 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /manage-authentication/src/main/java/com/dingjn/manage/autentication/config/util/JwtTokenUtil.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.autentication.config.util; 2 | 3 | import com.dingjn.manage.autentication.config.model.JwtProperties; 4 | import io.jsonwebtoken.Claims; 5 | import io.jsonwebtoken.Jwts; 6 | import io.jsonwebtoken.SignatureAlgorithm; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.Date; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | /** 15 | * @Auther: dingjn 16 | * @Desc: jwt工具类 17 | */ 18 | @Component 19 | public class JwtTokenUtil { 20 | 21 | private JwtProperties jwtProperties; 22 | 23 | public JwtTokenUtil(JwtProperties jwtProperties) { 24 | this.jwtProperties = jwtProperties; 25 | } 26 | 27 | public JwtProperties getJwtProperties() { 28 | return jwtProperties; 29 | } 30 | 31 | /** 32 | * 生成token令牌 33 | * 34 | * @param userDetails 用户 35 | * @param payloads 令牌中携带的附加信息 36 | * @return 令token牌 37 | */ 38 | public String generateToken(UserDetails userDetails, 39 | Map payloads) { 40 | int payloadSizes = payloads == null ? 0 : payloads.size(); 41 | 42 | Map claims = new HashMap<>(payloadSizes + 2); 43 | claims.put("sub", userDetails.getUsername()); 44 | claims.put("created", new Date()); 45 | 46 | if (payloadSizes > 0) { 47 | for (Map.Entry entry : payloads.entrySet()) { 48 | claims.put(entry.getKey(), entry.getValue()); 49 | } 50 | } 51 | 52 | return generateToken(claims); 53 | } 54 | 55 | /** 56 | * 从令牌中获取用户名 57 | * 58 | * @param token 令牌 59 | * @return 用户名 60 | */ 61 | public String getUsernameFromToken(String token) { 62 | String username; 63 | try { 64 | Claims claims = getClaimsFromToken(token); 65 | username = claims.getSubject(); 66 | } catch (Exception e) { 67 | username = null; 68 | } 69 | return username; 70 | } 71 | 72 | /** 73 | * 判断令牌是否过期 74 | * 75 | * @param token 令牌 76 | * @return 是否过期 77 | */ 78 | public Boolean isTokenExpired(String token) { 79 | try { 80 | Claims claims = getClaimsFromToken(token); 81 | Date expiration = claims.getExpiration(); 82 | return expiration.before(new Date()); 83 | } catch (Exception e) { 84 | return false; 85 | } 86 | } 87 | 88 | /** 89 | * 刷新令牌 90 | * 91 | * @param token 原令牌 92 | * @return 新令牌 93 | */ 94 | public String refreshToken(String token) { 95 | String refreshedToken; 96 | try { 97 | Claims claims = getClaimsFromToken(token); 98 | claims.put("created", new Date()); 99 | refreshedToken = generateToken(claims); 100 | } catch (Exception e) { 101 | refreshedToken = null; 102 | } 103 | return refreshedToken; 104 | } 105 | 106 | /** 107 | * 验证令牌 108 | * 109 | * @param token 令牌 110 | * @param userDetails 用户 111 | * @return 是否有效 112 | */ 113 | public Boolean validateToken(String token, UserDetails userDetails) { 114 | String username = getUsernameFromToken(token); 115 | return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); 116 | } 117 | 118 | 119 | /** 120 | * 从claims生成令牌,如果看不懂就看谁调用它 121 | * 122 | * @param claims 数据声明 123 | * @return 令牌 124 | */ 125 | private String generateToken(Map claims) { 126 | Date expirationDate = new Date(System.currentTimeMillis() + jwtProperties.getExpiration() * 1000); 127 | return Jwts.builder().setClaims(claims) 128 | .setExpiration(expirationDate) 129 | .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) 130 | .compact(); 131 | } 132 | 133 | /** 134 | * 从令牌中获取数据声明,如果看不懂就看谁调用它 135 | * 136 | * @param token 令牌 137 | * @return 数据声明 138 | */ 139 | private Claims getClaimsFromToken(String token) { 140 | Claims claims; 141 | try { 142 | claims = Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token).getBody(); 143 | } catch (Exception e) { 144 | claims = null; 145 | } 146 | return claims; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /manage-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | com.dingjn 7 | vue-manage 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | manage-common 13 | 14 | 15 | 16 | org.projectlombok 17 | lombok 18 | 19 | 20 | 21 | 22 | com.fasterxml.jackson.core 23 | jackson-core 24 | 2.10.4 25 | 26 | 27 | 28 | com.fasterxml.jackson.core 29 | jackson-databind 30 | 2.10.4 31 | 32 | 33 | 34 | com.fasterxml.jackson.core 35 | jackson-annotations 36 | 2.10.4 37 | 38 | 39 | 40 | 41 | org.apache.commons 42 | commons-lang3 43 | 3.10 44 | 45 | 46 | 47 | 48 | org.hibernate.validator 49 | hibernate-validator 50 | 6.0.20.Final 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /manage-common/src/main/java/com/dingjn/manage/common/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.common.exception; 2 | 3 | 4 | /** 5 | * @Auther: dingjn 6 | * @Desc: 自定义异常 7 | */ 8 | public class CustomException extends RuntimeException { 9 | //异常错误编码 10 | private int code ; 11 | //异常信息 12 | private String message; 13 | 14 | private CustomException(){} 15 | 16 | public CustomException(CustomExceptionType exceptionTypeEnum, 17 | String message) { 18 | this.code = exceptionTypeEnum.getCode(); 19 | this.message = message; 20 | } 21 | 22 | public int getCode() { 23 | return code; 24 | } 25 | 26 | @Override 27 | public String getMessage() { 28 | return message; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /manage-common/src/main/java/com/dingjn/manage/common/exception/CustomExceptionType.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.common.exception; 2 | 3 | /** 4 | * @Auther: dingjn 5 | * @Desc: 自定义异常枚举类型 6 | */ 7 | public enum CustomExceptionType { 8 | USER_INPUT_ERROR(400, "用户输入异常"), 9 | SYSTEM_ERROR(500, "系统服务异常"), 10 | OTHER_ERROR(999, "其他未知异常"); 11 | 12 | CustomExceptionType(int code, String typeDesc) { 13 | this.code = code; 14 | this.typeDesc = typeDesc; 15 | } 16 | 17 | private String typeDesc; 18 | 19 | private int code; 20 | 21 | public String getTypeDesc() { 22 | return typeDesc; 23 | } 24 | 25 | public int getCode() { 26 | return code; 27 | } 28 | } -------------------------------------------------------------------------------- /manage-common/src/main/java/com/dingjn/manage/common/response/ResponseCode.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.common.response; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | /** 7 | * @Auther: dingjn 8 | * @Desc: 9 | */ 10 | @Getter 11 | @AllArgsConstructor 12 | enum ResponseCode { 13 | 14 | SUCCESS(200, "success"), 15 | ERROR(0, "error"); 16 | 17 | private int code; 18 | private String msg; 19 | } 20 | -------------------------------------------------------------------------------- /manage-common/src/main/java/com/dingjn/manage/common/response/ServerResponse.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.common.response; 2 | 3 | import com.dingjn.manage.common.exception.CustomExceptionType; 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import com.fasterxml.jackson.annotation.JsonInclude; 6 | import lombok.Data; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @Auther: dingjn 12 | * @Desc: 统一响应类 13 | */ 14 | @Data 15 | @JsonInclude(JsonInclude.Include.NON_NULL) 16 | public class ServerResponse implements Serializable { 17 | 18 | /* 状态码 */ 19 | private int status; 20 | /* 消息 */ 21 | private String message; 22 | /* 实体 */ 23 | private T data; 24 | 25 | public ServerResponse(int status, String message, T data) { 26 | this.status = status; 27 | this.message = message; 28 | this.data = data; 29 | } 30 | 31 | public ServerResponse(int status, String message) { 32 | this.status = status; 33 | this.message = message; 34 | } 35 | 36 | public ServerResponse(String message, T data) { 37 | this.message = message; 38 | this.data = data; 39 | } 40 | 41 | public ServerResponse(int status, T data) { 42 | this.status = status; 43 | this.data = data; 44 | } 45 | 46 | 47 | public static ServerResponse success(T data) { 48 | return new ServerResponse(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMsg(), data); 49 | } 50 | 51 | public static ServerResponse success(String message, T data) { 52 | return new ServerResponse(ResponseCode.SUCCESS.getCode(), message, data); 53 | } 54 | 55 | public static ServerResponse error(int status, String message) { 56 | return new ServerResponse(status, message); 57 | } 58 | 59 | public static ServerResponse error(String message) { 60 | return new ServerResponse(ResponseCode.SUCCESS.getCode(), message); 61 | } 62 | 63 | public static ServerResponse error(CustomExceptionType type, String message) { 64 | return new ServerResponse(type.getCode(), message); 65 | } 66 | 67 | /** 68 | * 是否成功 不返回给前端. 69 | */ 70 | @JsonIgnore 71 | public boolean isSuccess() { 72 | return status == 1; 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /manage-common/src/main/java/com/dingjn/manage/common/util/DataTree.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.common.util; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @Auther: dingjn 7 | * @Desc: 树状数据接口,因为有很多需要返回树状 8 | */ 9 | public interface DataTree { 10 | //元素的Id 11 | Integer getId(); 12 | 13 | //元素的父Id 14 | //父id字段可能叫不同的名字,pid或parentId或org_pid等, 15 | //这里适配一下,统一为使用getParentId,获取父id数据 16 | Integer getParentId(); 17 | 18 | //子节点集合 19 | void setChildren(List children); 20 | 21 | List getChildren(); 22 | } 23 | -------------------------------------------------------------------------------- /manage-common/src/main/java/com/dingjn/manage/common/util/DataTreeUtil.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.common.util; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * @Auther: dingjn 9 | * @Desc: 10 | */ 11 | public class DataTreeUtil { 12 | 13 | public static > List buildTree( 14 | List paramList, Integer rootNodeId) { 15 | List returnList = new ArrayList(); 16 | for (T node : paramList) {//查找根节点 17 | if (node.getId().equals(rootNodeId)) { 18 | returnList.add(node); 19 | } 20 | } 21 | //递归为children赋值 22 | for (T entry : paramList) { 23 | toTreeChildren(returnList, entry); 24 | } 25 | return returnList; 26 | } 27 | 28 | public static > List buildTreeWithoutRoot( 29 | List paramList, Integer rootNodeId) { 30 | List returnList = new ArrayList(); 31 | for (T node : paramList) {//查找根节点 32 | if (node.getParentId().equals(rootNodeId)) { 33 | returnList.add(node); 34 | } 35 | } 36 | //递归为children赋值 37 | for (T entry : paramList) { 38 | toTreeChildren(returnList, entry); 39 | } 40 | return returnList; 41 | } 42 | 43 | private static > void toTreeChildren(List returnList, T entry) { 44 | for (T node : returnList) { //根节点 1 45 | if (entry.getParentId().equals(node.getId())) { //如果parentId等于 1,那就添加到字节点中 46 | if (node.getChildren() == null) { //没有创建 47 | node.setChildren(new ArrayList()); 48 | } 49 | node.getChildren().add(entry); //有就直接添加 childer = 2 50 | } 51 | if (node.getChildren() != null) { //如果不为 null再递归查找2的字节点,因为你都为null了,说明了 52 | toTreeChildren(node.getChildren(), entry); 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /manage-model/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | vue-manage 7 | com.dingjn 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | manage-model 13 | 14 | 15 | 16 | com.dingjn 17 | manage-common 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | com.baomidou 23 | mybatis-plus-boot-starter 24 | 3.2.0 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/dto/SysUserDTO.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * @Auther: dingjn 11 | * @Desc: 查询用户的传输类 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class SysUserDTO { 17 | Integer orgId; 18 | String username; 19 | String phone; 20 | String email; 21 | Boolean enabled; 22 | Date createStartTime; 23 | Date createEndTime; 24 | Integer pageNum; 25 | Integer pageSize; 26 | } 27 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/dto/SysUserRoleDTO.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @Auther: dingjn 11 | * @Desc: 为用户分配角色的传输类 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class SysUserRoleDTO { 17 | private Integer userId; 18 | private List checkedroleIds; 19 | } 20 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysApi.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 系统Http接口表,配合sys_role_api控制接口访问权限 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysApi extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 接口父ID(即接口分组) 26 | */ 27 | private Integer apiPid; 28 | 29 | /** 30 | * 当前接口的所有上级id(即所有上级分组) 31 | */ 32 | private String apiPids; 33 | 34 | /** 35 | * 0:不是叶子节点,1:是叶子节点 36 | */ 37 | private Boolean isLeaf; 38 | 39 | /** 40 | * 接口名称 41 | */ 42 | private String apiName; 43 | 44 | /** 45 | * 跳转URL 46 | */ 47 | private String url; 48 | 49 | /** 50 | * 排序 51 | */ 52 | private Integer sort; 53 | 54 | /** 55 | * 层级,1:接口分组,2:接口 56 | */ 57 | private Integer level; 58 | 59 | /** 60 | * 是否禁用,0:启用(否),1:禁用(是) 61 | */ 62 | private Boolean status; 63 | 64 | public Integer getId() { 65 | return id; 66 | } 67 | 68 | public void setId(Integer id) { 69 | this.id = id; 70 | } 71 | 72 | public Integer getApiPid() { 73 | return apiPid; 74 | } 75 | 76 | public void setApiPid(Integer apiPid) { 77 | this.apiPid = apiPid; 78 | } 79 | 80 | public String getApiPids() { 81 | return apiPids; 82 | } 83 | 84 | public void setApiPids(String apiPids) { 85 | this.apiPids = apiPids; 86 | } 87 | 88 | public Boolean getLeaf() { 89 | return isLeaf; 90 | } 91 | 92 | public void setLeaf(Boolean isLeaf) { 93 | this.isLeaf = isLeaf; 94 | } 95 | 96 | public String getApiName() { 97 | return apiName; 98 | } 99 | 100 | public void setApiName(String apiName) { 101 | this.apiName = apiName; 102 | } 103 | 104 | public String getUrl() { 105 | return url; 106 | } 107 | 108 | public void setUrl(String url) { 109 | this.url = url; 110 | } 111 | 112 | public Integer getSort() { 113 | return sort; 114 | } 115 | 116 | public void setSort(Integer sort) { 117 | this.sort = sort; 118 | } 119 | 120 | public Integer getLevel() { 121 | return level; 122 | } 123 | 124 | public void setLevel(Integer level) { 125 | this.level = level; 126 | } 127 | 128 | public Boolean getStatus() { 129 | return status; 130 | } 131 | 132 | public void setStatus(Boolean status) { 133 | this.status = status; 134 | } 135 | 136 | @Override 137 | protected Serializable pkVal() { 138 | return null; 139 | } 140 | 141 | @Override 142 | public String toString() { 143 | return "SysApi{" + 144 | ", id=" + id + 145 | ", apiPid=" + apiPid + 146 | ", apiPids=" + apiPids + 147 | ", isLeaf=" + isLeaf + 148 | ", apiName=" + apiName + 149 | ", url=" + url + 150 | ", sort=" + sort + 151 | ", level=" + level + 152 | ", status=" + status + 153 | "}"; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysApiNode.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | 4 | import com.dingjn.manage.common.util.DataTree; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 11 | */ 12 | public class SysApiNode extends SysApi implements DataTree { 13 | //为某对象加上children成员变量 14 | private List children; 15 | 16 | @Override 17 | public Integer getParentId() { 18 | return super.getApiPid(); 19 | } 20 | 21 | //set和get方法,为children赋值取值 22 | @Override 23 | public void setChildren(List children) { 24 | this.children = children; 25 | } 26 | 27 | @Override 28 | public List getChildren() { 29 | return this.children; 30 | } 31 | } -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysMenu.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 系统菜单表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysMenu extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 父菜单ID 26 | */ 27 | private Integer menuPid; 28 | 29 | /** 30 | * 当前菜单所有父菜单 31 | */ 32 | private String menuPids; 33 | 34 | /** 35 | * 0:不是叶子节点,1:是叶子节点 36 | */ 37 | private Boolean isLeaf; 38 | 39 | /** 40 | * 菜单名称 41 | */ 42 | private String menuName; 43 | 44 | /** 45 | * 跳转URL 46 | */ 47 | private String url; 48 | 49 | private String icon; 50 | 51 | /** 52 | * 排序 53 | */ 54 | private Integer sort; 55 | 56 | /** 57 | * 菜单层级 58 | */ 59 | private Integer level; 60 | 61 | /** 62 | * 是否禁用,0:启用(否),1:禁用(是) 63 | */ 64 | private Boolean status; 65 | 66 | public Integer getId() { 67 | return id; 68 | } 69 | 70 | public void setId(Integer id) { 71 | this.id = id; 72 | } 73 | 74 | public Integer getMenuPid() { 75 | return menuPid; 76 | } 77 | 78 | public void setMenuPid(Integer menuPid) { 79 | this.menuPid = menuPid; 80 | } 81 | 82 | public String getMenuPids() { 83 | return menuPids; 84 | } 85 | 86 | public void setMenuPids(String menuPids) { 87 | this.menuPids = menuPids; 88 | } 89 | 90 | public Boolean getLeaf() { 91 | return isLeaf; 92 | } 93 | 94 | public void setLeaf(Boolean isLeaf) { 95 | this.isLeaf = isLeaf; 96 | } 97 | 98 | public String getMenuName() { 99 | return menuName; 100 | } 101 | 102 | public void setMenuName(String menuName) { 103 | this.menuName = menuName; 104 | } 105 | 106 | public String getUrl() { 107 | return url; 108 | } 109 | 110 | public void setUrl(String url) { 111 | this.url = url; 112 | } 113 | 114 | public String getIcon() { 115 | return icon; 116 | } 117 | 118 | public void setIcon(String icon) { 119 | this.icon = icon; 120 | } 121 | 122 | public Integer getSort() { 123 | return sort; 124 | } 125 | 126 | public void setSort(Integer sort) { 127 | this.sort = sort; 128 | } 129 | 130 | public Integer getLevel() { 131 | return level; 132 | } 133 | 134 | public void setLevel(Integer level) { 135 | this.level = level; 136 | } 137 | 138 | public Boolean getStatus() { 139 | return status; 140 | } 141 | 142 | public void setStatus(Boolean status) { 143 | this.status = status; 144 | } 145 | 146 | @Override 147 | protected Serializable pkVal() { 148 | return null; 149 | } 150 | 151 | @Override 152 | public String toString() { 153 | return "SysMenu{" + 154 | ", id=" + id + 155 | ", menuPid=" + menuPid + 156 | ", menuPids=" + menuPids + 157 | ", isLeaf=" + isLeaf + 158 | ", menuName=" + menuName + 159 | ", url=" + url + 160 | ", icon=" + icon + 161 | ", sort=" + sort + 162 | ", level=" + level + 163 | ", status=" + status + 164 | "}"; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysMenuNode.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | 4 | import com.dingjn.manage.common.util.DataTree; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 11 | */ 12 | public class SysMenuNode extends SysMenu implements DataTree { 13 | 14 | private List children; 15 | 16 | private String path; //新加入path 17 | private String name; //新加入name 18 | 19 | public String getPath() { 20 | return this.getUrl(); //path返回url 21 | } 22 | public String getName() { 23 | return this.getMenuName(); //name返回menuName 24 | } 25 | 26 | @Override 27 | public Integer getParentId() { 28 | return super.getMenuPid(); 29 | } 30 | @Override 31 | public void setChildren(List children) { 32 | this.children = children; 33 | } 34 | @Override 35 | public List getChildren() { 36 | return this.children; 37 | } 38 | } -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysOrg.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 系统组织结构表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysOrg extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 上级组织编码 26 | */ 27 | private Integer orgPid; 28 | 29 | /** 30 | * 所有的父节点id 31 | */ 32 | private String orgPids; 33 | 34 | /** 35 | * 0:不是叶子节点,1:是叶子节点 36 | */ 37 | private Boolean isLeaf; 38 | 39 | /** 40 | * 组织名 41 | */ 42 | private String orgName; 43 | 44 | /** 45 | * 地址 46 | */ 47 | private String address; 48 | 49 | /** 50 | * 电话 51 | */ 52 | private String phone; 53 | 54 | /** 55 | * 邮件 56 | */ 57 | private String email; 58 | 59 | /** 60 | * 排序 61 | */ 62 | private Integer sort; 63 | 64 | /** 65 | * 组织层级 66 | */ 67 | private Integer level; 68 | 69 | /** 70 | * 是否禁用,0:启用(否),1:禁用(是) 71 | */ 72 | private Boolean status; 73 | 74 | public Integer getId() { 75 | return id; 76 | } 77 | 78 | public void setId(Integer id) { 79 | this.id = id; 80 | } 81 | 82 | public Integer getOrgPid() { 83 | return orgPid; 84 | } 85 | 86 | public void setOrgPid(Integer orgPid) { 87 | this.orgPid = orgPid; 88 | } 89 | 90 | public String getOrgPids() { 91 | return orgPids; 92 | } 93 | 94 | public void setOrgPids(String orgPids) { 95 | this.orgPids = orgPids; 96 | } 97 | 98 | public Boolean getLeaf() { 99 | return isLeaf; 100 | } 101 | 102 | public void setLeaf(Boolean isLeaf) { 103 | this.isLeaf = isLeaf; 104 | } 105 | 106 | public String getOrgName() { 107 | return orgName; 108 | } 109 | 110 | public void setOrgName(String orgName) { 111 | this.orgName = orgName; 112 | } 113 | 114 | public String getAddress() { 115 | return address; 116 | } 117 | 118 | public void setAddress(String address) { 119 | this.address = address; 120 | } 121 | 122 | public String getPhone() { 123 | return phone; 124 | } 125 | 126 | public void setPhone(String phone) { 127 | this.phone = phone; 128 | } 129 | 130 | public String getEmail() { 131 | return email; 132 | } 133 | 134 | public void setEmail(String email) { 135 | this.email = email; 136 | } 137 | 138 | public Integer getSort() { 139 | return sort; 140 | } 141 | 142 | public void setSort(Integer sort) { 143 | this.sort = sort; 144 | } 145 | 146 | public Integer getLevel() { 147 | return level; 148 | } 149 | 150 | public void setLevel(Integer level) { 151 | this.level = level; 152 | } 153 | 154 | public Boolean getStatus() { 155 | return status; 156 | } 157 | 158 | public void setStatus(Boolean status) { 159 | this.status = status; 160 | } 161 | 162 | @Override 163 | protected Serializable pkVal() { 164 | return null; 165 | } 166 | 167 | @Override 168 | public String toString() { 169 | return "SysOrg{" + 170 | ", id=" + id + 171 | ", orgPid=" + orgPid + 172 | ", orgPids=" + orgPids + 173 | ", isLeaf=" + isLeaf + 174 | ", orgName=" + orgName + 175 | ", address=" + address + 176 | ", phone=" + phone + 177 | ", email=" + email + 178 | ", sort=" + sort + 179 | ", level=" + level + 180 | ", status=" + status + 181 | "}"; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysOrgNode.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | 4 | import com.dingjn.manage.common.util.DataTree; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 11 | */ 12 | public class SysOrgNode extends SysOrg implements DataTree { 13 | //为某对象加上children成员变量 14 | private List children; 15 | 16 | @Override 17 | public Integer getParentId() { 18 | //因为不同的人设计model或者数据库, 19 | //父id字段叫不同的名字,pid或parentId或org_pid等, 20 | //这里适配一下,统一为使用getParentId,获取父id数据 21 | return super.getOrgPid(); 22 | } 23 | //set和get方法,为children赋值取值 24 | @Override 25 | public void setChildren(List children) { 26 | this.children = children; 27 | } 28 | 29 | @Override 30 | public List getChildren() { 31 | return this.children; 32 | } 33 | } -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/node/SysUser.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.node; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | *

12 | * 用户信息表 13 | *

14 | * 15 | * @author dingjn 16 | * @since 2020-06-13 17 | */ 18 | public class SysUser extends Model { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @TableId(value = "id", type = IdType.AUTO) 23 | private Integer id; 24 | 25 | /** 26 | * 用户名 27 | */ 28 | private String username; 29 | 30 | /** 31 | * 密码 32 | */ 33 | private String password; 34 | 35 | /** 36 | * 组织id 37 | */ 38 | private Integer orgId; 39 | 40 | /** 41 | * 0无效用户,1是有效用户 42 | */ 43 | private Boolean enabled; 44 | 45 | /** 46 | * 手机号 47 | */ 48 | private String phone; 49 | 50 | /** 51 | * email 52 | */ 53 | private String email; 54 | 55 | /** 56 | * 用户创建时间 57 | */ 58 | private LocalDateTime createTime; 59 | 60 | public Integer getId() { 61 | return id; 62 | } 63 | 64 | public void setId(Integer id) { 65 | this.id = id; 66 | } 67 | 68 | public String getUsername() { 69 | return username; 70 | } 71 | 72 | public void setUsername(String username) { 73 | this.username = username; 74 | } 75 | 76 | public String getPassword() { 77 | return password; 78 | } 79 | 80 | public void setPassword(String password) { 81 | this.password = password; 82 | } 83 | 84 | public Integer getOrgId() { 85 | return orgId; 86 | } 87 | 88 | public void setOrgId(Integer orgId) { 89 | this.orgId = orgId; 90 | } 91 | 92 | public Boolean getEnabled() { 93 | return enabled; 94 | } 95 | 96 | public void setEnabled(Boolean enabled) { 97 | this.enabled = enabled; 98 | } 99 | 100 | public String getPhone() { 101 | return phone; 102 | } 103 | 104 | public void setPhone(String phone) { 105 | this.phone = phone; 106 | } 107 | 108 | public String getEmail() { 109 | return email; 110 | } 111 | 112 | public void setEmail(String email) { 113 | this.email = email; 114 | } 115 | 116 | public LocalDateTime getCreateTime() { 117 | return createTime; 118 | } 119 | 120 | public void setCreateTime(LocalDateTime createTime) { 121 | this.createTime = createTime; 122 | } 123 | 124 | @Override 125 | protected Serializable pkVal() { 126 | return null; 127 | } 128 | 129 | @Override 130 | public String toString() { 131 | return "SysUser{" + 132 | ", id=" + id + 133 | ", username=" + username + 134 | ", password=" + password + 135 | ", orgId=" + orgId + 136 | ", enabled=" + enabled + 137 | ", phone=" + phone + 138 | ", email=" + email + 139 | ", createTime=" + createTime + 140 | "}"; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/vo/PermVO.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @Auther: dingjn 11 | * @Desc: 分配权限Vo类 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class PermVO { 17 | //角色id 18 | private Integer roleId; 19 | //menu或api的ids 20 | private List checkKeys; 21 | } 22 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/vo/SysRoleVO.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | 9 | /** 10 | * @Auther: dingjn 11 | * @Desc: 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class SysRoleVO { 17 | private Integer id; 18 | @NotBlank(message = "角色名称不能为空") 19 | private String roleName; 20 | @NotBlank(message = "角色描述不能为空") 21 | private String roleDesc; 22 | @NotBlank(message = "角色编码不能为空") 23 | private String roleCode; 24 | private Integer sort; 25 | } 26 | -------------------------------------------------------------------------------- /manage-model/src/main/java/com/dingjn/manage/model/vo/SysUserVO.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.model.vo; 2 | 3 | import com.dingjn.manage.model.node.SysUser; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class SysUserVO extends SysUser { 16 | String orgName; 17 | } 18 | -------------------------------------------------------------------------------- /manage-persistence/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | vue-manage 7 | com.dingjn 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | manage-persistence 13 | 14 | 15 | 16 | com.dingjn 17 | manage-model 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | mysql 23 | mysql-connector-java 24 | 25 | 26 | 27 | com.ibeetl 28 | beetl 29 | 2.9.10 30 | 31 | 32 | 33 | com.baomidou 34 | mybatis-plus-generator 35 | 3.2.0 36 | 37 | 38 | 39 | com.alibaba 40 | druid 41 | 42 | 43 | 44 | org.projectlombok 45 | lombok 46 | 47 | 48 | junit 49 | junit 50 | 4.12 51 | test 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysApi.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 系统Http接口表,配合sys_role_api控制接口访问权限 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysApi extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 接口父ID(即接口分组) 26 | */ 27 | private Integer apiPid; 28 | 29 | /** 30 | * 当前接口的所有上级id(即所有上级分组) 31 | */ 32 | private String apiPids; 33 | 34 | /** 35 | * 0:不是叶子节点,1:是叶子节点 36 | */ 37 | private Boolean isLeaf; 38 | 39 | /** 40 | * 接口名称 41 | */ 42 | private String apiName; 43 | 44 | /** 45 | * 跳转URL 46 | */ 47 | private String url; 48 | 49 | /** 50 | * 排序 51 | */ 52 | private Integer sort; 53 | 54 | /** 55 | * 层级,1:接口分组,2:接口 56 | */ 57 | private Integer level; 58 | 59 | /** 60 | * 是否禁用,0:启用(否),1:禁用(是) 61 | */ 62 | private Boolean status; 63 | 64 | public Integer getId() { 65 | return id; 66 | } 67 | 68 | public void setId(Integer id) { 69 | this.id = id; 70 | } 71 | 72 | public Integer getApiPid() { 73 | return apiPid; 74 | } 75 | 76 | public void setApiPid(Integer apiPid) { 77 | this.apiPid = apiPid; 78 | } 79 | 80 | public String getApiPids() { 81 | return apiPids; 82 | } 83 | 84 | public void setApiPids(String apiPids) { 85 | this.apiPids = apiPids; 86 | } 87 | 88 | public Boolean getLeaf() { 89 | return isLeaf; 90 | } 91 | 92 | public void setLeaf(Boolean isLeaf) { 93 | this.isLeaf = isLeaf; 94 | } 95 | 96 | public String getApiName() { 97 | return apiName; 98 | } 99 | 100 | public void setApiName(String apiName) { 101 | this.apiName = apiName; 102 | } 103 | 104 | public String getUrl() { 105 | return url; 106 | } 107 | 108 | public void setUrl(String url) { 109 | this.url = url; 110 | } 111 | 112 | public Integer getSort() { 113 | return sort; 114 | } 115 | 116 | public void setSort(Integer sort) { 117 | this.sort = sort; 118 | } 119 | 120 | public Integer getLevel() { 121 | return level; 122 | } 123 | 124 | public void setLevel(Integer level) { 125 | this.level = level; 126 | } 127 | 128 | public Boolean getStatus() { 129 | return status; 130 | } 131 | 132 | public void setStatus(Boolean status) { 133 | this.status = status; 134 | } 135 | 136 | @Override 137 | protected Serializable pkVal() { 138 | return null; 139 | } 140 | 141 | @Override 142 | public String toString() { 143 | return "SysApi{" + 144 | ", id=" + id + 145 | ", apiPid=" + apiPid + 146 | ", apiPids=" + apiPids + 147 | ", isLeaf=" + isLeaf + 148 | ", apiName=" + apiName + 149 | ", url=" + url + 150 | ", sort=" + sort + 151 | ", level=" + level + 152 | ", status=" + status + 153 | "}"; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysConfig.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | *

12 | * 系统全局配置参数 13 | *

14 | * 15 | * @author dingjn 16 | * @since 2020-06-13 17 | */ 18 | public class SysConfig extends Model { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @TableId(value = "id", type = IdType.AUTO) 23 | private Integer id; 24 | 25 | /** 26 | * 参数名称(中文) 27 | */ 28 | private String paramName; 29 | 30 | /** 31 | * 参数编码唯一标识(英文及数字) 32 | */ 33 | private String paramKey; 34 | 35 | /** 36 | * 参数值 37 | */ 38 | private String paramValue; 39 | 40 | /** 41 | * 参数描述备注 42 | */ 43 | private String paramDesc; 44 | 45 | /** 46 | * 创建时间 47 | */ 48 | private LocalDateTime createTime; 49 | 50 | public Integer getId() { 51 | return id; 52 | } 53 | 54 | public void setId(Integer id) { 55 | this.id = id; 56 | } 57 | 58 | public String getParamName() { 59 | return paramName; 60 | } 61 | 62 | public void setParamName(String paramName) { 63 | this.paramName = paramName; 64 | } 65 | 66 | public String getParamKey() { 67 | return paramKey; 68 | } 69 | 70 | public void setParamKey(String paramKey) { 71 | this.paramKey = paramKey; 72 | } 73 | 74 | public String getParamValue() { 75 | return paramValue; 76 | } 77 | 78 | public void setParamValue(String paramValue) { 79 | this.paramValue = paramValue; 80 | } 81 | 82 | public String getParamDesc() { 83 | return paramDesc; 84 | } 85 | 86 | public void setParamDesc(String paramDesc) { 87 | this.paramDesc = paramDesc; 88 | } 89 | 90 | public LocalDateTime getCreateTime() { 91 | return createTime; 92 | } 93 | 94 | public void setCreateTime(LocalDateTime createTime) { 95 | this.createTime = createTime; 96 | } 97 | 98 | @Override 99 | protected Serializable pkVal() { 100 | return null; 101 | } 102 | 103 | @Override 104 | public String toString() { 105 | return "SysConfig{" + 106 | ", id=" + id + 107 | ", paramName=" + paramName + 108 | ", paramKey=" + paramKey + 109 | ", paramValue=" + paramValue + 110 | ", paramDesc=" + paramDesc + 111 | ", createTime=" + createTime + 112 | "}"; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysDict.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | *

12 | * 数据字典表 13 | *

14 | * 15 | * @author dingjn 16 | * @since 2020-06-13 17 | */ 18 | public class SysDict extends Model { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @TableId(value = "id", type = IdType.AUTO) 23 | private Integer id; 24 | 25 | /** 26 | * 分组名称 27 | */ 28 | private String groupName; 29 | 30 | /** 31 | * 分组编码 32 | */ 33 | private String groupCode; 34 | 35 | /** 36 | * 字典项名称 37 | */ 38 | private String itemName; 39 | 40 | /** 41 | * 字典项Value 42 | */ 43 | private String itemValue; 44 | 45 | /** 46 | * 字典项描述 47 | */ 48 | private String itemDesc; 49 | 50 | /** 51 | * 字典项创建时间 52 | */ 53 | private LocalDateTime createTime; 54 | 55 | public Integer getId() { 56 | return id; 57 | } 58 | 59 | public void setId(Integer id) { 60 | this.id = id; 61 | } 62 | 63 | public String getGroupName() { 64 | return groupName; 65 | } 66 | 67 | public void setGroupName(String groupName) { 68 | this.groupName = groupName; 69 | } 70 | 71 | public String getGroupCode() { 72 | return groupCode; 73 | } 74 | 75 | public void setGroupCode(String groupCode) { 76 | this.groupCode = groupCode; 77 | } 78 | 79 | public String getItemName() { 80 | return itemName; 81 | } 82 | 83 | public void setItemName(String itemName) { 84 | this.itemName = itemName; 85 | } 86 | 87 | public String getItemValue() { 88 | return itemValue; 89 | } 90 | 91 | public void setItemValue(String itemValue) { 92 | this.itemValue = itemValue; 93 | } 94 | 95 | public String getItemDesc() { 96 | return itemDesc; 97 | } 98 | 99 | public void setItemDesc(String itemDesc) { 100 | this.itemDesc = itemDesc; 101 | } 102 | 103 | public LocalDateTime getCreateTime() { 104 | return createTime; 105 | } 106 | 107 | public void setCreateTime(LocalDateTime createTime) { 108 | this.createTime = createTime; 109 | } 110 | 111 | @Override 112 | protected Serializable pkVal() { 113 | return null; 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return "SysDict{" + 119 | ", id=" + id + 120 | ", groupName=" + groupName + 121 | ", groupCode=" + groupCode + 122 | ", itemName=" + itemName + 123 | ", itemValue=" + itemValue + 124 | ", itemDesc=" + itemDesc + 125 | ", createTime=" + createTime + 126 | "}"; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysMenu.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 系统菜单表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysMenu extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 父菜单ID 26 | */ 27 | private Integer menuPid; 28 | 29 | /** 30 | * 当前菜单所有父菜单 31 | */ 32 | private String menuPids; 33 | 34 | /** 35 | * 0:不是叶子节点,1:是叶子节点 36 | */ 37 | private Boolean isLeaf; 38 | 39 | /** 40 | * 菜单名称 41 | */ 42 | private String menuName; 43 | 44 | /** 45 | * 跳转URL 46 | */ 47 | private String url; 48 | 49 | private String icon; 50 | 51 | /** 52 | * 排序 53 | */ 54 | private Integer sort; 55 | 56 | /** 57 | * 菜单层级 58 | */ 59 | private Integer level; 60 | 61 | /** 62 | * 是否禁用,0:启用(否),1:禁用(是) 63 | */ 64 | private Boolean status; 65 | 66 | public Integer getId() { 67 | return id; 68 | } 69 | 70 | public void setId(Integer id) { 71 | this.id = id; 72 | } 73 | 74 | public Integer getMenuPid() { 75 | return menuPid; 76 | } 77 | 78 | public void setMenuPid(Integer menuPid) { 79 | this.menuPid = menuPid; 80 | } 81 | 82 | public String getMenuPids() { 83 | return menuPids; 84 | } 85 | 86 | public void setMenuPids(String menuPids) { 87 | this.menuPids = menuPids; 88 | } 89 | 90 | public Boolean getLeaf() { 91 | return isLeaf; 92 | } 93 | 94 | public void setLeaf(Boolean isLeaf) { 95 | this.isLeaf = isLeaf; 96 | } 97 | 98 | public String getMenuName() { 99 | return menuName; 100 | } 101 | 102 | public void setMenuName(String menuName) { 103 | this.menuName = menuName; 104 | } 105 | 106 | public String getUrl() { 107 | return url; 108 | } 109 | 110 | public void setUrl(String url) { 111 | this.url = url; 112 | } 113 | 114 | public String getIcon() { 115 | return icon; 116 | } 117 | 118 | public void setIcon(String icon) { 119 | this.icon = icon; 120 | } 121 | 122 | public Integer getSort() { 123 | return sort; 124 | } 125 | 126 | public void setSort(Integer sort) { 127 | this.sort = sort; 128 | } 129 | 130 | public Integer getLevel() { 131 | return level; 132 | } 133 | 134 | public void setLevel(Integer level) { 135 | this.level = level; 136 | } 137 | 138 | public Boolean getStatus() { 139 | return status; 140 | } 141 | 142 | public void setStatus(Boolean status) { 143 | this.status = status; 144 | } 145 | 146 | @Override 147 | protected Serializable pkVal() { 148 | return null; 149 | } 150 | 151 | @Override 152 | public String toString() { 153 | return "SysMenu{" + 154 | ", id=" + id + 155 | ", menuPid=" + menuPid + 156 | ", menuPids=" + menuPids + 157 | ", isLeaf=" + isLeaf + 158 | ", menuName=" + menuName + 159 | ", url=" + url + 160 | ", icon=" + icon + 161 | ", sort=" + sort + 162 | ", level=" + level + 163 | ", status=" + status + 164 | "}"; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysOrg.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import javax.validation.constraints.NotBlank; 8 | import java.io.Serializable; 9 | 10 | /** 11 | *

12 | * 系统组织结构表 13 | *

14 | * 15 | * @author dingjn 16 | * @since 2020-06-13 17 | */ 18 | public class SysOrg extends Model { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @TableId(value = "id", type = IdType.AUTO) 23 | private Integer id; 24 | 25 | /** 26 | * 上级组织编码 27 | */ 28 | private Integer orgPid; 29 | 30 | /** 31 | * 所有的父节点id 32 | */ 33 | private String orgPids; 34 | 35 | /** 36 | * 0:不是叶子节点,1:是叶子节点 37 | */ 38 | private Boolean isLeaf; 39 | 40 | /** 41 | * 组织名 42 | */ 43 | @NotBlank(message = "组织名不能为空") 44 | private String orgName; 45 | 46 | /** 47 | * 地址 48 | */ 49 | private String address; 50 | 51 | /** 52 | * 电话 53 | */ 54 | private String phone; 55 | 56 | /** 57 | * 邮件 58 | */ 59 | private String email; 60 | 61 | /** 62 | * 排序 63 | */ 64 | private Integer sort; 65 | 66 | /** 67 | * 组织层级 68 | */ 69 | private Integer level; 70 | 71 | /** 72 | * 是否禁用,0:启用(否),1:禁用(是) 73 | */ 74 | private Boolean status; 75 | 76 | public Integer getId() { 77 | return id; 78 | } 79 | 80 | public void setId(Integer id) { 81 | this.id = id; 82 | } 83 | 84 | public Integer getOrgPid() { 85 | return orgPid; 86 | } 87 | 88 | public void setOrgPid(Integer orgPid) { 89 | this.orgPid = orgPid; 90 | } 91 | 92 | public String getOrgPids() { 93 | return orgPids; 94 | } 95 | 96 | public void setOrgPids(String orgPids) { 97 | this.orgPids = orgPids; 98 | } 99 | 100 | public Boolean getLeaf() { 101 | return isLeaf; 102 | } 103 | 104 | public void setLeaf(Boolean isLeaf) { 105 | this.isLeaf = isLeaf; 106 | } 107 | 108 | public String getOrgName() { 109 | return orgName; 110 | } 111 | 112 | public void setOrgName(String orgName) { 113 | this.orgName = orgName; 114 | } 115 | 116 | public String getAddress() { 117 | return address; 118 | } 119 | 120 | public void setAddress(String address) { 121 | this.address = address; 122 | } 123 | 124 | public String getPhone() { 125 | return phone; 126 | } 127 | 128 | public void setPhone(String phone) { 129 | this.phone = phone; 130 | } 131 | 132 | public String getEmail() { 133 | return email; 134 | } 135 | 136 | public void setEmail(String email) { 137 | this.email = email; 138 | } 139 | 140 | public Integer getSort() { 141 | return sort; 142 | } 143 | 144 | public void setSort(Integer sort) { 145 | this.sort = sort; 146 | } 147 | 148 | public Integer getLevel() { 149 | return level; 150 | } 151 | 152 | public void setLevel(Integer level) { 153 | this.level = level; 154 | } 155 | 156 | public Boolean getStatus() { 157 | return status; 158 | } 159 | 160 | public void setStatus(Boolean status) { 161 | this.status = status; 162 | } 163 | 164 | @Override 165 | protected Serializable pkVal() { 166 | return null; 167 | } 168 | 169 | @Override 170 | public String toString() { 171 | return "SysOrg{" + 172 | ", id=" + id + 173 | ", orgPid=" + orgPid + 174 | ", orgPids=" + orgPids + 175 | ", isLeaf=" + isLeaf + 176 | ", orgName=" + orgName + 177 | ", address=" + address + 178 | ", phone=" + phone + 179 | ", email=" + email + 180 | ", sort=" + sort + 181 | ", level=" + level + 182 | ", status=" + status + 183 | "}"; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 系统角色表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysRole extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 角色名称(汉字) 26 | */ 27 | private String roleName; 28 | 29 | /** 30 | * 角色描述 31 | */ 32 | private String roleDesc; 33 | 34 | /** 35 | * 角色的英文code.如:ADMIN 36 | */ 37 | private String roleCode; 38 | 39 | /** 40 | * 角色顺序 41 | */ 42 | private Integer sort; 43 | 44 | /** 45 | * 是否禁用,0:启用(否),1:禁用(是) 46 | */ 47 | private Boolean status; 48 | 49 | public Integer getId() { 50 | return id; 51 | } 52 | 53 | public void setId(Integer id) { 54 | this.id = id; 55 | } 56 | 57 | public String getRoleName() { 58 | return roleName; 59 | } 60 | 61 | public void setRoleName(String roleName) { 62 | this.roleName = roleName; 63 | } 64 | 65 | public String getRoleDesc() { 66 | return roleDesc; 67 | } 68 | 69 | public void setRoleDesc(String roleDesc) { 70 | this.roleDesc = roleDesc; 71 | } 72 | 73 | public String getRoleCode() { 74 | return roleCode; 75 | } 76 | 77 | public void setRoleCode(String roleCode) { 78 | this.roleCode = roleCode; 79 | } 80 | 81 | public Integer getSort() { 82 | return sort; 83 | } 84 | 85 | public void setSort(Integer sort) { 86 | this.sort = sort; 87 | } 88 | 89 | public Boolean getStatus() { 90 | return status; 91 | } 92 | 93 | public void setStatus(Boolean status) { 94 | this.status = status; 95 | } 96 | 97 | @Override 98 | protected Serializable pkVal() { 99 | return null; 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return "SysRole{" + 105 | ", id=" + id + 106 | ", roleName=" + roleName + 107 | ", roleDesc=" + roleDesc + 108 | ", roleCode=" + roleCode + 109 | ", sort=" + sort + 110 | ", status=" + status + 111 | "}"; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysRoleApi.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 角色接口权限关系表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysRoleApi extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 角色id 26 | */ 27 | private Integer roleId; 28 | 29 | /** 30 | * 接口id 31 | */ 32 | private Integer apiId; 33 | 34 | public Integer getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Integer id) { 39 | this.id = id; 40 | } 41 | 42 | public Integer getRoleId() { 43 | return roleId; 44 | } 45 | 46 | public void setRoleId(Integer roleId) { 47 | this.roleId = roleId; 48 | } 49 | 50 | public Integer getApiId() { 51 | return apiId; 52 | } 53 | 54 | public void setApiId(Integer apiId) { 55 | this.apiId = apiId; 56 | } 57 | 58 | @Override 59 | protected Serializable pkVal() { 60 | return null; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return "SysRoleApi{" + 66 | ", id=" + id + 67 | ", roleId=" + roleId + 68 | ", apiId=" + apiId + 69 | "}"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysRoleMenu.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 角色菜单权限关系表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysRoleMenu extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 角色id 26 | */ 27 | private Integer roleId; 28 | 29 | /** 30 | * 权限id 31 | */ 32 | private Integer menuId; 33 | 34 | public Integer getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Integer id) { 39 | this.id = id; 40 | } 41 | 42 | public Integer getRoleId() { 43 | return roleId; 44 | } 45 | 46 | public void setRoleId(Integer roleId) { 47 | this.roleId = roleId; 48 | } 49 | 50 | public Integer getMenuId() { 51 | return menuId; 52 | } 53 | 54 | public void setMenuId(Integer menuId) { 55 | this.menuId = menuId; 56 | } 57 | 58 | @Override 59 | protected Serializable pkVal() { 60 | return null; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return "SysRoleMenu{" + 66 | ", id=" + id + 67 | ", roleId=" + roleId + 68 | ", menuId=" + menuId + 69 | "}"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysUser.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | *

12 | * 用户信息表 13 | *

14 | * 15 | * @author dingjn 16 | * @since 2020-06-13 17 | */ 18 | public class SysUser extends Model { 19 | 20 | private static final long serialVersionUID = 1L; 21 | 22 | @TableId(value = "id", type = IdType.AUTO) 23 | private Integer id; 24 | 25 | /** 26 | * 用户名 27 | */ 28 | private String username; 29 | 30 | /** 31 | * 密码 32 | */ 33 | private String password; 34 | 35 | /** 36 | * 组织id 37 | */ 38 | private Integer orgId; 39 | 40 | /** 41 | * 0无效用户,1是有效用户 42 | */ 43 | private Boolean enabled; 44 | 45 | /** 46 | * 手机号 47 | */ 48 | private String phone; 49 | 50 | /** 51 | * email 52 | */ 53 | private String email; 54 | 55 | /** 56 | * 用户创建时间 57 | */ 58 | private LocalDateTime createTime; 59 | 60 | public Integer getId() { 61 | return id; 62 | } 63 | 64 | public void setId(Integer id) { 65 | this.id = id; 66 | } 67 | 68 | public String getUsername() { 69 | return username; 70 | } 71 | 72 | public void setUsername(String username) { 73 | this.username = username; 74 | } 75 | 76 | public String getPassword() { 77 | return password; 78 | } 79 | 80 | public void setPassword(String password) { 81 | this.password = password; 82 | } 83 | 84 | public Integer getOrgId() { 85 | return orgId; 86 | } 87 | 88 | public void setOrgId(Integer orgId) { 89 | this.orgId = orgId; 90 | } 91 | 92 | public Boolean getEnabled() { 93 | return enabled; 94 | } 95 | 96 | public void setEnabled(Boolean enabled) { 97 | this.enabled = enabled; 98 | } 99 | 100 | public String getPhone() { 101 | return phone; 102 | } 103 | 104 | public void setPhone(String phone) { 105 | this.phone = phone; 106 | } 107 | 108 | public String getEmail() { 109 | return email; 110 | } 111 | 112 | public void setEmail(String email) { 113 | this.email = email; 114 | } 115 | 116 | public LocalDateTime getCreateTime() { 117 | return createTime; 118 | } 119 | 120 | public void setCreateTime(LocalDateTime createTime) { 121 | this.createTime = createTime; 122 | } 123 | 124 | @Override 125 | protected Serializable pkVal() { 126 | return null; 127 | } 128 | 129 | @Override 130 | public String toString() { 131 | return "SysUser{" + 132 | ", id=" + id + 133 | ", username=" + username + 134 | ", password=" + password + 135 | ", orgId=" + orgId + 136 | ", enabled=" + enabled + 137 | ", phone=" + phone + 138 | ", email=" + email + 139 | ", createTime=" + createTime + 140 | "}"; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/entity/SysUserRole.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.extension.activerecord.Model; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 用户角色关系表 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public class SysUserRole extends Model { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @TableId(value = "id", type = IdType.AUTO) 22 | private Integer id; 23 | 24 | /** 25 | * 角色自增id 26 | */ 27 | private Integer roleId; 28 | 29 | /** 30 | * 用户自增id 31 | */ 32 | private Integer userId; 33 | 34 | public Integer getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Integer id) { 39 | this.id = id; 40 | } 41 | 42 | public Integer getRoleId() { 43 | return roleId; 44 | } 45 | 46 | public void setRoleId(Integer roleId) { 47 | this.roleId = roleId; 48 | } 49 | 50 | public Integer getUserId() { 51 | return userId; 52 | } 53 | 54 | public void setUserId(Integer userId) { 55 | this.userId = userId; 56 | } 57 | 58 | @Override 59 | protected Serializable pkVal() { 60 | return null; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return "SysUserRole{" + 66 | ", id=" + id + 67 | ", roleId=" + roleId + 68 | ", userId=" + userId + 69 | "}"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysApiMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysApi; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 系统Http接口表,配合sys_role_api控制接口访问权限 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysApiMapper extends BaseMapper { 18 | List selectApiTree(@Param("rootApiId") Integer rootApiId, 19 | @Param("apiNameLike") String apiNameLike, 20 | @Param("apiStatus") Boolean apiStatus); 21 | } 22 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysConfigMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysConfig; 5 | 6 | /** 7 | *

8 | * 系统全局配置参数 Mapper 接口 9 | *

10 | * 11 | * @author dingjn 12 | * @since 2020-06-13 13 | */ 14 | public interface SysConfigMapper extends BaseMapper { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysDictMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysDict; 5 | 6 | /** 7 | *

8 | * 数据字典表 Mapper 接口 9 | *

10 | * 11 | * @author dingjn 12 | * @since 2020-06-13 13 | */ 14 | public interface SysDictMapper extends BaseMapper { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysMenu; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 系统菜单表 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysMenuMapper extends BaseMapper { 18 | 19 | List selectMenuTree(@Param("rootMenuId") Integer rootMenuId , 20 | @Param("menuNameLike") String menuNameLike, 21 | @Param("menuStatus") Boolean menuStatus); 22 | 23 | List selectMenuByUsername(@Param("username") String username ); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysOrgMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysOrg; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 系统组织结构表 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysOrgMapper extends BaseMapper { 18 | 19 | List selectOrgTree(@Param("rootOrgId") Integer rootOrgId, 20 | @Param("orgNameLike") String orgNameLike, 21 | @Param("orgStatus") Boolean orgStatus); 22 | } 23 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysRoleApiMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysRoleApi; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 角色接口权限关系表 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysRoleApiMapper extends BaseMapper { 18 | int saveApiPerm(@Param("roleId") Integer roleId, @Param("apiIds") List apiIds); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysRole; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 系统角色表 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysRoleMapper extends BaseMapper { 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysRoleMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysRoleMenu; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 角色菜单权限关系表 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysRoleMenuMapper extends BaseMapper { 18 | 19 | List getCheckKeys(Integer roleId); 20 | 21 | int saveMenuPerm(@Param("roleId") Integer roleId, @Param("menuIds") List menuIds); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.model.dto.SysUserDTO; 5 | import com.dingjn.manage.model.vo.SysUserVO; 6 | import com.dingjn.manage.persistence.entity.SysUser; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 用户信息表 Mapper 接口 13 | *

14 | * 15 | * @author dingjn 16 | * @since 2020-06-13 17 | */ 18 | public interface SysUserMapper extends BaseMapper { 19 | 20 | List getUsers(SysUserDTO sysUserBO); 21 | 22 | List getCheckedRoleIds(Integer userId); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/SysUserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.persistence.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.dingjn.manage.persistence.entity.SysUserRole; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 用户角色关系表 Mapper 接口 12 | *

13 | * 14 | * @author dingjn 15 | * @since 2020-06-13 16 | */ 17 | public interface SysUserRoleMapper extends BaseMapper { 18 | 19 | void saveRoles(@Param("userId") Integer userId, @Param("roleIds") List roleIds); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysApiMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 34 | 35 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysConfigMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysDictMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysMenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 34 | 35 | 36 | 46 | 47 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysOrgMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 35 | 36 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysRoleApiMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | INSERT INTO sys_role_api(role_id,api_id) VALUES 15 | 16 | (#{roleId},#{item}) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysRoleMenuMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | INSERT INTO sys_role_menu(role_id,menu_id) VALUES 22 | 23 | (#{roleId},#{item}) 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 47 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /manage-persistence/src/main/java/com/dingjn/manage/persistence/mapper/xml/SysUserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | INSERT INTO sys_user_role(user_id,role_id) VALUES 14 | 15 | (#{userId},#{item}) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /manage-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | vue-manage 7 | com.dingjn 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | manage-service 13 | 14 | 15 | 16 | com.dingjn 17 | manage-persistence 18 | 1.0-SNAPSHOT 19 | 20 | 21 | 22 | com.dingjn 23 | manage-authentication 24 | 1.0-SNAPSHOT 25 | 26 | 27 | 28 | com.github.pagehelper 29 | pagehelper-spring-boot-starter 30 | 1.2.10 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/SysApiService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service; 2 | 3 | import com.dingjn.manage.model.node.SysApiNode; 4 | import com.dingjn.manage.persistence.entity.SysApi; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 接口管理Service 11 | */ 12 | public interface SysApiService { 13 | 14 | /** 15 | * 获取接口全部信息 树状. 16 | */ 17 | List getApiTree(String apiNameLike, 18 | Boolean orgStatus); 19 | 20 | /** 21 | * 新增/修改菜单. 22 | */ 23 | void saveApi(SysApi sysApi); 24 | 25 | /** 26 | * 删除菜单. 27 | */ 28 | void delApi(Integer id, Integer apiPid); 29 | 30 | 31 | /** 32 | * 获取默认展开的数据 返回id集合. 33 | */ 34 | List getDefauleExpandedKeys(); 35 | 36 | /** 37 | * 获取当前角色默认具有的菜单 返回id集合. 38 | */ 39 | List getDefaultCheckedKeys(Integer roleId); 40 | 41 | 42 | /** 43 | * 保存角色的接口权限. 44 | */ 45 | void saveApiPerm(Integer roleId,List apiIds); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/SysMenuService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service; 2 | 3 | import com.dingjn.manage.model.node.SysMenuNode; 4 | import com.dingjn.manage.persistence.entity.SysMenu; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 菜单管理Service 11 | */ 12 | public interface SysMenuService { 13 | 14 | /** 15 | * 获取菜单全部信息 树状. 16 | */ 17 | List getMenuTree(String orgNameLike, 18 | Boolean orgStatus); 19 | 20 | 21 | /** 22 | * 新增/修改菜单. 23 | */ 24 | void saveMenu(SysMenu sysMenu); 25 | 26 | /** 27 | * 删除菜单. 28 | */ 29 | void delMenu(Integer id, Integer menuPid); 30 | 31 | /** 32 | * 获取默认展开的数据 返回id集合, 33 | */ 34 | List getDefauleExpandedKeys(); 35 | 36 | /** 37 | * 获取当前角色默认具有的菜单 返回id集合. 38 | */ 39 | List getDefaultCheckedKeys(Integer roleId); 40 | 41 | /** 42 | * 保存角色的菜单权限. 43 | */ 44 | void saveMenuPerm(Integer roleId, List menuIds); 45 | 46 | /** 47 | * 根据用户名获取菜单信息 树状. 48 | */ 49 | List getMenuTreeByUsername(String username); 50 | } -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/SysOrgService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service; 2 | 3 | import com.dingjn.manage.model.node.SysOrgNode; 4 | import com.dingjn.manage.persistence.entity.SysOrg; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 组织管理Service 11 | */ 12 | public interface SysOrgService { 13 | 14 | /** 15 | * 获取组织信息 树状. 16 | */ 17 | List getOrgTreeById(Integer rootOrgId, 18 | String orgNameLike, 19 | Boolean orgStatus); 20 | 21 | /** 22 | * 新增/修改组织. 23 | */ 24 | void saveOrg(SysOrg sysOrg); 25 | 26 | /** 27 | * 删除组织. 28 | */ 29 | void delOrg(Integer id, Integer orgPid); 30 | } 31 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/SysRoleService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service; 2 | 3 | import com.dingjn.manage.model.vo.SysRoleVO; 4 | import com.dingjn.manage.persistence.entity.SysRole; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @Auther: dingjn 10 | * @Desc: 角色服务Service 11 | */ 12 | public interface SysRoleService { 13 | 14 | /** 15 | * 获取角色信息. 16 | */ 17 | List getRoles(String roleLike); 18 | 19 | /** 20 | * 删除角色. 21 | */ 22 | void delRole(Integer roleId); 23 | 24 | /** 25 | * 保存角色. 26 | */ 27 | void saveRole(SysRoleVO sysRoleVO); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/SysUserService.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service; 2 | 3 | import com.dingjn.manage.model.dto.SysUserDTO; 4 | import com.dingjn.manage.model.dto.SysUserRoleDTO; 5 | import com.dingjn.manage.model.vo.SysUserVO; 6 | import com.dingjn.manage.persistence.entity.SysUser; 7 | import com.github.pagehelper.PageInfo; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * @Auther: dingjn 13 | * @Desc: 用户管理Service 14 | */ 15 | public interface SysUserService { 16 | 17 | /** 18 | * 根据用户名获取. 19 | */ 20 | SysUser getUserByUserName(String userName); 21 | 22 | /** 23 | * 根据前端传过来的条件获取. 24 | */ 25 | PageInfo getUsers(SysUserDTO sysUserBO); 26 | 27 | /** 28 | * 删除. 29 | */ 30 | void deleteUser(Integer userId); 31 | 32 | /** 33 | * 保存. 34 | */ 35 | void saveUser(SysUser sysuser); 36 | 37 | /** 38 | * 获取当前用户的权限. 39 | */ 40 | Map getCheckedRoles(Integer userId); 41 | 42 | /** 43 | * 保存当前用户的权限. 44 | */ 45 | void saveRoles(SysUserRoleDTO sysUserRoleDTO); 46 | } 47 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/impl/SysApiServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.dingjn.manage.common.exception.CustomException; 5 | import com.dingjn.manage.common.exception.CustomExceptionType; 6 | import com.dingjn.manage.common.util.DataTreeUtil; 7 | import com.dingjn.manage.model.node.SysApiNode; 8 | import com.dingjn.manage.persistence.entity.SysApi; 9 | import com.dingjn.manage.persistence.entity.SysMenu; 10 | import com.dingjn.manage.persistence.entity.SysRoleApi; 11 | import com.dingjn.manage.persistence.entity.SysRoleMenu; 12 | import com.dingjn.manage.persistence.mapper.SysApiMapper; 13 | import com.dingjn.manage.persistence.mapper.SysRoleApiMapper; 14 | import com.dingjn.manage.service.SysApiService; 15 | import org.apache.commons.lang3.StringUtils; 16 | import org.apache.ibatis.annotations.Mapper; 17 | import org.springframework.beans.BeanUtils; 18 | import org.springframework.stereotype.Service; 19 | import org.springframework.transaction.annotation.Transactional; 20 | 21 | import javax.annotation.Resource; 22 | import java.util.List; 23 | import java.util.stream.Collectors; 24 | 25 | /** 26 | * @Auther: dingjn 27 | * @Desc: 接口管理Service实现类 28 | */ 29 | @Service 30 | public class SysApiServiceImpl implements SysApiService { 31 | 32 | @Resource 33 | SysApiMapper sysApiMapper; 34 | 35 | @Resource 36 | SysRoleApiMapper sysRoleApiMapper; 37 | 38 | @Override 39 | public List getApiTree(String apiNameLike, Boolean orgStatus) { 40 | //1.找出根节点 41 | QueryWrapper queryWrapper = new QueryWrapper<>(); 42 | queryWrapper.eq("level", 1); 43 | SysApi sysMenu = sysApiMapper.selectOne(queryWrapper); 44 | 45 | List sysMenuList = sysApiMapper.selectApiTree(sysMenu.getApiPid(), apiNameLike, null); 46 | List sysMenuNodeList = sysMenuList.stream().map(menu -> { 47 | SysApiNode sysMenuNode = new SysApiNode(); 48 | BeanUtils.copyProperties(menu, sysMenuNode); 49 | return sysMenuNode; 50 | }).collect(Collectors.toList()); 51 | 52 | if (!StringUtils.isBlank(apiNameLike)) { 53 | return sysMenuNodeList; 54 | } else { 55 | return DataTreeUtil.buildTree(sysMenuNodeList, sysMenu.getId()); 56 | } 57 | } 58 | 59 | @Transactional 60 | public void saveApi(SysApi sysApi) { 61 | //判断是添加还是修改 62 | if (sysApi.getId() == null) { 63 | sysApi.setStatus(false);//默认不禁用 64 | sysApi.setLeaf(true);//默认是叶子节点 65 | setMenuPidsAndLevel(sysApi); 66 | //添加当前节点 67 | sysApiMapper.insert(sysApi); 68 | setMenuPidsAndLevel(sysApi); 69 | } else { 70 | sysApiMapper.updateById(sysApi); 71 | } 72 | } 73 | 74 | private void setMenuPidsAndLevel(SysApi child) { 75 | SysApi sysApi = sysApiMapper.selectById(child.getApiPid()); 76 | //设置menuPids 77 | child.setApiPids(sysApi.getApiPids() + ",[" + child.getApiPid() + "]"); 78 | //设置Level 79 | child.setLevel(sysApi.getLevel() + 1); 80 | } 81 | 82 | @Override 83 | @Transactional 84 | public void delApi(Integer id, Integer apiPid) { 85 | //查询当前节点是否有子节点 86 | QueryWrapper queryWrapper = new QueryWrapper<>(); 87 | queryWrapper.like("api_pids", "[" + id + "]"); 88 | List sysMenuList = sysApiMapper.selectList(queryWrapper); 89 | if (sysMenuList.size() > 0) { 90 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "不能删除有下级菜单的菜单!"); 91 | } 92 | setParentLeaf(apiPid); 93 | sysApiMapper.deleteById(id); 94 | } 95 | 96 | @Override 97 | public List getDefauleExpandedKeys() { 98 | //默认展开 99 | QueryWrapper queryWrapper = new QueryWrapper<>(); 100 | queryWrapper.eq("level", 2); 101 | List sysMenuList = sysApiMapper.selectList(queryWrapper); 102 | return sysMenuList.stream().map(SysApi -> SysApi.getId()).collect(Collectors.toList()); 103 | } 104 | 105 | @Override 106 | public List getDefaultCheckedKeys(Integer roleId) { 107 | QueryWrapper queryWrapper = new QueryWrapper<>(); 108 | queryWrapper.eq("role_id", roleId); 109 | List sysRoleApiList = sysRoleApiMapper.selectList(queryWrapper); 110 | return sysRoleApiList.stream().map(SysRoleApi::getApiId).collect(Collectors.toList()); 111 | } 112 | 113 | //设置它的父节点为叶子节点 114 | private void setParentLeaf(Integer menuPid) { 115 | //查询父节点有几个节点 116 | QueryWrapper queryWrapper = new QueryWrapper<>(); 117 | queryWrapper.like("api_pids", "[" + menuPid + "]"); 118 | List sysMenuList = sysApiMapper.selectList(queryWrapper); 119 | //如果只有它一下才设置 120 | if (sysMenuList.size() == 1) { 121 | SysApi parent = new SysApi(); 122 | parent.setId(menuPid); 123 | parent.setLeaf(true); 124 | sysApiMapper.updateById(parent); 125 | } 126 | } 127 | 128 | @Override 129 | @Transactional 130 | public void saveApiPerm(Integer roleId, List menuIds) { 131 | //在添加之前需要先讲之前的权限删掉 132 | QueryWrapper queryWrapper = new QueryWrapper<>(); 133 | queryWrapper.eq("role_id", roleId); 134 | sysRoleApiMapper.delete(queryWrapper); 135 | //添加 136 | sysRoleApiMapper.saveApiPerm(roleId, menuIds); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/impl/SysOrgServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.dingjn.manage.common.exception.CustomException; 5 | import com.dingjn.manage.common.exception.CustomExceptionType; 6 | import com.dingjn.manage.common.util.DataTreeUtil; 7 | import com.dingjn.manage.model.node.SysOrgNode; 8 | import com.dingjn.manage.persistence.entity.SysOrg; 9 | import com.dingjn.manage.persistence.mapper.SysOrgMapper; 10 | import com.dingjn.manage.service.SysOrgService; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.transaction.annotation.Transactional; 15 | 16 | import javax.annotation.Resource; 17 | import java.util.List; 18 | import java.util.stream.Collectors; 19 | 20 | /** 21 | * @Auther: dingjn 22 | * @Desc: 组织管理Service实现类 23 | */ 24 | @Service 25 | public class SysOrgServiceImpl implements SysOrgService { 26 | @Resource 27 | private SysOrgMapper sysOrgMapper; 28 | 29 | //查询组织信息 返回树状结构 30 | public List getOrgTreeById(Integer rootOrgId, 31 | String orgNameLike, 32 | Boolean orgStatus) { 33 | if (rootOrgId != null) { 34 | List sysOrgs 35 | = sysOrgMapper.selectOrgTree(rootOrgId, orgNameLike, orgStatus); 36 | 37 | List sysOrgNodes = sysOrgs.stream().map(item -> { 38 | SysOrgNode bean = new SysOrgNode(); 39 | BeanUtils.copyProperties(item, bean); 40 | return bean; 41 | }).collect(Collectors.toList()); 42 | 43 | 44 | if (StringUtils.isNotEmpty(orgNameLike) || orgStatus != null) { 45 | return sysOrgNodes;//根据条件查询,会破坏树形结构,所以返回平面列表 46 | } else {//否则返回树型结构列表 47 | return DataTreeUtil.buildTree(sysOrgNodes, rootOrgId); 48 | } 49 | 50 | } else { 51 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, 52 | "查询参数用户名组织id不能为空"); 53 | } 54 | } 55 | 56 | @Override 57 | @Transactional 58 | public void saveOrg(SysOrg sysOrg) { 59 | if (sysOrg.getId() == null) { 60 | //1.添加节点 61 | setOrgPidsAndLevel(sysOrg); 62 | sysOrg.setStatus(false);//默认不禁用 63 | sysOrg.setLeaf(true);//新增的节点都是叶子节点 64 | sysOrgMapper.insert(sysOrg); 65 | //2.更新父节点为非叶子节点 66 | SysOrg parent = new SysOrg(); 67 | parent.setId(sysOrg.getOrgPid()); 68 | parent.setLeaf(false); 69 | sysOrgMapper.updateById(parent); 70 | } else { 71 | //修改节点 72 | sysOrgMapper.updateById(sysOrg); 73 | } 74 | 75 | } 76 | 77 | //为新增的节点设置org_pids和level 78 | private void setOrgPidsAndLevel(SysOrg child) { 79 | //1.找出新增节点的直接父节点 80 | SysOrg sysOrg = sysOrgMapper.selectById(child.getOrgPid()); 81 | 82 | //2.直接父节点的所有父节点id+直接父节点的id=新增节点的所有父id 83 | //因为数据库中的org_pids格式为 [1],[2],[3] 84 | child.setOrgPids(sysOrg.getOrgPids() + ",[" + child.getOrgPid() + "]"); 85 | //4.设置新增节点的level 为父节点的level+1 86 | child.setLevel(sysOrg.getLevel() + 1); 87 | } 88 | 89 | @Override 90 | @Transactional 91 | public void delOrg(Integer id, Integer orgPid) { 92 | //查询当前节点下的子节点,如果有子节点不能删除,否则会破坏掉树形结构,导致它的子节点没有根源 93 | QueryWrapper queryWrapper = new QueryWrapper<>(); 94 | queryWrapper.like("org_pids", "[" + id + "]"); 95 | List childSysOrgList = sysOrgMapper.selectList(queryWrapper); 96 | if (childSysOrgList.size() > 0) { 97 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "不能删除有下级组织的组织机构"); 98 | } 99 | setParentLeaf(orgPid); 100 | sysOrgMapper.deleteById(id); 101 | 102 | } 103 | 104 | //如果当前节点的上级组织只有它一个节点,那么当前节点被删除以后,上级组织应该变为叶子节点 105 | private void setParentLeaf(Integer orgPid) { 106 | //找出当前父节点有几个子节点 107 | QueryWrapper queryWrapper = new QueryWrapper<>(); 108 | queryWrapper.like("org_pids", "[" + orgPid + "]"); 109 | List childSysOrgList = sysOrgMapper.selectList(queryWrapper); 110 | if (childSysOrgList.size() == 1) { 111 | //设置Leaf为true 112 | SysOrg parent = new SysOrg(); 113 | parent.setId(orgPid); 114 | parent.setLeaf(true); 115 | sysOrgMapper.updateById(parent); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/impl/SysRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.dingjn.manage.model.vo.SysRoleVO; 5 | import com.dingjn.manage.persistence.entity.SysRole; 6 | import com.dingjn.manage.persistence.mapper.SysRoleMapper; 7 | import com.dingjn.manage.service.SysRoleService; 8 | import org.springframework.beans.BeanUtils; 9 | import org.springframework.stereotype.Service; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | 14 | /** 15 | * @Auther: dingjn 16 | * @Desc: 权限管理Service实现类 17 | */ 18 | @Service 19 | public class SysRoleServiceImpl implements SysRoleService { 20 | 21 | @Resource 22 | SysRoleMapper sysRoleMapper; 23 | 24 | @Override 25 | public List getRoles(String roleLike) { 26 | QueryWrapper queryWrapper = new QueryWrapper<>(); 27 | queryWrapper.like("role_name", roleLike). 28 | or().like("role_code", roleLike). 29 | or().like("role_desc", roleLike); 30 | queryWrapper.orderByAsc("sort"); 31 | return sysRoleMapper.selectList(queryWrapper); 32 | } 33 | 34 | public void saveRole(SysRoleVO sysRoleVO) { 35 | SysRole sysRole = new SysRole(); 36 | BeanUtils.copyProperties(sysRoleVO, sysRole); 37 | if (sysRole.getId() == null) { 38 | sysRoleMapper.insert(sysRole); 39 | } else { 40 | sysRoleMapper.updateById(sysRole); 41 | } 42 | } 43 | 44 | @Override 45 | public void delRole(Integer roleId) { 46 | sysRoleMapper.deleteById(roleId); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /manage-service/src/main/java/com/dingjn/manage/service/impl/SysUserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | 5 | import com.dingjn.manage.model.dto.SysUserDTO; 6 | import com.dingjn.manage.model.dto.SysUserRoleDTO; 7 | import com.dingjn.manage.model.vo.SysUserVO; 8 | import com.dingjn.manage.persistence.entity.SysRole; 9 | import com.dingjn.manage.persistence.entity.SysUser; 10 | import com.dingjn.manage.persistence.entity.SysUserRole; 11 | import com.dingjn.manage.persistence.mapper.SysRoleMapper; 12 | import com.dingjn.manage.persistence.mapper.SysUserMapper; 13 | import com.dingjn.manage.persistence.mapper.SysUserRoleMapper; 14 | import com.dingjn.manage.service.SysUserService; 15 | import com.github.pagehelper.PageHelper; 16 | import com.github.pagehelper.PageInfo; 17 | import org.springframework.security.crypto.password.PasswordEncoder; 18 | import org.springframework.stereotype.Service; 19 | import org.springframework.transaction.annotation.Transactional; 20 | 21 | import javax.annotation.Resource; 22 | import java.time.LocalDateTime; 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | /** 28 | * @Auther: dingjn 29 | * @Desc: 用户管理Service实现类 30 | */ 31 | @Service 32 | public class SysUserServiceImpl implements SysUserService { 33 | 34 | @Resource 35 | SysUserMapper sysUserMapper; 36 | 37 | @Resource 38 | SysRoleMapper sysRoleMapper; 39 | 40 | @Resource 41 | SysUserRoleMapper sysUserRoleMapper; 42 | 43 | /** 44 | * 密码加密处理. 45 | */ 46 | @Resource 47 | private PasswordEncoder passwordEncoder; 48 | 49 | 50 | 51 | @Override 52 | public SysUser getUserByUserName(String userName) { 53 | QueryWrapper queryWrapper = new QueryWrapper<>(); 54 | queryWrapper.eq("username", userName); 55 | return sysUserMapper.selectOne(queryWrapper); 56 | } 57 | 58 | @Override 59 | public PageInfo getUsers(SysUserDTO sysUserBO) { 60 | PageHelper.startPage(sysUserBO.getPageNum(), sysUserBO.getPageSize()); 61 | List userVOList = sysUserMapper.getUsers(sysUserBO); 62 | return PageInfo.of(userVOList); 63 | } 64 | 65 | @Override 66 | public void saveUser(SysUser sysuser) { 67 | if (sysuser.getId() == null) { 68 | //TODO 初始密码优化为通用配置 69 | sysuser.setPassword(passwordEncoder.encode("123456")); 70 | sysuser.setCreateTime(LocalDateTime.now()); //创建时间 71 | sysuser.setEnabled(true); //新增用户激活 72 | sysUserMapper.insert(sysuser); 73 | } else { 74 | sysUserMapper.updateById(sysuser); 75 | } 76 | 77 | } 78 | 79 | @Override 80 | public Map getCheckedRoles(Integer userId) { 81 | HashMap resultMap = new HashMap<>(); 82 | //1.全部的角色 83 | List roleDatas = sysRoleMapper.selectList(null); 84 | //2.当前用户具有的角色 85 | List checkedRoleIds = sysUserMapper.getCheckedRoleIds(userId); 86 | resultMap.put("roleDatas", roleDatas); 87 | resultMap.put("checkedRoleIds", checkedRoleIds); 88 | return resultMap; 89 | } 90 | 91 | @Override 92 | public void deleteUser(Integer userId) { 93 | sysUserMapper.deleteById(userId); 94 | } 95 | 96 | @Override 97 | @Transactional 98 | public void saveRoles(SysUserRoleDTO sysUserRoleDTO) { 99 | //保存角色信息之前先删除之前的信息 100 | QueryWrapper queryWrapper = new QueryWrapper<>(); 101 | queryWrapper.eq("user_id", sysUserRoleDTO.getUserId()); 102 | sysUserRoleMapper.delete(queryWrapper); 103 | sysUserRoleMapper.saveRoles(sysUserRoleDTO.getUserId(), sysUserRoleDTO.getCheckedroleIds()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /manage-web/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /manage-web/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.dingjn 7 | vue-manage 8 | 1.0-SNAPSHOT 9 | 10 | 11 | com.dingjn 12 | manage-web 13 | 0.0.1-SNAPSHOT 14 | web核心模块 15 | jar 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | com.dingjn 24 | manage-service 25 | 1.0-SNAPSHOT 26 | 27 | 28 | 29 | org.mybatis.spring.boot 30 | mybatis-spring-boot-starter 31 | 2.1.2 32 | 33 | 34 | 35 | com.dingjn 36 | manage-common 37 | 1.0-SNAPSHOT 38 | 39 | 40 | 41 | com.dingjn 42 | manage-persistence 43 | 1.0-SNAPSHOT 44 | 45 | 46 | 47 | com.dingjn 48 | manage-authentication 49 | 1.0-SNAPSHOT 50 | 51 | 52 | 53 | mysql 54 | mysql-connector-java 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-starter-web 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-starter-security 67 | 68 | 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-starter-test 74 | test 75 | 76 | 77 | org.junit.vintage 78 | junit-vintage-engine 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | org.springframework.boot 90 | spring-boot-maven-plugin 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/ManageWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.context.annotation.ComponentScan; 7 | 8 | /** 9 | * 项目启动类. 10 | */ 11 | @ComponentScan(basePackages = "com.dingjn") //扫描指定包,因为是多moudle开发,所以需要指定才能扫描其他moudle 12 | @MapperScan(basePackages = {"com.dingjn.**.mapper"}) //扫描Mapper **代表中间不管隔多少包 13 | @SpringBootApplication 14 | public class ManageWebApplication { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(ManageWebApplication.class, args); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.config; 2 | 3 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.Ordered; 7 | import org.springframework.web.cors.CorsConfiguration; 8 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 9 | import org.springframework.web.filter.CorsFilter; 10 | 11 | /** 12 | * @Auther: dingjn 13 | * @Desc: 跨域配置 14 | */ 15 | @Configuration 16 | public class CorsConfig { 17 | @Bean 18 | public FilterRegistrationBean corsFilter() { 19 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 20 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 21 | corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用 22 | corsConfiguration.addAllowedHeader("*"); // 2允许任何头 23 | corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等) 24 | corsConfiguration.setAllowCredentials(true);// 4使用相同的sessionid 25 | source.registerCorsConfiguration("/**", corsConfiguration); 26 | FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new CorsFilter(source)); 27 | // 代表这个过滤器在众多过滤器中级别最高,也就是过滤的时候最先执行! 28 | //这个很重要,否则对于鉴权问题也会抛出跨域问题 29 | filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); 30 | return filterRegistrationBean; 31 | } 32 | } -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/config/GlobalExcepitonHandler.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.config; 2 | 3 | import com.dingjn.manage.common.exception.CustomException; 4 | import com.dingjn.manage.common.exception.CustomExceptionType; 5 | import com.dingjn.manage.common.response.ServerResponse; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.bind.MethodArgumentNotValidException; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | /** 11 | * @Auther: dingjn 12 | * @Desc: 全局异常处理 13 | */ 14 | @Slf4j 15 | @RestControllerAdvice 16 | public class GlobalExcepitonHandler { 17 | 18 | /** 19 | * 自定义异常. 20 | */ 21 | @ExceptionHandler(CustomException.class) 22 | public ServerResponse handle(CustomException e) { 23 | return ServerResponse.error(e.getCode(), e.getMessage()); 24 | } 25 | 26 | /** 27 | * 参数校验异常 BindingResult. 28 | */ 29 | @ExceptionHandler(MethodArgumentNotValidException.class) 30 | public ServerResponse methodArgumentNotValidException(MethodArgumentNotValidException e) { 31 | log.error("参数校验异常,提示信息:{},具体错误信息:{}", e.getBindingResult().getFieldErrors().get(0).getDefaultMessage(), e.getMessage()); 32 | return ServerResponse.error(CustomExceptionType.USER_INPUT_ERROR.getCode(), e.getBindingResult().getFieldErrors().get(0).getDefaultMessage()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/config/GlobalRequestAdvice.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.config; 2 | 3 | import org.springframework.beans.propertyeditors.CustomDateEditor; 4 | import org.springframework.web.bind.WebDataBinder; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.InitBinder; 7 | 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | /** 12 | * @Auther: dingjn 13 | * @Desc: 对日期空字符串全局处理 14 | */ 15 | @ControllerAdvice 16 | public class GlobalRequestAdvice { 17 | 18 | @InitBinder 19 | protected void initBinder(WebDataBinder binder) { 20 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 21 | binder.registerCustomEditor(Date.class, 22 | //true表示转换为日期的字符串可以为空,不设置这个值接收空串会报错 23 | new CustomDateEditor(dateFormat, true) 24 | ); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.config; 2 | 3 | 4 | import com.alibaba.druid.pool.DruidDataSource; 5 | import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; 6 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 7 | import org.mybatis.spring.annotation.MapperScan; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.transaction.annotation.EnableTransactionManagement; 11 | 12 | @Configuration //表示是一个配置组件 13 | @EnableTransactionManagement 14 | @MapperScan(basePackages = {"com.dingjn.manage.**.dao.mapper"}) //扫描该包下的Mapper类 15 | public class MybatisPlusConfig { 16 | /** 17 | * mybatis-plus分页插件 18 | */ 19 | @Bean 20 | public PaginationInterceptor paginationInterceptor() { 21 | return new PaginationInterceptor(); 22 | } 23 | 24 | /** 25 | * 乐观锁mybatis插件 26 | */ 27 | @Bean 28 | public OptimisticLockerInterceptor optimisticLockerInterceptor() { 29 | return new OptimisticLockerInterceptor(); 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/controller/SysApiController.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.controller; 2 | 3 | import com.dingjn.manage.common.exception.CustomException; 4 | import com.dingjn.manage.common.exception.CustomExceptionType; 5 | import com.dingjn.manage.common.response.ServerResponse; 6 | import com.dingjn.manage.model.vo.PermVO; 7 | import com.dingjn.manage.persistence.entity.SysApi; 8 | import com.dingjn.manage.service.SysApiService; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.annotation.Resource; 12 | import javax.validation.Valid; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @Auther: dingjn 18 | * @Desc: 接口管理Api 19 | */ 20 | @RestController 21 | @RequestMapping("/sysapi") 22 | public class SysApiController { 23 | 24 | @Resource 25 | private SysApiService sysApiService; 26 | 27 | @PostMapping(value = "/tree") 28 | public ServerResponse tree(@RequestParam("apiNameLike") String apiNameLike) { 29 | return ServerResponse.success(sysApiService.getApiTree(apiNameLike, null)); 30 | } 31 | 32 | 33 | @PostMapping(value = "/add") 34 | public ServerResponse saveOrg(@Valid @RequestBody SysApi sysApi) { 35 | sysApiService.saveApi(sysApi); 36 | return ServerResponse.success("保存接口信息成功!"); 37 | } 38 | 39 | 40 | @PostMapping(value = "/delete") 41 | public ServerResponse delOrg(@RequestParam("id") Integer id, 42 | @RequestParam("apiPid") Integer apiPid) { 43 | if (id == null || apiPid == null) { 44 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "参数id和apiPid不能为空"); 45 | } 46 | sysApiService.delApi(id, apiPid); 47 | return ServerResponse.success("删除接口信息成功!"); 48 | } 49 | 50 | @PostMapping(value = "/checkedtree") 51 | public ServerResponse checkTree(@RequestParam("roleId") Integer roleId) { 52 | Map resultMap = new HashMap<>(); 53 | // 1.获取全部的菜单树状数据 54 | resultMap.put("treeData", sysApiService.getApiTree(null, null)); 55 | // 2.获取默认展开的数据 id 56 | resultMap.put("expandedKeys", sysApiService.getDefauleExpandedKeys()); 57 | // 3.获取默认勾选的数据,也就是当前角色具有的菜单数据 58 | resultMap.put("checkedKeys", sysApiService.getDefaultCheckedKeys(roleId)); 59 | return ServerResponse.success(resultMap); 60 | } 61 | 62 | /** 63 | * 保存菜单权限. 64 | */ 65 | @PostMapping(value = "/savekeys") 66 | public ServerResponse saveMenuPerm(@RequestBody PermVO permVO) { 67 | sysApiService.saveApiPerm(permVO.getRoleId(), permVO.getCheckKeys()); 68 | return ServerResponse.success("保存菜单权限成功!"); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/controller/SysMenuController.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.controller; 2 | 3 | import com.dingjn.manage.common.exception.CustomException; 4 | import com.dingjn.manage.common.exception.CustomExceptionType; 5 | import com.dingjn.manage.common.response.ServerResponse; 6 | import com.dingjn.manage.model.node.SysMenuNode; 7 | import com.dingjn.manage.model.vo.PermVO; 8 | import com.dingjn.manage.persistence.entity.SysMenu; 9 | import com.dingjn.manage.service.SysMenuService; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.annotation.Resource; 13 | import javax.validation.Valid; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | /** 19 | * @Auther: dingjn 20 | * @Desc: 21 | */ 22 | @RestController 23 | @RequestMapping("/sysmenu") 24 | public class SysMenuController { 25 | 26 | @Resource 27 | private SysMenuService sysMenuService; 28 | 29 | @PostMapping(value = "/tree") 30 | public ServerResponse tree(@RequestParam("menuNameLike") String menuNameLike) { 31 | return ServerResponse.success(sysMenuService.getMenuTree(menuNameLike, null)); 32 | } 33 | 34 | 35 | @PostMapping(value = "/add") 36 | public ServerResponse saveOrg(@Valid @RequestBody SysMenu sysMenu) { 37 | sysMenuService.saveMenu(sysMenu); 38 | return ServerResponse.success("保存菜单信息成功!"); 39 | } 40 | 41 | 42 | @PostMapping(value = "/delete") 43 | public ServerResponse delOrg(@RequestParam("id") Integer id, 44 | @RequestParam("menuPid") Integer menuPid) { 45 | if (id == null || menuPid == null) { 46 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "参数id和menuPid不能为空"); 47 | } 48 | sysMenuService.delMenu(id, menuPid); 49 | return ServerResponse.success("删除菜单信息成功!"); 50 | } 51 | 52 | @PostMapping(value = "/checkedtree") 53 | public ServerResponse checkTree(@RequestParam("roleId") Integer roleId) { 54 | Map resultMap = new HashMap<>(); 55 | // 1.获取全部的菜单树状数据 56 | resultMap.put("treeData", sysMenuService.getMenuTree(null, null)); 57 | // 2.获取默认展开的数据 id 58 | resultMap.put("expandedKeys", sysMenuService.getDefauleExpandedKeys()); 59 | // 3.获取默认勾选的数据,也就是当前角色具有的菜单数据 60 | resultMap.put("checkedKeys", sysMenuService.getDefaultCheckedKeys(roleId)); 61 | return ServerResponse.success(resultMap); 62 | } 63 | 64 | /** 65 | * 保存菜单权限. 66 | */ 67 | @PostMapping(value = "/savekeys") 68 | public ServerResponse saveMenuPerm(@RequestBody PermVO permMenuVO) { 69 | sysMenuService.saveMenuPerm(permMenuVO.getRoleId(), permMenuVO.getCheckKeys()); 70 | return ServerResponse.success("保存菜单权限成功!"); 71 | } 72 | 73 | 74 | @PostMapping(value = "/tree/user") 75 | public ServerResponse usertree(@RequestParam("username") String username) { 76 | return ServerResponse.success(sysMenuService.getMenuTreeByUsername(username)); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/controller/SysOrgController.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.controller; 2 | 3 | import com.dingjn.manage.common.exception.CustomException; 4 | import com.dingjn.manage.common.exception.CustomExceptionType; 5 | import com.dingjn.manage.common.response.ServerResponse; 6 | import com.dingjn.manage.persistence.entity.SysOrg; 7 | import com.dingjn.manage.persistence.entity.SysUser; 8 | import com.dingjn.manage.service.SysOrgService; 9 | import com.dingjn.manage.service.SysUserService; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.annotation.Resource; 13 | import javax.validation.Valid; 14 | 15 | /** 16 | * @Auther: dingjn 17 | * @Desc: 组织管理Api 18 | */ 19 | @RestController 20 | @RequestMapping("/sysorg") 21 | public class SysOrgController { 22 | 23 | @Resource 24 | private SysOrgService sysOrgService; 25 | 26 | @Resource 27 | private SysUserService sysUserService; 28 | 29 | @PostMapping(value = "/tree") 30 | public ServerResponse tree(@RequestParam("username") String username, 31 | @RequestParam("orgNameLike") String orgNameLike) { 32 | //当前只能查看自己的部门和子节点的部门 33 | SysUser sysUser = sysUserService.getUserByUserName(username); 34 | return ServerResponse.success(sysOrgService.getOrgTreeById(sysUser.getOrgId(), orgNameLike, null)); 35 | 36 | } 37 | 38 | @PostMapping(value = "/add") 39 | public ServerResponse saveOrg(@Valid @RequestBody SysOrg sysOrg) { 40 | sysOrgService.saveOrg(sysOrg); 41 | return ServerResponse.success("保存组织机构成功!"); 42 | } 43 | 44 | 45 | @PostMapping(value = "/delete") 46 | public ServerResponse delOrg(@RequestParam("id") Integer id, 47 | @RequestParam("orgPid") Integer orgPid) { 48 | if (id == null || orgPid == null) { 49 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR, "参数id和orgPid不能为空"); 50 | } 51 | sysOrgService.delOrg(id, orgPid); 52 | return ServerResponse.success("删除组织机构成功!"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/controller/SysRoleController.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.controller; 2 | 3 | import com.dingjn.manage.common.response.ServerResponse; 4 | import com.dingjn.manage.model.vo.SysRoleVO; 5 | import com.dingjn.manage.persistence.entity.SysRole; 6 | import com.dingjn.manage.service.SysRoleService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @Auther: dingjn 14 | * @Desc: 角色管理Api 15 | */ 16 | @RestController 17 | @RequestMapping("/sysrole") 18 | public class SysRoleController { 19 | 20 | @Autowired 21 | SysRoleService sysRoleService; 22 | 23 | @GetMapping("/query") 24 | public ServerResponse getRoles(@RequestParam("roleLike") String roleLike) { 25 | List sysRoleList = sysRoleService.getRoles(roleLike); 26 | return ServerResponse.success(sysRoleList); 27 | } 28 | 29 | @PostMapping("/add") 30 | public ServerResponse saveRole(@RequestBody SysRoleVO sysRoleVO) { 31 | sysRoleService.saveRole(sysRoleVO); 32 | return ServerResponse.success("保存角色成功!"); 33 | } 34 | 35 | @PostMapping("/delete") 36 | public ServerResponse delRole(@RequestParam("id") Integer roleId) { 37 | sysRoleService.delRole(roleId); 38 | return ServerResponse.success("删除角色成功!"); 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /manage-web/src/main/java/com/dingjn/manage/web/controller/SysUserController.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web.controller; 2 | 3 | import com.dingjn.manage.common.response.ServerResponse; 4 | import com.dingjn.manage.model.dto.SysUserDTO; 5 | import com.dingjn.manage.model.dto.SysUserRoleDTO; 6 | import com.dingjn.manage.model.vo.SysUserVO; 7 | import com.dingjn.manage.persistence.entity.SysUser; 8 | import com.dingjn.manage.service.SysUserService; 9 | import com.github.pagehelper.PageInfo; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | /** 14 | * @Auther: dingjn 15 | * @Desc: 用户管理Controller 16 | */ 17 | @RestController 18 | @RequestMapping("/sysuser") 19 | public class SysUserController { 20 | 21 | @Autowired 22 | SysUserService sysUserService; 23 | 24 | @GetMapping("/query") 25 | public ServerResponse> getUsers(SysUserDTO sysUserBO) { 26 | return ServerResponse.success(sysUserService.getUsers(sysUserBO)); 27 | } 28 | 29 | @PostMapping(value = "/add") 30 | public ServerResponse saveUser(@RequestBody SysUser sysUser) { 31 | sysUserService.saveUser(sysUser); 32 | return ServerResponse.success("保存用户成功!"); 33 | } 34 | 35 | 36 | @PostMapping(value = "/delete") 37 | public ServerResponse delUser(@RequestParam Integer userId) { 38 | sysUserService.deleteUser(userId); 39 | return ServerResponse.success("删除用户成功!"); 40 | } 41 | 42 | 43 | @GetMapping("/checkedroles") 44 | public ServerResponse currentRole(@RequestParam("userId") Integer userId) { 45 | return ServerResponse.success(sysUserService.getCheckedRoles(userId)); 46 | } 47 | 48 | @PostMapping("/saveroles") 49 | public ServerResponse saveRoles(@RequestBody SysUserRoleDTO sysUserRoleDTO) { 50 | sysUserService.saveRoles(sysUserRoleDTO); 51 | return ServerResponse.success("分配角色成功!"); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /manage-web/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 #服务端口 3 | 4 | #################### 5 | # Spring 配置 6 | #################### 7 | spring: 8 | datasource: 9 | type: com.alibaba.druid.pool.DruidDataSource #数据源配置 10 | url: jdbc:mysql://localhost:3306/vuemanage?useUnicode=true&characterEncoding=utf-8&useSSL=false 11 | username: root 12 | password: 123456 13 | driver-class-name: com.mysql.cj.jdbc.Driver 14 | 15 | 16 | #################### 17 | # JWT 配置 18 | #################### 19 | manage: 20 | jwt: 21 | secret: fanffafw;asfkaweg # token密钥 22 | expiration: 3600 # token过期时间 秒 23 | header: JWTHeaderName # HearName用于接受前端传递的token 24 | 25 | 26 | #################### 27 | # Mybatis-plus 配置 28 | #################### 29 | mybatis-plus: 30 | configuration: 31 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql日志 32 | map-underscore-to-camel-case: true # 开启驼峰命名 33 | mapper-locations: classpath*:com/dingjn/manage/persistence/mapper/**/*.xml #Mapper映射文件地址,多moudle要用classpath* 34 | -------------------------------------------------------------------------------- /manage-web/src/test/java/com/dingjn/manage/web/BinarySearchTest.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web; 2 | 3 | /** 4 | * @Auther: dingjn 5 | * @Desc: 6 | */ 7 | public class BinarySearchTest { 8 | 9 | 10 | public static int binarySearch(int[] sortedArray, int targetValue) { 11 | //定义最小的下标 12 | int first = 0; 13 | //最大的下标 14 | int last = sortedArray.length - 1; 15 | 16 | //定义 17 | 18 | return -1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /manage-web/src/test/java/com/dingjn/manage/web/EntityGenerator.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web; 2 | 3 | import com.baomidou.mybatisplus.generator.AutoGenerator; 4 | import com.baomidou.mybatisplus.generator.InjectionConfig; 5 | import com.baomidou.mybatisplus.generator.config.DataSourceConfig; 6 | import com.baomidou.mybatisplus.generator.config.GlobalConfig; 7 | import com.baomidou.mybatisplus.generator.config.PackageConfig; 8 | import com.baomidou.mybatisplus.generator.config.StrategyConfig; 9 | import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; 10 | import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine; 11 | import org.junit.jupiter.api.Test; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /* 17 | 数据层内容生成 18 | */ 19 | public class EntityGenerator { 20 | 21 | // 生成输出目录,定位到工程的java目录下 22 | private String outputDir = "/Users/dingjn/Desktop/codes/vue-manage/manage-persistence/src/main/java"; 23 | // 生成类的作者 24 | private String author = "dingjn"; 25 | // 数据源相关配置 26 | private String url = "jdbc:mysql://localhost:3306/devicedb?useUnicode=true&characterEncoding=utf-8&useSSL=false"; 27 | private String driverName = "com.mysql.cj.jdbc.Driver"; 28 | private String userName = "root"; 29 | private String userPwd = "mysql04141015"; 30 | // DAO的包路径 31 | private String daoPackage = "com.dingjn.manage.persistence"; 32 | // 待生成的表名,注意是覆盖更新 33 | private static String[] tableNames; 34 | 35 | static{ 36 | tableNames = new String[]{ 37 | "sys_api", 38 | "sys_config", 39 | "sys_dict", 40 | "sys_menu", 41 | "sys_org", 42 | "sys_role", 43 | "sys_role_api", 44 | "sys_role_menu", 45 | "sys_user", 46 | "sys_user_role", 47 | }; 48 | } 49 | 50 | @Test 51 | public void entityGenerator() { 52 | AutoGenerator mpg = new AutoGenerator(); 53 | mpg.setTemplateEngine(new BeetlTemplateEngine()); 54 | // 全局配置 55 | GlobalConfig gc = new GlobalConfig(); 56 | gc.setOutputDir(outputDir); 57 | gc.setFileOverride(true); 58 | gc.setActiveRecord(true); 59 | gc.setEnableCache(false); 60 | gc.setBaseResultMap(true); 61 | gc.setBaseColumnList(false); 62 | gc.setAuthor(author); 63 | mpg.setGlobalConfig(gc); 64 | 65 | // 数据源配置 66 | DataSourceConfig dsc = new DataSourceConfig(); 67 | dsc.setUrl(url); 68 | // dsc.setSchemaName("public"); 69 | dsc.setDriverName(driverName); 70 | dsc.setUsername(userName); 71 | dsc.setPassword(userPwd); 72 | mpg.setDataSource(dsc); 73 | 74 | // 策略配置 75 | StrategyConfig strategy = new StrategyConfig(); 76 | //strategy.setTablePrefix(new String[]{"_"});// 此处可以修改为您的表前缀 77 | strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略 78 | strategy.setInclude(tableNames); 79 | mpg.setStrategy(strategy); 80 | 81 | // 包配置 82 | PackageConfig pc = new PackageConfig(); 83 | pc.setParent(null); 84 | pc.setEntity(daoPackage+".entity"); 85 | pc.setMapper(daoPackage+".mapper"); 86 | pc.setXml(daoPackage+".mapper.xml"); 87 | mpg.setPackageInfo(pc); 88 | 89 | // 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值 90 | InjectionConfig cfg = new InjectionConfig() { 91 | @Override 92 | public void initMap() { 93 | Map map = new HashMap<>(); 94 | map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp"); 95 | this.setMap(map); 96 | } 97 | }; 98 | 99 | mpg.setCfg(cfg); 100 | 101 | // 执行生成 102 | mpg.execute(); 103 | 104 | // 打印注入设置 105 | System.err.println(mpg.getCfg().getMap().get("abc")); 106 | 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /manage-web/src/test/java/com/dingjn/manage/web/ManageWebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ManageWebApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /manage-web/src/test/java/com/dingjn/manage/web/SolveTest.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | /** 6 | * @Auther: dingjn 7 | * @Desc: 8 | */ 9 | public class SolveTest { 10 | 11 | /** 12 | * 给定一个有序数组和元素,找出下标. 13 | */ 14 | @Test 15 | public void binarySearch() { 16 | int[] sortedArray = {2, 5, 7, 9, 15}; 17 | int targetValue = 3; 18 | int index = binarySearch(sortedArray, targetValue); 19 | System.out.println(index); 20 | } 21 | 22 | // 二分搜索法:先和中间的比较,小就往前找,大就往后找 23 | public static int binarySearch(int[] sortedArray, int targetValue) { 24 | //最小坐标 25 | int first = 0; 26 | //最大坐标 27 | int last = sortedArray.length - 1; 28 | //当最小的坐标超过了最大的坐标说明已经找过一轮都没找到 29 | while (first <= last) { 30 | int mid = (first + last) / 2; // //计算中间的坐标 31 | 32 | if (targetValue < sortedArray[mid]) { 33 | last = mid - 1; //如果目标值小于中间的值,就从前半部分开始找,最大的坐标则为中间的坐标-1 34 | } else if (targetValue > sortedArray[mid]) { 35 | first = mid + 1; // //如果目标值小于中间的值,就从前后 部分开始找,最小的坐标则为中间的坐标+1 36 | } else { 37 | return mid; // 如果目标值等于中间的值,说明找到了,直接返回 38 | } 39 | } 40 | 41 | return -1; //如果没找到返回-1 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /manage-web/src/test/java/com/dingjn/manage/web/UserMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.dingjn.manage.web; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | 6 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 7 | import com.baomidou.mybatisplus.core.metadata.IPage; 8 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 9 | import com.dingjn.manage.model.node.SysApiNode; 10 | import com.dingjn.manage.persistence.entity.SysUser; 11 | import com.dingjn.manage.persistence.mapper.SysUserMapper; 12 | import com.dingjn.manage.service.SysApiService; 13 | import com.dingjn.manage.service.SysUserService; 14 | import com.dingjn.manage.service.impl.SysApiServiceImpl; 15 | import org.junit.jupiter.api.Test; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.boot.test.context.SpringBootTest; 18 | import org.springframework.security.crypto.password.PasswordEncoder; 19 | 20 | import javax.annotation.Resource; 21 | import java.util.List; 22 | 23 | /** 24 | * @Auther: dingjn 25 | * @Desc: 26 | */ 27 | 28 | @SpringBootTest 29 | public class UserMapperTest { 30 | 31 | @Resource 32 | SysUserMapper sysUserMapper; 33 | 34 | @Autowired 35 | SysUserService sysUserService; 36 | 37 | @Autowired 38 | PasswordEncoder passwordEncoder; 39 | 40 | @Test 41 | public void test() { 42 | // List apiTree = sysApiService.getApiTree(null, null); 43 | // System.out.println(apiTree); 44 | } 45 | 46 | 47 | /** 48 | * 分页查询. 49 | */ 50 | @Test 51 | public void fenye() { 52 | //参数1:当前页数 参数2:每页记录数 53 | IPage iPage = new Page<>(1, 10); 54 | IPage sysUserIPage = sysUserMapper.selectPage(iPage, null); 55 | System.out.println("总记录数:" + sysUserIPage.getTotal()); 56 | System.out.println("总页数:" + sysUserIPage.getPages()); 57 | System.out.println("当前页数:" + sysUserIPage.getCurrent()); 58 | System.out.println("记录:" + sysUserIPage.getRecords()); 59 | System.out.println("大小:" + sysUserIPage.getSize()); 60 | } 61 | 62 | 63 | @Test 64 | public void save() { 65 | //参数1:当前页数 参数2:每页记录数 66 | for (int i = 0; i < 105; i++) { 67 | SysUser sysUser = new SysUser(); 68 | sysUser.setUsername("匿名:"+i); 69 | sysUser.setPassword(passwordEncoder.encode("123456")); 70 | sysUser.setOrgId(3); 71 | sysUser.setEnabled(false); 72 | sysUser.setPhone("17376554257"); 73 | sysUser.setEmail("code123@qq.com"); 74 | sysUser.setCreateTime(LocalDateTime.now()); 75 | sysUserService.saveUser(sysUser); 76 | } 77 | 78 | 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.dingjn 8 | vue-manage 9 | 1.0-SNAPSHOT 10 | 11 | pom 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 2.3.0.RELEASE 16 | 17 | 18 | 19 | manage-web 20 | manage-common 21 | manage-authentication 22 | manage-persistence 23 | manage-service 24 | manage-model 25 | 26 | 27 | 28 | 2.2.4.RELEASE 29 | 1.18.12 30 | 0.9.0 31 | 1.1.21 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-parent 40 | ${springboot.version} 41 | pom 42 | import 43 | 44 | 45 | 46 | org.projectlombok 47 | lombok 48 | ${lombok.version} 49 | 50 | 51 | 52 | io.jsonwebtoken 53 | jjwt 54 | ${jjwt.version} 55 | 56 | 57 | 58 | com.alibaba 59 | druid 60 | ${druid.version} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | src/main/java 69 | 70 | **/*.xml 71 | **/*.properties 72 | 73 | 74 | 75 | 76 | src/main/resources 77 | true 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /vue-manage-front/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-vue-jsx", "transform-runtime"] 12 | } 13 | -------------------------------------------------------------------------------- /vue-manage-front/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /vue-manage-front/README.md: -------------------------------------------------------------------------------- 1 | # vue-manage-front 2 | 3 | > A Vue.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /vue-manage-front/build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, (err, stats) => { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /vue-manage-front/build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | 7 | function exec (cmd) { 8 | return require('child_process').execSync(cmd).toString().trim() 9 | } 10 | 11 | const versionRequirements = [ 12 | { 13 | name: 'node', 14 | currentVersion: semver.clean(process.version), 15 | versionRequirement: packageConfig.engines.node 16 | } 17 | ] 18 | 19 | if (shell.which('npm')) { 20 | versionRequirements.push({ 21 | name: 'npm', 22 | currentVersion: exec('npm --version'), 23 | versionRequirement: packageConfig.engines.npm 24 | }) 25 | } 26 | 27 | module.exports = function () { 28 | const warnings = [] 29 | 30 | for (let i = 0; i < versionRequirements.length; i++) { 31 | const mod = versionRequirements[i] 32 | 33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 34 | warnings.push(mod.name + ': ' + 35 | chalk.red(mod.currentVersion) + ' should be ' + 36 | chalk.green(mod.versionRequirement) 37 | ) 38 | } 39 | } 40 | 41 | if (warnings.length) { 42 | console.log('') 43 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 44 | console.log() 45 | 46 | for (let i = 0; i < warnings.length; i++) { 47 | const warning = warnings[i] 48 | console.log(' ' + warning) 49 | } 50 | 51 | console.log() 52 | process.exit(1) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vue-manage-front/build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oxonan9/vue-manage/777a533ceef576ea86f793ffdd829df5c6edc70f/vue-manage-front/build/logo.png -------------------------------------------------------------------------------- /vue-manage-front/build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const packageConfig = require('../package.json') 6 | 7 | 8 | exports.assetsPath = function (_path) { 9 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 10 | ? config.build.assetsSubDirectory 11 | : config.dev.assetsSubDirectory 12 | 13 | return path.posix.join(assetsSubDirectory, _path) 14 | } 15 | 16 | exports.cssLoaders = function (options) { 17 | options = options || {} 18 | 19 | const cssLoader = { 20 | loader: 'css-loader', 21 | options: { 22 | sourceMap: options.sourceMap, 23 | minimize: true 24 | } 25 | } 26 | 27 | const postcssLoader = { 28 | loader: 'postcss-loader', 29 | options: { 30 | sourceMap: options.sourceMap 31 | } 32 | } 33 | 34 | // generate loader string to be used with extract text plugin 35 | function generateLoaders(loader, loaderOptions) { 36 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 37 | 38 | if (loader) { 39 | loaders.push({ 40 | loader: loader + '-loader', 41 | options: Object.assign({}, loaderOptions, { 42 | sourceMap: options.sourceMap 43 | }) 44 | }) 45 | } 46 | 47 | // Extract CSS when that option is specified 48 | // (which is the case during production build) 49 | if (options.extract) { 50 | return ExtractTextPlugin.extract({ 51 | use: loaders, 52 | fallback: 'vue-style-loader' 53 | }) 54 | } else { 55 | return ['vue-style-loader'].concat(loaders) 56 | } 57 | } 58 | 59 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 60 | return { 61 | css: generateLoaders(), 62 | postcss: generateLoaders(), 63 | less: generateLoaders('less'), 64 | sass: generateLoaders('sass', { indentedSyntax: true }), 65 | scss: generateLoaders('sass'), 66 | stylus: generateLoaders('stylus'), 67 | styl: generateLoaders('stylus') 68 | } 69 | } 70 | 71 | // Generate loaders for standalone style files (outside of .vue) 72 | exports.styleLoaders = function (options) { 73 | const output = [] 74 | const loaders = exports.cssLoaders(options) 75 | 76 | for (const extension in loaders) { 77 | const loader = loaders[extension] 78 | output.push({ 79 | test: new RegExp('\\.' + extension + '$'), 80 | use: loader 81 | }) 82 | } 83 | 84 | return output 85 | } 86 | 87 | exports.createNotifierCallback = () => { 88 | const notifier = require('node-notifier') 89 | 90 | return (severity, errors) => { 91 | if (severity !== 'error') return 92 | 93 | const error = errors[0] 94 | const filename = error.file && error.file.split('!').pop() 95 | 96 | notifier.notify({ 97 | title: packageConfig.name, 98 | message: severity + ': ' + error.name, 99 | subtitle: filename || '', 100 | icon: path.join(__dirname, 'logo.png') 101 | }) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /vue-manage-front/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | module.exports = { 10 | loaders: utils.cssLoaders({ 11 | sourceMap: sourceMapEnabled, 12 | extract: isProduction 13 | }), 14 | cssSourceMap: sourceMapEnabled, 15 | cacheBusting: config.dev.cacheBusting, 16 | transformToRequire: { 17 | video: ['src', 'poster'], 18 | source: 'src', 19 | img: 'src', 20 | image: 'xlink:href' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /vue-manage-front/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | 12 | 13 | module.exports = { 14 | context: path.resolve(__dirname, '../'), 15 | entry: { 16 | app: './src/main.js' 17 | }, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: '[name].js', 21 | publicPath: process.env.NODE_ENV === 'production' 22 | ? config.build.assetsPublicPath 23 | : config.dev.assetsPublicPath 24 | }, 25 | resolve: { 26 | extensions: ['.js', '.vue', '.json'], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.esm.js', 29 | '@': resolve('src'), 30 | } 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.vue$/, 36 | loader: 'vue-loader', 37 | options: vueLoaderConfig 38 | }, 39 | { 40 | test: /\.js$/, 41 | loader: 'babel-loader', 42 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] 43 | }, 44 | { 45 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 46 | loader: 'url-loader', 47 | options: { 48 | limit: 10000, 49 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 50 | } 51 | }, 52 | { 53 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 54 | loader: 'url-loader', 55 | options: { 56 | limit: 10000, 57 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 58 | } 59 | }, 60 | { 61 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 62 | loader: 'url-loader', 63 | options: { 64 | limit: 10000, 65 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 66 | } 67 | } 68 | ] 69 | }, 70 | node: { 71 | // prevent webpack from injecting useless setImmediate polyfill because Vue 72 | // source contains it (although only uses it if it's native). 73 | setImmediate: false, 74 | // prevent webpack from injecting mocks to Node native modules 75 | // that does not make sense for the client 76 | dgram: 'empty', 77 | fs: 'empty', 78 | net: 'empty', 79 | tls: 'empty', 80 | child_process: 'empty' 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vue-manage-front/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const path = require('path') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 11 | const portfinder = require('portfinder') 12 | 13 | const HOST = process.env.HOST 14 | const PORT = process.env.PORT && Number(process.env.PORT) 15 | 16 | const devWebpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 19 | }, 20 | // cheap-module-eval-source-map is faster for development 21 | devtool: config.dev.devtool, 22 | 23 | // these devServer options should be customized in /config/index.js 24 | devServer: { 25 | clientLogLevel: 'warning', 26 | historyApiFallback: { 27 | rewrites: [ 28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, 29 | ], 30 | }, 31 | hot: true, 32 | contentBase: false, // since we use CopyWebpackPlugin. 33 | compress: true, 34 | host: HOST || config.dev.host, 35 | port: PORT || config.dev.port, 36 | open: config.dev.autoOpenBrowser, 37 | overlay: config.dev.errorOverlay 38 | ? { warnings: false, errors: true } 39 | : false, 40 | publicPath: config.dev.assetsPublicPath, 41 | proxy: config.dev.proxyTable, 42 | quiet: true, // necessary for FriendlyErrorsPlugin 43 | watchOptions: { 44 | poll: config.dev.poll, 45 | } 46 | }, 47 | plugins: [ 48 | new webpack.DefinePlugin({ 49 | 'process.env': require('../config/dev.env') 50 | }), 51 | new webpack.HotModuleReplacementPlugin(), 52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 53 | new webpack.NoEmitOnErrorsPlugin(), 54 | // https://github.com/ampedandwired/html-webpack-plugin 55 | new HtmlWebpackPlugin({ 56 | filename: 'index.html', 57 | template: 'index.html', 58 | inject: true 59 | }), 60 | // copy custom static assets 61 | new CopyWebpackPlugin([ 62 | { 63 | from: path.resolve(__dirname, '../static'), 64 | to: config.dev.assetsSubDirectory, 65 | ignore: ['.*'] 66 | } 67 | ]) 68 | ] 69 | }) 70 | 71 | module.exports = new Promise((resolve, reject) => { 72 | portfinder.basePort = process.env.PORT || config.dev.port 73 | portfinder.getPort((err, port) => { 74 | if (err) { 75 | reject(err) 76 | } else { 77 | // publish the new Port, necessary for e2e tests 78 | process.env.PORT = port 79 | // add port to devServer config 80 | devWebpackConfig.devServer.port = port 81 | 82 | // Add FriendlyErrorsPlugin 83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 84 | compilationSuccessInfo: { 85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], 86 | }, 87 | onErrors: config.dev.notifyOnErrors 88 | ? utils.createNotifierCallback() 89 | : undefined 90 | })) 91 | 92 | resolve(devWebpackConfig) 93 | } 94 | }) 95 | }) 96 | -------------------------------------------------------------------------------- /vue-manage-front/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 13 | 14 | const env = require('../config/prod.env') 15 | 16 | const webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true, 21 | usePostCSS: true 22 | }) 23 | }, 24 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 25 | output: { 26 | path: config.build.assetsRoot, 27 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 29 | }, 30 | plugins: [ 31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 32 | new webpack.DefinePlugin({ 33 | 'process.env': env 34 | }), 35 | new UglifyJsPlugin({ 36 | uglifyOptions: { 37 | compress: { 38 | warnings: false 39 | } 40 | }, 41 | sourceMap: config.build.productionSourceMap, 42 | parallel: true 43 | }), 44 | // extract css into its own file 45 | new ExtractTextPlugin({ 46 | filename: utils.assetsPath('css/[name].[contenthash].css'), 47 | // Setting the following option to `false` will not extract CSS from codesplit chunks. 48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. 49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, 50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 51 | allChunks: true, 52 | }), 53 | // Compress extracted CSS. We are using this plugin so that possible 54 | // duplicated CSS from different components can be deduped. 55 | // new OptimizeCSSPlugin({ 56 | // cssProcessorOptions: config.build.productionSourceMap 57 | // ? { safe: true, map: { inline: false } } 58 | // : { safe: true } 59 | // }), 60 | // generate dist index.html with correct asset hash for caching. 61 | // you can customize output by editing /index.html 62 | // see https://github.com/ampedandwired/html-webpack-plugin 63 | new HtmlWebpackPlugin({ 64 | filename: config.build.index, 65 | template: 'index.html', 66 | inject: true, 67 | minify: { 68 | removeComments: true, 69 | collapseWhitespace: true, 70 | removeAttributeQuotes: true 71 | // more options: 72 | // https://github.com/kangax/html-minifier#options-quick-reference 73 | }, 74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 75 | chunksSortMode: 'dependency' 76 | }), 77 | // keep module.id stable when vendor modules does not change 78 | new webpack.HashedModuleIdsPlugin(), 79 | // enable scope hoisting 80 | new webpack.optimize.ModuleConcatenationPlugin(), 81 | // split vendor js into its own file 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'vendor', 84 | minChunks (module) { 85 | // any required modules inside node_modules are extracted to vendor 86 | return ( 87 | module.resource && 88 | /\.js$/.test(module.resource) && 89 | module.resource.indexOf( 90 | path.join(__dirname, '../node_modules') 91 | ) === 0 92 | ) 93 | } 94 | }), 95 | // extract webpack runtime and module manifest to its own file in order to 96 | // prevent vendor hash from being updated whenever app bundle is updated 97 | new webpack.optimize.CommonsChunkPlugin({ 98 | name: 'manifest', 99 | minChunks: Infinity 100 | }), 101 | // This instance extracts shared chunks from code splitted chunks and bundles them 102 | // in a separate chunk, similar to the vendor chunk 103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 104 | new webpack.optimize.CommonsChunkPlugin({ 105 | name: 'app', 106 | async: 'vendor-async', 107 | children: true, 108 | minChunks: 3 109 | }), 110 | 111 | // copy custom static assets 112 | new CopyWebpackPlugin([ 113 | { 114 | from: path.resolve(__dirname, '../static'), 115 | to: config.build.assetsSubDirectory, 116 | ignore: ['.*'] 117 | } 118 | ]) 119 | ] 120 | }) 121 | 122 | if (config.build.productionGzip) { 123 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 124 | 125 | webpackConfig.plugins.push( 126 | new CompressionWebpackPlugin({ 127 | asset: '[path].gz[query]', 128 | algorithm: 'gzip', 129 | test: new RegExp( 130 | '\\.(' + 131 | config.build.productionGzipExtensions.join('|') + 132 | ')$' 133 | ), 134 | threshold: 10240, 135 | minRatio: 0.8 136 | }) 137 | ) 138 | } 139 | 140 | if (config.build.bundleAnalyzerReport) { 141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 143 | } 144 | 145 | module.exports = webpackConfig 146 | -------------------------------------------------------------------------------- /vue-manage-front/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /vue-manage-front/config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.3.1 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | 24 | /** 25 | * Source Maps 26 | */ 27 | 28 | // https://webpack.js.org/configuration/devtool/#development 29 | devtool: 'cheap-module-eval-source-map', 30 | 31 | // If you have problems debugging vue-files in devtools, 32 | // set this to false - it *may* help 33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 34 | cacheBusting: true, 35 | 36 | cssSourceMap: true 37 | }, 38 | 39 | build: { 40 | // Template for index.html 41 | index: path.resolve(__dirname, '../dist/index.html'), 42 | 43 | // Paths 44 | assetsRoot: path.resolve(__dirname, '../dist'), 45 | assetsSubDirectory: 'static', 46 | assetsPublicPath: '/', 47 | 48 | /** 49 | * Source Maps 50 | */ 51 | 52 | productionSourceMap: true, 53 | // https://webpack.js.org/configuration/devtool/#production 54 | devtool: '#source-map', 55 | 56 | // Gzip off by default as many popular static hosts such as 57 | // Surge or Netlify already gzip all static assets for you. 58 | // Before setting to `true`, make sure to: 59 | // npm install --save-dev compression-webpack-plugin 60 | productionGzip: false, 61 | productionGzipExtensions: ['js', 'css'], 62 | 63 | // Run the build command with an extra argument to 64 | // View the bundle analyzer report after build finishes: 65 | // `npm run build --report` 66 | // Set to `true` or `false` to always turn it on or off 67 | bundleAnalyzerReport: process.env.npm_config_report 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /vue-manage-front/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /vue-manage-front/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vue-manage-front 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /vue-manage-front/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 20 | -------------------------------------------------------------------------------- /vue-manage-front/src/api/index.js: -------------------------------------------------------------------------------- 1 | import HttpRequest from '@/lib/request.js' 2 | 3 | export const jwtServerInstance = new HttpRequest("http://localhost:8080") 4 | -------------------------------------------------------------------------------- /vue-manage-front/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oxonan9/vue-manage/777a533ceef576ea86f793ffdd829df5c6edc70f/vue-manage-front/src/assets/logo.png -------------------------------------------------------------------------------- /vue-manage-front/src/components/Home.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 103 | 104 | 201 | -------------------------------------------------------------------------------- /vue-manage-front/src/components/Login.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 56 | 57 | 74 | -------------------------------------------------------------------------------- /vue-manage-front/src/components/layout/LayoutMenu.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 41 | 42 | 60 | -------------------------------------------------------------------------------- /vue-manage-front/src/components/layout/MultiTree.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /vue-manage-front/src/components/layout/TreeSelect.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 132 | 133 | 160 | -------------------------------------------------------------------------------- /vue-manage-front/src/components/system/FirstPage.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 31 | 32 | 40 | -------------------------------------------------------------------------------- /vue-manage-front/src/lib/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { getJwtToken } from "./utils"; 3 | 4 | class HttpRequest { 5 | //构造函数 6 | constructor(baseUrl) { 7 | this.baseUrl = baseUrl 8 | } 9 | 10 | //针对当前axios实例的默认配置 11 | initConfig() { 12 | const config = { 13 | baseURL: this.baseUrl, 14 | headers: { 15 | // 16 | } 17 | } 18 | return config 19 | } 20 | 21 | //创建并返回axios实例,options参数为创建实例时传递的个性化参数 22 | request(options) { 23 | const instance = axios.create() 24 | instance.interceptors.response.use( 25 | response => { 26 | const res = response.data; 27 | if (res.status == 200) { 28 | return res; 29 | } else { 30 | console.log("resres") 31 | throw res; 32 | } 33 | }, 34 | // 这里处理异常响应结果 35 | error => { 36 | if (error && error.response) { 37 | switch (error.response.status) { 38 | case 400: 39 | error.message = error.response.data.message; 40 | break; 41 | case 401: 42 | error.message = '未授权,请重新登录'; 43 | break; 44 | case 403: 45 | error.message = '拒绝访问'; 46 | break; 47 | case 404: 48 | error.message = '请求错误,未找到该资源'; 49 | break; 50 | case 405: 51 | error.message = '请求方法未允许'; 52 | break; 53 | case 408: 54 | error.message = '请求超时'; 55 | break; 56 | case 500: //服务器错误,返回具体的信息 57 | error.message = error.response.data.message; 58 | break; 59 | case 501: 60 | error.message = '网络未实现'; 61 | break; 62 | case 502: 63 | error.message = '网络错误'; 64 | break; 65 | case 503: 66 | error.message = '服务不可用'; 67 | break; 68 | case 504: 69 | error.message = '网络超时'; 70 | break; 71 | case 505: 72 | error.message = 'http版本不支持该请求'; 73 | break; 74 | default: 75 | error.message = `未知错误${error.response.status}`; 76 | } 77 | } else { 78 | error.message = "连接到服务器失败"; 79 | } 80 | return Promise.reject(error); 81 | } 82 | ) 83 | // request拦截器 84 | instance.interceptors.request.use( 85 | config => { 86 | //认证请求不需要携带令牌 87 | if (config.url !== "/authentication") { 88 | // 让每个请求携带token 89 | config.headers['JWTHeaderName'] = getJwtToken(); 90 | } 91 | return config; 92 | } 93 | ) 94 | options = Object.assign(this.initConfig(), options) 95 | return instance(options) 96 | } 97 | } 98 | 99 | export default HttpRequest 100 | -------------------------------------------------------------------------------- /vue-manage-front/src/lib/utils.js: -------------------------------------------------------------------------------- 1 | const LOCAL_JWT_KEY = "jskdfls"; 2 | export const setJwtToken = (jwtToken) => { 3 | localStorage.setItem(LOCAL_JWT_KEY,jwtToken) 4 | } 5 | export const getJwtToken = () => { 6 | return localStorage.getItem(LOCAL_JWT_KEY) 7 | } 8 | export const getTokenUser = () => { 9 | let userString = decodeURIComponent( 10 | window.atob(getJwtToken().split('.')[1]) 11 | ) 12 | return JSON.parse(userString).sub 13 | } -------------------------------------------------------------------------------- /vue-manage-front/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import ElementUI from 'element-ui'; 7 | import 'element-ui/lib/theme-chalk/index.css'; 8 | import axios from 'axios' 9 | import store from './store/index.js' 10 | 11 | Vue.prototype.$http=axios 12 | 13 | Vue.config.productionTip = false 14 | Vue.use(ElementUI) 15 | 16 | /* eslint-disable no-new */ 17 | new Vue({ 18 | el: '#app', 19 | router, 20 | store, 21 | components: { App }, 22 | template: '' 23 | }) 24 | -------------------------------------------------------------------------------- /vue-manage-front/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Login from '@/components/Login' 4 | import Home from '@/components/Home' 5 | import SysUser from '@/components/system/SysUser' 6 | import SysRole from '@/components/system/SysRole' 7 | import SysApi from '@/components/system/SysApi' 8 | import SysOrg from '@/components/system/SysOrg' 9 | import FirstPage from '@/components/system/FirstPage' 10 | import SysMenu from '@/components/system/SysMenu' 11 | import store from '@/store/index' 12 | import { refreshToken } from '@/api/system' 13 | import { setJwtToken } from "@/lib/utils"; 14 | 15 | 16 | Vue.use(Router) 17 | 18 | const router = new Router({ 19 | routes: [ 20 | { path: '/', redirect: '/login' }, 21 | { path: '/login', name: "login", component: Login }, 22 | { 23 | path: '/home', 24 | name: "home", 25 | component: Home, 26 | children: [ 27 | { path: '', redirect: 'firstPage' }, 28 | { path: 'firstPage', component: FirstPage }, 29 | { path: "sysuser", component: SysUser }, 30 | { path: "sysapi", component: SysApi }, 31 | { path: "sysorg", component: SysOrg }, 32 | { path: "sysrole", component: SysRole }, 33 | { path: "sysmenu", component: SysMenu }, 34 | ] 35 | } 36 | ] 37 | }) 38 | 39 | router.beforeEach((to, from, next) => { 40 | if (to.name !== 'login') { 41 | refreshToken().then(res => { 42 | //没有获得新的token==null, 43 | // 表示旧的token已经失效,需要重新登录 44 | if (res.data == null) { 45 | next({ name: 'login' }) //去登录界面 46 | setJwtToken('') //清空token 47 | } else {//否则去你想去的界面,并把新的token保存起来 48 | console.log("456" + res.data); 49 | // 把全局配置加载完成再去你想去的页面 50 | next() 51 | setJwtToken(res.data) 52 | } 53 | }) 54 | } else {//每次去到登录页面都刷新一下,清除vuex状态 55 | next() 56 | setJwtToken('') //清空token 57 | } 58 | 59 | if (to.name === 'firstpage') { 60 | store.dispatch('addTab', to.path) 61 | } 62 | }) 63 | 64 | router.afterEach((to, from) => { 65 | //store.commit('addTab',to.path) 66 | store.dispatch('addTab', to.path) 67 | }) 68 | export default router 69 | -------------------------------------------------------------------------------- /vue-manage-front/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vuex from 'vuex' 2 | import Vue from 'vue' 3 | import { getMenuTreeByUsername } from '@/api/system' 4 | 5 | 6 | Vue.use(Vuex) 7 | 8 | //创建store对象 9 | export default new Vuex.Store({ 10 | //state 存储全局共享数据 11 | state: { 12 | //存放{ route: 路由路径, name: tab显示名称}对象数组 13 | //存放{ route: 路由路径, name: tab显示名称}对象数组 14 | maintabs: [{ route: "/home/firstpage", name: "系统首页", closable: false }], 15 | //当前被激活显示的那个Tab内容对应的route 16 | activeRoute: "/home/firstPage", 17 | menuList: [ 18 | ], 19 | addTabName: "" 20 | }, 21 | mutations: { 22 | setActiveRoute(state, route) { 23 | state.activeRoute = route; 24 | }, 25 | addTabMutation(state, route) { 26 | let isAlreadyIn = 27 | state.maintabs.some(item => item.route === route) 28 | this.commit("findMenuNameByRoute", route); 29 | if (!isAlreadyIn && state.addTabName !== "") { 30 | state.maintabs.push({ route: route, name: state.addTabName }); 31 | } 32 | }, 33 | removeTab(state, route) { 34 | if (route !== "/home/firstpage") { 35 | state.maintabs = state.maintabs.filter( 36 | item => item.route !== route 37 | ) 38 | state.activeRoute = state.maintabs[state.maintabs.length - 1].route 39 | } 40 | }, 41 | findMenuNameByRoute(state, route) { 42 | let findOne; 43 | for (let i in state.menuList) { 44 | let tmpArr = state.menuList[i].children.filter( 45 | item => item.path === route 46 | ) 47 | if (tmpArr.length > 0) { 48 | findOne = tmpArr[0] 49 | break; 50 | } 51 | } 52 | state.addTabName = findOne ? findOne.name : ""; 53 | } 54 | }, 55 | actions: { 56 | addTab({ state, commit }, route) { 57 | //因为menuList里面有一项非菜单路由 58 | //大于等于一表示菜单已经加载过了,并且页面没刷新, 59 | //只是切换路由组件,不重新加载菜单 60 | commit("setActiveRoute", route); 61 | if (state.menuList.length <= 1) { 62 | getMenuTreeByUsername() 63 | .then(res => { 64 | console.log(res.data) 65 | state.menuList = [...res.data] 66 | commit("addTabMutation", route); //菜单加载完成之后将Tab导航项添加 67 | }) 68 | } else { 69 | commit("addTabMutation", route);//菜单加载完成之后将Tab导航项添加 70 | } 71 | } 72 | } 73 | }) -------------------------------------------------------------------------------- /vue-manage-front/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oxonan9/vue-manage/777a533ceef576ea86f793ffdd829df5c6edc70f/vue-manage-front/static/.gitkeep --------------------------------------------------------------------------------