├── .gitignore ├── LICENSE ├── README.md ├── code ├── backend │ ├── .gitignore │ ├── admin │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── huawei │ │ │ │ └── l00379880 │ │ │ │ └── admin │ │ │ │ ├── AdminApplication.java │ │ │ │ ├── aspect │ │ │ │ ├── MapperAspect.java │ │ │ │ └── SysLogAspect.java │ │ │ │ ├── config │ │ │ │ ├── CorsConfig.java │ │ │ │ ├── KaptchaConfig.java │ │ │ │ ├── SwaggerConfig.java │ │ │ │ └── WebSecurityConfig.java │ │ │ │ ├── constant │ │ │ │ └── SysConstants.java │ │ │ │ ├── controller │ │ │ │ ├── LoginController.java │ │ │ │ ├── SysConfigController.java │ │ │ │ ├── SysDeptController.java │ │ │ │ ├── SysDictController.java │ │ │ │ ├── SysLogController.java │ │ │ │ ├── SysLoginLogController.java │ │ │ │ ├── SysMenuController.java │ │ │ │ ├── SysRoleController.java │ │ │ │ └── SysUserController.java │ │ │ │ ├── mapper │ │ │ │ ├── MyBatisBaseDao.java │ │ │ │ ├── SysConfigMapper.java │ │ │ │ ├── SysDeptMapper.java │ │ │ │ ├── SysDictMapper.java │ │ │ │ ├── SysLogMapper.java │ │ │ │ ├── SysLoginLogMapper.java │ │ │ │ ├── SysMenuMapper.java │ │ │ │ ├── SysRoleDeptMapper.java │ │ │ │ ├── SysRoleMapper.java │ │ │ │ ├── SysRoleMenuMapper.java │ │ │ │ ├── SysUserMapper.java │ │ │ │ ├── SysUserRoleMapper.java │ │ │ │ └── package-info.java │ │ │ │ ├── model │ │ │ │ ├── BaseModel.java │ │ │ │ ├── SysConfig.java │ │ │ │ ├── SysDept.java │ │ │ │ ├── SysDict.java │ │ │ │ ├── SysLog.java │ │ │ │ ├── SysLoginLog.java │ │ │ │ ├── SysMenu.java │ │ │ │ ├── SysRole.java │ │ │ │ ├── SysRoleDept.java │ │ │ │ ├── SysRoleMenu.java │ │ │ │ ├── SysUser.java │ │ │ │ ├── SysUserRole.java │ │ │ │ └── package-info.java │ │ │ │ ├── security │ │ │ │ ├── GrantedAuthorityImpl.java │ │ │ │ ├── JwtAuthenticationFilter.java │ │ │ │ ├── JwtAuthenticationProvider.java │ │ │ │ ├── JwtAuthenticationToken.java │ │ │ │ ├── JwtTokenUtils.java │ │ │ │ ├── JwtUserDetails.java │ │ │ │ ├── SecurityUtils.java │ │ │ │ ├── UserDetailsServiceImpl.java │ │ │ │ └── package-info.java │ │ │ │ ├── service │ │ │ │ ├── SysConfigService.java │ │ │ │ ├── SysDeptService.java │ │ │ │ ├── SysDictService.java │ │ │ │ ├── SysLogService.java │ │ │ │ ├── SysLoginLogService.java │ │ │ │ ├── SysMenuService.java │ │ │ │ ├── SysRoleService.java │ │ │ │ ├── SysUserService.java │ │ │ │ └── impl │ │ │ │ │ ├── SysConfigServiceImpl.java │ │ │ │ │ ├── SysDeptServiceImpl.java │ │ │ │ │ ├── SysDictServiceImpl.java │ │ │ │ │ ├── SysLogServiceImpl.java │ │ │ │ │ ├── SysLoginLogServiceImpl.java │ │ │ │ │ ├── SysMenuServiceImpl.java │ │ │ │ │ ├── SysRoleServiceImpl.java │ │ │ │ │ └── SysUserServiceImpl.java │ │ │ │ ├── utils │ │ │ │ ├── HttpUtils.java │ │ │ │ └── IPUtils.java │ │ │ │ └── vo │ │ │ │ └── LoginBean.java │ │ │ └── resources │ │ │ ├── application-dev.yml │ │ │ ├── application-prod.yml │ │ │ ├── application.yml │ │ │ ├── banner.txt │ │ │ └── mapper │ │ │ ├── SysConfigMapper.xml │ │ │ ├── SysDeptMapper.xml │ │ │ ├── SysDictMapper.xml │ │ │ ├── SysLogMapper.xml │ │ │ ├── SysLoginLogMapper.xml │ │ │ ├── SysMenuMapper.xml │ │ │ ├── SysRoleDeptMapper.xml │ │ │ ├── SysRoleMapper.xml │ │ │ ├── SysRoleMenuMapper.xml │ │ │ ├── SysUserMapper.xml │ │ │ └── SysUserRoleMapper.xml │ ├── common │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── huawei │ │ │ └── l00379880 │ │ │ └── common │ │ │ └── utils │ │ │ ├── DateTimeUtils.java │ │ │ ├── FileUtils.java │ │ │ ├── IOUtils.java │ │ │ ├── PasswordEncoder.java │ │ │ ├── PasswordUtils.java │ │ │ ├── PoiUtils.java │ │ │ ├── ReflectionUtils.java │ │ │ └── StringUtils.java │ ├── core │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── huawei │ │ │ └── l00379880 │ │ │ └── core │ │ │ ├── exception │ │ │ └── package-info.java │ │ │ ├── http │ │ │ ├── HttpResult.java │ │ │ ├── HttpStatus.java │ │ │ └── package-info.java │ │ │ ├── page │ │ │ ├── MyBatisPageHelper.java │ │ │ ├── PageRequest.java │ │ │ ├── PageResult.java │ │ │ ├── Param.java │ │ │ └── package-info.java │ │ │ └── service │ │ │ ├── CurdService.java │ │ │ └── package-info.java │ └── pom.xml └── frontend │ ├── .editorconfig │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ ├── src │ ├── App.vue │ ├── assets │ │ ├── languages │ │ │ ├── en_us.json │ │ │ └── zh_cn.json │ │ ├── logo.png │ │ └── user.png │ ├── components │ │ ├── Core │ │ │ ├── IFrame.vue │ │ │ ├── Introduction.vue │ │ │ ├── KtButton.vue │ │ │ ├── KtTable.vue │ │ │ ├── MessagePanel.vue │ │ │ ├── NoticePanel.vue │ │ │ ├── PersonalPanel.vue │ │ │ ├── TableColumnFilterDialog.vue │ │ │ └── TableTreeColumn.vue │ │ ├── FaIconTooltip │ │ │ └── index.vue │ │ ├── Hamburger │ │ │ └── index.vue │ │ ├── HelloWorld.vue │ │ ├── MenuTree │ │ │ └── index.vue │ │ ├── PopupTreeInput │ │ │ └── index.vue │ │ ├── Sys │ │ │ ├── Config.vue │ │ │ ├── Dept.vue │ │ │ ├── Dict.vue │ │ │ ├── Log.vue │ │ │ ├── Loginlog.vue │ │ │ ├── Menu.vue │ │ │ ├── Online.vue │ │ │ ├── Role.vue │ │ │ └── User.vue │ │ └── ThemePicker │ │ │ └── index.vue │ ├── http │ │ ├── api.js │ │ ├── axios.js │ │ ├── config.js │ │ ├── index.js │ │ └── modules │ │ │ ├── config.js │ │ │ ├── dept.js │ │ │ ├── dict.js │ │ │ ├── index.js │ │ │ ├── log.js │ │ │ ├── login.js │ │ │ ├── loginlog.js │ │ │ ├── menu.js │ │ │ ├── role.js │ │ │ └── user.js │ ├── main.js │ ├── router │ │ └── index.js │ ├── store │ │ ├── index.js │ │ └── modules │ │ │ ├── app.js │ │ │ ├── iframe.js │ │ │ ├── menu.js │ │ │ ├── tab.js │ │ │ └── user.js │ ├── utils │ │ ├── datetime.js │ │ ├── global.js │ │ ├── i18n.js │ │ ├── iframe.js │ │ ├── permission.js │ │ └── validate.js │ └── views │ │ ├── 404.vue │ │ ├── About.vue │ │ ├── HeadBar.vue │ │ ├── Home.vue │ │ ├── Login.vue │ │ ├── MainContent.vue │ │ └── NavBar.vue │ └── vue.config.js ├── doc └── sql │ └── mango.sql └── images └── home.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 梁山广 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # spring-cloud-vue-admin 2 | 3 | 基于Spring Cloud和Vue最近版本的权限管理系统,预览地址:http://129.211.88.191:7777 4 | 5 | ![菜单介绍](images/home.png) 6 | 7 | ## 功能 8 | 9 | > ✔ 表示已完成,✘表示正在开发中 10 | 11 | + ✔ 系统登录:系统用户登录,系统登录认证(jwt token方式) 12 | + ✔ 用户管理:新建用户,修改用户,删除用户,查询用户 13 | + ✔ 机构管理:新建机构,修改机构,删除机构,查询机构 14 | + ✔ 角色管理:新建角色,修改角色,删除角色,查询角色 15 | + ✔ 菜单管理:新建菜单,修改菜单,删除菜单,查询菜单 16 | + ✔ 系统日志:记录用户操作日志,查看系统执行日志记录 17 | + ✔ 数据监控:定制Druid信息,提供简洁有效的SQL监控 18 | + ✔ 聚合文档:Swagger在线文档,提供简洁美观的API文档 19 | + ✔ 主题切换:支持主题切换,自定主题颜色,一键换肤 20 | + ✘ 服务治理:集成Spring Cloud,实现全方位服务治理 21 | + ✘ 服务监控:集成Spring Boot Admin,实现微服务监控 22 | 23 | ## 开发环境 24 | 25 | ### 后端 26 | 27 | + IDE : IDEA2019.2 28 | + JDK : JDK 1.8.0_212 29 | + Maven : Maven 3.6.2 30 | + MySQL: MySQL 5.7.15 31 | 32 | ### 前端 33 | 34 | + IDE : WebStorm 2019.2.4 35 | + Webpack:webpack 4.41.2 36 | + NODE: Node 10.16.3 37 | + NPM : NPM 6.9.0 38 | 39 | ## 技术选型 40 | 41 | ### 后端 42 | 43 | + 核心框架:Spring Boot 2.1.1.RELEASE 44 | + 服务治理:Spring Cloud Finchley.RELEASE 45 | + 持久层框架:MyBatis 3.4.6 46 | + 数据库连接池:Druid 1.1.10 47 | + 安全框架:Spring Security 5.1.2 + JWT 0.9.1 48 | + 接口文档:Swagger 2.9.2 49 | 50 | ### 前端 51 | 52 | + 前端框架:Vue.js 2.6.10 53 | + 页面库:Element 2.13.0 54 | + 状态管理:Vuex 3.0.1 55 | + 路由管理:Vue Router 3.1.3 56 | + 后台交互:axios 0.19.0 57 | + 脚手架:Vue Cli 4.0.5 58 | + 图标库:FontAwesome 4.7.0 59 | + 国际化:i18n 8.15.0 60 | 61 | ## 参考资料 62 | 63 | + [Spring Cloud](https://spring.io/projects/spring-cloud) 64 | + [Vue](https://cn.vuejs.org) 65 | + [Element](https://element.eleme.cn/#/zh-CN) 66 | + [《Spring Boot+Spring Cloud+Vue+Element项目实战》](https://item.jd.com/12624380.html) -------------------------------------------------------------------------------- /code/backend/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | target/ -------------------------------------------------------------------------------- /code/backend/admin/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /code/backend/admin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.huawei.l00379880 7 | backend 8 | 1.0-SNAPSHOT 9 | 10 | admin 11 | 1.0-SNAPSHOT 12 | admin 13 | admin module for backend 14 | 15 | 16 | 1.8 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | true 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-test 33 | test 34 | 35 | 36 | 37 | io.springfox 38 | springfox-swagger2 39 | 2.9.2 40 | 41 | 42 | 43 | io.springfox 44 | springfox-swagger-ui 45 | 2.9.2 46 | 47 | 48 | 49 | org.mybatis.spring.boot 50 | mybatis-spring-boot-starter 51 | 1.3.2 52 | 53 | 54 | 55 | mysql 56 | mysql-connector-java 57 | 58 | 59 | 60 | com.alibaba 61 | druid-spring-boot-starter 62 | 1.1.10 63 | 64 | 65 | 66 | com.huawei.l00379880 67 | core 68 | 1.0-SNAPSHOT 69 | 70 | 71 | 72 | com.github.axet 73 | kaptcha 74 | 0.0.9 75 | 76 | 77 | 78 | org.springframework.boot 79 | spring-boot-starter-security 80 | 81 | 82 | 83 | io.jsonwebtoken 84 | jjwt 85 | 0.9.1 86 | 87 | 88 | 89 | org.springframework.boot 90 | spring-boot-starter-aop 91 | 92 | 93 | 94 | com.alibaba 95 | fastjson 96 | 1.2.48 97 | 98 | 99 | 100 | 101 | 102 | 103 | org.springframework.boot 104 | spring-boot-maven-plugin 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/AdminApplication.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : admin的入口类 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 0:02 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin; 8 | 9 | import org.mybatis.spring.annotation.MapperScan; 10 | import org.springframework.boot.SpringApplication; 11 | import org.springframework.boot.autoconfigure.SpringBootApplication; 12 | 13 | @SpringBootApplication 14 | @MapperScan("com.huawei.l00379880.admin.mapper") 15 | public class AdminApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(AdminApplication.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/aspect/MapperAspect.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : DAO切面,插入创建人,创建时间,修改人,修改时间 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/29 0:05 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.aspect; 8 | 9 | 10 | import java.util.Date; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | 14 | import com.huawei.l00379880.admin.security.SecurityUtils; 15 | import com.huawei.l00379880.common.utils.StringUtils; 16 | import org.apache.commons.beanutils.BeanUtils; 17 | import org.aspectj.lang.ProceedingJoinPoint; 18 | import org.aspectj.lang.annotation.Around; 19 | import org.aspectj.lang.annotation.Aspect; 20 | import org.aspectj.lang.annotation.Pointcut; 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.stereotype.Component; 23 | import org.springframework.web.context.request.RequestContextHolder; 24 | import org.springframework.web.context.request.ServletRequestAttributes; 25 | 26 | @Aspect 27 | @Component 28 | @Configuration 29 | public class MapperAspect { 30 | private static final String CREATE_BY = "createBy"; 31 | private static final String CREATE_TIME = "createTime"; 32 | private static final String LAST_UPDATE_BY = "lastUpdateBy"; 33 | private static final String LAST_UPDATE_TIME = "lastUpdateTime"; 34 | 35 | @Pointcut("execution(* com.huawei.l00379880.*.mapper.*.update*(..))") 36 | public void daoUpdate() { 37 | } 38 | 39 | @Pointcut("execution(* com.huawei.l00379880.*.mapper.*.insert*(..))") 40 | public void daoCreate() { 41 | } 42 | 43 | @Around("daoUpdate()") 44 | public Object doAroundUpdate(ProceedingJoinPoint pjp) throws Throwable { 45 | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 46 | if (attributes == null) { 47 | return pjp.proceed(); 48 | } 49 | HttpServletRequest request = attributes.getRequest(); 50 | String token = request.getHeader("token"); 51 | String username = getUserName(); 52 | if (token != null && username != null) { 53 | Object[] objects = pjp.getArgs(); 54 | if (objects != null && objects.length > 0) { 55 | for (Object arg : objects) { 56 | BeanUtils.setProperty(arg, LAST_UPDATE_BY, username); 57 | BeanUtils.setProperty(arg, LAST_UPDATE_TIME, new Date()); 58 | } 59 | } 60 | } 61 | Object object = pjp.proceed(); 62 | return object; 63 | 64 | } 65 | 66 | @Around("daoCreate()") 67 | public Object doAroundCreate(ProceedingJoinPoint pjp) throws Throwable { 68 | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 69 | if (attributes == null) { 70 | return pjp.proceed(); 71 | } 72 | Object[] objects = pjp.getArgs(); 73 | if (objects != null && objects.length > 0) { 74 | for (Object arg : objects) { 75 | String username = getUserName(); 76 | if (username != null) { 77 | if (StringUtils.isBlank(BeanUtils.getProperty(arg, CREATE_BY))) { 78 | BeanUtils.setProperty(arg, CREATE_BY, username); 79 | } 80 | if (StringUtils.isBlank(BeanUtils.getProperty(arg, CREATE_TIME))) { 81 | BeanUtils.setProperty(arg, CREATE_TIME, new Date()); 82 | } 83 | } 84 | } 85 | } 86 | Object object = pjp.proceed(); 87 | return object; 88 | } 89 | 90 | private String getUserName() { 91 | return SecurityUtils.getUsername(); 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/aspect/SysLogAspect.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 系统日志,切面处理类,记录日志 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/29 0:12 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.aspect; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | 11 | import com.huawei.l00379880.admin.model.SysLog; 12 | import com.huawei.l00379880.admin.security.SecurityUtils; 13 | import com.huawei.l00379880.admin.service.SysLogService; 14 | import com.huawei.l00379880.admin.utils.HttpUtils; 15 | import com.huawei.l00379880.admin.utils.IPUtils; 16 | import org.aspectj.lang.ProceedingJoinPoint; 17 | import org.aspectj.lang.annotation.Around; 18 | import org.aspectj.lang.annotation.Aspect; 19 | import org.aspectj.lang.annotation.Pointcut; 20 | import org.aspectj.lang.reflect.MethodSignature; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.stereotype.Component; 23 | 24 | import com.alibaba.fastjson.JSONObject; 25 | 26 | /** 27 | * 系统日志,切面处理类,记录日志 28 | * 29 | * @author Louis 30 | * @date Jan 19, 2019 31 | */ 32 | @Aspect 33 | @Component 34 | public class SysLogAspect { 35 | 36 | @Autowired 37 | private SysLogService sysLogService; 38 | 39 | @Pointcut("execution(* com.louis.mango.*.service.*.*(..))") 40 | public void logPointCut() { 41 | 42 | } 43 | 44 | @Around("logPointCut()") 45 | public Object around(ProceedingJoinPoint point) throws Throwable { 46 | long beginTime = System.currentTimeMillis(); 47 | // 执行方法 48 | Object result = point.proceed(); 49 | // 执行时长(毫秒) 50 | long time = System.currentTimeMillis() - beginTime; 51 | // 保存日志 52 | saveSysLog(point, time); 53 | return result; 54 | } 55 | 56 | private void saveSysLog(ProceedingJoinPoint joinPoint, long time) { 57 | String userName = SecurityUtils.getUsername(); 58 | if (joinPoint.getTarget() instanceof SysLogService) { 59 | return; 60 | } 61 | MethodSignature signature = (MethodSignature) joinPoint.getSignature(); 62 | SysLog sysLog = new SysLog(); 63 | 64 | // Method method = signature.getMethod(); 65 | // com.louis.merak.admin.annotation.SysLog syslogAnno = method.getAnnotation(com.louis.merak.admin.annotation.SysLog.class); 66 | // if(syslogAnno != null){ 67 | // //注解上的描述 68 | // sysLog.setOperation(syslogAnno.value()); 69 | // } 70 | 71 | // 请求的方法名 72 | String className = joinPoint.getTarget().getClass().getName(); 73 | String methodName = signature.getName(); 74 | sysLog.setMethod(className + "." + methodName + "()"); 75 | 76 | // 请求的参数 77 | Object[] args = joinPoint.getArgs(); 78 | try { 79 | String params = JSONObject.toJSONString(args[0]); 80 | if (params.length() > 200) { 81 | params = params.substring(0, 200) + "..."; 82 | } 83 | sysLog.setParams(params); 84 | } catch (Exception e) { 85 | } 86 | 87 | // 获取request 88 | HttpServletRequest request = HttpUtils.getHttpServletRequest(); 89 | // 设置IP地址 90 | sysLog.setIp(IPUtils.getIpAddr(request)); 91 | 92 | // 用户名 93 | sysLog.setUserName(userName); 94 | 95 | // 执行时长(毫秒) 96 | sysLog.setTime(time); 97 | 98 | // 保存系统日志 99 | sysLogService.save(sysLog); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 跨域配置 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 11:44 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.config; 8 | 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 11 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 12 | 13 | @Configuration 14 | public class CorsConfig implements WebMvcConfigurer { 15 | @Override 16 | public void addCorsMappings(CorsRegistry registry) { 17 | // 允许跨域访问的路径 18 | registry.addMapping("/**") 19 | // 允许跨域访问的源 20 | .allowedOrigins("*") 21 | // 允许的请求方法类型 22 | .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") 23 | // 预检间隔时间, 预检请求:非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight) 24 | .maxAge(168000) 25 | // 允许头部设置 26 | .allowedHeaders("*") 27 | // 是否允许发送cookie 28 | .allowCredentials(true); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/config/KaptchaConfig.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 验证码配置 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 23:05 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.config; 8 | 9 | import com.google.code.kaptcha.impl.DefaultKaptcha; 10 | import com.google.code.kaptcha.util.Config; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | 14 | import java.util.Properties; 15 | 16 | @Configuration 17 | public class KaptchaConfig { 18 | @Bean 19 | public DefaultKaptcha producer() { 20 | Properties properties = new Properties(); 21 | properties.put("kaptcha.border", "no"); 22 | properties.put("kaptcha.textproducer.font.color", "black"); 23 | properties.put("kaptcha.textproducer.char.space", "5"); 24 | Config config = new Config(properties); 25 | DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); 26 | defaultKaptcha.setConfig(config); 27 | return defaultKaptcha; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : Swagger2的配置类 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 0:14 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.config; 8 | 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import springfox.documentation.builders.ApiInfoBuilder; 12 | import springfox.documentation.builders.ParameterBuilder; 13 | import springfox.documentation.builders.PathSelectors; 14 | import springfox.documentation.builders.RequestHandlerSelectors; 15 | import springfox.documentation.schema.ModelRef; 16 | import springfox.documentation.service.ApiInfo; 17 | import springfox.documentation.service.Contact; 18 | import springfox.documentation.service.Parameter; 19 | import springfox.documentation.spi.DocumentationType; 20 | import springfox.documentation.spring.web.plugins.Docket; 21 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | @Configuration 27 | @EnableSwagger2 28 | public class SwaggerConfig { 29 | @Bean 30 | public Docket createRestApi() { 31 | // 添加请求参数,这里我们把token作为请求头部参数传入后端 32 | ParameterBuilder parameterBuilder = new ParameterBuilder(); 33 | List parameters = new ArrayList<>(); 34 | parameterBuilder.name("token").description("jwt生成的令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); 35 | parameters.add(parameterBuilder.build()); 36 | return new Docket(DocumentationType.SWAGGER_2) 37 | .apiInfo(apiInfo()) 38 | .select() 39 | .apis(RequestHandlerSelectors.basePackage("com.huawei.l00379880.admin.controller")) 40 | .paths(PathSelectors.any()) 41 | .build() 42 | .globalOperationParameters(parameters); 43 | } 44 | 45 | private ApiInfo apiInfo() { 46 | return new ApiInfoBuilder() 47 | .title("基于SpringCloud与Vue的权限管理系统-后台接口") 48 | .version("0.1") 49 | .description("designed by 梁山广 at 2019-11-17") 50 | .build(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/config/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : Spring Security配置 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 23:28 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.config; 8 | 9 | import com.huawei.l00379880.admin.security.JwtAuthenticationFilter; 10 | import com.huawei.l00379880.admin.security.JwtAuthenticationProvider; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.http.HttpMethod; 15 | import org.springframework.security.authentication.AuthenticationManager; 16 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 17 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 18 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 19 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 20 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 21 | import org.springframework.security.core.userdetails.UserDetailsService; 22 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 23 | import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler; 24 | 25 | @Configuration 26 | // 开启Spring Secutiry 27 | @EnableWebSecurity 28 | // 开启权限注解,如preAuthorize注解 29 | @EnableGlobalMethodSecurity(prePostEnabled = true) 30 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 31 | 32 | @Autowired 33 | private UserDetailsService userDetailsService; 34 | 35 | @Override 36 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 37 | // 使用自定义身份验证组件 38 | auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService)); 39 | } 40 | 41 | @Override 42 | protected void configure(HttpSecurity http) throws Exception { 43 | // 禁用csrf,由于使用地是JWT,我们这里不需要csrf 44 | http.cors().and().csrf().disable() 45 | .authorizeRequests() 46 | // 允许所有跨域预检请求 47 | .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() 48 | // webjars 49 | .antMatchers("/webjars/**").permitAll() 50 | // 查看SQL监控 51 | .antMatchers("/druid/**").permitAll() 52 | // 首页和登录界面 53 | .antMatchers("/").permitAll() 54 | .antMatchers("/login").permitAll() 55 | // swagger 56 | .antMatchers("/swagger-ui.html").permitAll() 57 | .antMatchers("/swagger-resources/**").permitAll() 58 | .antMatchers("/v2/api-docs").permitAll() 59 | .antMatchers("/webjars/springfox-swagger-ui/**").permitAll() 60 | // 验证码 61 | .antMatchers("/captcha.jpg**").permitAll() 62 | // 服务监控 63 | .antMatchers("/actuator/**").permitAll() 64 | // 其他所有请求都需要身份验证 65 | .anyRequest().authenticated(); 66 | // 允许iframe嵌套 67 | http.headers().frameOptions().disable(); 68 | // 退出登录处理器 69 | http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()); 70 | // token验证过滤器 71 | http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class); 72 | } 73 | 74 | @Bean 75 | @Override 76 | protected AuthenticationManager authenticationManager() throws Exception { 77 | return super.authenticationManager(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/constant/SysConstants.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 常量 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 22:22 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.constant; 8 | 9 | public interface SysConstants { 10 | /** 11 | * 系统管理员用户名 12 | */ 13 | String ADMIN = "admin"; 14 | } 15 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 登录相关接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 23:14 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.google.code.kaptcha.Constants; 10 | import com.google.code.kaptcha.Producer; 11 | import com.huawei.l00379880.admin.model.SysUser; 12 | import com.huawei.l00379880.admin.security.JwtAuthenticationToken; 13 | import com.huawei.l00379880.admin.security.SecurityUtils; 14 | import com.huawei.l00379880.admin.service.SysLoginLogService; 15 | import com.huawei.l00379880.admin.service.SysUserService; 16 | import com.huawei.l00379880.admin.utils.IPUtils; 17 | import com.huawei.l00379880.admin.vo.LoginBean; 18 | import com.huawei.l00379880.common.utils.IOUtils; 19 | import com.huawei.l00379880.common.utils.PasswordUtils; 20 | import com.huawei.l00379880.core.http.HttpResult; 21 | import io.swagger.annotations.Api; 22 | import io.swagger.annotations.ApiOperation; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.security.authentication.AuthenticationManager; 25 | import org.springframework.web.bind.annotation.GetMapping; 26 | import org.springframework.web.bind.annotation.PostMapping; 27 | import org.springframework.web.bind.annotation.RequestBody; 28 | import org.springframework.web.bind.annotation.RestController; 29 | 30 | import javax.imageio.ImageIO; 31 | import javax.servlet.ServletOutputStream; 32 | import javax.servlet.http.HttpServletRequest; 33 | import javax.servlet.http.HttpServletResponse; 34 | import java.awt.image.BufferedImage; 35 | import java.io.IOException; 36 | 37 | @RestController 38 | @Api(tags = "登录和验证接口") 39 | public class LoginController { 40 | @Autowired 41 | private Producer producer; 42 | 43 | @Autowired 44 | private SysUserService sysUserService; 45 | 46 | @Autowired 47 | private SysLoginLogService sysLoginLogService; 48 | 49 | @Autowired 50 | private AuthenticationManager authenticationManager; 51 | 52 | @GetMapping("/captcha.jpg") 53 | @ApiOperation("获取验证码图片") 54 | public void captcha(HttpServletResponse response, HttpServletRequest request) throws IOException { 55 | response.setHeader("Cache-Control", "no-store, no-cache"); 56 | response.setContentType("image/jpeg"); 57 | // 生成文字验证码 58 | String text = producer.createText(); 59 | // 生成图片验证码 60 | BufferedImage image = producer.createImage(text); 61 | // 保存验证码到session 62 | request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text); 63 | ServletOutputStream out = response.getOutputStream(); 64 | ImageIO.write(image, "jpg", out); 65 | IOUtils.closeQuietly(out); 66 | } 67 | 68 | @PostMapping("/login") 69 | public HttpResult login(@RequestBody LoginBean loginBean, HttpServletRequest request) throws Exception { 70 | String username = loginBean.getAccount(); 71 | String password = loginBean.getPassword(); 72 | String captcha = loginBean.getCaptcha(); 73 | // 从Session获取之前保存的验证码,跟前台传来的验证码进行匹配 74 | String kaptcha = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); 75 | if (kaptcha == null) { 76 | return HttpResult.error("验证码已失效"); 77 | } 78 | if (!captcha.equalsIgnoreCase(kaptcha)) { 79 | return HttpResult.error("验证满不正确"); 80 | } 81 | SysUser user = sysUserService.findByName(username); 82 | if (user == null) { 83 | return HttpResult.error("账号不存在"); 84 | } 85 | if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) { 86 | return HttpResult.error("密码不正确"); 87 | } 88 | // 账号锁定 89 | if (user.getStatus() == 0) { 90 | return HttpResult.error("账号已被锁定,请联系管理员"); 91 | } 92 | // 系统登录认证 93 | JwtAuthenticationToken token = SecurityUtils.login(request, username, password, authenticationManager); 94 | // 记录登录日志 95 | sysLoginLogService.writeLoginLog(username, IPUtils.getIpAddr(request)); 96 | return HttpResult.ok(token); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysConfigController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 系统配置接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 20:17 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.model.SysConfig; 10 | import com.huawei.l00379880.admin.service.SysConfigService; 11 | import com.huawei.l00379880.core.http.HttpResult; 12 | import com.huawei.l00379880.core.page.PageRequest; 13 | import io.swagger.annotations.Api; 14 | import io.swagger.annotations.ApiOperation; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.security.access.prepost.PreAuthorize; 17 | import org.springframework.web.bind.annotation.*; 18 | 19 | import java.util.List; 20 | 21 | @RestController 22 | @RequestMapping("/config") 23 | @Api(tags = "系统配置接口") 24 | public class SysConfigController { 25 | @Autowired 26 | private SysConfigService sysConfigService; 27 | 28 | @PostMapping("/save") 29 | @ApiOperation("保存配置") 30 | @PreAuthorize("hasAuthority('sys:config:add') AND hasAuthority('sys:config:edit')") 31 | public HttpResult save(@RequestBody SysConfig record) { 32 | return HttpResult.ok(sysConfigService.save(record)); 33 | } 34 | 35 | @PostMapping("/delete") 36 | @ApiOperation("删除配置") 37 | @PreAuthorize("hasAuthority('sys:config:delete')") 38 | public HttpResult delete(@RequestBody List records) { 39 | return HttpResult.ok(sysConfigService.delete(records)); 40 | } 41 | 42 | @PostMapping("/findPage") 43 | @ApiOperation("获取配置的分页列表") 44 | @PreAuthorize("hasAuthority('sys:config:view')") 45 | public HttpResult findPage(@RequestBody PageRequest pageRequest) { 46 | return HttpResult.ok(sysConfigService.findPage(pageRequest)); 47 | } 48 | 49 | @GetMapping("/findByLabel") 50 | @ApiOperation("根据配置名获取配置分页对象") 51 | @PreAuthorize("hasAuthority('sys:config:view')") 52 | public HttpResult findByLabel(@RequestParam String label) { 53 | return HttpResult.ok(sysConfigService.findByLabel(label)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysDeptController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 部门管理接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:17 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.model.SysDept; 10 | import com.huawei.l00379880.admin.service.SysDeptService; 11 | import com.huawei.l00379880.core.http.HttpResult; 12 | import io.swagger.annotations.Api; 13 | import io.swagger.annotations.ApiOperation; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.security.access.prepost.PreAuthorize; 16 | import org.springframework.web.bind.annotation.*; 17 | 18 | import java.util.List; 19 | 20 | @RestController 21 | @RequestMapping("/dept") 22 | @Api(tags = "部门管理接口") 23 | public class SysDeptController { 24 | 25 | @Autowired 26 | private SysDeptService sysDeptService; 27 | 28 | @PostMapping("/save") 29 | @ApiOperation("保存部门信息") 30 | @PreAuthorize("hasAuthority('sys:dept:add') AND hasAuthority('sys:dept:edit')") 31 | public HttpResult save(@RequestBody SysDept record) { 32 | return HttpResult.ok(sysDeptService.save(record)); 33 | } 34 | 35 | @PostMapping("/delete") 36 | @ApiOperation("删除部门信息") 37 | @PreAuthorize("hasAuthority('sys:dept:delete')") 38 | public HttpResult delete(@RequestBody List records) { 39 | return HttpResult.ok(sysDeptService.delete(records)); 40 | } 41 | 42 | @GetMapping("/findTree") 43 | @ApiOperation("获取部门树") 44 | @PreAuthorize("hasAuthority('sys:dept:view')") 45 | public HttpResult findTree() { 46 | return HttpResult.ok(sysDeptService.findTree()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysDictController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 字典管理接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 16:44 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.model.SysDict; 10 | import com.huawei.l00379880.admin.service.SysDictService; 11 | import com.huawei.l00379880.core.http.HttpResult; 12 | import com.huawei.l00379880.core.page.PageRequest; 13 | import io.swagger.annotations.Api; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.security.access.prepost.PreAuthorize; 16 | import org.springframework.web.bind.annotation.*; 17 | 18 | import java.util.List; 19 | 20 | @RestController 21 | @RequestMapping("/dict") 22 | @Api(tags = "字典管理接口") 23 | public class SysDictController { 24 | @Autowired 25 | private SysDictService sysDictService; 26 | 27 | @PostMapping("/save") 28 | @PreAuthorize("hasAuthority('sys:dict:add') AND hasAuthority('sys:dict:edit')") 29 | public HttpResult save(@RequestBody SysDict record) { 30 | return HttpResult.ok(sysDictService.save(record)); 31 | } 32 | 33 | @PostMapping("/delete") 34 | @PreAuthorize("hasAuthority('sys:dict:delete')") 35 | public HttpResult delete(@RequestBody List records) { 36 | return HttpResult.ok(sysDictService.delete(records)); 37 | } 38 | 39 | @PostMapping("/findPage") 40 | @PreAuthorize("hasAuthority('sys:dict:view')") 41 | public HttpResult findPage(@RequestBody PageRequest pageRequest) { 42 | return HttpResult.ok(sysDictService.findPage(pageRequest)); 43 | } 44 | 45 | @GetMapping("/findByLabel") 46 | @PreAuthorize("hasAuthority('sys:dict:view')") 47 | public HttpResult findByLabel(@RequestParam String label) { 48 | return HttpResult.ok(sysDictService.findByLabel(label)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysLogController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 系统日志对外接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:36 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.model.SysLog; 10 | import com.huawei.l00379880.admin.service.SysLogService; 11 | import com.huawei.l00379880.core.http.HttpResult; 12 | import com.huawei.l00379880.core.page.PageRequest; 13 | import io.swagger.annotations.Api; 14 | import io.swagger.annotations.ApiOperation; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.security.access.prepost.PreAuthorize; 17 | import org.springframework.web.bind.annotation.PostMapping; 18 | import org.springframework.web.bind.annotation.RequestBody; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | import org.springframework.web.bind.annotation.RestController; 21 | 22 | import java.util.List; 23 | 24 | @RestController 25 | @RequestMapping("/log") 26 | @Api(tags = "操作日志接口") 27 | public class SysLogController { 28 | 29 | @Autowired 30 | private SysLogService sysLogService; 31 | 32 | @PostMapping("/findPage") 33 | @ApiOperation("获取系统日志的分页列表") 34 | @PreAuthorize("hasAuthority('sys:log:view')") 35 | public HttpResult findPage(@RequestBody PageRequest pageRequest) { 36 | return HttpResult.ok(sysLogService.findPage(pageRequest)); 37 | } 38 | 39 | @PostMapping("/delete") 40 | @ApiOperation("删除系统日志") 41 | @PreAuthorize("hasAuthority('sys:log:delete')") 42 | public HttpResult delete(@RequestBody List records) { 43 | return HttpResult.ok(sysLogService.delete(records)); 44 | } 45 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysLoginLogController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 登录日志接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:56 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.model.SysLoginLog; 10 | import com.huawei.l00379880.admin.service.SysLoginLogService; 11 | import com.huawei.l00379880.core.http.HttpResult; 12 | import com.huawei.l00379880.core.page.PageRequest; 13 | import io.swagger.annotations.Api; 14 | import io.swagger.annotations.ApiOperation; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.security.access.prepost.PreAuthorize; 17 | import org.springframework.web.bind.annotation.PostMapping; 18 | import org.springframework.web.bind.annotation.RequestBody; 19 | import org.springframework.web.bind.annotation.RequestMapping; 20 | import org.springframework.web.bind.annotation.RestController; 21 | 22 | import java.util.List; 23 | 24 | @RestController 25 | @RequestMapping("loginlog") 26 | @Api(tags = "登录日志接口") 27 | public class SysLoginLogController { 28 | @Autowired 29 | private SysLoginLogService sysLoginLogService; 30 | 31 | @PostMapping("/findPage") 32 | @ApiOperation("获取所有登录日志并进行分页") 33 | @PreAuthorize("hasAuthority('sys:loginlog:view')") 34 | public HttpResult findPage(@RequestBody PageRequest pageRequest) { 35 | return HttpResult.ok(sysLoginLogService.findPage(pageRequest)); 36 | } 37 | 38 | @PostMapping("/delete") 39 | @ApiOperation("删除登录日志") 40 | @PreAuthorize("hasAuthority('sys:loginlog:delete')") 41 | public HttpResult delete(@RequestBody List records) { 42 | return HttpResult.ok(sysLoginLogService.delete(records)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysMenuController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 菜单管理接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 20:50 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.model.SysMenu; 10 | import com.huawei.l00379880.admin.service.SysMenuService; 11 | import com.huawei.l00379880.core.http.HttpResult; 12 | import io.swagger.annotations.Api; 13 | import io.swagger.annotations.ApiOperation; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.security.access.prepost.PreAuthorize; 16 | import org.springframework.web.bind.annotation.*; 17 | 18 | import java.util.List; 19 | 20 | @RestController 21 | @RequestMapping("/menu") 22 | @Api(tags = "菜单管理接口") 23 | public class SysMenuController { 24 | 25 | @Autowired 26 | private SysMenuService sysMenuService; 27 | 28 | @PostMapping("/save") 29 | @ApiOperation("保存菜单") 30 | @PreAuthorize("hasAuthority('sys:menu:add') AND hasAuthority('sys:menu:edit')") 31 | public HttpResult save(@RequestBody SysMenu record) { 32 | return HttpResult.ok(sysMenuService.save(record)); 33 | } 34 | 35 | @PostMapping("/delete") 36 | @ApiOperation("删除菜单") 37 | @PreAuthorize("hasAuthority('sys:menu:delete')") 38 | public HttpResult delete(@RequestBody List records) { 39 | return HttpResult.ok(sysMenuService.delete(records)); 40 | } 41 | 42 | @GetMapping("/findNavTree") 43 | @ApiOperation("获取当前用户的导航树") 44 | @PreAuthorize("hasAuthority('sys:menu:view')") 45 | public HttpResult findNavTree(@RequestParam String userName) { 46 | return HttpResult.ok(sysMenuService.findTree(userName, 1)); 47 | } 48 | 49 | @GetMapping("/findMenuTree") 50 | @ApiOperation("获取菜单树") 51 | @PreAuthorize("hasAuthority('sys:menu:view')") 52 | public HttpResult findMenuTree() { 53 | return HttpResult.ok(sysMenuService.findTree(null, 0)); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/controller/SysRoleController.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 用户角色接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 22:27 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.controller; 8 | 9 | import com.huawei.l00379880.admin.constant.SysConstants; 10 | import com.huawei.l00379880.admin.mapper.SysRoleMapper; 11 | import com.huawei.l00379880.admin.model.SysRole; 12 | import com.huawei.l00379880.admin.model.SysRoleMenu; 13 | import com.huawei.l00379880.admin.service.SysRoleService; 14 | import com.huawei.l00379880.core.http.HttpResult; 15 | import com.huawei.l00379880.core.page.PageRequest; 16 | import io.swagger.annotations.Api; 17 | import io.swagger.annotations.ApiOperation; 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.security.access.prepost.PreAuthorize; 20 | import org.springframework.web.bind.annotation.*; 21 | 22 | import java.util.List; 23 | 24 | @RestController 25 | @RequestMapping("/role") 26 | @Api(tags = "用户角色接口") 27 | public class SysRoleController { 28 | @Autowired 29 | private SysRoleService sysRoleService; 30 | @Autowired 31 | private SysRoleMapper sysRoleMapper; 32 | 33 | @PostMapping("/save") 34 | @ApiOperation("修改角色") 35 | @PreAuthorize("hasAuthority('sys:role:add') AND hasAuthority('sys:role:edit')") 36 | public HttpResult save(@RequestBody SysRole record) { 37 | SysRole role = sysRoleService.findById(record.getId()); 38 | if (role != null) { 39 | if (SysConstants.ADMIN.equalsIgnoreCase(role.getName())) { 40 | return HttpResult.error("超级管理员不允许修改!"); 41 | } 42 | } 43 | // 新增角色 44 | List sysRoles = sysRoleService.findByName(record.getName()); 45 | if ((record.getId() == null || record.getId() == 0) && !sysRoles.isEmpty()) { 46 | return HttpResult.error("角色名已存在!"); 47 | } 48 | return HttpResult.ok(sysRoleService.save(record)); 49 | } 50 | 51 | @PostMapping("/delete") 52 | @ApiOperation("删除角色") 53 | @PreAuthorize("hasAuthority('sys:role:delete')") 54 | public HttpResult delete(@RequestBody List records) { 55 | return HttpResult.ok(sysRoleService.delete(records)); 56 | } 57 | 58 | @PostMapping("/findPage") 59 | @ApiOperation("拿到角色分页列表") 60 | @PreAuthorize("hasAuthority('sys:role:view')") 61 | public HttpResult findPage(@RequestBody PageRequest pageRequest) { 62 | return HttpResult.ok(sysRoleService.findPage(pageRequest)); 63 | } 64 | 65 | @GetMapping("/findAll") 66 | @ApiOperation("获取所有的角色列表") 67 | @PreAuthorize("hasAuthority('sys:role:view')") 68 | public HttpResult findAll() { 69 | return HttpResult.ok(sysRoleService.findAll()); 70 | } 71 | 72 | @GetMapping("/findRoleMenus") 73 | @ApiOperation("获取指定角色的可访问菜单") 74 | @PreAuthorize("hasAuthority('sys:role:view')") 75 | public HttpResult findRoleMenus(@RequestParam Long roleId) { 76 | return HttpResult.ok(sysRoleService.findRoleMenus(roleId)); 77 | } 78 | 79 | @PostMapping("/saveRoleMenus") 80 | @ApiOperation("更新指定角色的可访问菜单") 81 | @PreAuthorize("hasAuthority('sys:role:edit')") 82 | public HttpResult saveRoleMenus(@RequestBody List records) { 83 | for (SysRoleMenu record : records) { 84 | SysRole sysRole = sysRoleMapper.selectByPrimaryKey(record.getRoleId()); 85 | if (SysConstants.ADMIN.equalsIgnoreCase(sysRole.getName())) { 86 | // 如果是超级管理员,不允许修改 87 | return HttpResult.error("超级管理员拥有所有菜单权限,不允许修改!"); 88 | } 89 | } 90 | return HttpResult.ok(sysRoleService.saveRoleMenus(records)); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/MyBatisBaseDao.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | /** 8 | * DAO公共基类,由MybatisGenerator自动生成请勿修改 9 | * @param The Model Class 这里是泛型不是Model类 10 | * @param The Primary Key Class 如果是无主键,则可以用Model来跳过,如果是多主键则是Key类 11 | */ 12 | public interface MyBatisBaseDao { 13 | int deleteByPrimaryKey(PK id); 14 | 15 | int insert(Model record); 16 | 17 | int insertSelective(Model record); 18 | 19 | Model selectByPrimaryKey(PK id); 20 | 21 | int updateByPrimaryKeySelective(Model record); 22 | 23 | int updateByPrimaryKey(Model record); 24 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysConfigMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysConfig; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysConfigMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysConfigMapper extends MyBatisBaseDao { 16 | /** 17 | * 获取系统配置的分页结果 18 | * 19 | * @return 系统配置 20 | */ 21 | List findPage(); 22 | 23 | /** 24 | * 根据设置名拿到设置对象 25 | * 26 | * @param label 设置名 27 | * @return 设置对象 28 | */ 29 | List findByLabel(@Param("label") String label); 30 | 31 | /** 32 | * 根据设置名拿到设置分页对象 33 | * 34 | * @param label 设置名 35 | * @return 设置对象 36 | */ 37 | List findPageByLabel(@Param("label") String label); 38 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysDeptMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysDept; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * SysDeptMapper继承基类 10 | * 11 | * @author liangshanguang 12 | */ 13 | @Repository 14 | public interface SysDeptMapper extends MyBatisBaseDao { 15 | /** 16 | * 获取机构的分页信息 17 | * 18 | * @return 结构分页信息 19 | */ 20 | List findPage(); 21 | 22 | /** 23 | * 获取所有的机构信息 24 | * 25 | * @return 所有的结构信息 26 | */ 27 | List findAll(); 28 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysDictMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysDict; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysDictMapper继承基类 11 | * @author liangshanguang 12 | */ 13 | @Repository 14 | public interface SysDictMapper extends MyBatisBaseDao { 15 | /** 16 | * 分页查询 17 | * 18 | * @return 分页对象 19 | */ 20 | List findPage(); 21 | 22 | /** 23 | * 根据标签名进行查询 24 | * 25 | * @param label 标签名 26 | * @return 数据列表 27 | */ 28 | List findByLabel(@Param(value = "label") String label); 29 | 30 | /** 31 | * 根据标签名进行分页查询 32 | * 33 | * @param label 标签名 34 | * @return 分页对象 35 | */ 36 | List findPageByLabel(@Param(value = "label") String label); 37 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysLog; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysLogMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysLogMapper extends MyBatisBaseDao { 16 | /** 17 | * 获取所有的的系统日志 18 | * 19 | * @return 所有数据的分页对象 20 | */ 21 | List findPage(); 22 | 23 | /** 24 | * 根据用户名进行模糊查询 25 | * 26 | * @param userName 用户名,不必是完整的用户名 27 | * @return 符合条件的日志组成的对象 28 | */ 29 | List findPageByUserName(@Param("userName") String userName); 30 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysLoginLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysLoginLog; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysLoginLogMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysLoginLogMapper extends MyBatisBaseDao { 16 | /** 17 | * 获取所有登录日志 18 | * 19 | * @return 登录日志分页列表 20 | */ 21 | List findPage(); 22 | 23 | /** 24 | * 根据用户名进行模糊查询获得登录日志 25 | * 26 | * @param userName 用户名,不必写全 27 | * @return 日志分页列表 28 | */ 29 | List findPageByUserName(@Param("userName") String userName); 30 | 31 | /** 32 | * 根据登录状态筛选登录日志 33 | * 34 | * @param status 登录状态 35 | * @return 登录日志的分页列表 36 | */ 37 | List findPageByStatus(@Param("status") String status); 38 | 39 | /** 40 | * 根据用户名和和状态得到用户登录日志列表 41 | * 42 | * @param userName 用户名 43 | * @param status 账号状态 44 | * @return 登录日志 45 | */ 46 | List findByUserNameAndStatus(@Param("userName") String userName, @Param("status") String status); 47 | 48 | /** 49 | * 根据用户名和和状态得到用户登录分页日志列表 50 | * 51 | * @param userName 用户名 52 | * @param status 账号状态 53 | * @return 登录日志 54 | */ 55 | List findPageByUserNameAndStatus(@Param(value = "userName") String userName, @Param(value = "status") String status); 56 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysMenu; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysMenuMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysMenuMapper extends MyBatisBaseDao { 16 | List findPage(); 17 | 18 | List findPageByName(@Param("name") String name); 19 | 20 | List findAll(); 21 | 22 | List findByUserName(@Param("userName") String userName); 23 | 24 | List findRoleMenus(@Param("roleId") Long roleId); 25 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysRoleDeptMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysRoleDept; 4 | import org.springframework.stereotype.Repository; 5 | 6 | /** 7 | * SysRoleDeptMapper继承基类 8 | */ 9 | @Repository 10 | public interface SysRoleDeptMapper extends MyBatisBaseDao { 11 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysRole; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysRoleMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysRoleMapper extends MyBatisBaseDao { 16 | /** 17 | * 获取所有角色,结果分页 18 | * 19 | * @return 分页结果 20 | */ 21 | List findPage(); 22 | 23 | /** 24 | * 获取所有的角色,不分页 25 | * 26 | * @return 角色列表 27 | */ 28 | List findAll(); 29 | 30 | /** 31 | * 根据角色名获取角色列表,name支持模糊搜索 32 | * 33 | * @param name 角色名,可以不输全 34 | * @return 角色列表,分页了 35 | */ 36 | List findPageByName(@Param(value = "name") String name); 37 | 38 | /** 39 | * 根据完整的角色名获取角色列表 40 | * 41 | * @param name 角色名,必须完整 42 | * @return 角色列表,不分页 43 | */ 44 | List findByName(@Param(value = "name") String name); 45 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysRoleMenuMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysRoleMenu; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysRoleMenuMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysRoleMenuMapper extends MyBatisBaseDao { 16 | /** 17 | * 获取指定角色可访问的菜单列表 18 | * 19 | * @param roleId 角色id 20 | * @return 菜单列表 21 | */ 22 | List findRoleMenus(@Param("roleId") Long roleId); 23 | 24 | /** 25 | * 获取所有的菜单列表 26 | * 27 | * @return 菜单列表 28 | */ 29 | List findAll(); 30 | 31 | /** 32 | * 删除角色 33 | * 34 | * @param roleId 角色id 35 | * @return 操作返回码 36 | */ 37 | int deleteByRoleId(@Param("roleId") Long roleId); 38 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysUser; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysUserMapper继承基类 11 | */ 12 | @Repository 13 | public interface SysUserMapper extends MyBatisBaseDao { 14 | /** 15 | * 查找所有用户 16 | * 17 | * @return 所有用户 18 | */ 19 | List findAll(); 20 | 21 | /** 22 | * 拿到分页对象 23 | * 24 | * @return 数据列表 25 | */ 26 | List findPage(); 27 | 28 | /** 29 | * 根据用户名查询用户 30 | * 31 | * @param name 用户名 32 | * @return 找到的用户 33 | */ 34 | SysUser findByName(@Param(value = "name") String name); 35 | 36 | /** 37 | * 根据用户名(模糊搜索)获取用户列表的分页对象 38 | * 39 | * @param name 用户名 40 | * @return 分页对象 41 | */ 42 | List findPageByName(@Param(value = "name") String name); 43 | 44 | /** 45 | * 根据用户名(模糊搜索)和邮箱(模糊搜索)获取分页对象 46 | * 47 | * @param name 用户名 48 | * @param email 邮箱 49 | * @return 分页对象 50 | */ 51 | List findPageByNameAndEmail(@Param(value = "name") String name, @Param(value = "email") String email); 52 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/SysUserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.mapper; 2 | 3 | import com.huawei.l00379880.admin.model.SysUserRole; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * SysUserRoleMapper继承基类 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Repository 15 | public interface SysUserRoleMapper extends MyBatisBaseDao { 16 | 17 | /** 18 | * 获取指定用户的角色列表 19 | * 20 | * @param userId 用户id 21 | * @return 角色列表 22 | */ 23 | List findUserRoles(@Param("userId") Long userId); 24 | 25 | /** 26 | * 根据用户id删除该用户下的所有角色 27 | * 28 | * @param userId 用户id 29 | * @return 操作返回码 30 | */ 31 | int deleteByUserId(@Param("userId") Long userId); 32 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/mapper/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 0:57 3 | * Description : 数据库操作的方法 4 | */ 5 | package com.huawei.l00379880.admin.mapper; -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/BaseModel.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 各个表都有的字段 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 17:47 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.model; 8 | 9 | import lombok.Data; 10 | 11 | import java.util.Date; 12 | 13 | @Data 14 | public class BaseModel { 15 | /** 16 | * 编号 17 | */ 18 | private Long id; 19 | /** 20 | * 创建人 21 | */ 22 | private String createBy; 23 | 24 | /** 25 | * 创建时间 26 | */ 27 | private Date createTime; 28 | 29 | /** 30 | * 更新人 31 | */ 32 | private String lastUpdateBy; 33 | 34 | /** 35 | * 更新时间 36 | */ 37 | private Date lastUpdateTime; 38 | } 39 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysConfig.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_config 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysConfig extends BaseModel { 14 | /** 15 | * 数据值 16 | */ 17 | private String value; 18 | 19 | /** 20 | * 标签名 21 | */ 22 | private String label; 23 | 24 | /** 25 | * 类型 26 | */ 27 | private String type; 28 | 29 | /** 30 | * 描述 31 | */ 32 | private String description; 33 | 34 | /** 35 | * 排序(升序) 36 | */ 37 | private Long sort; 38 | 39 | /** 40 | * 备注信息 41 | */ 42 | private String remarks; 43 | 44 | /** 45 | * 是否删除:-1已删除;0正常 46 | */ 47 | private Byte delFlag; 48 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysDept.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * sys_dept 10 | * 11 | * @author liangshanguang 12 | */ 13 | @Data 14 | @EqualsAndHashCode(callSuper = true) 15 | public class SysDept extends BaseModel { 16 | /** 17 | * 机构名称 18 | */ 19 | private String name; 20 | 21 | /** 22 | * 上级机构id,一级机构id为0 23 | */ 24 | private Long parentId; 25 | 26 | /** 27 | * 排序 28 | */ 29 | private Integer orderNum; 30 | 31 | /** 32 | * 是否删除:-1已删除;0正常 33 | */ 34 | private Byte delFlag; 35 | 36 | /** 37 | * 非数据库字段:该部门的字部门 38 | */ 39 | private List children; 40 | /** 41 | * 非数据库字段:上一级部门的名称 42 | */ 43 | private String parentName; 44 | /** 45 | * 非数据库字段:部门的级别 46 | */ 47 | private Integer level; 48 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysDict.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_dict 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysDict extends BaseModel { 14 | /** 15 | * 数据值 16 | */ 17 | private String value; 18 | 19 | /** 20 | * 标签名 21 | */ 22 | private String label; 23 | 24 | /** 25 | * 类型 26 | */ 27 | private String type; 28 | 29 | /** 30 | * 描述 31 | */ 32 | private String description; 33 | 34 | /** 35 | * 排序(升序) 36 | */ 37 | private Long sort; 38 | 39 | /** 40 | * 备注信息 41 | */ 42 | private String remarks; 43 | 44 | /** 45 | * 是否删除:-1已删除;0正常 46 | */ 47 | private Byte delFlag; 48 | 49 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysLog.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_log 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysLog extends BaseModel { 14 | /** 15 | * 用户名 16 | */ 17 | private String userName; 18 | 19 | /** 20 | * 用户操作 21 | */ 22 | private String operation; 23 | 24 | /** 25 | * 请求方法 26 | */ 27 | private String method; 28 | 29 | /** 30 | * 请求参数 31 | */ 32 | private String params; 33 | 34 | /** 35 | * 执行时长(毫秒) 36 | */ 37 | private Long time; 38 | 39 | /** 40 | * ip地址 41 | */ 42 | private String ip; 43 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysLoginLog.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_login_log 8 | * 9 | * @author liangshanguang 10 | */ 11 | 12 | @Data 13 | @EqualsAndHashCode(callSuper = true) 14 | public class SysLoginLog extends BaseModel { 15 | 16 | public static final String STATUS_LOGIN = "login"; 17 | public static final String STATUS_LOGOUT = "logout"; 18 | public static final String STATUS_ONLINE = "online"; 19 | 20 | /** 21 | * 用户名 22 | */ 23 | private String userName; 24 | 25 | /** 26 | * 登录状态:online在线,登录初始状态,方便统计在线人数;login:退出登录后将online置为login;logout:退出登录 27 | */ 28 | private String status; 29 | 30 | /** 31 | * ip地址 32 | */ 33 | private String ip; 34 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysMenu.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * sys_menu 10 | * 11 | * @author liangshanguang 12 | */ 13 | @Data 14 | @EqualsAndHashCode(callSuper = true) 15 | public class SysMenu extends BaseModel { 16 | /** 17 | * 菜单名称 18 | */ 19 | private String name; 20 | 21 | /** 22 | * 父菜单id,一级菜单id为0 23 | */ 24 | private Long parentId; 25 | 26 | /** 27 | * 菜单URL,类型有:1.普通vue路由入/sys/user;2.嵌套完整外部页面以http(s)开头的链接;3.嵌套服务器页面,使用iframe,用ifram://实际url的形式,在使用时会进行替换 28 | */ 29 | private String url; 30 | 31 | /** 32 | * 授权,多个用逗号分隔,入sys:user:add,sys:user:edit 33 | */ 34 | private String perms; 35 | 36 | /** 37 | * 类型:0目录;1菜单;2按钮 38 | */ 39 | private Integer type; 40 | 41 | /** 42 | * 菜单图标 43 | */ 44 | private String icon; 45 | 46 | /** 47 | * 排序 48 | */ 49 | private Integer orderNum; 50 | 51 | /** 52 | * 是否删除:-1已删除;0正常 53 | */ 54 | private Byte delFlag; 55 | 56 | /** 57 | * 非数据库字段:父菜单的名字 58 | */ 59 | private String parentName; 60 | /** 61 | * 非数据库字段:菜单层级 62 | */ 63 | private Integer level; 64 | /** 65 | * 非数据库字段:当前菜单的所有字菜单 66 | */ 67 | private List children; 68 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_role 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysRole extends BaseModel { 14 | /** 15 | * 角色名称 16 | */ 17 | private String name; 18 | 19 | /** 20 | * 备注 21 | */ 22 | private String remark; 23 | 24 | /** 25 | * 是否删除:-1已删除;0正常 26 | */ 27 | private Byte delFlag; 28 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysRoleDept.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_role_dept 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysRoleDept extends BaseModel { 14 | /** 15 | * 角色id 16 | */ 17 | private Long roleId; 18 | 19 | /** 20 | * 机构id 21 | */ 22 | private Long deptId; 23 | 24 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysRoleMenu.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_role_menu 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysRoleMenu extends BaseModel { 14 | /** 15 | * 角色id 16 | */ 17 | private Long roleId; 18 | 19 | /** 20 | * 菜单id 21 | */ 22 | private Long menuId; 23 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysUser.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * sys_user 11 | * 12 | * @author liangshanguang 13 | */ 14 | @Data 15 | @EqualsAndHashCode(callSuper = true) 16 | public class SysUser extends BaseModel { 17 | 18 | 19 | /** 20 | * 用户名 21 | */ 22 | private String name; 23 | 24 | /** 25 | * 昵称 26 | */ 27 | private String nickName; 28 | 29 | /** 30 | * 头像 31 | */ 32 | private String avatar; 33 | 34 | /** 35 | * 密码 36 | */ 37 | private String password; 38 | 39 | /** 40 | * 加密盐 41 | */ 42 | private String salt; 43 | 44 | /** 45 | * 邮箱 46 | */ 47 | private String email; 48 | 49 | /** 50 | * 手机号 51 | */ 52 | private String mobile; 53 | 54 | /** 55 | * 状态: 0禁用;1正常 56 | */ 57 | private Byte status; 58 | 59 | /** 60 | * 机构id 61 | */ 62 | private Long deptId; 63 | 64 | /** 65 | * 是否删除:-1已删除;0正常 66 | */ 67 | private Byte delFlag; 68 | 69 | /** 70 | * 部门名称,非数据库字段,方便前端显示 71 | */ 72 | private String deptName; 73 | /** 74 | * 非数据库字段,角色列表拼接的字符串 75 | */ 76 | private String roleNames; 77 | /** 78 | * 非数据库字段:角色对象列表 79 | */ 80 | private List userRoles = new ArrayList<>(); 81 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/SysUserRole.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.admin.model; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | /** 7 | * sys_user_role 8 | * 9 | * @author liangshanguang 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = true) 13 | public class SysUserRole extends BaseModel { 14 | 15 | /** 16 | * 用户id 17 | */ 18 | private Long userId; 19 | 20 | /** 21 | * 角色id 22 | */ 23 | private Long roleId; 24 | } -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/model/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 0:57 3 | * Description : 数据库表对应的实体类 4 | */ 5 | package com.huawei.l00379880.admin.model; -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/GrantedAuthorityImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 权限封装 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/18 0:34 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.security; 8 | 9 | import org.springframework.security.core.GrantedAuthority; 10 | 11 | public class GrantedAuthorityImpl implements GrantedAuthority { 12 | private static final long serialVersionUID = 1L; 13 | 14 | private String authority; 15 | 16 | public GrantedAuthorityImpl(String authority) { 17 | this.authority = authority; 18 | } 19 | 20 | public void setAuthority(String authority) { 21 | this.authority = authority; 22 | } 23 | 24 | @Override 25 | public String getAuthority() { 26 | return this.authority; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/JwtAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 登录认证过滤器 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 23:47 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.security; 8 | 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.security.authentication.AuthenticationManager; 11 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 12 | 13 | import javax.servlet.FilterChain; 14 | import javax.servlet.ServletException; 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | import java.io.IOException; 18 | 19 | public class JwtAuthenticationFilter extends BasicAuthenticationFilter { 20 | @Autowired 21 | public JwtAuthenticationFilter(AuthenticationManager authenticationManager) { 22 | super(authenticationManager); 23 | } 24 | 25 | @Override 26 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { 27 | // 获取token,并检查登录状态 28 | SecurityUtils.checkAuthentication(request); 29 | chain.doFilter(request, response); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/JwtAuthenticationProvider.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 身份验证提供者 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/18 0:40 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.security; 8 | 9 | import com.huawei.l00379880.common.utils.PasswordEncoder; 10 | import org.springframework.security.authentication.BadCredentialsException; 11 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 12 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 13 | import org.springframework.security.core.AuthenticationException; 14 | import org.springframework.security.core.userdetails.UserDetails; 15 | import org.springframework.security.core.userdetails.UserDetailsService; 16 | 17 | public class JwtAuthenticationProvider extends DaoAuthenticationProvider { 18 | public JwtAuthenticationProvider(UserDetailsService userDetailsService) { 19 | setUserDetailsService(userDetailsService); 20 | } 21 | 22 | @Override 23 | protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 24 | if (authentication.getCredentials() == null) { 25 | logger.debug("Authentication failed: no credentials provided"); 26 | throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); 27 | } 28 | String presentPassword = authentication.getCredentials().toString(); 29 | String salt = ((JwtUserDetails) userDetails).getSalt(); 30 | // 覆写密码验证逻辑 31 | if (!new PasswordEncoder(salt).matches(userDetails.getPassword(), presentPassword)) { 32 | // 密码不正确,校验失败 33 | logger.debug("Authentication failed: password does not match stored value"); 34 | throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/JwtAuthenticationToken.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 自定义令牌对象 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/18 0:35 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.security; 8 | 9 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 10 | import org.springframework.security.core.GrantedAuthority; 11 | 12 | import java.util.Collection; 13 | 14 | public class JwtAuthenticationToken extends UsernamePasswordAuthenticationToken { 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | private String token; 19 | 20 | public JwtAuthenticationToken(Object principal, Object credentials) { 21 | super(principal, credentials); 22 | } 23 | 24 | public JwtAuthenticationToken(Object principal, Object credentials, String token) { 25 | super(principal, credentials); 26 | this.token = token; 27 | } 28 | 29 | 30 | public JwtAuthenticationToken(Object principal, Object credentials, Collection authorities, String token) { 31 | super(principal, credentials, authorities); 32 | this.token = token; 33 | } 34 | 35 | public String getToken() { 36 | return token; 37 | } 38 | 39 | public void setToken(String token) { 40 | this.token = token; 41 | } 42 | 43 | public static long getSerialVersionUID() { 44 | return serialVersionUID; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/JwtUserDetails.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 安全用户模型 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/18 0:45 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.security; 8 | 9 | import com.fasterxml.jackson.annotation.JsonIgnore; 10 | import org.springframework.security.core.GrantedAuthority; 11 | import org.springframework.security.core.userdetails.UserDetails; 12 | 13 | import java.util.Collection; 14 | 15 | public class JwtUserDetails implements UserDetails { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private String username; 20 | private String password; 21 | 22 | private String salt; 23 | private Collection authorities; 24 | 25 | public JwtUserDetails(String username, String password, String salt, Collection authorities) { 26 | this.username = username; 27 | this.password = password; 28 | this.salt = salt; 29 | this.authorities = authorities; 30 | } 31 | 32 | @Override 33 | public String getUsername() { 34 | return username; 35 | } 36 | 37 | @JsonIgnore 38 | @Override 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | 44 | public String getSalt() { 45 | return salt; 46 | } 47 | 48 | @Override 49 | public Collection getAuthorities() { 50 | return authorities; 51 | } 52 | 53 | @JsonIgnore 54 | @Override 55 | public boolean isAccountNonExpired() { 56 | return true; 57 | } 58 | 59 | @JsonIgnore 60 | @Override 61 | public boolean isAccountNonLocked() { 62 | return true; 63 | } 64 | 65 | @JsonIgnore 66 | @Override 67 | public boolean isCredentialsNonExpired() { 68 | return true; 69 | } 70 | 71 | @JsonIgnore 72 | @Override 73 | public boolean isEnabled() { 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 23:49 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.security; 8 | 9 | import org.springframework.security.authentication.AuthenticationManager; 10 | import org.springframework.security.core.Authentication; 11 | import org.springframework.security.core.context.SecurityContextHolder; 12 | import org.springframework.security.core.userdetails.UserDetails; 13 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | 17 | public class SecurityUtils { 18 | public static void checkAuthentication(HttpServletRequest request) { 19 | // 获取令牌并根据令牌获取登录认证信息 20 | Authentication authentication = JwtTokenUtils.getAuthenticationFromToken(request); 21 | // 设置登录认证信息到上下文 22 | SecurityContextHolder.getContext().setAuthentication(authentication); 23 | } 24 | 25 | 26 | public static Authentication getAuthentication() { 27 | if (SecurityContextHolder.getContext() == null) { 28 | return null; 29 | } 30 | return SecurityContextHolder.getContext().getAuthentication(); 31 | } 32 | 33 | public static String getUsername() { 34 | String username = null; 35 | Authentication authentication = getAuthentication(); 36 | if (authentication != null) { 37 | Object principal = authentication.getPrincipal(); 38 | if (principal instanceof UserDetails) { 39 | username = ((UserDetails) principal).getUsername(); 40 | } 41 | } 42 | return username; 43 | } 44 | 45 | /** 46 | * 获取用户名 47 | * 48 | * @param authentication 认证信息 49 | * @return 用户名 50 | */ 51 | public static String getUsername(Authentication authentication) { 52 | String username = null; 53 | if (authentication != null) { 54 | Object principal = authentication.getPrincipal(); 55 | if (principal instanceof UserDetails) { 56 | username = ((UserDetails) principal).getUsername(); 57 | } 58 | } 59 | return username; 60 | } 61 | 62 | /** 63 | * 系统登录认证 64 | * 65 | * @param request 用户请求 66 | * @param username 用户名 67 | * @param password 密码 68 | * @param authenticationManager 认证管理器 69 | * @return token对象 70 | */ 71 | public static JwtAuthenticationToken login(HttpServletRequest request, String username, String password, AuthenticationManager authenticationManager) { 72 | JwtAuthenticationToken token = new JwtAuthenticationToken(username, password); 73 | token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); 74 | // 执行登录认证过程 75 | Authentication authentication = authenticationManager.authenticate(token); 76 | // 认证成功,存储认证信息到上下文 77 | SecurityContextHolder.getContext().setAuthentication(authentication); 78 | // 生成令牌返回给客户端 79 | token.setToken(JwtTokenUtils.generateToken(authentication)); 80 | return token; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : UserDetailsService接口用于返回用户相关数据。它有loadUserByUsername()方法,根据username查询用户实体, 3 | * 可以实现该接口覆盖该方法,实现自定义获取用户过程。该接口实现类被DaoAuthenticationProvider 类使用,用于认证过程中载入用户信息 4 | * 5 | * @author : 梁山广(Liang Shan Guang) 6 | * @date : 2019/11/18 0:54 7 | * @email : liangshanguang2@gmail.com 8 | ***********************************************************/ 9 | package com.huawei.l00379880.admin.security; 10 | 11 | import com.huawei.l00379880.admin.model.SysUser; 12 | import com.huawei.l00379880.admin.service.SysUserService; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.security.core.GrantedAuthority; 15 | import org.springframework.security.core.userdetails.UserDetails; 16 | import org.springframework.security.core.userdetails.UserDetailsService; 17 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 18 | import org.springframework.stereotype.Service; 19 | 20 | import java.util.List; 21 | import java.util.Set; 22 | import java.util.stream.Collectors; 23 | 24 | @Service 25 | public class UserDetailsServiceImpl implements UserDetailsService { 26 | 27 | @Autowired 28 | private SysUserService sysUserService; 29 | 30 | @Override 31 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 32 | SysUser user = sysUserService.findByName(username); 33 | if (user == null) { 34 | throw new UsernameNotFoundException("该用户不存在!"); 35 | } 36 | // 用户权限列表,根据权限标识如@PreAuthorize("hasAuthority('sys:menu:view')")标注的接口对比,决定是否可以调用接口 37 | Set permissions = sysUserService.findPermissions(user.getName()); 38 | List grantedAuthorities = permissions.stream().map(GrantedAuthorityImpl::new).collect(Collectors.toList()); 39 | return new JwtUserDetails(user.getName(), user.getPassword(), user.getSalt(), grantedAuthorities); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/security/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 23:45 3 | * Description : 用于spring security的登录和认证过滤器 4 | */ 5 | package com.huawei.l00379880.admin.security; -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysConfigService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 配置接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 20:09 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysConfig; 10 | import com.huawei.l00379880.core.service.CurdService; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.List; 14 | 15 | public interface SysConfigService extends CurdService { 16 | List findByLabel(String label); 17 | } 18 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysDeptService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 部门管理接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:08 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysDept; 10 | import com.huawei.l00379880.core.service.CurdService; 11 | 12 | import java.util.List; 13 | 14 | public interface SysDeptService extends CurdService { 15 | /** 16 | * 查询部门树 17 | * 18 | * @return 部门树 19 | */ 20 | List findTree(); 21 | } 22 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysDictService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 字典管理接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 16:31 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysDict; 10 | import com.huawei.l00379880.core.service.CurdService; 11 | 12 | import java.util.List; 13 | 14 | public interface SysDictService extends CurdService { 15 | /** 16 | * 根据label名进行查询 17 | * 18 | * @param label 标签名 19 | * @return 字典对象列表 20 | */ 21 | List findByLabel(String label); 22 | } 23 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysLogService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 系统日志接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:32 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysLog; 10 | import com.huawei.l00379880.core.service.CurdService; 11 | 12 | public interface SysLogService extends CurdService { 13 | } 14 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysLoginLogService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 用户登录日志接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:49 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysLoginLog; 10 | import com.huawei.l00379880.core.service.CurdService; 11 | 12 | public interface SysLoginLogService extends CurdService { 13 | /** 14 | * 记录登录日志 15 | * 16 | * @param username 登录用户名 17 | * @param ipAddr 登录者的ip 18 | * @return 执行成功与否的错误码 19 | */ 20 | int writeLoginLog(String username, String ipAddr); 21 | } 22 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysMenuService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 菜单管理 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 19:11 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysMenu; 10 | import com.huawei.l00379880.core.service.CurdService; 11 | 12 | import java.util.List; 13 | 14 | public interface SysMenuService extends CurdService { 15 | /** 16 | * 查询菜单树,用户名和菜单类型均为空则查询全部 17 | * 18 | * @param userName 用户名 19 | * @param menuType 获取菜单类型,0:获取所有菜单,包含按钮,1:获取所有菜单,不包含按钮 20 | * @return 菜单树 21 | */ 22 | List findTree(String userName, int menuType); 23 | 24 | /** 25 | * 根据用户名得到菜单列表 26 | * 27 | * @param userName 用户名 28 | * @return 菜单列表 29 | */ 30 | List findByUser(String userName); 31 | } 32 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysRoleService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 角色接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 22:14 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysMenu; 10 | import com.huawei.l00379880.admin.model.SysRole; 11 | import com.huawei.l00379880.admin.model.SysRoleMenu; 12 | import com.huawei.l00379880.core.service.CurdService; 13 | 14 | import java.util.List; 15 | 16 | public interface SysRoleService extends CurdService { 17 | /** 18 | * 查询全部角色 19 | * 20 | * @return 全部角色的列表 21 | */ 22 | List findAll(); 23 | 24 | /** 25 | * 查询角色菜单集合 26 | * 27 | * @param roleId 角色的id 28 | * @return 查询指定角色下的菜单 29 | */ 30 | List findRoleMenus(Long roleId); 31 | 32 | /** 33 | * 保存角色菜单 34 | * 35 | * @param records 保存角色的菜单 36 | * @return 保存成功与否的标志 37 | */ 38 | int saveRoleMenus(List records); 39 | 40 | /** 41 | * 根据名称查询 42 | * 43 | * @param name 根据角色名查询角色列表 44 | * @return 角色列表 45 | */ 46 | List findByName(String name); 47 | } 48 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/SysUserService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 用户服务实现 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 1:51 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service; 8 | 9 | import com.huawei.l00379880.admin.model.SysUser; 10 | import com.huawei.l00379880.admin.model.SysUserRole; 11 | import com.huawei.l00379880.core.page.PageRequest; 12 | import com.huawei.l00379880.core.service.CurdService; 13 | 14 | import java.io.File; 15 | import java.util.List; 16 | import java.util.Set; 17 | 18 | public interface SysUserService extends CurdService { 19 | /** 20 | * 获取所有的用户信息 21 | * 22 | * @return 所有的用户信息 23 | */ 24 | List findAll(); 25 | 26 | /** 27 | * 根据完整的用户名获取指定用户的完整信息 28 | * 29 | * @param userName 用户名,非模糊查询 30 | * @return 用户对象 31 | */ 32 | SysUser findByName(String userName); 33 | 34 | /** 35 | * 获取指定用户的权限标志集合 36 | * 37 | * @param userName 用户名 38 | * @return 权限集合 39 | */ 40 | Set findPermissions(String userName); 41 | 42 | /** 43 | * 根据用户id获取用户的角色集合 44 | * 45 | * @param userId 用户id 46 | * @return 角色集合 47 | */ 48 | List findUserRoles(Long userId); 49 | 50 | /** 51 | * 生成用户信息的excel文件 52 | * 53 | * @param pageRequest 要导出的分页查询参数 54 | * @return 用户信息的对象 55 | */ 56 | File createUserExcelFile(PageRequest pageRequest); 57 | } 58 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/impl/SysConfigServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 配置接口的实现 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 20:11 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service.impl; 8 | 9 | import com.huawei.l00379880.admin.mapper.SysConfigMapper; 10 | import com.huawei.l00379880.admin.model.SysConfig; 11 | import com.huawei.l00379880.admin.service.SysConfigService; 12 | import com.huawei.l00379880.core.page.MyBatisPageHelper; 13 | import com.huawei.l00379880.core.page.PageRequest; 14 | import com.huawei.l00379880.core.page.PageResult; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.List; 19 | 20 | @Service 21 | public class SysConfigServiceImpl implements SysConfigService { 22 | 23 | @Autowired 24 | private SysConfigMapper sysConfigMapper; 25 | 26 | @Override 27 | public List findByLabel(String label) { 28 | return sysConfigMapper.findByLabel(label); 29 | } 30 | 31 | @Override 32 | public int save(SysConfig record) { 33 | if (record.getId() == null || record.getId() == 0) { 34 | return sysConfigMapper.insertSelective(record); 35 | } 36 | return sysConfigMapper.updateByPrimaryKeySelective(record); 37 | } 38 | 39 | @Override 40 | public int delete(SysConfig record) { 41 | return sysConfigMapper.deleteByPrimaryKey(record.getId()); 42 | } 43 | 44 | @Override 45 | public int delete(List records) { 46 | for (SysConfig record : records) { 47 | delete(record); 48 | } 49 | return 1; 50 | } 51 | 52 | @Override 53 | public SysConfig findById(Long id) { 54 | return sysConfigMapper.selectByPrimaryKey(id); 55 | } 56 | 57 | @Override 58 | public PageResult findPage(PageRequest pageRequest) { 59 | Object label = pageRequest.getParamValue("label"); 60 | if (label != null) { 61 | return MyBatisPageHelper.findPage(pageRequest, sysConfigMapper, "findPageByLabel", label); 62 | } 63 | return MyBatisPageHelper.findPage(pageRequest, sysConfigMapper); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/impl/SysDeptServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:09 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service.impl; 8 | 9 | import com.huawei.l00379880.admin.mapper.SysDeptMapper; 10 | import com.huawei.l00379880.admin.model.SysDept; 11 | import com.huawei.l00379880.admin.service.SysDeptService; 12 | import com.huawei.l00379880.core.page.MyBatisPageHelper; 13 | import com.huawei.l00379880.core.page.PageRequest; 14 | import com.huawei.l00379880.core.page.PageResult; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | @Service 22 | public class SysDeptServiceImpl implements SysDeptService { 23 | @Autowired 24 | private SysDeptMapper sysDeptMapper; 25 | 26 | @Override 27 | public List findTree() { 28 | List sysDepts = new ArrayList<>(); 29 | List depts = sysDeptMapper.findAll(); 30 | for (SysDept dept : depts) { 31 | if (dept.getParentId() == null || dept.getParentId() == 0) { 32 | dept.setLevel(0); 33 | sysDepts.add(dept); 34 | } 35 | } 36 | findChildren(sysDepts, depts); 37 | return sysDepts; 38 | } 39 | 40 | private void findChildren(List sysDepts, List depts) { 41 | for (SysDept sysDept : sysDepts) { 42 | List children = new ArrayList<>(); 43 | for (SysDept dept : depts) { 44 | if (sysDept.getId() != null && sysDept.getId().equals(dept.getParentId())) { 45 | dept.setParentName(dept.getName()); 46 | dept.setLevel(sysDept.getLevel() + 1); 47 | children.add(dept); 48 | } 49 | } 50 | sysDept.setChildren(children); 51 | // 递归获取部门树,层级可以无限延展 52 | findChildren(children, depts); 53 | } 54 | } 55 | 56 | @Override 57 | public int save(SysDept record) { 58 | if (record.getId() == null || record.getId() == 0) { 59 | return sysDeptMapper.insertSelective(record); 60 | } 61 | return sysDeptMapper.updateByPrimaryKeySelective(record); 62 | } 63 | 64 | @Override 65 | public int delete(SysDept record) { 66 | return sysDeptMapper.deleteByPrimaryKey(record.getId()); 67 | } 68 | 69 | @Override 70 | public int delete(List records) { 71 | for (SysDept record : records) { 72 | delete(record); 73 | } 74 | return 1; 75 | } 76 | 77 | @Override 78 | public SysDept findById(Long id) { 79 | return sysDeptMapper.selectByPrimaryKey(id); 80 | } 81 | 82 | @Override 83 | public PageResult findPage(PageRequest pageRequest) { 84 | return MyBatisPageHelper.findPage(pageRequest, sysDeptMapper); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/impl/SysDictServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 字段管理接口实现 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 16:32 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service.impl; 8 | 9 | import com.huawei.l00379880.admin.mapper.SysDictMapper; 10 | import com.huawei.l00379880.admin.model.SysDict; 11 | import com.huawei.l00379880.admin.service.SysDictService; 12 | import com.huawei.l00379880.core.page.MyBatisPageHelper; 13 | import com.huawei.l00379880.core.page.PageRequest; 14 | import com.huawei.l00379880.core.page.PageResult; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.List; 19 | 20 | @Service 21 | public class SysDictServiceImpl implements SysDictService { 22 | 23 | @Autowired 24 | private SysDictMapper sysDictMapper; 25 | 26 | @Override 27 | public List findByLabel(String label) { 28 | return sysDictMapper.findByLabel(label); 29 | } 30 | 31 | @Override 32 | public int save(SysDict record) { 33 | if (record.getId() == null || record.getId() == 0) { 34 | return sysDictMapper.insertSelective(record); 35 | } 36 | return sysDictMapper.updateByPrimaryKeySelective(record); 37 | } 38 | 39 | @Override 40 | public int delete(SysDict record) { 41 | return sysDictMapper.deleteByPrimaryKey(record.getId()); 42 | } 43 | 44 | @Override 45 | public int delete(List records) { 46 | for (SysDict record : records) { 47 | delete(record); 48 | } 49 | return 1; 50 | } 51 | 52 | @Override 53 | public SysDict findById(Long id) { 54 | return sysDictMapper.selectByPrimaryKey(id); 55 | } 56 | 57 | @Override 58 | public PageResult findPage(PageRequest pageRequest) { 59 | Object label = pageRequest.getParamValue("label"); 60 | if (label != null) { 61 | return MyBatisPageHelper.findPage(pageRequest, sysDictMapper, "findPageByLabel", label); 62 | } 63 | return MyBatisPageHelper.findPage(pageRequest, sysDictMapper); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/impl/SysLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 系统日志接口的实现类 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:33 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service.impl; 8 | 9 | import com.huawei.l00379880.admin.mapper.SysLogMapper; 10 | import com.huawei.l00379880.admin.model.SysLog; 11 | import com.huawei.l00379880.admin.service.SysLogService; 12 | import com.huawei.l00379880.core.page.MyBatisPageHelper; 13 | import com.huawei.l00379880.core.page.PageRequest; 14 | import com.huawei.l00379880.core.page.PageResult; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.List; 19 | 20 | @Service 21 | public class SysLogServiceImpl implements SysLogService { 22 | 23 | @Autowired 24 | private SysLogMapper sysLogMapper; 25 | 26 | @Override 27 | public int save(SysLog record) { 28 | if (record.getId() == null || record.getId() == 0) { 29 | return sysLogMapper.insertSelective(record); 30 | } 31 | return sysLogMapper.updateByPrimaryKeySelective(record); 32 | } 33 | 34 | @Override 35 | public int delete(SysLog record) { 36 | return sysLogMapper.deleteByPrimaryKey(record.getId()); 37 | } 38 | 39 | @Override 40 | public int delete(List records) { 41 | for (SysLog record : records) { 42 | delete(record); 43 | } 44 | return 1; 45 | } 46 | 47 | @Override 48 | public SysLog findById(Long id) { 49 | return sysLogMapper.selectByPrimaryKey(id); 50 | } 51 | 52 | @Override 53 | public PageResult findPage(PageRequest pageRequest) { 54 | Object label = pageRequest.getParamValue("userName"); 55 | if (label != null) { 56 | return MyBatisPageHelper.findPage(pageRequest, sysLogMapper, "findPageByUserName", label); 57 | } 58 | return MyBatisPageHelper.findPage(pageRequest, sysLogMapper); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/impl/SysLoginLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 用户登录日志获取接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 21:50 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service.impl; 8 | 9 | import com.huawei.l00379880.admin.mapper.SysLoginLogMapper; 10 | import com.huawei.l00379880.admin.model.SysLoginLog; 11 | import com.huawei.l00379880.admin.service.SysLoginLogService; 12 | import com.huawei.l00379880.core.page.MyBatisPageHelper; 13 | import com.huawei.l00379880.core.page.PageRequest; 14 | import com.huawei.l00379880.core.page.PageResult; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.transaction.annotation.Transactional; 18 | 19 | import java.util.List; 20 | 21 | @Service 22 | public class SysLoginLogServiceImpl implements SysLoginLogService { 23 | @Autowired 24 | private SysLoginLogMapper sysLoginLogMapper; 25 | 26 | @Override 27 | public int save(SysLoginLog record) { 28 | if (record.getId() == null || record.getId() == 0) { 29 | return sysLoginLogMapper.insertSelective(record); 30 | } 31 | return sysLoginLogMapper.updateByPrimaryKeySelective(record); 32 | } 33 | 34 | @Override 35 | public int delete(SysLoginLog record) { 36 | return sysLoginLogMapper.deleteByPrimaryKey(record.getId()); 37 | } 38 | 39 | @Override 40 | public int delete(List records) { 41 | for (SysLoginLog record : records) { 42 | delete(record); 43 | } 44 | return 1; 45 | } 46 | 47 | @Override 48 | public SysLoginLog findById(Long id) { 49 | return sysLoginLogMapper.selectByPrimaryKey(id); 50 | } 51 | 52 | @Override 53 | public PageResult findPage(PageRequest pageRequest) { 54 | Object userName = pageRequest.getParamValue("userName"); 55 | if (userName != null) { 56 | return MyBatisPageHelper.findPage(pageRequest, sysLoginLogMapper, "findPageByUserName", userName); 57 | } 58 | Object status = pageRequest.getParamValue("status"); 59 | if (status != null) { 60 | return MyBatisPageHelper.findPage(pageRequest, sysLoginLogMapper, "findPageByStatus", status); 61 | } 62 | return MyBatisPageHelper.findPage(pageRequest, sysLoginLogMapper); 63 | } 64 | 65 | @Transactional(rollbackFor = Exception.class) 66 | @Override 67 | public int writeLoginLog(String userName, String ip) { 68 | List sysLoginLogs = sysLoginLogMapper.findByUserNameAndStatus(userName, SysLoginLog.STATUS_ONLINE); 69 | for (SysLoginLog sysLoginLog : sysLoginLogs) { 70 | sysLoginLog.setStatus(SysLoginLog.STATUS_LOGIN); 71 | sysLoginLogMapper.updateByPrimaryKey(sysLoginLog); 72 | } 73 | SysLoginLog record = new SysLoginLog(); 74 | record.setUserName(userName); 75 | record.setIp(ip); 76 | record.setStatus(SysLoginLog.STATUS_LOGOUT); 77 | sysLoginLogMapper.insertSelective(record); 78 | record.setStatus(SysLoginLog.STATUS_ONLINE); 79 | sysLoginLogMapper.insertSelective(record); 80 | return 0; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/service/impl/SysRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 角色列表 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 22:17 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.service.impl; 8 | 9 | import com.huawei.l00379880.admin.constant.SysConstants; 10 | import com.huawei.l00379880.admin.mapper.SysMenuMapper; 11 | import com.huawei.l00379880.admin.mapper.SysRoleMapper; 12 | import com.huawei.l00379880.admin.mapper.SysRoleMenuMapper; 13 | import com.huawei.l00379880.admin.model.SysMenu; 14 | import com.huawei.l00379880.admin.model.SysRole; 15 | import com.huawei.l00379880.admin.model.SysRoleMenu; 16 | import com.huawei.l00379880.admin.service.SysRoleService; 17 | import com.huawei.l00379880.core.page.MyBatisPageHelper; 18 | import com.huawei.l00379880.core.page.PageRequest; 19 | import com.huawei.l00379880.core.page.PageResult; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.stereotype.Service; 22 | 23 | import java.util.List; 24 | 25 | @Service 26 | public class SysRoleServiceImpl implements SysRoleService { 27 | 28 | @Autowired 29 | private SysRoleMapper sysRoleMapper; 30 | @Autowired 31 | private SysRoleMenuMapper sysRoleMenuMapper; 32 | @Autowired 33 | private SysMenuMapper sysMenuMapper; 34 | 35 | @Override 36 | public List findAll() { 37 | return sysRoleMapper.findAll(); 38 | } 39 | 40 | @Override 41 | public List findRoleMenus(Long roleId) { 42 | SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleId); 43 | if (SysConstants.ADMIN.equalsIgnoreCase(sysRole.getName())) { 44 | // 如果是超级管理员,返回全部 45 | return sysMenuMapper.findAll(); 46 | } 47 | return sysMenuMapper.findRoleMenus(roleId); 48 | } 49 | 50 | @Override 51 | public int saveRoleMenus(List records) { 52 | if (records == null || records.isEmpty()) { 53 | return 1; 54 | } 55 | Long roleId = records.get(0).getRoleId(); 56 | sysRoleMenuMapper.deleteByRoleId(roleId); 57 | for (SysRoleMenu record : records) { 58 | sysRoleMenuMapper.insertSelective(record); 59 | } 60 | return 1; 61 | } 62 | 63 | @Override 64 | public List findByName(String name) { 65 | return sysRoleMapper.findByName(name); 66 | } 67 | 68 | @Override 69 | public int save(SysRole record) { 70 | if (record.getId() == null || record.getId() == 0) { 71 | return sysRoleMapper.insertSelective(record); 72 | } 73 | return sysRoleMapper.updateByPrimaryKeySelective(record); 74 | } 75 | 76 | @Override 77 | public int delete(SysRole record) { 78 | return sysRoleMapper.deleteByPrimaryKey(record.getId()); 79 | } 80 | 81 | @Override 82 | public int delete(List records) { 83 | for (SysRole record : records) { 84 | delete(record); 85 | } 86 | return 1; 87 | } 88 | 89 | @Override 90 | public SysRole findById(Long id) { 91 | return sysRoleMapper.selectByPrimaryKey(id); 92 | } 93 | 94 | @Override 95 | public PageResult findPage(PageRequest pageRequest) { 96 | Object label = pageRequest.getParamValue("name"); 97 | if (label != null) { 98 | return MyBatisPageHelper.findPage(pageRequest, sysRoleMapper, "findPageByName", label); 99 | } 100 | return MyBatisPageHelper.findPage(pageRequest, sysRoleMapper); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/utils/HttpUtils.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/29 0:15 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.utils; 8 | 9 | import java.io.IOException; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | 14 | import com.huawei.l00379880.core.http.HttpResult; 15 | import org.springframework.web.context.request.RequestContextHolder; 16 | import org.springframework.web.context.request.ServletRequestAttributes; 17 | 18 | import com.alibaba.fastjson.JSONObject; 19 | 20 | /** 21 | * HTTP工具类 22 | * 23 | * @author Louis 24 | * @date Jan 19, 2019 25 | */ 26 | public class HttpUtils { 27 | 28 | /** 29 | * 获取HttpServletRequest对象 30 | * 31 | * @return 32 | */ 33 | public static HttpServletRequest getHttpServletRequest() { 34 | return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 35 | } 36 | 37 | /** 38 | * 输出信息到浏览器 39 | * 40 | * @param response 响应体 41 | * @param code 返回码 42 | * @param msg 提示消息 43 | * @throws IOException 44 | */ 45 | public static void print(HttpServletResponse response, int code, String msg) throws IOException { 46 | response.setContentType("application/json; charset=utf-8"); 47 | HttpResult result = HttpResult.error(code, msg); 48 | String json = JSONObject.toJSONString(result); 49 | response.getWriter().print(json); 50 | response.getWriter().flush(); 51 | response.getWriter().close(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/utils/IPUtils.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : IP工具类 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/29 0:18 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.utils; 8 | 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.util.StringUtils; 15 | 16 | /** 17 | * IP相关工具类 18 | */ 19 | public class IPUtils { 20 | private static Logger logger = LoggerFactory.getLogger(IPUtils.class); 21 | private static final String UNKNOWN = "unknown"; 22 | 23 | /** 24 | * 获取IP地址 25 | * 26 | * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 27 | * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 28 | */ 29 | public static String getIpAddr(HttpServletRequest request) { 30 | String ip = null; 31 | try { 32 | ip = request.getHeader("x-forwarded-for"); 33 | if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 34 | ip = request.getHeader("Proxy-Client-IP"); 35 | } 36 | if (StringUtils.isEmpty(ip) || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { 37 | ip = request.getHeader("WL-Proxy-Client-IP"); 38 | } 39 | if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 40 | ip = request.getHeader("HTTP_CLIENT_IP"); 41 | } 42 | if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 43 | ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 44 | } 45 | if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) { 46 | ip = request.getRemoteAddr(); 47 | } 48 | } catch (Exception e) { 49 | logger.error("IPUtils ERROR ", e); 50 | } 51 | 52 | // //使用代理,则获取第一个IP地址 53 | // if(StringUtils.isEmpty(ip) && ip.length() > 15) { 54 | // if(ip.indexOf(",") > 0) { 55 | // ip = ip.substring(0, ip.indexOf(",")); 56 | // } 57 | // } 58 | 59 | return ip; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/java/com/huawei/l00379880/admin/vo/LoginBean.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 登录时的传参 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/18 7:58 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.admin.vo; 8 | 9 | import lombok.Data; 10 | 11 | @Data 12 | public class LoginBean { 13 | String account; 14 | String password; 15 | String captcha; 16 | } 17 | -------------------------------------------------------------------------------- /code/backend/admin/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9528 3 | servlet: 4 | context-path: /api -------------------------------------------------------------------------------- /code/backend/admin/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9528 3 | servlet: 4 | context-path: # 这里配置为空是因为生产环境法需要自己配置nginx的转发,nginx可以参考我的配置doc/deploy/nginx.conf -------------------------------------------------------------------------------- /code/backend/admin/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev 4 | datasource: 5 | driver-class-name: com.mysql.cj.jdbc.Driver 6 | url: jdbc:mysql://localhost:3306/mango?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 7 | username: root 8 | password: aA111111 9 | # druid配置 10 | name: druidDataSource 11 | type: com.alibaba.druid.pool.DruidDataSource 12 | druid: 13 | # 配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙 14 | filters: stat,wall,config 15 | # 初始化数量 16 | initial-size: 1 17 | # 最大链接数 18 | max-active: 100 19 | # 获取链接的等待超时时间 20 | max-wait: 60000 21 | # 最小连接数 22 | min-idle: 1 23 | # 间隔多久需要进行一次检测,检测的目的是关闭空闲连接,单位毫秒 24 | time-between-eviction-runs-millis: 60000 25 | #配置一个连接在池中最小生存时间,单位是毫秒 26 | minEvictableIdleTimeMillis: 300000 27 | # 测试sql 28 | validation-query: select 'x' 29 | #建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 30 | test-while-idle: true 31 | # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 32 | test-on-borrow: false 33 | # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 34 | test-on-return: false 35 | # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 36 | pool-prepared-statements: true 37 | max-open-prepared-statements: 50 38 | # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 39 | max-pool-prepared-statement-per-connection-size: 20 40 | # druid的可视化界面的参数配置 41 | stat-view-servlet: 42 | enabled: true 43 | url-pattern: /druid/* 44 | reset-enable: true 45 | login-username: admin 46 | login-password: admin 47 | allow: 127.0.0.1 48 | deny: 192.168.10.1 49 | 50 | mybatis: 51 | mapper-locations: classpath:mapper/*.xml 52 | type-aliases-package: com.huawei.l00379880.admin.model 53 | configuration: 54 | map-underscore-to-camel-case: true 55 | 56 | pagehelper: 57 | helper-dialect: mysql 58 | params: count=countSql 59 | reasonable: true 60 | support-methods-arguments: true -------------------------------------------------------------------------------- /code/backend/admin/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | _ _ _ _ _ 2 | (_) | | | | | | (_) 3 | ___ _ __ _ __ _ _ __ __ _ ______ ___| | ___ _ _ __| |________ ___ _ ___ ______ __ _ __| |_ __ ___ _ _ __ 4 | / __| '_ \| '__| | '_ \ / _` |______/ __| |/ _ \| | | |/ _` |______\ \ / / | | |/ _ \______/ _` |/ _` | '_ ` _ \| | '_ \ 5 | \__ \ |_) | | | | | | | (_| | | (__| | (_) | |_| | (_| | \ V /| |_| | __/ | (_| | (_| | | | | | | | | | | 6 | |___/ .__/|_| |_|_| |_|\__, | \___|_|\___/ \__,_|\__,_| \_/ \__,_|\___| \__,_|\__,_|_| |_| |_|_|_| |_| 7 | | | __/ | 8 | |_| |___/ 9 | spring-cloud-vue-admin v0.1 -------------------------------------------------------------------------------- /code/backend/common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend 7 | com.huawei.l00379880 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | common 13 | 1.0-SNAPSHOT 14 | jar 15 | common 16 | admin module for backend 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | commons-beanutils 27 | commons-beanutils 28 | 1.9.3 29 | 30 | 31 | 32 | org.apache.poi 33 | poi-ooxml 34 | 4.0.1 35 | 36 | 37 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/DateTimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.common.utils; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | /** 7 | * 日期时间相关工具 8 | * 9 | * @author Louis 10 | * @date Jan 14, 2019 11 | */ 12 | public class DateTimeUtils { 13 | 14 | private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; 15 | 16 | /** 17 | * 获取当前标准格式化日期时间 18 | * 19 | * @return 当前时间的字符串 20 | */ 21 | public static String getDateTime() { 22 | return getDateTime(new Date()); 23 | } 24 | 25 | /** 26 | * 标准格式化日期时间 27 | * 28 | * @param date 要格式化的日期对象 29 | * @return 格式化后的日期 30 | */ 31 | public static String getDateTime(Date date) { 32 | return (new SimpleDateFormat(DATE_FORMAT)).format(date); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.common.utils; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.BufferedOutputStream; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.InputStream; 8 | 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | /** 12 | * 文件相关操作 13 | * 14 | * @author Louis 15 | * @date Jan 14, 2019 16 | */ 17 | public class FileUtils { 18 | 19 | /** 20 | * 下载文件 21 | * 22 | * @param response 相应 23 | * @param file 文件对象 24 | * @param newFileName 新的文件名 25 | */ 26 | public static void downloadFile(HttpServletResponse response, File file, String newFileName) { 27 | try { 28 | response.setHeader("Content-Disposition", "attachment; filename=" + new String(newFileName.getBytes("ISO-8859-1"), "UTF-8")); 29 | BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); 30 | InputStream is = new FileInputStream(file.getAbsolutePath()); 31 | BufferedInputStream bis = new BufferedInputStream(is); 32 | int length = 0; 33 | byte[] temp = new byte[1 * 1024 * 10]; 34 | while ((length = bis.read(temp)) != -1) { 35 | bos.write(temp, 0, length); 36 | } 37 | bos.flush(); 38 | bis.close(); 39 | bos.close(); 40 | is.close(); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/IOUtils.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.common.utils; 2 | 3 | import java.io.Closeable; 4 | import java.io.IOException; 5 | 6 | /** 7 | * IO相关工具类 8 | * 9 | * @author Louis 10 | * @date Oct 29, 2018 11 | */ 12 | public class IOUtils { 13 | 14 | /** 15 | * 关闭对象,连接 16 | * 17 | * @param closeable 可关闭的流对象 18 | */ 19 | public static void closeQuietly(final Closeable closeable) { 20 | try { 21 | if (closeable != null) { 22 | closeable.close(); 23 | } 24 | } catch (final IOException ioe) { 25 | // ignore 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/PasswordEncoder.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 密码加解密工具 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 19:30 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.common.utils; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | import java.security.MessageDigest; 11 | 12 | public class PasswordEncoder { 13 | 14 | private final static String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", 15 | "e", "f"}; 16 | 17 | private final static String MD5 = "MD5"; 18 | private final static String SHA = "SHA"; 19 | 20 | private Object salt; 21 | private String algorithm; 22 | 23 | public PasswordEncoder(Object salt) { 24 | this(salt, MD5); 25 | } 26 | 27 | public PasswordEncoder(Object salt, String algorithm) { 28 | this.salt = salt; 29 | this.algorithm = algorithm; 30 | } 31 | 32 | /** 33 | * 密码加密 34 | * 35 | * @param rawPass 原始密码 36 | * @return 加密后的密码 37 | */ 38 | public String encode(String rawPass) { 39 | String result = null; 40 | try { 41 | MessageDigest md = MessageDigest.getInstance(algorithm); 42 | // 加密后的字符串 43 | result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes(StandardCharsets.UTF_8))); 44 | } catch (Exception ex) { 45 | ex.printStackTrace(); 46 | } 47 | return result; 48 | } 49 | 50 | /** 51 | * 密码匹配验证 52 | * 53 | * @param encPass 密文 54 | * @param rawPass 明文 55 | * @return 验证密码和明文是否匹配 56 | */ 57 | public boolean matches(String encPass, String rawPass) { 58 | String pass1 = "" + encPass; 59 | String pass2 = encode(rawPass); 60 | 61 | return pass1.equals(pass2); 62 | } 63 | 64 | private String mergePasswordAndSalt(String password) { 65 | if (password == null) { 66 | password = ""; 67 | } 68 | 69 | if ((salt == null) || "".equals(salt)) { 70 | return password; 71 | } else { 72 | return password + "{" + salt.toString() + "}"; 73 | } 74 | } 75 | 76 | /** 77 | * 转换字节数组为16进制字串 78 | * 79 | * @param b 字节数组 80 | * @return 16进制字串 81 | */ 82 | private String byteArrayToHexString(byte[] b) { 83 | StringBuilder resultSb = new StringBuilder(); 84 | for (byte value : b) { 85 | resultSb.append(byteToHexString(value)); 86 | } 87 | return resultSb.toString(); 88 | } 89 | 90 | /** 91 | * 将字节转换为16进制 92 | * 93 | * @param b 要转换的字节 94 | * @return 转换后的16进制字节字符串 95 | */ 96 | private static String byteToHexString(byte b) { 97 | int n = b; 98 | if (n < 0) { 99 | n = 256 + n; 100 | } 101 | int d1 = n / 16; 102 | int d2 = n % 16; 103 | return HEX_DIGITS[d1] + HEX_DIGITS[d2]; 104 | } 105 | 106 | public static void main(String[] args) { 107 | String salt = "helloworld"; 108 | PasswordEncoder encoderMd5 = new PasswordEncoder(salt, "MD5"); 109 | String encode = encoderMd5.encode("test"); 110 | System.out.println(encode); 111 | boolean passwordValid = encoderMd5.matches("1bd98ed329aebc7b2f89424b5a38926e", "test"); 112 | System.out.println(passwordValid); 113 | 114 | PasswordEncoder encoderSha = new PasswordEncoder(salt, "SHA"); 115 | String pass2 = encoderSha.encode("test"); 116 | System.out.println(pass2); 117 | boolean passwordValid2 = encoderSha.matches("1bd98ed329aebc7b2f89424b5a38926e", "test"); 118 | System.out.println(passwordValid2); 119 | } 120 | } -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/PasswordUtils.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 密码操作工具类 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 19:34 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.common.utils; 8 | 9 | import java.util.UUID; 10 | 11 | public class PasswordUtils { 12 | /** 13 | * 匹配密码 14 | * 15 | * @param salt 盐 16 | * @param rawPass 明文 17 | * @param encPass 密文 18 | * @return 密码是否匹配 19 | */ 20 | public static boolean matches(String salt, String rawPass, String encPass) { 21 | return new PasswordEncoder(salt).matches(encPass, rawPass); 22 | } 23 | 24 | /** 25 | * 明文密码加密 26 | * 27 | * @param rawPass 明文 28 | * @param salt 里用盐加密 29 | * @return 加密后的字符串 30 | */ 31 | public static String encode(String rawPass, String salt) { 32 | return new PasswordEncoder(salt).encode(rawPass); 33 | } 34 | 35 | /** 36 | * 获取加密盐 37 | * 38 | * @return 加密盐 39 | */ 40 | public static String getSalt() { 41 | return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/PoiUtils.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.common.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.OutputStream; 8 | 9 | import org.apache.poi.ss.usermodel.Workbook; 10 | 11 | /** 12 | * POI相关操作 13 | * 14 | * @author Louis 15 | * @date Jan 14, 2019 16 | */ 17 | public class PoiUtils { 18 | 19 | /** 20 | * 生成Excel文件 21 | * 22 | * @param workbook excel对象 23 | * @param fileName 生成的excel文件名 24 | * @return 生成的excel文件对象 25 | */ 26 | public static File createExcelFile(Workbook workbook, String fileName) { 27 | OutputStream stream = null; 28 | File file = null; 29 | try { 30 | file = File.createTempFile(fileName, ".xlsx"); 31 | stream = new FileOutputStream(file.getAbsoluteFile()); 32 | workbook.write(stream); 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } finally { 36 | IOUtils.closeQuietly(workbook); 37 | IOUtils.closeQuietly(stream); 38 | } 39 | return file; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/ReflectionUtils.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.common.utils; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * 反射相关辅助方法 8 | * 9 | * @author Louis 10 | * @date Aug 19, 2018 11 | */ 12 | public class ReflectionUtils { 13 | 14 | 15 | /** 16 | * 根据方法名调用指定对象的方法 17 | * 18 | * @param object 要调用方法的对象 19 | * @param method 要调用的方法名 20 | * @param args 参数对象数组 21 | * @return 22 | */ 23 | public static Object invoke(Object object, String method, Object... args) { 24 | Object result = null; 25 | Class clazz = object.getClass(); 26 | Method queryMethod = getMethod(clazz, method, args); 27 | if (queryMethod != null) { 28 | try { 29 | result = queryMethod.invoke(object, args); 30 | } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 31 | e.printStackTrace(); 32 | } 33 | } else { 34 | try { 35 | throw new NoSuchMethodException(clazz.getName() + " 类中没有找到 " + method + " 方法。"); 36 | } catch (NoSuchMethodException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | return result; 41 | } 42 | 43 | /** 44 | * 根据方法名和参数对象查找方法 45 | * 46 | * @param clazz 对象 47 | * @param name 方法名 48 | * @param args 参数实例数据 49 | * @return 找到的方法 50 | */ 51 | public static Method getMethod(Class clazz, String name, Object[] args) { 52 | Method queryMethod = null; 53 | Method[] methods = clazz.getMethods(); 54 | for (Method method : methods) { 55 | if (method.getName().equals(name)) { 56 | Class[] parameterTypes = method.getParameterTypes(); 57 | if (parameterTypes.length == args.length) { 58 | boolean isSameMethod = true; 59 | for (int i = 0; i < parameterTypes.length; i++) { 60 | Object arg = args[i]; 61 | if (arg == null) { 62 | arg = ""; 63 | } 64 | if (!parameterTypes[i].equals(args[i].getClass())) { 65 | isSameMethod = false; 66 | } 67 | } 68 | if (isSameMethod) { 69 | queryMethod = method; 70 | break; 71 | } 72 | } 73 | } 74 | } 75 | return queryMethod; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /code/backend/common/src/main/java/com/huawei/l00379880/common/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.huawei.l00379880.common.utils; 2 | 3 | /** 4 | * 字符串工具类 5 | * 6 | * @author Louis 7 | * @date Sep 1, 2018 8 | */ 9 | public class StringUtils { 10 | 11 | /** 12 | * 判空操作 13 | * 14 | * @param value 要判断的字符串 15 | * @return true或false 16 | */ 17 | public static boolean isBlank(String value) { 18 | return value == null || "".equals(value) || "null".equals(value) || "undefined".equals(value); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /code/backend/core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend 7 | com.huawei.l00379880 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | core 13 | 14 | 15 | 16 | com.github.pagehelper 17 | pagehelper-spring-boot-starter 18 | 1.2.5 19 | 20 | 21 | com.huawei.l00379880 22 | common 23 | 1.0-SNAPSHOT 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | true 29 | 30 | 31 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/exception/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 12:38 3 | * Description : 异常信息封装 4 | */ 5 | package com.huawei.l00379880.core.exception; -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/http/HttpResult.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : HTTP结果封装 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 13:03 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.core.http; 8 | 9 | public class HttpResult { 10 | /** 11 | * 状态码,默认是200,表示请求成功 12 | */ 13 | private int code = 200; 14 | private String msg; 15 | private Object data; 16 | 17 | private static HttpResult error() { 18 | return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员!"); 19 | } 20 | 21 | public static HttpResult error(String msg) { 22 | return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg); 23 | } 24 | 25 | public static HttpResult error(int code, String msg) { 26 | HttpResult result = new HttpResult(); 27 | result.setCode(code); 28 | result.setMsg(msg); 29 | return result; 30 | } 31 | 32 | public static HttpResult ok(String msg) { 33 | HttpResult result = new HttpResult(); 34 | result.setMsg(msg); 35 | return result; 36 | } 37 | 38 | public static HttpResult ok(Object data) { 39 | HttpResult result = new HttpResult(); 40 | result.setData(data); 41 | return result; 42 | } 43 | 44 | public static HttpResult ok() { 45 | return new HttpResult(); 46 | } 47 | 48 | public int getCode() { 49 | return code; 50 | } 51 | 52 | public void setCode(int code) { 53 | this.code = code; 54 | } 55 | 56 | public String getMsg() { 57 | return msg; 58 | } 59 | 60 | public void setMsg(String msg) { 61 | this.msg = msg; 62 | } 63 | 64 | public Object getData() { 65 | return data; 66 | } 67 | 68 | public void setData(Object data) { 69 | this.data = data; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/http/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 12:39 3 | * Description : HTTP返回结果的封装 4 | */ 5 | package com.huawei.l00379880.core.http; -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/page/MyBatisPageHelper.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 分页查询助手 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 12:59 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.core.page; 8 | 9 | import com.github.pagehelper.PageHelper; 10 | import com.github.pagehelper.PageInfo; 11 | import com.huawei.l00379880.common.utils.ReflectionUtils; 12 | 13 | import java.util.List; 14 | 15 | public class MyBatisPageHelper { 16 | public static final String findPage = "findPage"; 17 | 18 | /** 19 | * 分页查询,约定查询方法为"findPage" 20 | * 21 | * @param pageRequest 分页请求 22 | * @param mapper dao对象,MyBatis的Mapper 23 | * @return 分页结果 24 | */ 25 | public static PageResult findPage(PageRequest pageRequest, Object mapper) { 26 | return findPage(pageRequest, mapper, findPage); 27 | } 28 | 29 | /** 30 | * 调用分页插件进行分页查询 31 | * 32 | * @param pageRequest 分页请求 33 | * @param mapper dao对象,MyBatis的Mapper 34 | * @param queryMethodName 查询方法名 35 | * @param args 额外的参数 36 | * @return 查询结果 37 | */ 38 | public static PageResult findPage(PageRequest pageRequest, Object mapper, String queryMethodName, Object... args) { 39 | // 设置分页参数 40 | int pageNum = pageRequest.getPageNum(); 41 | int pageSize = pageRequest.getPageSize(); 42 | PageHelper.startPage(pageNum, pageSize); 43 | // 里用反射调用方法 44 | Object result = ReflectionUtils.invoke(mapper, queryMethodName, args); 45 | return getPageResult(pageRequest, new PageInfo((List) result)); 46 | } 47 | 48 | /** 49 | * 将分页信息封装到统一的接口 50 | * 51 | * @param pageRequest 请求参数 52 | * @param pageInfo 分页信息对象 53 | * @return 分页结果 54 | */ 55 | private static PageResult getPageResult(PageRequest pageRequest, PageInfo pageInfo) { 56 | PageResult pageResult = new PageResult(); 57 | pageResult.setPageNum(pageInfo.getPageNum()); 58 | pageResult.setPageSize(pageInfo.getPageSize()); 59 | pageResult.setTotalSize(pageInfo.getTotal()); 60 | pageResult.setTotalPages(pageInfo.getPages()); 61 | pageResult.setContent(pageInfo.getList()); 62 | return pageResult; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/page/PageRequest.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 分页请求对象 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 12:48 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.core.page; 8 | 9 | import lombok.Data; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | @Data 15 | public class PageRequest { 16 | /** 17 | * 当前页码 18 | */ 19 | private int pageNum; 20 | 21 | /** 22 | * 每页数量 23 | */ 24 | private int pageSize; 25 | 26 | /** 27 | * 查询参数 28 | */ 29 | private List params = new ArrayList<>(); 30 | 31 | /** 32 | * 查询参数对象 33 | * 34 | * @param name Param的value 35 | * @return 指定的键值对对象 36 | */ 37 | public Param getParam(String name) { 38 | for (Param param : this.params) { 39 | if (name != null && name.equals(param.getName())) { 40 | return param; 41 | } 42 | } 43 | return null; 44 | } 45 | 46 | /** 47 | * 查询参数值 48 | * 49 | * @param name 参数名称 50 | * @return 参数值 51 | */ 52 | public String getParamValue(String name) { 53 | Param param = getParam(name); 54 | if (param != null) { 55 | return param.getValue(); 56 | } 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/page/PageResult.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 分页返回结果 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 12:48 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.core.page; 8 | 9 | import java.util.List; 10 | 11 | public class PageResult { 12 | /** 13 | * 当前页码 14 | */ 15 | private int pageNum; 16 | 17 | /** 18 | * 每页数量 19 | */ 20 | private int pageSize; 21 | 22 | /** 23 | * 记录总数 24 | */ 25 | private long totalSize; 26 | 27 | /** 28 | * 页码总数 29 | */ 30 | private int totalPages; 31 | 32 | /** 33 | * 分页数据 34 | */ 35 | private List content; 36 | 37 | public int getPageNum() { 38 | return pageNum; 39 | } 40 | 41 | public void setPageNum(int pageNum) { 42 | this.pageNum = pageNum; 43 | } 44 | 45 | public int getPageSize() { 46 | return pageSize; 47 | } 48 | 49 | public void setPageSize(int pageSize) { 50 | this.pageSize = pageSize; 51 | } 52 | 53 | public long getTotalSize() { 54 | return totalSize; 55 | } 56 | 57 | public void setTotalSize(long totalSize) { 58 | this.totalSize = totalSize; 59 | } 60 | 61 | public int getTotalPages() { 62 | return totalPages; 63 | } 64 | 65 | public void setTotalPages(int totalPages) { 66 | this.totalPages = totalPages; 67 | } 68 | 69 | public List getContent() { 70 | return content; 71 | } 72 | 73 | public void setContent(List content) { 74 | this.content = content; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/page/Param.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 封装页面参数 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/27 22:57 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.core.page; 8 | 9 | import lombok.Data; 10 | 11 | @Data 12 | public class Param { 13 | private String name; 14 | private String value; 15 | } 16 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/page/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 12:39 3 | * Description : 分页请求、相应对象;PageHelper实现地分页工具类 4 | */ 5 | package com.huawei.l00379880.core.page; -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/service/CurdService.java: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 封装基础的增删改查服务的接口 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/17 12:40 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | package com.huawei.l00379880.core.service; 8 | 9 | import com.huawei.l00379880.core.page.PageRequest; 10 | import com.huawei.l00379880.core.page.PageResult; 11 | 12 | import java.util.List; 13 | 14 | public interface CurdService { 15 | /** 16 | * 保存记录 17 | * 18 | * @param record 要保存到数据库的记录对象 19 | * @return 操作返回码 20 | */ 21 | int save(T record); 22 | 23 | /** 24 | * 删除指定的记录 25 | * 26 | * @param record 要删除的记录对象 27 | * @return 操作返回码 28 | */ 29 | int delete(T record); 30 | 31 | /** 32 | * 批量删除记录 33 | * 34 | * @param records 要删除的记录列表 35 | * @return 操作返回码 36 | */ 37 | int delete(List records); 38 | 39 | /** 40 | * 根据id查询指定的记录 41 | * 42 | * @param id 记录的id 43 | * @return 记录对象 44 | */ 45 | T findById(Long id); 46 | 47 | /** 48 | * 分页查询,这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 49 | *

