├── UI ├── dump.rdb ├── .DS_Store ├── images │ ├── index_1.jpg │ ├── index_2.jpg │ ├── index_3.jpg │ └── login.jpeg ├── src │ ├── config │ │ └── config.js │ ├── vendors.js │ ├── router │ │ ├── _import_development.js │ │ └── index.js │ ├── app.vue │ ├── store │ │ ├── getters.js │ │ ├── index.js │ │ └── modules │ │ │ ├── Permission.js │ │ │ └── user.js │ ├── utils │ │ ├── auth.js │ │ └── fetch.js │ ├── views │ │ ├── dashboard │ │ │ ├── navMenu.vue │ │ │ ├── index.vue │ │ │ └── wordCountPanel.vue │ │ ├── login │ │ │ ├── signed.vue │ │ │ ├── index.vue │ │ │ └── signIn.vue │ │ ├── admin │ │ │ ├── index.vue │ │ │ ├── roleInfoPanel.vue │ │ │ ├── permissionInfoPanel.vue │ │ │ └── userInfoPanel.vue │ │ └── index │ │ │ └── index.vue │ ├── libs │ │ └── util.js │ ├── template │ │ └── index.ejs │ ├── api │ │ └── login.js │ ├── main.js │ └── permission.js ├── index.html ├── package.json └── webpack.config.js ├── Server ├── dump.rdb ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── zhuxs │ │ │ │ └── result │ │ │ │ ├── service │ │ │ │ ├── WordCountService.java │ │ │ │ ├── PermissionService.java │ │ │ │ ├── RoleService.java │ │ │ │ ├── UserService.java │ │ │ │ └── impl │ │ │ │ │ ├── PermissionServiceImpl.java │ │ │ │ │ ├── UserServiceImpl.java │ │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ │ └── WordCountServiceImpl.java │ │ │ │ ├── domain │ │ │ │ ├── RoleDao.java │ │ │ │ ├── enums │ │ │ │ │ ├── JobTypeEnum.java │ │ │ │ │ ├── ResourceType.java │ │ │ │ │ ├── UserStatus.java │ │ │ │ │ ├── ActionType.java │ │ │ │ │ ├── ErrorCode.java │ │ │ │ │ └── JobStatus.java │ │ │ │ ├── PermissionDao.java │ │ │ │ ├── UserDao.java │ │ │ │ ├── JobDao.java │ │ │ │ └── entity │ │ │ │ │ ├── Job.java │ │ │ │ │ ├── Permission.java │ │ │ │ │ ├── Role.java │ │ │ │ │ └── User.java │ │ │ │ ├── bo │ │ │ │ ├── Word.java │ │ │ │ ├── comparator │ │ │ │ │ └── CountComparator.java │ │ │ │ └── Count.java │ │ │ │ ├── config │ │ │ │ ├── ModelMapperConfig.java │ │ │ │ ├── CorsConfig.java │ │ │ │ ├── RedisCacheConfig.java │ │ │ │ ├── ApplicationConfig.java │ │ │ │ └── ShiroConfig.java │ │ │ │ ├── ResultApplication.java │ │ │ │ ├── shiro │ │ │ │ ├── ShiroSessionFactory.java │ │ │ │ ├── ShiroSessionListener.java │ │ │ │ ├── ShiroSession.java │ │ │ │ ├── ShiroRealm.java │ │ │ │ └── ShiroSessionDao.java │ │ │ │ ├── dto │ │ │ │ ├── TextDto.java │ │ │ │ ├── ErrorDto.java │ │ │ │ ├── RoleDto.java │ │ │ │ ├── PermissionDto.java │ │ │ │ └── UserDto.java │ │ │ │ ├── utils │ │ │ │ ├── RegsUtil.java │ │ │ │ ├── ApplicationUtil.java │ │ │ │ └── SerializeUtils.java │ │ │ │ ├── Exception │ │ │ │ └── ResultException.java │ │ │ │ ├── Handler │ │ │ │ └── GlobalExceptionHandler.java │ │ │ │ └── controller │ │ │ │ ├── JobController.java │ │ │ │ ├── AuthController.java │ │ │ │ └── AdminController.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── zhuxs │ │ └── result │ │ └── ResultApplicationTests.java ├── pom.xml ├── mvnw.cmd └── mvnw ├── .gitignore ├── README.md └── LICENSE /UI/dump.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/UI/dump.rdb -------------------------------------------------------------------------------- /UI/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/UI/.DS_Store -------------------------------------------------------------------------------- /Server/dump.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/Server/dump.rdb -------------------------------------------------------------------------------- /UI/images/index_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/UI/images/index_1.jpg -------------------------------------------------------------------------------- /UI/images/index_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/UI/images/index_2.jpg -------------------------------------------------------------------------------- /UI/images/index_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/UI/images/index_3.jpg -------------------------------------------------------------------------------- /UI/images/login.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhuXS/Spring-Shiro-Spark/HEAD/UI/images/login.jpeg -------------------------------------------------------------------------------- /UI/src/config/config.js: -------------------------------------------------------------------------------- 1 | import Env from './env'; 2 | 3 | let config = { 4 | env: Env 5 | }; 6 | export default config; -------------------------------------------------------------------------------- /UI/src/vendors.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import iView from 'iview'; 3 | import VueRouter from 'vue-router'; 4 | import axios from 'axios'; -------------------------------------------------------------------------------- /UI/src/router/_import_development.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | module.exports = file => require('../views/' + file + ".vue").default 5 | -------------------------------------------------------------------------------- /UI/src/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /UI/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello RESult 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | 3 | ### IntelliJ IDEA ### 4 | Server/.idea 5 | UI/.idea 6 | UI/node_modules 7 | UI/dist 8 | Server/.idea/workspace.xml 9 | Server/.idea/workspace.xml 10 | UI/.idea/workspace.xml 11 | Server/.idea/workspace.xml 12 | UI/.idea/workspace.xml 13 | .DS_Store 14 | 15 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/WordCountService.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service; 2 | 3 | import com.zhuxs.result.bo.Count; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by shusesshou on 2017/9/11. 9 | */ 10 | public interface WordCountService { 11 | List wordCount(String words); 12 | } 13 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/RoleDao.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain; 2 | 3 | import com.zhuxs.result.domain.entity.Role; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by shusesshou on 2017/9/20. 8 | */ 9 | public interface RoleDao extends JpaRepository{ 10 | } 11 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/enums/JobTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.enums; 2 | 3 | /** 4 | * Created by shusesshou on 2017/9/15. 5 | */ 6 | public class JobTypeEnum { 7 | public static final int WORDCOUNT_SIM = 0; 8 | public static final int WORDCOUNT_FILE = 1; 9 | public static final int WORDCOUNT_URL = 2; 10 | } 11 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/PermissionDao.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain; 2 | 3 | import com.zhuxs.result.domain.entity.Permission; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by shusesshou on 2017/9/20. 8 | */ 9 | public interface PermissionDao extends JpaRepository { 10 | } 11 | -------------------------------------------------------------------------------- /UI/src/store/getters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | const getters = { 5 | status: state => state.user.status, 6 | username: state => state.user.username, 7 | name: state => state.user.name, 8 | roles: state => state.user.roles, 9 | addRouters: state => state.permission.addRouters 10 | } 11 | 12 | export default getters 13 | -------------------------------------------------------------------------------- /UI/src/utils/auth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | import Cookies from 'js-cookie' 5 | 6 | const sessionId = 'JSESSIONID' 7 | 8 | export function getSessionId() { 9 | return Cookies.get(sessionId) 10 | } 11 | 12 | export function setSessionId(token) { 13 | return Cookies.set(sessionId,token) 14 | } 15 | 16 | export function removeSessionId() { 17 | return Cookies.remove(sessionId) 18 | } 19 | -------------------------------------------------------------------------------- /UI/src/views/dashboard/navMenu.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /UI/src/store/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | import user from './modules/user' 5 | import permission from './modules/permission' 6 | import getters from './getters' 7 | 8 | import Vue from 'vue' 9 | import Vuex from 'vuex' 10 | 11 | Vue.use(Vuex) 12 | 13 | const store = new Vuex.Store({ 14 | modules: { 15 | user, 16 | permission 17 | }, 18 | getters 19 | }) 20 | 21 | export default store 22 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain; 2 | 3 | import com.zhuxs.result.domain.entity.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import javax.transaction.Transactional; 7 | 8 | /** 9 | * Created by shusesshou on 2017/9/20. 10 | */ 11 | public interface UserDao extends JpaRepository{ 12 | 13 | @Transactional 14 | User findUserByUsername(String username); 15 | } 16 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/bo/Word.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.bo; 2 | 3 | /** 4 | * Created by shusesshou on 2017/9/4. 5 | */ 6 | public class Word { 7 | 8 | private String word; 9 | 10 | public Word(){} 11 | 12 | public Word(String word) { 13 | this.word = word; 14 | } 15 | 16 | public String getWord() { 17 | return word; 18 | } 19 | 20 | public void setWord(String word) { 21 | this.word = word; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/config/ModelMapperConfig.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.config; 2 | 3 | import org.modelmapper.ModelMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * Created by shusesshou on 2017/9/25. 9 | */ 10 | @Configuration 11 | public class ModelMapperConfig { 12 | @Bean 13 | public ModelMapper modelMapper(){ 14 | return new ModelMapper(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Server/src/test/java/com/zhuxs/result/ResultApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @Ignore 10 | @RunWith(SpringRunner.class) 11 | @SpringBootTest 12 | public class ResultApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/PermissionService.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service; 2 | 3 | import com.zhuxs.result.domain.entity.Permission; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by shusesshou on 2017/9/25. 9 | */ 10 | public interface PermissionService { 11 | Permission addPermission(Permission permission); 12 | List listPermissions(); 13 | List getPermissionsByUserId(long userId); 14 | 15 | void delPermissionById(long id); 16 | } 17 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/bo/comparator/CountComparator.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.bo.comparator; 2 | 3 | import com.zhuxs.result.bo.Count; 4 | 5 | import java.util.Comparator; 6 | 7 | import static java.lang.Math.toIntExact; 8 | 9 | /** 10 | * Created by shusesshou on 2017/9/14. 11 | */ 12 | public class CountComparator implements Comparator{ 13 | 14 | @Override 15 | public int compare(Count o1, Count o2) { 16 | return toIntExact(o2.getCount() - o1.getCount()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /UI/src/views/login/signed.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 15 | 16 | -------------------------------------------------------------------------------- /UI/src/libs/util.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import env from '../config/env'; 3 | 4 | let util = { 5 | 6 | }; 7 | util.title = function(title) { 8 | title = title ? title + ' - Home' : 'iView project'; 9 | window.document.title = title; 10 | }; 11 | 12 | const ajaxUrl = env === 'development' ? 13 | 'http://127.0.0.1:8888' : 14 | env === 'production' ? 15 | 'https://www.url.com' : 16 | 'https://debug.url.com'; 17 | 18 | util.ajax = axios.create({ 19 | baseURL: ajaxUrl, 20 | timeout: 30000 21 | }); 22 | 23 | export default util; -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/JobDao.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain; 2 | 3 | import com.zhuxs.result.domain.entity.Job; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import javax.transaction.Transactional; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by shusesshou on 2017/9/16. 13 | */ 14 | @Transactional 15 | @Repository 16 | public interface JobDao extends JpaRepository { 17 | public List findAllByEndDate(Date date); 18 | } 19 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/RoleService.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service; 2 | 3 | import com.zhuxs.result.domain.entity.Permission; 4 | import com.zhuxs.result.domain.entity.Role; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by shusesshou on 2017/9/25. 10 | */ 11 | public interface RoleService { 12 | Role addRole(Role role); 13 | 14 | List listRoles(); 15 | 16 | List getRolesByUserId(long userId); 17 | 18 | Role updatePermissionsById(long id,List permissions); 19 | 20 | void delRoleById(long id); 21 | } -------------------------------------------------------------------------------- /UI/src/views/dashboard/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /UI/src/template/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | iView project 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service; 2 | 3 | import com.zhuxs.result.domain.entity.Permission; 4 | import com.zhuxs.result.domain.entity.Role; 5 | import com.zhuxs.result.domain.entity.User; 6 | import com.zhuxs.result.dto.UserDto; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by shusesshou on 2017/9/25. 12 | */ 13 | public interface UserService { 14 | User addUser(User user); 15 | List listUsers(); 16 | User updateRolesById(long id, List roles); 17 | User updatePermissionsById(long id, List permissions); 18 | void delUserById(long id); 19 | } 20 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/ResultApplication.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 7 | import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; 8 | 9 | @SpringBootApplication 10 | public class ResultApplication { 11 | public static void main(String[] args) { 12 | System.setProperty("spark.executor.memory","512m"); 13 | SpringApplication.run(ResultApplication.class, args); 14 | } 15 | 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/shiro/ShiroSessionFactory.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.shiro; 2 | 3 | import org.apache.shiro.session.Session; 4 | import org.apache.shiro.session.mgt.SessionContext; 5 | import org.apache.shiro.session.mgt.SessionFactory; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * Created by shusesshou on 2017/9/22. 11 | */ 12 | public class ShiroSessionFactory implements SessionFactory{ 13 | private static final Logger logger = LoggerFactory.getLogger(ShiroSessionFactory.class); 14 | 15 | @Override 16 | public Session createSession(SessionContext sessionContext) { 17 | ShiroSession session = new ShiroSession(); 18 | return session; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/bo/Count.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.bo; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * Created by shusesshou on 2017/9/4. 7 | */ 8 | public class Count{ 9 | private String word; 10 | private long count; 11 | 12 | public Count(){} 13 | 14 | public Count(String word, long count) { 15 | this.word = word; 16 | this.count = count; 17 | } 18 | 19 | public String getWord() { 20 | return word; 21 | } 22 | 23 | public void setWord(String word) { 24 | this.word = word; 25 | } 26 | 27 | public long getCount() { 28 | return count; 29 | } 30 | 31 | public void setCount(long count) { 32 | this.count = count; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /UI/src/api/login.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | import fetch from '../utils/fetch' 5 | 6 | export function login(username, password) { 7 | const data = { 8 | username, 9 | password 10 | } 11 | return fetch({ 12 | url: '/login', 13 | method: 'post', 14 | data 15 | }) 16 | } 17 | 18 | //test the user login or not and get the userInfo 19 | export function getUserInfo() { 20 | return fetch({ 21 | url:'/userInfo', 22 | method:'get' 23 | }) 24 | } 25 | 26 | export function logout(sessionId) { 27 | const data = { 28 | sessionId 29 | } 30 | return fetch({ 31 | url:'/logout', 32 | method: 'post', 33 | data 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/enums/ResourceType.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.enums; 2 | 3 | /** 4 | * Created by shusesshou on 2017/9/20. 5 | */ 6 | public enum ResourceType { 7 | 8 | WORDCOUNT(0,"WordCount"); 9 | 10 | private int type; 11 | private String desc; 12 | 13 | ResourceType() { 14 | } 15 | 16 | ResourceType(int type, String desc) { 17 | this.type = type; 18 | this.desc = desc; 19 | } 20 | 21 | public int getType() { 22 | return type; 23 | } 24 | 25 | public void setType(int type) { 26 | this.type = type; 27 | } 28 | 29 | public String getDesc() { 30 | return desc; 31 | } 32 | 33 | public void setDesc(String desc) { 34 | this.desc = desc; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spark-Shiro-Spark 2 | Spark-Shiro-Spark是Spring-Boot Hibernate Spark Spark-SQL Shiro iView VueJs... ...的集成尝试 3 | ## 主要做了两件事 4 | - **前后端分离下的用户认证和鉴权实践** 5 |     6 | - [前后端分离下的用户认证和鉴权实践(一) 概述](https://github.com/ZhuXS/RESult/issues/1) 7 | - [前后端分离下的用户认证和鉴权实践(二) 权限粒度的设计](https://github.com/ZhuXS/RESult/issues/2) 8 | - [前后端分离下的用户认证和鉴权实践(三) Shiro简介](https://github.com/ZhuXS/RESult/issues/4) 9 | - [前后端分离下的用户认证和鉴权实践(四) 基于shiro的后端认证和鉴权](https://github.com/ZhuXS/RESult/issues/5) 10 | - [前后端分离下的用户认证和鉴权实践(五) 用户登录状态的保持和单点登录](https://github.com/ZhuXS/RESult/issues/6) 11 | - [前后端分离下的用户认证和鉴权实践(六) 前端的路由控制和动态渲染](https://github.com/ZhuXS/RESult/issues/7) 12 | 13 | - **Spring Boot与Spark的集成实践** 14 |     15 | - [Spring Boot与Spark的集成实践](https://github.com/ZhuXS/RESult/issues/8) 16 | 17 |   18 | ## 欢迎批评指教 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/enums/UserStatus.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.enums; 2 | 3 | /** 4 | * Created by shusesshou on 2017/9/19. 5 | */ 6 | public enum UserStatus { 7 | 8 | CREATE(1,"create without certification"), 9 | NORMAL(2,"normal"), 10 | LOCKED(3,"locked"); 11 | 12 | private int status; 13 | private String desc; 14 | 15 | UserStatus() { 16 | } 17 | 18 | UserStatus(int status, String desc) { 19 | this.status = status; 20 | this.desc = desc; 21 | } 22 | 23 | public int getStatus() { 24 | return status; 25 | } 26 | 27 | public void setStatus(int status) { 28 | this.status = status; 29 | } 30 | 31 | public String getDesc() { 32 | return desc; 33 | } 34 | 35 | public void setDesc(String desc) { 36 | this.desc = desc; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/enums/ActionType.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.enums; 2 | 3 | /** 4 | * Created by shusesshou on 2017/10/9. 5 | */ 6 | public enum ActionType { 7 | ALL(0,"all"), 8 | CREATE(1,"create"), 9 | READ(2,"read"), 10 | UPDATE(3,"update"), 11 | DELETE(4,"delete") 12 | ; 13 | private int type; 14 | private String desc; 15 | 16 | ActionType() { 17 | } 18 | 19 | ActionType(int type, String desc) { 20 | this.type = type; 21 | this.desc = desc; 22 | } 23 | 24 | public int getType() { 25 | return type; 26 | } 27 | 28 | public void setType(int type) { 29 | this.type = type; 30 | } 31 | 32 | public String getDesc() { 33 | return desc; 34 | } 35 | 36 | public void setDesc(String desc) { 37 | this.desc = desc; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/dto/TextDto.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.dto; 2 | 3 | /** 4 | * Created by shusesshou on 2017/9/11. 5 | */ 6 | public class TextDto { 7 | private String words; 8 | 9 | public TextDto() { 10 | } 11 | 12 | public TextDto(String words) { 13 | this.words = words; 14 | } 15 | 16 | public String getWords() { 17 | return words; 18 | } 19 | 20 | public void setWords(String words) { 21 | this.words = words; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (this == o) return true; 27 | if (o == null || getClass() != o.getClass()) return false; 28 | 29 | TextDto TextDto = (TextDto) o; 30 | 31 | return words != null ? words.equals(TextDto.words) : TextDto.words == null; 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return words != null ? words.hashCode() : 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /UI/src/views/admin/index.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /UI/src/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/8. 3 | */ 4 | import Vue from 'vue' 5 | import VueRouter from 'vue-router' 6 | import Vuex from 'vuex' 7 | import App from './app.vue' 8 | import router from './router/index' 9 | import store from './store' 10 | 11 | //agile for index 12 | import VueAgile from 'vue-agile' 13 | Vue.use(VueAgile) 14 | 15 | //iView UI 16 | import iView from 'iview'; 17 | import 'iview/dist/styles/iview.css'; 18 | import './permission' 19 | 20 | //加载路由中间件 21 | Vue.use(iView) 22 | Vue.use(Vuex) 23 | 24 | //Global Error Handler 25 | Vue.config.errorHandler = function (err,vm,info) { 26 | //Server Error 27 | alert(err) 28 | if(err.response){ 29 | //not Auth 30 | if(err.response.data.errorCode === 40010){ 31 | Vue.$router.push({ 32 | path:'/login' 33 | }) 34 | } 35 | } 36 | } 37 | 38 | new Vue({ 39 | el: '#app', 40 | router, 41 | store, 42 | render: h => h(App) 43 | }) 44 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/enums/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.enums; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | 5 | /** 6 | * Created by shusesshou on 2017/9/18. 7 | */ 8 | @JsonFormat(shape = JsonFormat.Shape.OBJECT) 9 | public enum ErrorCode { 10 | ERROR(40000,"error"), 11 | NOTAUTHC(40100,"not authc"), 12 | NOTAUTHZ(40101,"not authz"), 13 | USERNAMEORPASSWORD(40401,"Username or Password Not Correct"); 14 | 15 | private final int code; 16 | private final String desc; 17 | 18 | ErrorCode(int code, String desc) { 19 | this.code = code; 20 | this.desc = desc; 21 | } 22 | 23 | public int getCode() { 24 | return code; 25 | } 26 | 27 | public String getDesc() { 28 | return desc; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return "ErrorCode{" + 34 | "code=" + code + 35 | ", desc='" + desc + '\'' + 36 | '}'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/enums/JobStatus.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.enums; 2 | 3 | /** 4 | * Created by shusesshou on 2017/9/18. 5 | */ 6 | public enum JobStatus { 7 | 8 | WAITING(0,"waiting"), 9 | READY(1,"ready"), 10 | RUNNING(2,"running"), 11 | BLOCK(3,"block"), 12 | FAILED(4,"failed"), 13 | SUCCESS(5,"success"); 14 | 15 | private int status; 16 | private String desc; 17 | 18 | JobStatus(int status, String desc) { 19 | this.status = status; 20 | this.desc = desc; 21 | } 22 | 23 | public int getStatus() { 24 | return status; 25 | } 26 | 27 | public void setStatus(int status) { 28 | this.status = status; 29 | } 30 | 31 | public String getDesc() { 32 | return desc; 33 | } 34 | 35 | public void setDesc(String desc) { 36 | this.desc = desc; 37 | } 38 | 39 | 40 | @Override 41 | public String toString() { 42 | return "JobStatus{" + 43 | "status=" + status + 44 | ", desc='" + desc + '\'' + 45 | '}'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/utils/RegsUtil.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.utils; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | import java.util.regex.PatternSyntaxException; 6 | 7 | /** 8 | * Created by shusesshou on 2017/9/14. 9 | */ 10 | public class RegsUtil { 11 | 12 | public static boolean checkSpecialChar(String str) throws PatternSyntaxException { 13 | // 清除掉所有特殊字符 14 | String regEx = ".*[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?\\\\]+.*"; 15 | Pattern p = Pattern.compile(regEx); 16 | Matcher m = p.matcher(str); 17 | return m.matches(); 18 | } 19 | 20 | /** 21 | * replace all special symbol by one space 22 | * @param str 23 | * @return 24 | * @throws PatternSyntaxException 25 | */ 26 | public static String filterString(String str) throws PatternSyntaxException { 27 | String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?\\\\]"; 28 | Pattern p = Pattern.compile(regEx); 29 | Matcher m = p.matcher(str); 30 | return m.replaceAll(" ").replaceAll("\\s+"," ").trim(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/utils/ApplicationUtil.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.web.context.request.WebRequest; 8 | import org.springframework.web.util.UriComponents; 9 | import org.springframework.web.util.UriComponentsBuilder; 10 | 11 | import java.net.URI; 12 | 13 | 14 | /** 15 | * Created by shusesshou on 2017/9/11. 16 | */ 17 | public class ApplicationUtil { 18 | private static final Logger logger = LoggerFactory.getLogger(ApplicationUtil.class); 19 | 20 | public static HttpHeaders getHttpHeaders(UriComponentsBuilder uriComponentsBuilder,String uri,Object... uriVariableValues){ 21 | UriComponents uriComponents = uriComponentsBuilder.path(uri).buildAndExpand(uriVariableValues); 22 | HttpHeaders headers = new HttpHeaders(); 23 | try { 24 | headers.setLocation(new URI(uriComponents.getPath())); 25 | }catch (Exception e){ 26 | logger.error(e.getStackTrace().toString()); 27 | } 28 | headers.setContentType(MediaType.APPLICATION_JSON); 29 | return headers; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /UI/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui", 3 | "version": "1.0.0", 4 | "description": "UI of RESult", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "test", 8 | "dev": "webpack-dev-server --hot --open --port 8086" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "axios": "^0.16.2", 14 | "babel-core": "^6.26.0", 15 | "babel-loader": "^7.1.2", 16 | "babel-preset-vue-app": "^1.3.0", 17 | "cross-env": "^5.0.5", 18 | "css-loader": "^0.28.7", 19 | "file-loader": "^0.11.2", 20 | "iview": "^2.3.2", 21 | "js-cookie": "^2.1.4", 22 | "nprogress": "^0.2.0", 23 | "style-loader": "^0.18.2", 24 | "vue": "^2.4.2", 25 | "vue-agile": "^0.2.6", 26 | "vue-html-loader": "^1.2.4", 27 | "vue-loader": "^13.0.4", 28 | "vue-resource": "^1.3.4", 29 | "vue-router": "^2.7.0", 30 | "vue-style-loader": "^3.0.1", 31 | "vue-template-compiler": "^2.4.2", 32 | "vuex": "^2.4.0", 33 | "webpack": "^3.5.5", 34 | "webpack-dev-server": "^2.7.1" 35 | }, 36 | "devDependencies": { 37 | "babel-plugin-component": "^0.10.0", 38 | "html-webpack-plugin": "^2.30.1", 39 | "node-sass": "^4.5.3", 40 | "sass-loader": "^6.0.6", 41 | "vue": "^2.4.2" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /UI/src/utils/fetch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | import axios from 'axios' 5 | import { getToken } from './auth' 6 | import store from '../store' 7 | 8 | //创建axios实例 9 | const service = axios.create({ 10 | baseURL: "http://localhost:8081", 11 | timeout: 5000, //请求超时时间 12 | withCredentials : true 13 | }) 14 | 15 | //是否保留跨域请求凭证 16 | service.defaults.withCredentials = true 17 | 18 | //request拦截器 19 | service.interceptors.request.use(config => { 20 | if(store.getters.status){ 21 | //take token or sessionId 22 | } 23 | return config 24 | },error => { 25 | console.log(error) 26 | Promise.reject(error) 27 | }) 28 | 29 | //response拦截器 30 | service.interceptors.response.use(response => { 31 | //alert(response.data) 32 | return response 33 | },error => { 34 | //alert(error.response.data.errorCode.code) 35 | if(error.response.data.errorCode.code === 40100){ 36 | window.location .href = "login" 37 | return Promise.reject(error) 38 | } else if(error.response.data.errorCode.code === 40101){ 39 | window.location.href = "dashboard" 40 | return Promise.reject(error) 41 | }else { 42 | return Promise.reject(error) 43 | } 44 | }) 45 | 46 | export default service -------------------------------------------------------------------------------- /UI/src/views/login/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 33 | 34 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 7 | import org.springframework.web.filter.CorsFilter; 8 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 9 | 10 | /** 11 | * Created by shusesshou on 2017/9/11. 12 | */ 13 | @Configuration 14 | public class CorsConfig { 15 | private CorsConfiguration buildConfig(){ 16 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 17 | corsConfiguration.addAllowedOrigin("*"); //allow all cross origin 18 | corsConfiguration.addAllowedHeader("*"); //allow all header 19 | corsConfiguration.addAllowedMethod("*"); //allow all http method 20 | corsConfiguration.setAllowCredentials(true); //允许保留跨域请求凭证 21 | return corsConfiguration; 22 | } 23 | 24 | @Bean 25 | public CorsFilter corsFilter(){ 26 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 27 | source.registerCorsConfiguration("/**",buildConfig()); 28 | return new CorsFilter(source); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/dto/ErrorDto.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.dto; 2 | 3 | import com.zhuxs.result.domain.enums.ErrorCode; 4 | 5 | /** 6 | * Created by shusesshou on 2017/9/18. 7 | */ 8 | public class ErrorDto { 9 | private String status; 10 | private ErrorCode errorCode; 11 | private String url; 12 | private String msg; 13 | 14 | public ErrorDto() { 15 | } 16 | 17 | public ErrorDto(String status, ErrorCode errorCode, String url, String msg) { 18 | this.status = status; 19 | this.errorCode = errorCode; 20 | this.url = url; 21 | this.msg = msg; 22 | } 23 | 24 | public String getStatus() { 25 | return status; 26 | } 27 | 28 | public void setStatus(String status) { 29 | this.status = status; 30 | } 31 | 32 | public ErrorCode getErrorCode() { 33 | return errorCode; 34 | } 35 | 36 | public void setErrorCode(ErrorCode errorCode) { 37 | this.errorCode = errorCode; 38 | } 39 | 40 | public String getUrl() { 41 | return url; 42 | } 43 | 44 | public void setUrl(String url) { 45 | this.url = url; 46 | } 47 | 48 | public String getMsg() { 49 | return msg; 50 | } 51 | 52 | public void setMsg(String msg) { 53 | this.msg = msg; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/Exception/ResultException.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.exception; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import com.zhuxs.result.domain.enums.ErrorCode; 5 | 6 | /** 7 | * Created by shusesshou on 2017/9/18. 8 | */ 9 | public class ResultException extends RuntimeException{ 10 | private ErrorCode errorCode; 11 | 12 | public ResultException() { 13 | } 14 | 15 | public ResultException(String message) { 16 | super(message); 17 | } 18 | 19 | public ResultException(String message, ErrorCode errorCode) { 20 | super(message); 21 | this.errorCode = errorCode; 22 | } 23 | 24 | public ResultException(Throwable cause, ErrorCode errorCode) { 25 | super(cause); 26 | this.errorCode = errorCode; 27 | } 28 | 29 | public ResultException(String message, Throwable cause, ErrorCode errorCode) { 30 | super(message, cause); 31 | this.errorCode = errorCode; 32 | } 33 | 34 | public ErrorCode getErrorCode() { 35 | return errorCode; 36 | } 37 | 38 | public void setErrorCode(ErrorCode errorCode) { 39 | this.errorCode = errorCode; 40 | } 41 | 42 | @JsonIgnore 43 | public ResultException getResultExceptionWithoutCause(){ 44 | return new ResultException(this.getMessage(),this.getErrorCode()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /UI/src/router/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | import Vue from 'vue' 5 | import Router from "vue-router" 6 | 7 | const _import = require('./_import_development') 8 | 9 | Vue.use(Router) 10 | 11 | //所有权限通用路由表 12 | export const constantRouterMap = [ 13 | { 14 | path: '/', 15 | component: _import('index/index'), 16 | name: "hello" 17 | }, 18 | { 19 | path: '/dashboard', 20 | component: _import('dashboard/index'), 21 | name: "RESult", 22 | }, 23 | { 24 | path: "/login", 25 | component: _import('login/index'), 26 | name: "login" 27 | }, 28 | { 29 | path: "/admin", 30 | component: _import('admin/index'), 31 | //redirect: '/dashboard', 32 | meta:{ 33 | role: ['Admin'] 34 | }, 35 | name: "admin" 36 | }, 37 | { 38 | path: "*", 39 | component: _import('index/index'), 40 | name: "Not Found" 41 | } 42 | ] 43 | 44 | export default new Router({ 45 | mode: 'history', 46 | scrollBehavior: () => ({y:0}), 47 | routes: constantRouterMap 48 | }) 49 | 50 | export const asyncRouterMap = [ 51 | { 52 | path: "/admin", 53 | component: _import('admin/index'), 54 | //redirect: '/dashboard', 55 | meta:{ 56 | role: ['Admin'] 57 | }, 58 | name: "admin" 59 | } 60 | ] -------------------------------------------------------------------------------- /Server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ################################### 2 | ############# BASE 3 | ################################### 4 | app.name=RESult 5 | 6 | ################################### 7 | ############# SPARK 8 | ################################### 9 | spark.home=127.0.0.1 10 | master.uri=spark://127.0.0.1:7077 11 | server.port=8081 12 | 13 | ################################### 14 | ############# MYSQL 15 | ################################### 16 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/result?useSSL=false 17 | spring.datasource.username=root 18 | spring.datasource.password=root 19 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 20 | 21 | ################################### 22 | ############# HIBERNATE 23 | ################################### 24 | spring.jpa.database=mysql 25 | spring.jpa.hibernate.ddl-auto=update 26 | spring.jpa.show-sql=true 27 | spring.jpa.properties.hibernate.format_sql=true 28 | 29 | ################################### 30 | ############# REDIS 31 | ################################### 32 | # Redis数据库索引 33 | spring.redis.database=0 34 | # Redis服务器地址 35 | spring.redis.host=127.0.0.1 36 | # Redis服务器连接端口 37 | spring.redis.port=6379 38 | # Redis服务器连接密码 39 | spring.redis.password=redis 40 | # 连接池最大阻塞等待时间 41 | spring.redis.pool.max-wait=-1 42 | # 连接池中的最大空闲连接 43 | spring.redis.pool.max-idle=-1 44 | # 连接池中的最小空闲连接 45 | spring.redis.pool.min-idle=-1 46 | # 连接超时时间 47 | spring.redis.timeout=5000 48 | 49 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/shiro/ShiroSessionListener.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.shiro; 2 | 3 | import org.apache.shiro.session.Session; 4 | import org.apache.shiro.session.SessionListener; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import redis.clients.jedis.Jedis; 9 | import redis.clients.jedis.JedisPool; 10 | 11 | /** 12 | * Created by shusesshou on 2017/9/22. 13 | */ 14 | public class ShiroSessionListener implements SessionListener { 15 | 16 | private static final Logger logger = LoggerFactory.getLogger(ShiroSessionListener.class); 17 | 18 | @Autowired 19 | private ShiroSessionDao shiroSessionDao; 20 | 21 | @Autowired 22 | private JedisPool jedisPool; 23 | 24 | @Override 25 | public void onStart(Session session) { 26 | logger.debug("session {} onStart",session.getId()); 27 | } 28 | 29 | @Override 30 | public void onStop(Session session) { 31 | shiroSessionDao.delete(session); 32 | Jedis jedis = jedisPool.getResource(); 33 | jedis.publish("shiro.session.uncache",(String) session.getId()); 34 | logger.debug("session {} onStop", session.getId()); 35 | } 36 | 37 | @Override 38 | public void onExpiration(Session session) { 39 | shiroSessionDao.delete(session); 40 | Jedis jedis = jedisPool.getResource(); 41 | jedis.publish("shiro.session.uncache",(String) session.getId()); 42 | logger.debug("session {} onExpiration", session.getId()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/utils/SerializeUtils.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.utils; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.zhuxs.result.exception.ResultException; 5 | import org.apache.commons.lang3.SerializationUtils; 6 | import org.apache.shiro.codec.Base64; 7 | 8 | import java.io.Serializable; 9 | import java.util.Collection; 10 | import java.util.List; 11 | 12 | /** 13 | * Created by shusesshou on 2017/9/22. 14 | */ 15 | public class SerializeUtils extends SerializationUtils{ 16 | public static String serializaToString(Serializable obj){ 17 | try{ 18 | byte[] value = serialize(obj); 19 | return Base64.encodeToString(value); 20 | }catch (Exception e){ 21 | throw new ResultException("serialize session error"); 22 | } 23 | } 24 | 25 | public static T deserializeFromString(String base64){ 26 | try{ 27 | byte[] objectData = Base64.decode(base64); 28 | return deserialize(objectData); 29 | } catch (Exception e){ 30 | throw new ResultException("deserialize session error"); 31 | } 32 | } 33 | 34 | public static Collection deserializeFromStrings(Collection base64s){ 35 | try{ 36 | List list = Lists.newLinkedList(); 37 | for(String base64 : base64s){ 38 | byte[] objectData = Base64.decode(base64); 39 | T t = deserialize(objectData); 40 | list.add(t); 41 | } 42 | return list; 43 | }catch (Exception e){ 44 | throw new ResultException("deserialize session error"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/config/RedisCacheConfig.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.cache.annotation.CachingConfigurerSupport; 7 | import org.springframework.cache.annotation.EnableCaching; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import redis.clients.jedis.JedisPool; 11 | import redis.clients.jedis.JedisPoolConfig; 12 | 13 | /** 14 | * Created by shusesshou on 2017/9/23. 15 | */ 16 | @Configuration 17 | @EnableCaching 18 | public class RedisCacheConfig extends CachingConfigurerSupport{ 19 | private Logger logger = LoggerFactory.getLogger(RedisCacheConfig.class); 20 | 21 | @Value("${spring.redis.host}") 22 | private String host; 23 | 24 | @Value("${spring.redis.port}") 25 | private int port; 26 | 27 | @Value("${spring.redis.timeout}") 28 | private int timeout; 29 | 30 | @Value("${spring.redis.pool.max-idle}") 31 | private int maxIdle; 32 | 33 | @Value("${spring.redis.pool.max-wait}") 34 | private long maxWaitMillis; 35 | 36 | @Value("${spring.redis.password}") 37 | private String password; 38 | 39 | @Bean 40 | public JedisPool redisPoolFactory() { 41 | logger.info("redis: " + host + ":" + port); 42 | JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); 43 | jedisPoolConfig.setMaxIdle(maxIdle); 44 | jedisPoolConfig.setMaxWaitMillis(maxWaitMillis); 45 | 46 | JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password); 47 | return jedisPool; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /UI/src/permission.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/26. 3 | */ 4 | import router from './router' 5 | import store from './store' 6 | import { getSessionId } from "./utils/auth" 7 | import NProgress from 'nprogress' //进度条 8 | import 'nprogress/nprogress.css' 9 | 10 | //permission judge 11 | function hasPermission(roles,permissions) { 12 | if (roles.indexOf('admin') > 0) return true //admin权限,直接通过 13 | if(!permissions) return true 14 | 15 | } 16 | 17 | //register global progress 18 | const whiteList = ['/login','/'] //不重定向白名单 19 | router.beforeEach((to,from,next) => { 20 | NProgress.start(); //开启Progress 21 | if(store.getters.status) { 22 | next 23 | } else { 24 | if(whiteList.indexOf(to.path) !== -1){ //在登录白名单,直接进入 25 | //alert("test") 26 | next(); 27 | } else { 28 | store.dispatch('GetUserInfo').then(res => { 29 | //拉取user_info,并测试用户是否登录 30 | const roles = res.data.roles 31 | store.dispatch('GenerateRoutes',roles).then(() => { 32 | console.log(store.getters.addRouters) 33 | router.addRoutes(store.getters.addRouters) //动态添加可访问路由表 34 | console.log(router) 35 | next() 36 | //next({ ...to }) 37 | }) 38 | }).catch(e => { 39 | if(e.response.data.errorCode.code === 40010){ 40 | next('/login') //否则全部定向到登录页 41 | } 42 | if(e.response.data.errorCode.code === 1) 43 | next('/login') //否则全部定向到登录页 44 | }) 45 | } 46 | } 47 | }) 48 | 49 | router.afterEach(() => { 50 | NProgress.done() //结束Progress 51 | }) -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/impl/PermissionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service.impl; 2 | 3 | import com.zhuxs.result.domain.PermissionDao; 4 | import com.zhuxs.result.domain.UserDao; 5 | import com.zhuxs.result.domain.entity.Permission; 6 | import com.zhuxs.result.domain.entity.User; 7 | import com.zhuxs.result.exception.ResultException; 8 | import com.zhuxs.result.service.PermissionService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created by shusesshou on 2017/9/25. 16 | */ 17 | @Service 18 | public class PermissionServiceImpl implements PermissionService { 19 | @Autowired 20 | private UserDao userDao; 21 | @Autowired 22 | private PermissionDao permissionDao; 23 | @Override 24 | public Permission addPermission(Permission permission) { 25 | permissionDao.save(permission); 26 | return null; 27 | } 28 | 29 | @Override 30 | public List listPermissions() { 31 | List permissions = permissionDao.findAll(); 32 | return permissions; 33 | } 34 | 35 | @Override 36 | public List getPermissionsByUserId(long userId) { 37 | if(!userDao.exists(userId)){ 38 | throw new ResultException(); 39 | } 40 | try { 41 | User user = userDao.findOne(userId); 42 | List permissions = user.getPermissions(); 43 | return permissions; 44 | }catch (Exception e){ 45 | throw new ResultException(); 46 | } 47 | } 48 | 49 | @Override 50 | public void delPermissionById(long id) { 51 | permissionDao.delete(id); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /UI/src/views/index/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 62 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/dto/RoleDto.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by shusesshou on 2017/9/25. 7 | */ 8 | public class RoleDto implements Serializable{ 9 | private long id; 10 | private String name; 11 | private String desc; 12 | 13 | public RoleDto() { 14 | } 15 | 16 | public RoleDto(String name, String desc) { 17 | this.name = name; 18 | this.desc = desc; 19 | } 20 | 21 | public RoleDto(long id, String name, String desc) { 22 | this.id = id; 23 | this.name = name; 24 | this.desc = desc; 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public void setName(String name) { 32 | this.name = name; 33 | } 34 | 35 | public String getDesc() { 36 | return desc; 37 | } 38 | 39 | public void setDesc(String desc) { 40 | this.desc = desc; 41 | } 42 | 43 | public long getId() { 44 | return id; 45 | } 46 | 47 | public void setId(long id) { 48 | this.id = id; 49 | } 50 | 51 | @Override 52 | public boolean equals(Object o) { 53 | if (this == o) return true; 54 | if (o == null || getClass() != o.getClass()) return false; 55 | 56 | RoleDto roleDto = (RoleDto) o; 57 | 58 | if (id != roleDto.id) return false; 59 | if (name != null ? !name.equals(roleDto.name) : roleDto.name != null) return false; 60 | return desc != null ? desc.equals(roleDto.desc) : roleDto.desc == null; 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | int result = (int) (id ^ (id >>> 32)); 66 | result = 31 * result + (name != null ? name.hashCode() : 0); 67 | result = 31 * result + (desc != null ? desc.hashCode() : 0); 68 | return result; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /UI/src/store/modules/Permission.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/28. 3 | */ 4 | import { asyncRouterMap,constantRouterMap } from "../../router" 5 | 6 | /** 7 | * 通过meta.role判断是否与当前用户权限匹配 8 | */ 9 | function hasPermission(roles,route) { 10 | if(route.meta && route.meta.roles) { 11 | return roles.some(roles => route.meta.indexOf(roles) >= 0) 12 | } else { 13 | return true 14 | } 15 | } 16 | /** 17 | * 递归过滤异步路由表,返回符合角色权限的路由表 18 | */ 19 | function filterAsyncRouter(asyncRouterMap,roles) { 20 | const accessedRouters = asyncRouterMap.filter(route => { 21 | if(hasPermission(roles,route)){ 22 | if(route.children && route.children.length){ 23 | route.children = filterAsyncRouter(route.children,roles) 24 | } 25 | return true 26 | } 27 | return false 28 | }) 29 | return accessedRouters 30 | } 31 | 32 | const permission = { 33 | state: { 34 | routers: constantRouterMap, 35 | addRouters: [] 36 | }, 37 | mutations: { 38 | SET_ROUTERS: (state, routers) => { 39 | state.addRouters = routers 40 | state.routers = constantRouterMap.concat(routers) 41 | //alert(state.routers.length) 42 | } 43 | }, 44 | actions: { 45 | GenerateRoutes({commit},data){ 46 | return new Promise(resolve => { 47 | const roles = data.map(item => { 48 | return item.name 49 | }) 50 | let accessedRouters 51 | 52 | if(roles.indexOf('Admin') >= 0){ 53 | accessedRouters = asyncRouterMap 54 | } else { 55 | accessedRouters = filterAsyncRouter(asyncRouterMap,roles) 56 | } 57 | commit('SET_ROUTERS',accessedRouters) 58 | resolve() 59 | }) 60 | } 61 | } 62 | } 63 | 64 | export default permission 65 | 66 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service.impl; 2 | 3 | import com.zhuxs.result.domain.entity.Permission; 4 | import com.zhuxs.result.exception.ResultException; 5 | import com.zhuxs.result.domain.UserDao; 6 | import com.zhuxs.result.domain.entity.Role; 7 | import com.zhuxs.result.domain.entity.User; 8 | import com.zhuxs.result.service.UserService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created by shusesshou on 2017/9/25. 16 | */ 17 | @Service 18 | public class UserServiceImpl implements UserService { 19 | @Autowired 20 | private UserDao userDao; 21 | @Override 22 | public User addUser(User user) { 23 | user = userDao.save(user); 24 | return user; 25 | } 26 | 27 | @Override 28 | public List listUsers() { 29 | List users = userDao.findAll(); 30 | return users; 31 | } 32 | 33 | @Override 34 | public User updateRolesById(long id, List roles) { 35 | if(!userDao.exists(id)){ 36 | throw new ResultException(); 37 | } 38 | try { 39 | User user = userDao.findOne(id); 40 | user.setRoles(roles); 41 | user = userDao.save(user); 42 | return user; 43 | }catch (Exception e){ 44 | //throw e; 45 | throw new ResultException(); 46 | } 47 | } 48 | 49 | @Override 50 | public User updatePermissionsById(long id, List permissions) { 51 | if(!userDao.exists(id)){ 52 | throw new ResultException(); 53 | } 54 | try { 55 | User user = userDao.findOne(id); 56 | user.setPermissions(permissions); 57 | user = userDao.save(user); 58 | return user; 59 | }catch (Exception e){ 60 | throw new ResultException(); 61 | } 62 | } 63 | 64 | @Override 65 | public void delUserById(long id) { 66 | userDao.delete(id); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/impl/RoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service.impl; 2 | 3 | import com.zhuxs.result.domain.UserDao; 4 | import com.zhuxs.result.domain.entity.User; 5 | import com.zhuxs.result.exception.ResultException; 6 | import com.zhuxs.result.domain.RoleDao; 7 | import com.zhuxs.result.domain.entity.Permission; 8 | import com.zhuxs.result.domain.entity.Role; 9 | import com.zhuxs.result.service.RoleService; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Created by shusesshou on 2017/9/25. 17 | */ 18 | @Service 19 | public class RoleServiceImpl implements RoleService{ 20 | @Autowired 21 | private RoleDao roleDao; 22 | @Autowired 23 | private UserDao userDao; 24 | @Override 25 | public Role addRole(Role role) { 26 | role = roleDao.save(role); 27 | return role; 28 | } 29 | 30 | @Override 31 | public List listRoles() { 32 | List roles = roleDao.findAll(); 33 | return roles; 34 | } 35 | 36 | @Override 37 | public List getRolesByUserId(long userId) { 38 | if (!userDao.exists(userId)){ 39 | throw new ResultException(); 40 | } 41 | try{ 42 | User user = userDao.findOne(userId); 43 | List roles = user.getRoles(); 44 | return roles; 45 | }catch (Exception e){ 46 | throw new ResultException(); 47 | } 48 | } 49 | 50 | @Override 51 | public Role updatePermissionsById(long id, List permissions){ 52 | if(!roleDao.exists(id)){ 53 | throw new ResultException(); 54 | } 55 | try { 56 | Role role = roleDao.findOne(id); 57 | role.setPermissions(permissions); 58 | role = roleDao.save(role); 59 | return role; 60 | } catch (Exception e){ 61 | throw new ResultException(); 62 | } 63 | } 64 | 65 | @Override 66 | public void delRoleById(long id) { 67 | roleDao.delete(id); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/Handler/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.Handler; 2 | 3 | import com.zhuxs.result.exception.ResultException; 4 | import com.zhuxs.result.dto.ErrorDto; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.http.HttpHeaders; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.web.bind.annotation.ControllerAdvice; 12 | import org.springframework.web.bind.annotation.ExceptionHandler; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.net.URI; 17 | import java.net.URISyntaxException; 18 | 19 | /** 20 | * Created by shusesshou on 2017/9/18. 21 | */ 22 | @ControllerAdvice 23 | @RestController 24 | public class GlobalExceptionHandler { 25 | private Logger logger = LoggerFactory.getLogger("com.zhuxs.result.GlobalExceptionHandler"); 26 | 27 | @ExceptionHandler(value = {ResultException.class}) 28 | public ResponseEntity handleException(ResultException ex, HttpServletRequest request) throws URISyntaxException { 29 | HttpHeaders headers = new HttpHeaders(); 30 | headers.setLocation(new URI(request.getRequestURI())); 31 | headers.setContentType(MediaType.APPLICATION_JSON); 32 | logger.error("-----exception Handler---Host: {} invokes url: {} ERROR: {} Cause:",request.getRemoteHost(),request.getRequestURL(), ex.getMessage(),ex.getCause()); 33 | return handleExceptionInternal(ex,headers,HttpStatus.INTERNAL_SERVER_ERROR,request); 34 | } 35 | 36 | protected ResponseEntity handleExceptionInternal(ResultException ex, HttpHeaders headers, HttpStatus status,HttpServletRequest request){ 37 | ErrorDto errorDto = new ErrorDto(); 38 | errorDto.setStatus(status.toString()); 39 | errorDto.setErrorCode(ex.getErrorCode()); 40 | errorDto.setUrl(request.getRequestURL().toString()); 41 | errorDto.setMsg(ex.getMessage()); 42 | return new ResponseEntity(errorDto,headers,status); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/config/ApplicationConfig.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.config; 2 | 3 | import org.apache.spark.SparkConf; 4 | import org.apache.spark.api.java.JavaSparkContext; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.autoconfigure.domain.EntityScan; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.PropertySource; 11 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 12 | import org.springframework.core.env.Environment; 13 | import org.apache.spark.sql.SparkSession; 14 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 15 | 16 | import javax.persistence.Entity; 17 | 18 | /** 19 | * Created by shusesshou on 2017/9/4. 20 | */ 21 | @Configuration 22 | @PropertySource("classpath:application.properties") 23 | @EnableJpaRepositories(basePackages = { 24 | "com.zhuxs.result.domain" 25 | }) 26 | @EntityScan("com.zhuxs.result.domain.entity") 27 | public class ApplicationConfig { 28 | 29 | @Autowired 30 | private Environment env; 31 | 32 | @Value("${app.name:RESult}") 33 | private String appName; 34 | 35 | @Value("${spark.home}") 36 | private String sparkHome; 37 | 38 | @Value("${master.uri:local}") 39 | private String masterUri; 40 | 41 | @Bean 42 | public SparkConf sparkConf() { 43 | SparkConf sparkConf = new SparkConf() 44 | .setAppName(appName) 45 | .setMaster("local"); 46 | return sparkConf; 47 | } 48 | 49 | @Bean 50 | public JavaSparkContext javaSparkContext(){ 51 | return new JavaSparkContext(sparkConf()); 52 | } 53 | 54 | @Bean 55 | public SparkSession sparkSession(){ 56 | return SparkSession 57 | .builder() 58 | .sparkContext(javaSparkContext().sc()) 59 | .appName("Java Spark SQL basic example") 60 | .getOrCreate(); 61 | } 62 | 63 | @Bean 64 | public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){ 65 | return new PropertySourcesPlaceholderConfigurer(); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/controller/JobController.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.controller; 2 | 3 | import com.zhuxs.result.exception.ResultException; 4 | import com.zhuxs.result.bo.Count; 5 | import com.zhuxs.result.domain.JobDao; 6 | import com.zhuxs.result.dto.TextDto; 7 | import com.zhuxs.result.service.WordCountService; 8 | import com.zhuxs.result.utils.ApplicationUtil; 9 | import org.apache.shiro.SecurityUtils; 10 | import org.apache.shiro.authz.annotation.RequiresPermissions; 11 | import org.apache.shiro.subject.Subject; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.http.HttpHeaders; 14 | import org.springframework.http.HttpStatus; 15 | import org.springframework.http.MediaType; 16 | import org.springframework.http.ResponseEntity; 17 | import org.springframework.stereotype.Controller; 18 | import org.springframework.web.bind.annotation.PostMapping; 19 | import org.springframework.web.bind.annotation.PutMapping; 20 | import org.springframework.web.bind.annotation.RequestBody; 21 | import org.springframework.web.bind.annotation.RequestMapping; 22 | import org.springframework.web.util.UriComponentsBuilder; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * Created by shusesshou on 2017/9/4. 28 | */ 29 | @RequestMapping(value = JobController.PATH,produces = MediaType.APPLICATION_JSON_VALUE) 30 | @Controller 31 | public class JobController { 32 | public static final String PATH = "jobs"; 33 | 34 | public static final String SUBPATH_WORDCOUNT = "0"; 35 | 36 | @Autowired 37 | private WordCountService wordCountService; 38 | 39 | @Autowired 40 | private JobDao jobDao; 41 | 42 | @PostMapping(value = SUBPATH_WORDCOUNT) 43 | public ResponseEntity> getCounts(@RequestBody TextDto words, 44 | UriComponentsBuilder uriComponentsBuilder) throws ResultException{ 45 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH); 46 | Subject subject = SecurityUtils.getSubject(); 47 | /**if(!subject.isPermitted("WORDCOUNT:CREATE")){ 48 | throw new ResultException("fuck shiro"); 49 | } else { 50 | throw new ResultException("fuck"); 51 | }*/ 52 | return new ResponseEntity<>(wordCountService.wordCount(words.getWords()),HttpStatus.OK); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /UI/src/views/login/signIn.vue: -------------------------------------------------------------------------------- 1 | 18 | 61 | -------------------------------------------------------------------------------- /UI/src/store/modules/user.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/21. 3 | */ 4 | import Cookies from 'js-cookie' 5 | import { login,logout,getUserInfo } from '../../api/login' 6 | import {getSessionId,setSessionId,removeSessionId} from '../../utils/auth' 7 | 8 | const user = { 9 | state: { 10 | username: '', 11 | name: '', 12 | sessionId: getSessionId(), 13 | roles:[], 14 | status: '' 15 | }, 16 | mutations: { 17 | SET_USERNAME: (state, username) => { 18 | state.username = username 19 | }, 20 | SET_NAME: (state, name) => { 21 | state.name = name 22 | }, 23 | SET_SESSIONID: (state,sessionId) => { 24 | state.sessionId = sessionId 25 | }, 26 | SET_ROLES: (state,roles) => { 27 | state.roles = roles 28 | }, 29 | SET_STATUS: (state, status) => { 30 | state.status = status 31 | } 32 | }, 33 | actions: { 34 | //用户名登录 35 | Login({ commit }, userInfo){ 36 | const username = userInfo.username.trim() 37 | return new Promise((resolve, reject) => { 38 | login(username,userInfo.password).then(response => { 39 | //commit('SET_STATUS',true) 40 | resolve(); 41 | }).catch(error => { 42 | reject(error) 43 | }) 44 | }) 45 | }, 46 | 47 | //获取用户信息 48 | GetUserInfo({ commit } ){ 49 | return new Promise((resolve,reject) => { 50 | getUserInfo().then(response => { 51 | commit('SET_NAME',response.data.name) 52 | commit('SET_USERNAME',response.data.username) 53 | commit('SET_ROLES',response.data.roles) 54 | //commit('SET_') 55 | commit('SET_STATUS',true) 56 | //alert(state.name) 57 | resolve(response) 58 | }).catch(error => { 59 | reject(error) 60 | }) 61 | }) 62 | }, 63 | 64 | //登出 65 | LogOut({ commit,state }) { 66 | return new Promise((resolve,reject) => { 67 | logout(state.sessionId).then(() => { 68 | commit('SET_NAME',"") 69 | commit('SET_USERNAME',"") 70 | commit('SET_SESSIONID',"") 71 | commit('SET_ROLES',"") 72 | //commit('SET_') 73 | commit('SET_STATUS',false) 74 | removeSessionId() 75 | resolve() 76 | }) 77 | }) 78 | } 79 | } 80 | } 81 | 82 | export default user 83 | 84 | -------------------------------------------------------------------------------- /UI/webpack.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by shusesshou on 2017/9/6. 3 | */ 4 | var path = require('path') 5 | var webpack = require('webpack') 6 | 7 | module.exports = { 8 | entry: './src/main.js', 9 | output: { 10 | path: path.resolve(__dirname, './dist'), 11 | publicPath: '/dist/', 12 | filename: 'build.js' 13 | }, 14 | module: { 15 | loaders: [ 16 | { 17 | test: /\.vue$/, 18 | loader: 'vue-loader' 19 | }, 20 | { 21 | test: /\.js$/, 22 | loader: 'babel-loader', 23 | exclude: /node_modules/ 24 | }, 25 | { 26 | test: /\.css$/, 27 | loader: 'style-loader!css-loader' 28 | }, 29 | { 30 | test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, 31 | loader: 'file-loader' 32 | }, 33 | { 34 | test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/, 35 | loader: 'file-loader', 36 | query: { 37 | name: '[name].[ext]?[hash]' 38 | } 39 | } 40 | ] 41 | }, 42 | resolve: { 43 | alias: { 44 | 'vue$': 'vue/dist/vue.esm.js', 45 | '@': path.resolve('src'), 46 | 'src': path.resolve(__dirname, '../src'), 47 | 'assets': path.resolve(__dirname, '../src/assets'), 48 | 'components': path.resolve(__dirname, '../src/components'), 49 | 'views': path.resolve(__dirname, '../src/views'), 50 | 'styles': path.resolve(__dirname, '../src/styles'), 51 | 'api': path.resolve(__dirname, '../src/api'), 52 | 'utils': path.resolve(__dirname, '../src/utils'), 53 | 'store': path.resolve(__dirname, '../src/store'), 54 | 'router': path.resolve(__dirname, '../src/router'), 55 | 'mock': path.resolve(__dirname, '../src/mock'), 56 | 'vendor': path.resolve(__dirname, '../src/vendor'), 57 | 'static': path.resolve(__dirname, '../static') 58 | } 59 | }, 60 | devServer: { 61 | historyApiFallback: true, 62 | noInfo: true 63 | }, 64 | devtool: '#eval-source-map' 65 | } 66 | 67 | if (process.env.NODE_ENV === 'production') { 68 | module.exports.devtool = '#source-map' 69 | // http://vue-loader.vuejs.org/en/workflow/production.html 70 | module.exports.plugins = (module.exports.plugins || []).concat([ 71 | new webpack.DefinePlugin({ 72 | 'process.env': { 73 | NODE_ENV: '"production"' 74 | } 75 | }), 76 | new webpack.optimize.UglifyJsPlugin({ 77 | compress: { 78 | warnings: false 79 | } 80 | }) 81 | ]) 82 | } -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/shiro/ShiroSession.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.shiro; 2 | 3 | import org.apache.shiro.session.mgt.SimpleSession; 4 | 5 | import javax.xml.crypto.Data; 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | import java.util.Map; 9 | 10 | /** 11 | * Created by shusesshou on 2017/9/22. 12 | * SimpleSession lastAccessTime更改后也会调用SessionDao update方法 13 | * 增加标识位,如果只是更新lastAccessTime方法直接返回 14 | */ 15 | public class ShiroSession extends SimpleSession implements Serializable{ 16 | private Boolean isChanged; 17 | 18 | public ShiroSession(){ 19 | super(); 20 | this.setIsChanged(true); 21 | } 22 | 23 | public ShiroSession(String Host){ 24 | super(Host); 25 | this.setIsChanged(true); 26 | } 27 | 28 | @Override 29 | public void setId(Serializable id){ 30 | super.setId(id); 31 | this.setIsChanged(true); 32 | } 33 | 34 | @Override 35 | public void setStopTimestamp(Date stopTimeStamp){ 36 | super.setStopTimestamp(stopTimeStamp); 37 | this.setIsChanged(true); 38 | } 39 | 40 | @Override 41 | public void setExpired(boolean expired){ 42 | super.setExpired(expired); 43 | this.setIsChanged(true); 44 | } 45 | 46 | @Override 47 | public void setTimeout(long timeout){ 48 | super.setTimeout(timeout); 49 | this.setIsChanged(true); 50 | } 51 | 52 | @Override 53 | public void setHost(String host){ 54 | super.setHost(host); 55 | this.setIsChanged(true); 56 | } 57 | 58 | @Override 59 | public void setAttributes(Map attributes){ 60 | super.setAttributes(attributes); 61 | this.setIsChanged(true); 62 | } 63 | 64 | @Override 65 | public void setAttribute(Object key, Object value){ 66 | super.setAttribute(key,value); 67 | this.setIsChanged(true); 68 | } 69 | 70 | @Override 71 | public Object removeAttribute(Object key){ 72 | this.setIsChanged(true); 73 | return super.removeAttribute(key); 74 | } 75 | 76 | @Override 77 | protected void expire(){ 78 | this.stop(); 79 | this.setExpired(true); 80 | } 81 | 82 | public Boolean getIsChanged(){ 83 | return isChanged; 84 | } 85 | 86 | public void setIsChanged(Boolean isChanged){ 87 | this.isChanged = isChanged; 88 | } 89 | 90 | @Override 91 | public boolean equals(Object object){ 92 | return super.equals(object); 93 | } 94 | 95 | @Override 96 | protected boolean onEquals(SimpleSession ss){ 97 | return super.onEquals(ss); 98 | } 99 | 100 | @Override 101 | public int hashCode(){ 102 | return super.hashCode(); 103 | } 104 | 105 | @Override 106 | public String toString(){ 107 | return super.toString(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /UI/src/views/dashboard/wordCountPanel.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 35 | 36 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/dto/PermissionDto.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.dto; 2 | 3 | import com.zhuxs.result.domain.enums.ActionType; 4 | import com.zhuxs.result.domain.enums.ResourceType; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Created by shusesshou on 2017/9/25. 10 | */ 11 | public class PermissionDto implements Serializable{ 12 | private long id; 13 | private String name; 14 | private String resource; 15 | private ResourceType resourceType; 16 | private ActionType action; 17 | 18 | public PermissionDto() { 19 | } 20 | 21 | public PermissionDto(String name, String resource, ResourceType resourceType) { 22 | this.name = name; 23 | this.resource = resource; 24 | this.resourceType = resourceType; 25 | } 26 | 27 | public PermissionDto(long id, String name, String resource, ResourceType resourceType) { 28 | this.id = id; 29 | this.name = name; 30 | this.resource = resource; 31 | this.resourceType = resourceType; 32 | } 33 | 34 | public PermissionDto(long id, String name, String resource, ResourceType resourceType, ActionType action) { 35 | this.id = id; 36 | this.name = name; 37 | this.resource = resource; 38 | this.resourceType = resourceType; 39 | this.action = action; 40 | } 41 | 42 | public String getName() { 43 | return name; 44 | } 45 | 46 | public void setName(String name) { 47 | this.name = name; 48 | } 49 | 50 | public String getResource() { 51 | return resource; 52 | } 53 | 54 | public void setResource(String resource) { 55 | this.resource = resource; 56 | } 57 | 58 | public ResourceType getResourceType() { 59 | return resourceType; 60 | } 61 | 62 | public void setResourceType(ResourceType resourceType) { 63 | this.resourceType = resourceType; 64 | } 65 | 66 | public long getId() { 67 | return id; 68 | } 69 | 70 | public void setId(long id) { 71 | this.id = id; 72 | } 73 | 74 | public ActionType getAction() { 75 | return action; 76 | } 77 | 78 | public void setAction(ActionType action) { 79 | this.action = action; 80 | } 81 | 82 | @Override 83 | public boolean equals(Object o) { 84 | if (this == o) return true; 85 | if (o == null || getClass() != o.getClass()) return false; 86 | 87 | PermissionDto that = (PermissionDto) o; 88 | 89 | if (id != that.id) return false; 90 | if (name != null ? !name.equals(that.name) : that.name != null) return false; 91 | if (resource != null ? !resource.equals(that.resource) : that.resource != null) return false; 92 | if (resourceType != that.resourceType) return false; 93 | return action == that.action; 94 | } 95 | 96 | @Override 97 | public int hashCode() { 98 | int result = (int) (id ^ (id >>> 32)); 99 | result = 31 * result + (name != null ? name.hashCode() : 0); 100 | result = 31 * result + (resource != null ? resource.hashCode() : 0); 101 | result = 31 * result + (resourceType != null ? resourceType.hashCode() : 0); 102 | result = 31 * result + (action != null ? action.hashCode() : 0); 103 | return result; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/entity/Job.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.entity; 2 | 3 | import com.zhuxs.result.domain.enums.JobStatus; 4 | 5 | import javax.persistence.*; 6 | import javax.validation.constraints.NotNull; 7 | import java.sql.Timestamp; 8 | 9 | /** 10 | * Created by shusesshou on 2017/9/15. 11 | */ 12 | @Entity 13 | @Table(name = "RESULT_JOB") 14 | public class Job { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.AUTO) 17 | private Long id; 18 | 19 | @Column(name = "type") 20 | @NotNull 21 | private Integer type; 22 | 23 | @Column(name = "start_time") 24 | @NotNull 25 | private Timestamp startDate; 26 | 27 | @Column(name = "end_time") 28 | private Timestamp endDate; 29 | 30 | @Column(name = "status") 31 | @NotNull 32 | private JobStatus status; 33 | 34 | @ManyToOne(cascade = CascadeType.MERGE) 35 | @JoinColumn(name = "user_id") 36 | private User user; 37 | 38 | public JobStatus getStatus() { 39 | return status; 40 | } 41 | 42 | public void setStatus(JobStatus status) { 43 | this.status = status; 44 | } 45 | 46 | public Job(int type, Timestamp startDate, JobStatus status) { 47 | this.type = type; 48 | this.startDate = startDate; 49 | this.status = status; 50 | } 51 | 52 | public Job() { 53 | } 54 | 55 | public Long getId() { 56 | return id; 57 | } 58 | 59 | public void setId(Long id) { 60 | this.id = id; 61 | } 62 | 63 | public Integer getType() { 64 | return type; 65 | } 66 | 67 | public void setType(Integer type) { 68 | this.type = type; 69 | } 70 | 71 | public Timestamp getStartDate() { 72 | return startDate; 73 | } 74 | 75 | public void setStartDate(Timestamp startDate) { 76 | this.startDate = startDate; 77 | } 78 | 79 | public Timestamp getEndDate() { 80 | return endDate; 81 | } 82 | 83 | public void setEndDate(Timestamp endDate) { 84 | this.endDate = endDate; 85 | } 86 | 87 | public User getUser() { 88 | return user; 89 | } 90 | 91 | public void setUser(User user) { 92 | this.user = user; 93 | } 94 | 95 | @Override 96 | public boolean equals(Object o) { 97 | if (this == o) return true; 98 | if (o == null || getClass() != o.getClass()) return false; 99 | 100 | Job job = (Job) o; 101 | 102 | if (id != null ? !id.equals(job.id) : job.id != null) return false; 103 | if (type != null ? !type.equals(job.type) : job.type != null) return false; 104 | if (startDate != null ? !startDate.equals(job.startDate) : job.startDate != null) return false; 105 | if (endDate != null ? !endDate.equals(job.endDate) : job.endDate != null) return false; 106 | if (status != job.status) return false; 107 | return user != null ? user.equals(job.user) : job.user == null; 108 | } 109 | 110 | @Override 111 | public int hashCode() { 112 | int result = id != null ? id.hashCode() : 0; 113 | result = 31 * result + (type != null ? type.hashCode() : 0); 114 | result = 31 * result + (startDate != null ? startDate.hashCode() : 0); 115 | result = 31 * result + (endDate != null ? endDate.hashCode() : 0); 116 | result = 31 * result + (status != null ? status.hashCode() : 0); 117 | result = 31 * result + (user != null ? user.hashCode() : 0); 118 | return result; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/entity/Permission.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.entity; 2 | 3 | import com.zhuxs.result.domain.enums.ActionType; 4 | import com.zhuxs.result.domain.enums.ResourceType; 5 | 6 | import javax.persistence.*; 7 | import javax.validation.constraints.NotNull; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by shusesshou on 2017/9/19. 13 | */ 14 | @Entity 15 | @Table(name = "permission") 16 | public class Permission { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.AUTO) 20 | private Long id; 21 | 22 | @Column(name = "name") 23 | @NotNull 24 | private String name; 25 | 26 | /** 27 | * 资源url 28 | */ 29 | @Column(name = "url") 30 | @NotNull 31 | private String resource; 32 | 33 | /** 34 | * 操作类型 35 | */ 36 | @Column(name = "action") 37 | @NotNull 38 | private ActionType action; 39 | 40 | @Column(name = "type") 41 | @NotNull 42 | private ResourceType type; 43 | 44 | @ManyToMany(mappedBy = "permissions",fetch = FetchType.LAZY) 45 | private List roles = new ArrayList<>(); 46 | 47 | @ManyToMany(mappedBy = "permissions",fetch = FetchType.LAZY) 48 | private List users = new ArrayList<>(); 49 | 50 | public Permission() { 51 | } 52 | 53 | public Permission(String name, String resource, ResourceType type) { 54 | this.name = name; 55 | this.resource = resource; 56 | this.type = type; 57 | } 58 | 59 | public Long getId() { 60 | return id; 61 | } 62 | 63 | public void setId(Long id) { 64 | this.id = id; 65 | } 66 | 67 | public String getName() { 68 | return name; 69 | } 70 | 71 | public void setName(String name) { 72 | this.name = name; 73 | } 74 | 75 | public ResourceType getType() { 76 | return type; 77 | } 78 | 79 | public void setType(ResourceType type) { 80 | this.type = type; 81 | } 82 | 83 | public String getResource() { 84 | return resource; 85 | } 86 | 87 | public void setResource(String resource) { 88 | this.resource = resource; 89 | } 90 | 91 | public ActionType getAction() { 92 | return action; 93 | } 94 | 95 | public void setAction(ActionType action) { 96 | this.action = action; 97 | } 98 | 99 | public List getRoles() { 100 | return roles; 101 | } 102 | 103 | public void setRoles(List roles) { 104 | this.roles = roles; 105 | } 106 | 107 | public List getUsers() { 108 | return users; 109 | } 110 | 111 | public void setUsers(List users) { 112 | this.users = users; 113 | } 114 | 115 | @Override 116 | public boolean equals(Object o) { 117 | if (this == o) return true; 118 | if (o == null || getClass() != o.getClass()) return false; 119 | 120 | Permission that = (Permission) o; 121 | 122 | if (id != null ? !id.equals(that.id) : that.id != null) return false; 123 | if (name != null ? !name.equals(that.name) : that.name != null) return false; 124 | if (resource != null ? !resource.equals(that.resource) : that.resource != null) return false; 125 | if (action != that.action) return false; 126 | return type == that.type; 127 | } 128 | 129 | @Override 130 | public int hashCode() { 131 | int result = id != null ? id.hashCode() : 0; 132 | result = 31 * result + (name != null ? name.hashCode() : 0); 133 | result = 31 * result + (resource != null ? resource.hashCode() : 0); 134 | result = 31 * result + (action != null ? action.hashCode() : 0); 135 | result = 31 * result + (type != null ? type.hashCode() : 0); 136 | return result; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.zhuxs 7 | result 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | result 12 | You give me a word, I give you all 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.6.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | 38 | mysql 39 | mysql-connector-java 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-test 44 | test 45 | 46 | 47 | 48 | org.apache.spark 49 | spark-core_2.11 50 | 2.1.1 51 | 52 | 53 | 54 | org.apache.spark 55 | spark-sql_2.11 56 | 2.1.1 57 | 58 | 59 | 60 | org.codehaus.janino 61 | janino 62 | 2.7.8 63 | 64 | 65 | 66 | org.scala-lang 67 | scala-library 68 | 2.11.8 69 | 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-starter-redis 74 | 75 | 76 | 77 | org.apache.shiro 78 | shiro-spring 79 | 1.4.0 80 | 81 | 82 | 83 | 84 | joda-time 85 | joda-time 86 | 2.9.9 87 | 88 | 89 | 90 | 91 | org.modelmapper 92 | modelmapper 93 | 0.7.5 94 | 95 | 96 | org.apdplat 97 | word 98 | 1.3 99 | 100 | 101 | org.slf4j 102 | slf4j-log4j12 103 | 104 | 105 | ch.qos.logback 106 | logback-classic 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | org.springframework.boot 116 | spring-boot-maven-plugin 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/entity/Role.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.entity; 2 | 3 | import org.hibernate.annotations.CollectionId; 4 | import org.hibernate.annotations.Type; 5 | 6 | import javax.persistence.*; 7 | import javax.validation.constraints.NotNull; 8 | import java.io.Serializable; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Created by shusesshou on 2017/9/19. 14 | */ 15 | @Entity 16 | @Table(name = "role") 17 | public class Role implements Serializable{ 18 | 19 | @Id 20 | @Column(name = "id") 21 | @GeneratedValue(strategy = GenerationType.AUTO) 22 | private Long id; 23 | 24 | @Column(name = "name") 25 | @NotNull 26 | private String name; 27 | 28 | @Column(name = "description") 29 | private String desc; 30 | 31 | @Column(name = "available") 32 | @NotNull 33 | private Boolean available = Boolean.FALSE; 34 | 35 | @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY) 36 | private List users = new ArrayList<>(); 37 | 38 | @ManyToMany(cascade = CascadeType.MERGE,fetch = FetchType.LAZY) 39 | @JoinTable(name = "role_permission", 40 | joinColumns = {@JoinColumn(name = "roleId",referencedColumnName = "id")}, 41 | inverseJoinColumns = {@JoinColumn(name = "permissionId",referencedColumnName = "id")}) 42 | @CollectionId(columns = @Column(name = "id"), 43 | type = @Type(type = "long"), 44 | generator = "identity") 45 | private List permissions = new ArrayList<>(); 46 | 47 | public Role() { 48 | } 49 | 50 | public Role(String name, String desc, Boolean available) { 51 | this.name = name; 52 | this.desc = desc; 53 | this.available = available; 54 | } 55 | 56 | public Long getId() { 57 | return id; 58 | } 59 | 60 | public void setId(Long id) { 61 | this.id = id; 62 | } 63 | 64 | public String getName() { 65 | return name; 66 | } 67 | 68 | public void setName(String name) { 69 | this.name = name; 70 | } 71 | 72 | public String getDesc() { 73 | return desc; 74 | } 75 | 76 | public void setDesc(String desc) { 77 | this.desc = desc; 78 | } 79 | 80 | public Boolean getAvailable() { 81 | return available; 82 | } 83 | 84 | public void setAvailable(Boolean available) { 85 | this.available = available; 86 | } 87 | 88 | public List getUsers() { 89 | return users; 90 | } 91 | 92 | public void setUsers(List users) { 93 | this.users = users; 94 | } 95 | 96 | @Override 97 | public boolean equals(Object o) { 98 | if (this == o) return true; 99 | if (o == null || getClass() != o.getClass()) return false; 100 | 101 | Role role = (Role) o; 102 | 103 | if (id != null ? !id.equals(role.id) : role.id != null) return false; 104 | if (name != null ? !name.equals(role.name) : role.name != null) return false; 105 | if (desc != null ? !desc.equals(role.desc) : role.desc != null) return false; 106 | if (available != null ? !available.equals(role.available) : role.available != null) return false; 107 | if (users != null ? !users.equals(role.users) : role.users != null) return false; 108 | return permissions != null ? permissions.equals(role.permissions) : role.permissions == null; 109 | } 110 | 111 | @Override 112 | public int hashCode() { 113 | int result = id != null ? id.hashCode() : 0; 114 | result = 31 * result + (name != null ? name.hashCode() : 0); 115 | result = 31 * result + (desc != null ? desc.hashCode() : 0); 116 | result = 31 * result + (available != null ? available.hashCode() : 0); 117 | result = 31 * result + (users != null ? users.hashCode() : 0); 118 | result = 31 * result + (permissions != null ? permissions.hashCode() : 0); 119 | return result; 120 | } 121 | 122 | public List getPermissions() { 123 | 124 | return permissions; 125 | } 126 | 127 | public void setPermissions(List permissions) { 128 | this.permissions = permissions; 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/dto/UserDto.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.dto; 2 | 3 | import javax.validation.constraints.Max; 4 | import java.io.Serializable; 5 | import java.util.List; 6 | 7 | /** 8 | * Created by shusesshou on 2017/9/22. 9 | */ 10 | public class UserDto implements Serializable{ 11 | private long id; 12 | private String name; 13 | 14 | private String username; 15 | private String password; 16 | private String salt; 17 | private List roles; 18 | private List permissions; 19 | 20 | public UserDto() { 21 | } 22 | 23 | public UserDto(String username, String password) { 24 | this.username = username; 25 | this.password = password; 26 | } 27 | 28 | public UserDto(String name, String username, String password) { 29 | this.name = name; 30 | this.username = username; 31 | this.password = password; 32 | } 33 | 34 | public UserDto(long id, String name, String username, String password) { 35 | this.id = id; 36 | this.name = name; 37 | this.username = username; 38 | this.password = password; 39 | } 40 | 41 | public UserDto(long id, String name, String username, String password, List roles) { 42 | this.id = id; 43 | this.name = name; 44 | this.username = username; 45 | this.password = password; 46 | this.roles = roles; 47 | } 48 | 49 | public UserDto(long id, String name, String username, String password, String salt) { 50 | this.id = id; 51 | this.name = name; 52 | this.username = username; 53 | this.password = password; 54 | this.salt = salt; 55 | } 56 | 57 | public UserDto(long id, String name, String username, String password, String salt, List roles) { 58 | this.id = id; 59 | this.name = name; 60 | this.username = username; 61 | this.password = password; 62 | this.salt = salt; 63 | this.roles = roles; 64 | } 65 | 66 | public String getUsername() { 67 | return username; 68 | } 69 | 70 | public void setUsername(String username) { 71 | this.username = username; 72 | } 73 | 74 | public String getPassword() { 75 | return password; 76 | } 77 | 78 | public void setPassword(String password) { 79 | this.password = password; 80 | } 81 | 82 | public String getName() { 83 | return name; 84 | } 85 | 86 | public void setName(String name) { 87 | this.name = name; 88 | } 89 | 90 | public long getId() { 91 | return id; 92 | } 93 | 94 | public void setId(long id) { 95 | this.id = id; 96 | } 97 | 98 | public List getRoles() { 99 | return roles; 100 | } 101 | 102 | public void setRoles(List roles) { 103 | this.roles = roles; 104 | } 105 | 106 | public String getSalt() { 107 | return salt; 108 | } 109 | 110 | public void setSalt(String salt) { 111 | this.salt = salt; 112 | } 113 | 114 | public List getPermissions() { 115 | return permissions; 116 | } 117 | 118 | public void setPermissions(List permissions) { 119 | this.permissions = permissions; 120 | } 121 | 122 | @Override 123 | public boolean equals(Object o) { 124 | if (this == o) return true; 125 | if (o == null || getClass() != o.getClass()) return false; 126 | 127 | UserDto userDto = (UserDto) o; 128 | 129 | if (id != userDto.id) return false; 130 | if (name != null ? !name.equals(userDto.name) : userDto.name != null) return false; 131 | if (username != null ? !username.equals(userDto.username) : userDto.username != null) return false; 132 | if (password != null ? !password.equals(userDto.password) : userDto.password != null) return false; 133 | return salt != null ? salt.equals(userDto.salt) : userDto.salt == null; 134 | } 135 | 136 | @Override 137 | public int hashCode() { 138 | int result = (int) (id ^ (id >>> 32)); 139 | result = 31 * result + (name != null ? name.hashCode() : 0); 140 | result = 31 * result + (username != null ? username.hashCode() : 0); 141 | result = 31 * result + (password != null ? password.hashCode() : 0); 142 | result = 31 * result + (salt != null ? salt.hashCode() : 0); 143 | return result; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/service/impl/WordCountServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.service.impl; 2 | 3 | import com.zhuxs.result.exception.ResultException; 4 | import com.zhuxs.result.bo.Count; 5 | import com.zhuxs.result.bo.Word; 6 | import com.zhuxs.result.bo.comparator.CountComparator; 7 | import com.zhuxs.result.domain.JobDao; 8 | import com.zhuxs.result.domain.entity.Job; 9 | import com.zhuxs.result.domain.enums.ErrorCode; 10 | import com.zhuxs.result.domain.enums.JobStatus; 11 | import com.zhuxs.result.domain.enums.JobTypeEnum; 12 | import com.zhuxs.result.utils.RegsUtil; 13 | import com.zhuxs.result.service.WordCountService; 14 | import org.apache.spark.api.java.JavaSparkContext; 15 | import org.apache.spark.sql.Dataset; 16 | import org.apache.spark.sql.RelationalGroupedDataset; 17 | import org.apache.spark.sql.Row; 18 | import org.apache.spark.sql.SparkSession; 19 | import org.apdplat.word.WordSegmenter; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.stereotype.Service; 22 | 23 | import java.sql.Timestamp; 24 | import java.util.Arrays; 25 | import java.util.List; 26 | import java.util.function.Function; 27 | import java.util.stream.Collectors; 28 | 29 | import static org.apache.spark.sql.functions.col; 30 | 31 | /** 32 | * Created by shusesshou on 2017/9/4. 33 | */ 34 | @Service 35 | public class WordCountServiceImpl implements WordCountService { 36 | @Autowired 37 | private JavaSparkContext javaSparkContext; 38 | @Autowired 39 | private SparkSession sparkSession; 40 | 41 | @Autowired 42 | private JobDao jobDao; 43 | 44 | public List wordCount(String words) throws ResultException{ 45 | //declare the var 46 | String[] tempWords = {}; 47 | Dataset dataFrame; 48 | Timestamp start = new Timestamp(System.currentTimeMillis()); 49 | Timestamp end; 50 | Job job = new Job(JobTypeEnum.WORDCOUNT_SIM,start, JobStatus.WAITING); 51 | job = jobDao.save(job); 52 | //format the words 53 | try{ 54 | words = RegsUtil.filterString(words); 55 | List segWords = WordSegmenter.seg(words); 56 | tempWords = segWords.stream() 57 | .map(word -> { 58 | return word.getText(); 59 | }) 60 | .collect(Collectors.toList()) 61 | .toArray(new String[segWords.size()]); 62 | }catch (Exception e){ 63 | end = new Timestamp(System.currentTimeMillis()); 64 | job.setEndDate(end); 65 | job.setStatus(JobStatus.FAILED); 66 | job = jobDao.save(job); 67 | throw new ResultException("Illegal Input",e, ErrorCode.ERROR); 68 | } 69 | 70 | //create the dataframe 71 | try{ 72 | job.setStatus(JobStatus.RUNNING); 73 | job = jobDao.save(job); 74 | List wordList = Arrays.stream(tempWords).map(Word::new).collect(Collectors.toList()); 75 | dataFrame = sparkSession.createDataFrame(wordList,Word.class); 76 | dataFrame.show(); 77 | }catch (Exception e){ 78 | end = new Timestamp(System.currentTimeMillis()); 79 | job.setEndDate(end); 80 | job.setStatus(JobStatus.FAILED); 81 | job = jobDao.save(job); 82 | throw new ResultException("CreateDataFrame Error",e,ErrorCode.ERROR); 83 | } 84 | 85 | //count 86 | try{ 87 | RelationalGroupedDataset groupedDataset = dataFrame.groupBy(col("word")); 88 | List rows = groupedDataset.count().collectAsList(); 89 | end = new Timestamp(System.currentTimeMillis()); 90 | job.setEndDate(end); 91 | job.setStatus(JobStatus.SUCCESS); 92 | job = jobDao.save(job); 93 | return rows.stream().map(new Function() { 94 | @Override 95 | public Count apply(Row row) { 96 | return new Count(row.getString(0),row.getLong(1)); 97 | } 98 | }).sorted(new CountComparator()).collect(Collectors.toList()); 99 | 100 | }catch (Exception e){ 101 | end = new Timestamp(System.currentTimeMillis()); 102 | job.setEndDate(end); 103 | job.setStatus(JobStatus.FAILED); 104 | job = jobDao.save(job); 105 | throw new ResultException("Count Error",e,ErrorCode.ERROR); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/controller/AuthController.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.controller; 2 | 3 | import com.zhuxs.result.domain.entity.Role; 4 | import com.zhuxs.result.dto.RoleDto; 5 | import com.zhuxs.result.exception.ResultException; 6 | import com.zhuxs.result.domain.entity.User; 7 | import com.zhuxs.result.domain.enums.ErrorCode; 8 | import com.zhuxs.result.dto.UserDto; 9 | import com.zhuxs.result.utils.ApplicationUtil; 10 | import org.apache.shiro.SecurityUtils; 11 | import org.apache.shiro.authc.AuthenticationException; 12 | import org.apache.shiro.authc.UsernamePasswordToken; 13 | import org.apache.shiro.subject.Subject; 14 | import org.modelmapper.ModelMapper; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.http.HttpHeaders; 19 | import org.springframework.http.HttpStatus; 20 | import org.springframework.http.ResponseEntity; 21 | import org.springframework.web.bind.annotation.GetMapping; 22 | import org.springframework.web.bind.annotation.PostMapping; 23 | import org.springframework.web.bind.annotation.RequestBody; 24 | import org.springframework.web.bind.annotation.RestController; 25 | import org.springframework.web.util.UriComponentsBuilder; 26 | 27 | import javax.transaction.Transactional; 28 | import java.util.List; 29 | import java.util.stream.Collectors; 30 | 31 | /** 32 | * Created by shusesshou on 2017/9/22. 33 | */ 34 | @RestController 35 | public class AuthController { 36 | private Logger logger = LoggerFactory.getLogger(this.getClass()); 37 | public static final String SUBPATH_LOGIN = "/login"; 38 | public static final String SUBPATH_USERINFO = "/userInfo"; 39 | @Autowired 40 | private ModelMapper modelMapper; 41 | 42 | @PostMapping(value = SUBPATH_LOGIN) 43 | public ResponseEntity login(@RequestBody UserDto userDto, 44 | UriComponentsBuilder uriComponentsBuilder){ 45 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,SUBPATH_LOGIN); 46 | logger.info("================userInfo================username: " + userDto.getUsername() + ",pw: " + userDto.getPassword()); 47 | Subject subject = SecurityUtils.getSubject(); 48 | UsernamePasswordToken token = new UsernamePasswordToken(userDto.getUsername(),userDto.getPassword()); 49 | //User user = new User("root","root","root","root"); 50 | //userDao.save(user); 51 | try{ 52 | subject.login(token); 53 | } catch (AuthenticationException e){ 54 | logger.error("======登录失败======"); 55 | throw new ResultException(ErrorCode.USERNAMEORPASSWORD.getDesc(),ErrorCode.USERNAMEORPASSWORD); 56 | } 57 | UserDto loginUserDto = (UserDto) SecurityUtils.getSubject().getSession().getAttribute("user"); 58 | 59 | return new ResponseEntity<>(loginUserDto,headers, HttpStatus.OK); 60 | } 61 | 62 | @GetMapping(value = SUBPATH_USERINFO) 63 | public ResponseEntity getUserInfo(UriComponentsBuilder uriComponentsBuilder){ 64 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,SUBPATH_USERINFO); 65 | UserDto userDto = (UserDto) SecurityUtils.getSubject().getSession().getAttribute("user"); 66 | 67 | return new ResponseEntity(userDto,headers,HttpStatus.OK); 68 | } 69 | 70 | @GetMapping(value = "notAuthc") 71 | public void notAuthc(UriComponentsBuilder uriComponentsBuilder){ 72 | throw new ResultException("Not Authc", ErrorCode.NOTAUTHC); 73 | } 74 | 75 | @GetMapping(value = "notAuthz") 76 | public void notAuthz(UriComponentsBuilder uriComponentsBuilder){ 77 | UserDto loginUserDto = (UserDto) SecurityUtils.getSubject().getSession().getAttribute("user"); 78 | throw new ResultException( 79 | "UserName: " + loginUserDto.getName() 80 | + "\nPermissions: " + loginUserDto.getPermissions().toString() 81 | + "\nRoles: " + loginUserDto.getRoles().toString() 82 | , ErrorCode.NOTAUTHC); 83 | } 84 | 85 | private UserDto convertToDto(User user){ 86 | //return modelMapper.map(user,UserDto.class); 87 | UserDto userDto = new UserDto(); 88 | userDto.setId(user.getId()); 89 | userDto.setName(user.getName()); 90 | userDto.setUsername(user.getUsername()); 91 | List roles = user.getRoles(); 92 | userDto.setRoles(roles.stream() 93 | .map(role -> { 94 | return convertToDto(role); 95 | }) 96 | .collect(Collectors.toList())); 97 | 98 | return userDto; 99 | } 100 | 101 | private RoleDto convertToDto(Role role){ 102 | RoleDto roleDto = new RoleDto(); 103 | roleDto.setName(role.getName()); 104 | return roleDto; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/shiro/ShiroRealm.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.shiro; 2 | 3 | import com.zhuxs.result.domain.PermissionDao; 4 | import com.zhuxs.result.domain.UserDao; 5 | import com.zhuxs.result.domain.entity.Permission; 6 | import com.zhuxs.result.domain.entity.Role; 7 | import com.zhuxs.result.domain.entity.User; 8 | import com.zhuxs.result.dto.PermissionDto; 9 | import com.zhuxs.result.dto.RoleDto; 10 | import com.zhuxs.result.dto.UserDto; 11 | import org.apache.shiro.SecurityUtils; 12 | import org.apache.shiro.authc.*; 13 | import org.apache.shiro.authz.AuthorizationInfo; 14 | import org.apache.shiro.authz.SimpleAuthorizationInfo; 15 | import org.apache.shiro.realm.AuthorizingRealm; 16 | import org.apache.shiro.session.Session; 17 | import org.apache.shiro.subject.PrincipalCollection; 18 | import org.modelmapper.ModelMapper; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | 23 | import javax.transaction.Transactional; 24 | import java.io.Serializable; 25 | import java.util.List; 26 | import java.util.stream.Collectors; 27 | 28 | /** 29 | * Created by shusesshou on 2017/9/20. 30 | */ 31 | public class ShiroRealm extends AuthorizingRealm{ 32 | private Logger logger = LoggerFactory.getLogger(this.getClass()); 33 | 34 | @Autowired 35 | private UserDao userDao; 36 | @Autowired 37 | private PermissionDao permissionDao; 38 | @Autowired 39 | private ShiroSessionDao shiroSessionDao; 40 | @Autowired 41 | private ModelMapper modelMapper; 42 | 43 | @Override 44 | //@org.springframework.transaction.annotation.Transactional 45 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 46 | //获取当前用户 47 | //UserDto user = convertToDto(userDao.findUserByUsername((String)principalCollection.getPrimaryPrincipal())); 48 | //User currentUser = userDao.findUserByUsername((String)principalCollection.getPrimaryPrincipal()); 49 | UserDto user = (UserDto) SecurityUtils.getSubject().getSession().getAttribute("user"); 50 | 51 | //把principals放session中,key=userId value=principals 52 | SecurityUtils.getSubject().getSession().setAttribute(String.valueOf(user.getId()),SecurityUtils.getSubject().getPrincipals()); 53 | 54 | SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 55 | //赋予角色 56 | for(RoleDto role:user.getRoles()){ 57 | info.addRole(role.getName()); 58 | } 59 | //赋予权限 60 | for(PermissionDto permission:user.getPermissions()){ 61 | //System.out.println(permission.getName()); 62 | info.addStringPermission(permission.getName()); 63 | } 64 | return info; 65 | } 66 | 67 | @Override 68 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { 69 | UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; 70 | String userName = token.getUsername(); 71 | 72 | User user = userDao.findUserByUsername(userName); 73 | UserDto userDto = convertToDto(user); 74 | if(user != null){ 75 | //登陆成功 76 | Session session = SecurityUtils.getSubject().getSession(); 77 | session.setAttribute("user",userDto); 78 | session.setAttribute("id",user.getId()); 79 | session.setAttribute("username",user.getUsername()); 80 | session.setAttribute("name",user.getName()); 81 | return new SimpleAuthenticationInfo( 82 | userName, //用户 83 | user.getPassword(), //密码 84 | getName() //realm name 85 | ); 86 | } else { 87 | throw new UnknownAccountException(); 88 | } 89 | } 90 | 91 | private UserDto convertToDto(User user){ 92 | //return modelMapper.map(user,UserDto.class); 93 | UserDto userDto = new UserDto(); 94 | userDto.setId(user.getId()); 95 | userDto.setName(user.getName()); 96 | userDto.setUsername(user.getUsername()); 97 | List roles = user.getRoles(); 98 | List permissions = user.getPermissions(); 99 | userDto.setRoles(roles.stream() 100 | .map(role -> { 101 | return convertToDto(role); 102 | }) 103 | .collect(Collectors.toList())); 104 | userDto.setPermissions(permissions.stream() 105 | .map(permission -> { 106 | return convertToDto(permission); 107 | }) 108 | .collect(Collectors.toList())); 109 | 110 | return userDto; 111 | } 112 | 113 | private RoleDto convertToDto(Role role){ 114 | RoleDto roleDto = new RoleDto(); 115 | roleDto.setName(role.getName()); 116 | return roleDto; 117 | } 118 | 119 | private PermissionDto convertToDto(Permission permission){ 120 | return modelMapper.map(permission,PermissionDto.class); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /UI/src/views/admin/roleInfoPanel.vue: -------------------------------------------------------------------------------- 1 | 23 | 30 | 148 | -------------------------------------------------------------------------------- /Server/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/domain/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.domain.entity; 2 | 3 | import com.zhuxs.result.domain.enums.UserStatus; 4 | import org.hibernate.annotations.CollectionId; 5 | import org.hibernate.annotations.Fetch; 6 | import org.hibernate.annotations.FetchMode; 7 | import org.hibernate.annotations.Type; 8 | 9 | import javax.persistence.*; 10 | import javax.validation.constraints.NotNull; 11 | import java.io.Serializable; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by shusesshou on 2017/9/19. 17 | */ 18 | @Entity 19 | @Table(name = "user") 20 | public class User implements Serializable{ 21 | @Id 22 | @Column(name = "id") 23 | @GeneratedValue(strategy = GenerationType.AUTO) 24 | private Long id; 25 | 26 | @Column(unique = true, name = "user_name") 27 | @NotNull 28 | private String username; 29 | 30 | @Column(unique = true, name = "name") 31 | @NotNull 32 | private String name; 33 | 34 | @Column(name = "password") 35 | @NotNull 36 | private String password; 37 | 38 | @Column(name = "salt") 39 | @NotNull 40 | private String salt; 41 | 42 | @Column(name = "status") 43 | @NotNull 44 | private UserStatus status = UserStatus.CREATE; 45 | 46 | @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY) 47 | @JoinTable(name = "user_role", 48 | joinColumns = {@JoinColumn(name = "userId",referencedColumnName = "id")}, 49 | inverseJoinColumns = {@JoinColumn(name = "roleId",referencedColumnName = "id")}) 50 | private List roles = new ArrayList<>(); 51 | 52 | @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY) 53 | @JoinTable(name = "user_permission", 54 | joinColumns = {@JoinColumn(name = "userId",referencedColumnName = "id")}, 55 | inverseJoinColumns = {@JoinColumn(name = "permissionId",referencedColumnName = "id")}) 56 | private List permissions = new ArrayList<>(); 57 | 58 | @OneToMany(cascade = CascadeType.ALL, mappedBy = "user",fetch = FetchType.LAZY) 59 | @Fetch(value = FetchMode.SUBSELECT) 60 | private List jobs = new ArrayList<>(); 61 | 62 | public User() { 63 | } 64 | 65 | public Long getId() { 66 | return id; 67 | } 68 | 69 | public void setId(Long id) { 70 | this.id = id; 71 | } 72 | 73 | public String getUsername() { 74 | return username; 75 | } 76 | 77 | public void setUsername(String username) { 78 | this.username = username; 79 | } 80 | 81 | public String getName() { 82 | return name; 83 | } 84 | 85 | public void setName(String name) { 86 | this.name = name; 87 | } 88 | 89 | public String getPassword() { 90 | return password; 91 | } 92 | 93 | public void setPassword(String password) { 94 | this.password = password; 95 | } 96 | 97 | public String getSalt() { 98 | return salt; 99 | } 100 | 101 | public void setSalt(String salt) { 102 | this.salt = salt; 103 | } 104 | 105 | public UserStatus getStatus() { 106 | return status; 107 | } 108 | 109 | public void setStatus(UserStatus status) { 110 | this.status = status; 111 | } 112 | 113 | public List getRoles() { 114 | return roles; 115 | } 116 | 117 | public void setRoles(List roles) { 118 | this.roles = roles; 119 | } 120 | 121 | public List getJobs() { 122 | return jobs; 123 | } 124 | 125 | public void setJobs(List jobs) { 126 | this.jobs = jobs; 127 | } 128 | 129 | public User(String username, String name, String password, String salt) { 130 | this.username = username; 131 | this.name = name; 132 | this.password = password; 133 | this.salt = salt; 134 | } 135 | 136 | public List getPermissions() { 137 | return permissions; 138 | } 139 | 140 | public void setPermissions(List permissions) { 141 | this.permissions = permissions; 142 | } 143 | 144 | @Override 145 | public boolean equals(Object o) { 146 | if (this == o) return true; 147 | if (o == null || getClass() != o.getClass()) return false; 148 | 149 | User user = (User) o; 150 | 151 | if (id != null ? !id.equals(user.id) : user.id != null) return false; 152 | if (username != null ? !username.equals(user.username) : user.username != null) return false; 153 | if (name != null ? !name.equals(user.name) : user.name != null) return false; 154 | if (password != null ? !password.equals(user.password) : user.password != null) return false; 155 | if (salt != null ? !salt.equals(user.salt) : user.salt != null) return false; 156 | if (status != user.status) return false; 157 | if (roles != null ? !roles.equals(user.roles) : user.roles != null) return false; 158 | return jobs != null ? jobs.equals(user.jobs) : user.jobs == null; 159 | } 160 | 161 | @Override 162 | public int hashCode() { 163 | int result = id != null ? id.hashCode() : 0; 164 | result = 31 * result + (username != null ? username.hashCode() : 0); 165 | result = 31 * result + (name != null ? name.hashCode() : 0); 166 | result = 31 * result + (password != null ? password.hashCode() : 0); 167 | result = 31 * result + (salt != null ? salt.hashCode() : 0); 168 | result = 31 * result + (status != null ? status.hashCode() : 0); 169 | result = 31 * result + (roles != null ? roles.hashCode() : 0); 170 | result = 31 * result + (jobs != null ? jobs.hashCode() : 0); 171 | return result; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /UI/src/views/admin/permissionInfoPanel.vue: -------------------------------------------------------------------------------- 1 | 30 | 37 | 159 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/config/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.config; 2 | 3 | import com.zhuxs.result.shiro.ShiroSessionDao; 4 | import com.zhuxs.result.shiro.ShiroRealm; 5 | import com.zhuxs.result.shiro.ShiroSessionFactory; 6 | import org.apache.shiro.authc.credential.HashedCredentialsMatcher; 7 | import org.apache.shiro.spring.LifecycleBeanPostProcessor; 8 | import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 9 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 10 | import org.apache.shiro.web.filter.authc.LogoutFilter; 11 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 12 | import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; 13 | import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 14 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Configuration; 17 | import org.springframework.context.annotation.DependsOn; 18 | 19 | import javax.servlet.Filter; 20 | import java.util.LinkedHashMap; 21 | import java.util.Map; 22 | 23 | 24 | /** 25 | * Created by shusesshou on 2017/9/20. 26 | */ 27 | @Configuration 28 | public class ShiroConfig { 29 | /** 30 | * LifecycleBeanPostProcessor,DestructionAwareBeanPostProcessor的子类 31 | * 负责org.apache.shiro.util.Initializable类型bean的生命周期,初始化和销毁 32 | * 主要是AuthorizingRealm类的子类,以及EhCacheManager类 33 | */ 34 | @Bean(name = "lifecycleBeanPostProcessor") 35 | public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){ 36 | return new LifecycleBeanPostProcessor(); 37 | } 38 | 39 | /** 40 | * HashCredentialsMatcher,对密码进行编码 41 | */ 42 | @Bean(name = "hashCredentialsMatcher") 43 | public HashedCredentialsMatcher hashedCredentialsMatcher(){ 44 | HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); 45 | credentialsMatcher.setHashAlgorithmName("MD5"); 46 | credentialsMatcher.setHashIterations(2); //散列两次 47 | credentialsMatcher.setStoredCredentialsHexEncoded(true); 48 | return credentialsMatcher; 49 | } 50 | 51 | /** 52 | * ShiroRealm, 自定义的认证类 53 | */ 54 | @Bean(name = "shiroRealm") 55 | @DependsOn("lifecycleBeanPostProcessor") 56 | public ShiroRealm shiroRealm(){ 57 | return new ShiroRealm(); 58 | } 59 | 60 | /** 61 | * CachingShiroSessionDao 62 | */ 63 | @Bean(name = "shiroSessionDao") 64 | public ShiroSessionDao shiroSessionDao(){ 65 | return new ShiroSessionDao(); 66 | } 67 | /** 68 | * EhCacheManager,缓存管理,用户登陆成功后,把用户信息和权限信息缓存起来 69 | */ 70 | @Bean(name = "sessionFactory") 71 | public ShiroSessionFactory shiroSessionFactory() { 72 | return new ShiroSessionFactory(); 73 | } 74 | 75 | @Bean(name = "sessionManager") 76 | public DefaultWebSessionManager sessionManager(){ 77 | DefaultWebSessionManager manager = new DefaultWebSessionManager(); 78 | //manager.setCacheManager(cacheManager);// 加入缓存管理器 79 | manager.setSessionFactory(shiroSessionFactory());//设置sessionFactory 80 | manager.setSessionDAO(shiroSessionDao());// 设置SessionDao 81 | manager.setDeleteInvalidSessions(true);// 删除过期的session 82 | manager.setGlobalSessionTimeout(shiroSessionDao().getExpireTime());// 设置全局session超时时间 83 | manager.setSessionValidationSchedulerEnabled(true);// 是否定时检查session 84 | return manager; 85 | } 86 | 87 | /** 88 | * SecurityManager,权限管理,组合了登录、登出、权限和session的处理 89 | * 90 | */ 91 | @Bean(name = "securityManager") 92 | public DefaultWebSecurityManager securityManager(){ 93 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 94 | //设置Realm 95 | securityManager.setRealm(shiroRealm()); 96 | //设置session管理器 97 | securityManager.setSessionManager(sessionManager()); 98 | return securityManager; 99 | } 100 | 101 | /** 102 | * ShirpFilterFactoryBean, 生成ShiroFilter 103 | * securityManager,filters,filterChainDefinitionManager 104 | */ 105 | @Bean(name = "shiroFilter") 106 | public ShiroFilterFactoryBean shiroFilterFactoryBean(){ 107 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 108 | shiroFilterFactoryBean.setSecurityManager(securityManager()); 109 | 110 | Map filters = new LinkedHashMap(); 111 | LogoutFilter logoutFilter = new LogoutFilter(); 112 | logoutFilter.setRedirectUrl("/login"); 113 | shiroFilterFactoryBean.setFilters(filters); 114 | shiroFilterFactoryBean.setLoginUrl("/notAuthc"); 115 | 116 | Map filterChainDefinitionManager = new LinkedHashMap(); 117 | filterChainDefinitionManager.put("/logout","logout"); 118 | filterChainDefinitionManager.put("/userInfo","authc"); 119 | filterChainDefinitionManager.put("/jobs/**","perms[WORDCOUNT:CREATE]"); 120 | filterChainDefinitionManager.put("/admin/**","roles[Admin]"); 121 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager); 122 | 123 | shiroFilterFactoryBean.setSuccessUrl("/"); 124 | shiroFilterFactoryBean.setUnauthorizedUrl("/notAuthz"); 125 | return shiroFilterFactoryBean; 126 | } 127 | 128 | /** 129 | * 由Advisor决定对哪些类的方法进行AOP代理 130 | */ 131 | @Bean 132 | @ConditionalOnMissingBean 133 | public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){ 134 | DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); 135 | defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); 136 | return defaultAdvisorAutoProxyCreator; 137 | } 138 | 139 | /** 140 | * 141 | */ 142 | @Bean 143 | public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { 144 | AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); 145 | authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); 146 | return authorizationAttributeSourceAdvisor; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Server/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/shiro/ShiroSessionDao.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.shiro; 2 | 3 | import com.zhuxs.result.utils.SerializeUtils; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.apache.shiro.session.Session; 6 | import org.apache.shiro.session.UnknownSessionException; 7 | import org.apache.shiro.session.mgt.ValidatingSession; 8 | import org.apache.shiro.session.mgt.eis.CachingSessionDAO; 9 | import org.apache.shiro.subject.support.DefaultSubjectContext; 10 | import org.apache.shiro.util.CollectionUtils; 11 | import org.joda.time.DateTime; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Service; 16 | import redis.clients.jedis.Jedis; 17 | import redis.clients.jedis.JedisPool; 18 | import redis.clients.jedis.Transaction; 19 | 20 | import java.io.Serializable; 21 | import java.util.Collection; 22 | import java.util.List; 23 | import java.util.Set; 24 | 25 | /** 26 | * Created by shusesshou on 2017/9/22. 27 | * 针对自定义的ShiroSession的Redis CRUD操作,通过isChanged标识符,确定是否需要Update方法 28 | * 通过配置securityManager在属性cacheManager从缓存中查找Session是否存在,如果找不到再调用方法 29 | * Shiro内部相应的组件(DefaultSecurityManager)会自动检测相应的对象(Realm)是否实现了CacheManagerAware并注入相应的CacheManager 30 | */ 31 | @Service 32 | public class ShiroSessionDao extends CachingSessionDAO{ 33 | 34 | private static final Logger logger = LoggerFactory.getLogger(ShiroSessionDao.class); 35 | 36 | //保存到Redis中key的前缀 37 | private String prefix = ""; 38 | 39 | //设置会话的过期时间 40 | private int expireTime = 3600000; 41 | 42 | //特殊配置 只用于没有redis时,将session放到EhCache中 43 | private Boolean onlyEhcache; 44 | 45 | @Autowired 46 | private JedisPool jedisPool; 47 | /** 48 | * 如果session中没有登录信息就调用doReadSession方法从Redis中重读 49 | * session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null 代表没有登录,登录后Shiro会放入该值 50 | * @param sessionId 51 | * @return 52 | * @throws UnknownSessionException 53 | */ 54 | @Override 55 | public Session readSession(Serializable sessionId) throws UnknownSessionException{ 56 | Session session = getCachedSession(sessionId); 57 | if(session == null || session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) == null) { 58 | session = this.doReadSession(sessionId); 59 | if(session == null){ 60 | throw new UnknownSessionException("There is no session with id [" + sessionId + "]"); 61 | }else { 62 | cache(session,session.getId()); 63 | } 64 | } 65 | return session; 66 | } 67 | 68 | /** 69 | * 更新会话 70 | * @param session 71 | */ 72 | @Override 73 | protected void doUpdate(Session session) { 74 | try { 75 | if(session instanceof ValidatingSession && !((ValidatingSession)session).isValid()){ 76 | return; 77 | } 78 | } catch (Exception e){ 79 | logger.error("ValidatingSession error"); 80 | } 81 | try { 82 | if(session instanceof ShiroSession){ 83 | //如果没有字段(除lastAccessTime以外其他字段)发生改变 84 | ShiroSession shiroSession = (ShiroSession) session; 85 | if(!shiroSession.getIsChanged()){ 86 | return; 87 | } 88 | Jedis jedis = null; 89 | Transaction transaction = null; 90 | try { 91 | jedis = jedisPool.getResource(); 92 | //开启事务 93 | transaction = jedis.multi(); 94 | shiroSession.setIsChanged(false); 95 | shiroSession.setLastAccessTime(DateTime.now().toDate()); 96 | transaction.setex(prefix + session.getId(),expireTime,SerializeUtils.serializaToString(shiroSession)); 97 | logger.debug("sessionId {} name {} 被更新", session.getId(), session.getClass().getName()); 98 | //执行事务 99 | transaction.exec(); 100 | } catch (Exception e){ 101 | if(transaction != null){ 102 | transaction.discard(); 103 | } 104 | throw e; 105 | } finally { 106 | jedis.close(); 107 | } 108 | }else { 109 | logger.debug("sessionId {} name {} 更新失败", session.getId(), session.getClass().getName()); 110 | } 111 | } catch (Exception e){ 112 | logger.warn("更新Session失败", e); 113 | } 114 | 115 | } 116 | 117 | /** 118 | * 删除会话 119 | * 当会话过期/会话停止时会调用 120 | * @param session 121 | */ 122 | @Override 123 | protected void doDelete(Session session) { 124 | logger.debug("begin doDelete {}", session); 125 | Jedis jedis = null; 126 | try { 127 | jedis = jedisPool.getResource(); 128 | jedis.del(prefix + session.getId()); 129 | this.uncache(session.getId()); 130 | logger.debug("shiro session id {} 被删除", session.getId()); 131 | } catch (Exception e){ 132 | logger.warn("删除session失败",e); 133 | } finally { 134 | jedis.close(); 135 | } 136 | } 137 | 138 | /** 139 | * 删除cache中缓存的Session 140 | */ 141 | public void uncache(Serializable sessionId) { 142 | try { 143 | Session session = super.getCachedSession(sessionId); 144 | super.uncache(session); 145 | logger.debug("shiro session id {} 的缓存失效", sessionId); 146 | } catch (Exception e) { 147 | e.printStackTrace(); 148 | } 149 | } 150 | 151 | /** 152 | * SessionManager创建完session后会调用该方法 153 | * @param session 154 | * @return 155 | */ 156 | @Override 157 | protected Serializable doCreate(Session session) { 158 | Serializable sessionId = this.generateSessionId(session); 159 | assignSessionId(session,sessionId); 160 | Jedis jedis = null; 161 | try{ 162 | jedis = jedisPool.getResource(); 163 | //session由Redis缓存失效决定,这里作简单标识 164 | session.setTimeout(expireTime); 165 | jedis.setex(prefix + sessionId, expireTime, SerializeUtils.serializaToString((ShiroSession) session)); 166 | logger.info("sessionId {} name {} 被创建", sessionId, session.getClass().getName()); 167 | }catch (Exception e){ 168 | logger.warn("创建session失败",e); 169 | }finally { 170 | jedis.close(); 171 | } 172 | return sessionId; 173 | } 174 | 175 | @Override 176 | protected Session doReadSession(Serializable sessionId) { 177 | logger.debug("begin doReadSession {}", sessionId); 178 | Jedis jedis = jedisPool.getResource(); 179 | Session session = null; 180 | try { 181 | String key = prefix + sessionId; 182 | String value = jedis.get(key); 183 | if(StringUtils.isNotBlank(value)){ 184 | session = SerializeUtils.deserializeFromString(value); 185 | logger.info("sessionId {} ttl {}: ", sessionId, jedis.ttl(key)); 186 | //重置Redis中缓存过期的时间 187 | jedis.expire(key,expireTime); 188 | logger.info("sessionId {} name {} 被读取", sessionId, session.getClass().getName()); 189 | } 190 | } catch (Exception e){ 191 | logger.warn("读取session失败"); 192 | } finally { 193 | jedis.close(); 194 | } 195 | return session; 196 | } 197 | 198 | /** 199 | * 从Redis中读取,但不重置Redis中缓存过期时间 200 | */ 201 | public Session doReadSessionWithoutExpire(Serializable sessionId) { 202 | Session session = null; 203 | Jedis jedis = null; 204 | try { 205 | jedis = jedisPool.getResource(); 206 | String key = prefix + sessionId; 207 | String value = jedis.get(key); 208 | if(StringUtils.isNotBlank(value)){ 209 | session = SerializeUtils.deserializeFromString(value); 210 | } 211 | } catch (Exception e){ 212 | logger.warn("读取Session失败", e); 213 | } finally { 214 | jedis.close(); 215 | } 216 | return session; 217 | } 218 | 219 | /** 220 | * 获取当前所有活跃用户 221 | */ 222 | @Override 223 | public Collection getActiveSessions(){ 224 | Jedis jedis = null; 225 | try { 226 | jedis = jedisPool.getResource(); 227 | Set keys = jedis.keys(prefix + "*"); 228 | if(CollectionUtils.isEmpty(keys)){ 229 | return null; 230 | } 231 | List values = jedis.mget(keys.toArray(new String[keys.size()])); 232 | return SerializeUtils.deserializeFromStrings(values); 233 | } catch (Exception e){ 234 | logger.warn("统计Session信息失败", e); 235 | } finally { 236 | jedis.close(); 237 | } 238 | return null; 239 | } 240 | 241 | /** 242 | * 返回本机Ehcache中Session 243 | */ 244 | public Collection getEhCacheActiveSessions() { 245 | return super.getActiveSessions(); 246 | } 247 | 248 | public void setPrefix(String prefix) { 249 | this.prefix = prefix; 250 | } 251 | 252 | public String getPrefix() { 253 | return prefix; 254 | } 255 | 256 | public int getExpireTime() { 257 | return expireTime; 258 | } 259 | 260 | public void setExpireTime(int expireTime) { 261 | this.expireTime = expireTime; 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Server/src/main/java/com/zhuxs/result/controller/AdminController.java: -------------------------------------------------------------------------------- 1 | package com.zhuxs.result.controller; 2 | 3 | import com.zhuxs.result.domain.entity.Permission; 4 | import com.zhuxs.result.domain.entity.Role; 5 | import com.zhuxs.result.domain.entity.User; 6 | import com.zhuxs.result.dto.PermissionDto; 7 | import com.zhuxs.result.dto.RoleDto; 8 | import com.zhuxs.result.dto.UserDto; 9 | import com.zhuxs.result.service.PermissionService; 10 | import com.zhuxs.result.service.RoleService; 11 | import com.zhuxs.result.service.UserService; 12 | import com.zhuxs.result.utils.ApplicationUtil; 13 | import org.hibernate.annotations.Parameter; 14 | import org.modelmapper.ModelMapper; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.http.HttpHeaders; 17 | import org.springframework.http.HttpStatus; 18 | import org.springframework.http.MediaType; 19 | import org.springframework.http.ResponseEntity; 20 | import org.springframework.stereotype.Controller; 21 | import org.springframework.web.bind.annotation.*; 22 | import org.springframework.web.util.UriComponentsBuilder; 23 | 24 | import java.util.List; 25 | import java.util.stream.Collectors; 26 | 27 | /** 28 | * Created by shusesshou on 2017/9/25. 29 | */ 30 | @RequestMapping(value = AdminController.PATH,produces = MediaType.APPLICATION_JSON_VALUE) 31 | @Controller 32 | public class AdminController { 33 | public static final String PATH = "admin"; 34 | 35 | public static final String SUBPATH_ROLE = "/roles"; 36 | public static final String SUBPATH_USER = "/users"; 37 | public static final String SUBPATH_PERMISSION = "/permissions"; 38 | 39 | public static final String PATHVARIABLE_ID = "/{id}"; 40 | 41 | public static final String USER_ID = "userId"; 42 | 43 | @Autowired 44 | private ModelMapper modelMapper; 45 | @Autowired 46 | private UserService userService; 47 | @Autowired 48 | private RoleService roleService; 49 | @Autowired 50 | private PermissionService permissionService; 51 | 52 | @PostMapping(value = SUBPATH_PERMISSION) 53 | public ResponseEntity addPermission(@RequestBody PermissionDto permissionDto, 54 | UriComponentsBuilder uriComponentsBuilder){ 55 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_PERMISSION); 56 | permissionDto.setResource(""); 57 | String name = permissionDto.getResourceType() + ":" + permissionDto.getAction(); 58 | permissionDto.setName(name); 59 | 60 | Permission permission = convertToEntity(permissionDto); 61 | permissionService.addPermission(permission); 62 | return new ResponseEntity(headers, HttpStatus.OK); 63 | } 64 | 65 | @GetMapping(value = SUBPATH_PERMISSION) 66 | public ResponseEntity> listPermissions(UriComponentsBuilder uriComponentsBuilder){ 67 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_PERMISSION); 68 | List permissions = permissionService.listPermissions(); 69 | List permissionDtos = permissions.stream() 70 | .map(permission -> { 71 | return convertToDto(permission); 72 | }) 73 | .collect(Collectors.toList()); 74 | return new ResponseEntity>(permissionDtos,headers,HttpStatus.OK); 75 | } 76 | 77 | @GetMapping(value = SUBPATH_PERMISSION, 78 | params = USER_ID) 79 | public ResponseEntity> getRolesByPermissionId(UriComponentsBuilder uriComponentsBuilder, 80 | @RequestParam long userId){ 81 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_PERMISSION); 82 | List permissions = permissionService.getPermissionsByUserId(userId); 83 | List permissionDtos = permissions.stream() 84 | .map(permission -> { 85 | return convertToDto(permission); 86 | }) 87 | .collect(Collectors.toList()); 88 | 89 | return new ResponseEntity>(permissionDtos,headers,HttpStatus.OK); 90 | } 91 | 92 | 93 | @DeleteMapping(value = SUBPATH_PERMISSION + PATHVARIABLE_ID) 94 | public ResponseEntity deletePermissionById(UriComponentsBuilder uriComponentsBuilder, 95 | @PathVariable long id){ 96 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_PERMISSION + "/" + id); 97 | permissionService.delPermissionById(id); 98 | return new ResponseEntity(id,headers,HttpStatus.OK); 99 | } 100 | 101 | @PostMapping(value = SUBPATH_ROLE) 102 | public ResponseEntity addRole(@RequestBody RoleDto roleDto, 103 | UriComponentsBuilder uriComponentsBuilder){ 104 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_ROLE); 105 | Role role = convertToEntity(roleDto); 106 | roleService.addRole(role); 107 | return new ResponseEntity(headers,HttpStatus.OK); 108 | } 109 | 110 | @GetMapping(value = SUBPATH_ROLE) 111 | public ResponseEntity> listRoles(UriComponentsBuilder uriComponentsBuilder){ 112 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_ROLE); 113 | List roles = roleService.listRoles(); 114 | List roleDtos = roles.stream() 115 | .map(role -> { 116 | return convertToDto(role); 117 | }) 118 | .collect(Collectors.toList()); 119 | return new ResponseEntity>(roleDtos,headers,HttpStatus.OK); 120 | } 121 | 122 | @GetMapping(value = SUBPATH_ROLE, 123 | params = USER_ID) 124 | public ResponseEntity> getRolesByUserId(UriComponentsBuilder uriComponentsBuilder, 125 | @RequestParam long userId){ 126 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_ROLE); 127 | List roles = roleService.getRolesByUserId(userId); 128 | List roleDtos = roles.stream() 129 | .map(role -> { 130 | return convertToDto(role); 131 | }) 132 | .collect(Collectors.toList()); 133 | return new ResponseEntity>(roleDtos,headers,HttpStatus.OK); 134 | } 135 | 136 | @PutMapping(value = SUBPATH_ROLE + PATHVARIABLE_ID + SUBPATH_PERMISSION) 137 | public ResponseEntity updatePermissionsById(@PathVariable long id,@RequestBody List permissionDtos, 138 | UriComponentsBuilder uriComponentsBuilder){ 139 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_ROLE + PATHVARIABLE_ID + SUBPATH_PERMISSION); 140 | List permissions = permissionDtos.stream() 141 | .map(permissionDto -> convertToEntity(permissionDto)) 142 | .collect(Collectors.toList()); 143 | Role role = roleService.updatePermissionsById(id,permissions); 144 | RoleDto roleDto = convertToDto(role); 145 | return new ResponseEntity(roleDto,headers,HttpStatus.OK); 146 | } 147 | 148 | @DeleteMapping(value = SUBPATH_ROLE + PATHVARIABLE_ID) 149 | public ResponseEntity deleteRoleById(UriComponentsBuilder uriComponentsBuilder, 150 | @PathVariable long id){ 151 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_ROLE + "/" + id); 152 | roleService.delRoleById(id); 153 | return new ResponseEntity(id,headers,HttpStatus.OK); 154 | } 155 | 156 | 157 | @PostMapping(value = SUBPATH_USER) 158 | public ResponseEntity addUser(@RequestBody UserDto userDto, 159 | UriComponentsBuilder uriComponentsBuilder){ 160 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_USER); 161 | User user = convertToEntity(userDto); 162 | userService.addUser(user); 163 | return new ResponseEntity(headers,HttpStatus.OK); 164 | } 165 | 166 | @GetMapping(value = SUBPATH_USER) 167 | public ResponseEntity> listUsers(UriComponentsBuilder uriComponentsBuilder){ 168 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_USER); 169 | List users = userService.listUsers(); 170 | List userDtos = users.stream() 171 | .map(user -> { 172 | return convertToDto(user); 173 | }) 174 | .collect(Collectors.toList()); 175 | return new ResponseEntity>(userDtos,headers,HttpStatus.OK); 176 | } 177 | 178 | @PutMapping(value = SUBPATH_USER + PATHVARIABLE_ID + SUBPATH_ROLE) 179 | public ResponseEntity updateRolesById(@PathVariable Long id, @RequestBody List roleDtos, 180 | UriComponentsBuilder uriComponentsBuilder){ 181 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,SUBPATH_USER + "/" + id.toString() + SUBPATH_ROLE); 182 | List roles = roleDtos.stream() 183 | .map(roleDto -> convertToEntity(roleDto)) 184 | .collect(Collectors.toList()); 185 | User user = userService.updateRolesById(id,roles); 186 | UserDto userDto = convertToDto(user); 187 | return new ResponseEntity(userDto,headers,HttpStatus.OK); 188 | } 189 | 190 | @PutMapping(value = SUBPATH_USER + PATHVARIABLE_ID + SUBPATH_PERMISSION) 191 | public ResponseEntity updatePermissionsById(@PathVariable Long id, @RequestBody List permissionDtos, 192 | UriComponentsBuilder uriComponentsBuilder){ 193 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,SUBPATH_USER + "/" + id.toString() + SUBPATH_PERMISSION); 194 | List permissions = permissionDtos.stream() 195 | .map(permissionDto -> convertToEntity(permissionDto)) 196 | .collect(Collectors.toList()); 197 | User user = userService.updatePermissionsById(id,permissions); 198 | UserDto userDto = convertToDto(user); 199 | return new ResponseEntity(userDto,headers,HttpStatus.OK); 200 | } 201 | 202 | 203 | @DeleteMapping(value = SUBPATH_USER + PATHVARIABLE_ID) 204 | public ResponseEntity deleteUserById(UriComponentsBuilder uriComponentsBuilder, 205 | @PathVariable long id){ 206 | HttpHeaders headers = ApplicationUtil.getHttpHeaders(uriComponentsBuilder,PATH + SUBPATH_USER + "/" + id); 207 | userService.delUserById(id); 208 | return new ResponseEntity(id,headers,HttpStatus.OK); 209 | } 210 | 211 | 212 | private Permission convertToEntity(PermissionDto permissionDto){ 213 | return modelMapper.map(permissionDto,Permission.class); 214 | } 215 | private PermissionDto convertToDto(Permission permission){ 216 | return modelMapper.map(permission,PermissionDto.class); 217 | } 218 | 219 | private Role convertToEntity(RoleDto roleDto){ 220 | return modelMapper.map(roleDto,Role.class); 221 | } 222 | private RoleDto convertToDto(Role role){ 223 | return modelMapper.map(role,RoleDto.class); 224 | } 225 | 226 | private User convertToEntity(UserDto userDto){ 227 | return modelMapper.map(userDto,User.class); 228 | } 229 | 230 | private UserDto convertToDto(User user){ 231 | return modelMapper.map(user,UserDto.class); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /UI/src/views/admin/userInfoPanel.vue: -------------------------------------------------------------------------------- 1 | 60 | 67 | 362 | --------------------------------------------------------------------------------