├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── help ├── database.md ├── spring.md └── vue.md ├── images ├── 20181030192809.png ├── 20181030200933.png ├── 20181030201140.png ├── 20181030201718.png ├── 20181030201808.png ├── 20181030202432.png ├── 20191224164214.png ├── 20200116220840.jpg ├── 20220514212052.png ├── 20220514212233.png ├── idea.png └── sql1030192411.png ├── spring-boot.sh ├── spring-restful-api ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── Dockerfile ├── REST API │ ├── http-client.env.json │ ├── 文件上传API.http │ └── 认证授权API.http ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── xaaef │ │ │ └── robin │ │ │ ├── SpringRestfulApplication.java │ │ │ ├── aspect │ │ │ ├── BindingResultAspect.java │ │ │ └── log │ │ │ │ ├── LogStorage.java │ │ │ │ ├── LogType.java │ │ │ │ ├── MysqlLogStorage.java │ │ │ │ ├── OperateLog.java │ │ │ │ └── OperateLogAspect.java │ │ │ ├── base │ │ │ ├── entity │ │ │ │ └── BaseEntity.java │ │ │ └── service │ │ │ │ ├── BaseService.java │ │ │ │ └── impl │ │ │ │ └── BaseServiceImpl.java │ │ │ ├── config │ │ │ ├── GlobalExceptionHandler.java │ │ │ ├── MybatisPlusConfiguration.java │ │ │ ├── SpringMvcConfiguration.java │ │ │ ├── SwaggerConfiguration.java │ │ │ ├── WebSecurityConfiguration.java │ │ │ ├── props │ │ │ │ └── CustomizeSwaggerProperties.java │ │ │ └── xss │ │ │ │ ├── XssFilterConfiguration.java │ │ │ │ ├── XssHttpServletRequestWrapper.java │ │ │ │ └── XssStringJsonDeserializer.java │ │ │ ├── constant │ │ │ ├── ConfigKey.java │ │ │ └── LoginConstant.java │ │ │ ├── controller │ │ │ ├── AuthController.java │ │ │ ├── ChinaAreaController.java │ │ │ ├── IndexController.java │ │ │ ├── LoginLogController.java │ │ │ ├── OperLogController.java │ │ │ ├── SysConfigController.java │ │ │ ├── SysDeptController.java │ │ │ ├── SysDictDataController.java │ │ │ ├── SysDictTypeController.java │ │ │ ├── SysPermissionController.java │ │ │ ├── SysRoleController.java │ │ │ ├── SysUserController.java │ │ │ └── UploadController.java │ │ │ ├── domain │ │ │ ├── Pagination.java │ │ │ └── TreeNode.java │ │ │ ├── entity │ │ │ ├── ChinaArea.java │ │ │ ├── LoginLog.java │ │ │ ├── OperLog.java │ │ │ ├── SysConfig.java │ │ │ ├── SysDept.java │ │ │ ├── SysDictData.java │ │ │ ├── SysDictType.java │ │ │ ├── SysNotice.java │ │ │ ├── SysPermission.java │ │ │ ├── SysRole.java │ │ │ ├── SysRoleProxy.java │ │ │ ├── SysUser.java │ │ │ └── SysUserSocial.java │ │ │ ├── enums │ │ │ ├── AdminFlagEnum.java │ │ │ ├── DefaultEnum.java │ │ │ ├── GenderEnum.java │ │ │ ├── GrantType.java │ │ │ ├── OAuth2Error.java │ │ │ ├── PermissionTypeEnum.java │ │ │ └── StatusEnum.java │ │ │ ├── exception │ │ │ └── JwtAuthException.java │ │ │ ├── jwt │ │ │ ├── JwtAccessDeniedHandler.java │ │ │ ├── JwtAuthenticationTokenFilter.java │ │ │ ├── JwtLoginUser.java │ │ │ ├── JwtSecurityUtils.java │ │ │ ├── JwtTokenProperties.java │ │ │ ├── JwtTokenUtils.java │ │ │ ├── JwtTokenValue.java │ │ │ └── StringGrantedAuthority.java │ │ │ ├── mapper │ │ │ ├── ChinaAreaMapper.java │ │ │ ├── LoginLogMapper.java │ │ │ ├── OperLogMapper.java │ │ │ ├── SysConfigMapper.java │ │ │ ├── SysDeptMapper.java │ │ │ ├── SysDictDataMapper.java │ │ │ ├── SysDictTypeMapper.java │ │ │ ├── SysNoticeMapper.java │ │ │ ├── SysPermissionMapper.java │ │ │ ├── SysRoleMapper.java │ │ │ ├── SysUserMapper.java │ │ │ └── SysUserSocialMapper.java │ │ │ ├── param │ │ │ ├── DictQueryParams.java │ │ │ ├── QueryParams.java │ │ │ └── UserQueryParams.java │ │ │ ├── service │ │ │ ├── ChinaAreaService.java │ │ │ ├── JwtTokenService.java │ │ │ ├── LoginLogService.java │ │ │ ├── OperLogService.java │ │ │ ├── SysConfigService.java │ │ │ ├── SysDeptService.java │ │ │ ├── SysDictDataService.java │ │ │ ├── SysDictTypeService.java │ │ │ ├── SysNoticeService.java │ │ │ ├── SysPermissionService.java │ │ │ ├── SysRoleService.java │ │ │ ├── SysUserService.java │ │ │ ├── SysUserSocialService.java │ │ │ ├── UserLoginService.java │ │ │ ├── VerifyCodeService.java │ │ │ └── impl │ │ │ │ ├── ChinaAreaServiceImpl.java │ │ │ │ ├── JwtTokenServiceImpl.java │ │ │ │ ├── LoginLogServiceImpl.java │ │ │ │ ├── OperLogServiceImpl.java │ │ │ │ ├── SysConfigServiceImpl.java │ │ │ │ ├── SysDeptServiceImpl.java │ │ │ │ ├── SysDictDataServiceImpl.java │ │ │ │ ├── SysDictTypeServiceImpl.java │ │ │ │ ├── SysNoticeServiceImpl.java │ │ │ │ ├── SysPermissionServiceImpl.java │ │ │ │ ├── SysRoleServiceImpl.java │ │ │ │ ├── SysUserServiceImpl.java │ │ │ │ ├── SysUserSocialServiceImpl.java │ │ │ │ ├── UserLoginServiceImpl.java │ │ │ │ └── VerifyCodeServiceImpl.java │ │ │ ├── util │ │ │ ├── ConvertUtils.java │ │ │ ├── FSTUtils.java │ │ │ ├── IdUtils.java │ │ │ ├── IpUtils.java │ │ │ ├── JsonResult.java │ │ │ ├── JsonUtils.java │ │ │ ├── MsgpackUtils.java │ │ │ ├── QiniuUtils.java │ │ │ ├── RedisCacheUtils.java │ │ │ ├── RegexUtils.java │ │ │ ├── RequestUtils.java │ │ │ ├── ServletUtils.java │ │ │ ├── SpringUtils.java │ │ │ ├── TimeUtils.java │ │ │ ├── TreeNodeUtils.java │ │ │ ├── VerifyCodeUtils.java │ │ │ └── useragent │ │ │ │ ├── Constants.java │ │ │ │ ├── UserAgent.java │ │ │ │ ├── UserAgentParser.java │ │ │ │ ├── browser │ │ │ │ ├── Browser.java │ │ │ │ ├── BrowserParser.java │ │ │ │ ├── BrowserPattern.java │ │ │ │ ├── Engine.java │ │ │ │ └── EngineEnum.java │ │ │ │ └── os │ │ │ │ ├── Os.java │ │ │ │ ├── OsParser.java │ │ │ │ ├── OsPattern.java │ │ │ │ └── PlatformEnum.java │ │ │ └── vo │ │ │ ├── BindingPermsVO.java │ │ │ ├── BindingRolesVO.java │ │ │ ├── ButtonVO.java │ │ │ ├── LoginUserVO.java │ │ │ ├── MenuVO.java │ │ │ ├── ResetPasswordVO.java │ │ │ ├── SysUserVO.java │ │ │ ├── UpdatePasswordVO.java │ │ │ ├── UpdatePermsVO.java │ │ │ └── UserIdAndNicknameVO.java │ └── resources │ │ ├── application-dev.yml │ │ ├── application-prod.yml │ │ ├── application.yml │ │ ├── images │ │ └── watermark.png │ │ ├── logback-spring.xml │ │ ├── mapper │ │ ├── ChinaAreaMapper.xml │ │ ├── LoginLogMapper.xml │ │ ├── OperLogMapper.xml │ │ ├── SysConfigMapper.xml │ │ ├── SysDeptMapper.xml │ │ ├── SysDictDataMapper.xml │ │ ├── SysDictTypeMapper.xml │ │ ├── SysNoticeMapper.xml │ │ ├── SysPermissionMapper.xml │ │ ├── SysRoleMapper.xml │ │ ├── SysUserMapper.xml │ │ └── SysUserSocialMapper.xml │ │ └── useragent │ │ ├── browser.yml │ │ └── os.yml │ └── test │ └── java │ └── com │ └── xaaef │ └── robin │ └── NoSpringTests.java ├── spring_admin_vue.sql └── vue-admin-template ├── .editorconfig ├── .env.development ├── .env.production ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── README.md ├── babel.config.js ├── jest.config.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── api │ ├── chinaArea.js │ ├── fileUpload.js │ ├── sysDept.js │ ├── sysLog.js │ ├── sysPermission.js │ ├── sysRole.js │ └── sysUser.js ├── assets │ ├── 401_images │ │ └── 401.gif │ ├── 404_images │ │ ├── 404.png │ │ └── 404_cloud.png │ └── images │ │ └── logo.png ├── components │ ├── BackToTop │ │ └── index.vue │ ├── Breadcrumb │ │ └── index.vue │ ├── Charts │ │ ├── Keyboard.vue │ │ ├── LineMarker.vue │ │ ├── MixChart.vue │ │ └── mixins │ │ │ └── resize.js │ ├── Copyright │ │ └── index.vue │ ├── DragSelect │ │ └── index.vue │ ├── Dropzone │ │ └── index.vue │ ├── ErrorLog │ │ └── index.vue │ ├── GithubCorner │ │ └── index.vue │ ├── Hamburger │ │ └── index.vue │ ├── HeaderSearch │ │ └── index.vue │ ├── PanThumb │ │ └── index.vue │ ├── Screenfull │ │ └── index.vue │ ├── ShowUserAvatar │ │ └── index.vue │ ├── SizeSelect │ │ └── index.vue │ ├── SvgIcon │ │ └── index.vue │ ├── TextHoverEffect │ │ └── Mallki.vue │ └── UserAvatar │ │ └── index.vue ├── directive │ └── index.js ├── filters │ └── index.js ├── icons │ ├── index.js │ ├── svg │ │ ├── dashboard.svg │ │ ├── exit-fullscreen.svg │ │ ├── eye-open.svg │ │ ├── eye.svg │ │ ├── fullscreen.svg │ │ ├── link.svg │ │ ├── message.svg │ │ ├── money.svg │ │ ├── password.svg │ │ ├── peoples.svg │ │ ├── pre.svg │ │ ├── pre_dept.svg │ │ ├── pre_perm.svg │ │ ├── pre_role.svg │ │ ├── pre_user.svg │ │ ├── search.svg │ │ ├── shopping.svg │ │ ├── size.svg │ │ ├── sys.svg │ │ ├── sys_china_area.svg │ │ ├── sys_dictionary.svg │ │ ├── sys_login_log.svg │ │ ├── sys_logs.svg │ │ ├── sys_oper_log.svg │ │ ├── sys_swagger2.svg │ │ ├── sys_wechat.svg │ │ └── user.svg │ └── svgo.yml ├── layout │ ├── components │ │ ├── AppMain.vue │ │ ├── Navbar.vue │ │ ├── Settings │ │ │ └── index.vue │ │ ├── Sidebar │ │ │ ├── FixiOSBug.js │ │ │ ├── Item.vue │ │ │ ├── Link.vue │ │ │ ├── Logo.vue │ │ │ ├── SidebarItem.vue │ │ │ └── index.vue │ │ ├── TagsView │ │ │ ├── ScrollPane.vue │ │ │ └── index.vue │ │ └── index.js │ ├── index.vue │ └── mixin │ │ └── ResizeHandler.js ├── main.js ├── permission.js ├── router │ └── index.js ├── settings.js ├── store │ ├── getters.js │ ├── index.js │ └── modules │ │ ├── app.js │ │ ├── errorLog.js │ │ ├── permission.js │ │ ├── settings.js │ │ ├── tagsView.js │ │ └── user.js ├── styles │ ├── element-ui.scss │ ├── index.scss │ ├── mixin.scss │ ├── sidebar.scss │ ├── transition.scss │ └── variables.scss ├── utils │ ├── auth.js │ ├── get-page-title.js │ ├── index.js │ ├── open-window.js │ ├── regular.js │ ├── request.js │ └── validate.js └── views │ ├── dashboard │ ├── components │ │ ├── BarChart.vue │ │ ├── BoxCard.vue │ │ ├── LineChart.vue │ │ ├── PanelGroup.vue │ │ ├── PieChart.vue │ │ ├── RaddarChart.vue │ │ ├── TodoList │ │ │ ├── Todo.vue │ │ │ ├── index.scss │ │ │ └── index.vue │ │ ├── TransactionTable.vue │ │ └── mixins │ │ │ └── resize.js │ └── index.vue │ ├── error │ ├── 401 │ │ └── index.vue │ └── 404 │ │ └── index.vue │ ├── login │ └── index.vue │ ├── pre │ ├── dept │ │ └── index.vue │ ├── perm │ │ └── index.vue │ ├── role │ │ └── index.vue │ └── user │ │ └── index.vue │ ├── redirect │ └── index.vue │ ├── sys │ ├── chinaArea │ │ └── index.vue │ ├── dictionary │ │ └── index.vue │ ├── loginLog │ │ └── index.vue │ ├── notice │ │ └── index.vue │ ├── operLog │ │ └── index.vue │ ├── swagger │ │ └── index.vue │ └── wechat │ │ └── index.vue │ └── userinfo │ └── index.vue ├── tests └── unit │ ├── .eslintrc.js │ ├── components │ ├── Breadcrumb.spec.js │ ├── Hamburger.spec.js │ └── SvgIcon.spec.js │ └── utils │ ├── formatTime.spec.js │ ├── param2Obj.spec.js │ ├── parseTime.spec.js │ └── validate.spec.js └── vue.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.sql linguist-language=java 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | README.md 2 | target/ 3 | 4 | **/node_modules/ 5 | !.mvn/wrapper/maven-wrapper.jar 6 | !**/src/main/** 7 | !**/src/test/** 8 | 9 | ### STS ### 10 | .apt_generated 11 | .classpath 12 | .factorypath 13 | .project 14 | .settings 15 | .springBeans 16 | .sts4-cache 17 | 18 | ### IntelliJ IDEA ### 19 | .idea 20 | *.iws 21 | *.iml 22 | *.ipr 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /help/database.md: -------------------------------------------------------------------------------- 1 | 2 | ## 先从数据库开始 3 | 4 | 大部分的权限管理系统都是5张表结构(同样我们这里也采用这种方式) 5 | 6 |  7 | 8 | ### **t_sys_user -----> t_sys_user_role -----> t_sys_role -----> t_sys_role_permission ----> t_sys_permission** 9 | 10 | 这里我们主要看权限表(t_sys_permission ) 11 | 12 |  13 | 14 | 最重要的就是resources和type字段,这两个字段在后面和vue.js整合的时候会用到, 15 | 16 | ### type字段,只有两个类型,是按钮还是菜单 17 | -------------------------------------------------------------------------------- /images/20181030192809.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20181030192809.png -------------------------------------------------------------------------------- /images/20181030200933.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20181030200933.png -------------------------------------------------------------------------------- /images/20181030201140.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20181030201140.png -------------------------------------------------------------------------------- /images/20181030201718.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20181030201718.png -------------------------------------------------------------------------------- /images/20181030201808.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20181030201808.png -------------------------------------------------------------------------------- /images/20181030202432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20181030202432.png -------------------------------------------------------------------------------- /images/20191224164214.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20191224164214.png -------------------------------------------------------------------------------- /images/20200116220840.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20200116220840.jpg -------------------------------------------------------------------------------- /images/20220514212052.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20220514212052.png -------------------------------------------------------------------------------- /images/20220514212233.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/20220514212233.png -------------------------------------------------------------------------------- /images/idea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/idea.png -------------------------------------------------------------------------------- /images/sql1030192411.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/images/sql1030192411.png -------------------------------------------------------------------------------- /spring-restful-api/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 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 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /spring-restful-api/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thousmile/spring-admin-vue/74cc1589e84db19c8906517e0f47694b27c6458d/spring-restful-api/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring-restful-api/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /spring-restful-api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:11.0.13_8-jre 2 | 3 | MAINTAINER Wang Chen Chen<932560435@qq.com> 4 | 5 | ENV VERSION 1.1 6 | # 挂载容器目录 7 | # tmp: 临时文件目录,内嵌tomcat启动时,用到 8 | # logs: spring-boot 日志输出的目录 9 | # config: spring-boot 外部化配置文件目录 10 | VOLUME ["/tmp","/logs","/config"] 11 | 12 | # 对应pom.xml文件中的dockerfile-maven-plugin插件JAR_FILE的值 13 | ARG JAR_FILE 14 | 15 | # 复制打包 完成后的jar文件,名字修改成 app.jar 16 | COPY ${JAR_FILE} app.jar 17 | 18 | # 设置编码 19 | ENV LANG C.UTF-8 20 | 21 | # 设置环境变量 22 | ENV CONSUL_SERVER_PORT=8500 23 | 24 | # JVM参数 25 | ENV JVM_OPTS="-server -Xms2048M -Xmx2048M -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError" 26 | 27 | # spring 启动环境 28 | ENV SPRING_ENV="prod" 29 | 30 | # 服务暴露端口PORT 31 | EXPOSE 18888 32 | 33 | # 启动 Spring Boot App 命令 34 | ENTRYPOINT java ${JVM_OPTS} -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom -jar /app.jar --spring.profiles.active=${SPRING_ENV} 35 | -------------------------------------------------------------------------------- /spring-restful-api/REST API/http-client.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "baseUrl": "http://localhost:18888" 4 | }, 5 | "prod": { 6 | "baseUrl": "https://api.mhtled.com" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spring-restful-api/REST API/文件上传API.http: -------------------------------------------------------------------------------- 1 | ### 图片上传 2 | POST {{baseUrl}}/upload/image 3 | Authorization: Bearer {{tokenValue}} 4 | Content-Type: multipart/form-data; boundary=WebAppBoundary 5 | 6 | --WebAppBoundary 7 | Content-Disposition: form-data; name="file"; filename="tR9669GlNMU-343X.bin" 8 | Content-Type: multipart/form-data 9 | 10 | < C:\\Users\\demo\\Desktop\\地图和头像\\tR9669GlNMU-343X.bin 11 | --WebAppBoundary-- 12 | 13 | 14 | 15 | 16 | ### 头像上传 17 | POST {{baseUrl}}/upload/avatar 18 | Authorization: Bearer {{tokenValue}} 19 | Content-Type: multipart/form-data; boundary=WebAppBoundary 20 | 21 | --WebAppBoundary 22 | Content-Disposition: form-data; name="file"; filename="avatar-4.jpg" 23 | Content-Type: multipart/form-data 24 | 25 | < C:\\Users\\demo\\Desktop\\地图和头像\\avatar-4.jpg 26 | --WebAppBoundary-- 27 | 28 | 29 | 30 | 31 | ### 删除图片 32 | DELETE {{baseUrl}}/upload/delete?url=https://images.xaaef.com/20210728105923.png 33 | Authorization: Bearer {{tokenValue}} 34 | -------------------------------------------------------------------------------- /spring-restful-api/REST API/认证授权API.http: -------------------------------------------------------------------------------- 1 | ## 安全认证 2 | 3 | ## 验证码一定要在浏览器获取 codeKey 要是随机数。在登录的时候会用到 codeKey 4 | GET {{baseUrl}}/auth/captcha/codes/5jXzuwcoUzbtnHNh 5 | 6 | ### 密码模式登录 7 | POST {{baseUrl}}/auth/login 8 | Content-Type: application/json 9 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0 10 | 11 | { 12 | "username": "admin", 13 | "password": "admin", 14 | "codeKey": "5jXzuwcoUzbtnHNh", 15 | "codeText": "9jps" 16 | } 17 | 18 | > {% 19 | client.global.set("tokenValue", response.body.data.access_token); 20 | client.global.set("refreshToken", response.body.data.refresh_token); 21 | %} 22 | 23 | ### 退出登录 24 | POST {{baseUrl}}/auth/logout 25 | Content-Type: application/json 26 | Authorization: Bearer {{tokenValue}} 27 | 28 | ### 刷新token 29 | GET {{baseUrl}}/auth/refresh 30 | Content-Type: application/json 31 | Authorization: Bearer {{tokenValue}} 32 | 33 | ### 获取登录的用户信息 34 | GET {{baseUrl}}/user/info 35 | Content-Type: application/json 36 | Authorization: Bearer {{tokenValue}} 37 | 38 | 39 | 40 | ### 首页 测试 @PreAuthorize("hasAuthority('home:get')") 41 | GET {{baseUrl}}/home 42 | Content-Type: application/json 43 | Authorization: Bearer {{tokenValue}} 44 | 45 | 46 | ### 首页 测试 @PreAuthorize("hasAuthority('index:get')") 47 | GET {{baseUrl}}/index 48 | Content-Type: application/json 49 | Authorization: Bearer {{tokenValue}} 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/SpringRestfulApplication.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.scheduling.annotation.EnableAsync; 8 | import org.springframework.scheduling.annotation.EnableScheduling; 9 | 10 | 11 | @EnableAsync 12 | @EnableCaching 13 | @EnableScheduling 14 | @MapperScan("com.xaaef.robin.mapper") 15 | @SpringBootApplication 16 | public class SpringRestfulApplication { 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.run(SpringRestfulApplication.class, args); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/aspect/BindingResultAspect.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.aspect; 2 | 3 | import com.xaaef.robin.util.JsonResult; 4 | import org.aspectj.lang.ProceedingJoinPoint; 5 | import org.aspectj.lang.annotation.Around; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.aspectj.lang.annotation.Pointcut; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.validation.BindingResult; 11 | 12 | /** 13 | *
14 | * Hibernate-Validator 错误结果处理切面 15 | *
16 | * 17 | * @author Wang Chen Chen <932560435@qq.com> 18 | * @version 2.0 19 | * @date 2019/4/18 11:45 20 | */ 21 | 22 | @Aspect 23 | @Component 24 | @Order(2) 25 | public class BindingResultAspect { 26 | 27 | @Pointcut("execution(public * com.xaaef.robin.*.controller..*.*(..))") 28 | public void BindingResult1() { 29 | } 30 | 31 | @Pointcut("execution(public * com.xaaef.robin.controller..*.*(..))") 32 | public void BindingResult2() { 33 | } 34 | 35 | @Around("BindingResult1() || BindingResult2()") 36 | public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { 37 | var args = joinPoint.getArgs(); 38 | for (Object arg : args) { 39 | if (arg instanceof BindingResult) { 40 | BindingResult result = (BindingResult) arg; 41 | if (result.hasErrors()) { 42 | var fieldError = result.getFieldError(); 43 | if (fieldError != null) { 44 | return JsonResult.fail(fieldError.getDefaultMessage()); 45 | } else { 46 | return JsonResult.fail("请求参数错误!"); 47 | } 48 | } 49 | } 50 | } 51 | return joinPoint.proceed(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/aspect/log/LogType.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.aspect.log; 2 | 3 | /** 4 | *5 | * 操作类型 6 | *
7 | * 8 | * @author Wang Chen Chen 9 | * @version 1.0.1 10 | * @date 2021/8/10 15:01 11 | */ 12 | 13 | public enum LogType { 14 | 15 | // 新增 16 | INSERT, 17 | 18 | // 删除 19 | DELETE, 20 | 21 | // 修改 22 | UPDATE, 23 | 24 | // 查询 25 | SELECT, 26 | 27 | // 执行 28 | EXECUTE, 29 | 30 | } 31 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/aspect/log/MysqlLogStorage.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.aspect.log; 2 | 3 | import com.xaaef.robin.entity.LoginLog; 4 | import com.xaaef.robin.entity.OperLog; 5 | import com.xaaef.robin.service.LoginLogService; 6 | import com.xaaef.robin.service.OperLogService; 7 | import lombok.AllArgsConstructor; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.scheduling.annotation.Async; 10 | import org.springframework.stereotype.Component; 11 | 12 | 13 | /** 14 | *15 | * 操作日志 16 | *
17 | * 18 | * @author Wang Chen Chen 19 | * @version 1.0.1 20 | * @date 2021/8/17 16:18 21 | */ 22 | 23 | @Slf4j 24 | @Component 25 | @AllArgsConstructor 26 | public class MysqlLogStorage implements LogStorage { 27 | 28 | private final LoginLogService loginLogService; 29 | 30 | private final OperLogService operLogService; 31 | 32 | @Async 33 | @Override 34 | public void asyncLoginSave(LoginLog loginLog) { 35 | loginLogService.save(loginLog); 36 | } 37 | 38 | 39 | @Async 40 | @Override 41 | public void asyncOperateSave(OperLog operLog) { 42 | operLogService.save(operLog); 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/aspect/log/OperateLog.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.aspect.log; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | *7 | * 操作日志 8 | *
9 | * 10 | * @author Wang Chen Chen 11 | * @version 1.0.1 12 | * @date 2021/8/10 15:00 13 | */ 14 | 15 | @Documented 16 | @Target(ElementType.METHOD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface OperateLog { 19 | 20 | String title() default ""; 21 | 22 | LogType type() default LogType.SELECT; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/base/entity/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.base.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldFill; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | *12 | * 通用父实体类 13 | *
14 | * 15 | * @author Wang Chen Chen 16 | * @version 1.0 17 | * @date 2021/7/5 9:31 18 | */ 19 | 20 | @Getter 21 | @Setter 22 | public class BaseEntity implements java.io.Serializable { 23 | 24 | /** 25 | * 创建时间 26 | * 27 | * @date 2019/12/11 21:12 28 | */ 29 | @TableField(fill = FieldFill.INSERT) 30 | protected LocalDateTime createTime; 31 | 32 | /** 33 | * 创建人 id 34 | * 35 | * @date 2019/12/11 21:12 36 | */ 37 | @TableField(fill = FieldFill.INSERT) 38 | protected Long createUser; 39 | 40 | /** 41 | * 最后一次修改时间 42 | * 43 | * @date 2019/12/11 21:12 44 | */ 45 | @TableField(fill = FieldFill.INSERT_UPDATE) 46 | protected LocalDateTime lastUpdateTime; 47 | 48 | /** 49 | * 最后一次修改人 id 50 | * 51 | * @date 2019/12/11 21:12 52 | */ 53 | @TableField(fill = FieldFill.INSERT_UPDATE) 54 | protected Long lastUpdateUser; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/config/props/CustomizeSwaggerProperties.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.config.props; 2 | 3 | import lombok.*; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * All rights Reserved, Designed By www.xaaef.com 8 | *9 | *
10 | * 11 | * @author Wang Chen Chen<932560435@qq.com> 12 | * @version 1.0.0 13 | * @date 2020/7/2515:30 14 | */ 15 | 16 | 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Builder 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | @ConfigurationProperties(prefix = "customize.swagger") 24 | public class CustomizeSwaggerProperties { 25 | 26 | /** 27 | * 标题 28 | */ 29 | private String title; 30 | 31 | /** 32 | * 文档描述 33 | */ 34 | private String description; 35 | 36 | /** 37 | * 版本 38 | */ 39 | private String version = "3.0"; 40 | 41 | /** 42 | * 名称 43 | */ 44 | private String name; 45 | 46 | /** 47 | * URL地址 48 | */ 49 | private String url; 50 | 51 | /** 52 | * 邮箱 53 | */ 54 | private String email; 55 | 56 | /** 57 | * 服务地址 58 | */ 59 | private String serviceUrl; 60 | 61 | } 62 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/config/xss/XssFilterConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.config.xss; 2 | 3 | import com.fasterxml.jackson.core.JsonParser; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.DeserializationContext; 6 | import com.fasterxml.jackson.databind.JsonDeserializer; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import com.fasterxml.jackson.databind.module.SimpleModule; 9 | import com.xaaef.robin.util.JsonUtils; 10 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.Primary; 14 | import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; 15 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 16 | import org.springframework.web.util.HtmlUtils; 17 | 18 | import javax.servlet.*; 19 | import javax.servlet.http.HttpServletRequest; 20 | import java.io.IOException; 21 | 22 | 23 | /** 24 | *25 | * 26 | *
27 | * 28 | * @author WangChenChen 29 | * @version 1.0 30 | * @date 2022/3/25 9:28 31 | */ 32 | 33 | 34 | @Configuration 35 | public class XssFilterConfiguration { 36 | 37 | @Bean 38 | public FilterRegistrationBean12 | * 13 | *
14 | * 15 | * @author WangChenChen 16 | * @version 1.0 17 | * @date 2022/3/25 9:40 18 | */ 19 | 20 | 21 | public class XssStringJsonDeserializer extends JsonDeserializer5 | * 全局配置文件 key 6 | *
7 | * 8 | * @author Wang Chen Chen 9 | * @version 1.0.1 10 | * @date 2021/7/16 15:15 11 | */ 12 | 13 | public class ConfigKey { 14 | 15 | /** 16 | * 用户默认密码 17 | */ 18 | public static final String USER_DEFAULT_PASSWORD = "user_default_password"; 19 | 20 | /** 21 | * 默认logo 22 | */ 23 | public static final String DEFAULT_LOGO = "default_logo"; 24 | 25 | /** 26 | * 获取法定节假日的接口 27 | */ 28 | public static final String LEGAL_HOLIDAY_URL = "legal_holiday_url"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/constant/LoginConstant.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.constant; 2 | 3 | public class LoginConstant { 4 | 5 | /** 6 | * 验证码 redis key 7 | */ 8 | public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; 9 | 10 | /** 11 | * 登录用户 redis key 12 | */ 13 | public static final String LOGIN_TOKEN_KEY = "login_tokens:"; 14 | 15 | /** 16 | * 在线用户,令牌前缀 17 | */ 18 | public static final String ONLINE_USER_KEY = "online_user:"; 19 | 20 | /** 21 | * 强制下线,令牌前缀 22 | */ 23 | public static final String FORCED_OFFLINE_KEY = "forced_offline_user:"; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.controller; 2 | 3 | import com.xaaef.robin.util.JsonResult; 4 | import io.swagger.annotations.Api; 5 | import io.swagger.annotations.ApiOperation; 6 | import lombok.AllArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.security.access.prepost.PreAuthorize; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | 12 | /** 13 | *14 | * 首页 控制器 15 | *
16 | * 17 | * @author Wang Chen Chen <932560435@qq.com> 18 | * @version 3.0 19 | */ 20 | 21 | 22 | @Slf4j 23 | @Api(tags = "[ 首页 ]") 24 | @RestController 25 | @AllArgsConstructor 26 | public class IndexController { 27 | 28 | @PreAuthorize("hasAuthority('home:get')") 29 | @ApiOperation(value = "home", notes = "home") 30 | @GetMapping(value = {"home",}) 31 | public JsonResult21 | * 用户登录日志 Controller 22 | *
23 | * 24 | * @author Wang Chen Chen<932560435@qq.com> 25 | * @version 2.0 26 | * @date 2019/12/25 22:13 27 | */ 28 | 29 | 30 | @Slf4j 31 | @Api(tags = "[ 系统 ] 登录日志") 32 | @RestController 33 | @AllArgsConstructor 34 | @RequestMapping("/login/log") 35 | public class LoginLogController { 36 | 37 | private LoginLogService baseService; 38 | 39 | @ApiOperation(value = "分页查询", notes = "根据关键字搜索") 40 | @GetMapping("/query") 41 | public JsonResult21 | * 用户操作日志 Controller 22 | *
23 | * 24 | * @author Wang Chen Chen<932560435@qq.com> 25 | * @version 2.0 26 | * @date 2019/12/25 22:13 27 | */ 28 | 29 | 30 | @Slf4j 31 | @Api(tags = "[ 系统 ] 操作日志") 32 | @RestController 33 | @AllArgsConstructor 34 | @RequestMapping("/oper/log") 35 | public class OperLogController { 36 | 37 | private OperLogService baseService; 38 | 39 | @ApiOperation(value = "分页查询", notes = "根据关键字搜索") 40 | @GetMapping("/query") 41 | public JsonResult12 | * 返回分页 13 | *
14 | * 15 | * @author WangChenChen 16 | * @version 1.0.1 17 | * @date 2021/10/14 14:00 18 | */ 19 | 20 | @Getter 21 | @Setter 22 | @AllArgsConstructor 23 | @NoArgsConstructor 24 | public class Pagination9 | * 树节点 10 | *
11 | * 12 | * @author Wang Chen Chen 13 | * @version 1.0 14 | * @date 2021/7/5 9:31 15 | */ 16 | 17 | public interface TreeNode12 | * 0.普通用户 13 | * 1.管理员 ( 管理员是禁止被删除 ) 14 | *
15 | * 16 | * @author Wang Chen Chen 17 | * @version 1.0 18 | * @date 2021/7/5 9:31 19 | */ 20 | 21 | 22 | @Getter 23 | @ToString 24 | public enum AdminFlagEnum { 25 | 26 | USER(0, "用户"), 27 | 28 | ADMIN(1, "管理员"); 29 | 30 | AdminFlagEnum(int code, String description) { 31 | this.code = code; 32 | this.description = description; 33 | } 34 | 35 | @EnumValue 36 | @JsonValue 37 | private final int code; 38 | 39 | private final String description; 40 | 41 | /** 42 | * 用于 spring mvc 实体参数绑定 43 | */ 44 | @JsonCreator 45 | public static AdminFlagEnum create(Integer value) { 46 | for (var v : values()) { 47 | if (v.code == value) { 48 | return v; 49 | } 50 | } 51 | return USER; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/enums/DefaultEnum.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.enums; 2 | 3 | import com.baomidou.mybatisplus.annotation.EnumValue; 4 | import com.fasterxml.jackson.annotation.JsonCreator; 5 | import com.fasterxml.jackson.annotation.JsonValue; 6 | import lombok.Getter; 7 | import lombok.ToString; 8 | 9 | /** 10 | *11 | * 默认 12 | * 1.是 13 | * 0.否 14 | *
15 | * 16 | * @author Wang Chen Chen 17 | * @version 1.0 18 | * @date 2021/7/5 9:31 19 | */ 20 | 21 | @Getter 22 | @ToString 23 | public enum DefaultEnum { 24 | 25 | YES(1, "是"), 26 | 27 | NO(0, "否"); 28 | 29 | DefaultEnum(int code, String description) { 30 | this.code = code; 31 | this.description = description; 32 | } 33 | 34 | @EnumValue 35 | @JsonValue 36 | private final int code; 37 | 38 | private final String description; 39 | 40 | /** 41 | * 用于 spring mvc 实体参数绑定 42 | */ 43 | @JsonCreator 44 | public static DefaultEnum create(Integer value) { 45 | for (var v : values()) { 46 | if (v.code == value) { 47 | return v; 48 | } 49 | } 50 | return NO; 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/enums/GenderEnum.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.enums; 2 | 3 | import com.baomidou.mybatisplus.annotation.EnumValue; 4 | import com.fasterxml.jackson.annotation.JsonCreator; 5 | import com.fasterxml.jackson.annotation.JsonValue; 6 | import lombok.Getter; 7 | import lombok.ToString; 8 | 9 | /** 10 | *11 | * 性别 12 | * 0.女 13 | * 1.男 14 | * 2.未知 15 | *
16 | * 17 | * @author Wang Chen Chen 18 | * @version 1.0 19 | * @date 2021/7/5 9:31 20 | */ 21 | 22 | @Getter 23 | @ToString 24 | public enum GenderEnum { 25 | 26 | FEMALE(0, "女"), 27 | 28 | MALE(1, "男"), 29 | 30 | UNKNOWN(2, "未知"); 31 | 32 | GenderEnum(int code, String description) { 33 | this.code = code; 34 | this.description = description; 35 | } 36 | 37 | @EnumValue 38 | @JsonValue 39 | private final int code; 40 | 41 | private final String description; 42 | 43 | /** 44 | * 用于 spring mvc 实体参数绑定 45 | */ 46 | @JsonCreator 47 | public static GenderEnum create(Integer value) { 48 | for (var v : values()) { 49 | if (v.code == value) { 50 | return v; 51 | } 52 | } 53 | return UNKNOWN; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/enums/GrantType.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.enums; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonValue; 5 | import lombok.Getter; 6 | import lombok.ToString; 7 | 8 | /** 9 | *10 | * password : 密码模式 11 | * we_chat : 微信登陆模式 12 | * tencent_qq : 腾讯 QQ 登陆模式 13 | * sms : 手机短信模式 14 | *
15 | * 16 | * @author Wang Chen Chen 17 | * @version 1.0.1 18 | * @date 2021/7/5 9:31 19 | */ 20 | 21 | @Getter 22 | @ToString 23 | public enum GrantType { 24 | 25 | PASSWORD("password", "密码 登录模式"), 26 | 27 | WECHAT("we_chat", "微信登录 模式"), 28 | 29 | TENCENT_QQ("tencent_qq", "腾讯QQ登录 模式"), 30 | 31 | SEND_SMS("send_sms", "发送短信"), 32 | 33 | SMS("sms", "手机短信登录 模式"); 34 | 35 | GrantType(String code, String description) { 36 | this.code = code; 37 | this.description = description; 38 | } 39 | 40 | @JsonValue 41 | private final String code; 42 | 43 | private final String description; 44 | 45 | @JsonCreator 46 | public static GrantType get(String value) { 47 | for (var v : values()) { 48 | if (v.code.equalsIgnoreCase(value)) { 49 | return v; 50 | } 51 | } 52 | return PASSWORD; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/enums/OAuth2Error.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *7 | * 认证状态 8 | *
9 | * 10 | * @author Wang Chen Chen 11 | * @version 1.0.1 12 | * @date 2021/7/5 9:31 13 | */ 14 | 15 | @Getter 16 | public enum OAuth2Error { 17 | 18 | /** 19 | * 认证错误,不知道啥原因 20 | */ 21 | OAUTH2_EXCEPTION(400004, "认证错误!"), 22 | 23 | 24 | /** 25 | * access_token 不存在 26 | */ 27 | ACCESS_TOKEN_INVALID(400010, "access_token 不存在"), 28 | 29 | 30 | /** 31 | * access_token 过期 32 | */ 33 | ACCESS_TOKEN_EXPIRED(400011, "access_token 已过期"), 34 | 35 | 36 | /** 37 | * token 格式错误 38 | */ 39 | TOKEN_FORMAT_ERROR(400012, "access_token 格式错误"), 40 | 41 | 42 | /** 43 | * 用户不存在 44 | */ 45 | USER_INVALID(400020, "用户或者密码错误"), 46 | 47 | 48 | /** 49 | * 当前用户被锁定 50 | */ 51 | USER_LOCKING(400023, "此用户被锁定"), 52 | 53 | /** 54 | * 用户手机号不存在 55 | */ 56 | USER_MOBILE_INVALID(400024, "用户手机号不存在"), 57 | 58 | /** 59 | * 授权类型错误 60 | */ 61 | AUTHORIZATION_GRANT_TYPE(400033, "授权类型错误"), 62 | 63 | /** 64 | * 请求参数解析错误 65 | */ 66 | REQUEST_PARAM_VALIDATE(400044, "请求参数解析错误"), 67 | 68 | /** 69 | * 验证码错误 70 | */ 71 | VERIFICATION_CODE_ERROR(400045, "验证码错误"), 72 | 73 | /** 74 | * 权限不足 75 | */ 76 | ACCESS_DENIED(400061, "请求访问,权限不足"); 77 | 78 | OAuth2Error(Integer status, String error) { 79 | this.status = status; 80 | this.error = error; 81 | } 82 | 83 | /** 84 | * 状态信息 85 | */ 86 | private final Integer status; 87 | 88 | /** 89 | * 错误消息 90 | */ 91 | private final String error; 92 | 93 | } 94 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/enums/PermissionTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.enums; 2 | 3 | import com.baomidou.mybatisplus.annotation.EnumValue; 4 | import com.fasterxml.jackson.annotation.JsonCreator; 5 | import com.fasterxml.jackson.annotation.JsonValue; 6 | import lombok.Getter; 7 | import lombok.ToString; 8 | 9 | /** 10 | *11 | * 菜单的类型 12 | * 0.菜单 13 | * 1.按钮 14 | *
15 | * 16 | * @author Wang Chen Chen 17 | * @version 1.0 18 | * @date 2021/7/5 9:31 19 | */ 20 | 21 | @Getter 22 | @ToString 23 | public enum PermissionTypeEnum { 24 | 25 | MENU(0, "菜单"), 26 | 27 | BUTTON(1, "按钮"); 28 | 29 | PermissionTypeEnum(int code, String description) { 30 | this.code = code; 31 | this.description = description; 32 | } 33 | 34 | @EnumValue 35 | @JsonValue 36 | private final int code; 37 | 38 | private final String description; 39 | 40 | 41 | /** 42 | * 用于 spring mvc 实体参数绑定 43 | */ 44 | @JsonCreator 45 | public static PermissionTypeEnum create(Integer value) { 46 | for (var v : values()) { 47 | if (v.code == value) { 48 | return v; 49 | } 50 | } 51 | return MENU; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/enums/StatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.enums; 2 | 3 | import com.baomidou.mybatisplus.annotation.EnumValue; 4 | import com.fasterxml.jackson.annotation.JsonCreator; 5 | import com.fasterxml.jackson.annotation.JsonValue; 6 | import lombok.Getter; 7 | import lombok.ToString; 8 | 9 | /** 10 | *11 | * 0.禁用 12 | * 1.正常 13 | *
14 | * 15 | * @author Wang Chen Chen 16 | * @version 1.0 17 | * @date 2021/7/5 9:31 18 | */ 19 | 20 | 21 | @Getter 22 | @ToString 23 | public enum StatusEnum { 24 | 25 | DISABLE(0, "禁用"), 26 | 27 | NORMAL(1, "正常"); 28 | 29 | StatusEnum(int code, String description) { 30 | this.code = code; 31 | this.description = description; 32 | } 33 | 34 | @EnumValue 35 | @JsonValue 36 | private final int code; 37 | 38 | private final String description; 39 | 40 | 41 | /** 42 | * 用于 spring mvc 实体参数绑定 43 | */ 44 | @JsonCreator 45 | public static StatusEnum create(Integer value) { 46 | for (var v : values()) { 47 | if (v.code == value) { 48 | return v; 49 | } 50 | } 51 | return NORMAL; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/exception/JwtAuthException.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.exception; 2 | 3 | import com.xaaef.robin.enums.OAuth2Error; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | import org.springframework.security.core.AuthenticationException; 8 | 9 | import static com.xaaef.robin.enums.OAuth2Error.OAUTH2_EXCEPTION; 10 | 11 | 12 | /** 13 | *14 | * 认证异常 15 | *
16 | * 17 | * @author Wang Chen Chen 18 | * @version 1.0.1 19 | * @date 2021/7/5 9:31 20 | */ 21 | 22 | @Getter 23 | @Setter 24 | @ToString 25 | public class JwtAuthException extends AuthenticationException { 26 | 27 | private Integer status; 28 | 29 | 30 | public Integer getStatus() { 31 | return status; 32 | } 33 | 34 | 35 | public void setStatus(Integer status) { 36 | this.status = status; 37 | } 38 | 39 | 40 | public JwtAuthException(int status, String message) { 41 | super(message); 42 | this.status = status; 43 | } 44 | 45 | 46 | public JwtAuthException(String message) { 47 | this(OAUTH2_EXCEPTION.getStatus(), message); 48 | } 49 | 50 | 51 | public JwtAuthException(OAuth2Error status) { 52 | this(status.getStatus(), status.getError()); 53 | } 54 | 55 | 56 | public JwtAuthException() { 57 | this(OAUTH2_EXCEPTION.getError()); 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/jwt/JwtAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.jwt; 2 | 3 | import com.xaaef.robin.enums.OAuth2Error; 4 | import com.xaaef.robin.util.JsonResult; 5 | import com.xaaef.robin.util.JsonUtils; 6 | import com.xaaef.robin.util.ServletUtils; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.security.access.AccessDeniedException; 9 | import org.springframework.security.core.AuthenticationException; 10 | import org.springframework.security.web.AuthenticationEntryPoint; 11 | import org.springframework.security.web.access.AccessDeniedHandler; 12 | import org.springframework.stereotype.Component; 13 | 14 | import javax.servlet.ServletException; 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | import java.io.IOException; 18 | 19 | 20 | @Component 21 | public class JwtAccessDeniedHandler implements AccessDeniedHandler, AuthenticationEntryPoint { 22 | 23 | /** 24 | * 权限不足, 25 | */ 26 | @Override 27 | public void handle(HttpServletRequest request, 28 | HttpServletResponse response, 29 | AccessDeniedException e) throws IOException { 30 | String msg = String.format("请求访问:%s,权限不足,请联系管理员", request.getRequestURI()); 31 | ServletUtils.renderError(response, OAuth2Error.ACCESS_DENIED.getStatus(), msg); 32 | } 33 | 34 | 35 | /** 36 | * 未认证 37 | */ 38 | @Override 39 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 40 | String msg = String.format("请求访问:%s,认证失败,无法访问系统资源", request.getRequestURI()); 41 | ServletUtils.renderError(response, OAuth2Error.OAUTH2_EXCEPTION.getStatus(), msg); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/jwt/JwtTokenProperties.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.jwt; 2 | 3 | import lombok.*; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *10 | *
11 | * 12 | * @author Wang Chen Chen<932560435@qq.com> 13 | * @version 1.0.0 14 | * @date 2020/7/2515:30 15 | */ 16 | 17 | @Getter 18 | @Setter 19 | @ToString 20 | @Builder 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | @ConfigurationProperties(prefix = "jwt.token") 24 | public class JwtTokenProperties { 25 | 26 | /** 27 | * token 在请求头中的名称 28 | */ 29 | private String tokenHeader = "Authorization"; 30 | 31 | /** 32 | * token 类型 33 | */ 34 | private String tokenType = "Bearer "; 35 | 36 | /** 37 | * token 缓存 过期时间 单位(秒) 38 | */ 39 | private Integer tokenExpired = 3600; 40 | 41 | /** 42 | * 短信验证码过期时间 单位(秒) 43 | */ 44 | private Integer smsCodeExpired = 600; 45 | 46 | /** 47 | * 用户被挤下线,提示的过期时间 单位(秒) 48 | */ 49 | private Integer promptExpired = 600; 50 | 51 | /** 52 | * 秘钥 53 | */ 54 | private String secret = "2N321lIkh$*!IfNt4&5!YZykD$7@ApaM8r@b@r@&4CZ7eqKe!s"; 55 | 56 | /** 57 | * 单点登录,是否启用 58 | */ 59 | private Boolean sso = Boolean.TRUE; 60 | 61 | /** 62 | * 需要排除的URL 63 | */ 64 | private String[] excludePath; 65 | 66 | } 67 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/jwt/JwtTokenValue.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.jwt; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | /** 9 | *10 | * token 返回值 11 | *
12 | * 13 | * @author Wang Chen Chen<932560435@qq.com> 14 | * @version 2.0 15 | * @date 2019/12/12 23:29 16 | */ 17 | 18 | 19 | @Getter 20 | @Setter 21 | @Builder 22 | public class JwtTokenValue implements java.io.Serializable { 23 | 24 | /** 25 | * 请求头的值 26 | */ 27 | private String header; 28 | 29 | /** 30 | * 表示访问令牌,必选项。 31 | */ 32 | @JsonProperty("access_token") 33 | private String accessToken; 34 | 35 | /** 36 | * 表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。 37 | */ 38 | @JsonProperty("token_type") 39 | private String tokenType; 40 | 41 | /** 42 | * 表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。 43 | */ 44 | @JsonProperty("expires_in") 45 | private Integer expiresIn; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/jwt/StringGrantedAuthority.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.jwt; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.NoArgsConstructor; 5 | import org.springframework.security.core.GrantedAuthority; 6 | 7 | /** 8 | *9 | * 10 | *
11 | * 12 | * @author WangChenChen 13 | * @version 1.0 14 | * @date 2022/3/22 18:05 15 | */ 16 | 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class StringGrantedAuthority implements GrantedAuthority { 20 | 21 | private String authority; 22 | 23 | public void setAuthority(String authority) { 24 | this.authority = authority; 25 | } 26 | 27 | @Override 28 | public String getAuthority() { 29 | return this.authority; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/mapper/ChinaAreaMapper.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.mapper; 2 | 3 | import com.xaaef.robin.entity.ChinaArea; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | 6 | /** 7 | * @author WangChenChen 8 | * @description 针对表【cn_area([ 通用 ] 中国行政地区表)】的数据库操作Mapper 9 | * @createDate 2022-03-22 09:59:32 10 | * @Entity com.xaaef.robin.entity.CnArea 11 | */ 12 | 13 | public interface ChinaAreaMapper extends BaseMapper10 | * 字典查询,参数 11 | *
12 | * 13 | * @author Wang Chen Chen <932560435@qq.com> 14 | * @version 2.0 15 | * @date 2019/4/18 11:45 16 | */ 17 | 18 | @Data 19 | @ToString 20 | @EqualsAndHashCode 21 | public class DictQueryParams extends QueryParams { 22 | 23 | /** 24 | * 字典类型 25 | */ 26 | private String dictTypeKey; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/param/QueryParams.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.param; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | *12 | * 基础参数传递 13 | *
14 | * 15 | * @author Wang Chen Chen<932560435@qq.com> 16 | * @date 2021/10/21 21:38 17 | */ 18 | 19 | @Getter 20 | @Setter 21 | @ToString 22 | @AllArgsConstructor 23 | public class QueryParams implements java.io.Serializable { 24 | 25 | public static QueryParams build() { 26 | return new QueryParams(); 27 | } 28 | 29 | public static QueryParams build(Integer pageNum, Integer pageSize) { 30 | return new QueryParams(pageNum, pageSize, null, null, null); 31 | } 32 | 33 | public static QueryParams build(Integer pageNum, Integer pageSize, String keywords) { 34 | return new QueryParams(pageNum, pageSize, keywords, null, null); 35 | } 36 | 37 | public QueryParams() { 38 | this.pageNum = 1; 39 | this.pageSize = 10; 40 | } 41 | 42 | /** 43 | * 当前第几页 44 | */ 45 | private Integer pageNum; 46 | 47 | /** 48 | * 每页多少条数据 49 | */ 50 | private Integer pageSize; 51 | 52 | /** 53 | * 搜索,关键字 54 | */ 55 | private String keywords; 56 | 57 | /** 58 | * 开始时间 59 | */ 60 | private LocalDateTime startTime; 61 | 62 | /** 63 | * 结束时间 64 | */ 65 | private LocalDateTime endTime; 66 | 67 | } 68 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/param/UserQueryParams.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.param; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | 8 | /** 9 | *10 | * 用户查询的参数 11 | *
12 | * 13 | * @author Wang Chen Chen <932560435@qq.com> 14 | * @version 2.0 15 | * @date 2019/4/18 11:45 16 | */ 17 | 18 | @Getter 19 | @Setter 20 | @ToString 21 | public class UserQueryParams extends QueryParams { 22 | 23 | /** 24 | * 角色 ID 25 | */ 26 | private Long roleId; 27 | 28 | /** 29 | * 部门 ID 30 | */ 31 | private Long deptId; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /spring-restful-api/src/main/java/com/xaaef/robin/service/ChinaAreaService.java: -------------------------------------------------------------------------------- 1 | package com.xaaef.robin.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; 5 | import com.xaaef.robin.entity.ChinaArea; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | import com.xaaef.robin.param.QueryParams; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author WangChenChen 13 | * @description 针对表【cn_area([ 通用 ] 中国行政地区表)】的数据库操作Service 14 | * @createDate 2022-03-22 09:59:32 15 | */ 16 | 17 | public interface ChinaAreaService extends IService12 | * 服务端 token 认证 13 | *
14 | * 15 | * @author Wang Chen Chen 16 | * @version 1.0.1 17 | * @date 2021/7/12 16:28 18 | */ 19 | 20 | 21 | public interface JwtTokenService { 22 | 23 | /** 24 | * 设置登录的用户 到redis中 25 | * 26 | * @param loginId 27 | * @param loginUser 28 | */ 29 | void setLoginUser(String loginId, JwtLoginUser loginUser); 30 | 31 | 32 | /** 33 | * 校验 token 值是否正确 34 | *
35 | * 例: Bearer eyJhbGciOiJIUzUxMiJ9.eyJqdG6IjE2NDPuFA
36 | *
37 | * @param bearerToken
38 | * @author Wang Chen Chen
39 | * @date 2021/7/12 16:29
40 | */
41 | JwtLoginUser validate(String bearerToken) throws JwtAuthException;
42 |
43 |
44 | /**
45 | * 刷新 token
46 | */
47 | JwtTokenValue refresh();
48 |
49 |
50 | /**
51 | * 退出登录
52 | */
53 | void logout();
54 |
55 |
56 | /**
57 | * 获取 所有的在线用户
58 | *
59 | * @return String 用户名称
60 | * @author Wang Chen Chen
61 | * @date 2021/7/12 16:29
62 | */
63 | Set
12 | * 用户 登录 Service 接口
13 | *
7 | * 验证码
8 | *
13 | * 请求工具类
14 | *