50 | * 如MyBatis或JPA的分页对象从而避免因替换ORM框架导致服务层、控制层的分页接 51 | *

52 | * 口也需要变动的情况,替换ORM框架也不会影响服务层,所以这个分页接口起到了解耦的作用 53 | * 54 | * @param pageRequest 自己定义的统一分页查询请求 55 | * @return PageResult 自己定义的统一分页查询结果 56 | */ 57 | PageResult findPage(PageRequest pageRequest); 58 | } 59 | -------------------------------------------------------------------------------- /code/backend/core/src/main/java/com/huawei/l00379880/core/service/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By Liang Shan Guang at 2019/11/17 12:39 3 | * Description : 通用业务接口封装 4 | */ 5 | package com.huawei.l00379880.core.service; -------------------------------------------------------------------------------- /code/backend/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.huawei.l00379880 8 | backend 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | 13 | UTF-8 14 | UTF-8 15 | 1.8 16 | 17 | 18 | 19 | admin 20 | common 21 | core 22 | 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-parent 27 | 2.1.1.RELEASE 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-dependencies 41 | Finchley.RELEASE 42 | pom 43 | import 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | spring-milestones 52 | Spring Milestones 53 | https://repo.spring.io/libs-milestone 54 | 55 | false 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /code/frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /code/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /code/frontend/README.md: -------------------------------------------------------------------------------- 1 | # frontend 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | 26 | ### 常见到的问题 27 | 28 | + node-sass安装失败 29 | > 单独用命令安装`npm i node-sass@^4.12.0 --dev --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/` 30 | -------------------------------------------------------------------------------- /code/frontend/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /code/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.0", 12 | "core-js": "^3.3.2", 13 | "element-ui": "^2.13.0", 14 | "font-awesome": "^4.7.0", 15 | "js-cookie": "^2.2.1", 16 | "vue": "^2.6.10", 17 | "vue-i18n": "^8.15.0", 18 | "vue-router": "^3.1.3", 19 | "vuex": "^3.0.1" 20 | }, 21 | "devDependencies": { 22 | "@vue/cli-plugin-babel": "^4.0.0", 23 | "@vue/cli-plugin-eslint": "^4.0.0", 24 | "@vue/cli-plugin-router": "^4.0.0", 25 | "@vue/cli-plugin-vuex": "^4.0.0", 26 | "@vue/cli-service": "^4.0.0", 27 | "@vue/eslint-config-standard": "^4.0.0", 28 | "babel-eslint": "^10.0.3", 29 | "eslint": "^5.16.0", 30 | "eslint-plugin-vue": "^5.0.0", 31 | "fibers": "^3.1.0", 32 | "node-sass": "^4.13.0", 33 | "sass": "^1.23.7", 34 | "sass-loader": "^8.0.0", 35 | "vue-template-compiler": "^2.6.10" 36 | }, 37 | "eslintConfig": { 38 | "root": true, 39 | "env": { 40 | "node": true 41 | }, 42 | "extends": [ 43 | "plugin:vue/essential", 44 | "@vue/standard" 45 | ], 46 | "rules": {}, 47 | "parserOptions": { 48 | "parser": "babel-eslint" 49 | } 50 | }, 51 | "postcss": { 52 | "plugins": { 53 | "autoprefixer": {} 54 | } 55 | }, 56 | "browserslist": [ 57 | "> 1%", 58 | "last 2 versions" 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /code/frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/code/frontend/public/favicon.ico -------------------------------------------------------------------------------- /code/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | frontend 9 | 10 | 11 | 14 |

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /code/frontend/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | -------------------------------------------------------------------------------- /code/frontend/src/assets/languages/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "common": { 3 | "home": "Home", 4 | "login": "Login", 5 | "logout": "Logout", 6 | "doc": "Document", 7 | "blog": "Blog", 8 | "projectRepo": "Project", 9 | "myMsg": "Me Message", 10 | "config": "Config", 11 | "backup": "Backup", 12 | "restore": "Restore", 13 | "backupRestore": "Back Restore", 14 | "versionName": "Version", 15 | "exit": "Exit" 16 | }, 17 | "action": { 18 | "operation": "Operation", 19 | "add": "Add", 20 | "edit": "Edit", 21 | "delete": "Delete", 22 | "batchDelete": "Batch Delete", 23 | "search": "Search", 24 | "loading": "loading", 25 | "submit": "Submit", 26 | "confirm": "Confirm", 27 | "cancel": "Cancel", 28 | "reset": "Reset" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code/frontend/src/assets/languages/zh_cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "common": { 3 | "home": "首页", 4 | "login": "登录", 5 | "logout": "退出登录", 6 | "doc": "文档", 7 | "blog": "博客", 8 | "projectRepo": "项目", 9 | "myMsg": "我的消息", 10 | "config": "系统配置", 11 | "backup": "备份", 12 | "restore": "还原", 13 | "backupRestore": "备份还原", 14 | "versionName": "版本名称", 15 | "exit": "退出" 16 | }, 17 | "action": { 18 | "operation": "操作", 19 | "add": "新增", 20 | "edit": "编辑", 21 | "delete": "删除", 22 | "batchDelete": "批量删除", 23 | "search": "查询", 24 | "loading": "加载中", 25 | "submit": "提交", 26 | "confirm": "确定", 27 | "cancel": "取消", 28 | "reset": "重置" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code/frontend/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/code/frontend/src/assets/logo.png -------------------------------------------------------------------------------- /code/frontend/src/assets/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/code/frontend/src/assets/user.png -------------------------------------------------------------------------------- /code/frontend/src/components/Core/IFrame.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 51 | 52 | 66 | -------------------------------------------------------------------------------- /code/frontend/src/components/Core/KtButton.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 57 | 58 | 61 | -------------------------------------------------------------------------------- /code/frontend/src/components/Core/MessagePanel.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 81 | 82 | 154 | -------------------------------------------------------------------------------- /code/frontend/src/components/Core/NoticePanel.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 60 | 61 | 112 | -------------------------------------------------------------------------------- /code/frontend/src/components/Core/TableColumnFilterDialog.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 85 | 86 | 89 | -------------------------------------------------------------------------------- /code/frontend/src/components/Core/TableTreeColumn.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 85 | -------------------------------------------------------------------------------- /code/frontend/src/components/FaIconTooltip/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 31 | -------------------------------------------------------------------------------- /code/frontend/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 37 | 38 | 53 | -------------------------------------------------------------------------------- /code/frontend/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 44 | 45 | 46 | 62 | -------------------------------------------------------------------------------- /code/frontend/src/components/MenuTree/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 41 | 42 | 45 | -------------------------------------------------------------------------------- /code/frontend/src/components/PopupTreeInput/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 58 | 59 | 62 | -------------------------------------------------------------------------------- /code/frontend/src/components/Sys/Log.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 75 | 76 | 79 | -------------------------------------------------------------------------------- /code/frontend/src/components/Sys/Loginlog.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 73 | 74 | 77 | -------------------------------------------------------------------------------- /code/frontend/src/components/Sys/Online.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 73 | 74 | 77 | -------------------------------------------------------------------------------- /code/frontend/src/http/api.js: -------------------------------------------------------------------------------- 1 | import * as config from './modules/config' 2 | import * as dept from './modules/dept' 3 | import * as dict from './modules/dict' 4 | import * as log from './modules/log' 5 | import * as login from './modules/login' 6 | import * as loginlog from './modules/loginlog' 7 | import * as menu from './modules/menu' 8 | import * as role from './modules/role' 9 | import * as user from './modules/user' 10 | 11 | // 默认全部导出 12 | export default { 13 | config, dept, dict, log, login, loginlog, menu, role, user 14 | } 15 | -------------------------------------------------------------------------------- /code/frontend/src/http/axios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * axios拦截器,可以进行请求拦截和相应拦截,在发送请求和相应请求时执行一些操作 3 | */ 4 | import axios from 'axios' 5 | import config from './config' 6 | import Cookies from 'js-cookie' 7 | import router from '../router' 8 | 9 | export default function $axios (options) { 10 | // Promise是异步编程的一种解决方案, 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数(例如ajax调用) 11 | return new Promise((resolve, reject) => { 12 | const instance = axios.create({ 13 | baseURL: config.baseUrl, 14 | headers: config.headers, 15 | timeout: config.timeout, 16 | withCredentials: config.withCredentials 17 | }) 18 | 19 | // request请求拦截器 20 | instance.interceptors.request.use( 21 | config => { 22 | let token = Cookies.get('token') 23 | if (token) { // 如果Cookie里有token就在发送请求的时候带上。 24 | config.headers.token = token 25 | } else { // Cookie中没有token,说明用户还没登录,跳转到登录页 26 | router.push('/login') // 实际可以用this.$router.push('router中的路径')来进行跳转,因为在main.js中已经全局注册了router 27 | } 28 | return config 29 | }, 30 | error => { 31 | return Promise.reject(error) 32 | } 33 | ) 34 | 35 | // response响应拦截器 36 | instance.interceptors.response.use( 37 | response => { 38 | return response.data 39 | }, 40 | error => { 41 | return Promise.reject(error) 42 | } 43 | ) 44 | 45 | // 请求处理 46 | instance(options).then(res => { 47 | resolve(res) 48 | return false 49 | }).catch(error => { 50 | reject(error) 51 | }) 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /code/frontend/src/http/config.js: -------------------------------------------------------------------------------- 1 | import { baseUrl } from '../utils/global' 2 | 3 | export default { 4 | method: 'get', 5 | // 基础url前缀 6 | baseUrl: baseUrl, 7 | // 请求头信息 8 | headers: { 9 | 'Content-type': 'application/json;charset=UTF-8' 10 | }, 11 | // 参数 12 | data: {}, 13 | // 设置超时时间,单位毫秒 14 | timeout: 10000, 15 | // 携带凭证 16 | withCredentials: true, 17 | // 返回数据类型 18 | responseType: 'json' 19 | } 20 | -------------------------------------------------------------------------------- /code/frontend/src/http/index.js: -------------------------------------------------------------------------------- 1 | import api from './api' // 导入所有接口 2 | 3 | const install = Vue => { 4 | if (install.installed) { 5 | return 6 | } 7 | install.installed = true 8 | Object.defineProperties(Vue.prototype, { 9 | // 注意,此处挂载在Vue原型的$api对象上 10 | $api: { 11 | get () { 12 | return api 13 | } 14 | } 15 | }) 16 | } 17 | export default install 18 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/config.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const save = (data) => { 5 | return axios({ 6 | url: REST_URLS.ConfigSave, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const batchDelete = (data) => { 13 | return axios({ 14 | url: REST_URLS.ConfigDelete, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | 20 | export const findPage = (data) => { 21 | return axios({ 22 | url: REST_URLS.ConfigPage, 23 | method: 'post', 24 | data 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/dept.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const save = (data) => { 5 | return axios({ 6 | url: REST_URLS.DeptSave, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const batchDelete = (data) => { 13 | return axios({ 14 | url: REST_URLS.DeptDelete, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | 20 | export const findDeptTree = () => { 21 | return axios({ 22 | url: REST_URLS.DeptTree, 23 | method: 'get' 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/dict.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const save = (data) => { 5 | return axios({ 6 | url: REST_URLS.DictSave, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const batchDelete = (data) => { 13 | return axios({ 14 | url: REST_URLS.DictDelete, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | 20 | export const findPage = (data) => { 21 | return axios({ 22 | url: REST_URLS.DictPage, 23 | method: 'post', 24 | data 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 所有接口的url 3 | */ 4 | const modules = ['config', 'dept', 'dict', 'log', 'login', 'loginlog', 'menu', 'role', 'user'] 5 | const REST_URLS = { 6 | // 1.系统配置接口 7 | ConfigSave: `/${modules[0]}/save`, // 保存 8 | ConfigDelete: `/${modules[0]}/delete`, // 删除 9 | ConfigPage: `/${modules[0]}/findPage`, // 分页查询 10 | 11 | // 2.机构管理模块 12 | DeptSave: `/${modules[1]}/save`, // 保存 13 | DeptDelete: `/${modules[1]}/delete`, // 删除 14 | DeptTree: `/${modules[1]}/findTree`, // 查询机构树 15 | 16 | // 3.字典管理模块 17 | DictSave: `/${modules[2]}/save`, // 保存 18 | DictDelete: `/${modules[2]}/delete`, // 删除 19 | DictPage: `/${modules[2]}/findPage`, // 分页查询 20 | 21 | // 4.操作日志模块 22 | LogDelete: `/${modules[3]}/delete`, // 删除 23 | LogPage: `/${modules[3]}/findPage`, // 分页查询 24 | 25 | // 5.系统登录模块 26 | Login: `login`, // 登录 27 | Logout: `logout`, // 登出 28 | 29 | // 6.登录日志模块 30 | LoginlogDelete: `/${modules[5]}/delete`, 31 | LoginlogPage: `/${modules[5]}/findPage`, // 分页查询 32 | 33 | // 7.菜单管理模块 34 | MenuSave: `/${modules[6]}/save`, // 保存 35 | MenuDelete: `/${modules[6]}/delete`, // 删除 36 | MenuNavTree: `/${modules[6]}/findNavTree`, // 获取导航树 37 | MenuTree: `/${modules[6]}/findMenuTree`, // 获取菜单树 38 | 39 | // 8.角色管理模块 40 | RoleSave: `/${modules[7]}/save`, // 保存 41 | RoleDelete: `/${modules[7]}/delete`, // 删除 42 | RolePage: `/${modules[7]}/findPage`, // 分页查询 43 | RoleAll: `/${modules[7]}/findAll`, // 获取所有角色 44 | RoleMenusGet: `/${modules[7]}/findRoleMenus`, // 获取指定角色可以访问的菜单集合 45 | RoleMenusSave: `/${modules[7]}/saveRoleMenus`, // 保存指定角色可以访问的菜单集合 46 | 47 | // 9.用户管理模块 48 | UserSave: `/${modules[8]}/save`, // 保存 49 | UserDelete: `/${modules[8]}/delete`, // 删除 50 | UserPage: `/${modules[8]}/findPage`, // 分页查询 51 | UserPermissions: `/${modules[8]}/findPermissions` // 获取指定用户的菜单权限集合 52 | } 53 | export default REST_URLS 54 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/log.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const batchDelete = (data) => { 5 | return axios({ 6 | url: REST_URLS.LogDelete, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const findPage = (data) => { 13 | return axios({ 14 | url: REST_URLS.LogPage, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/login.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const login = (data) => { 5 | return axios({ 6 | url: REST_URLS.Login, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const logout = () => { 13 | return axios({ 14 | url: REST_URLS.Logout, 15 | method: 'get' 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/loginlog.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const batchDelete = (data) => { 5 | return axios({ 6 | url: REST_URLS.LoginlogDelete, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const findPage = (data) => { 13 | return axios({ 14 | url: REST_URLS.LoginlogPage, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/menu.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const save = (data) => { 5 | return axios({ 6 | url: REST_URLS.MenuSave, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const batchDelete = (data) => { 13 | return axios({ 14 | url: REST_URLS.MenuDelete, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | 20 | export const findNavTree = (params) => { 21 | return axios({ 22 | url: REST_URLS.MenuNavTree, 23 | method: 'get', 24 | params 25 | }) 26 | } 27 | 28 | export const findMenuTree = () => { 29 | return axios({ 30 | url: REST_URLS.MenuTree, 31 | method: 'get' 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/role.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const save = (data) => { 5 | return axios({ 6 | url: REST_URLS.RoleSave, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const batchDelete = (data) => { 13 | return axios({ 14 | url: REST_URLS.RoleDelete, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | 20 | export const findPage = (data) => { 21 | return axios({ 22 | url: REST_URLS.RolePage, 23 | method: 'post', 24 | data 25 | }) 26 | } 27 | 28 | export const findAll = () => { 29 | return axios({ 30 | url: REST_URLS.RoleAll, 31 | method: 'get' 32 | }) 33 | } 34 | 35 | export const findRoleMenus = (params) => { 36 | return axios({ 37 | url: REST_URLS.RoleMenusGet, 38 | method: 'get', 39 | params 40 | }) 41 | } 42 | 43 | export const saveRoleMenus = (data) => { 44 | return axios({ 45 | url: REST_URLS.RoleMenusSave, 46 | method: 'post', 47 | data 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /code/frontend/src/http/modules/user.js: -------------------------------------------------------------------------------- 1 | import axios from '../axios' 2 | import REST_URLS from './index' 3 | 4 | export const save = (data) => { 5 | return axios({ 6 | url: REST_URLS.UserSave, 7 | method: 'post', 8 | data 9 | }) 10 | } 11 | 12 | export const batchDelete = (data) => { 13 | return axios({ 14 | url: REST_URLS.UserDelete, 15 | method: 'post', 16 | data 17 | }) 18 | } 19 | 20 | export const findPage = (data) => { 21 | return axios({ 22 | url: REST_URLS.UserPage, 23 | method: 'post', 24 | data 25 | }) 26 | } 27 | 28 | export const findPermissions = (params) => { 29 | return axios({ 30 | url: REST_URLS.UserPermissions, 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /code/frontend/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import api from './http' 5 | import i18n from './utils/i18n' 6 | import global from './utils/global' 7 | import store from './store' 8 | import ElementUI from 'element-ui' 9 | import 'element-ui/lib/theme-chalk/index.css' 10 | import 'font-awesome/css/font-awesome.min.css' 11 | 12 | import Router from 'vue-router' 13 | 14 | // 避免$route.push的时候没有接住Promise表达式而报错 15 | const originalPush = Router.prototype.push 16 | Router.prototype.push = function push (location) { 17 | return originalPush.call(this, location).catch(err => err) 18 | } 19 | 20 | Vue.config.productionTip = false 21 | 22 | Vue.use(api) // 注册使用API模块 23 | 24 | Vue.use(ElementUI) // 注册使用ElementUI模块 25 | 26 | Vue.prototype.global = global // 挂载全局配置模块 27 | 28 | new Vue({ 29 | i18n, 30 | router, 31 | store, 32 | render: h => h(App) 33 | }).$mount('#app') 34 | -------------------------------------------------------------------------------- /code/frontend/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | // 引入子模块 5 | import app from './modules/app' 6 | import user from './modules/user' 7 | import menu from './modules/menu' 8 | import tab from './modules/tab' 9 | import iframe from './modules/iframe' 10 | 11 | Vue.use(Vuex) 12 | 13 | const store = new Vuex.Store({ 14 | state: {}, 15 | mutations: {}, 16 | actions: {}, 17 | modules: { 18 | app: app, // 键值相同时应该可以缩写成单个的app,这里就不省略了 19 | iframe: iframe, 20 | user: user, 21 | tab: tab, 22 | menu: menu 23 | } 24 | }) 25 | export default store 26 | -------------------------------------------------------------------------------- /code/frontend/src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | appName: 'Vue Admin', // 应用名称 4 | themeColor: '#14889A', // 主题颜色 5 | oldThemeColor: '#14889A', // 上一次主题颜色 6 | collapse: false, // 导航栏收缩状态 7 | menuRouteLoaded: false // 菜单和路由是否已经加载 8 | }, 9 | getters: { 10 | collapse (state) { 11 | // 对应着上面的state 12 | return state.collapse 13 | } 14 | }, 15 | mutations: { 16 | onCollapse (state) { 17 | // 改变收缩状态 18 | state.collapse = !state.collapse 19 | }, 20 | setThemeColor (state, newThemeColor) { 21 | // 改变主题颜色 22 | state.oldThemeColor = state.themeColor 23 | state.themeColor = newThemeColor 24 | }, 25 | menuRouteLoaded (state, menuRouteLoaded) { 26 | // 改变菜单加载状态 27 | state.menuRouteLoaded = menuRouteLoaded 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /code/frontend/src/store/modules/iframe.js: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 嵌套页面 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/28 7:47 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | export default { 8 | state: { 9 | iframeUrl: [], // 当前嵌套页面路由路径 10 | iframeUrls: [] // 所有嵌套页面路由路径访问URL 11 | }, 12 | getters: {}, 13 | mutations: { 14 | setIFrameUrl (state, iframeUrl) { // 设置iframeUrl 15 | state.iframeUrl = iframeUrl 16 | }, 17 | addIFrameUrl (state, iframeUrl) { // iframeUrls 18 | state.iframeUrls.push(iframeUrl) 19 | } 20 | }, 21 | actions: {} 22 | } 23 | -------------------------------------------------------------------------------- /code/frontend/src/store/modules/menu.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | navTree: [] // 导航菜单树 4 | }, 5 | getters: {}, 6 | mutations: { 7 | // 设置导航菜单树 8 | setNavTree (state, navTree) { 9 | state.navTree = navTree 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code/frontend/src/store/modules/tab.js: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 标签页管理功能 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/26 23:59 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | export default { 8 | state: { 9 | // 主入口标签 10 | mainTabs: [], 11 | // 当前页标签 12 | mainTabsActiveName: '' 13 | }, 14 | mutations: { 15 | updateMainTabs (state, tabs) { 16 | state.mainTabs = tabs 17 | }, 18 | updateMainTabsActiveName (state, name) { 19 | state.mainTabsActiveName = name 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /code/frontend/src/store/modules/user.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | perms: [] // 用户权限标识集合,记录可以访问哪些路由 4 | }, 5 | getters: {}, 6 | mutations: { 7 | setPerms (state, perms) { 8 | // 设置用户权限标识集合 9 | state.perms = perms 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code/frontend/src/utils/datetime.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 时间日期相关操作 3 | */ 4 | 5 | /** 6 | * 时间格式化 7 | * 将 2018-09-23T11:54:16.000+0000 格式化成 2018-09-23 11:54:16 8 | * @param datetime 国际化日期格式 9 | */ 10 | export function format (datetime) { 11 | return formatWithSeparator(datetime, '-', ':') 12 | } 13 | 14 | /** 15 | * 时间格式化 16 | * 将 2018-09-23T11:54:16.000+0000 格式化成类似 2018/09/23 11:54:16 17 | * 可以指定日期和时间分隔符 18 | * @param datetime 国际化日期格式 19 | * @param dateSeparator 日期分隔符(年月日的分隔符) 20 | * @param timeSeparator 时间分隔符(时分秒的分隔符) 21 | */ 22 | export function formatWithSeparator (datetime, dateSeparator, timeSeparator) { 23 | if (datetime != null) { 24 | const dateMat = new Date(datetime) 25 | const year = dateMat.getFullYear() 26 | const month = dateMat.getMonth() + 1 27 | const day = dateMat.getDate() 28 | const hh = dateMat.getHours() 29 | const mm = dateMat.getMinutes() 30 | const ss = dateMat.getSeconds() 31 | return year + dateSeparator + month + dateSeparator + day + ' ' + hh + timeSeparator + mm + timeSeparator + ss 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /code/frontend/src/utils/global.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 全局常量和方法封装模块 3 | * 通过原型prototype挂载到Vue属性 4 | * 通过this.Global调用 5 | */ 6 | 7 | // 后台服务器的接口基地址 8 | export const baseUrl = '/api' 9 | // 图床的基地址 10 | export const picBaseUrl = 'https://i.loli.net' 11 | 12 | export default { 13 | baseUrl, 14 | picBaseUrl 15 | } 16 | -------------------------------------------------------------------------------- /code/frontend/src/utils/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | 4 | Vue.use(VueI18n) 5 | 6 | // 注册i18n实例并引入语言文件,文件格式等下解析 7 | const i18n = new VueI18n({ 8 | locale: 'zh_cn', 9 | messages: { 10 | 'zh_cn': require('../assets/languages/zh_cn.json'), 11 | 'en_us': require('../assets/languages/en_us.json') 12 | } 13 | }) 14 | 15 | export default i18n 16 | -------------------------------------------------------------------------------- /code/frontend/src/utils/iframe.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 嵌套页面IFrame模块,主要用户URL替换和页面嵌入外部页面 3 | */ 4 | 5 | import { baseUrl } from './global' 6 | 7 | /** 8 | * 嵌套页面URL地址 9 | * @param {*} url 10 | */ 11 | export function getIFramePath (url) { 12 | let iframeUrl = '' 13 | if (/^iframe:.*/.test(url)) { 14 | iframeUrl = url.replace('iframe:', '') 15 | } else if (/^http[s]?:\/\/.*/.test(url)) { 16 | iframeUrl = url.replace('http://', '') 17 | if (iframeUrl.indexOf(':') !== -1) { 18 | iframeUrl = iframeUrl.substring(iframeUrl.lastIndexOf(':') + 1) 19 | } 20 | } 21 | return iframeUrl 22 | } 23 | 24 | /** 25 | * 嵌套页面路由路径 26 | * @param {*} url 27 | */ 28 | export function getIFrameUrl (url) { 29 | let iframeUrl = '' 30 | if (/^iframe:.*/.test(url)) { 31 | iframeUrl = baseUrl + url.replace('iframe:', '') 32 | } else if (/^http[s]?:\/\/.*/.test(url)) { 33 | iframeUrl = url 34 | } 35 | return iframeUrl 36 | } 37 | -------------------------------------------------------------------------------- /code/frontend/src/utils/permission.js: -------------------------------------------------------------------------------- 1 | import store from '../store' 2 | 3 | /** 4 | * 判断当前用户是否有操作权限。 5 | * 原理:根据传入的权限标识,查看总的权限列表perms中是否有指定的权限集合 6 | * @param perms 用户传入的权限集合 7 | * @returns {boolean} 用户是否有权限 8 | */ 9 | export function hasPermission (perms) { 10 | let hasPermission = false 11 | let permissions = store.state.user.perms 12 | let len = permissions.length 13 | for (let i = 0; i < len; i++) { 14 | if (permissions[i] === perms) { 15 | hasPermission = true 16 | break 17 | } 18 | } 19 | return hasPermission 20 | } 21 | -------------------------------------------------------------------------------- /code/frontend/src/utils/validate.js: -------------------------------------------------------------------------------- 1 | /*********************************************************** 2 | * @Description : 正则匹配的工具类 3 | * @author : 梁山广(Liang Shan Guang) 4 | * @date : 2019/11/26 23:34 5 | * @email : liangshanguang2@gmail.com 6 | ***********************************************************/ 7 | 8 | /** 9 | * 邮箱 10 | * @param {*} s 11 | */ 12 | export function isEmail (s) { 13 | return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s) 14 | } 15 | 16 | /** 17 | * 手机号码 18 | * @param {*} s 19 | */ 20 | export function isMobile (s) { 21 | return /^1[0-9]{10}$/.test(s) 22 | } 23 | 24 | /** 25 | * 电话号码 26 | * @param {*} s 27 | */ 28 | export function isPhone (s) { 29 | return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s) 30 | } 31 | 32 | /** 33 | * URL地址 34 | * @param {*} s 35 | */ 36 | export function isURL (s) { 37 | return /^http[s]?:\/\/.*/.test(s) 38 | } 39 | -------------------------------------------------------------------------------- /code/frontend/src/views/404.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | 20 | 69 | -------------------------------------------------------------------------------- /code/frontend/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /code/frontend/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | 29 | 38 | -------------------------------------------------------------------------------- /code/frontend/src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 97 | 98 | 118 | -------------------------------------------------------------------------------- /code/frontend/src/views/NavBar.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 86 | 87 | 136 | -------------------------------------------------------------------------------- /code/frontend/vue.config.js: -------------------------------------------------------------------------------- 1 | // https://cli.vuejs.org/zh/config/#vue-config-js 2 | module.exports = { 3 | devServer: { 4 | port: 7777, 5 | proxy: 'http://localhost:9528' 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/images/home.png --------------------------------------------------------------------------------