From 2841620be623be15c1832a783136a2b73c2b4424 Mon Sep 17 00:00:00 2001 From: 疯狂的狮子li <15040126243@163.com> Date: 星期四, 13 二月 2020 10:48:51 +0800 Subject: [PATCH] 初始化项目 --- ruoyi-ui/.eslintignore | 10 ruoyi-ui/src/components/ThemePicker/index.vue | 175 ruoyi-ui/src/utils/scroll-to.js | 58 ruoyi-ui/src/layout/components/index.js | 5 ruoyi-ui/src/assets/icons/svg/international.svg | 1 ruoyi/src/main/resources/mybatis/tool/GenTableColumnMapper.xml | 120 ruoyi-ui/src/assets/icons/svg/druid.svg | 1 ruoyi-ui/src/assets/icons/svg/eye.svg | 1 ruoyi-ui/src/assets/styles/index.scss | 191 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java | 100 ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml | 144 ruoyi-ui/package.json | 103 ruoyi-ui/src/api/system/dict/type.js | 61 ruoyi-ui/src/assets/icons/svg/system.svg | 2 ruoyi-ui/src/assets/icons/svg/tree.svg | 1 ruoyi-ui/src/assets/icons/svg/bug.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataScope.java | 28 ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue | 85 ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableMapper.java | 76 ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml | 122 ruoyi-ui/src/assets/icons/svg/pdf.svg | 1 ruoyi-ui/src/views/system/dept/index.vue | 308 ruoyi/src/main/java/com/ruoyi/common/utils/DateUtils.java | 155 ruoyi-ui/build/index.js | 35 ruoyi/src/main/java/com/ruoyi/framework/security/service/PermissionService.java | 169 ruoyi-ui/src/assets/icons/svg/monitor.svg | 2 ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java | 46 ruoyi-ui/.env.development | 8 ruoyi/src/main/java/com/ruoyi/framework/interceptor/annotation/RepeatSubmit.java | 23 ruoyi-ui/src/utils/jsencrypt.js | 30 ruoyi-ui/src/assets/icons/svg/job.svg | 1 ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java | 101 ruoyi-ui/src/store/modules/user.js | 96 ruoyi-ui/src/components/Editor/index.vue | 226 ruoyi-ui/src/store/index.js | 23 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysMenuService.java | 136 ruoyi-ui/src/assets/icons/svg/date.svg | 1 ruoyi-ui/src/views/system/menu/index.vue | 337 ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml | 123 ruoyi-ui/src/assets/icons/svg/guide.svg | 1 ruoyi-ui/src/api/system/user.js | 127 ruoyi-ui/src/views/system/log/index.vue | 3 ruoyi-ui/src/assets/icons/svg/validCode.svg | 1 ruoyi/src/main/java/com/ruoyi/common/core/text/StrFormatter.java | 92 ruoyi/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java | 34 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysProfileController.java | 127 ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java | 26 ruoyi-ui/src/assets/404_images/404.png | 0 ruoyi-ui/src/assets/icons/svg/lock.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java | 105 ruoyi-ui/src/assets/image/profile.jpg | 0 ruoyi-ui/src/api/menu.js | 9 ruoyi-ui/src/components/Screenfull/index.vue | 60 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java | 198 ruoyi/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java | 16 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java | 116 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java | 177 ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java | 126 ruoyi-ui/src/assets/icons/svg/user.svg | 1 ruoyi-ui/src/assets/icons/svg/tree-table.svg | 1 ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTable.java | 269 ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java | 89 ruoyi-ui/src/views/components/icons/element-icons.js | 74 ruoyi/src/main/java/com/ruoyi/framework/web/page/PageDomain.java | 69 ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/MetaVo.java | 49 ruoyi-ui/src/views/tool/gen/genInfoForm.vue | 154 ruoyi-ui/src/assets/icons/svg/form.svg | 1 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java | 176 ruoyi-ui/src/assets/icons/svg/edit.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/config/GenConfig.java | 66 ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java | 113 ruoyi-ui/src/assets/image/login-background.jpg | 0 ruoyi-ui/src/assets/styles/element-variables.scss | 31 ruoyi/src/main/resources/vm/vue/index.vue.vm | 439 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java | 85 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java | 77 LICENSE | 20 ruoyi-ui/src/views/system/user/profile/userInfo.vue | 80 ruoyi-ui/src/store/modules/tagsView.js | 165 ruoyi/src/main/java/com/ruoyi/common/utils/IdUtils.java | 51 ruoyi/src/main/java/com/ruoyi/project/common/CaptchaController.java | 62 ruoyi-ui/src/layout/components/Sidebar/index.vue | 54 ruoyi-ui/src/assets/icons/svg/drag.svg | 1 ruoyi/src/main/java/com/ruoyi/common/utils/Arith.java | 114 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java | 60 ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTableColumn.java | 368 ruoyi-ui/bin/package.bat | 12 ruoyi-ui/src/layout/components/Navbar.vue | 181 ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java | 16 ruoyi/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java | 248 ruoyi-ui/src/components/RightPanel/index.vue | 149 ruoyi-ui/src/layout/components/Sidebar/Logo.vue | 84 ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java | 84 ruoyi-ui/src/api/system/menu.js | 60 ruoyi-ui/src/views/monitor/online/index.vue | 128 ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java | 116 ruoyi/src/main/java/com/ruoyi/framework/security/service/SysPermissionService.java | 66 ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java | 61 ruoyi-ui/src/assets/icons/svg/theme.svg | 1 ruoyi-ui/src/assets/icons/svgo.yml | 22 ruoyi/src/main/java/com/ruoyi/common/constant/UserConstants.java | 39 ruoyi-ui/src/store/modules/permission.js | 54 ruoyi/src/main/resources/logback.xml | 93 ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java | 113 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java | 113 ruoyi-ui/.gitignore | 23 ruoyi-ui/src/views/login/auth-redirect.vue | 15 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java | 113 ruoyi/src/main/resources/vm/java/domain.java.vm | 76 ruoyi-ui/src/components/Hamburger/index.vue | 44 ruoyi-ui/src/assets/icons/svg/eye-open.svg | 1 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java | 48 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java | 76 ruoyi/src/main/resources/vm/xml/mapper.xml.vm | 95 ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableColumnServiceImpl.java | 68 ruoyi/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java | 77 ruoyi-ui/src/assets/styles/btn.scss | 99 ruoyi-ui/src/api/monitor/server.js | 9 ruoyi-ui/src/assets/icons/svg/documentation.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java | 94 ruoyi-ui/src/assets/icons/svg/code.svg | 1 ruoyi/bin/clean.bat | 12 ruoyi/src/main/java/com/ruoyi/common/utils/text/Convert.java | 999 + ruoyi-ui/src/assets/icons/index.js | 9 ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java | 41 ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableServiceImpl.java | 341 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java | 324 ruoyi/src/main/java/com/ruoyi/common/enums/UserStatus.java | 30 ruoyi-ui/src/api/tool/gen.js | 59 ruoyi-ui/src/views/tool/build/index.vue | 5 ruoyi/src/main/java/com/ruoyi/common/utils/text/CharsetKit.java | 87 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java | 217 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java | 95 ruoyi/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java | 44 ruoyi/src/main/resources/vm/java/controller.java.vm | 103 ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java | 48 ruoyi-ui/src/assets/icons/svg/phone.svg | 1 ruoyi-ui/src/layout/components/Settings/index.vue | 108 ruoyi-ui/.editorconfig | 22 ruoyi-ui/src/store/getters.js | 15 ruoyi-ui/src/views/tool/swagger/index.vue | 26 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java | 119 ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml | 56 ruoyi/src/main/java/com/ruoyi/framework/manager/AsyncManager.java | 55 ruoyi-ui/src/assets/icons/svg/qq.svg | 1 ruoyi-ui/src/components/RuoYi/index.vue | 21 ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java | 67 ruoyi-ui/src/views/system/user/profile/userAvatar.vue | 138 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java | 311 ruoyi-ui/src/assets/icons/svg/logininfor.svg | 1 ruoyi-ui/src/directive/permission/index.js | 15 ruoyi-ui/src/assets/logo/logo.png | 0 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java | 109 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDeptService.java | 101 ruoyi-ui/src/utils/request.js | 65 ruoyi/src/main/java/com/ruoyi/common/utils/sign/Base64.java | 291 ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java | 253 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java | 381 ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableColumnMapper.java | 52 ruoyi-ui/src/components/SvgIcon/index.vue | 61 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java | 100 ruoyi/src/main/java/com/ruoyi/common/exception/user/UserException.java | 18 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java | 154 ruoyi/src/main/java/com/ruoyi/common/utils/ServletUtils.java | 136 ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/RouterVo.java | 133 ruoyi-ui/src/store/modules/app.js | 56 ruoyi-ui/src/views/dashboard/RaddarChart.vue | 116 ruoyi-ui/src/views/system/user/index.vue | 663 ruoyi/src/main/java/com/ruoyi/framework/web/domain/Server.java | 241 ruoyi-ui/src/assets/icons/svg/online.svg | 1 ruoyi/ry.sh | 86 ruoyi-ui/src/views/components/icons/index.vue | 87 ruoyi/src/main/resources/banner.txt | 24 ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableService.java | 99 ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java | 16 ruoyi-ui/src/assets/icons/svg/component.svg | 1 ruoyi-ui/src/assets/icons/svg/clipboard.svg | 1 ruoyi-ui/src/views/tool/gen/editTable.vue | 204 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java | 59 ruoyi-ui/src/components/IconSelect/requireIcons.js | 11 ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue | 93 ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml | 182 ruoyi/src/main/java/com/ruoyi/framework/web/domain/AjaxResult.java | 148 ruoyi/src/main/java/com/ruoyi/common/exception/BaseException.java | 97 ruoyi-ui/src/views/tool/gen/importTable.vue | 114 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java | 131 ruoyi-ui/vue.config.js | 130 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java | 95 ruoyi-ui/src/assets/icons/svg/server.svg | 1 README.md | 84 ruoyi-ui/src/assets/styles/mixin.scss | 66 ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java | 76 ruoyi-ui/src/layout/index.vue | 102 ruoyi/src/main/java/com/ruoyi/framework/config/ServerConfig.java | 32 ruoyi-ui/src/assets/icons/svg/message.svg | 1 ruoyi-ui/bin/run-web.bat | 12 ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java | 43 ruoyi-ui/src/views/dashboard/PieChart.vue | 79 ruoyi-ui/src/views/error/401.vue | 88 ruoyi-ui/src/store/modules/settings.js | 34 ruoyi-ui/README.md | 30 ruoyi-ui/src/layout/components/Sidebar/FixiOSBug.js | 25 ruoyi-ui/src/layout/components/Sidebar/Link.vue | 36 ruoyi-ui/src/assets/icons/svg/star.svg | 1 ruoyi-ui/src/views/system/dict/data.vue | 355 ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/GenUtils.java | 238 ruoyi-ui/src/settings.js | 31 ruoyi/src/main/java/com/ruoyi/common/core/lang/UUID.java | 481 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java | 107 ruoyi-ui/public/favicon.ico | 0 ruoyi-ui/src/views/monitor/server/index.vue | 210 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java | 130 ruoyi-ui/src/views/components/icons/svg-icons.js | 10 ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml | 105 ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java | 220 ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java | 92 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserRole.java | 46 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java | 202 ruoyi-ui/src/assets/styles/element-ui.scss | 79 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java | 134 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java | 455 ruoyi-ui/src/views/dashboard/mixins/resize.js | 52 ruoyi/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java | 66 ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java | 160 ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java | 142 ruoyi-ui/src/views/dashboard/LineChart.vue | 135 ruoyi/src/main/resources/mybatis/system/SysUserPostMapper.xml | 34 ruoyi-ui/src/views/system/dict/index.vue | 350 ruoyi-ui/src/assets/icons/svg/build.svg | 1 ruoyi-ui/src/views/system/user/profile/index.vue | 91 ruoyi/src/main/java/com/ruoyi/project/monitor/controller/ServerController.java | 28 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java | 294 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java | 60 ruoyi-ui/src/api/system/dept.js | 60 ruoyi-ui/src/assets/icons/svg/icon.svg | 1 ruoyi-ui/src/layout/components/TagsView/index.vue | 286 ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml | 82 ruoyi/src/main/resources/mybatis/system/SysDeptMapper.xml | 151 ruoyi-ui/src/assets/icons/svg/example.svg | 1 ruoyi-ui/src/views/system/post/index.vue | 327 ruoyi/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java | 69 ruoyi-ui/src/assets/styles/sidebar.scss | 209 ruoyi-ui/src/api/system/post.js | 53 ruoyi-ui/src/components/IconSelect/index.vue | 69 ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java | 55 ruoyi-ui/src/assets/icons/svg/excel.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java | 55 ruoyi-ui/src/assets/401_images/401.gif | 0 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java | 123 ruoyi/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java | 53 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java | 92 ruoyi-ui/src/components/PanThumb/index.vue | 142 ruoyi-ui/src/utils/index.js | 317 ruoyi-ui/src/assets/icons/svg/link.svg | 1 ruoyi-ui/src/assets/icons/svg/email.svg | 1 ruoyi/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java | 569 ruoyi-ui/src/views/system/role/index.vue | 548 ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java | 45 ruoyi-ui/src/assets/icons/svg/people.svg | 1 ruoyi/src/main/java/com/ruoyi/common/exception/UtilException.java | 26 ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java | 114 ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml | 112 ruoyi/src/main/java/com/ruoyi/framework/web/domain/BaseEntity.java | 156 ruoyi-ui/src/api/login.js | 40 ruoyi-ui/src/assets/icons/svg/log.svg | 1 ruoyi-ui/src/assets/icons/svg/nested.svg | 1 ruoyi/src/main/resources/mybatis/system/SysUserRoleMapper.xml | 44 ruoyi-ui/src/permission.js | 64 ruoyi-ui/src/views/tool/gen/basicInfoForm.vue | 61 ruoyi/src/main/resources/vm/java/mapper.java.vm | 61 ruoyi-ui/src/views/monitor/druid/index.vue | 26 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java | 116 ruoyi-ui/src/assets/icons/svg/chart.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java | 122 ruoyi-ui/src/views/login.vue | 203 ruoyi-ui/src/api/system/config.js | 61 ruoyi-ui/src/views/redirect.vue | 12 ruoyi/sql/ry_20191202.sql | 675 ruoyi/src/main/resources/application.yml | 122 ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml | 89 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java | 167 ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java | 94 ruoyi/src/main/java/com/ruoyi/common/utils/SecurityUtils.java | 90 ruoyi/src/main/resources/mybatis/mybatis-config.xml | 15 ruoyi-ui/src/views/error/404.vue | 233 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java | 20 ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java | 40 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserPostMapper.java | 44 ruoyi-ui/.env.production | 5 ruoyi-ui/.env.staging | 7 ruoyi-ui/src/main.js | 70 ruoyi-ui/src/assets/404_images/404_cloud.png | 0 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java | 129 ruoyi-ui/src/router/index.js | 114 ruoyi-ui/src/assets/icons/svg/education.svg | 1 ruoyi-ui/src/assets/styles/transition.scss | 48 ruoyi-ui/public/index.html | 207 ruoyi/src/main/java/com/ruoyi/common/exception/DemoModeException.java | 15 ruoyi-ui/src/assets/icons/svg/table.svg | 1 ruoyi-ui/src/layout/mixin/ResizeHandler.js | 45 ruoyi/src/main/java/com/ruoyi/RuoYiApplication.java | 30 ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java | 228 ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableColumnService.java | 44 ruoyi-ui/src/components/SizeSelect/index.vue | 57 ruoyi-ui/src/layout/components/AppMain.vue | 57 ruoyi/src/main/resources/vm/java/service.java.vm | 61 ruoyi-ui/src/assets/icons/svg/tool.svg | 1 ruoyi-ui/src/views/dashboard/PanelGroup.vue | 181 ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java | 85 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java | 141 ruoyi/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java | 39 ruoyi/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java | 71 ruoyi-ui/src/assets/icons/svg/money.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java | 18 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java | 111 ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java | 30 ruoyi-ui/src/components/Breadcrumb/index.vue | 81 ruoyi-ui/src/assets/styles/variables.scss | 35 ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java | 65 ruoyi-ui/src/assets/icons/svg/skill.svg | 1 ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java | 66 ruoyi/src/main/java/com/ruoyi/common/core/text/CharsetKit.java | 86 ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java | 105 ruoyi-ui/src/assets/icons/svg/tab.svg | 1 ruoyi/pom.xml | 282 ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java | 142 ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java | 207 ruoyi/src/main/resources/i18n/messages.properties | 36 ruoyi-ui/src/assets/icons/svg/password.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java | 117 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserPost.java | 46 ruoyi-ui/src/assets/icons/svg/wechat.svg | 1 ruoyi/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java | 16 ruoyi-ui/src/assets/icons/svg/dashboard.svg | 1 ruoyi/src/main/java/com/ruoyi/common/constant/HttpStatus.java | 89 ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityInitializer.java | 35 ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeSelect.java | 77 ruoyi/src/main/java/com/ruoyi/common/utils/MessageUtils.java | 26 ruoyi/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java | 36 ruoyi-ui/src/assets/icons/svg/size.svg | 1 ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | 872 + ruoyi/src/main/java/com/ruoyi/common/exception/CustomException.java | 43 ruoyi-ui/src/directive/permission/hasRole.js | 28 ruoyi-ui/src/assets/icons/svg/shopping.svg | 1 ruoyi-ui/src/utils/ruoyi.js | 103 ruoyi/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java | 114 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java | 99 ruoyi-ui/src/utils/permission.js | 24 ruoyi/src/main/java/com/ruoyi/framework/web/page/TableSupport.java | 49 ruoyi-ui/src/assets/icons/svg/dict.svg | 1 ruoyi/src/main/java/com/ruoyi/common/utils/VerifyCodeUtils.java | 226 ruoyi/src/main/java/com/ruoyi/framework/security/service/UserDetailsServiceImpl.java | 60 ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java | 62 ruoyi-ui/src/utils/auth.js | 15 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserRoleMapper.java | 62 ruoyi-ui/src/components/Pagination/index.vue | 101 ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java | 97 ruoyi/src/main/resources/vm/java/serviceImpl.java.vm | 109 ruoyi-ui/src/views/tool/gen/index.vue | 287 ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java | 83 ruoyi-ui/src/views/dashboard/BarChart.vue | 102 ruoyi-ui/src/api/system/notice.js | 44 ruoyi-ui/src/views/index.vue | 98 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java | 19 ruoyi-ui/src/assets/icons/svg/zip.svg | 1 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java | 141 ruoyi-ui/src/assets/icons/svg/404.svg | 1 ruoyi/src/main/java/com/ruoyi/RuoYiServletInitializer.java | 18 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java | 68 ruoyi/src/main/java/com/ruoyi/framework/security/service/SysLoginService.java | 88 ruoyi/src/main/resources/application-druid.yml | 57 ruoyi-ui/src/assets/icons/svg/exit-fullscreen.svg | 1 ruoyi/src/main/java/com/ruoyi/common/exception/file/FileException.java | 19 ruoyi-ui/src/utils/validate.js | 83 ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java | 406 ruoyi/src/main/resources/mybatis/system/SysRoleDeptMapper.xml | 34 ruoyi-ui/src/api/monitor/operlog.js | 35 ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java | 85 ruoyi/src/main/resources/mybatis/system/SysRoleMenuMapper.xml | 27 ruoyi-ui/src/assets/styles/ruoyi.scss | 190 ruoyi-ui/src/views/monitor/operlog/index.vue | 315 ruoyi/src/main/java/com/ruoyi/project/tool/swagger/TestController.java | 175 ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java | 41 ruoyi-ui/src/layout/components/Sidebar/Item.vue | 29 ruoyi/src/main/resources/vm/js/api.js.vm | 53 ruoyi-ui/src/api/monitor/logininfor.js | 35 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java | 197 ruoyi-ui/src/directive/permission/hasPermi.js | 28 ruoyi/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java | 217 ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java | 134 ruoyi/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java | 189 ruoyi-ui/src/assets/icons/svg/fullscreen.svg | 1 ruoyi/src/main/java/com/ruoyi/common/utils/LogUtils.java | 18 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleMenu.java | 46 ruoyi-ui/src/assets/icons/svg/post.svg | 1 ruoyi/bin/run-tomcat.bat | 14 ruoyi-ui/src/assets/icons/svg/swagger.svg | 1 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleDept.java | 46 ruoyi/src/main/java/com/ruoyi/common/utils/text/StrFormatter.java | 93 ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java | 185 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysLoginController.java | 94 ruoyi-ui/src/views/system/notice/index.vue | 345 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java | 109 ruoyi-ui/.eslintrc.js | 199 ruoyi/.gitignore | 43 ruoyi/bin/package.bat | 12 ruoyi-ui/src/views/monitor/job/index.vue | 5 ruoyi-ui/src/views/system/config/index.vue | 346 ruoyi-ui/src/assets/icons/svg/peoples.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java | 26 ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java | 48 ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java | 75 ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityUtils.java | 281 ruoyi/src/main/java/com/ruoyi/common/utils/StringUtils.java | 453 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMenuMapper.java | 36 ruoyi/src/main/java/com/ruoyi/common/enums/HttpMethod.java | 36 ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java | 94 ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleDeptMapper.java | 44 ruoyi-ui/src/api/system/dict/data.js | 61 ruoyi-ui/src/utils/zipdownload.js | 40 ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java | 121 ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java | 91 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java | 24 ruoyi-ui/src/api/monitor/online.js | 18 ruoyi-ui/src/assets/icons/svg/search.svg | 1 ruoyi-ui/src/views/login/components/SocialSignin.vue | 72 ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java | 41 ruoyi/src/main/resources/vm/sql/sql.vm | 22 ruoyi-ui/src/assets/icons/svg/language.svg | 1 ruoyi/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java | 101 ruoyi/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java | 152 ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java | 243 ruoyi/src/main/java/com/ruoyi/common/core/text/Convert.java | 999 + ruoyi/src/main/resources/mybatis/tool/GenTableMapper.xml | 181 ruoyi-ui/babel.config.js | 5 ruoyi-ui/src/views/monitor/logininfor/index.vue | 227 ruoyi-ui/src/assets/icons/svg/download.svg | 1 ruoyi-ui/src/assets/icons/svg/list.svg | 1 ruoyi/src/main/resources/mybatis/system/SysMenuMapper.xml | 174 ruoyi-ui/src/api/system/role.js | 75 ruoyi-ui/src/components/HeaderSearch/index.vue | 180 ruoyi-ui/src/views/system/user/profile/resetPwd.vue | 76 ruoyi-ui/src/App.vue | 11 ruoyi/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java | 16 ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java | 42 ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java | 101 ruoyi/src/main/java/com/ruoyi/common/utils/Threads.java | 99 447 files changed, 43,037 insertions(+), 0 deletions(-) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8564f29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 RuoYi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d09856 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +## 骞冲彴绠�浠� + +涓�鐩存兂鍋氫竴娆惧悗鍙扮鐞嗙郴缁燂紝鐪嬩簡寰堝浼樼鐨勫紑婧愰」鐩絾鏄彂鐜版病鏈夊悎閫傜殑銆備簬鏄埄鐢ㄧ┖闂蹭紤鎭椂闂村紑濮嬭嚜宸卞啓浜嗕竴濂楀悗鍙扮郴缁熴�傚姝ゆ湁浜嗚嫢渚濄�傚ス鍙互鐢ㄤ簬鎵�鏈夌殑Web搴旂敤绋嬪簭锛屽缃戠珯绠$悊鍚庡彴锛岀綉绔欎細鍛樹腑蹇冿紝CMS锛孋RM锛孫A銆傛墍鏈夊墠绔悗鍙颁唬鐮佸皝瑁呰繃鍚庡崄鍒嗙簿绠�鏄撲笂鎵嬶紝鍑洪敊姒傜巼浣庛�傚悓鏃舵敮鎸佺Щ鍔ㄥ鎴风璁块棶銆傜郴缁熶細闄嗙画鏇存柊涓�浜涘疄鐢ㄥ姛鑳姐�� + +鎬у埆鐢凤紝鑻ヤ緷鏄粰杩樻病鏈夊嚭鐢熷コ鍎垮彇鐨勫悕瀛楋紙瀵撴剰锛氫綘鑻ヤ笉绂讳笉寮冿紝鎴戝繀鐢熸鐩镐緷锛� + +鍙傝�冨悗鍙版ā鏉縖vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) + +> 闃块噷浜戞湇鍔″櫒89鍏�/骞达紝鍙�12骞存湯鐗规儬锛岀垎娆句骇鍝侀檺鏃�1鎶� 锛歔鐐规垜杩涘叆](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link) + +> 濡傞渶涓嶅垎绂诲簲鐢紝璇风Щ姝� [RuoYi](https://gitee.com/y_project/RuoYi) `(淇濇寔鍚屾鏇存柊)`锛屽闇�鍏朵粬鐗堟湰锛岃绉绘 [椤圭洰鎵╁睍](http://doc.ruoyi.vip/ruoyi/document/xmkz.html) `(涓嶅畾鏃舵洿鏂�)` + +> 闃块噷浜戦�氱敤浜戜骇鍝�1888浼樻儬鍒� 锛歔鐐规垜棰嗗彇](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof) 鑵捐浜戦�氱敤浜戜骇鍝�2860浼樻儬鍒� 锛歔鐐规垜棰嗗彇](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console) `(浠呴檺鏂扮敤鎴�)` + +> 闃块噷浜慔i鎷艰喘 闄愰噺鐖嗘 浣庤嚦199鍏�/骞� [鐐规垜杩涘叆](https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof) `(浠呴檺鏂扮敤鎴�)` + +## 鍐呯疆鍔熻兘 + +1. 鐢ㄦ埛绠$悊锛氱敤鎴锋槸绯荤粺鎿嶄綔鑰咃紝璇ュ姛鑳戒富瑕佸畬鎴愮郴缁熺敤鎴烽厤缃�� +2. 閮ㄩ棬绠$悊锛氶厤缃郴缁熺粍缁囨満鏋勶紙鍏徃銆侀儴闂ㄣ�佸皬缁勶級锛屾爲缁撴瀯灞曠幇鏀寔鏁版嵁鏉冮檺銆� +3. 宀椾綅绠$悊锛氶厤缃郴缁熺敤鎴锋墍灞炴媴浠昏亴鍔°�� +4. 鑿滃崟绠$悊锛氶厤缃郴缁熻彍鍗曪紝鎿嶄綔鏉冮檺锛屾寜閽潈闄愭爣璇嗙瓑銆� +5. 瑙掕壊绠$悊锛氳鑹茶彍鍗曟潈闄愬垎閰嶃�佽缃鑹叉寜鏈烘瀯杩涜鏁版嵁鑼冨洿鏉冮檺鍒掑垎銆� +6. 瀛楀吀绠$悊锛氬绯荤粺涓粡甯镐娇鐢ㄧ殑涓�浜涜緝涓哄浐瀹氱殑鏁版嵁杩涜缁存姢銆� +7. 鍙傛暟绠$悊锛氬绯荤粺鍔ㄦ�侀厤缃父鐢ㄥ弬鏁般�� +8. 閫氱煡鍏憡锛氱郴缁熼�氱煡鍏憡淇℃伅鍙戝竷缁存姢銆� +9. 鎿嶄綔鏃ュ織锛氱郴缁熸甯告搷浣滄棩蹇楄褰曞拰鏌ヨ锛涚郴缁熷紓甯镐俊鎭棩蹇楄褰曞拰鏌ヨ銆� +10. 鐧诲綍鏃ュ織锛氱郴缁熺櫥褰曟棩蹇楄褰曟煡璇㈠寘鍚櫥褰曞紓甯搞�� +11. 鍦ㄧ嚎鐢ㄦ埛锛氬綋鍓嶇郴缁熶腑娲昏穬鐢ㄦ埛鐘舵�佺洃鎺с�� +12. 瀹氭椂浠诲姟锛氬湪绾匡紙娣诲姞銆佷慨鏀广�佸垹闄�)浠诲姟璋冨害鍖呭惈鎵ц缁撴灉鏃ュ織銆� +13. 浠g爜鐢熸垚锛氬墠鍚庣浠g爜鐨勭敓鎴愶紙java銆乭tml銆亁ml銆乻ql锛夋敮鎸丆RUD涓嬭浇 銆� +14. 绯荤粺鎺ュ彛锛氭牴鎹笟鍔′唬鐮佽嚜鍔ㄧ敓鎴愮浉鍏崇殑api鎺ュ彛鏂囨。銆� +15. 鏈嶅姟鐩戞帶锛氱洃瑙嗗綋鍓嶇郴缁烠PU銆佸唴瀛樸�佺鐩樸�佸爢鏍堢瓑鐩稿叧淇℃伅銆� +16. 鍦ㄧ嚎鏋勫缓鍣細鎷栧姩琛ㄥ崟鍏冪礌鐢熸垚鐩稿簲鐨凥TML浠g爜銆� +17. 杩炴帴姹犵洃瑙嗭細鐩戣褰撳墠绯荤粺鏁版嵁搴撹繛鎺ユ睜鐘舵�侊紝鍙繘琛屽垎鏋怱QL鎵惧嚭绯荤粺鎬ц兘鐡堕銆� +## 鍦ㄧ嚎浣撻獙 +> admin/admin123 +> 闄嗛檰缁画鏀跺埌涓�浜涙墦璧忥紝涓轰簡鏇村ソ鐨勪綋楠屽凡鐢ㄤ簬婕旂ず鏈嶅姟鍣ㄥ崌绾с�傝阿璋㈠悇浣嶅皬浼欎即銆� + +婕旂ず鍦板潃锛歨ttp://vue.ruoyi.vip + +鏂囨。鍦板潃锛歨ttp://doc.ruoyi.vip + +## 婕旂ず鍥� + +<table> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/707825ad3f29de74a8d6d02fbd73ad631ea.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/46be40cc6f01aa300eed53a19b5012bf484.jpg"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/4284796d4cea240d181b8f2201813dda710.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/3ecfac87a049f7fe36abbcaafb2c40d36cf.jpg"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/c14c1ee9a64a6a9c2c22f67d43198767dbe.jpg"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/fdea1d8bb8625c27bf964176a2c8ebc6945.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/509d2708cfd762b6e6339364cac1cc1970c.jpg"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/up-f1fd681cc9d295db74e85ad6d2fe4389454.png"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td> + </tr> + <tr> + <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td> + <td><img src="https://oscimg.oschina.net/oscnet/up-6d73c2140ce694e3de4c05035fdc1868d4c.png"/></td> + </tr> +</table> + + +## 鑻ヤ緷鍓嶅悗绔垎绂讳氦娴佺兢 + +QQ缇わ細 [ [鐐瑰嚮鎸夐挳鍏ョ兢銆� \ No newline at end of file diff --git a/ruoyi-ui/.editorconfig b/ruoyi-ui/.editorconfig new file mode 100644 index 0000000..7034f9b --- /dev/null +++ b/ruoyi-ui/.editorconfig @@ -0,0 +1,22 @@ +# 鍛婅瘔EditorConfig鎻掍欢锛岃繖鏄牴鏂囦欢锛屼笉鐢ㄧ户缁線涓婃煡鎵� +root = true + +# 鍖归厤鍏ㄩ儴鏂囦欢 +[*] +# 璁剧疆瀛楃闆� +charset = utf-8 +# 缂╄繘椋庢牸锛屽彲閫塻pace銆乼ab +indent_style = space +# 缂╄繘鐨勭┖鏍兼暟 +indent_size = 2 +# 缁撳熬鎹㈣绗︼紝鍙�塴f銆乧r銆乧rlf +end_of_line = lf +# 鍦ㄦ枃浠剁粨灏炬彃鍏ユ柊琛� +insert_final_newline = true +# 鍒犻櫎涓�琛屼腑鐨勫墠鍚庣┖鏍� +trim_trailing_whitespace = true + +# 鍖归厤md缁撳熬鐨勬枃浠� +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development new file mode 100644 index 0000000..28b97c7 --- /dev/null +++ b/ruoyi-ui/.env.development @@ -0,0 +1,8 @@ +# 寮�鍙戠幆澧冮厤缃� +ENV = 'development' + +# 鑻ヤ緷绠$悊绯荤粺/寮�鍙戠幆澧� +VUE_APP_BASE_API = '/dev-api' + +# 璺敱鎳掑姞杞� +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production new file mode 100644 index 0000000..27c717e --- /dev/null +++ b/ruoyi-ui/.env.production @@ -0,0 +1,5 @@ +# 鐢熶骇鐜閰嶇疆 +ENV = 'production' + +# 鑻ヤ緷绠$悊绯荤粺/鐢熶骇鐜 +VUE_APP_BASE_API = '/prod-api' diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging new file mode 100644 index 0000000..6195736 --- /dev/null +++ b/ruoyi-ui/.env.staging @@ -0,0 +1,7 @@ +NODE_ENV = production + +# 娴嬭瘯鐜閰嶇疆 +ENV = 'staging' + +# 鑻ヤ緷绠$悊绯荤粺/娴嬭瘯鐜 +VUE_APP_BASE_API = '/stage-api' diff --git a/ruoyi-ui/.eslintignore b/ruoyi-ui/.eslintignore new file mode 100644 index 0000000..89be6f6 --- /dev/null +++ b/ruoyi-ui/.eslintignore @@ -0,0 +1,10 @@ +# 蹇界暐build鐩綍涓嬬被鍨嬩负js鐨勬枃浠剁殑璇硶妫�鏌� +build/*.js +# 蹇界暐src/assets鐩綍涓嬫枃浠剁殑璇硶妫�鏌� +src/assets +# 蹇界暐public鐩綍涓嬫枃浠剁殑璇硶妫�鏌� +public +# 蹇界暐褰撳墠鐩綍涓嬩负js鐨勬枃浠剁殑璇硶妫�鏌� +*.js +# 蹇界暐褰撳墠鐩綍涓嬩负vue鐨勬枃浠剁殑璇硶妫�鏌� +*.vue \ No newline at end of file diff --git a/ruoyi-ui/.eslintrc.js b/ruoyi-ui/.eslintrc.js new file mode 100644 index 0000000..82bbdee --- /dev/null +++ b/ruoyi-ui/.eslintrc.js @@ -0,0 +1,199 @@ +// ESlint 妫�鏌ラ厤缃� +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/ruoyi-ui/.gitignore b/ruoyi-ui/.gitignore new file mode 100644 index 0000000..78a752d --- /dev/null +++ b/ruoyi-ui/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/ruoyi-ui/README.md b/ruoyi-ui/README.md new file mode 100644 index 0000000..3b5daac --- /dev/null +++ b/ruoyi-ui/README.md @@ -0,0 +1,30 @@ +## 开发 + +```bash +# 克隆项目 +git clone https://gitee.com/y_project/RuoYi-Vue + +# 进入项目目录 +cd ruoyi-ui + +# 安装依赖 +npm install + +# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 +npm install --registry=https://registry.npm.taobao.org + +# 启动服务 +npm run dev +``` + +浏览器访问 http://localhost:80 + +## 发布 + +```bash +# 构建测试环境 +npm run build:stage + +# 构建生产环境 +npm run build:prod +``` \ No newline at end of file diff --git a/ruoyi-ui/babel.config.js b/ruoyi-ui/babel.config.js new file mode 100644 index 0000000..ba17966 --- /dev/null +++ b/ruoyi-ui/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/app' + ] +} diff --git a/ruoyi-ui/bin/package.bat b/ruoyi-ui/bin/package.bat new file mode 100644 index 0000000..9997921 --- /dev/null +++ b/ruoyi-ui/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 打包Web工程,生成node_modules包文件。 +echo. + +%~d0 +cd %~dp0 + +cd .. +npm install --registry=https://registry.npm.taobao.org + +pause \ No newline at end of file diff --git a/ruoyi-ui/bin/run-web.bat b/ruoyi-ui/bin/run-web.bat new file mode 100644 index 0000000..a938e89 --- /dev/null +++ b/ruoyi-ui/bin/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 使用 Vue 运行 Web 工程。 +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run dev + +pause \ No newline at end of file diff --git a/ruoyi-ui/build/index.js b/ruoyi-ui/build/index.js new file mode 100644 index 0000000..0c57de2 --- /dev/null +++ b/ruoyi-ui/build/index.js @@ -0,0 +1,35 @@ +const { run } = require('runjs') +const chalk = require('chalk') +const config = require('../vue.config.js') +const rawArgv = process.argv.slice(2) +const args = rawArgv.join(' ') + +if (process.env.npm_config_preview || rawArgv.includes('--preview')) { + const report = rawArgv.includes('--report') + + run(`vue-cli-service build ${args}`) + + const port = 9526 + const publicPath = config.publicPath + + var connect = require('connect') + var serveStatic = require('serve-static') + const app = connect() + + app.use( + publicPath, + serveStatic('./dist', { + index: ['index.html', '/'] + }) + ) + + app.listen(port, function () { + console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) + if (report) { + console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) + } + + }) +} else { + run(`vue-cli-service build ${args}`) +} diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json new file mode 100644 index 0000000..cafa1da --- /dev/null +++ b/ruoyi-ui/package.json @@ -0,0 +1,103 @@ +{ + "name": "ruoyi", + "version": "2.0.0", + "description": "鑻ヤ緷绠$悊绯荤粺", + "author": "鑻ヤ緷", + "license": "MIT", + "scripts": { + "dev": "vue-cli-service serve", + "build:prod": "vue-cli-service build", + "build:stage": "vue-cli-service build --mode staging", + "preview": "node build/index.js --preview", + "lint": "eslint --ext .js,.vue src", + "test:unit": "jest --clearCache && vue-cli-service test:unit", + "test:ci": "npm run lint && npm run test:unit", + "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", + "new": "plop" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "keywords": [ + "vue", + "admin", + "dashboard", + "element-ui", + "boilerplate", + "admin-template", + "management-system" + ], + "repository": { + "type": "git", + "url": "https://gitee.com/y_project/RuoYi-Vue.git" + }, + "dependencies": { + "@riophae/vue-treeselect": "0.4.0", + "vue-quill-editor": "3.0.6", + "vue-cropper": "0.4.9", + "axios": "0.18.1", + "echarts": "4.2.1", + "element-ui": "2.11.1", + "fuse.js": "3.4.4", + "js-cookie": "2.2.0", + "jsencrypt": "3.0.0-rc.1", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "path-to-regexp": "2.4.0", + "screenfull": "4.2.0", + "vue": "2.6.10", + "vue-count-to": "1.0.13", + "vue-router": "3.0.2", + "vue-splitpane": "1.0.4", + "vuex": "3.1.0" + }, + "devDependencies": { + "@babel/core": "7.0.0", + "@babel/register": "7.0.0", + "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-eslint": "^3.9.1", + "@vue/cli-plugin-unit-jest": "3.5.3", + "@vue/cli-service": "3.5.3", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "^9.5.1", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "chalk": "2.4.2", + "chokidar": "2.1.5", + "connect": "3.6.6", + "eslint": "5.15.3", + "eslint-plugin-vue": "5.2.2", + "html-webpack-plugin": "3.2.0", + "http-proxy-middleware": "^0.19.1", + "husky": "1.3.1", + "lint-staged": "8.1.5", + "mockjs": "1.0.1-beta3", + "node-sass": "^4.9.0", + "plop": "2.3.0", + "runjs": "^4.3.2", + "sass-loader": "^7.1.0", + "script-ext-html-webpack-plugin": "2.1.3", + "script-loader": "0.7.2", + "serve-static": "^1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.0", + "vue-template-compiler": "2.6.10" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} diff --git a/ruoyi-ui/public/favicon.ico b/ruoyi-ui/public/favicon.ico new file mode 100644 index 0000000..e263760 --- /dev/null +++ b/ruoyi-ui/public/favicon.ico Binary files differ diff --git a/ruoyi-ui/public/index.html b/ruoyi-ui/public/index.html new file mode 100644 index 0000000..6d64bf9 --- /dev/null +++ b/ruoyi-ui/public/index.html @@ -0,0 +1,207 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="renderer" content="webkit"> + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> + <link rel="icon" href="<%= BASE_URL %>favicon.ico"> + <title><%= webpackConfig.name %></title> + <style> + html, + body, + #app { + height: 100%; + margin: 0px; + padding: 0px; + } + .chromeframe { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; + } + + #loader-wrapper { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 999999; + } + + #loader { + display: block; + position: relative; + left: 50%; + top: 50%; + width: 150px; + height: 150px; + margin: -75px 0 0 -75px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #FFF; + -webkit-animation: spin 2s linear infinite; + -ms-animation: spin 2s linear infinite; + -moz-animation: spin 2s linear infinite; + -o-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; + z-index: 1001; + } + + #loader:before { + content: ""; + position: absolute; + top: 5px; + left: 5px; + right: 5px; + bottom: 5px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #FFF; + -webkit-animation: spin 3s linear infinite; + -moz-animation: spin 3s linear infinite; + -o-animation: spin 3s linear infinite; + -ms-animation: spin 3s linear infinite; + animation: spin 3s linear infinite; + } + + #loader:after { + content: ""; + position: absolute; + top: 15px; + left: 15px; + right: 15px; + bottom: 15px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #FFF; + -moz-animation: spin 1.5s linear infinite; + -o-animation: spin 1.5s linear infinite; + -ms-animation: spin 1.5s linear infinite; + -webkit-animation: spin 1.5s linear infinite; + animation: spin 1.5s linear infinite; + } + + + @-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } + } + + @keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + -ms-transform: rotate(360deg); + transform: rotate(360deg); + } + } + + + #loader-wrapper .loader-section { + position: fixed; + top: 0; + width: 51%; + height: 100%; + background: #7171C6; + z-index: 1000; + -webkit-transform: translateX(0); + -ms-transform: translateX(0); + transform: translateX(0); + } + + #loader-wrapper .loader-section.section-left { + left: 0; + } + + #loader-wrapper .loader-section.section-right { + right: 0; + } + + + .loaded #loader-wrapper .loader-section.section-left { + -webkit-transform: translateX(-100%); + -ms-transform: translateX(-100%); + transform: translateX(-100%); + -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); + transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); + } + + .loaded #loader-wrapper .loader-section.section-right { + -webkit-transform: translateX(100%); + -ms-transform: translateX(100%); + transform: translateX(100%); + -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); + transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); + } + + .loaded #loader { + opacity: 0; + -webkit-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; + } + + .loaded #loader-wrapper { + visibility: hidden; + -webkit-transform: translateY(-100%); + -ms-transform: translateY(-100%); + transform: translateY(-100%); + -webkit-transition: all 0.3s 1s ease-out; + transition: all 0.3s 1s ease-out; + } + + .no-js #loader-wrapper { + display: none; + } + + .no-js h1 { + color: #222222; + } + + #loader-wrapper .load_title { + font-family: 'Open Sans'; + color: #FFF; + font-size: 19px; + width: 100%; + text-align: center; + z-index: 9999999999999; + position: absolute; + top: 60%; + opacity: 1; + line-height: 30px; + } + + #loader-wrapper .load_title span { + font-weight: normal; + font-style: italic; + font-size: 13px; + color: #FFF; + opacity: 0.5; + } + </style> + </head> + <body> + <div id="app"> + <div id="loader-wrapper"> + <div id="loader"></div> + <div class="loader-section section-left"></div> + <div class="loader-section section-right"></div> + <div class="load_title">姝e湪鍔犺浇绯荤粺璧勬簮锛岃鑰愬績绛夊緟</div> + </div> + </div> + </body> +</html> diff --git a/ruoyi-ui/src/App.vue b/ruoyi-ui/src/App.vue new file mode 100644 index 0000000..e448b11 --- /dev/null +++ b/ruoyi-ui/src/App.vue @@ -0,0 +1,11 @@ +<template> + <div id="app"> + <router-view /> + </div> +</template> + +<script> +export default { + name: 'App' +} +</script> diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js new file mode 100644 index 0000000..1e84761 --- /dev/null +++ b/ruoyi-ui/src/api/login.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +// 鐧诲綍鏂规硶 +export function login(username, password, code, uuid) { + const data = { + username, + password, + code, + uuid + } + return request({ + url: '/login', + method: 'post', + params: data + }) +} + +// 鑾峰彇鐢ㄦ埛璇︾粏淇℃伅 +export function getInfo() { + return request({ + url: '/getInfo', + method: 'get' + }) +} + +// 閫�鍑烘柟娉� +export function logout() { + return request({ + url: '/logout', + method: 'post' + }) +} + +// 鑾峰彇楠岃瘉鐮� +export function getCodeImg() { + return request({ + url: '/captchaImage', + method: 'get' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/menu.js b/ruoyi-ui/src/api/menu.js new file mode 100644 index 0000000..faef101 --- /dev/null +++ b/ruoyi-ui/src/api/menu.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 鑾峰彇璺敱 +export const getRouters = () => { + return request({ + url: '/getRouters', + method: 'get' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/monitor/logininfor.js b/ruoyi-ui/src/api/monitor/logininfor.js new file mode 100644 index 0000000..383d61f --- /dev/null +++ b/ruoyi-ui/src/api/monitor/logininfor.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +// 鏌ヨ鐧诲綍鏃ュ織鍒楄〃 +export function list(query) { + return request({ + url: '/monitor/logininfor/list', + method: 'get', + params: query + }) +} + +// 鍒犻櫎鐧诲綍鏃ュ織 +export function delLogininfor(infoId) { + return request({ + url: '/monitor/logininfor/' + infoId, + method: 'delete' + }) +} + +// 娓呯┖鐧诲綍鏃ュ織 +export function cleanLogininfor() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }) +} + +// 瀵煎嚭鐧诲綍鏃ュ織 +export function exportLogininfor(query) { + return request({ + url: '/monitor/logininfor/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/monitor/online.js b/ruoyi-ui/src/api/monitor/online.js new file mode 100644 index 0000000..bd22137 --- /dev/null +++ b/ruoyi-ui/src/api/monitor/online.js @@ -0,0 +1,18 @@ +import request from '@/utils/request' + +// 鏌ヨ鍦ㄧ嚎鐢ㄦ埛鍒楄〃 +export function list(query) { + return request({ + url: '/monitor/online/list', + method: 'get', + params: query + }) +} + +// 寮洪��鐢ㄦ埛 +export function forceLogout(tokenId) { + return request({ + url: '/monitor/online/' + tokenId, + method: 'delete' + }) +} diff --git a/ruoyi-ui/src/api/monitor/operlog.js b/ruoyi-ui/src/api/monitor/operlog.js new file mode 100644 index 0000000..f09b8ed --- /dev/null +++ b/ruoyi-ui/src/api/monitor/operlog.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +// 鏌ヨ鎿嶄綔鏃ュ織鍒楄〃 +export function list(query) { + return request({ + url: '/monitor/operlog/list', + method: 'get', + params: query + }) +} + +// 鍒犻櫎鎿嶄綔鏃ュ織 +export function delOperlog(operId) { + return request({ + url: '/monitor/operlog/' + operId, + method: 'delete' + }) +} + +// 娓呯┖鎿嶄綔鏃ュ織 +export function cleanOperlog() { + return request({ + url: '/monitor/operlog/clean', + method: 'delete' + }) +} + +// 瀵煎嚭鎿嶄綔鏃ュ織 +export function exportOperlog(query) { + return request({ + url: '/monitor/operlog/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/monitor/server.js b/ruoyi-ui/src/api/monitor/server.js new file mode 100644 index 0000000..feed783 --- /dev/null +++ b/ruoyi-ui/src/api/monitor/server.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 鏌ヨ鏈嶅姟鍣ㄨ缁� +export function getServer() { + return request({ + url: '/monitor/server', + method: 'get' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/config.js b/ruoyi-ui/src/api/system/config.js new file mode 100644 index 0000000..f2e792c --- /dev/null +++ b/ruoyi-ui/src/api/system/config.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 鏌ヨ鍙傛暟鍒楄〃 +export function listConfig(query) { + return request({ + url: '/system/config/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鍙傛暟璇︾粏 +export function getConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'get' + }) +} + +// 鏍规嵁鍙傛暟閿悕鏌ヨ鍙傛暟鍊� +export function getConfigKey(configKey) { + return request({ + url: '/system/config/configKey/' + configKey, + method: 'get' + }) +} + +// 鏂板鍙傛暟閰嶇疆 +export function addConfig(data) { + return request({ + url: '/system/config', + method: 'post', + data: data + }) +} + +// 淇敼鍙傛暟閰嶇疆 +export function updateConfig(data) { + return request({ + url: '/system/config', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鍙傛暟閰嶇疆 +export function delConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'delete' + }) +} + +// 瀵煎嚭鍙傛暟 +export function exportConfig(query) { + return request({ + url: '/system/config/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/dept.js b/ruoyi-ui/src/api/system/dept.js new file mode 100644 index 0000000..c26894c --- /dev/null +++ b/ruoyi-ui/src/api/system/dept.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 鏌ヨ閮ㄩ棬鍒楄〃 +export function listDept(query) { + return request({ + url: '/system/dept/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ閮ㄩ棬璇︾粏 +export function getDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'get' + }) +} + +// 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� +export function treeselect() { + return request({ + url: '/system/dept/treeselect', + method: 'get' + }) +} + +// 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戠粨鏋� +export function roleDeptTreeselect(roleId) { + return request({ + url: '/system/dept/roleDeptTreeselect/' + roleId, + method: 'get' + }) +} + +// 鏂板閮ㄩ棬 +export function addDept(data) { + return request({ + url: '/system/dept', + method: 'post', + data: data + }) +} + +// 淇敼閮ㄩ棬 +export function updateDept(data) { + return request({ + url: '/system/dept', + method: 'put', + data: data + }) +} + +// 鍒犻櫎閮ㄩ棬 +export function delDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/dict/data.js b/ruoyi-ui/src/api/system/dict/data.js new file mode 100644 index 0000000..5597204 --- /dev/null +++ b/ruoyi-ui/src/api/system/dict/data.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 鏌ヨ瀛楀吀鏁版嵁鍒楄〃 +export function listData(query) { + return request({ + url: '/system/dict/data/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ瀛楀吀鏁版嵁璇︾粏 +export function getData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'get' + }) +} + +// 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁淇℃伅 +export function getDicts(dictType) { + return request({ + url: '/system/dict/data/dictType/' + dictType, + method: 'get' + }) +} + +// 鏂板瀛楀吀鏁版嵁 +export function addData(data) { + return request({ + url: '/system/dict/data', + method: 'post', + data: data + }) +} + +// 淇敼瀛楀吀鏁版嵁 +export function updateData(data) { + return request({ + url: '/system/dict/data', + method: 'put', + data: data + }) +} + +// 鍒犻櫎瀛楀吀鏁版嵁 +export function delData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'delete' + }) +} + +// 瀵煎嚭瀛楀吀鏁版嵁 +export function exportData(query) { + return request({ + url: '/system/dict/data/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/dict/type.js b/ruoyi-ui/src/api/system/dict/type.js new file mode 100644 index 0000000..b8d974e --- /dev/null +++ b/ruoyi-ui/src/api/system/dict/type.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 鏌ヨ瀛楀吀绫诲瀷鍒楄〃 +export function listType(query) { + return request({ + url: '/system/dict/type/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ瀛楀吀绫诲瀷璇︾粏 +export function getType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'get' + }) +} + +// 鏂板瀛楀吀绫诲瀷 +export function addType(data) { + return request({ + url: '/system/dict/type', + method: 'post', + data: data + }) +} + +// 淇敼瀛楀吀绫诲瀷 +export function updateType(data) { + return request({ + url: '/system/dict/type', + method: 'put', + data: data + }) +} + +// 鍒犻櫎瀛楀吀绫诲瀷 +export function delType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'delete' + }) +} + +// 瀵煎嚭瀛楀吀绫诲瀷 +export function exportType(query) { + return request({ + url: '/system/dict/type/export', + method: 'get', + params: query + }) +} + +// 鑾峰彇瀛楀吀閫夋嫨妗嗗垪琛� +export function optionselect() { + return request({ + url: '/system/dict/type/optionselect', + method: 'get' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/menu.js b/ruoyi-ui/src/api/system/menu.js new file mode 100644 index 0000000..f6415c6 --- /dev/null +++ b/ruoyi-ui/src/api/system/menu.js @@ -0,0 +1,60 @@ +import request from '@/utils/request' + +// 鏌ヨ鑿滃崟鍒楄〃 +export function listMenu(query) { + return request({ + url: '/system/menu/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鑿滃崟璇︾粏 +export function getMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'get' + }) +} + +// 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� +export function treeselect() { + return request({ + url: '/system/menu/treeselect', + method: 'get' + }) +} + +// 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� +export function roleMenuTreeselect(roleId) { + return request({ + url: '/system/menu/roleMenuTreeselect/' + roleId, + method: 'get' + }) +} + +// 鏂板鑿滃崟 +export function addMenu(data) { + return request({ + url: '/system/menu', + method: 'post', + data: data + }) +} + +// 淇敼鑿滃崟 +export function updateMenu(data) { + return request({ + url: '/system/menu', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鑿滃崟 +export function delMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/notice.js b/ruoyi-ui/src/api/system/notice.js new file mode 100644 index 0000000..c274ea5 --- /dev/null +++ b/ruoyi-ui/src/api/system/notice.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ鍏憡鍒楄〃 +export function listNotice(query) { + return request({ + url: '/system/notice/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鍏憡璇︾粏 +export function getNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'get' + }) +} + +// 鏂板鍏憡 +export function addNotice(data) { + return request({ + url: '/system/notice', + method: 'post', + data: data + }) +} + +// 淇敼鍏憡 +export function updateNotice(data) { + return request({ + url: '/system/notice', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鍏憡 +export function delNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/post.js b/ruoyi-ui/src/api/system/post.js new file mode 100644 index 0000000..434cd35 --- /dev/null +++ b/ruoyi-ui/src/api/system/post.js @@ -0,0 +1,53 @@ +import request from '@/utils/request' + +// 鏌ヨ宀椾綅鍒楄〃 +export function listPost(query) { + return request({ + url: '/system/post/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ宀椾綅璇︾粏 +export function getPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'get' + }) +} + +// 鏂板宀椾綅 +export function addPost(data) { + return request({ + url: '/system/post', + method: 'post', + data: data + }) +} + +// 淇敼宀椾綅 +export function updatePost(data) { + return request({ + url: '/system/post', + method: 'put', + data: data + }) +} + +// 鍒犻櫎宀椾綅 +export function delPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'delete' + }) +} + +// 瀵煎嚭宀椾綅 +export function exportPost(query) { + return request({ + url: '/system/post/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/role.js b/ruoyi-ui/src/api/system/role.js new file mode 100644 index 0000000..463501c --- /dev/null +++ b/ruoyi-ui/src/api/system/role.js @@ -0,0 +1,75 @@ +import request from '@/utils/request' + +// 鏌ヨ瑙掕壊鍒楄〃 +export function listRole(query) { + return request({ + url: '/system/role/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ瑙掕壊璇︾粏 +export function getRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'get' + }) +} + +// 鏂板瑙掕壊 +export function addRole(data) { + return request({ + url: '/system/role', + method: 'post', + data: data + }) +} + +// 淇敼瑙掕壊 +export function updateRole(data) { + return request({ + url: '/system/role', + method: 'put', + data: data + }) +} + +// 瑙掕壊鏁版嵁鏉冮檺 +export function dataScope(data) { + return request({ + url: '/system/role/dataScope', + method: 'put', + data: data + }) +} + +// 瑙掕壊鐘舵�佷慨鏀� +export function changeRoleStatus(roleId, status) { + const data = { + roleId, + status + } + return request({ + url: '/system/role/changeStatus', + method: 'put', + data: data + }) +} + +// 鍒犻櫎瑙掕壊 +export function delRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'delete' + }) +} + +// 瀵煎嚭瑙掕壊 +export function exportRole(query) { + return request({ + url: '/system/role/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi-ui/src/api/system/user.js b/ruoyi-ui/src/api/system/user.js new file mode 100644 index 0000000..3b9a776 --- /dev/null +++ b/ruoyi-ui/src/api/system/user.js @@ -0,0 +1,127 @@ +import request from '@/utils/request' +import { praseStrEmpty } from "@/utils/ruoyi"; + +// 鏌ヨ鐢ㄦ埛鍒楄〃 +export function listUser(query) { + return request({ + url: '/system/user/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鐢ㄦ埛璇︾粏 +export function getUser(userId) { + return request({ + url: '/system/user/' + praseStrEmpty(userId), + method: 'get' + }) +} + +// 鏂板鐢ㄦ埛 +export function addUser(data) { + return request({ + url: '/system/user', + method: 'post', + data: data + }) +} + +// 淇敼鐢ㄦ埛 +export function updateUser(data) { + return request({ + url: '/system/user', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鐢ㄦ埛 +export function delUser(userId) { + return request({ + url: '/system/user/' + userId, + method: 'delete' + }) +} + +// 瀵煎嚭鐢ㄦ埛 +export function exportUser(query) { + return request({ + url: '/system/user/export', + method: 'get', + params: query + }) +} + +// 鐢ㄦ埛瀵嗙爜閲嶇疆 +export function resetUserPwd(userId, password) { + const data = { + userId, + password + } + return request({ + url: '/system/user/resetPwd', + method: 'put', + data: data + }) +} + +// 鐢ㄦ埛鐘舵�佷慨鏀� +export function changeUserStatus(userId, status) { + const data = { + userId, + status + } + return request({ + url: '/system/user/changeStatus', + method: 'put', + data: data + }) +} + +// 鏌ヨ鐢ㄦ埛涓汉淇℃伅 +export function getUserProfile() { + return request({ + url: '/system/user/profile', + method: 'get' + }) +} + +// 淇敼鐢ㄦ埛涓汉淇℃伅 +export function updateUserProfile(data) { + return request({ + url: '/system/user/profile', + method: 'put', + data: data + }) +} + +// 鐢ㄦ埛瀵嗙爜閲嶇疆 +export function updateUserPwd(oldPassword, newPassword) { + const data = { + oldPassword, + newPassword + } + return request({ + url: '/system/user/profile/updatePwd', + method: 'put', + params: data + }) +} + +// 鐢ㄦ埛澶村儚涓婁紶 +export function uploadAvatar(data) { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + data: data + }) +} + +// 涓嬭浇鐢ㄦ埛瀵煎叆妯℃澘 +export function importTemplate() { + return request({ + url: '/system/user/importTemplate', + method: 'get' + }) +} diff --git a/ruoyi-ui/src/api/tool/gen.js b/ruoyi-ui/src/api/tool/gen.js new file mode 100644 index 0000000..09a0b6f --- /dev/null +++ b/ruoyi-ui/src/api/tool/gen.js @@ -0,0 +1,59 @@ +import request from '@/utils/request' + +// 鏌ヨ鐢熸垚琛ㄦ暟鎹� +export function listTable(query) { + return request({ + url: '/tool/gen/list', + method: 'get', + params: query + }) +} +// 鏌ヨdb鏁版嵁搴撳垪琛� +export function listDbTable(query) { + return request({ + url: '/tool/gen/db/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ琛ㄨ缁嗕俊鎭� +export function getGenTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'get' + }) +} + +// 淇敼浠g爜鐢熸垚淇℃伅 +export function updateGenTable(data) { + return request({ + url: '/tool/gen', + method: 'put', + data: data + }) +} + +// 瀵煎叆琛� +export function importTable(data) { + return request({ + url: '/tool/gen/importTable', + method: 'post', + params: data + }) +} +// 棰勮鐢熸垚浠g爜 +export function previewTable(tableId) { + return request({ + url: '/tool/gen/preview/' + tableId, + method: 'get' + }) +} +// 鍒犻櫎琛ㄦ暟鎹� +export function delTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'delete' + }) +} + diff --git a/ruoyi-ui/src/assets/401_images/401.gif b/ruoyi-ui/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 --- /dev/null +++ b/ruoyi-ui/src/assets/401_images/401.gif Binary files differ diff --git a/ruoyi-ui/src/assets/404_images/404.png b/ruoyi-ui/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 --- /dev/null +++ b/ruoyi-ui/src/assets/404_images/404.png Binary files differ diff --git a/ruoyi-ui/src/assets/404_images/404_cloud.png b/ruoyi-ui/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 --- /dev/null +++ b/ruoyi-ui/src/assets/404_images/404_cloud.png Binary files differ diff --git a/ruoyi-ui/src/assets/icons/index.js b/ruoyi-ui/src/assets/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/ruoyi-ui/src/assets/icons/svg/404.svg b/ruoyi-ui/src/assets/icons/svg/404.svg new file mode 100644 index 0000000..6df5019 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/404.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/bug.svg b/ruoyi-ui/src/assets/icons/svg/bug.svg new file mode 100644 index 0000000..05a150d --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/bug.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M127.88 73.143c0 1.412-.506 2.635-1.518 3.669-1.011 1.033-2.209 1.55-3.592 1.55h-17.887c0 9.296-1.783 17.178-5.35 23.645l16.609 17.044c1.011 1.034 1.517 2.257 1.517 3.67 0 1.412-.506 2.635-1.517 3.668-.958 1.033-2.155 1.55-3.593 1.55-1.438 0-2.635-.517-3.593-1.55l-15.811-16.063a15.49 15.49 0 0 1-1.196 1.06c-.532.434-1.65 1.208-3.353 2.322a50.104 50.104 0 0 1-5.192 2.974c-1.758.87-3.94 1.658-6.546 2.364-2.607.706-5.189 1.06-7.748 1.06V47.044H58.89v73.062c-2.716 0-5.417-.367-8.106-1.102-2.688-.734-5.003-1.631-6.945-2.692a66.769 66.769 0 0 1-5.268-3.179c-1.571-1.057-2.73-1.94-3.476-2.65L33.9 109.34l-14.611 16.877c-1.066 1.14-2.344 1.711-3.833 1.711-1.277 0-2.422-.434-3.434-1.304-1.012-.978-1.557-2.187-1.635-3.627-.079-1.44.333-2.705 1.236-3.794l16.129-18.51c-3.087-6.197-4.63-13.644-4.63-22.342H5.235c-1.383 0-2.58-.517-3.592-1.55S.125 74.545.125 73.132c0-1.412.506-2.635 1.518-3.668 1.012-1.034 2.21-1.55 3.592-1.55h17.887V43.939L9.308 29.833c-1.012-1.033-1.517-2.256-1.517-3.669 0-1.412.505-2.635 1.517-3.668 1.012-1.034 2.21-1.55 3.593-1.55s2.58.516 3.593 1.55l13.813 14.106h67.396l13.814-14.106c1.012-1.034 2.21-1.55 3.592-1.55 1.384 0 2.581.516 3.593 1.55 1.012 1.033 1.518 2.256 1.518 3.668 0 1.413-.506 2.636-1.518 3.67l-13.814 14.105v23.975h17.887c1.383 0 2.58.516 3.593 1.55 1.011 1.033 1.517 2.256 1.517 3.668l-.005.01zM89.552 26.175H38.448c0-7.23 2.489-13.386 7.466-18.469C50.892 2.623 56.92.082 64 .082c7.08 0 13.108 2.541 18.086 7.624 4.977 5.083 7.466 11.24 7.466 18.469z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/build.svg b/ruoyi-ui/src/assets/icons/svg/build.svg new file mode 100644 index 0000000..97c4688 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/build.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899741379" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M960 591.424V368.96c0-0.288 0.16-0.512 0.16-0.768S960 367.68 960 367.424V192a32 32 0 0 0-32-32H96a32 32 0 0 0-32 32v175.424c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768v222.464c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768V864a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32v-271.04c0-0.288 0.16-0.512 0.16-0.768S960 591.68 960 591.424z m-560-31.232v-160H608v160h-208z m208 64V832h-208v-207.808H608z m-480-224h208v160H128v-160z m544 0h224v160h-224v-160zM896 224v112.192H128V224h768zM128 624.192h208V832H128v-207.808zM672 832v-207.808h224V832h-224z" p-id="2055"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/chart.svg b/ruoyi-ui/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/clipboard.svg b/ruoyi-ui/src/assets/icons/svg/clipboard.svg new file mode 100644 index 0000000..90923ff --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/clipboard.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.857 118.857h64V73.143H89.143c-1.902 0-3.52-.668-4.855-2.002-1.335-1.335-2.002-2.954-2.002-4.855V36.57H54.857v82.286zM73.143 16v-4.571a2.2 2.2 0 0 0-.677-1.61 2.198 2.198 0 0 0-1.609-.676H20.571c-.621 0-1.158.225-1.609.676a2.198 2.198 0 0 0-.676 1.61V16a2.2 2.2 0 0 0 .676 1.61c.451.45.988.676 1.61.676h50.285c.622 0 1.158-.226 1.61-.677.45-.45.676-.987.676-1.609zm18.286 48h21.357L91.43 42.642V64zM128 73.143v48c0 1.902-.667 3.52-2.002 4.855-1.335 1.335-2.953 2.002-4.855 2.002H52.57c-1.901 0-3.52-.667-4.854-2.002-1.335-1.335-2.003-2.953-2.003-4.855v-11.429H6.857c-1.902 0-3.52-.667-4.855-2.002C.667 106.377 0 104.759 0 102.857v-96c0-1.902.667-3.52 2.002-4.855C3.337.667 4.955 0 6.857 0h77.714c1.902 0 3.52.667 4.855 2.002 1.335 1.335 2.003 2.953 2.003 4.855V30.29c1 .622 1.856 1.29 2.569 2.003l29.147 29.147c1.335 1.335 2.478 3.145 3.429 5.43.95 2.287 1.426 4.383 1.426 6.291v-.018z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/code.svg b/ruoyi-ui/src/assets/icons/svg/code.svg new file mode 100644 index 0000000..ed4d23c --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/code.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1546567861908" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2422" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M318.577778 819.2L17.066667 512l301.511111-307.2 45.511111 45.511111L96.711111 512l267.377778 261.688889zM705.422222 819.2l-45.511111-45.511111L927.288889 512l-267.377778-261.688889 45.511111-45.511111L1006.933333 512zM540.785778 221.866667l55.751111 11.150222L483.157333 802.133333l-55.751111-11.093333z" fill="#bfbfbf" p-id="2423"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/component.svg b/ruoyi-ui/src/assets/icons/svg/component.svg new file mode 100644 index 0000000..207ada3 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/component.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h54.857v54.857H0V0zm0 73.143h54.857V128H0V73.143zm73.143 0H128V128H73.143V73.143zm27.428-18.286C115.72 54.857 128 42.577 128 27.43 128 12.28 115.72 0 100.571 0 85.423 0 73.143 12.28 73.143 27.429c0 15.148 12.28 27.428 27.428 27.428z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/dashboard.svg b/ruoyi-ui/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ +<svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/date.svg b/ruoyi-ui/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..2a28112 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1567417179372" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1155" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M947.2 1024 76.8 1024C38.4 1024 0 992 0 953.6L0 172.8c0-38.4 38.4-70.4 76.8-70.4l38.4 0 0 102.4c0 38.4 38.4 70.4 76.8 70.4l76.8 0c44.8 0 76.8-32 76.8-70.4L345.6 102.4l313.6 0 0 102.4c0 38.4 38.4 70.4 76.8 70.4l76.8 0c44.8 0 76.8-32 76.8-70.4L889.6 102.4l38.4 0c44.8 0 76.8 32 76.8 70.4l0 787.2C1024 992 985.6 1024 947.2 1024zM352 339.2 115.2 339.2 115.2 512l236.8 0L352 339.2zM352 544 115.2 544l0 172.8 236.8 0L352 544zM352 748.8 115.2 748.8l0 172.8 236.8 0L352 748.8zM627.2 339.2 396.8 339.2 396.8 512l236.8 0L633.6 339.2zM627.2 544 396.8 544l0 172.8 236.8 0L633.6 544zM627.2 748.8 396.8 748.8l0 172.8 236.8 0L633.6 748.8zM908.8 339.2l-236.8 0L672 512l236.8 0L908.8 339.2zM908.8 544l-236.8 0 0 172.8 236.8 0L908.8 544zM908.8 748.8l-236.8 0 0 172.8 236.8 0L908.8 748.8zM787.2 236.8c-44.8 0-76.8-32-76.8-70.4L710.4 70.4c0-38.4 38.4-70.4 76.8-70.4s76.8 32 76.8 70.4l0 102.4C864 211.2 832 236.8 787.2 236.8zM236.8 236.8C192 236.8 160 211.2 160 172.8L160 70.4C160 32 192 0 236.8 0s76.8 32 76.8 70.4l0 102.4C313.6 211.2 281.6 236.8 236.8 236.8z" p-id="1156"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/dict.svg b/ruoyi-ui/src/assets/icons/svg/dict.svg new file mode 100644 index 0000000..4849377 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/dict.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035680909" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3601" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1002.0848 744.672l-33.568 10.368c0.96 7.264 2.144 14.304 2.144 21.76 0 7.328-1.184 14.432-2.368 21.568l33.792 10.56c7.936 2.24 14.496 7.616 18.336 14.752 3.84 7.328 4.672 15.808 1.952 23.552-5.376 16-23.168 24.672-39.936 19.68l-34.176-10.624c-7.136 12.8-15.776 24.672-26.208 35.2l20.8 27.488a28.96 28.96 0 0 1 5.824 22.816 29.696 29.696 0 0 1-12.704 19.616 32.544 32.544 0 0 1-44.416-6.752l-20.8-27.552c-13.696 6.56-28.192 11.2-43.008 13.888v33.632c0 16.736-14.112 30.432-31.648 30.432-17.6 0-31.872-13.696-31.872-30.432v-33.632a167.616 167.616 0 0 1-42.88-13.888l-20.928 27.552c-10.72 13.76-30.08 16.64-44.288 6.752a29.632 29.632 0 0 1-12.704-19.616 29.28 29.28 0 0 1 5.696-22.816l20.896-27.808a166.72 166.72 0 0 1-27.008-34.688l-33.376 10.432c-16.8 5.184-34.56-3.552-39.936-19.616a29.824 29.824 0 0 1 20.224-38.24l33.472-10.432c-0.8-7.264-2.016-14.304-2.016-21.824 0-7.36 1.184-14.496 2.304-21.632l-33.792-10.368c-16.672-5.376-25.632-22.496-20.224-38.432 5.376-16 23.136-24.672 39.936-19.68l34.016 10.752c7.328-12.672 15.84-24.8 26.336-35.328l-20.8-27.552a29.44 29.44 0 0 1 6.944-42.432 32.704 32.704 0 0 1 44.384 6.752l20.832 27.616c13.696-6.432 28.224-11.2 43.104-13.952v-33.568c0-16.736 14.048-30.432 31.648-30.432 17.536 0 31.808 13.568 31.808 30.432v33.504c15.072 2.688 29.344 7.808 42.848 14.016l20.992-27.616a32.48 32.48 0 0 1 44.224-6.752 29.568 29.568 0 0 1 7.136 42.432l-21.024 27.808c10.432 10.432 19.872 21.888 27.04 34.752l33.376-10.432c16.768-5.12 34.56 3.68 39.936 19.68 5.536 15.936-3.712 33.056-20.32 38.304z m-206.016-74.432c-61.344 0-111.136 47.808-111.136 106.56 0 58.88 49.792 106.496 111.136 106.496 61.312 0 111.104-47.616 111.104-106.496 0-58.752-49.792-106.56-111.104-106.56z" p-id="3602"></path><path d="M802.7888 57.152h-76.448c0-22.08-21.024-38.24-42.848-38.24H39.3968a39.68 39.68 0 0 0-39.36 40.032v795.616s41.888 120.192 110.752 120.192H673.2848a227.488 227.488 0 0 1-107.04-97.44H117.6368s-40.608-13.696-40.608-41.248l470.304-0.256 1.664 3.36a227.68 227.68 0 0 1-12.64-73.632c0-60.576 24-118.624 66.88-161.44a228.352 228.352 0 0 1 123.552-63.392l-3.2 0.288 2.144-424.672h38.208l0.576 421.024c27.04 0 52.672 4.8 76.64 13.344V101.536c0.032 0-6.304-44.384-38.368-44.384zM149.7648 514.336H72.3888v-77.408H149.7648v77.408z m0-144.32H72.3888v-77.44H149.7648v77.44z m0-137.248H72.3888v-77.44H149.7648v77.44z m501.856 281.568H206.0848v-77.408h445.536v77.408z m0-144.32H206.0848v-77.44h445.536v77.44z m0-137.248H206.0848v-77.44h445.536v77.44z" p-id="3603"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/documentation.svg b/ruoyi-ui/src/assets/icons/svg/documentation.svg new file mode 100644 index 0000000..7043122 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/documentation.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M71.984 44.815H115.9L71.984 9.642v35.173zM16.094.05h63.875l47.906 38.37v76.74c0 3.392-1.682 6.645-4.677 9.044-2.995 2.399-7.056 3.746-11.292 3.746H16.094c-4.236 0-8.297-1.347-11.292-3.746-2.995-2.399-4.677-5.652-4.677-9.044V12.84C.125 5.742 7.23.05 16.094.05zm71.86 102.32V89.58h-71.86v12.79h71.86zm23.952-25.58V64H16.094v12.79h95.812z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/download.svg b/ruoyi-ui/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..c896951 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569915748289" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3062" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M768.35456 416a256 256 0 1 0-512 0 192 192 0 1 0 0 384v64a256 256 0 0 1-58.88-505.216 320.128 320.128 0 0 1 629.76 0A256.128 256.128 0 0 1 768.35456 864v-64a192 192 0 0 0 0-384z m-512 384h64v64H256.35456v-64z m448 0h64v64h-64v-64z" fill="#333333" p-id="3063"></path><path d="M539.04256 845.248V512.192a32.448 32.448 0 0 0-32-32.192c-17.664 0-32 14.912-32 32.192v333.056l-36.096-36.096a32.192 32.192 0 0 0-45.056 0.192 31.616 31.616 0 0 0-0.192 45.056l90.88 90.944a31.36 31.36 0 0 0 22.528 9.088 30.08 30.08 0 0 0 22.4-9.088l90.88-90.88a32.192 32.192 0 0 0-0.192-45.12 31.616 31.616 0 0 0-45.056-0.192l-36.096 36.096z" fill="#333333" p-id="3064"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/drag.svg b/ruoyi-ui/src/assets/icons/svg/drag.svg new file mode 100644 index 0000000..4185d3c --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/drag.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M73.137 29.08h-9.209 29.7L63.886.093 34.373 29.08h20.49v27.035H27.238v17.948h27.625v27.133h18.274V74.063h27.41V56.115h-27.41V29.08zm-9.245 98.827l27.518-26.711H36.59l27.302 26.71zM.042 64.982l27.196 27.029V38.167L.042 64.982zm100.505-26.815V92.01l27.41-27.029-27.41-26.815z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/druid.svg b/ruoyi-ui/src/assets/icons/svg/druid.svg new file mode 100644 index 0000000..a2b4b4e --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/druid.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036347051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5853" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M832 128H192a64.19 64.19 0 0 0-64 64v640a64.19 64.19 0 0 0 64 64h640a64.19 64.19 0 0 0 64-64V192a64.19 64.19 0 0 0-64-64z m0 703.89l-0.11 0.11H192.11l-0.11-0.11V768h640zM832 544H720L605.6 696.54 442.18 435.07 333.25 544H192v-64h114.75l147.07-147.07L610.4 583.46 688 480h144z m0-288H192v-63.89l0.11-0.11h639.78l0.11 0.11z" p-id="5854"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/edit.svg b/ruoyi-ui/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M106.133 67.2a4.797 4.797 0 0 0-4.8 4.8c0 .187.014.36.027.533h-.027V118.4H9.6V26.667h50.133c2.654 0 4.8-2.147 4.8-4.8 0-2.654-2.146-4.8-4.8-4.8H9.6a9.594 9.594 0 0 0-9.6 9.6V118.4c0 5.307 4.293 9.6 9.6 9.6h91.733c5.307 0 9.6-4.293 9.6-9.6V72.533h-.026c.013-.173.026-.346.026-.533 0-2.653-2.146-4.8-4.8-4.8z"/><path d="M125.16 13.373L114.587 2.8c-3.747-3.747-9.854-3.72-13.6.027l-52.96 52.96a4.264 4.264 0 0 0-.907 1.36L33.813 88.533c-.746 1.76-.226 3.534.907 4.68 1.133 1.147 2.92 1.667 4.693.92l31.4-13.293c.507-.213.96-.52 1.36-.907l52.96-52.96c3.747-3.746 3.774-9.853.027-13.6zM66.107 72.4l-18.32 7.76 7.76-18.32L92.72 24.667l10.56 10.56L66.107 72.4zm52.226-52.227l-8.266 8.267-10.56-10.56 8.266-8.267.027-.026 10.56 10.56-.027.026z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/education.svg b/ruoyi-ui/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M88.883 119.565c-7.284 0-19.434 2.495-21.333 8.25v.127c-4.232.13-5.222 0-7.108 0-1.895-5.76-14.045-8.256-21.333-8.256H0V0h42.523c9.179 0 17.109 5.47 21.47 13.551C68.352 5.475 76.295 0 85.478 0H128v119.57l-39.113-.005h-.004zM60.442 24.763c0-9.651-8.978-16.507-17.777-16.507H7.108V111.43H39.11c7.054-.14 18.177.082 21.333 6.12v-4.628c-.134-5.722-.004-13.522 0-13.832V27.413l.004-2.655-.004.005zm60.442-16.517h-35.55c-8.802 0-17.78 6.856-17.78 16.493v74.259c.004.32.138 8.115 0 13.813v4.627c3.155-6.022 14.279-6.26 21.333-6.114h32V8.25l-.003-.005z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/email.svg b/ruoyi-ui/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..74d25e2 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ +<svg width="128" height="96" xmlns="http://www.w3.org/2000/svg"><path d="M64.125 56.975L120.188.912A12.476 12.476 0 0 0 115.5 0h-103c-1.588 0-3.113.3-4.513.838l56.138 56.137z"/><path d="M64.125 68.287l-62.3-62.3A12.42 12.42 0 0 0 0 12.5v71C0 90.4 5.6 96 12.5 96h103c6.9 0 12.5-5.6 12.5-12.5v-71a12.47 12.47 0 0 0-1.737-6.35L64.125 68.287z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/example.svg b/ruoyi-ui/src/assets/icons/svg/example.svg new file mode 100644 index 0000000..46f42b5 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/example.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/excel.svg b/ruoyi-ui/src/assets/icons/svg/excel.svg new file mode 100644 index 0000000..74d97b8 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/excel.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.208 16.576v8.384h38.72v5.376h-38.72v8.704h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.512h38.72v5.376h-38.72v11.136H128v-94.72H78.208zM0 114.368L72.128 128V0L0 13.632v100.736z"/><path d="M28.672 82.56h-11.2l14.784-23.488-14.08-22.592h11.52l8.192 14.976 8.448-14.976h11.136l-14.08 22.208L58.368 82.56H46.656l-8.768-15.68z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/exit-fullscreen.svg b/ruoyi-ui/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/eye-open.svg b/ruoyi-ui/src/assets/icons/svg/eye-open.svg new file mode 100644 index 0000000..88dcc98 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/eye-open.svg @@ -0,0 +1 @@ +<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/eye.svg b/ruoyi-ui/src/assets/icons/svg/eye.svg new file mode 100644 index 0000000..16ed2d8 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/eye.svg @@ -0,0 +1 @@ +<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/form.svg b/ruoyi-ui/src/assets/icons/svg/form.svg new file mode 100644 index 0000000..dcbaa18 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/form.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/fullscreen.svg b/ruoyi-ui/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/guide.svg b/ruoyi-ui/src/assets/icons/svg/guide.svg new file mode 100644 index 0000000..b271001 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/guide.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.482 70.131l36.204 16.18 69.932-65.485-61.38 70.594 46.435 18.735c1.119.425 2.397-.17 2.797-1.363v-.085L127.998.047 1.322 65.874c-1.12.597-1.519 1.959-1.04 3.151.32.511.72.937 1.2 1.107zm44.676 57.821L64.22 107.26l-18.062-7.834v28.527z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/icon.svg b/ruoyi-ui/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82be8ee --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 0 1 4.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 0 1 2.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/international.svg b/ruoyi-ui/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/job.svg b/ruoyi-ui/src/assets/icons/svg/job.svg new file mode 100644 index 0000000..2a93a25 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/job.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036191400" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5472" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M934.912 1016.832H192c-14.336 0-25.6-11.264-25.6-25.6v-189.44c0-14.336 11.264-25.6 25.6-25.6s25.6 11.264 25.6 25.6v163.84h691.712V64H217.6v148.48c0 14.336-11.264 25.6-25.6 25.6s-25.6-11.264-25.6-25.6v-174.08c0-14.336 11.264-25.6 25.6-25.6h742.912c14.336 0 25.6 11.264 25.6 25.6v952.832c0 14.336-11.264 25.6-25.6 25.6z" p-id="5473"></path><path d="M232.96 371.2h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM232.96 540.16h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM232.96 698.88h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM574.464 762.88c-134.144 0-243.2-109.056-243.2-243.2S440.32 276.48 574.464 276.48s243.2 109.056 243.2 243.2-109.056 243.2-243.2 243.2z m0-435.2c-105.984 0-192 86.016-192 192S468.48 711.68 574.464 711.68s192-86.016 192-192S680.448 327.68 574.464 327.68z" p-id="5474"></path><path d="M663.04 545.28h-87.04c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h87.04c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6z" p-id="5475"></path><path d="M576 545.28c-14.336 0-25.6-11.264-25.6-25.6v-87.04c0-14.336 11.264-25.6 25.6-25.6s25.6 11.264 25.6 25.6v87.04c0 14.336-11.264 25.6-25.6 25.6z" p-id="5476"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/language.svg b/ruoyi-ui/src/assets/icons/svg/language.svg new file mode 100644 index 0000000..0082b57 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/language.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.742 36.8c2.398 7.2 5.595 12.8 11.19 18.4 4.795-4.8 7.992-11.2 10.39-18.4h-21.58zm-52.748 40h20.78l-10.39-28-10.39 28z"/><path d="M111.916 0H16.009C7.218 0 .025 7.2.025 16v96c0 8.8 7.193 16 15.984 16h95.907c8.791 0 15.984-7.2 15.984-16V16c0-8.8-6.394-16-15.984-16zM72.754 103.2c-1.598 1.6-3.197 1.6-4.795 1.6-.8 0-2.398 0-3.197-.8-.8-.8-1.599 0-1.599-.8s-.799-1.6-1.598-3.2c-.8-1.6-.8-2.4-1.599-4l-3.196-8.8H28.797L25.6 96c-1.598 3.2-2.398 5.6-3.197 7.2-.8 1.6-2.398 1.6-4.795 1.6-1.599 0-3.197-.8-4.796-1.6-1.598-1.6-2.397-2.4-2.397-4 0-.8 0-1.6.799-3.2.8-1.6.8-2.4 1.598-4l17.583-44.8c.8-1.6.8-3.2 1.599-4.8.799-1.6 1.598-3.2 2.397-4 .8-.8 1.599-2.4 3.197-3.2 1.599-.8 3.197-.8 4.796-.8 1.598 0 3.196 0 4.795.8 1.598.8 2.398 1.6 3.197 3.2.799.8 1.598 2.4 2.397 4 .8 1.6 1.599 3.2 2.398 5.6l17.583 44c1.598 3.2 2.398 5.6 2.398 7.2-.8.8-1.599 2.4-2.398 4zM116.711 72c-8.791-3.2-15.185-7.2-20.78-12-5.594 5.6-12.787 9.6-21.579 12l-2.397-4c8.791-2.4 15.984-5.6 21.579-11.2C87.939 51.2 83.144 44 81.545 36h-7.992v-3.2h21.58c-1.6-2.4-3.198-5.6-4.796-8l2.397-.8c1.599 2.4 3.997 5.6 5.595 8.8h19.98v4h-7.992c-2.397 8-6.393 15.2-11.189 20 5.595 4.8 11.988 8.8 20.78 11.2l-3.197 4z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/link.svg b/ruoyi-ui/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/list.svg b/ruoyi-ui/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.585 12.087c0 6.616 3.974 11.98 8.877 11.98 4.902 0 8.877-5.364 8.877-11.98 0-6.616-3.975-11.98-8.877-11.98-4.903 0-8.877 5.364-8.877 11.98zM125.86.107H35.613c-1.268 0-2.114 1.426-2.114 2.852v18.255c0 1.712 1.057 2.853 2.114 2.853h90.247c1.268 0 2.114-1.426 2.114-2.853V2.96c0-1.711-1.057-2.852-2.114-2.852zM.106 62.86c0 6.615 3.974 11.979 8.876 11.979 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zM124.17 50.88H33.921c-1.268 0-2.114 1.425-2.114 2.851v18.256c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852V53.73c0-1.426-.846-2.852-2.114-2.852zM.106 115.913c0 6.616 3.974 11.98 8.876 11.98 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zm124.064-11.98H33.921c-1.268 0-2.114 1.426-2.114 2.853v18.255c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852v-18.255c0-1.427-.846-2.853-2.114-2.853z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/lock.svg b/ruoyi-ui/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..74fee54 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M119.88 49.674h-7.987V39.52C111.893 17.738 90.45.08 63.996.08 37.543.08 16.1 17.738 16.1 39.52v10.154H8.113c-4.408 0-7.987 2.94-7.987 6.577v65.13c0 3.637 3.57 6.577 7.987 6.577H119.88c4.407 0 7.987-2.94 7.987-6.577v-65.13c-.008-3.636-3.58-6.577-7.987-6.577zm-23.953 0H32.065V39.52c0-14.524 14.301-26.295 31.931-26.295 17.63 0 31.932 11.777 31.932 26.295v10.153z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/log.svg b/ruoyi-ui/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..d879d33 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035943711" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4805" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M208.736 566.336H64.384v59.328h144.352v-59.328z m0-336.096H165.44V74.592c0-7.968 4.896-14.848 10.464-14.848h502.016V0.448H175.936c-38.72 1.248-69.248 34.368-68.192 74.144v155.648H64.384V289.6h144.352V230.24z m0 168.096H64.384v59.328h144.352v-59.328z m714.656 76.576h-57.76v474.496c0 7.936-4.896 14.848-10.464 14.848H175.936c-5.568 0-10.464-6.912-10.464-14.848v-155.68h43.296v-59.296H64.384v59.296h43.328v155.68c-1.024 39.776 29.472 72.896 68.192 74.144h679.232c38.72-1.184 69.248-34.368 68.256-74.144V474.912z m14.944-290.336l-83.072-85.312a71.264 71.264 0 0 0-52.544-21.728 71.52 71.52 0 0 0-51.616 23.872L386.528 507.264a30.496 30.496 0 0 0-6.176 10.72L308.16 740.512a30.016 30.016 0 0 0 6.976 30.24c7.712 7.968 19.2 10.752 29.568 7.2l216.544-74.112a28.736 28.736 0 0 0 12.128-7.936L940.448 287.456a75.552 75.552 0 0 0-2.112-102.88z m-557.12 518.272l39.104-120.64 78.336 80.416-117.44 40.224z m170.048-70.016l-103.552-106.016 200.16-222.4 103.52 106.304-200.128 222.112zM897.952 247.072l-0.256 0.224-107.136 119.168-103.52-106.528 106.432-118.624a14.144 14.144 0 0 1 10.304-4.736 13.44 13.44 0 0 1 10.464 4.288l83.264 85.696c5.472 5.6 5.664 14.72 0.448 20.512z" p-id="4806"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/logininfor.svg b/ruoyi-ui/src/assets/icons/svg/logininfor.svg new file mode 100644 index 0000000..267f844 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/logininfor.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036016814" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5261" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 128h-85.333333a42.666667 42.666667 0 0 0 0 85.333333h42.666666v640H170.666667V213.333333h42.666666a42.666667 42.666667 0 0 0 0-85.333333H128a42.666667 42.666667 0 0 0-42.666667 42.666667v725.333333a42.666667 42.666667 0 0 0 42.666667 42.666667h768a42.666667 42.666667 0 0 0 42.666667-42.666667V170.666667a42.666667 42.666667 0 0 0-42.666667-42.666667z" p-id="5262"></path><path d="M341.333333 298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333333 0v128a42.666667 42.666667 0 0 0 42.666666 42.666667zM512 298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333334 0v128a42.666667 42.666667 0 0 0 42.666667 42.666667zM682.666667 298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667V128a42.666667 42.666667 0 0 0-85.333333 0v128a42.666667 42.666667 0 0 0 42.666667 42.666667zM341.333333 768a42.666667 42.666667 0 0 0 42.666667-42.666667 128 128 0 0 1 256 0 42.666667 42.666667 0 0 0 85.333333 0 213.333333 213.333333 0 0 0-107.52-184.32A128 128 0 0 0 640 469.333333a128 128 0 0 0-256 0 128 128 0 0 0 22.186667 71.68A213.333333 213.333333 0 0 0 298.666667 725.333333a42.666667 42.666667 0 0 0 42.666666 42.666667z m128-298.666667a42.666667 42.666667 0 1 1 42.666667 42.666667 42.666667 42.666667 0 0 1-42.666667-42.666667z" p-id="5263"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/message.svg b/ruoyi-ui/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/money.svg b/ruoyi-ui/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/monitor.svg b/ruoyi-ui/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..bc308cb --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/monitor.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543827393750" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4695" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: rbicon; src: url("chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2") format("woff2"); font-weight: normal; font-style: normal; } +</style></defs><path d="M64 64V640H896V64H64zM0 0h960v704H0V0z" p-id="4696"></path><path d="M192 896H768v64H192zM448 640H512v256h-64z" p-id="4697"></path><path d="M479.232 561.604267l309.9904-348.330667-47.803733-42.5472-259.566934 291.669333L303.957333 240.008533 163.208533 438.6048l52.224 37.009067 91.6224-129.28z" p-id="4698"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/nested.svg b/ruoyi-ui/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/online.svg b/ruoyi-ui/src/assets/icons/svg/online.svg new file mode 100644 index 0000000..330a202 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/online.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899557259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="535" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M356.246145 681.56286c-68.156286-41.949414-107.246583-103.84102-107.246583-169.805384 0-65.966411 39.090297-127.860063 107.246583-169.809477 12.046361-7.414877 15.800871-23.190165 8.385994-35.236526-7.413853-12.046361-23.191188-15.801894-35.236526-8.387018-39.640836 24.399713-72.539106 56.044434-95.137801 91.515297-23.86657 37.461193-36.481889 79.620385-36.481889 121.917724 0 42.297338 12.615319 84.454484 36.481889 121.914654 22.598694 35.469839 55.496965 67.11456 95.137801 91.51325 4.185322 2.576685 8.821923 3.804652 13.400195 3.804652 8.598842 0 16.998139-4.329609 21.836331-12.190647C372.047016 704.752002 368.291482 688.976714 356.246145 681.56286zM263.943926 754.580874c-92.603071-61.111846-145.713686-149.623739-145.713686-242.840794 0-93.195565 53.094242-181.682899 145.667637-242.774279 11.805884-7.79043 15.061021-23.677259 7.269567-35.483142-7.79043-11.805884-23.677259-15.062044-35.483142-7.269567C128.487861 296.954249 67.006602 401.024489 67.006602 511.74008c0 110.73708 61.496609 214.830857 168.721703 285.593504 4.343935 2.867304 9.240455 4.238534 14.08274 4.238534 8.317433 0 16.476253-4.046153 21.400403-11.507078C279.003923 778.258133 275.748786 762.372328 263.943926 754.580874zM788.660552 226.213092c-11.80486-7.791453-27.692712-4.536316-35.483142 7.269567-7.79043 11.805884-4.536316 27.692712 7.269567 35.483142 92.575442 61.092403 145.670707 149.579737 145.670707 242.774279 0 93.216032-53.111638 181.727924-145.715733 242.840794-11.805884 7.79043-15.059997 23.678282-7.269567 35.484166 4.925173 7.461949 13.081946 11.507078 21.400403 11.507078 4.841262 0 9.739828-1.37123 14.083763-4.238534 107.22714-70.761624 168.724773-174.857447 168.724773-285.593504C957.341323 401.025513 895.860063 296.955272 788.660552 226.213092zM790.090111 633.67213c23.865547-37.459147 36.480866-79.617315 36.480866-121.914654 0-42.298362-12.615319-84.45653-36.480866-121.917724-22.598694-35.470863-55.496965-67.115584-95.139847-91.515297-12.047384-7.413853-27.821649-3.659343-35.236526 8.387018-7.414877 12.045337-3.659343 27.821649 8.385994 35.236526 68.156286 41.949414 107.247606 103.842043 107.247606 169.809477 0 65.964364-39.090297 127.85597-107.247606 169.804361-12.045337 7.414877-15.800871 23.190165-8.385994 35.237549 4.838192 7.861038 13.236466 12.190647 21.835308 12.190647 4.579295 0 9.215896-1.227967 13.400195-3.804652C734.591099 700.786691 767.490394 669.142993 790.090111 633.67213zM567.129086 518.274914c24.12342-17.150612 39.887452-45.305859 39.887452-77.07133 0-52.128241-42.452881-94.538143-94.634334-94.538143-52.18043 0-94.633311 42.408879-94.633311 94.538143 0 31.695886 15.696494 59.797921 39.730886 76.958766-49.875944 21.128203-84.917018 70.234621-84.917018 127.301338 0 2.366907 0.061398 4.762467 0.182149 7.119141l1.249457 24.296359 276.373515 0 1.238201-24.308639c0.119727-2.358721 0.181125-4.750187 0.181125-7.106862C651.786185 588.497255 616.865861 539.465538 567.129086 518.274914zM512.381182 397.889079c23.937179 0 43.411719 19.430538 43.411719 43.314505 0 23.882943-19.47454 43.313481-43.411719 43.313481-23.936155 0-43.409672-19.430538-43.409672-43.313481C468.971509 417.320641 488.445026 397.889079 512.381182 397.889079zM426.08884 625.656573c9.119705-38.542828 44.254923-67.337641 86.085634-67.337641s76.966952 28.794813 86.085634 67.337641L426.08884 625.656573z" p-id="536"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/password.svg b/ruoyi-ui/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..e291d85 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/pdf.svg b/ruoyi-ui/src/assets/icons/svg/pdf.svg new file mode 100644 index 0000000..957aa0c --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/pdf.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path d="M869.073 277.307H657.111V65.344l211.962 211.963zm-238.232 26.27V65.344l-476.498-.054v416.957h714.73v-178.67H630.841zm-335.836 360.57c-5.07-3.064-10.944-5.133-17.61-6.201-6.67-1.064-13.603-1.6-20.81-1.6h-48.821v85.641h48.822c7.206 0 14.14-.532 20.81-1.6 6.665-1.065 12.54-3.133 17.609-6.202 5.064-3.063 9.134-7.406 12.208-13.007 3.065-5.602 4.6-12.937 4.6-22.011 0-9.07-1.535-16.408-4.6-22.01-3.074-5.603-7.144-9.94-12.208-13.01zM35.82 541.805v416.904h952.358V541.805H35.821zm331.421 191.179c-3.6 11.071-9.343 20.879-17.209 29.413-7.874 8.542-18.078 15.408-30.617 20.61-12.544 5.206-27.747 7.807-45.621 7.807h-66.036v102.45h-62.831V607.517h128.867c17.874 0 33.077 2.6 45.62 7.802 12.541 5.207 22.745 12.076 30.618 20.615 7.866 8.538 13.604 18.277 17.21 29.212 3.6 10.943 5.401 22.278 5.401 34.018 0 11.477-1.8 22.752-5.402 33.819zM644.9 806.417c-5.343 17.61-13.408 32.818-24.212 45.627-10.807 12.803-24.283 22.879-40.423 30.213-16.146 7.343-35.155 11.007-57.03 11.007h-123.26V607.518h123.26c18.41 0 35.552 2.941 51.428 8.808 15.873 5.869 29.618 14.671 41.22 26.412 11.608 11.744 20.674 26.411 27.217 44.02 6.535 17.61 9.803 38.288 9.803 62.035 0 20.81-2.67 40.02-8.003 57.624zm245.362-146.07h-138.07v66.03h119.66v48.829h-119.66v118.058h-62.83V607.518h200.9v52.829h-.001zm-318.2 25.611c-6.402-8.266-14.877-14.604-25.412-19.01-10.544-4.402-23.551-6.602-39.019-6.602h-44.825v180.088h56.029c9.07 0 17.872-1.463 26.415-4.401 8.535-2.932 16.14-7.802 22.812-14.609 6.665-6.8 12.007-15.667 16.007-26.61 4.003-10.94 6.003-24.275 6.003-40.021 0-14.408-1.4-27.416-4.202-39.019-2.8-11.607-7.406-21.542-13.808-29.816zm0 0"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/people.svg b/ruoyi-ui/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M104.185 95.254c8.161 7.574 13.145 17.441 13.145 28.28 0 1.508-.098 2.998-.285 4.466h-10.784c.238-1.465.403-2.948.403-4.465 0-8.983-4.36-17.115-11.419-23.216C86 104.66 75.355 107.162 64 107.162c-11.344 0-21.98-2.495-31.22-6.83-7.064 6.099-11.444 14.218-11.444 23.203 0 1.517.165 3 .403 4.465H10.955a35.444 35.444 0 0 1-.285-4.465c0-10.838 4.974-20.713 13.127-28.291C9.294 85.42.003 70.417.003 53.58.003 23.99 28.656.001 64 .001s63.997 23.988 63.997 53.58c0 16.842-9.299 31.85-23.812 41.673zM64 36.867c-29.454 0-53.33-10.077-53.33 15.342 0 25.418 23.876 46.023 53.33 46.023 29.454 0 53.33-20.605 53.33-46.023 0-25.419-23.876-15.342-53.33-15.342zm24.888 25.644c-3.927 0-7.111-2.665-7.111-5.953 0-3.288 3.184-5.954 7.11-5.954 3.928 0 7.111 2.666 7.111 5.954s-3.183 5.953-7.11 5.953zm-3.556 16.372c0 4.11-9.55 7.442-21.332 7.442-11.781 0-21.332-3.332-21.332-7.442 0-1.06.656-2.064 1.8-2.976 3.295 2.626 10.79 4.465 19.532 4.465 8.743 0 16.237-1.84 19.531-4.465 1.145.912 1.801 1.916 1.801 2.976zm-46.22-16.372c-3.927 0-7.11-2.665-7.11-5.953 0-3.288 3.183-5.954 7.11-5.954 3.927 0 7.111 2.666 7.111 5.954s-3.184 5.953-7.11 5.953z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/peoples.svg b/ruoyi-ui/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..aab852e --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/phone.svg b/ruoyi-ui/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..ab8e8c4 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1567417214476" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2266" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M761.503029 2.90619 242.121921 2.90619c-32.405037 0-58.932204 26.060539-58.932204 58.527998l0 902.302287c0 32.156374 26.217105 58.216913 58.932204 58.216913l519.381108 0c32.344662 0 58.591443-26.060539 58.591443-58.216913L820.094472 61.123103C820.094472 28.966729 793.847691 2.90619 761.503029 2.90619M452.878996 61.123103l98.147344 0c6.780427 0 12.31549 5.536087 12.31549 12.253068 0 6.748704-5.535063 12.253068-12.31549 12.253068l-98.147344 0c-6.779404 0-12.345166-5.504364-12.345166-12.253068C440.532807 66.659189 446.099592 61.123103 452.878996 61.123103M501.641583 980.593398c-29.636994 0-53.987588-23.946388-53.987588-53.677527 0-29.356608 24.039509-53.614082 53.987588-53.614082 29.91738 0 53.987588 23.883967 53.987588 53.614082C555.629171 956.647009 531.559986 980.593398 501.641583 980.593398M766.35657 803.142893c0 16.23373-13.186324 29.107945-29.233811 29.107945l-470.618521 0c-16.35755 0-29.325909-13.186324-29.325909-29.107945L237.178329 163.500794c0-16.232706 13.279445-29.138644 29.325909-29.138644l470.246037 0c16.420995 0 29.357632 13.1853 29.357632 29.138644l0 639.642099L766.35657 803.142893zM766.35657 803.142893" p-id="2267"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/post.svg b/ruoyi-ui/src/assets/icons/svg/post.svg new file mode 100644 index 0000000..2922c61 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/post.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035724641" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3998" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M136.4 434.3h77.7c21.5 0 38.9-17.4 38.9-38.9s-17.4-38.9-38.9-38.9h-77.7c-21.5 0-38.9 17.4-38.9 38.9s17.4 38.9 38.9 38.9zM252.9 628.6c0-21.5-17.4-38.9-38.9-38.9h-77.7c-21.5 0-38.9 17.4-38.9 38.9s17.4 38.9 38.9 38.9H214c21.5-0.1 38.9-17.5 38.9-38.9z" p-id="3999"></path><path d="M874.7 97.5H227c-28.6 0-51.8 23.2-51.8 51.8v194.3h38.9c28.6 0 51.8 23.2 51.8 51.8 0 28.6-23.2 51.8-51.8 51.8h-38.9v129.5h38.9c28.6 0 51.8 23.2 51.8 51.8 0 28.6-23.2 51.8-51.8 51.8h-38.9v194.3c0 28.6 23.2 51.8 51.8 51.8h647.7c28.6 0 51.8-23.2 51.8-51.8V149.3c0-28.6-23.2-51.8-51.8-51.8z m-311.3 723c-15.6 0-146.7-71.6-146.7-91 0-19.4 102-368.6 102-368.6l-83.6-104s-12.3-23.1 24.6-23.1h208.9c36.9 0 18.4 23.1 18.4 23.1l-79 104s102 351.3 102 368.6c0.1 17.3-131 91-146.6 91z m169.2-253.6l-27.9 40.2-74.5-240 103.4 171.7c4.6 7.9 4.2 20.6-1 28.1z" p-id="4000"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/qq.svg b/ruoyi-ui/src/assets/icons/svg/qq.svg new file mode 100644 index 0000000..ee13d4e --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/qq.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M18.448 57.545l-.244-.744-.198-.968-.132-.53v-2.181l.236-.859.24-.908.317-.953.428-1.06.561-1.103.794-1.104v-.773l.077-.724.123-.984.34-1.106.313-1.194.25-.548.289-.511.371-.569.405-.423v-2.73l.234-1.407.236-1.633.42-1.955.577-2.035.43-1.118.426-1.217.468-1.135.559-1.216.57-1.332.655-1.247.737-1.331.929-1.33.43-.762.457-.624.995-1.406 1.025-1.403 1.163-1.444 1.246-1.405 1.352-1.384 1.41-1.423 1.708-1.536 1.083-.934 1.322-1.008 1.34-.89 1.448-.855 1.392-.76 1.57-.63 1.667-.775 1.657-.532 1.653-.552 1.787-.548 1.785-.417 1.876-.347L59.128.68l1.879-.245 1.876-.252 2.002-.106h5.912l1.97.243 1.981.231 2.019.207 1.874.441 1.979.413 1.857.475 2.035.53 1.862.646 1.782.738 1.904.78 1.736.853 1.689.95 1.655 1.044 1.425.971.662.548.693.401 1.323 1.1 1.115 1.064 1.112 1.1 1.083 1.214.894 1.178 1.064 1.217.74 1.306.752 1.162.798 1.352.661 1.175 1.113 2.489.546 1.286.428 1.192.428 1.294.384 1.217.267 1.047.347 1.231.607 2.198.388 1.924.253 1.861.217 1.497.342 2.28.077.362.274.41.737 1.18.473.8.42.832.534.892.472 1.07.307 1.093.334 1.2.252 1.232.115.605.106.746v.648l-.106.643v.8l-.192.774-.35 1.5-.403.76-.299.852v.213l.142.264.4.623 1.746 2.53 1.377 1.9.66 1.267.889 1.389.774 1.52.893 1.627.894 1.828 1.006 2.069.567 1.268.518 1.239.447 1.307.44 1.175.336 1.235.342 1.16.432 2.261.343 2.31.235 2.05v2.891l-.158 1.025-.226 1.768-.308 1.59-.48 1.44-.18.588-.336.707-.28.493-.375.607-.33.383-.42.494-.375.4-.401.34-.48.207-.432.207-.355.114h-.543l-.346-.114-.66-.32-.302-.212-.317-.223-.347-.304-.35-.342-.579-.63-.684-.89-.539-.917-.538-.734-.526-.855-.741-1.517-.833-1.579-.098-.055h-.138l-.338.247-.196.415-.326.516-.567 1.533-.856 2.182-1.096 2.626-.824 1.308-.864 1.366-1.027 1.536-1.09 1.503-.557.68-.676.743-1.555 1.497.136.135.21.214.777.446 3.235 1.524 1.41.779 1.347.756 1.332.953 1.187.982.574.443.432.511.445.593.367.643.198.533.242.64.105.554.115.647-.115.433v.44l-.105.454-.242.415-.092.325-.22.394-.587.784-.543.627-.42.47-.35.348-.893.638-1.01.556-1.077.532-1.155.511-1.287.495-.693.207-.608.167-1.496.342-1.545.325-1.552.323-1.689.27-1.74.072-1.785.21h-5.539l-1.998-.114-1.86-.168-2.005-.27-1.99-.209-2.095-.286-2.03-.495-1.981-.374-1.968-.552-2.019-.707-1.98-.585-1.044-.342-.927-.323-.586-.223-.582-.12h-1.647l-1.904-.131-.962-.096-1.24-.135-.795.705-1.085.665-1.471.701-1.628.875-.99.475-1.033.376-2.281.914-1.24.305-1.3.343-1.803.344-1.13.086-1.193.1-1.246.135-1.45.053h-5.926l-3.346-.053-3.25-.321-1.644-.23-1.589-.23-1.546-.227-1.547-.305-1.442-.456-1.434-.325-1.294-.51-1.223-.474-1.142-.533-.99-.583-.984-.71-.336-.343-.44-.415-.334-.362-.3-.417-.278-.415-.215-.42-.311-.89-.109-.46-.138-.51v-.473l.138-.533v-.53l.109-.53v-1.069l.052-.564.259-.647.215-.646.39-.779.286-.3.236-.348.615-.738.49-.38.464-.266.428-.338.676-.21.543-.324.676-.341.77-.227.775-.231.897-.192.85-.11 1.008-.13 1.093-.081.284-.092h.063l.137-.115v-.13l-.2-.266-.58-.27-1.45-1.231-.975-.761-1.127-.967-1.136-1.082-1.181-1.382-1.36-1.558-.508-.843-.672-.87-.58-1.007-.522-1.1-.704-1.047-.459-1.194-.547-1.192-.546-1.33-.397-1.273-.378-1.575-.112-.057h-.115l-.059-.113h-.14l-.23.113-.114.057-.158.264-.057.321-.119.286-.206.477-.664 1.157-.345.701-.546.612-.58.736-.641.816-.677.724-.795.701-.734.658-.814.524-.89.546-.855.325-1.008.247-.99.095h-.233l-.228-.095-.18-.384-.29-.188-.38-.912-.237-.493-.255-.707-.21-.734-.113-.724-.313-1.648-.12-.972v-3.185l.12-2.379.196-1.214.23-1.252.21-1.347.374-1.254.42-1.443.431-1.407.578-1.448.545-1.38.754-1.4.699-1.52.855-1.425 1.006-1.538 1.023-1.382 1.069-1.538.891-1.071 1.142-1.227 1.202-1.237.56-.59.678-.662.985-.836 1.012-.853 1.647-1.446 1.242-.889z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/search.svg b/ruoyi-ui/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M124.884 109.812L94.256 79.166c-.357-.357-.757-.629-1.129-.914a50.366 50.366 0 0 0 8.186-27.59C101.327 22.689 78.656 0 50.67 0 22.685 0 0 22.688 0 50.663c0 27.989 22.685 50.663 50.656 50.663 10.186 0 19.643-3.03 27.6-8.201.286.385.557.771.9 1.114l30.628 30.632a10.633 10.633 0 0 0 7.543 3.129c2.728 0 5.457-1.043 7.543-3.115 4.171-4.157 4.171-10.915.014-15.073M50.671 85.338C31.557 85.338 16 69.78 16 50.663c0-19.102 15.557-34.661 34.67-34.661 19.115 0 34.657 15.559 34.657 34.675 0 19.102-15.557 34.661-34.656 34.661"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/server.svg b/ruoyi-ui/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..ca37b00 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547360688278" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M890 120H134a70 70 0 0 0-70 70v500a70 70 0 0 0 70 70h756a70 70 0 0 0 70-70V190a70 70 0 0 0-70-70z m-10 520a40 40 0 0 1-40 40H712V448a40 40 0 0 0-80 0v232h-80V368a40 40 0 0 0-80 0v312h-80V512a40 40 0 0 0-80 0v168H184a40 40 0 0 1-40-40V240a40 40 0 0 1 40-40h656a40 40 0 0 1 40 40zM696 824H328a40 40 0 0 0 0 80h368a40 40 0 0 0 0-80z" fill="#bfbfbf" p-id="6718"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/shopping.svg b/ruoyi-ui/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/size.svg b/ruoyi-ui/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/skill.svg b/ruoyi-ui/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M31.652 93.206h33.401c1.44 2.418 3.077 4.663 4.93 6.692h-38.33v-6.692zm0-10.586h28.914a44.8 44.8 0 0 1-1.264-6.688h-27.65v6.688zm0-17.27H59.39c.288-2.286.714-4.532 1.34-6.687H31.65v6.687h.003zm53.913 44.84v5.85c0 2.798-2.095 5.075-4.667 5.075h-70.07c-2.576 0-4.663-2.277-4.663-5.075V31.26l23.22-20.96v22.25H17.16v6.688h18.39V6.688h45.348c2.576 0 4.667 2.277 4.667 5.066v20.009c1.987-.675 4.053-1.128 6.17-1.445v-18.56C91.738 5.28 86.874 0 80.902 0H31.15L0 28.118v87.917c0 6.48 4.859 11.759 10.832 11.759h70.07c5.974 0 10.837-5.27 10.837-11.759v-4.41c-2.117-.312-4.183-.765-6.17-1.435h-.004zM23.279 58.667h-7.96v6.688h7.96v-6.688zm-7.956 41.23h7.96v-6.691h-7.96v6.692zm7.956-23.96h-7.96v6.687h7.96v-6.688zm89.718-15.042l-4.896-4.07-12.447 17.613-11.19-9.305-3.762 5.311 16.091 13.38 16.204-22.929zM128 70.978c0-18.632-13.97-33.782-31.147-33.782-17.168 0-31.135 15.155-31.135 33.782 0 18.628 13.97 33.783 31.135 33.783 17.172 0 31.143-15.15 31.143-33.783H128zm-6.17 0c0 14.933-11.203 27.1-24.981 27.1-13.77 0-24.987-12.158-24.987-27.1 0-14.941 11.195-27.099 24.987-27.099 13.778 0 24.982 12.158 24.982 27.1z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/star.svg b/ruoyi-ui/src/assets/icons/svg/star.svg new file mode 100644 index 0000000..6cf86e6 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/star.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M70.66 4.328l14.01 29.693c1.088 2.29 3.177 3.882 5.603 4.25l31.347 4.76c6.087.926 8.528 8.756 4.117 13.247L103.05 79.395c-1.75 1.78-2.544 4.352-2.132 6.867l5.352 32.641c1.043 6.337-5.33 11.182-10.778 8.19l-28.039-15.409a7.13 7.13 0 0 0-6.91 0l-28.039 15.41c-5.448 2.99-11.821-1.854-10.777-8.19l5.352-32.642c.415-2.515-.387-5.088-2.136-6.867L2.264 56.278C-2.146 51.787.286 43.957 6.38 43.031l31.343-4.76c2.419-.368 4.51-1.96 5.595-4.25L57.334 4.328c2.728-5.77 10.605-5.77 13.325 0z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/swagger.svg b/ruoyi-ui/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..05d4e7b --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036776944" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6463" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M64 223.995345h168.001164v47.997673c0 26.428509 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.569164 41.984-47.997673v-47.997673h504.003491a32.004655 32.004655 0 0 0 0-64.009309H455.996509V111.988364c0-26.428509-18.878836-47.997673-41.984-47.997673H273.985164c-23.095855 0-41.984 21.569164-41.984 47.997673v47.997672H64a32.004655 32.004655 0 0 0 0 64.009309zM288.004655 128h111.997672V256H288.004655V128zM960 479.995345H791.998836v-47.997672c0-26.372655-18.878836-47.997673-41.984-47.997673H609.978182c-23.095855 0-41.984 21.634327-41.984 47.997673v47.997672H64a32.004655 32.004655 0 0 0 0 64.00931h504.003491v47.997672c0 26.363345 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.634327 41.984-47.997673v-47.997672h168.001164a32.004655 32.004655 0 1 0-0.009309-64.00931zM735.995345 576H623.997673v-128h111.997672v128zM960 800.293236v-0.288581H455.996509v-47.997673c0-26.363345-18.878836-47.997673-41.984-47.997673H274.050327c-23.105164 0-41.984 21.634327-41.984 47.997673v47.997673H64v0.288581a32.004655 32.004655 0 0 0 0 64.009309c0.986764 0 1.917673-0.195491 2.885818-0.288581h165.115346v47.997672c0 26.363345 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.634327 41.984-47.997673v-47.997672h501.108364c0.968145 0.093091 1.899055 0.288582 2.895127 0.288581a32.004655 32.004655 0 1 0-0.009309-64.009309zM400.002327 896H288.004655V768h111.997672v128z" fill="" p-id="6464"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/system.svg b/ruoyi-ui/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..dba28cf --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/system.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543827724451" class="icon" style="" viewBox="0 0 1084 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10233" xmlns:xlink="http://www.w3.org/1999/xlink" width="211.71875" height="200"><defs><style type="text/css">@font-face { font-family: rbicon; src: url("chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2") format("woff2"); font-weight: normal; font-style: normal; } +</style></defs><path d="M1080.09609 434.500756c-4.216302-23.731757-26.9241-47.945376-50.595623-53.185637l-17.648235-4.095836a175.940257 175.940257 0 0 1-101.612877-80.832531 177.807476 177.807476 0 0 1-18.732427-129.801867l5.541425-16.684509c7.10748-23.129428-2.108151-54.992624-20.599646-70.833873 0 0-16.624276-14.094495-63.244529-41.199293-46.800951-26.984332-66.858502-34.513443-66.858502-34.513443-22.76803-8.372371-54.631227-0.361397-71.255503 17.407304l-12.287509 13.251234a173.470708 173.470708 0 0 1-120.465769 48.065842A174.13327 174.13327 0 0 1 421.329029 33.590675L409.583617 20.761071C393.140039 2.99237 361.096144-4.898138 338.267881 3.353767c0 0-20.358715 7.529111-67.099434 34.513443-46.800951 27.34573-63.244529 41.440225-63.244529 41.440225-18.431263 15.66055-27.646894 47.222582-20.539413 70.592941l5.059562 16.865207a178.048407 178.048407 0 0 1-18.672194 129.621169 174.916297 174.916297 0 0 1-102.275439 81.073463l-17.045906 3.854904c-23.310126 5.42096-46.258856 29.333415-50.595623 53.185637 0 0-3.854905 21.382674-3.854905 75.712737 0 54.330062 3.854905 75.712736 3.854905 75.712736 4.216302 23.972688 26.9241 47.945376 50.595623 53.185637l16.624276 3.854905a174.253736 174.253736 0 0 1 102.395904 81.314394c23.310126 40.837896 28.911785 87.337683 18.732427 129.801867l-4.81863 16.443578c-7.10748 23.129428 2.108151 54.992624 20.599646 70.833872 0 0 16.624276 14.094495 63.244529 41.199293 46.800951 27.104798 66.918735 34.513443 66.918735 34.513443 22.707798 8.372371 54.631227 0.361397 71.255503-17.407303l11.624947-12.588673a175.096996 175.096996 0 0 1 242.256662 0.120465l11.624947 12.648906c16.383345 17.708468 48.427239 25.598976 71.255503 17.347071 0 0 20.358715-7.529111 67.159666-34.513443 46.740719-27.104798 63.124063-41.199293 63.124064-41.199293 18.491496-15.600317 27.707127-47.463513 20.599646-70.833873l-5.059562-17.106139a176.723284 176.723284 0 0 1 18.672194-129.139305 176.060722 176.060722 0 0 1 102.395904-81.314394l16.68451-3.854905c23.310126-5.42096 46.258856-29.333415 50.595623-53.185637 0 0 3.854905-21.382674 3.854904-75.712737-0.240932-54.330062-4.095836-75.833202-4.095836-75.833202z m-537.819428 293.334149c-119.261112 0-216.175824-97.336342-216.175824-217.621412a216.657687 216.657687 0 0 1 216.236057-217.320249c119.200879 0 216.115591 97.276109 216.11559 217.56118-0.240932 120.044139-96.974945 217.320248-216.175823 217.320249z" p-id="10234" fill="#bfbfbf"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/tab.svg b/ruoyi-ui/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.921.052H49.08c-1.865 0-3.198 1.599-3.198 3.464v6.661c0 1.865 1.6 3.464 3.198 3.464h29.84c1.865 0 3.198-1.599 3.198-3.464V3.516C82.385 1.65 80.786.052 78.92.052zm45.563 0H94.642c-1.865 0-3.464 1.599-3.464 3.464v6.661c0 1.865 1.599 3.464 3.464 3.464h29.842c1.865-.266 3.464-1.599 3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464zm0 22.382H40.02c-1.866 0-3.464-1.599-3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464H3.516C1.65.052.052 1.651.052 3.516V124.75c0 1.598 1.599 3.197 3.464 3.197h120.968c1.865 0 3.464-1.599 3.464-3.464V25.898c0-1.865-1.599-3.464-3.464-3.464z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/table.svg b/ruoyi-ui/src/assets/icons/svg/table.svg new file mode 100644 index 0000000..0e3dc9d --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/table.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/theme.svg b/ruoyi-ui/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M125.5 36.984L95.336 2.83C93.735 1.018 91.565 0 89.3 0c-2.263 0-4.433 1.018-6.033 2.83l-3.786 4.286c-1.6 1.812-3.77 2.83-6.032 2.831H54.553c-2.263 0-4.434-1.018-6.033-2.83L44.734 2.83C43.134 1.018 40.964 0 38.701 0c-2.263 0-4.434 1.018-6.034 2.83L2.5 36.984C.9 38.796 0 41.254 0 43.815c0 2.562.899 5.02 2.5 6.831L14.565 64.31c2.178 2.468 5.367 3.403 8.33 2.444 1.35-.435 2.709.592 2.709 2.18v49.407c0 5.313 3.84 9.66 8.532 9.66h59.726c4.693 0 8.532-4.347 8.532-9.66V68.934c0-1.59 1.36-2.616 2.71-2.181 2.962.96 6.15.024 8.329-2.444L125.5 50.646c1.6-1.811 2.499-4.269 2.499-6.83 0-2.563-.899-5.02-2.5-6.832z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/tool.svg b/ruoyi-ui/src/assets/icons/svg/tool.svg new file mode 100644 index 0000000..c813067 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/tool.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1553828490559" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1684" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M898.831744 900.517641 103.816972 900.517641c-36.002982 0-65.363683-29.286-65.363683-65.313541l0-554.949184c0-36.041868 29.361725-65.326844 65.363683-65.326844l795.015795 0c36.002982 0 65.198931 29.284977 65.198931 65.326844l0 554.949184C964.030675 871.231641 934.834726 900.517641 898.831744 900.517641L898.831744 900.517641zM103.816972 255.593236c-13.576203 0-24.711821 11.085476-24.711821 24.662703l0 554.949184c0 13.576203 11.136641 24.662703 24.711821 24.662703l795.015795 0c13.577227 0 24.547069-11.086499 24.547069-24.662703l0-554.949184c0-13.577227-10.970866-24.662703-24.547069-24.662703L103.816972 255.593236 103.816972 255.593236zM664.346245 251.774257c-11.161201 0-20.332071-9.080819-20.332071-20.332071l0-101.278661c0-13.576203-11.047614-24.623817-24.699542-24.623817L383.181611 105.539708c-13.576203 0-24.712845 11.04659-24.712845 24.623817l0 101.278661c0 11.252275-9.041934 20.332071-20.332071 20.332071-11.20111 0-20.319791-9.080819-20.319791-20.332071l0-101.278661c0-35.989679 29.323862-65.275679 65.364707-65.275679l236.133022 0c36.06745 0 65.402569 29.284977 65.402569 65.275679l0 101.278661C684.717202 242.694461 675.636383 251.774257 664.346245 251.774257L664.346245 251.774257zM413.233044 521.725502 75.694471 521.725502c-11.163247 0-20.333094-9.117658-20.333094-20.35663 0-11.252275 9.169847-20.332071 20.333094-20.332071l337.538573 0c11.277858 0 20.319791 9.080819 20.319791 20.332071C433.552835 512.607844 424.510902 521.725502 413.233044 521.725502L413.233044 521.725502zM912.894018 521.725502 575.367725 521.725502c-11.213389 0-20.332071-9.117658-20.332071-20.35663 0-11.252275 9.118682-20.332071 20.332071-20.332071l337.526293 0c11.290137 0 20.332071 9.080819 20.332071 20.332071C933.226089 512.607844 924.184155 521.725502 912.894018 521.725502L912.894018 521.725502zM557.56322 634.217552 445.085496 634.217552c-11.213389 0-20.332071-9.079796-20.332071-20.331048l0-168.763658c0-11.251252 9.118682-20.332071 20.332071-20.332071l112.478747 0c11.290137 0 20.370956 9.080819 20.370956 20.332071l0 168.763658C577.934177 625.137757 568.853357 634.217552 557.56322 634.217552L557.56322 634.217552zM465.417567 593.514525l71.827909 0L537.245476 465.454918l-71.827909 0L465.417567 593.514525 465.417567 593.514525z" p-id="1685" fill="#bfbfbf"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/tree-table.svg b/ruoyi-ui/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/tree.svg b/ruoyi-ui/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/user.svg b/ruoyi-ui/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..0ba0716 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ +<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/validCode.svg b/ruoyi-ui/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..cfb1021 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569580729849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1939" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" fill="#C6CCDA" p-id="1940"></path><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" fill="#C6CCDA" p-id="1941"></path></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/wechat.svg b/ruoyi-ui/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ +<svg width="128" height="110" xmlns="http://www.w3.org/2000/svg"><path d="M86.635 33.334c1.467 0 2.917.113 4.358.283C87.078 14.392 67.58.111 45.321.111 20.44.111.055 17.987.055 40.687c0 13.104 6.781 23.863 18.115 32.209l-4.527 14.352 15.82-8.364c5.666 1.182 10.207 2.395 15.858 2.395 1.42 0 2.829-.073 4.227-.189-.886-3.19-1.398-6.53-1.398-9.996 0-20.845 16.98-37.76 38.485-37.76zm-24.34-12.936c3.407 0 5.665 2.363 5.665 5.954 0 3.576-2.258 5.97-5.666 5.97-3.392 0-6.795-2.395-6.795-5.97 0-3.591 3.403-5.954 6.795-5.954zM30.616 32.323c-3.393 0-6.818-2.395-6.818-5.971 0-3.591 3.425-5.954 6.818-5.954 3.392 0 5.65 2.363 5.65 5.954 0 3.576-2.258 5.97-5.65 5.97z"/><path d="M127.945 70.52c0-19.075-18.108-34.623-38.448-34.623-21.537 0-38.5 15.548-38.5 34.623 0 19.108 16.963 34.622 38.5 34.622 4.508 0 9.058-1.2 13.584-2.395l12.414 7.167-3.404-11.923c9.087-7.184 15.854-16.712 15.854-27.471zm-50.928-5.97c-2.254 0-4.53-2.362-4.53-4.773 0-2.378 2.276-4.771 4.53-4.771 3.422 0 5.665 2.393 5.665 4.771 0 2.41-2.243 4.773-5.665 4.773zm24.897 0c-2.24 0-4.498-2.362-4.498-4.773 0-2.378 2.258-4.771 4.498-4.771 3.392 0 5.665 2.393 5.665 4.771 0 2.41-2.273 4.773-5.665 4.773z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svg/zip.svg b/ruoyi-ui/src/assets/icons/svg/zip.svg new file mode 100644 index 0000000..f806fc4 --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svg/zip.svg @@ -0,0 +1 @@ +<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.527 116.793c.178.008.348.024.527.024h40.233c4.711-.005 8.53-3.677 8.534-8.21V18.895c-.004-4.532-3.823-8.204-8.534-8.209H79.054c-.179 0-.353.016-.527.024V0L0 10.082v107.406l78.527 10.342v-11.037zm0-101.362c.174-.024.348-.052.527-.052h40.233c2.018 0 3.659 1.578 3.659 3.52v89.713c-.003 1.942-1.64 3.517-3.659 3.519H79.054c-.179 0-.353-.028-.527-.052V15.431zM30.262 75.757l-18.721-.46V72.37l11.3-16.673v-.148l-10.266.164v-4.51l17.504-.44v3.264L18.696 70.76v.144l11.566.176v4.678zm9.419.231l-5.823-.144V50.671l5.823-.144v25.461zm22.255-11.632c-2.168 1.922-5.353 2.76-9.02 2.736-.702.004-1.402-.04-2.097-.131v9.303l-5.997-.148V50.743c1.852-.352 4.473-.647 8.218-.743 3.838-.096 6.608.539 8.48 1.913 1.807 1.306 3.032 3.5 3.032 6.112s-.926 4.833-2.612 6.331h-.004zM53.36 54.45c-.856-.01-1.71.083-2.541.275v7.682c.523.116 1.167.152 2.06.152 3.301-.004 5.36-1.614 5.36-4.314 0-2.425-1.772-3.843-4.875-3.791l-.004-.004zm39.847-37.066h9.564v3.795h-9.564v-3.795zm-9.568 5.68h9.564v3.8h-9.564v-3.8zm9.568 6.216h9.564v3.799h-9.564V29.28zm0 12h9.564v3.794h-9.564V41.28zm-9.568-6.096h9.564v3.795h-9.564v-3.795zm9.472 47.064c2.512 0 4.921-.96 6.697-2.67 1.776-1.708 2.773-4.026 2.772-6.442l-1.748-15.263c0-5.033-2.492-9.112-7.725-9.112-5.232 0-7.72 4.079-7.72 9.112l-1.752 15.263c-.001 2.417.996 4.735 2.773 6.444 1.777 1.71 4.187 2.669 6.7 2.668h.003zm-3.135-16.75h6.27v12.743h-6.27V65.5z"/></svg> \ No newline at end of file diff --git a/ruoyi-ui/src/assets/icons/svgo.yml b/ruoyi-ui/src/assets/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/ruoyi-ui/src/assets/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/ruoyi-ui/src/assets/image/login-background.jpg b/ruoyi-ui/src/assets/image/login-background.jpg new file mode 100644 index 0000000..8a89eb8 --- /dev/null +++ b/ruoyi-ui/src/assets/image/login-background.jpg Binary files differ diff --git a/ruoyi-ui/src/assets/image/profile.jpg b/ruoyi-ui/src/assets/image/profile.jpg new file mode 100644 index 0000000..b3a940b --- /dev/null +++ b/ruoyi-ui/src/assets/image/profile.jpg Binary files differ diff --git a/ruoyi-ui/src/assets/logo/logo.png b/ruoyi-ui/src/assets/logo/logo.png new file mode 100644 index 0000000..e263760 --- /dev/null +++ b/ruoyi-ui/src/assets/logo/logo.png Binary files differ diff --git a/ruoyi-ui/src/assets/styles/btn.scss b/ruoyi-ui/src/assets/styles/btn.scss new file mode 100644 index 0000000..e6ba1a8 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@import './variables.scss'; + +@mixin colorBtn($color) { + background: $color; + + &:hover { + color: $color; + + &:before, + &:after { + background: $color; + } + } +} + +.blue-btn { + @include colorBtn($blue) +} + +.light-blue-btn { + @include colorBtn($light-blue) +} + +.red-btn { + @include colorBtn($red) +} + +.pink-btn { + @include colorBtn($pink) +} + +.green-btn { + @include colorBtn($green) +} + +.tiffany-btn { + @include colorBtn($tiffany) +} + +.yellow-btn { + @include colorBtn($yellow) +} + +.pan-btn { + font-size: 14px; + color: #fff; + padding: 14px 36px; + border-radius: 8px; + border: none; + outline: none; + transition: 600ms ease all; + position: relative; + display: inline-block; + + &:hover { + background: #fff; + + &:before, + &:after { + width: 100%; + transition: 600ms ease all; + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + right: 0; + height: 2px; + width: 0; + transition: 400ms ease all; + } + + &::after { + right: inherit; + top: inherit; + left: 0; + bottom: 0; + } +} + +.custom-button { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: #fff; + color: #fff; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: 0; + margin: 0; + padding: 10px 15px; + font-size: 14px; + border-radius: 4px; +} diff --git a/ruoyi-ui/src/assets/styles/element-ui.scss b/ruoyi-ui/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..9581d56 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/element-ui.scss @@ -0,0 +1,79 @@ +// cover some element-ui styles + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0px; + } +} + +.small-padding { + .cell { + padding-left: 5px; + padding-right: 5px; + } +} + +.fixed-width { + .el-button--mini { + padding: 7px 10px; + width: 60px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0px; + } + } +} + +// to fixed https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block + } +} + +// fix date-picker ui bug in filter-item +.el-range-editor.el-input__inner { + display: inline-flex !important; +} diff --git a/ruoyi-ui/src/assets/styles/element-variables.scss b/ruoyi-ui/src/assets/styles/element-variables.scss new file mode 100644 index 0000000..30a0e6b --- /dev/null +++ b/ruoyi-ui/src/assets/styles/element-variables.scss @@ -0,0 +1,31 @@ +/** +* I think element-ui's default theme color is too light for long-term use. +* So I modified the default color and you can modify it to your liking. +**/ + +/* theme color */ +$--color-primary: #1890ff; +$--color-success: #13ce66; +$--color-warning: #FFBA00; +$--color-danger: #ff4949; +// $--color-info: #1E1E1E; + +$--button-font-weight: 400; + +// $--color-text-regular: #1f2d3d; + +$--border-color-light: #dfe4ed; +$--border-color-lighter: #e6ebf5; + +$--table-border:1px solid#dfe6ec; + +/* icon font path, required */ +$--font-path: '~element-ui/lib/theme-chalk/fonts'; + +@import "~element-ui/packages/theme-chalk/src/index"; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + theme: $--color-primary; +} diff --git a/ruoyi-ui/src/assets/styles/index.scss b/ruoyi-ui/src/assets/styles/index.scss new file mode 100644 index 0000000..96095ef --- /dev/null +++ b/ruoyi-ui/src/assets/styles/index.scss @@ -0,0 +1,191 @@ +@import './variables.scss'; +@import './mixin.scss'; +@import './transition.scss'; +@import './element-ui.scss'; +@import './sidebar.scss'; +@import './btn.scss'; + +body { + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; +} + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +#app { + height: 100%; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.no-padding { + padding: 0px !important; +} + +.padding-content { + padding: 4px 0; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.fr { + float: right; +} + +.fl { + float: left; +} + +.pr-5 { + padding-right: 5px; +} + +.pl-5 { + padding-left: 5px; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +.inlineBlock { + display: block; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +aside { + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + a { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } + } +} + +//main-container鍏ㄥ眬鏍峰紡 +.app-container { + padding: 20px; +} + +.components-container { + margin: 30px 50px; + position: relative; +} + +.pagination-container { + margin-top: 30px; +} + +.text-center { + text-align: center +} + +.sub-navbar { + height: 50px; + line-height: 50px; + position: relative; + width: 100%; + text-align: right; + padding-right: 20px; + transition: 600ms ease position; + background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + + .subtitle { + font-size: 20px; + color: #fff; + } + + &.draft { + background: #d0d0d0; + } + + &.deleted { + background: #d0d0d0; + } +} + +.link-type, +.link-type:focus { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } +} + +.filter-container { + padding-bottom: 10px; + + .filter-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + } +} + +//refine vue-multiselect plugin +.multiselect { + line-height: 16px; +} + +.multiselect--active { + z-index: 1000 !important; +} diff --git a/ruoyi-ui/src/assets/styles/mixin.scss b/ruoyi-ui/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/mixin.scss @@ -0,0 +1,66 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + +@mixin pct($pct) { + width: #{$pct}; + position: relative; + margin: 0 auto; +} + +@mixin triangle($width, $height, $color, $direction) { + $width: $width/2; + $color-border-style: $height solid $color; + $transparent-border-style: $width solid transparent; + height: 0; + width: 0; + + @if $direction==up { + border-bottom: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==right { + border-left: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } + + @else if $direction==down { + border-top: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==left { + border-right: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } +} diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss new file mode 100644 index 0000000..3b2df35 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/ruoyi.scss @@ -0,0 +1,190 @@ + /** + * 閫氱敤css鏍峰紡甯冨眬澶勭悊 + * Copyright (c) 2019 ruoyi + */ + + /** 鍩虹閫氱敤 **/ +.pt5 { + padding-top: 5px; +} +.pr5 { + padding-right: 5px; +} +.pb5 { + padding-bottom: 5px; +} +.mt5 { + margin-top: 5px; +} +.mr5 { + margin-right: 5px; +} +.mb5 { + margin-bottom: 5px; +} +.mb8 { + margin-bottom: 8px; +} +.ml5 { + margin-left: 5px; +} +.mt10 { + margin-top: 10px; +} +.mr10 { + margin-right: 10px; +} +.mb10 { + margin-bottom: 10px; +} +.ml0 { + margin-left: 10px; +} +.mt20 { + margin-top: 20px; +} +.mr20 { + margin-right: 20px; +} +.mb20 { + margin-bottom: 20px; +} +.m20 { + margin-left: 20px; +} + +.el-dialog { + margin-top: 6vh !important; +} + +.el-table .el-table__header-wrapper th { + word-break: break-word; + background-color: #f8f8f9; + color: #515a6e; + height: 40px; + font-size: 13px; +} + +/** 琛ㄥ崟甯冨眬 **/ +.form-header { + font-size:15px; + color:#6379bb; + border-bottom:1px solid #ddd; + margin:8px 10px 25px 10px; + padding-bottom:5px +} + +/** 琛ㄦ牸甯冨眬 **/ +.pagination-container { + position: relative; + height: 25px; + margin-bottom: 10px; + margin-top: 15px; + padding: 10px 20px !important; +} + +.pagination-container .el-pagination { + right: 0; + position: absolute; +} + +.el-table .fixed-width .el-button--mini { + color: #409EFF; + padding-left: 0; + padding-right: 0; + width: inherit; +} + +.el-tree-node__content > .el-checkbox { + margin-right: 8px; +} + +.list-group-striped > .list-group-item { + border-left: 0; + border-right: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0; +} + +.list-group { + padding-left: 0px; + list-style: none; +} + +.list-group-item { + border-bottom: 1px solid #e7eaec; + border-top: 1px solid #e7eaec; + margin-bottom: -1px; + padding: 11px 0px; + font-size: 13px; +} + +.pull-right { + float: right !important; +} + +.el-card__header { + padding: 14px 15px 7px; + min-height: 40px; +} + +.el-card__body { + padding: 15px 20px 20px 20px; +} + +.card-box { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 10px; +} + +/* text color */ +.text-navy { + color: #1ab394; +} + +.text-primary { + color: inherit; +} + +.text-success { + color: #1c84c6; +} + +.text-info { + color: #23c6c8; +} + +.text-warning { + color: #f8ac59; +} + +.text-danger { + color: #ed5565; +} + +.text-muted { + color: #888888; +} + +/* image */ +.img-circle { + border-radius: 50%; +} + +.img-lg { + width: 120px; + height: 120px; +} + +.avatar-upload-preview { + position: absolute; + top: 50%; + transform: translate(50%, -50%); + width: 180px; + height: 180px; + border-radius: 50%; + box-shadow: 0 0 4px #ccc; + overflow: hidden; +} \ No newline at end of file diff --git a/ruoyi-ui/src/assets/styles/sidebar.scss b/ruoyi-ui/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..3dad4c3 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/sidebar.scss @@ -0,0 +1,209 @@ +#app { + + .main-container { + min-height: 100%; + transition: margin-left .28s; + margin-left: $sideBarWidth; + position: relative; + } + + .sidebar-container { + transition: width 0.28s; + width: $sideBarWidth !important; + background-color: $menuBg; + height: 100%; + position: fixed; + font-size: 0px; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + + // reset element-ui css + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + + .scrollbar-wrapper { + overflow-x: hidden !important; + } + + .el-scrollbar__bar.is-vertical { + right: 0px; + } + + .el-scrollbar { + height: 100%; + } + + &.has-logo { + .el-scrollbar { + height: calc(100% - 50px); + } + } + + .is-horizontal { + display: none; + } + + a { + display: inline-block; + width: 100%; + overflow: hidden; + } + + .svg-icon { + margin-right: 16px; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + + // menu hover + .submenu-title-noDropdown, + .el-submenu__title { + &:hover { + background-color: $menuHover !important; + } + } + + .is-active>.el-submenu__title { + color: $subMenuActiveText !important; + } + + & .nest-menu .el-submenu>.el-submenu__title, + & .el-submenu .el-menu-item { + min-width: $sideBarWidth !important; + background-color: $subMenuBg !important; + + &:hover { + background-color: $subMenuHover !important; + } + } + } + + .hideSidebar { + .sidebar-container { + width: 54px !important; + } + + .main-container { + margin-left: 54px; + } + + .submenu-title-noDropdown { + padding: 0 !important; + position: relative; + + .el-tooltip { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + } + } + + .el-submenu { + overflow: hidden; + + &>.el-submenu__title { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + + .el-submenu__icon-arrow { + display: none; + } + } + } + + .el-menu--collapse { + .el-submenu { + &>.el-submenu__title { + &>span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } + } + + .el-menu--collapse .el-menu .el-submenu { + min-width: $sideBarWidth !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar-container { + transition: transform .28s; + width: $sideBarWidth !important; + } + + &.hideSidebar { + .sidebar-container { + pointer-events: none; + transition-duration: 0.3s; + transform: translate3d(-$sideBarWidth, 0, 0); + } + } + } + + .withoutAnimation { + + .main-container, + .sidebar-container { + transition: none; + } + } +} + +// when menu collapsed +.el-menu--vertical { + &>.el-menu { + .svg-icon { + margin-right: 16px; + } + } + + .nest-menu .el-submenu>.el-submenu__title, + .el-menu-item { + &:hover { + // you can use $subMenuHover + background-color: $menuHover !important; + } + } + + // the scroll bar appears when the subMenu is too long + >.el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } + } +} diff --git a/ruoyi-ui/src/assets/styles/transition.scss b/ruoyi-ui/src/assets/styles/transition.scss new file mode 100644 index 0000000..4cb27cc --- /dev/null +++ b/ruoyi-ui/src/assets/styles/transition.scss @@ -0,0 +1,48 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/ruoyi-ui/src/assets/styles/variables.scss b/ruoyi-ui/src/assets/styles/variables.scss new file mode 100644 index 0000000..5688f25 --- /dev/null +++ b/ruoyi-ui/src/assets/styles/variables.scss @@ -0,0 +1,35 @@ +// base color +$blue:#324157; +$light-blue:#3A71A8; +$red:#C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow:#FEC171; +$panGreen: #30B08F; + +// sidebar +$menuText:#bfcbd9; +$menuActiveText:#409EFF; +$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 + +$menuBg:#304156; +$menuHover:#263445; + +$subMenuBg:#1f2d3d; +$subMenuHover:#001528; + +$sideBarWidth: 200px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuText: $menuText; + menuActiveText: $menuActiveText; + subMenuActiveText: $subMenuActiveText; + menuBg: $menuBg; + menuHover: $menuHover; + subMenuBg: $subMenuBg; + subMenuHover: $subMenuHover; + sideBarWidth: $sideBarWidth; +} diff --git a/ruoyi-ui/src/components/Breadcrumb/index.vue b/ruoyi-ui/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..97603c4 --- /dev/null +++ b/ruoyi-ui/src/components/Breadcrumb/index.vue @@ -0,0 +1,81 @@ +<template> + <el-breadcrumb class="app-breadcrumb" separator="/"> + <transition-group name="breadcrumb"> + <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path"> + <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span> + <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> + </el-breadcrumb-item> + </transition-group> + </el-breadcrumb> +</template> + +<script> +import pathToRegexp from 'path-to-regexp' + +export default { + data() { + return { + levelList: null + } + }, + watch: { + $route(route) { + // if you go to the redirect page, do not update the breadcrumbs + if (route.path.startsWith('/redirect/')) { + return + } + this.getBreadcrumb() + } + }, + created() { + this.getBreadcrumb() + }, + methods: { + getBreadcrumb() { + // only show routes with meta.title + let matched = this.$route.matched.filter(item => item.meta && item.meta.title) + const first = matched[0] + + if (!this.isDashboard(first)) { + matched = [{ path: '/index', meta: { title: '棣栭〉' }}].concat(matched) + } + + this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) + }, + isDashboard(route) { + const name = route && route.name + if (!name) { + return false + } + return name.trim() === '棣栭〉' + }, + pathCompile(path) { + const { params } = this.$route + var toPath = pathToRegexp.compile(path) + return toPath(params) + }, + handleLink(item) { + const { redirect, path } = item + if (redirect) { + this.$router.push(redirect) + return + } + this.$router.push(this.pathCompile(path)) + } + } +} +</script> + +<style lang="scss" scoped> +.app-breadcrumb.el-breadcrumb { + display: inline-block; + font-size: 14px; + line-height: 50px; + margin-left: 8px; + + .no-redirect { + color: #97a8be; + cursor: text; + } +} +</style> diff --git a/ruoyi-ui/src/components/Editor/index.vue b/ruoyi-ui/src/components/Editor/index.vue new file mode 100644 index 0000000..91fbc7d --- /dev/null +++ b/ruoyi-ui/src/components/Editor/index.vue @@ -0,0 +1,226 @@ +<template> + <div> + <!-- 鍥剧墖涓婁紶缁勪欢杈呭姪 --> + <el-upload + class="avatar-uploader quill-img" + :action="uploadImgUrl" + name="file" + :headers="headers" + :show-file-list="false" + :on-success="quillImgSuccess" + :on-error="uploadError" + :before-upload="quillImgBefore" + accept='.jpg,.jpeg,.png,.gif' + ></el-upload> + + <!-- 瀵屾枃鏈粍浠� --> + <quill-editor + class="editor" + v-model="content" + ref="quillEditor" + :options="editorOption" + @blur="onEditorBlur($event)" + @focus="onEditorFocus($event)" + @change="onEditorChange($event)" + ></quill-editor> + </div> +</template> + +<script> +import { getToken } from '@/utils/auth' + +// 宸ュ叿鏍忛厤缃� +const toolbarOptions = [ + ["bold", "italic", "underline", "strike"], // 鍔犵矖 鏂滀綋 涓嬪垝绾� 鍒犻櫎绾� + ["blockquote", "code-block"], // 寮曠敤 浠g爜鍧� + [{ list: "ordered" }, { list: "bullet" }], // 鏈夊簭銆佹棤搴忓垪琛� + [{ indent: "-1" }, { indent: "+1" }], // 缂╄繘 + [{ size: ["small", false, "large", "huge"] }], // 瀛椾綋澶у皬 + [{ header: [1, 2, 3, 4, 5, 6, false] }], // 鏍囬 + [{ color: [] }, { background: [] }], // 瀛椾綋棰滆壊銆佸瓧浣撹儗鏅鑹� + [{ align: [] }], // 瀵归綈鏂瑰紡 + ["clean"], // 娓呴櫎鏂囨湰鏍煎紡 + ["link", "image", "video"] // 閾炬帴銆佸浘鐗囥�佽棰� +]; + +import { quillEditor } from "vue-quill-editor"; +import "quill/dist/quill.core.css"; +import "quill/dist/quill.snow.css"; +import "quill/dist/quill.bubble.css"; + +export default { + props: { + /* 缂栬緫鍣ㄧ殑鍐呭 */ + value: { + type: String + }, + /* 鍥剧墖澶у皬 */ + maxSize: { + type: Number, + default: 4000 //kb + } + }, + components: { quillEditor }, + data() { + return { + content: this.value, + uploadImgUrl: "", + editorOption: { + placeholder: "", + theme: "snow", // or 'bubble' + placeholder: "璇疯緭鍏ュ唴瀹�", + modules: { + toolbar: { + container: toolbarOptions, + handlers: { + image: function(value) { + if (value) { + // 瑙﹀彂input妗嗛�夋嫨鍥剧墖鏂囦欢 + document.querySelector(".quill-img input").click(); + } else { + this.quill.format("image", false); + } + } + } + } + } + }, + uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃 + headers: { + Authorization: 'Bearer ' + getToken() + } + }; + }, + watch: { + value: function() { + this.content = this.value; + } + }, + methods: { + onEditorBlur() { + //澶卞幓鐒︾偣浜嬩欢 + }, + onEditorFocus() { + //鑾峰緱鐒︾偣浜嬩欢 + }, + onEditorChange() { + //鍐呭鏀瑰彉浜嬩欢 + this.$emit("input", this.content); + }, + + // 瀵屾枃鏈浘鐗囦笂浼犲墠 + quillImgBefore(file) { + let fileType = file.type; + if(fileType === 'image/jpeg' || fileType === 'image/png'){ + return true; + }else { + this.$message.error('璇锋彃鍏ュ浘鐗囩被鍨嬫枃浠�(jpg/jpeg/png)'); + return false; + } + }, + + quillImgSuccess(res, file) { + // res涓哄浘鐗囨湇鍔″櫒杩斿洖鐨勬暟鎹� + // 鑾峰彇瀵屾枃鏈粍浠跺疄渚� + let quill = this.$refs.quillEditor.quill; + // 濡傛灉涓婁紶鎴愬姛 + if (res.code == 200) { + // 鑾峰彇鍏夋爣鎵�鍦ㄤ綅缃� + let length = quill.getSelection().index; + // 鎻掑叆鍥剧墖 res.url涓烘湇鍔″櫒杩斿洖鐨勫浘鐗囧湴鍧� + quill.insertEmbed(length, "image", res.url); + // 璋冩暣鍏夋爣鍒版渶鍚� + quill.setSelection(length + 1); + } else { + this.$message.error("鍥剧墖鎻掑叆澶辫触"); + } + }, + // 瀵屾枃鏈浘鐗囦笂浼犲け璐� + uploadError() { + // loading鍔ㄧ敾娑堝け + this.$message.error("鍥剧墖鎻掑叆澶辫触"); + } + } +}; +</script> + +<style> +.editor { + line-height: normal !important; + height: 192px; +} +.quill-img { + display: none; +} +.ql-snow .ql-tooltip[data-mode="link"]::before { + content: "璇疯緭鍏ラ摼鎺ュ湴鍧�:"; +} +.ql-snow .ql-tooltip.ql-editing a.ql-action::after { + border-right: 0px; + content: "淇濆瓨"; + padding-right: 0px; +} + +.ql-snow .ql-tooltip[data-mode="video"]::before { + content: "璇疯緭鍏ヨ棰戝湴鍧�:"; +} + +.ql-snow .ql-picker.ql-size .ql-picker-label::before, +.ql-snow .ql-picker.ql-size .ql-picker-item::before { + content: "14px"; +} +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { + content: "10px"; +} +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { + content: "18px"; +} +.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, +.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { + content: "32px"; +} + +.ql-snow .ql-picker.ql-header .ql-picker-label::before, +.ql-snow .ql-picker.ql-header .ql-picker-item::before { + content: "鏂囨湰"; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { + content: "鏍囬1"; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { + content: "鏍囬2"; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { + content: "鏍囬3"; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { + content: "鏍囬4"; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { + content: "鏍囬5"; +} +.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, +.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { + content: "鏍囬6"; +} + +.ql-snow .ql-picker.ql-font .ql-picker-label::before, +.ql-snow .ql-picker.ql-font .ql-picker-item::before { + content: "鏍囧噯瀛椾綋"; +} +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before { + content: "琛嚎瀛椾綋"; +} +.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, +.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { + content: "绛夊瀛椾綋"; +} +</style> \ No newline at end of file diff --git a/ruoyi-ui/src/components/Hamburger/index.vue b/ruoyi-ui/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/ruoyi-ui/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ +<template> + <div style="padding: 0 15px;" @click="toggleClick"> + <svg + :class="{'is-active':isActive}" + class="hamburger" + viewBox="0 0 1024 1024" + xmlns="http://www.w3.org/2000/svg" + width="64" + height="64" + > + <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> + </svg> + </div> +</template> + +<script> +export default { + name: 'Hamburger', + props: { + isActive: { + type: Boolean, + default: false + } + }, + methods: { + toggleClick() { + this.$emit('toggleClick') + } + } +} +</script> + +<style scoped> +.hamburger { + display: inline-block; + vertical-align: middle; + width: 20px; + height: 20px; +} + +.hamburger.is-active { + transform: rotate(180deg); +} +</style> diff --git a/ruoyi-ui/src/components/HeaderSearch/index.vue b/ruoyi-ui/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..af04716 --- /dev/null +++ b/ruoyi-ui/src/components/HeaderSearch/index.vue @@ -0,0 +1,180 @@ +<template> + <div :class="{'show':show}" class="header-search"> + <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> + <el-select + ref="headerSearchSelect" + v-model="search" + :remote-method="querySearch" + filterable + default-first-option + remote + placeholder="Search" + class="header-search-select" + @change="change" + > + <el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" /> + </el-select> + </div> +</template> + +<script> +// fuse is a lightweight fuzzy-search module +// make search results more in line with expectations +import Fuse from 'fuse.js' +import path from 'path' + +export default { + name: 'HeaderSearch', + data() { + return { + search: '', + options: [], + searchPool: [], + show: false, + fuse: undefined + } + }, + computed: { + routes() { + return this.$store.getters.permission_routes + } + }, + watch: { + routes() { + this.searchPool = this.generateRoutes(this.routes) + }, + searchPool(list) { + this.initFuse(list) + }, + show(value) { + if (value) { + document.body.addEventListener('click', this.close) + } else { + document.body.removeEventListener('click', this.close) + } + } + }, + mounted() { + this.searchPool = this.generateRoutes(this.routes) + }, + methods: { + click() { + this.show = !this.show + if (this.show) { + this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus() + } + }, + close() { + this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur() + this.options = [] + this.show = false + }, + change(val) { + this.$router.push(val.path) + this.search = '' + this.options = [] + this.$nextTick(() => { + this.show = false + }) + }, + initFuse(list) { + this.fuse = new Fuse(list, { + shouldSort: true, + threshold: 0.4, + location: 0, + distance: 100, + maxPatternLength: 32, + minMatchCharLength: 1, + keys: [{ + name: 'title', + weight: 0.7 + }, { + name: 'path', + weight: 0.3 + }] + }) + }, + // Filter out the routes that can be displayed in the sidebar + // And generate the internationalized title + generateRoutes(routes, basePath = '/', prefixTitle = []) { + let res = [] + + for (const router of routes) { + // skip hidden router + if (router.hidden) { continue } + + const data = { + path: path.resolve(basePath, router.path), + title: [...prefixTitle] + } + + if (router.meta && router.meta.title) { + data.title = [...data.title, router.meta.title] + + if (router.redirect !== 'noRedirect') { + // only push the routes with title + // special case: need to exclude parent router without redirect + res.push(data) + } + } + + // recursive child routes + if (router.children) { + const tempRoutes = this.generateRoutes(router.children, data.path, data.title) + if (tempRoutes.length >= 1) { + res = [...res, ...tempRoutes] + } + } + } + return res + }, + querySearch(query) { + if (query !== '') { + this.options = this.fuse.search(query) + } else { + this.options = [] + } + } + } +} +</script> + +<style lang="scss" scoped> +.header-search { + font-size: 0 !important; + + .search-icon { + cursor: pointer; + font-size: 18px; + vertical-align: middle; + } + + .header-search-select { + font-size: 18px; + transition: width 0.2s; + width: 0; + overflow: hidden; + background: transparent; + border-radius: 0; + display: inline-block; + vertical-align: middle; + + /deep/ .el-input__inner { + border-radius: 0; + border: 0; + padding-left: 0; + padding-right: 0; + box-shadow: none !important; + border-bottom: 1px solid #d9d9d9; + vertical-align: middle; + } + } + + &.show { + .header-search-select { + width: 210px; + margin-left: 10px; + } + } +} +</style> diff --git a/ruoyi-ui/src/components/IconSelect/index.vue b/ruoyi-ui/src/components/IconSelect/index.vue new file mode 100644 index 0000000..0611dc5 --- /dev/null +++ b/ruoyi-ui/src/components/IconSelect/index.vue @@ -0,0 +1,69 @@ +<!-- @author zhengjie --> +<template> + <div class="icon-body"> + <el-input v-model="name" style="position: relative;" clearable placeholder="璇疯緭鍏ュ浘鏍囧悕绉�" @clear="filterIcons" @input.native="filterIcons"> + <i slot="suffix" class="el-icon-search el-input__icon" /> + </el-input> + <div class="icon-list"> + <div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)"> + <svg-icon :icon-class="item" style="height: 30px;width: 16px;" /> + <span>{{ item }}</span> + </div> + </div> + </div> +</template> + +<script> +import icons from './requireIcons' +export default { + name: 'IconSelect', + data() { + return { + name: '', + iconList: icons + } + }, + methods: { + filterIcons() { + if (this.name) { + this.iconList = this.iconList.filter(item => item.includes(this.name)) + } else { + this.iconList = icons + } + }, + selectedIcon(name) { + this.$emit('selected', name) + document.body.click() + }, + reset() { + this.name = '' + this.iconList = icons + } + } +} +</script> + +<style rel="stylesheet/scss" lang="scss" scoped> + .icon-body { + width: 100%; + padding: 10px; + .icon-list { + height: 200px; + overflow-y: scroll; + div { + height: 30px; + line-height: 30px; + margin-bottom: -5px; + cursor: pointer; + width: 33%; + float: left; + } + span { + display: inline-block; + vertical-align: -0.15em; + fill: currentColor; + overflow: hidden; + } + } + } +</style> diff --git a/ruoyi-ui/src/components/IconSelect/requireIcons.js b/ruoyi-ui/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..99e5c54 --- /dev/null +++ b/ruoyi-ui/src/components/IconSelect/requireIcons.js @@ -0,0 +1,11 @@ + +const req = require.context('../../assets/icons/svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys() + +const re = /\.\/(.*)\.svg/ + +const icons = requireAll(req).map(i => { + return i.match(re)[1] +}) + +export default icons diff --git a/ruoyi-ui/src/components/Pagination/index.vue b/ruoyi-ui/src/components/Pagination/index.vue new file mode 100644 index 0000000..c815e13 --- /dev/null +++ b/ruoyi-ui/src/components/Pagination/index.vue @@ -0,0 +1,101 @@ +<template> + <div :class="{'hidden':hidden}" class="pagination-container"> + <el-pagination + :background="background" + :current-page.sync="currentPage" + :page-size.sync="pageSize" + :layout="layout" + :page-sizes="pageSizes" + :total="total" + v-bind="$attrs" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> +</template> + +<script> +import { scrollTo } from '@/utils/scroll-to' + +export default { + name: 'Pagination', + props: { + total: { + required: true, + type: Number + }, + page: { + type: Number, + default: 1 + }, + limit: { + type: Number, + default: 20 + }, + pageSizes: { + type: Array, + default() { + return [10, 20, 30, 50] + } + }, + layout: { + type: String, + default: 'total, sizes, prev, pager, next, jumper' + }, + background: { + type: Boolean, + default: true + }, + autoScroll: { + type: Boolean, + default: true + }, + hidden: { + type: Boolean, + default: false + } + }, + computed: { + currentPage: { + get() { + return this.page + }, + set(val) { + this.$emit('update:page', val) + } + }, + pageSize: { + get() { + return this.limit + }, + set(val) { + this.$emit('update:limit', val) + } + } + }, + methods: { + handleSizeChange(val) { + this.$emit('pagination', { page: this.currentPage, limit: val }) + if (this.autoScroll) { + scrollTo(0, 800) + } + }, + handleCurrentChange(val) { + this.$emit('pagination', { page: val, limit: this.pageSize }) + if (this.autoScroll) { + scrollTo(0, 800) + } + } + } +} +</script> + +<style scoped> +.pagination-container { + background: #fff; + padding: 32px 16px; +} +.pagination-container.hidden { + display: none; +} +</style> diff --git a/ruoyi-ui/src/components/PanThumb/index.vue b/ruoyi-ui/src/components/PanThumb/index.vue new file mode 100644 index 0000000..1bcf417 --- /dev/null +++ b/ruoyi-ui/src/components/PanThumb/index.vue @@ -0,0 +1,142 @@ +<template> + <div :style="{zIndex:zIndex,height:height,width:width}" class="pan-item"> + <div class="pan-info"> + <div class="pan-info-roles-container"> + <slot /> + </div> + </div> + <!-- eslint-disable-next-line --> + <div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div> + </div> +</template> + +<script> +export default { + name: 'PanThumb', + props: { + image: { + type: String, + required: true + }, + zIndex: { + type: Number, + default: 1 + }, + width: { + type: String, + default: '150px' + }, + height: { + type: String, + default: '150px' + } + } +} +</script> + +<style scoped> +.pan-item { + width: 200px; + height: 200px; + border-radius: 50%; + display: inline-block; + position: relative; + cursor: default; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} + +.pan-info-roles-container { + padding: 20px; + text-align: center; +} + +.pan-thumb { + width: 100%; + height: 100%; + background-position: center center; + background-size: cover; + border-radius: 50%; + overflow: hidden; + position: absolute; + transform-origin: 95% 40%; + transition: all 0.3s ease-in-out; +} + +/* .pan-thumb:after { + content: ''; + width: 8px; + height: 8px; + position: absolute; + border-radius: 50%; + top: 40%; + left: 95%; + margin: -4px 0 0 -4px; + background: radial-gradient(ellipse at center, rgba(14, 14, 14, 1) 0%, rgba(125, 126, 125, 1) 100%); + box-shadow: 0 0 1px rgba(255, 255, 255, 0.9); +} */ + +.pan-info { + position: absolute; + width: inherit; + height: inherit; + border-radius: 50%; + overflow: hidden; + box-shadow: inset 0 0 0 5px rgba(0, 0, 0, 0.05); +} + +.pan-info h3 { + color: #fff; + text-transform: uppercase; + position: relative; + letter-spacing: 2px; + font-size: 18px; + margin: 0 60px; + padding: 22px 0 0 0; + height: 85px; + font-family: 'Open Sans', Arial, sans-serif; + text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3); +} + +.pan-info p { + color: #fff; + padding: 10px 5px; + font-style: italic; + margin: 0 30px; + font-size: 12px; + border-top: 1px solid rgba(255, 255, 255, 0.5); +} + +.pan-info p a { + display: block; + color: #333; + width: 80px; + height: 80px; + background: rgba(255, 255, 255, 0.3); + border-radius: 50%; + color: #fff; + font-style: normal; + font-weight: 700; + text-transform: uppercase; + font-size: 9px; + letter-spacing: 1px; + padding-top: 24px; + margin: 7px auto 0; + font-family: 'Open Sans', Arial, sans-serif; + opacity: 0; + transition: transform 0.3s ease-in-out 0.2s, opacity 0.3s ease-in-out 0.2s, background 0.2s linear 0s; + transform: translateX(60px) rotate(90deg); +} + +.pan-info p a:hover { + background: rgba(255, 255, 255, 0.5); +} + +.pan-item:hover .pan-thumb { + transform: rotate(-110deg); +} + +.pan-item:hover .pan-info p a { + opacity: 1; + transform: translateX(0px) rotate(0deg); +} +</style> diff --git a/ruoyi-ui/src/components/RightPanel/index.vue b/ruoyi-ui/src/components/RightPanel/index.vue new file mode 100644 index 0000000..fbf27eb --- /dev/null +++ b/ruoyi-ui/src/components/RightPanel/index.vue @@ -0,0 +1,149 @@ +<template> + <div ref="rightPanel" :class="{show:show}" class="rightPanel-container"> + <div class="rightPanel-background" /> + <div class="rightPanel"> + <div class="rightPanel-items"> + <slot /> + </div> + </div> + </div> +</template> + +<script> +import { addClass, removeClass } from '@/utils' + +export default { + name: 'RightPanel', + props: { + clickNotClose: { + default: false, + type: Boolean + }, + buttonTop: { + default: 250, + type: Number + } + }, + computed: { + show: { + get() { + return this.$store.state.settings.showSettings + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'showSettings', + value: val + }) + } + }, + theme() { + return this.$store.state.settings.theme + }, + }, + watch: { + show(value) { + if (value && !this.clickNotClose) { + this.addEventClick() + } + if (value) { + addClass(document.body, 'showRightPanel') + } else { + removeClass(document.body, 'showRightPanel') + } + } + }, + mounted() { + this.insertToBody() + this.addEventClick() + }, + beforeDestroy() { + const elx = this.$refs.rightPanel + elx.remove() + }, + methods: { + addEventClick() { + window.addEventListener('click', this.closeSidebar) + }, + closeSidebar(evt) { + const parent = evt.target.closest('.rightPanel') + if (!parent) { + this.show = false + window.removeEventListener('click', this.closeSidebar) + } + }, + insertToBody() { + const elx = this.$refs.rightPanel + const body = document.querySelector('body') + body.insertBefore(elx, body.firstChild) + } + } +} +</script> + +<style> +.showRightPanel { + overflow: hidden; + position: relative; + width: calc(100% - 15px); +} +</style> + +<style lang="scss" scoped> +.rightPanel-background { + position: fixed; + top: 0; + left: 0; + opacity: 0; + transition: opacity .3s cubic-bezier(.7, .3, .1, 1); + background: rgba(0, 0, 0, .2); + z-index: -1; +} + +.rightPanel { + width: 100%; + max-width: 260px; + height: 100vh; + position: fixed; + top: 0; + right: 0; + box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05); + transition: all .25s cubic-bezier(.7, .3, .1, 1); + transform: translate(100%); + background: #fff; + z-index: 40000; +} + +.show { + transition: all .3s cubic-bezier(.7, .3, .1, 1); + + .rightPanel-background { + z-index: 20000; + opacity: 1; + width: 100%; + height: 100%; + } + + .rightPanel { + transform: translate(0); + } +} + +.handle-button { + width: 48px; + height: 48px; + position: absolute; + left: -48px; + text-align: center; + font-size: 24px; + border-radius: 6px 0 0 6px !important; + z-index: 0; + pointer-events: auto; + cursor: pointer; + color: #fff; + line-height: 48px; + i { + font-size: 24px; + line-height: 48px; + } +} +</style> diff --git a/ruoyi-ui/src/components/RuoYi/index.vue b/ruoyi-ui/src/components/RuoYi/index.vue new file mode 100644 index 0000000..3f541d1 --- /dev/null +++ b/ruoyi-ui/src/components/RuoYi/index.vue @@ -0,0 +1,21 @@ +<template> + <div> + <svg-icon icon-class="download" @click="handleDownload"/> + </div> +</template> + +<script> +export default { + name: 'RuoYi', + data() { + return { + url: 'https://gitee.com/y_project/RuoYi-Vue' + } + }, + methods: { + handleDownload() { + window.open(this.url) + } + } +} +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/components/Screenfull/index.vue b/ruoyi-ui/src/components/Screenfull/index.vue new file mode 100644 index 0000000..260c90d --- /dev/null +++ b/ruoyi-ui/src/components/Screenfull/index.vue @@ -0,0 +1,60 @@ +<template> + <div> + <svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" /> + </div> +</template> + +<script> +import screenfull from 'screenfull' + +export default { + name: 'Screenfull', + data() { + return { + isFullscreen: false + } + }, + mounted() { + this.init() + }, + beforeDestroy() { + this.destroy() + }, + methods: { + click() { + if (!screenfull.enabled) { + this.$message({ + message: 'you browser can not work', + type: 'warning' + }) + return false + } + screenfull.toggle() + }, + change() { + this.isFullscreen = screenfull.isFullscreen + }, + init() { + if (screenfull.enabled) { + screenfull.on('change', this.change) + } + }, + destroy() { + if (screenfull.enabled) { + screenfull.off('change', this.change) + } + } + } +} +</script> + +<style scoped> +.screenfull-svg { + display: inline-block; + cursor: pointer; + fill: #5a5e66;; + width: 20px; + height: 20px; + vertical-align: 10px; +} +</style> diff --git a/ruoyi-ui/src/components/SizeSelect/index.vue b/ruoyi-ui/src/components/SizeSelect/index.vue new file mode 100644 index 0000000..e88065b --- /dev/null +++ b/ruoyi-ui/src/components/SizeSelect/index.vue @@ -0,0 +1,57 @@ +<template> + <el-dropdown trigger="click" @command="handleSetSize"> + <div> + <svg-icon class-name="size-icon" icon-class="size" /> + </div> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value"> + {{ + item.label }} + </el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> +</template> + +<script> +export default { + data() { + return { + sizeOptions: [ + { label: 'Default', value: 'default' }, + { label: 'Medium', value: 'medium' }, + { label: 'Small', value: 'small' }, + { label: 'Mini', value: 'mini' } + ] + } + }, + computed: { + size() { + return this.$store.getters.size + } + }, + methods: { + handleSetSize(size) { + this.$ELEMENT.size = size + this.$store.dispatch('app/setSize', size) + this.refreshView() + this.$message({ + message: 'Switch Size Success', + type: 'success' + }) + }, + refreshView() { + // In order to make the cached page re-rendered + this.$store.dispatch('tagsView/delAllCachedViews', this.$route) + + const { fullPath } = this.$route + + this.$nextTick(() => { + this.$router.replace({ + path: '/redirect' + fullPath + }) + }) + } + } + +} +</script> diff --git a/ruoyi-ui/src/components/SvgIcon/index.vue b/ruoyi-ui/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..e4bf5ad --- /dev/null +++ b/ruoyi-ui/src/components/SvgIcon/index.vue @@ -0,0 +1,61 @@ +<template> + <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> + <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners"> + <use :xlink:href="iconName" /> + </svg> +</template> + +<script> +import { isExternal } from '@/utils/validate' + +export default { + name: 'SvgIcon', + props: { + iconClass: { + type: String, + required: true + }, + className: { + type: String, + default: '' + } + }, + computed: { + isExternal() { + return isExternal(this.iconClass) + }, + iconName() { + return `#icon-${this.iconClass}` + }, + svgClass() { + if (this.className) { + return 'svg-icon ' + this.className + } else { + return 'svg-icon' + } + }, + styleExternalIcon() { + return { + mask: `url(${this.iconClass}) no-repeat 50% 50%`, + '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%` + } + } + } +} +</script> + +<style scoped> +.svg-icon { + width: 1em; + height: 1em; + vertical-align: -0.15em; + fill: currentColor; + overflow: hidden; +} + +.svg-external-icon { + background-color: currentColor; + mask-size: cover!important; + display: inline-block; +} +</style> diff --git a/ruoyi-ui/src/components/ThemePicker/index.vue b/ruoyi-ui/src/components/ThemePicker/index.vue new file mode 100644 index 0000000..3879c5a --- /dev/null +++ b/ruoyi-ui/src/components/ThemePicker/index.vue @@ -0,0 +1,175 @@ +<template> + <el-color-picker + v-model="theme" + :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" + class="theme-picker" + popper-class="theme-picker-dropdown" + /> +</template> + +<script> +const version = require('element-ui/package.json').version // element-ui version from node_modules +const ORIGINAL_THEME = '#409EFF' // default color + +export default { + data() { + return { + chalk: '', // content of theme-chalk css + theme: '' + } + }, + computed: { + defaultTheme() { + return this.$store.state.settings.theme + } + }, + watch: { + defaultTheme: { + handler: function(val, oldVal) { + this.theme = val + }, + immediate: true + }, + async theme(val) { + const oldVal = this.chalk ? this.theme : ORIGINAL_THEME + if (typeof val !== 'string') return + const themeCluster = this.getThemeCluster(val.replace('#', '')) + const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) + console.log(themeCluster, originalCluster) + + const $message = this.$message({ + message: ' Compiling the theme', + customClass: 'theme-message', + type: 'success', + duration: 0, + iconClass: 'el-icon-loading' + }) + + const getHandler = (variable, id) => { + return () => { + const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) + const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) + + let styleTag = document.getElementById(id) + if (!styleTag) { + styleTag = document.createElement('style') + styleTag.setAttribute('id', id) + document.head.appendChild(styleTag) + } + styleTag.innerText = newStyle + } + } + + if (!this.chalk) { + const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css` + await this.getCSSString(url, 'chalk') + } + + const chalkHandler = getHandler('chalk', 'chalk-style') + + chalkHandler() + + const styles = [].slice.call(document.querySelectorAll('style')) + .filter(style => { + const text = style.innerText + return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text) + }) + styles.forEach(style => { + const { innerText } = style + if (typeof innerText !== 'string') return + style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) + }) + + this.$emit('change', val) + + $message.close() + } + }, + + methods: { + updateStyle(style, oldCluster, newCluster) { + let newStyle = style + oldCluster.forEach((color, index) => { + newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) + }) + return newStyle + }, + + getCSSString(url, variable) { + return new Promise(resolve => { + const xhr = new XMLHttpRequest() + xhr.onreadystatechange = () => { + if (xhr.readyState === 4 && xhr.status === 200) { + this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') + resolve() + } + } + xhr.open('GET', url) + xhr.send() + }) + }, + + getThemeCluster(theme) { + const tintColor = (color, tint) => { + let red = parseInt(color.slice(0, 2), 16) + let green = parseInt(color.slice(2, 4), 16) + let blue = parseInt(color.slice(4, 6), 16) + + if (tint === 0) { // when primary color is in its rgb space + return [red, green, blue].join(',') + } else { + red += Math.round(tint * (255 - red)) + green += Math.round(tint * (255 - green)) + blue += Math.round(tint * (255 - blue)) + + red = red.toString(16) + green = green.toString(16) + blue = blue.toString(16) + + return `#${red}${green}${blue}` + } + } + + const shadeColor = (color, shade) => { + let red = parseInt(color.slice(0, 2), 16) + let green = parseInt(color.slice(2, 4), 16) + let blue = parseInt(color.slice(4, 6), 16) + + red = Math.round((1 - shade) * red) + green = Math.round((1 - shade) * green) + blue = Math.round((1 - shade) * blue) + + red = red.toString(16) + green = green.toString(16) + blue = blue.toString(16) + + return `#${red}${green}${blue}` + } + + const clusters = [theme] + for (let i = 0; i <= 9; i++) { + clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) + } + clusters.push(shadeColor(theme, 0.1)) + return clusters + } + } +} +</script> + +<style> +.theme-message, +.theme-picker-dropdown { + z-index: 99999 !important; +} + +.theme-picker .el-color-picker__trigger { + height: 26px !important; + width: 26px !important; + padding: 2px; +} + +.theme-picker-dropdown .el-color-dropdown__link-btn { + display: none; +} +</style> diff --git a/ruoyi-ui/src/directive/permission/hasPermi.js b/ruoyi-ui/src/directive/permission/hasPermi.js new file mode 100644 index 0000000..d7107ce --- /dev/null +++ b/ruoyi-ui/src/directive/permission/hasPermi.js @@ -0,0 +1,28 @@ + /** + * 鎿嶄綔鏉冮檺澶勭悊 + * Copyright (c) 2019 ruoyi + */ + +import store from '@/store' + +export default { + inserted(el, binding, vnode) { + const { value } = binding + const all_permission = "*:*:*"; + const permissions = store.getters && store.getters.permissions + + if (value && value instanceof Array && value.length > 0) { + const permissionFlag = value + + const hasPermissions = permissions.some(permission => { + return all_permission === permission || permissionFlag.includes(permission) + }) + + if (!hasPermissions) { + el.parentNode && el.parentNode.removeChild(el) + } + } else { + throw new Error(`璇疯缃搷浣滄潈闄愭爣绛惧�糮) + } + } +} diff --git a/ruoyi-ui/src/directive/permission/hasRole.js b/ruoyi-ui/src/directive/permission/hasRole.js new file mode 100644 index 0000000..1303809 --- /dev/null +++ b/ruoyi-ui/src/directive/permission/hasRole.js @@ -0,0 +1,28 @@ + /** + * 瑙掕壊鏉冮檺澶勭悊 + * Copyright (c) 2019 ruoyi + */ + +import store from '@/store' + +export default { + inserted(el, binding, vnode) { + const { value } = binding + const super_admin = "admin"; + const roles = store.getters && store.getters.roles + + if (value && value instanceof Array && value.length > 0) { + const roleFlag = value + + const hasRole = roles.some(role => { + return super_admin === role || roleFlag.includes(role) + }) + + if (!hasRole) { + el.parentNode && el.parentNode.removeChild(el) + } + } else { + throw new Error(`璇疯缃鑹叉潈闄愭爣绛惧��"`) + } + } +} diff --git a/ruoyi-ui/src/directive/permission/index.js b/ruoyi-ui/src/directive/permission/index.js new file mode 100644 index 0000000..e3d76d3 --- /dev/null +++ b/ruoyi-ui/src/directive/permission/index.js @@ -0,0 +1,15 @@ +import hasRole from './hasRole' +import hasPermi from './hasPermi' + +const install = function(Vue) { + Vue.directive('hasRole', hasRole) + Vue.directive('hasPermi', hasPermi) +} + +if (window.Vue) { + window['hasRole'] = hasRole + window['hasPermi'] = hasPermi + Vue.use(install); // eslint-disable-line +} + +export default install diff --git a/ruoyi-ui/src/layout/components/AppMain.vue b/ruoyi-ui/src/layout/components/AppMain.vue new file mode 100644 index 0000000..a897638 --- /dev/null +++ b/ruoyi-ui/src/layout/components/AppMain.vue @@ -0,0 +1,57 @@ +<template> + <section class="app-main"> + <transition name="fade-transform" mode="out-in"> + <keep-alive :include="cachedViews"> + <router-view :key="key" /> + </keep-alive> + </transition> + </section> +</template> + +<script> +export default { + name: 'AppMain', + computed: { + cachedViews() { + return this.$store.state.tagsView.cachedViews + }, + key() { + return this.$route.path + } + } +} +</script> + +<style lang="scss" scoped> +.app-main { + /* 50= navbar 50 */ + min-height: calc(100vh - 50px); + width: 100%; + position: relative; + overflow: hidden; +} + +.fixed-header+.app-main { + padding-top: 50px; +} + +.hasTagsView { + .app-main { + /* 84 = navbar + tags-view = 50 + 34 */ + min-height: calc(100vh - 84px); + } + + .fixed-header+.app-main { + padding-top: 84px; + } +} +</style> + +<style lang="scss"> +// fix css style bug in open el-dialog +.el-popup-parent--hidden { + .fixed-header { + padding-right: 15px; + } +} +</style> diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue new file mode 100644 index 0000000..123158b --- /dev/null +++ b/ruoyi-ui/src/layout/components/Navbar.vue @@ -0,0 +1,181 @@ +<template> + <div class="navbar"> + <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> + + <breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> + + <div class="right-menu"> + <template v-if="device!=='mobile'"> + <search id="header-search" class="right-menu-item" /> + + <el-tooltip content="涓嬭浇婧愮爜" effect="dark" placement="bottom"> + <ruo-yi id="ruoyi" class="right-menu-item hover-effect" /> + </el-tooltip> + + <screenfull id="screenfull" class="right-menu-item hover-effect" /> + + <el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom"> + <size-select id="size-select" class="right-menu-item hover-effect" /> + </el-tooltip> + + </template> + + <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> + <div class="avatar-wrapper"> + <img :src="avatar" class="user-avatar"> + <i class="el-icon-caret-bottom" /> + </div> + <el-dropdown-menu slot="dropdown"> + <router-link to="/user/profile"> + <el-dropdown-item>涓汉涓績</el-dropdown-item> + </router-link> + <el-dropdown-item> + <span @click="setting = true">甯冨眬璁剧疆</span> + </el-dropdown-item> + <el-dropdown-item divided> + <span @click="logout">閫�鍑虹櫥褰�</span> + </el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </div> + </div> +</template> + +<script> +import { mapGetters } from 'vuex' +import Breadcrumb from '@/components/Breadcrumb' +import Hamburger from '@/components/Hamburger' +import Screenfull from '@/components/Screenfull' +import SizeSelect from '@/components/SizeSelect' +import Search from '@/components/HeaderSearch' +import RuoYi from '@/components/RuoYi' + +export default { + components: { + Breadcrumb, + Hamburger, + Screenfull, + SizeSelect, + Search, + RuoYi + }, + computed: { + ...mapGetters([ + 'sidebar', + 'avatar', + 'device' + ]), + setting: { + get() { + return this.$store.state.settings.showSettings + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'showSettings', + value: val + }) + } + } + }, + methods: { + toggleSideBar() { + this.$store.dispatch('app/toggleSideBar') + }, + async logout() { + this.$confirm('纭畾娉ㄩ攢骞堕��鍑虹郴缁熷悧锛�', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + this.$store.dispatch('LogOut').then(() => { + location.reload() + }) + }) + } + } +} +</script> + +<style lang="scss" scoped> +.navbar { + height: 50px; + overflow: hidden; + position: relative; + background: #fff; + box-shadow: 0 1px 4px rgba(0,21,41,.08); + + .hamburger-container { + line-height: 46px; + height: 100%; + float: left; + cursor: pointer; + transition: background .3s; + -webkit-tap-highlight-color:transparent; + + &:hover { + background: rgba(0, 0, 0, .025) + } + } + + .breadcrumb-container { + float: left; + } + + .errLog-container { + display: inline-block; + vertical-align: top; + } + + .right-menu { + float: right; + height: 100%; + line-height: 50px; + + &:focus { + outline: none; + } + + .right-menu-item { + display: inline-block; + padding: 0 8px; + height: 100%; + font-size: 18px; + color: #5a5e66; + vertical-align: text-bottom; + + &.hover-effect { + cursor: pointer; + transition: background .3s; + + &:hover { + background: rgba(0, 0, 0, .025) + } + } + } + + .avatar-container { + margin-right: 30px; + + .avatar-wrapper { + margin-top: 5px; + position: relative; + + .user-avatar { + cursor: pointer; + width: 40px; + height: 40px; + border-radius: 10px; + } + + .el-icon-caret-bottom { + cursor: pointer; + position: absolute; + right: -20px; + top: 25px; + font-size: 12px; + } + } + } + } +} +</style> diff --git a/ruoyi-ui/src/layout/components/Settings/index.vue b/ruoyi-ui/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..90d99df --- /dev/null +++ b/ruoyi-ui/src/layout/components/Settings/index.vue @@ -0,0 +1,108 @@ +<template> + <div class="drawer-container"> + <div> + <h3 class="drawer-title">绯荤粺甯冨眬閰嶇疆</h3> + + <div class="drawer-item"> + <span>涓婚棰滆壊</span> + <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" /> + </div> + + <div class="drawer-item"> + <span>寮�鍚� Tags-Views</span> + <el-switch v-model="tagsView" class="drawer-switch" /> + </div> + + <div class="drawer-item"> + <span>鍥哄畾 Header</span> + <el-switch v-model="fixedHeader" class="drawer-switch" /> + </div> + + <div class="drawer-item"> + <span>鏄剧ず Logo</span> + <el-switch v-model="sidebarLogo" class="drawer-switch" /> + </div> + + </div> + </div> +</template> + +<script> +import ThemePicker from '@/components/ThemePicker' + +export default { + components: { ThemePicker }, + data() { + return {} + }, + computed: { + fixedHeader: { + get() { + return this.$store.state.settings.fixedHeader + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'fixedHeader', + value: val + }) + } + }, + tagsView: { + get() { + return this.$store.state.settings.tagsView + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'tagsView', + value: val + }) + } + }, + sidebarLogo: { + get() { + return this.$store.state.settings.sidebarLogo + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'sidebarLogo', + value: val + }) + } + }, + }, + methods: { + themeChange(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'theme', + value: val + }) + } + } +} +</script> + +<style lang="scss" scoped> +.drawer-container { + padding: 24px; + font-size: 14px; + line-height: 1.5; + word-wrap: break-word; + + .drawer-title { + margin-bottom: 12px; + color: rgba(0, 0, 0, .85); + font-size: 14px; + line-height: 22px; + } + + .drawer-item { + color: rgba(0, 0, 0, .65); + font-size: 14px; + padding: 12px 0; + } + + .drawer-switch { + float: right + } +} +</style> diff --git a/ruoyi-ui/src/layout/components/Sidebar/FixiOSBug.js b/ruoyi-ui/src/layout/components/Sidebar/FixiOSBug.js new file mode 100644 index 0000000..6823726 --- /dev/null +++ b/ruoyi-ui/src/layout/components/Sidebar/FixiOSBug.js @@ -0,0 +1,25 @@ +export default { + computed: { + device() { + return this.$store.state.app.device + } + }, + mounted() { + // In order to fix the click on menu on the ios device will trigger the mouseleave bug + this.fixBugIniOS() + }, + methods: { + fixBugIniOS() { + const $subMenu = this.$refs.subMenu + if ($subMenu) { + const handleMouseleave = $subMenu.handleMouseleave + $subMenu.handleMouseleave = (e) => { + if (this.device === 'mobile') { + return + } + handleMouseleave(e) + } + } + } + } +} diff --git a/ruoyi-ui/src/layout/components/Sidebar/Item.vue b/ruoyi-ui/src/layout/components/Sidebar/Item.vue new file mode 100644 index 0000000..b515f61 --- /dev/null +++ b/ruoyi-ui/src/layout/components/Sidebar/Item.vue @@ -0,0 +1,29 @@ +<script> +export default { + name: 'MenuItem', + functional: true, + props: { + icon: { + type: String, + default: '' + }, + title: { + type: String, + default: '' + } + }, + render(h, context) { + const { icon, title } = context.props + const vnodes = [] + + if (icon) { + vnodes.push(<svg-icon icon-class={icon}/>) + } + + if (title) { + vnodes.push(<span slot='title'>{(title)}</span>) + } + return vnodes + } +} +</script> diff --git a/ruoyi-ui/src/layout/components/Sidebar/Link.vue b/ruoyi-ui/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..eb4dd10 --- /dev/null +++ b/ruoyi-ui/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,36 @@ + +<template> + <!-- eslint-disable vue/require-component-is --> + <component v-bind="linkProps(to)"> + <slot /> + </component> +</template> + +<script> +import { isExternal } from '@/utils/validate' + +export default { + props: { + to: { + type: String, + required: true + } + }, + methods: { + linkProps(url) { + if (isExternal(url)) { + return { + is: 'a', + href: url, + target: '_blank', + rel: 'noopener' + } + } + return { + is: 'router-link', + to: url + } + } + } +} +</script> diff --git a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..410d432 --- /dev/null +++ b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,84 @@ +<template> + <div class="sidebar-logo-container" :class="{'collapse':collapse}"> + <transition name="sidebarLogoFade"> + <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> + <img v-if="logo" :src="logo" class="sidebar-logo"> + <h1 v-else class="sidebar-title">{{ title }} </h1> + </router-link> + <router-link v-else key="expand" class="sidebar-logo-link" to="/"> + <img v-if="logo" :src="logo" class="sidebar-logo"> + <h1 class="sidebar-title">{{ title }} </h1> + </router-link> + </transition> + </div> +</template> + +<script> +import logoImg from '@/assets/logo/logo.png' + +export default { + name: 'SidebarLogo', + props: { + collapse: { + type: Boolean, + required: true + } + }, + data() { + return { + title: '鑻ヤ緷绠$悊绯荤粺', + logo: logoImg + } + } +} +</script> + +<style lang="scss" scoped> +.sidebarLogoFade-enter-active { + transition: opacity 1.5s; +} + +.sidebarLogoFade-enter, +.sidebarLogoFade-leave-to { + opacity: 0; +} + +.sidebar-logo-container { + position: relative; + width: 100%; + height: 50px; + line-height: 50px; + background: #2b2f3a; + text-align: center; + overflow: hidden; + + & .sidebar-logo-link { + height: 100%; + width: 100%; + + & .sidebar-logo { + width: 32px; + height: 32px; + vertical-align: middle; + margin-right: 12px; + } + + & .sidebar-title { + display: inline-block; + margin: 0; + color: #fff; + font-weight: 600; + line-height: 50px; + font-size: 14px; + font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; + vertical-align: middle; + } + } + + &.collapse { + .sidebar-logo { + margin-right: 0px; + } + } +} +</style> diff --git a/ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue b/ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..cd21d81 --- /dev/null +++ b/ruoyi-ui/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,93 @@ +<template> + <div v-if="!item.hidden" class="menu-wrapper"> + <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> + <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> + <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> + <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> + </el-menu-item> + </app-link> + </template> + + <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> + <template slot="title"> + <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> + </template> + <sidebar-item + v-for="child in item.children" + :key="child.path" + :is-nest="true" + :item="child" + :base-path="resolvePath(child.path)" + class="nest-menu" + /> + </el-submenu> + </div> +</template> + +<script> +import path from 'path' +import { isExternal } from '@/utils/validate' +import Item from './Item' +import AppLink from './Link' +import FixiOSBug from './FixiOSBug' + +export default { + name: 'SidebarItem', + components: { Item, AppLink }, + mixins: [FixiOSBug], + props: { + // route object + item: { + type: Object, + required: true + }, + isNest: { + type: Boolean, + default: false + }, + basePath: { + type: String, + default: '' + } + }, + data() { + this.onlyOneChild = null + return {} + }, + methods: { + hasOneShowingChild(children = [], parent) { + const showingChildren = children.filter(item => { + if (item.hidden) { + return false + } else { + // Temp set(will be used if only has one showing child) + this.onlyOneChild = item + return true + } + }) + + // When there is only one child router, the child router is displayed by default + if (showingChildren.length === 1) { + return true + } + + // Show parent if there are no child router to display + if (showingChildren.length === 0) { + this.onlyOneChild = { ... parent, path: '', noShowingChildren: true } + return true + } + + return false + }, + resolvePath(routePath) { + if (isExternal(routePath)) { + return routePath + } + if (isExternal(this.basePath)) { + return this.basePath + } + return path.resolve(this.basePath, routePath) + } + } +} +</script> diff --git a/ruoyi-ui/src/layout/components/Sidebar/index.vue b/ruoyi-ui/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..476e45b --- /dev/null +++ b/ruoyi-ui/src/layout/components/Sidebar/index.vue @@ -0,0 +1,54 @@ +<template> + <div :class="{'has-logo':showLogo}"> + <logo v-if="showLogo" :collapse="isCollapse" /> + <el-scrollbar wrap-class="scrollbar-wrapper"> + <el-menu + :default-active="activeMenu" + :collapse="isCollapse" + :background-color="variables.menuBg" + :text-color="variables.menuText" + :unique-opened="true" + :active-text-color="variables.menuActiveText" + :collapse-transition="false" + mode="vertical" + > + <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" /> + </el-menu> + </el-scrollbar> + </div> +</template> + +<script> +import { mapGetters } from 'vuex' +import Logo from './Logo' +import SidebarItem from './SidebarItem' +import variables from '@/assets/styles/variables.scss' + +export default { + components: { SidebarItem, Logo }, + computed: { + ...mapGetters([ + 'permission_routes', + 'sidebar' + ]), + activeMenu() { + const route = this.$route + const { meta, path } = route + // if set path, the sidebar will highlight the path you set + if (meta.activeMenu) { + return meta.activeMenu + } + return path + }, + showLogo() { + return this.$store.state.settings.sidebarLogo + }, + variables() { + return variables + }, + isCollapse() { + return !this.sidebar.opened + } + } +} +</script> diff --git a/ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue b/ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..0ec76e7 --- /dev/null +++ b/ruoyi-ui/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,85 @@ +<template> + <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll"> + <slot /> + </el-scrollbar> +</template> + +<script> +const tagAndTagSpacing = 4 // tagAndTagSpacing + +export default { + name: 'ScrollPane', + data() { + return { + left: 0 + } + }, + computed: { + scrollWrapper() { + return this.$refs.scrollContainer.$refs.wrap + } + }, + methods: { + handleScroll(e) { + const eventDelta = e.wheelDelta || -e.deltaY * 40 + const $scrollWrapper = this.scrollWrapper + $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 + }, + moveToTarget(currentTag) { + const $container = this.$refs.scrollContainer.$el + const $containerWidth = $container.offsetWidth + const $scrollWrapper = this.scrollWrapper + const tagList = this.$parent.$refs.tag + + let firstTag = null + let lastTag = null + + // find first tag and last tag + if (tagList.length > 0) { + firstTag = tagList[0] + lastTag = tagList[tagList.length - 1] + } + + if (firstTag === currentTag) { + $scrollWrapper.scrollLeft = 0 + } else if (lastTag === currentTag) { + $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth + } else { + // find preTag and nextTag + const currentIndex = tagList.findIndex(item => item === currentTag) + const prevTag = tagList[currentIndex - 1] + const nextTag = tagList[currentIndex + 1] + + // the tag's offsetLeft after of nextTag + const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing + + // the tag's offsetLeft before of prevTag + const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing + + if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { + $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth + } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { + $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft + } + } + } + } +} +</script> + +<style lang="scss" scoped> +.scroll-container { + white-space: nowrap; + position: relative; + overflow: hidden; + width: 100%; + /deep/ { + .el-scrollbar__bar { + bottom: 0px; + } + .el-scrollbar__wrap { + height: 49px; + } + } +} +</style> diff --git a/ruoyi-ui/src/layout/components/TagsView/index.vue b/ruoyi-ui/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..ea272dc --- /dev/null +++ b/ruoyi-ui/src/layout/components/TagsView/index.vue @@ -0,0 +1,286 @@ +<template> + <div id="tags-view-container" class="tags-view-container"> + <scroll-pane ref="scrollPane" class="tags-view-wrapper"> + <router-link + v-for="tag in visitedViews" + ref="tag" + :key="tag.path" + :class="isActive(tag)?'active':''" + :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" + tag="span" + class="tags-view-item" + @click.middle.native="closeSelectedTag(tag)" + @contextmenu.prevent.native="openMenu(tag,$event)" + > + {{ tag.title }} + <span v-if="!tag.meta.affix" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> + </router-link> + </scroll-pane> + <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> + <li @click="refreshSelectedTag(selectedTag)">鍒锋柊椤甸潰</li> + <li v-if="!(selectedTag.meta&&selectedTag.meta.affix)" @click="closeSelectedTag(selectedTag)">鍏抽棴褰撳墠</li> + <li @click="closeOthersTags">鍏抽棴鍏朵粬</li> + <li @click="closeAllTags(selectedTag)">鍏抽棴鎵�鏈�</li> + </ul> + </div> +</template> + +<script> +import ScrollPane from './ScrollPane' +import path from 'path' + +export default { + components: { ScrollPane }, + data() { + return { + visible: false, + top: 0, + left: 0, + selectedTag: {}, + affixTags: [] + } + }, + computed: { + visitedViews() { + return this.$store.state.tagsView.visitedViews + }, + routes() { + return this.$store.state.permission.routes + } + }, + watch: { + $route() { + this.addTags() + this.moveToCurrentTag() + }, + visible(value) { + if (value) { + document.body.addEventListener('click', this.closeMenu) + } else { + document.body.removeEventListener('click', this.closeMenu) + } + } + }, + mounted() { + this.initTags() + this.addTags() + }, + methods: { + isActive(route) { + return route.path === this.$route.path + }, + filterAffixTags(routes, basePath = '/') { + let tags = [] + routes.forEach(route => { + if (route.meta && route.meta.affix) { + const tagPath = path.resolve(basePath, route.path) + tags.push({ + fullPath: tagPath, + path: tagPath, + name: route.name, + meta: { ...route.meta } + }) + } + if (route.children) { + const tempTags = this.filterAffixTags(route.children, route.path) + if (tempTags.length >= 1) { + tags = [...tags, ...tempTags] + } + } + }) + return tags + }, + initTags() { + const affixTags = this.affixTags = this.filterAffixTags(this.routes) + for (const tag of affixTags) { + // Must have tag name + if (tag.name) { + this.$store.dispatch('tagsView/addVisitedView', tag) + } + } + }, + addTags() { + const { name } = this.$route + if (name) { + this.$store.dispatch('tagsView/addView', this.$route) + } + return false + }, + moveToCurrentTag() { + const tags = this.$refs.tag + this.$nextTick(() => { + for (const tag of tags) { + if (tag.to.path === this.$route.path) { + this.$refs.scrollPane.moveToTarget(tag) + // when query is different then update + if (tag.to.fullPath !== this.$route.fullPath) { + this.$store.dispatch('tagsView/updateVisitedView', this.$route) + } + break + } + } + }) + }, + refreshSelectedTag(view) { + this.$store.dispatch('tagsView/delCachedView', view).then(() => { + const { fullPath } = view + this.$nextTick(() => { + this.$router.replace({ + path: '/redirect' + fullPath + }) + }) + }) + }, + closeSelectedTag(view) { + this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { + if (this.isActive(view)) { + this.toLastView(visitedViews, view) + } + }) + }, + closeOthersTags() { + this.$router.push(this.selectedTag) + this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => { + this.moveToCurrentTag() + }) + }, + closeAllTags(view) { + this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => { + if (this.affixTags.some(tag => tag.path === view.path)) { + return + } + this.toLastView(visitedViews, view) + }) + }, + toLastView(visitedViews, view) { + const latestView = visitedViews.slice(-1)[0] + if (latestView) { + this.$router.push(latestView) + } else { + // now the default is to redirect to the home page if there is no tags-view, + // you can adjust it according to your needs. + if (view.name === 'Dashboard') { + // to reload home page + this.$router.replace({ path: '/redirect' + view.fullPath }) + } else { + this.$router.push('/') + } + } + }, + openMenu(tag, e) { + const menuMinWidth = 105 + const offsetLeft = this.$el.getBoundingClientRect().left // container margin left + const offsetWidth = this.$el.offsetWidth // container width + const maxLeft = offsetWidth - menuMinWidth // left boundary + const left = e.clientX - offsetLeft + 15 // 15: margin right + + if (left > maxLeft) { + this.left = maxLeft + } else { + this.left = left + } + + this.top = e.clientY + this.visible = true + this.selectedTag = tag + }, + closeMenu() { + this.visible = false + } + } +} +</script> + +<style lang="scss" scoped> +.tags-view-container { + height: 34px; + width: 100%; + background: #fff; + border-bottom: 1px solid #d8dce5; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04); + .tags-view-wrapper { + .tags-view-item { + display: inline-block; + position: relative; + cursor: pointer; + height: 26px; + line-height: 26px; + border: 1px solid #d8dce5; + color: #495060; + background: #fff; + padding: 0 8px; + font-size: 12px; + margin-left: 5px; + margin-top: 4px; + &:first-of-type { + margin-left: 15px; + } + &:last-of-type { + margin-right: 15px; + } + &.active { + background-color: #42b983; + color: #fff; + border-color: #42b983; + &::before { + content: ''; + background: #fff; + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + position: relative; + margin-right: 2px; + } + } + } + } + .contextmenu { + margin: 0; + background: #fff; + z-index: 3000; + position: absolute; + list-style-type: none; + padding: 5px 0; + border-radius: 4px; + font-size: 12px; + font-weight: 400; + color: #333; + box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); + li { + margin: 0; + padding: 7px 16px; + cursor: pointer; + &:hover { + background: #eee; + } + } + } +} +</style> + +<style lang="scss"> +//reset element css of el-icon-close +.tags-view-wrapper { + .tags-view-item { + .el-icon-close { + width: 16px; + height: 16px; + vertical-align: 2px; + border-radius: 50%; + text-align: center; + transition: all .3s cubic-bezier(.645, .045, .355, 1); + transform-origin: 100% 50%; + &:before { + transform: scale(.6); + display: inline-block; + vertical-align: -3px; + } + &:hover { + background-color: #b4bccc; + color: #fff; + } + } + } +} +</style> diff --git a/ruoyi-ui/src/layout/components/index.js b/ruoyi-ui/src/layout/components/index.js new file mode 100644 index 0000000..104bd3a --- /dev/null +++ b/ruoyi-ui/src/layout/components/index.js @@ -0,0 +1,5 @@ +export { default as AppMain } from './AppMain' +export { default as Navbar } from './Navbar' +export { default as Settings } from './Settings' +export { default as Sidebar } from './Sidebar/index.vue' +export { default as TagsView } from './TagsView/index.vue' diff --git a/ruoyi-ui/src/layout/index.vue b/ruoyi-ui/src/layout/index.vue new file mode 100644 index 0000000..889b7dc --- /dev/null +++ b/ruoyi-ui/src/layout/index.vue @@ -0,0 +1,102 @@ +<template> + <div :class="classObj" class="app-wrapper"> + <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> + <sidebar class="sidebar-container" /> + <div :class="{hasTagsView:needTagsView}" class="main-container"> + <div :class="{'fixed-header':fixedHeader}"> + <navbar /> + <tags-view v-if="needTagsView" /> + </div> + <app-main /> + <right-panel v-if="showSettings"> + <settings /> + </right-panel> + </div> + </div> +</template> + +<script> +import RightPanel from '@/components/RightPanel' +import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components' +import ResizeMixin from './mixin/ResizeHandler' +import { mapState } from 'vuex' + +export default { + name: 'Layout', + components: { + AppMain, + Navbar, + RightPanel, + Settings, + Sidebar, + TagsView + }, + mixins: [ResizeMixin], + computed: { + ...mapState({ + sidebar: state => state.app.sidebar, + device: state => state.app.device, + showSettings: state => state.settings.showSettings, + needTagsView: state => state.settings.tagsView, + fixedHeader: state => state.settings.fixedHeader + }), + classObj() { + return { + hideSidebar: !this.sidebar.opened, + openSidebar: this.sidebar.opened, + withoutAnimation: this.sidebar.withoutAnimation, + mobile: this.device === 'mobile' + } + } + }, + methods: { + handleClickOutside() { + this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) + } + } +} +</script> + +<style lang="scss" scoped> + @import "~@/assets/styles/mixin.scss"; + @import "~@/assets/styles/variables.scss"; + + .app-wrapper { + @include clearfix; + position: relative; + height: 100%; + width: 100%; + + &.mobile.openSidebar { + position: fixed; + top: 0; + } + } + + .drawer-bg { + background: #000; + opacity: 0.3; + width: 100%; + top: 0; + height: 100%; + position: absolute; + z-index: 999; + } + + .fixed-header { + position: fixed; + top: 0; + right: 0; + z-index: 9; + width: calc(100% - #{$sideBarWidth}); + transition: width 0.28s; + } + + .hideSidebar .fixed-header { + width: calc(100% - 54px) + } + + .mobile .fixed-header { + width: 100%; + } +</style> diff --git a/ruoyi-ui/src/layout/mixin/ResizeHandler.js b/ruoyi-ui/src/layout/mixin/ResizeHandler.js new file mode 100644 index 0000000..e8d0df8 --- /dev/null +++ b/ruoyi-ui/src/layout/mixin/ResizeHandler.js @@ -0,0 +1,45 @@ +import store from '@/store' + +const { body } = document +const WIDTH = 992 // refer to Bootstrap's responsive design + +export default { + watch: { + $route(route) { + if (this.device === 'mobile' && this.sidebar.opened) { + store.dispatch('app/closeSideBar', { withoutAnimation: false }) + } + } + }, + beforeMount() { + window.addEventListener('resize', this.$_resizeHandler) + }, + beforeDestroy() { + window.removeEventListener('resize', this.$_resizeHandler) + }, + mounted() { + const isMobile = this.$_isMobile() + if (isMobile) { + store.dispatch('app/toggleDevice', 'mobile') + store.dispatch('app/closeSideBar', { withoutAnimation: true }) + } + }, + methods: { + // use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + $_isMobile() { + const rect = body.getBoundingClientRect() + return rect.width - 1 < WIDTH + }, + $_resizeHandler() { + if (!document.hidden) { + const isMobile = this.$_isMobile() + store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') + + if (isMobile) { + store.dispatch('app/closeSideBar', { withoutAnimation: true }) + } + } + } + } +} diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js new file mode 100644 index 0000000..111f7ef --- /dev/null +++ b/ruoyi-ui/src/main.js @@ -0,0 +1,70 @@ +import Vue from 'vue' + +import Cookies from 'js-cookie' + +import 'normalize.css/normalize.css' // a modern alternative to CSS resets + +import Element from 'element-ui' +import './assets/styles/element-variables.scss' + +import '@/assets/styles/index.scss' // global css +import '@/assets/styles/ruoyi.scss' // ruoyi css +import App from './App' +import store from './store' +import router from './router' +import permission from './directive/permission' + +import './assets/icons' // icon +import './permission' // permission control +import { getDicts } from "@/api/system/dict/data"; +import { getConfigKey } from "@/api/system/config"; +import { parseTime, resetForm, addDateRange, selectDictLabel, download } from "@/utils/ruoyi"; +import Pagination from "@/components/Pagination"; + +// 鍏ㄥ眬鏂规硶鎸傝浇 +Vue.prototype.getDicts = getDicts +Vue.prototype.getConfigKey = getConfigKey +Vue.prototype.parseTime = parseTime +Vue.prototype.resetForm = resetForm +Vue.prototype.addDateRange = addDateRange +Vue.prototype.selectDictLabel = selectDictLabel +Vue.prototype.download = download + +Vue.prototype.msgSuccess = function (msg) { + this.$message({ showClose: true, message: msg, type: "success" }); +} + +Vue.prototype.msgError = function (msg) { + this.$message({ showClose: true, message: msg, type: "error" }); +} + +Vue.prototype.msgInfo = function (msg) { + this.$message.info(msg); +} + +// 鍏ㄥ眬缁勪欢鎸傝浇 +Vue.component('Pagination', Pagination) + +Vue.use(permission) + +/** + * If you don't want to use mock-server + * you want to use MockJs for mock api + * you can execute: mockXHR() + * + * Currently MockJs will be used in the production environment, + * please remove it before going online! ! ! + */ + +Vue.use(Element, { + size: Cookies.get('size') || 'medium' // set element-ui default size +}) + +Vue.config.productionTip = false + +new Vue({ + el: '#app', + router, + store, + render: h => h(App) +}) diff --git a/ruoyi-ui/src/permission.js b/ruoyi-ui/src/permission.js new file mode 100644 index 0000000..d4f6ae4 --- /dev/null +++ b/ruoyi-ui/src/permission.js @@ -0,0 +1,64 @@ +import router from './router' +import store from './store' +import { Message } from 'element-ui' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/auth-redirect', '/bind', '/register'] + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else { + if (store.getters.roles.length === 0) { + // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁宸叉媺鍙栧畬user_info淇℃伅 + store.dispatch('GetInfo').then(res => { + // 鎷夊彇user_info + const roles = res.roles + store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { + // 娴嬭瘯 榛樿闈欐�侀〉闈� + // store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => { + // 鏍规嵁roles鏉冮檺鐢熸垚鍙闂殑璺敱琛� + router.addRoutes(accessRoutes) // 鍔ㄦ�佹坊鍔犲彲璁块棶璺敱琛� + next({ ...to, replace: true }) // hack鏂规硶 纭繚addRoutes宸插畬鎴� + }) + }) + .catch(err => { + store.dispatch('FedLogOut').then(() => { + Message.error(err) + next({ path: '/' }) + }) + }) + } else { + next() + // 娌℃湁鍔ㄦ�佹敼鍙樻潈闄愮殑闇�姹傚彲鐩存帴next() 鍒犻櫎涓嬫柟鏉冮檺鍒ゆ柇 鈫� + // if (hasPermission(store.getters.roles, to.meta.roles)) { + // next() + // } else { + // next({ path: '/401', replace: true, query: { noGoBack: true }}) + // } + // 鍙垹 鈫� + } + } + } else { + // 娌℃湁token + if (whiteList.indexOf(to.path) !== -1) { + // 鍦ㄥ厤鐧诲綍鐧藉悕鍗曪紝鐩存帴杩涘叆 + next() + } else { + next(`/login?redirect=${to.path}`) // 鍚﹀垯鍏ㄩ儴閲嶅畾鍚戝埌鐧诲綍椤� + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js new file mode 100644 index 0000000..dba21e4 --- /dev/null +++ b/ruoyi-ui/src/router/index.js @@ -0,0 +1,114 @@ +import Vue from 'vue' +import Router from 'vue-router' + +Vue.use(Router) + +/* Layout */ +import Layout from '@/layout' + +/** + * Note: 璺敱閰嶇疆椤� + * + * hidden: true // 褰撹缃� true 鐨勬椂鍊欒璺敱涓嶄細鍐嶄晶杈规爮鍑虹幇 濡�401锛宭ogin绛夐〉闈紝鎴栬�呭涓�浜涚紪杈戦〉闈�/edit/1 + * alwaysShow: true // 褰撲綘涓�涓矾鐢变笅闈㈢殑 children 澹版槑鐨勮矾鐢卞ぇ浜�1涓椂锛岃嚜鍔ㄤ細鍙樻垚宓屽鐨勬ā寮�--濡傜粍浠堕〉闈� + * // 鍙湁涓�涓椂锛屼細灏嗛偅涓瓙璺敱褰撳仛鏍硅矾鐢辨樉绀哄湪渚ц竟鏍�--濡傚紩瀵奸〉闈� + * // 鑻ヤ綘鎯充笉绠¤矾鐢变笅闈㈢殑 children 澹版槑鐨勪釜鏁伴兘鏄剧ず浣犵殑鏍硅矾鐢� + * // 浣犲彲浠ヨ缃� alwaysShow: true锛岃繖鏍峰畠灏变細蹇界暐涔嬪墠瀹氫箟鐨勮鍒欙紝涓�鐩存樉绀烘牴璺敱 + * redirect: noRedirect // 褰撹缃� noRedirect 鐨勬椂鍊欒璺敱鍦ㄩ潰鍖呭睉瀵艰埅涓笉鍙鐐瑰嚮 + * name:'router-name' // 璁惧畾璺敱鐨勫悕瀛楋紝涓�瀹氳濉啓涓嶇劧浣跨敤<keep-alive>鏃朵細鍑虹幇鍚勭闂 + * meta : { + roles: ['admin','editor'] // 璁剧疆璇ヨ矾鐢辫繘鍏ョ殑鏉冮檺锛屾敮鎸佸涓潈闄愬彔鍔� + title: 'title' // 璁剧疆璇ヨ矾鐢卞湪渚ц竟鏍忓拰闈㈠寘灞戜腑灞曠ず鐨勫悕瀛� + icon: 'svg-name' // 璁剧疆璇ヨ矾鐢辩殑鍥炬爣锛屽搴旇矾寰剆rc/icons/svg + breadcrumb: false // 濡傛灉璁剧疆涓篺alse锛屽垯涓嶄細鍦╞readcrumb闈㈠寘灞戜腑鏄剧ず + } + */ + +// 鍏叡璺敱 +export const constantRoutes = [ + { + path: '/redirect', + component: Layout, + hidden: true, + children: [ + { + path: '/redirect/:path*', + component: () => import('@/views/redirect') + } + ] + }, + { + path: '/login', + component: () => import('@/views/login'), + hidden: true + }, + { + path: '/404', + component: () => import('@/views/error/404'), + hidden: true + }, + { + path: '/401', + component: () => import('@/views/error/401'), + hidden: true + }, + { + path: '', + component: Layout, + redirect: 'index', + children: [ + { + path: 'index', + component: () => import('@/views/index'), + name: '棣栭〉', + meta: { title: '棣栭〉', icon: 'dashboard', noCache: true, affix: true } + } + ] + }, + { + path: '/user', + component: Layout, + hidden: true, + redirect: 'noredirect', + children: [ + { + path: 'profile', + component: () => import('@/views/system/user/profile/index'), + name: 'Profile', + meta: { title: '涓汉涓績', icon: 'user' } + } + ] + }, + { + path: '/dict', + component: Layout, + hidden: true, + children: [ + { + path: 'type/data/:dictId(\\d+)', + component: () => import('@/views/system/dict/data'), + name: 'Data', + meta: { title: '瀛楀吀鏁版嵁', icon: '' } + } + ] + }, + { + path: '/gen', + component: Layout, + hidden: true, + children: [ + { + path: 'edit', + component: () => import('@/views/tool/gen/editTable'), + name: 'GenEdit', + meta: { title: '淇敼鐢熸垚閰嶇疆' } + } + ] + } +] + +export default new Router({ + mode: 'history', // 鍘绘帀url涓殑# + scrollBehavior: () => ({ y: 0 }), + routes: constantRoutes +}) diff --git a/ruoyi-ui/src/settings.js b/ruoyi-ui/src/settings.js new file mode 100644 index 0000000..6edb05b --- /dev/null +++ b/ruoyi-ui/src/settings.js @@ -0,0 +1,31 @@ +module.exports = { + title: '鑻ヤ緷绠$悊绯荤粺', + + /** + * 鏄惁绯荤粺甯冨眬閰嶇疆 + */ + showSettings: false, + + /** + * 鏄惁鏄剧ず tagsView + */ + tagsView: true, + + /** + * 鏄惁鍥哄畾澶撮儴 + */ + fixedHeader: false, + + /** + * 鏄惁鏄剧ずlogo + */ + sidebarLogo: true, + + /** + * @type {string | array} 'production' | ['production', 'development'] + * @description Need show err logs component. + * The default is only used in the production env + * If you want to also use it in dev, you can pass ['production', 'development'] + */ + errorLog: 'production' +} diff --git a/ruoyi-ui/src/store/getters.js b/ruoyi-ui/src/store/getters.js new file mode 100644 index 0000000..df51465 --- /dev/null +++ b/ruoyi-ui/src/store/getters.js @@ -0,0 +1,15 @@ +const getters = { + sidebar: state => state.app.sidebar, + size: state => state.app.size, + device: state => state.app.device, + visitedViews: state => state.tagsView.visitedViews, + cachedViews: state => state.tagsView.cachedViews, + token: state => state.user.token, + avatar: state => state.user.avatar, + name: state => state.user.name, + introduction: state => state.user.introduction, + roles: state => state.user.roles, + permissions: state => state.user.permissions, + permission_routes: state => state.permission.routes +} +export default getters diff --git a/ruoyi-ui/src/store/index.js b/ruoyi-ui/src/store/index.js new file mode 100644 index 0000000..53b8437 --- /dev/null +++ b/ruoyi-ui/src/store/index.js @@ -0,0 +1,23 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import app from './modules/app' +import user from './modules/user' +import tagsView from './modules/tagsView' +import permission from './modules/permission' +import settings from './modules/settings' +import getters from './getters' + +Vue.use(Vuex) + +const store = new Vuex.Store({ + modules: { + app, + user, + tagsView, + permission, + settings + }, + getters +}) + +export default store diff --git a/ruoyi-ui/src/store/modules/app.js b/ruoyi-ui/src/store/modules/app.js new file mode 100644 index 0000000..45d89bb --- /dev/null +++ b/ruoyi-ui/src/store/modules/app.js @@ -0,0 +1,56 @@ +import Cookies from 'js-cookie' + +const state = { + sidebar: { + opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, + withoutAnimation: false + }, + device: 'desktop', + size: Cookies.get('size') || 'medium' +} + +const mutations = { + TOGGLE_SIDEBAR: state => { + state.sidebar.opened = !state.sidebar.opened + state.sidebar.withoutAnimation = false + if (state.sidebar.opened) { + Cookies.set('sidebarStatus', 1) + } else { + Cookies.set('sidebarStatus', 0) + } + }, + CLOSE_SIDEBAR: (state, withoutAnimation) => { + Cookies.set('sidebarStatus', 0) + state.sidebar.opened = false + state.sidebar.withoutAnimation = withoutAnimation + }, + TOGGLE_DEVICE: (state, device) => { + state.device = device + }, + SET_SIZE: (state, size) => { + state.size = size + Cookies.set('size', size) + } +} + +const actions = { + toggleSideBar({ commit }) { + commit('TOGGLE_SIDEBAR') + }, + closeSideBar({ commit }, { withoutAnimation }) { + commit('CLOSE_SIDEBAR', withoutAnimation) + }, + toggleDevice({ commit }, device) { + commit('TOGGLE_DEVICE', device) + }, + setSize({ commit }, size) { + commit('SET_SIZE', size) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/ruoyi-ui/src/store/modules/permission.js b/ruoyi-ui/src/store/modules/permission.js new file mode 100644 index 0000000..df319e9 --- /dev/null +++ b/ruoyi-ui/src/store/modules/permission.js @@ -0,0 +1,54 @@ +import { constantRoutes } from '@/router' +import { getRouters } from '@/api/menu' +import Layout from '@/layout/index' + +const permission = { + state: { + routes: [], + addRoutes: [] + }, + mutations: { + SET_ROUTES: (state, routes) => { + state.addRoutes = routes + state.routes = constantRoutes.concat(routes) + } + }, + actions: { + // 鐢熸垚璺敱 + GenerateRoutes({ commit }) { + return new Promise(resolve => { + // 鍚戝悗绔姹傝矾鐢辨暟鎹� + getRouters().then(res => { + const accessedRoutes = filterAsyncRouter(res.data) + accessedRoutes.push({ path: '*', redirect: '/404', hidden: true }) + commit('SET_ROUTES', accessedRoutes) + resolve(accessedRoutes) + }) + }) + } + } +} + +// 閬嶅巻鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆锛岃浆鎹负缁勪欢瀵硅薄 +function filterAsyncRouter(asyncRouterMap) { + return asyncRouterMap.filter(route => { + if (route.component) { + // Layout缁勪欢鐗规畩澶勭悊 + if (route.component === 'Layout') { + route.component = Layout + } else { + route.component = loadView(route.component) + } + } + if (route.children != null && route.children && route.children.length) { + route.children = filterAsyncRouter(route.children) + } + return true + }) +} + +export const loadView = (view) => { // 璺敱鎳掑姞杞� + return () => import(`@/views/${view}`) +} + +export default permission diff --git a/ruoyi-ui/src/store/modules/settings.js b/ruoyi-ui/src/store/modules/settings.js new file mode 100644 index 0000000..a1152a9 --- /dev/null +++ b/ruoyi-ui/src/store/modules/settings.js @@ -0,0 +1,34 @@ +import variables from '@/assets/styles/element-variables.scss' +import defaultSettings from '@/settings' + +const { showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings + +const state = { + theme: variables.theme, + showSettings: showSettings, + tagsView: tagsView, + fixedHeader: fixedHeader, + sidebarLogo: sidebarLogo +} + +const mutations = { + CHANGE_SETTING: (state, { key, value }) => { + if (state.hasOwnProperty(key)) { + state[key] = value + } + } +} + +const actions = { + changeSetting({ commit }, data) { + commit('CHANGE_SETTING', data) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/ruoyi-ui/src/store/modules/tagsView.js b/ruoyi-ui/src/store/modules/tagsView.js new file mode 100644 index 0000000..3e2c170 --- /dev/null +++ b/ruoyi-ui/src/store/modules/tagsView.js @@ -0,0 +1,165 @@ +const state = { + visitedViews: [], + cachedViews: [] +} + +const mutations = { + ADD_VISITED_VIEW: (state, view) => { + if (state.visitedViews.some(v => v.path === view.path)) return + state.visitedViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + ADD_CACHED_VIEW: (state, view) => { + if (state.cachedViews.includes(view.name)) return + if (!view.meta.noCache) { + state.cachedViews.push(view.name) + } + }, + + DEL_VISITED_VIEW: (state, view) => { + for (const [i, v] of state.visitedViews.entries()) { + if (v.path === view.path) { + state.visitedViews.splice(i, 1) + break + } + } + }, + DEL_CACHED_VIEW: (state, view) => { + for (const i of state.cachedViews) { + if (i === view.name) { + const index = state.cachedViews.indexOf(i) + state.cachedViews.splice(index, 1) + break + } + } + }, + + DEL_OTHERS_VISITED_VIEWS: (state, view) => { + state.visitedViews = state.visitedViews.filter(v => { + return v.meta.affix || v.path === view.path + }) + }, + DEL_OTHERS_CACHED_VIEWS: (state, view) => { + for (const i of state.cachedViews) { + if (i === view.name) { + const index = state.cachedViews.indexOf(i) + state.cachedViews = state.cachedViews.slice(index, index + 1) + break + } + } + }, + + DEL_ALL_VISITED_VIEWS: state => { + // keep affix tags + const affixTags = state.visitedViews.filter(tag => tag.meta.affix) + state.visitedViews = affixTags + }, + DEL_ALL_CACHED_VIEWS: state => { + state.cachedViews = [] + }, + + UPDATE_VISITED_VIEW: (state, view) => { + for (let v of state.visitedViews) { + if (v.path === view.path) { + v = Object.assign(v, view) + break + } + } + } +} + +const actions = { + addView({ dispatch }, view) { + dispatch('addVisitedView', view) + dispatch('addCachedView', view) + }, + addVisitedView({ commit }, view) { + commit('ADD_VISITED_VIEW', view) + }, + addCachedView({ commit }, view) { + commit('ADD_CACHED_VIEW', view) + }, + + delView({ dispatch, state }, view) { + return new Promise(resolve => { + dispatch('delVisitedView', view) + dispatch('delCachedView', view) + resolve({ + visitedViews: [...state.visitedViews], + cachedViews: [...state.cachedViews] + }) + }) + }, + delVisitedView({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_VISITED_VIEW', view) + resolve([...state.visitedViews]) + }) + }, + delCachedView({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_CACHED_VIEW', view) + resolve([...state.cachedViews]) + }) + }, + + delOthersViews({ dispatch, state }, view) { + return new Promise(resolve => { + dispatch('delOthersVisitedViews', view) + dispatch('delOthersCachedViews', view) + resolve({ + visitedViews: [...state.visitedViews], + cachedViews: [...state.cachedViews] + }) + }) + }, + delOthersVisitedViews({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_OTHERS_VISITED_VIEWS', view) + resolve([...state.visitedViews]) + }) + }, + delOthersCachedViews({ commit, state }, view) { + return new Promise(resolve => { + commit('DEL_OTHERS_CACHED_VIEWS', view) + resolve([...state.cachedViews]) + }) + }, + + delAllViews({ dispatch, state }, view) { + return new Promise(resolve => { + dispatch('delAllVisitedViews', view) + dispatch('delAllCachedViews', view) + resolve({ + visitedViews: [...state.visitedViews], + cachedViews: [...state.cachedViews] + }) + }) + }, + delAllVisitedViews({ commit, state }) { + return new Promise(resolve => { + commit('DEL_ALL_VISITED_VIEWS') + resolve([...state.visitedViews]) + }) + }, + delAllCachedViews({ commit, state }) { + return new Promise(resolve => { + commit('DEL_ALL_CACHED_VIEWS') + resolve([...state.cachedViews]) + }) + }, + + updateVisitedView({ commit }, view) { + commit('UPDATE_VISITED_VIEW', view) + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} diff --git a/ruoyi-ui/src/store/modules/user.js b/ruoyi-ui/src/store/modules/user.js new file mode 100644 index 0000000..2e77452 --- /dev/null +++ b/ruoyi-ui/src/store/modules/user.js @@ -0,0 +1,96 @@ +import { login, logout, getInfo } from '@/api/login' +import { getToken, setToken, removeToken } from '@/utils/auth' + +const user = { + state: { + token: getToken(), + name: '', + avatar: '', + roles: [], + permissions: [] + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + SET_NAME: (state, name) => { + state.name = name + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar + }, + SET_ROLES: (state, roles) => { + state.roles = roles + }, + SET_PERMISSIONS: (state, permissions) => { + state.permissions = permissions + } + }, + + actions: { + // 鐧诲綍 + Login({ commit }, userInfo) { + const username = userInfo.username.trim() + const password = userInfo.password + const code = userInfo.code + const uuid = userInfo.uuid + return new Promise((resolve, reject) => { + login(username, password, code, uuid).then(res => { + setToken(res.token) + commit('SET_TOKEN', res.token) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 鑾峰彇鐢ㄦ埛淇℃伅 + GetInfo({ commit, state }) { + return new Promise((resolve, reject) => { + getInfo(state.token).then(res => { + const user = res.user + const avatar = user.avatar == "" ? require("@/assets/image/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; + if (res.roles && res.roles.length > 0) { // 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁� + commit('SET_ROLES', res.roles) + commit('SET_PERMISSIONS', res.permissions) + } else { + commit('SET_ROLES', ['ROLE_DEFAULT']) + } + commit('SET_NAME', user.username) + commit('SET_AVATAR', avatar) + resolve(res) + }).catch(error => { + reject(error) + }) + }) + }, + + // 閫�鍑虹郴缁� + LogOut({ commit, state }) { + return new Promise((resolve, reject) => { + logout(state.token).then(() => { + commit('SET_TOKEN', '') + commit('SET_ROLES', []) + commit('SET_PERMISSIONS', []) + removeToken() + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 鍓嶇 鐧诲嚭 + FedLogOut({ commit }) { + return new Promise(resolve => { + commit('SET_TOKEN', '') + removeToken() + resolve() + }) + } + } +} + +export default user diff --git a/ruoyi-ui/src/utils/auth.js b/ruoyi-ui/src/utils/auth.js new file mode 100644 index 0000000..08a43d6 --- /dev/null +++ b/ruoyi-ui/src/utils/auth.js @@ -0,0 +1,15 @@ +import Cookies from 'js-cookie' + +const TokenKey = 'Admin-Token' + +export function getToken() { + return Cookies.get(TokenKey) +} + +export function setToken(token) { + return Cookies.set(TokenKey, token) +} + +export function removeToken() { + return Cookies.remove(TokenKey) +} diff --git a/ruoyi-ui/src/utils/index.js b/ruoyi-ui/src/utils/index.js new file mode 100644 index 0000000..04299a9 --- /dev/null +++ b/ruoyi-ui/src/utils/index.js @@ -0,0 +1,317 @@ +/** + * 琛ㄦ牸鏃堕棿鏍煎紡鍖� + */ +export function formatDate(cellValue) { + if (cellValue == null || cellValue == "") return ""; + var date = new Date(cellValue) + var year = date.getFullYear() + var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 + var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() + var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() + var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() + return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds +} + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export function formatTime(time, option) { + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '鍒氬垰' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '鍒嗛挓鍓�' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '灏忔椂鍓�' + } else if (diff < 3600 * 24 * 2) { + return '1澶╁墠' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '鏈�' + + d.getDate() + + '鏃�' + + d.getHours() + + '鏃�' + + d.getMinutes() + + '鍒�' + ) + } +} + +/** + * @param {string} url + * @returns {Object} + */ +export function getQueryObject(url) { + url = url == null ? window.location.href : url + const search = url.substring(url.lastIndexOf('?') + 1) + const obj = {} + const reg = /([^?&=]+)=([^?&=]*)/g + search.replace(reg, (rs, $1, $2) => { + const name = decodeURIComponent($1) + let val = decodeURIComponent($2) + val = String(val) + obj[name] = val + return rs + }) + return obj +} + +/** + * @param {string} input value + * @returns {number} output value + */ +export function byteLength(str) { + // returns the byte length of an utf8 string + let s = str.length + for (var i = str.length - 1; i >= 0; i--) { + const code = str.charCodeAt(i) + if (code > 0x7f && code <= 0x7ff) s++ + else if (code > 0x7ff && code <= 0xffff) s += 2 + if (code >= 0xDC00 && code <= 0xDFFF) i-- + } + return s +} + +/** + * @param {Array} actual + * @returns {Array} + */ +export function cleanArray(actual) { + const newArray = [] + for (let i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]) + } + } + return newArray +} + +/** + * @param {Object} json + * @returns {Array} + */ +export function param(json) { + if (!json) return '' + return cleanArray( + Object.keys(json).map(key => { + if (json[key] === undefined) return '' + return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) + }) + ).join('&') +} + +/** + * @param {string} url + * @returns {Object} + */ +export function param2Obj(url) { + const search = url.split('?')[1] + if (!search) { + return {} + } + return JSON.parse( + '{"' + + decodeURIComponent(search) + .replace(/"/g, '\\"') + .replace(/&/g, '","') + .replace(/=/g, '":"') + .replace(/\+/g, ' ') + + '"}' + ) +} + +/** + * @param {string} val + * @returns {string} + */ +export function html2Text(val) { + const div = document.createElement('div') + div.innerHTML = val + return div.textContent || div.innerText +} + +/** + * Merges two objects, giving the last one precedence + * @param {Object} target + * @param {(Object|Array)} source + * @returns {Object} + */ +export function objectMerge(target, source) { + if (typeof target !== 'object') { + target = {} + } + if (Array.isArray(source)) { + return source.slice() + } + Object.keys(source).forEach(property => { + const sourceProperty = source[property] + if (typeof sourceProperty === 'object') { + target[property] = objectMerge(target[property], sourceProperty) + } else { + target[property] = sourceProperty + } + }) + return target +} + +/** + * @param {HTMLElement} element + * @param {string} className + */ +export function toggleClass(element, className) { + if (!element || !className) { + return + } + let classString = element.className + const nameIndex = classString.indexOf(className) + if (nameIndex === -1) { + classString += '' + className + } else { + classString = + classString.substr(0, nameIndex) + + classString.substr(nameIndex + className.length) + } + element.className = classString +} + +/** + * @param {string} type + * @returns {Date} + */ +export function getTime(type) { + if (type === 'start') { + return new Date().getTime() - 3600 * 1000 * 24 * 90 + } else { + return new Date(new Date().toDateString()) + } +} + +/** + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + * @return {*} + */ +export function debounce(func, wait, immediate) { + let timeout, args, context, timestamp, result + + const later = function() { + // 鎹笂涓�娆¤Е鍙戞椂闂撮棿闅� + const last = +new Date() - timestamp + + // 涓婃琚寘瑁呭嚱鏁拌璋冪敤鏃堕棿闂撮殧 last 灏忎簬璁惧畾鏃堕棿闂撮殧 wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last) + } else { + timeout = null + // 濡傛灉璁惧畾涓篿mmediate===true锛屽洜涓哄紑濮嬭竟鐣屽凡缁忚皟鐢ㄨ繃浜嗘澶勬棤闇�璋冪敤 + if (!immediate) { + result = func.apply(context, args) + if (!timeout) context = args = null + } + } + } + + return function(...args) { + context = this + timestamp = +new Date() + const callNow = immediate && !timeout + // 濡傛灉寤舵椂涓嶅瓨鍦紝閲嶆柊璁惧畾寤舵椂 + if (!timeout) timeout = setTimeout(later, wait) + if (callNow) { + result = func.apply(context, args) + context = args = null + } + + return result + } +} + +/** + * This is just a simple version of deep copy + * Has a lot of edge cases bug + * If you want to use a perfect deep copy, use lodash's _.cloneDeep + * @param {Object} source + * @returns {Object} + */ +export function deepClone(source) { + if (!source && typeof source !== 'object') { + throw new Error('error arguments', 'deepClone') + } + const targetObj = source.constructor === Array ? [] : {} + Object.keys(source).forEach(keys => { + if (source[keys] && typeof source[keys] === 'object') { + targetObj[keys] = deepClone(source[keys]) + } else { + targetObj[keys] = source[keys] + } + }) + return targetObj +} + +/** + * @param {Array} arr + * @returns {Array} + */ +export function uniqueArr(arr) { + return Array.from(new Set(arr)) +} + +/** + * @returns {string} + */ +export function createUniqueString() { + const timestamp = +new Date() + '' + const randomNum = parseInt((1 + Math.random()) * 65536) + '' + return (+(randomNum + timestamp)).toString(32) +} + +/** + * Check if an element has a class + * @param {HTMLElement} elm + * @param {string} cls + * @returns {boolean} + */ +export function hasClass(ele, cls) { + return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) +} + +/** + * Add class to element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function addClass(ele, cls) { + if (!hasClass(ele, cls)) ele.className += ' ' + cls +} + +/** + * Remove class from element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function removeClass(ele, cls) { + if (hasClass(ele, cls)) { + const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') + ele.className = ele.className.replace(reg, ' ') + } +} diff --git a/ruoyi-ui/src/utils/jsencrypt.js b/ruoyi-ui/src/utils/jsencrypt.js new file mode 100644 index 0000000..83db480 --- /dev/null +++ b/ruoyi-ui/src/utils/jsencrypt.js @@ -0,0 +1,30 @@ +import JSEncrypt from 'jsencrypt/bin/jsencrypt' + +// 瀵嗛挜瀵圭敓鎴� http://web.chacuo.net/netrsakeypair + +const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n' + + '2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==' + +const privateKey = 'MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8\n' + + 'mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9p\n' + + 'B6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue\n' + + '/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZ\n' + + 'UBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6\n' + + 'vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha\n' + + '4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3\n' + + 'tTbklZkD2A==' + +// 鍔犲瘑 +export function encrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPublicKey(publicKey) // 璁剧疆鍏挜 + return encryptor.encrypt(txt) // 瀵归渶瑕佸姞瀵嗙殑鏁版嵁杩涜鍔犲瘑 +} + +// 瑙e瘑 +export function decrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) + return encryptor.decrypt(txt) +} + diff --git a/ruoyi-ui/src/utils/permission.js b/ruoyi-ui/src/utils/permission.js new file mode 100644 index 0000000..591e1c1 --- /dev/null +++ b/ruoyi-ui/src/utils/permission.js @@ -0,0 +1,24 @@ +import store from '@/store' + +/** + * @param {Array} value + * @returns {Boolean} + */ +export default function checkPermission(value) { + if (value && value instanceof Array && value.length > 0) { + const roles = store.getters && store.getters.roles + const permissionRoles = value + + const hasPermission = roles.some(role => { + return permissionRoles.includes(role) + }) + + if (!hasPermission) { + return false + } + return true + } else { + console.error(`need roles! Like v-permission="['admin','editor']"`) + return false + } +} diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js new file mode 100644 index 0000000..6961649 --- /dev/null +++ b/ruoyi-ui/src/utils/request.js @@ -0,0 +1,65 @@ +import axios from 'axios' +import { Notification, MessageBox, Message } from 'element-ui' +import store from '@/store' +import { getToken } from '@/utils/auth' + +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +// 鍒涘缓axios瀹炰緥 +const service = axios.create({ + // axios涓姹傞厤缃湁baseURL閫夐」锛岃〃绀鸿姹俇RL鍏叡閮ㄥ垎 + baseURL: process.env.VUE_APP_BASE_API, + // 瓒呮椂 + timeout: 10000 +}) +// request鎷︽埅鍣� +service.interceptors.request.use( + config => { + if (getToken()) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 璁╂瘡涓姹傛惡甯﹁嚜瀹氫箟token 璇锋牴鎹疄闄呮儏鍐佃嚜琛屼慨鏀� + } + return config + }, + error => { + console.log(error) + Promise.reject(error) + } +) + +// 鍝嶅簲鎷︽埅鍣� +service.interceptors.response.use(res => { + const code = res.data.code + if (code === 401) { + MessageBox.confirm( + '鐧诲綍鐘舵�佸凡杩囨湡锛屾偍鍙互缁х画鐣欏湪璇ラ〉闈紝鎴栬�呴噸鏂扮櫥褰�', + '绯荤粺鎻愮ず', + { + confirmButtonText: '閲嶆柊鐧诲綍', + cancelButtonText: '鍙栨秷', + type: 'warning' + } + ).then(() => { + store.dispatch('LogOut').then(() => { + location.reload() // 涓轰簡閲嶆柊瀹炰緥鍖杤ue-router瀵硅薄 閬垮厤bug + }) + }) + } else if (code !== 200) { + Notification.error({ + title: res.data.msg + }) + return Promise.reject('error') + } else { + return res.data + } + }, + error => { + console.log('err' + error) + Message({ + message: error.message, + type: 'error', + duration: 5 * 1000 + }) + return Promise.reject(error) + } +) + +export default service diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js new file mode 100644 index 0000000..71fc8da --- /dev/null +++ b/ruoyi-ui/src/utils/ruoyi.js @@ -0,0 +1,103 @@ +/** + * 閫氱敤js鏂规硶灏佽澶勭悊 + * Copyright (c) 2019 ruoyi + */ + +const baseURL = process.env.VUE_APP_BASE_API + +// 鏃ユ湡鏍煎紡鍖� +export function parseTime(time, pattern) { + if (arguments.length === 0 || !time) { + return null + } + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { + time = parseInt(time) + } + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { + let value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { return ['鏃�', '涓�', '浜�', '涓�', '鍥�', '浜�', '鍏�'][value] } + if (result.length > 0 && value < 10) { + value = '0' + value + } + return value || 0 + }) + return time_str +} + +// 琛ㄥ崟閲嶇疆 +export function resetForm(refName) { + if (this.$refs[refName]) { + this.$refs[refName].resetFields(); + } +} + +// 娣诲姞鏃ユ湡鑼冨洿 +export function addDateRange(params, dateRange) { + var search = params; + search.beginTime = ""; + search.endTime = ""; + if (null != dateRange && '' != dateRange) { + search.beginTime = this.dateRange[0]; + search.endTime = this.dateRange[1]; + } + return search; +} + +// 鍥炴樉鏁版嵁瀛楀吀 +export function selectDictLabel(datas, value) { + var actions = []; + Object.keys(datas).map((key) => { + if (datas[key].dictValue == ('' + value)) { + actions.push(datas[key].dictLabel); + return false; + } + }) + return actions.join(''); +} + +// 閫氱敤涓嬭浇鏂规硶 +export function download(fileName) { + window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true; +} + +// 瀛楃涓叉牸寮忓寲(%s ) +export function sprintf(str) { + var args = arguments, flag = true, i = 1; + str = str.replace(/%s/g, function () { + var arg = args[i++]; + if (typeof arg === 'undefined') { + flag = false; + return ''; + } + return arg; + }); + return flag ? str : ''; +} + +// 杞崲瀛楃涓诧紝undefined,null绛夎浆鍖栦负"" +export function praseStrEmpty(str) { + if (!str || str == "undefined" || str == "null") { + return ""; + } + return str; +} \ No newline at end of file diff --git a/ruoyi-ui/src/utils/scroll-to.js b/ruoyi-ui/src/utils/scroll-to.js new file mode 100644 index 0000000..c5d8e04 --- /dev/null +++ b/ruoyi-ui/src/utils/scroll-to.js @@ -0,0 +1,58 @@ +Math.easeInOutQuad = function(t, b, c, d) { + t /= d / 2 + if (t < 1) { + return c / 2 * t * t + b + } + t-- + return -c / 2 * (t * (t - 2) - 1) + b +} + +// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts +var requestAnimFrame = (function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } +})() + +/** + * Because it's so fucking difficult to detect the scrolling element, just move them all + * @param {number} amount + */ +function move(amount) { + document.documentElement.scrollTop = amount + document.body.parentNode.scrollTop = amount + document.body.scrollTop = amount +} + +function position() { + return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop +} + +/** + * @param {number} to + * @param {number} duration + * @param {Function} callback + */ +export function scrollTo(to, duration, callback) { + const start = position() + const change = to - start + const increment = 20 + let currentTime = 0 + duration = (typeof (duration) === 'undefined') ? 500 : duration + var animateScroll = function() { + // increment the time + currentTime += increment + // find the value with the quadratic in-out easing function + var val = Math.easeInOutQuad(currentTime, start, change, duration) + // move the document.body + move(val) + // do the animation unless its over + if (currentTime < duration) { + requestAnimFrame(animateScroll) + } else { + if (callback && typeof (callback) === 'function') { + // the animation is done so lets callback + callback() + } + } + } + animateScroll() +} diff --git a/ruoyi-ui/src/utils/validate.js b/ruoyi-ui/src/utils/validate.js new file mode 100644 index 0000000..adfa254 --- /dev/null +++ b/ruoyi-ui/src/utils/validate.js @@ -0,0 +1,83 @@ +/** + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUsername(str) { + const valid_map = ['admin', 'editor'] + return valid_map.indexOf(str.trim()) >= 0 +} + +/** + * @param {string} url + * @returns {Boolean} + */ +export function validURL(url) { + const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return reg.test(url) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validLowerCase(str) { + const reg = /^[a-z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUpperCase(str) { + const reg = /^[A-Z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validAlphabets(str) { + const reg = /^[A-Za-z]+$/ + return reg.test(str) +} + +/** + * @param {string} email + * @returns {Boolean} + */ +export function validEmail(email) { + const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + return reg.test(email) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function isString(str) { + if (typeof str === 'string' || str instanceof String) { + return true + } + return false +} + +/** + * @param {Array} arg + * @returns {Boolean} + */ +export function isArray(arg) { + if (typeof Array.isArray === 'undefined') { + return Object.prototype.toString.call(arg) === '[object Array]' + } + return Array.isArray(arg) +} diff --git a/ruoyi-ui/src/utils/zipdownload.js b/ruoyi-ui/src/utils/zipdownload.js new file mode 100644 index 0000000..363c45a --- /dev/null +++ b/ruoyi-ui/src/utils/zipdownload.js @@ -0,0 +1,40 @@ +import axios from 'axios' +import { getToken } from '@/utils/auth' + +const mimeMap = { + xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + zip: 'application/zip' +} + +const baseUrl = process.env.VUE_APP_BASE_API +export function downLoadZip(str, filename) { + var url = baseUrl + str + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(res => { + resolveBlob(res, mimeMap.zip) + }) +} +/** + * 瑙f瀽blob鍝嶅簲鍐呭骞朵笅杞� + * @param {*} res blob鍝嶅簲鍐呭 + * @param {String} mimeType MIME绫诲瀷 + */ +export function resolveBlob(res, mimeType) { + const aLink = document.createElement('a') + var blob = new Blob([res.data], { type: mimeType }) + // //浠巖esponse鐨刪eaders涓幏鍙杅ilename, 鍚庣response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 璁剧疆鐨勬枃浠跺悕; + var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') + var contentDisposition = decodeURI(res.headers['content-disposition']) + var result = patt.exec(contentDisposition) + var fileName = result[1] + fileName = fileName.replace(/\"/g, '') + aLink.href = URL.createObjectURL(blob) + aLink.setAttribute('download', fileName) // 璁剧疆涓嬭浇鏂囦欢鍚嶇О + document.body.appendChild(aLink) + aLink.click() + document.body.appendChild(aLink) +} diff --git a/ruoyi-ui/src/views/components/icons/element-icons.js b/ruoyi-ui/src/views/components/icons/element-icons.js new file mode 100644 index 0000000..df72201 --- /dev/null +++ b/ruoyi-ui/src/views/components/icons/element-icons.js @@ -0,0 +1,74 @@ +const elementIcons = [ + 'info', + 'error', + 'success', + 'warning', + 'question', + 'back', + 'arrow-left', + 'arrow-down', + 'arrow-right', + 'arrow-up', + 'caret-left', + 'caret-bottom', + 'caret-top', + 'caret-right', + 'd-arrow-left', + 'd-arrow-right', + 'minus', + 'plus', + 'remove', + 'circle-plus', + 'remove-outline', + 'circle-plus-outline', + 'close', + 'check', + 'circle-close', + 'circle-check', + 'circle-close-outline', + 'circle-check-outline', + 'zoom-out', + 'zoom-in', + 'd-caret', + 'sort', + 'sort-down', + 'sort-up', + 'tickets', + 'document', + 'goods', + 'sold-out', + 'news', + 'message', + 'date', + 'printer', + 'time', + 'bell', + 'mobile-phone', + 'service', + 'view', + 'menu', + 'more', + 'more-outline', + 'star-on', + 'star-off', + 'location', + 'location-outline', + 'phone', + 'phone-outline', + 'picture', + 'picture-outline', + 'delete', + 'search', + 'edit', + 'edit-outline', + 'rank', + 'refresh', + 'share', + 'setting', + 'upload', + 'upload2', + 'download', + 'loading' +] + +export default elementIcons diff --git a/ruoyi-ui/src/views/components/icons/index.vue b/ruoyi-ui/src/views/components/icons/index.vue new file mode 100644 index 0000000..d3c9a71 --- /dev/null +++ b/ruoyi-ui/src/views/components/icons/index.vue @@ -0,0 +1,87 @@ +<template> + <div class="icons-container"> + <aside> + <a href="#" target="_blank">Add and use + </a> + </aside> + <el-tabs type="border-card"> + <el-tab-pane label="Icons"> + <div v-for="item of svgIcons" :key="item"> + <el-tooltip placement="top"> + <div slot="content"> + {{ generateIconCode(item) }} + </div> + <div class="icon-item"> + <svg-icon :icon-class="item" class-name="disabled" /> + <span>{{ item }}</span> + </div> + </el-tooltip> + </div> + </el-tab-pane> + <el-tab-pane label="Element-UI Icons"> + <div v-for="item of elementIcons" :key="item"> + <el-tooltip placement="top"> + <div slot="content"> + {{ generateElementIconCode(item) }} + </div> + <div class="icon-item"> + <i :class="'el-icon-' + item" /> + <span>{{ item }}</span> + </div> + </el-tooltip> + </div> + </el-tab-pane> + </el-tabs> + </div> +</template> + +<script> +import svgIcons from './svg-icons' +import elementIcons from './element-icons' + +export default { + name: 'Icons', + data() { + return { + svgIcons, + elementIcons + } + }, + methods: { + generateIconCode(symbol) { + return `<svg-icon icon-class="${symbol}" />` + }, + generateElementIconCode(symbol) { + return `<i class="el-icon-${symbol}" />` + } + } +} +</script> + +<style lang="scss" scoped> +.icons-container { + margin: 10px 20px 0; + overflow: hidden; + + .icon-item { + margin: 20px; + height: 85px; + text-align: center; + width: 100px; + float: left; + font-size: 30px; + color: #24292e; + cursor: pointer; + } + + span { + display: block; + font-size: 16px; + margin-top: 10px; + } + + .disabled { + pointer-events: none; + } +} +</style> diff --git a/ruoyi-ui/src/views/components/icons/svg-icons.js b/ruoyi-ui/src/views/components/icons/svg-icons.js new file mode 100644 index 0000000..724cd8e --- /dev/null +++ b/ruoyi-ui/src/views/components/icons/svg-icons.js @@ -0,0 +1,10 @@ +const req = require.context('../../../assets/icons/svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys() + +const re = /\.\/(.*)\.svg/ + +const svgIcons = requireAll(req).map(i => { + return i.match(re)[1] +}) + +export default svgIcons diff --git a/ruoyi-ui/src/views/dashboard/BarChart.vue b/ruoyi-ui/src/views/dashboard/BarChart.vue new file mode 100644 index 0000000..be0af34 --- /dev/null +++ b/ruoyi-ui/src/views/dashboard/BarChart.vue @@ -0,0 +1,102 @@ +<template> + <div :class="className" :style="{height:height,width:width}" /> +</template> + +<script> +import echarts from 'echarts' +require('echarts/theme/macarons') // echarts theme +import resize from './mixins/resize' + +const animationDuration = 6000 + +export default { + mixins: [resize], + props: { + className: { + type: String, + default: 'chart' + }, + width: { + type: String, + default: '100%' + }, + height: { + type: String, + default: '300px' + } + }, + data() { + return { + chart: null + } + }, + mounted() { + this.$nextTick(() => { + this.initChart() + }) + }, + beforeDestroy() { + if (!this.chart) { + return + } + this.chart.dispose() + this.chart = null + }, + methods: { + initChart() { + this.chart = echarts.init(this.$el, 'macarons') + + this.chart.setOption({ + tooltip: { + trigger: 'axis', + axisPointer: { // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥 + type: 'shadow' // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow' + } + }, + grid: { + top: 10, + left: '2%', + right: '2%', + bottom: '3%', + containLabel: true + }, + xAxis: [{ + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + axisTick: { + alignWithLabel: true + } + }], + yAxis: [{ + type: 'value', + axisTick: { + show: false + } + }], + series: [{ + name: 'pageA', + type: 'bar', + stack: 'vistors', + barWidth: '60%', + data: [79, 52, 200, 334, 390, 330, 220], + animationDuration + }, { + name: 'pageB', + type: 'bar', + stack: 'vistors', + barWidth: '60%', + data: [80, 52, 200, 334, 390, 330, 220], + animationDuration + }, { + name: 'pageC', + type: 'bar', + stack: 'vistors', + barWidth: '60%', + data: [30, 52, 200, 334, 390, 330, 220], + animationDuration + }] + }) + } + } +} +</script> diff --git a/ruoyi-ui/src/views/dashboard/LineChart.vue b/ruoyi-ui/src/views/dashboard/LineChart.vue new file mode 100644 index 0000000..e654168 --- /dev/null +++ b/ruoyi-ui/src/views/dashboard/LineChart.vue @@ -0,0 +1,135 @@ +<template> + <div :class="className" :style="{height:height,width:width}" /> +</template> + +<script> +import echarts from 'echarts' +require('echarts/theme/macarons') // echarts theme +import resize from './mixins/resize' + +export default { + mixins: [resize], + props: { + className: { + type: String, + default: 'chart' + }, + width: { + type: String, + default: '100%' + }, + height: { + type: String, + default: '350px' + }, + autoResize: { + type: Boolean, + default: true + }, + chartData: { + type: Object, + required: true + } + }, + data() { + return { + chart: null + } + }, + watch: { + chartData: { + deep: true, + handler(val) { + this.setOptions(val) + } + } + }, + mounted() { + this.$nextTick(() => { + this.initChart() + }) + }, + beforeDestroy() { + if (!this.chart) { + return + } + this.chart.dispose() + this.chart = null + }, + methods: { + initChart() { + this.chart = echarts.init(this.$el, 'macarons') + this.setOptions(this.chartData) + }, + setOptions({ expectedData, actualData } = {}) { + this.chart.setOption({ + xAxis: { + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + boundaryGap: false, + axisTick: { + show: false + } + }, + grid: { + left: 10, + right: 10, + bottom: 20, + top: 30, + containLabel: true + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross' + }, + padding: [5, 10] + }, + yAxis: { + axisTick: { + show: false + } + }, + legend: { + data: ['expected', 'actual'] + }, + series: [{ + name: 'expected', itemStyle: { + normal: { + color: '#FF005A', + lineStyle: { + color: '#FF005A', + width: 2 + } + } + }, + smooth: true, + type: 'line', + data: expectedData, + animationDuration: 2800, + animationEasing: 'cubicInOut' + }, + { + name: 'actual', + smooth: true, + type: 'line', + itemStyle: { + normal: { + color: '#3888fa', + lineStyle: { + color: '#3888fa', + width: 2 + }, + areaStyle: { + color: '#f3f8ff' + } + } + }, + data: actualData, + animationDuration: 2800, + animationEasing: 'quadraticOut' + }] + }) + } + } +} +</script> diff --git a/ruoyi-ui/src/views/dashboard/PanelGroup.vue b/ruoyi-ui/src/views/dashboard/PanelGroup.vue new file mode 100644 index 0000000..1a1081f --- /dev/null +++ b/ruoyi-ui/src/views/dashboard/PanelGroup.vue @@ -0,0 +1,181 @@ +<template> + <el-row :gutter="40" class="panel-group"> + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> + <div class="card-panel" @click="handleSetLineChartData('newVisitis')"> + <div class="card-panel-icon-wrapper icon-people"> + <svg-icon icon-class="peoples" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text"> + 璁垮 + </div> + <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> + <div class="card-panel" @click="handleSetLineChartData('messages')"> + <div class="card-panel-icon-wrapper icon-message"> + <svg-icon icon-class="message" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text"> + 娑堟伅 + </div> + <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> + <div class="card-panel" @click="handleSetLineChartData('purchases')"> + <div class="card-panel-icon-wrapper icon-money"> + <svg-icon icon-class="money" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text"> + 閲戦 + </div> + <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> + <div class="card-panel" @click="handleSetLineChartData('shoppings')"> + <div class="card-panel-icon-wrapper icon-shopping"> + <svg-icon icon-class="shopping" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text"> + 璁㈠崟 + </div> + <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" /> + </div> + </div> + </el-col> + </el-row> +</template> + +<script> +import CountTo from 'vue-count-to' + +export default { + components: { + CountTo + }, + methods: { + handleSetLineChartData(type) { + this.$emit('handleSetLineChartData', type) + } + } +} +</script> + +<style lang="scss" scoped> +.panel-group { + margin-top: 18px; + + .card-panel-col { + margin-bottom: 32px; + } + + .card-panel { + height: 108px; + cursor: pointer; + font-size: 12px; + position: relative; + overflow: hidden; + color: #666; + background: #fff; + box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); + border-color: rgba(0, 0, 0, .05); + + &:hover { + .card-panel-icon-wrapper { + color: #fff; + } + + .icon-people { + background: #40c9c6; + } + + .icon-message { + background: #36a3f7; + } + + .icon-money { + background: #f4516c; + } + + .icon-shopping { + background: #34bfa3 + } + } + + .icon-people { + color: #40c9c6; + } + + .icon-message { + color: #36a3f7; + } + + .icon-money { + color: #f4516c; + } + + .icon-shopping { + color: #34bfa3 + } + + .card-panel-icon-wrapper { + float: left; + margin: 14px 0 0 14px; + padding: 16px; + transition: all 0.38s ease-out; + border-radius: 6px; + } + + .card-panel-icon { + float: left; + font-size: 48px; + } + + .card-panel-description { + float: right; + font-weight: bold; + margin: 26px; + margin-left: 0px; + + .card-panel-text { + line-height: 18px; + color: rgba(0, 0, 0, 0.45); + font-size: 16px; + margin-bottom: 12px; + } + + .card-panel-num { + font-size: 20px; + } + } + } +} + +@media (max-width:550px) { + .card-panel-description { + display: none; + } + + .card-panel-icon-wrapper { + float: none !important; + width: 100%; + height: 100%; + margin: 0 !important; + + .svg-icon { + display: block; + margin: 14px auto !important; + float: none !important; + } + } +} +</style> diff --git a/ruoyi-ui/src/views/dashboard/PieChart.vue b/ruoyi-ui/src/views/dashboard/PieChart.vue new file mode 100644 index 0000000..4d2ef32 --- /dev/null +++ b/ruoyi-ui/src/views/dashboard/PieChart.vue @@ -0,0 +1,79 @@ +<template> + <div :class="className" :style="{height:height,width:width}" /> +</template> + +<script> +import echarts from 'echarts' +require('echarts/theme/macarons') // echarts theme +import resize from './mixins/resize' + +export default { + mixins: [resize], + props: { + className: { + type: String, + default: 'chart' + }, + width: { + type: String, + default: '100%' + }, + height: { + type: String, + default: '300px' + } + }, + data() { + return { + chart: null + } + }, + mounted() { + this.$nextTick(() => { + this.initChart() + }) + }, + beforeDestroy() { + if (!this.chart) { + return + } + this.chart.dispose() + this.chart = null + }, + methods: { + initChart() { + this.chart = echarts.init(this.$el, 'macarons') + + this.chart.setOption({ + tooltip: { + trigger: 'item', + formatter: '{a} <br/>{b} : {c} ({d}%)' + }, + legend: { + left: 'center', + bottom: '10', + data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts'] + }, + series: [ + { + name: 'WEEKLY WRITE ARTICLES', + type: 'pie', + roseType: 'radius', + radius: [15, 95], + center: ['50%', '38%'], + data: [ + { value: 320, name: 'Industries' }, + { value: 240, name: 'Technology' }, + { value: 149, name: 'Forex' }, + { value: 100, name: 'Gold' }, + { value: 59, name: 'Forecasts' } + ], + animationEasing: 'cubicInOut', + animationDuration: 2600 + } + ] + }) + } + } +} +</script> diff --git a/ruoyi-ui/src/views/dashboard/RaddarChart.vue b/ruoyi-ui/src/views/dashboard/RaddarChart.vue new file mode 100644 index 0000000..6823af3 --- /dev/null +++ b/ruoyi-ui/src/views/dashboard/RaddarChart.vue @@ -0,0 +1,116 @@ +<template> + <div :class="className" :style="{height:height,width:width}" /> +</template> + +<script> +import echarts from 'echarts' +require('echarts/theme/macarons') // echarts theme +import resize from './mixins/resize' + +const animationDuration = 3000 + +export default { + mixins: [resize], + props: { + className: { + type: String, + default: 'chart' + }, + width: { + type: String, + default: '100%' + }, + height: { + type: String, + default: '300px' + } + }, + data() { + return { + chart: null + } + }, + mounted() { + this.$nextTick(() => { + this.initChart() + }) + }, + beforeDestroy() { + if (!this.chart) { + return + } + this.chart.dispose() + this.chart = null + }, + methods: { + initChart() { + this.chart = echarts.init(this.$el, 'macarons') + + this.chart.setOption({ + tooltip: { + trigger: 'axis', + axisPointer: { // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥 + type: 'shadow' // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow' + } + }, + radar: { + radius: '66%', + center: ['50%', '42%'], + splitNumber: 8, + splitArea: { + areaStyle: { + color: 'rgba(127,95,132,.3)', + opacity: 1, + shadowBlur: 45, + shadowColor: 'rgba(0,0,0,.5)', + shadowOffsetX: 0, + shadowOffsetY: 15 + } + }, + indicator: [ + { name: 'Sales', max: 10000 }, + { name: 'Administration', max: 20000 }, + { name: 'Information Techology', max: 20000 }, + { name: 'Customer Support', max: 20000 }, + { name: 'Development', max: 20000 }, + { name: 'Marketing', max: 20000 } + ] + }, + legend: { + left: 'center', + bottom: '10', + data: ['Allocated Budget', 'Expected Spending', 'Actual Spending'] + }, + series: [{ + type: 'radar', + symbolSize: 0, + areaStyle: { + normal: { + shadowBlur: 13, + shadowColor: 'rgba(0,0,0,.2)', + shadowOffsetX: 0, + shadowOffsetY: 10, + opacity: 1 + } + }, + data: [ + { + value: [5000, 7000, 12000, 11000, 15000, 14000], + name: 'Allocated Budget' + }, + { + value: [4000, 9000, 15000, 15000, 13000, 11000], + name: 'Expected Spending' + }, + { + value: [5500, 11000, 12000, 15000, 12000, 12000], + name: 'Actual Spending' + } + ], + animationDuration: animationDuration + }] + }) + } + } +} +</script> diff --git a/ruoyi-ui/src/views/dashboard/mixins/resize.js b/ruoyi-ui/src/views/dashboard/mixins/resize.js new file mode 100644 index 0000000..ae02e64 --- /dev/null +++ b/ruoyi-ui/src/views/dashboard/mixins/resize.js @@ -0,0 +1,52 @@ +import { debounce } from '@/utils' + +export default { + data() { + return { + $_sidebarElm: null + } + }, + mounted() { + this.$_initResizeEvent() + this.$_initSidebarResizeEvent() + }, + beforeDestroy() { + this.$_destroyResizeEvent() + this.$_destroySidebarResizeEvent() + }, + activated() { + this.$_initResizeEvent() + this.$_initSidebarResizeEvent() + }, + deactivated() { + this.$_destroyResizeEvent() + this.$_destroySidebarResizeEvent() + }, + methods: { + $_resizeHandler() { + return debounce(() => { + if (this.chart) { + this.chart.resize() + } + }, 100)() + }, + $_initResizeEvent() { + window.addEventListener('resize', this.$_resizeHandler) + }, + $_destroyResizeEvent() { + window.removeEventListener('resize', this.$_resizeHandler) + }, + $_sidebarResizeHandler(e) { + if (e.propertyName === 'width') { + this.$_resizeHandler() + } + }, + $_initSidebarResizeEvent() { + this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] + this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) + }, + $_destroySidebarResizeEvent() { + this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) + } + } +} diff --git a/ruoyi-ui/src/views/error/401.vue b/ruoyi-ui/src/views/error/401.vue new file mode 100644 index 0000000..448b6ec --- /dev/null +++ b/ruoyi-ui/src/views/error/401.vue @@ -0,0 +1,88 @@ +<template> + <div class="errPage-container"> + <el-button icon="arrow-left" class="pan-back-btn" @click="back"> + 杩斿洖 + </el-button> + <el-row> + <el-col :span="12"> + <h1 class="text-jumbo text-ginormous"> + 401閿欒! + </h1> + <h2>鎮ㄦ病鏈夎闂潈闄愶紒</h2> + <h6>瀵逛笉璧凤紝鎮ㄦ病鏈夎闂潈闄愶紝璇蜂笉瑕佽繘琛岄潪娉曟搷浣滐紒鎮ㄥ彲浠ヨ繑鍥炰富椤甸潰</h6> + <ul class="list-unstyled"> + <li class="link-type"> + <router-link to="/"> + 鍥為椤� + </router-link> + </li> + </ul> + </el-col> + <el-col :span="12"> + <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream."> + </el-col> + </el-row> + </div> +</template> + +<script> +import errGif from '@/assets/401_images/401.gif' + +export default { + name: 'Page401', + data() { + return { + errGif: errGif + '?' + +new Date() + } + }, + methods: { + back() { + if (this.$route.query.noGoBack) { + this.$router.push({ path: '/' }) + } else { + this.$router.go(-1) + } + } + } +} +</script> + +<style lang="scss" scoped> + .errPage-container { + width: 800px; + max-width: 100%; + margin: 100px auto; + .pan-back-btn { + background: #008489; + color: #fff; + border: none!important; + } + .pan-gif { + margin: 0 auto; + display: block; + } + .pan-img { + display: block; + margin: 0 auto; + width: 100%; + } + .text-jumbo { + font-size: 60px; + font-weight: 700; + color: #484848; + } + .list-unstyled { + font-size: 14px; + li { + padding-bottom: 5px; + } + a { + color: #008489; + text-decoration: none; + &:hover { + text-decoration: underline; + } + } + } + } +</style> diff --git a/ruoyi-ui/src/views/error/404.vue b/ruoyi-ui/src/views/error/404.vue new file mode 100644 index 0000000..96f075c --- /dev/null +++ b/ruoyi-ui/src/views/error/404.vue @@ -0,0 +1,233 @@ +<template> + <div class="wscn-http404-container"> + <div class="wscn-http404"> + <div class="pic-404"> + <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404"> + <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404"> + <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404"> + <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> + </div> + <div class="bullshit"> + <div class="bullshit__oops"> + 404閿欒! + </div> + <div class="bullshit__headline"> + {{ message }} + </div> + <div class="bullshit__info"> + 瀵逛笉璧凤紝鎮ㄦ鍦ㄥ鎵剧殑椤甸潰涓嶅瓨鍦ㄣ�傚皾璇曟鏌RL鐨勯敊璇紝鐒跺悗鎸夋祻瑙堝櫒涓婄殑鍒锋柊鎸夐挳鎴栧皾璇曞湪鎴戜滑鐨勫簲鐢ㄧ▼搴忎腑鎵惧埌鍏朵粬鍐呭銆� + </div> + <router-link to="/" class="bullshit__return-home"> + 杩斿洖棣栭〉 + </router-link> + </div> + </div> + </div> +</template> + +<script> + +export default { + name: 'Page404', + computed: { + message() { + return '鎵句笉鍒扮綉椤碉紒' + } + } +} +</script> + +<style lang="scss" scoped> +.wscn-http404-container{ + transform: translate(-50%,-50%); + position: absolute; + top: 40%; + left: 50%; +} +.wscn-http404 { + position: relative; + width: 1200px; + padding: 0 50px; + overflow: hidden; + .pic-404 { + position: relative; + float: left; + width: 600px; + overflow: hidden; + &__parent { + width: 100%; + } + &__child { + position: absolute; + &.left { + width: 80px; + top: 17px; + left: 220px; + opacity: 0; + animation-name: cloudLeft; + animation-duration: 2s; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-delay: 1s; + } + &.mid { + width: 46px; + top: 10px; + left: 420px; + opacity: 0; + animation-name: cloudMid; + animation-duration: 2s; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-delay: 1.2s; + } + &.right { + width: 62px; + top: 100px; + left: 500px; + opacity: 0; + animation-name: cloudRight; + animation-duration: 2s; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-delay: 1s; + } + @keyframes cloudLeft { + 0% { + top: 17px; + left: 220px; + opacity: 0; + } + 20% { + top: 33px; + left: 188px; + opacity: 1; + } + 80% { + top: 81px; + left: 92px; + opacity: 1; + } + 100% { + top: 97px; + left: 60px; + opacity: 0; + } + } + @keyframes cloudMid { + 0% { + top: 10px; + left: 420px; + opacity: 0; + } + 20% { + top: 40px; + left: 360px; + opacity: 1; + } + 70% { + top: 130px; + left: 180px; + opacity: 1; + } + 100% { + top: 160px; + left: 120px; + opacity: 0; + } + } + @keyframes cloudRight { + 0% { + top: 100px; + left: 500px; + opacity: 0; + } + 20% { + top: 120px; + left: 460px; + opacity: 1; + } + 80% { + top: 180px; + left: 340px; + opacity: 1; + } + 100% { + top: 200px; + left: 300px; + opacity: 0; + } + } + } + } + .bullshit { + position: relative; + float: left; + width: 300px; + padding: 30px 0; + overflow: hidden; + &__oops { + font-size: 32px; + font-weight: bold; + line-height: 40px; + color: #1482f0; + opacity: 0; + margin-bottom: 20px; + animation-name: slideUp; + animation-duration: 0.5s; + animation-fill-mode: forwards; + } + &__headline { + font-size: 20px; + line-height: 24px; + color: #222; + font-weight: bold; + opacity: 0; + margin-bottom: 10px; + animation-name: slideUp; + animation-duration: 0.5s; + animation-delay: 0.1s; + animation-fill-mode: forwards; + } + &__info { + font-size: 13px; + line-height: 21px; + color: grey; + opacity: 0; + margin-bottom: 30px; + animation-name: slideUp; + animation-duration: 0.5s; + animation-delay: 0.2s; + animation-fill-mode: forwards; + } + &__return-home { + display: block; + float: left; + width: 110px; + height: 36px; + background: #1482f0; + border-radius: 100px; + text-align: center; + color: #ffffff; + opacity: 0; + font-size: 14px; + line-height: 36px; + cursor: pointer; + animation-name: slideUp; + animation-duration: 0.5s; + animation-delay: 0.3s; + animation-fill-mode: forwards; + } + @keyframes slideUp { + 0% { + transform: translateY(60px); + opacity: 0; + } + 100% { + transform: translateY(0); + opacity: 1; + } + } + } +} +</style> diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue new file mode 100644 index 0000000..d2d2ec6 --- /dev/null +++ b/ruoyi-ui/src/views/index.vue @@ -0,0 +1,98 @@ +<template> + <div class="dashboard-editor-container"> + + <panel-group @handleSetLineChartData="handleSetLineChartData" /> + + <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> + <line-chart :chart-data="lineChartData" /> + </el-row> + + <el-row :gutter="32"> + <el-col :xs="24" :sm="24" :lg="8"> + <div class="chart-wrapper"> + <raddar-chart /> + </div> + </el-col> + <el-col :xs="24" :sm="24" :lg="8"> + <div class="chart-wrapper"> + <pie-chart /> + </div> + </el-col> + <el-col :xs="24" :sm="24" :lg="8"> + <div class="chart-wrapper"> + <bar-chart /> + </div> + </el-col> + </el-row> + + + </div> +</template> + +<script> +import PanelGroup from './dashboard/PanelGroup' +import LineChart from './dashboard/LineChart' +import RaddarChart from './dashboard/RaddarChart' +import PieChart from './dashboard/PieChart' +import BarChart from './dashboard/BarChart' + +const lineChartData = { + newVisitis: { + expectedData: [100, 120, 161, 134, 105, 160, 165], + actualData: [120, 82, 91, 154, 162, 140, 145] + }, + messages: { + expectedData: [200, 192, 120, 144, 160, 130, 140], + actualData: [180, 160, 151, 106, 145, 150, 130] + }, + purchases: { + expectedData: [80, 100, 121, 104, 105, 90, 100], + actualData: [120, 90, 100, 138, 142, 130, 130] + }, + shoppings: { + expectedData: [130, 140, 141, 142, 145, 150, 160], + actualData: [120, 82, 91, 154, 162, 140, 130] + } +} + +export default { + name: 'Index', + components: { + PanelGroup, + LineChart, + RaddarChart, + PieChart, + BarChart + }, + data() { + return { + lineChartData: lineChartData.newVisitis + } + }, + methods: { + handleSetLineChartData(type) { + this.lineChartData = lineChartData[type] + } + } +} +</script> + +<style lang="scss" scoped> +.dashboard-editor-container { + padding: 32px; + background-color: rgb(240, 242, 245); + position: relative; + + .chart-wrapper { + background: #fff; + padding: 16px 16px 0; + margin-bottom: 32px; + } +} + +@media (max-width:1024px) { + .chart-wrapper { + padding: 8px; + } +} +</style> diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue new file mode 100644 index 0000000..91df596 --- /dev/null +++ b/ruoyi-ui/src/views/login.vue @@ -0,0 +1,203 @@ +<template> + <div class="login"> + <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> + <h3 class="title">鑻ヤ緷鍚庡彴绠$悊绯荤粺</h3> + <el-form-item prop="username"> + <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="璐﹀彿"> + <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> + </el-input> + </el-form-item> + <el-form-item prop="password"> + <el-input + v-model="loginForm.password" + type="password" + auto-complete="off" + placeholder="瀵嗙爜" + @keyup.enter.native="handleLogin" + > + <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> + </el-input> + </el-form-item> + <el-form-item prop="code"> + <el-input + v-model="loginForm.code" + auto-complete="off" + placeholder="楠岃瘉鐮�" + style="width: 63%" + @keyup.enter.native="handleLogin" + > + <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> + </el-input> + <div class="login-code"> + <img :src="codeUrl" @click="getCode" /> + </div> + </el-form-item> + <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">璁颁綇瀵嗙爜</el-checkbox> + <el-form-item style="width:100%;"> + <el-button + :loading="loading" + size="medium" + type="primary" + style="width:100%;" + @click.native.prevent="handleLogin" + > + <span v-if="!loading">鐧� 褰�</span> + <span v-else>鐧� 褰� 涓�...</span> + </el-button> + </el-form-item> + </el-form> + <!-- 搴曢儴 --> + <div class="el-login-footer"> + <span>Copyright 漏 2018-2019 ruoyi.vip All Rights Reserved.</span> + </div> + </div> +</template> + +<script> +import { getCodeImg } from "@/api/login"; +import Cookies from "js-cookie"; +import { encrypt, decrypt } from '@/utils/jsencrypt' + +export default { + name: "Login", + data() { + return { + codeUrl: "", + cookiePassword: "", + loginForm: { + username: "admin", + password: "admin123", + rememberMe: false, + code: "", + uuid: "" + }, + loginRules: { + username: [ + { required: true, trigger: "blur", message: "鐢ㄦ埛鍚嶄笉鑳戒负绌�" } + ], + password: [ + { required: true, trigger: "blur", message: "瀵嗙爜涓嶈兘涓虹┖" } + ], + code: [{ required: true, trigger: "change", message: "楠岃瘉鐮佷笉鑳戒负绌�" }] + }, + loading: false, + redirect: undefined + }; + }, + watch: { + $route: { + handler: function(route) { + this.redirect = route.query && route.query.redirect; + }, + immediate: true + } + }, + created() { + this.getCode(); + this.getCookie(); + }, + methods: { + getCode() { + getCodeImg().then(res => { + this.codeUrl = "data:image/gif;base64," + res.img; + this.loginForm.uuid = res.uuid; + }); + }, + getCookie() { + const username = Cookies.get("username"); + const password = Cookies.get("password"); + const rememberMe = Cookies.get('rememberMe') + this.loginForm = { + username: username === undefined ? this.loginForm.username : username, + password: password === undefined ? this.loginForm.password : decrypt(password), + rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) + }; + }, + handleLogin() { + this.$refs.loginForm.validate(valid => { + if (valid) { + this.loading = true; + if (this.loginForm.rememberMe) { + Cookies.set("username", this.loginForm.username, { expires: 30 }); + Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); + Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); + } else { + Cookies.remove("username"); + Cookies.remove("password"); + Cookies.remove('rememberMe'); + } + this.$store + .dispatch("Login", this.loginForm) + .then(() => { + this.$router.push({ path: this.redirect || "/" }); + }) + .catch(() => { + this.loading = false; + this.getCode(); + }); + } + }); + } + } +}; +</script> + +<style rel="stylesheet/scss" lang="scss"> +.login { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + background-image: url("../assets/image/login-background.jpg"); + background-size: cover; +} +.title { + margin: 0px auto 30px auto; + text-align: center; + color: #707070; +} + +.login-form { + border-radius: 6px; + background: #ffffff; + width: 400px; + padding: 25px 25px 5px 25px; + .el-input { + height: 38px; + input { + height: 38px; + } + } + .input-icon { + height: 39px; + width: 14px; + margin-left: 2px; + } +} +.login-tip { + font-size: 13px; + text-align: center; + color: #bfbfbf; +} +.login-code { + width: 33%; + height: 38px; + float: right; + img { + cursor: pointer; + vertical-align: middle; + } +} +.el-login-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #fff; + font-family: Arial; + font-size: 12px; + letter-spacing: 1px; +} +</style> diff --git a/ruoyi-ui/src/views/login/auth-redirect.vue b/ruoyi-ui/src/views/login/auth-redirect.vue new file mode 100644 index 0000000..7df8934 --- /dev/null +++ b/ruoyi-ui/src/views/login/auth-redirect.vue @@ -0,0 +1,15 @@ +<script> +export default { + name: 'AuthRedirect', + created() { + const hash = window.location.search.slice(1) + if (window.localStorage) { + window.localStorage.setItem('x-admin-oauth-code', hash) + window.close() + } + }, + render: function(h) { + return h() // avoid warning message + } +} +</script> diff --git a/ruoyi-ui/src/views/login/components/SocialSignin.vue b/ruoyi-ui/src/views/login/components/SocialSignin.vue new file mode 100644 index 0000000..e9bf4f2 --- /dev/null +++ b/ruoyi-ui/src/views/login/components/SocialSignin.vue @@ -0,0 +1,72 @@ +<template> + <div class="social-signup-container"> + <div class="sign-btn" @click="wechatHandleClick('wechat')"> + <span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span> + WeChat + </div> + <div class="sign-btn" @click="tencentHandleClick('tencent')"> + <span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span> + QQ + </div> + </div> +</template> + +<script> +// import openWindow from '@/utils/open-window' + +export default { + name: 'SocialSignin', + methods: { + wechatHandleClick(thirdpart) { + alert('ok') + // this.$store.commit('SET_AUTH_TYPE', thirdpart) + // const appid = 'xxxxx' + // const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect') + // const url = 'https://open.weixin.qq.com/connect/qrconnect?appid=' + appid + '&redirect_uri=' + redirect_uri + '&response_type=code&scope=snsapi_login#wechat_redirect' + // openWindow(url, thirdpart, 540, 540) + }, + tencentHandleClick(thirdpart) { + alert('ok') + // this.$store.commit('SET_AUTH_TYPE', thirdpart) + // const client_id = 'xxxxx' + // const redirect_uri = encodeURIComponent('xxx/redirect?redirect=' + window.location.origin + '/auth-redirect') + // const url = 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirect_uri + // openWindow(url, thirdpart, 540, 540) + } + } +} +</script> + +<style lang="scss" scoped> + .social-signup-container { + margin: 20px 0; + .sign-btn { + display: inline-block; + cursor: pointer; + } + .icon { + color: #fff; + font-size: 24px; + margin-top: 8px; + } + .wx-svg-container, + .qq-svg-container { + display: inline-block; + width: 40px; + height: 40px; + line-height: 40px; + text-align: center; + padding-top: 1px; + border-radius: 4px; + margin-bottom: 20px; + margin-right: 5px; + } + .wx-svg-container { + background-color: #24da70; + } + .qq-svg-container { + background-color: #6BA2D6; + margin-left: 50px; + } + } +</style> diff --git a/ruoyi-ui/src/views/monitor/druid/index.vue b/ruoyi-ui/src/views/monitor/druid/index.vue new file mode 100644 index 0000000..da5b08f --- /dev/null +++ b/ruoyi-ui/src/views/monitor/druid/index.vue @@ -0,0 +1,26 @@ +<template> + <div v-loading="loading" :style="'height:'+ height"> + <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" /> + </div> +</template> +<script> +export default { + name: "Druid", + data() { + return { + src: process.env.VUE_APP_BASE_API + "/druid/index.html", + height: document.documentElement.clientHeight - 94.5 + "px;", + loading: true + }; + }, + mounted: function() { + setTimeout(() => { + this.loading = false; + }, 230); + const that = this; + window.onresize = function temp() { + that.height = document.documentElement.clientHeight - 94.5 + "px;"; + }; + } +}; +</script> diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue new file mode 100644 index 0000000..db2a0e1 --- /dev/null +++ b/ruoyi-ui/src/views/monitor/job/index.vue @@ -0,0 +1,5 @@ +<template> + <div class="app-container"> + 瀹氭椂浠诲姟 + </div> +</template> \ No newline at end of file diff --git a/ruoyi-ui/src/views/monitor/logininfor/index.vue b/ruoyi-ui/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..e9d731b --- /dev/null +++ b/ruoyi-ui/src/views/monitor/logininfor/index.vue @@ -0,0 +1,227 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="鐧诲綍鍦板潃" prop="ipaddr"> + <el-input + v-model="queryParams.ipaddr" + placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�" + clearable + style="width: 240px;" + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName"> + <el-input + v-model="queryParams.userName" + placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" + clearable + style="width: 240px;" + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select + v-model="queryParams.status" + placeholder="鐧诲綍鐘舵��" + clearable + size="small" + style="width: 240px" + > + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鐧诲綍鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['monitor:logininfor:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + @click="handleClean" + v-hasPermi="['monitor:logininfor:remove']" + >娓呯┖</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:logininfor:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="璁块棶缂栧彿" align="center" prop="infoId" /> + <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" /> + <el-table-column label="鐧诲綍鍦板潃" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" /> + <el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" /> + <el-table-column label="娴忚鍣�" align="center" prop="browser" /> + <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" /> + <el-table-column label="鐧诲綍鐘舵��" align="center" prop="status" :formatter="statusFormat" /> + <el-table-column label="鎿嶄綔淇℃伅" align="center" prop="msg" /> + <el-table-column label="鐧诲綍鏃ユ湡" align="center" prop="loginTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.loginTime) }}</span> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + </div> +</template> + +<script> +import { list, delLogininfor, cleanLogininfor, exportLogininfor } from "@/api/monitor/logininfor"; + +export default { + name: "Logininfor", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ牸鏁版嵁 + list: [], + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + ipaddr: undefined, + userName: undefined, + status: undefined + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_common_status").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ鐧诲綍鏃ュ織鍒楄〃 */ + getList() { + this.loading = true; + list(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.list = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + // 鐧诲綍鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.infoId) + this.multiple = !selection.length + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const infoIds = row.infoId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎璁块棶缂栧彿涓�"' + infoIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delLogininfor(infoIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 娓呯┖鎸夐挳鎿嶄綔 */ + handleClean() { + this.$confirm('鏄惁纭娓呯┖鎵�鏈夌櫥褰曟棩蹇楁暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return cleanLogininfor(); + }).then(() => { + this.getList(); + this.msgSuccess("娓呯┖鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夋搷浣滄棩蹇楁暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportLogininfor(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> + diff --git a/ruoyi-ui/src/views/monitor/online/index.vue b/ruoyi-ui/src/views/monitor/online/index.vue new file mode 100644 index 0000000..462a2ac --- /dev/null +++ b/ruoyi-ui/src/views/monitor/online/index.vue @@ -0,0 +1,128 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true"> + <el-form-item label="鐧诲綍鍦板潃" prop="ipaddr"> + <el-input + v-model="queryParams.ipaddr" + placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName"> + <el-input + v-model="queryParams.userName" + placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-table + v-loading="loading" + :data="list.slice((pageNum-1)*pageSize,pageNum*pageSize)" + style="width: 100%;" + > + <el-table-column label="搴忓彿" type="index" align="center"> + <template slot-scope="scope"> + <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span> + </template> + </el-table-column> + <el-table-column label="浼氳瘽缂栧彿" align="center" prop="tokenId" :show-overflow-tooltip="true" /> + <el-table-column label="鐧诲綍鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" /> + <el-table-column label="閮ㄩ棬鍚嶇О" align="center" prop="deptName" /> + <el-table-column label="涓绘満" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> + <el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" /> + <el-table-column label="娴忚鍣�" align="center" prop="browser" /> + <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" /> + <el-table-column label="鐧诲綍鏃堕棿" align="center" prop="loginTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.loginTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleForceLogout(scope.row)" + v-hasPermi="['monitor:online:forceLogout']" + >寮洪��</el-button> + </template> + </el-table-column> + </el-table> + + <pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" /> + </div> +</template> + +<script> +import { list, forceLogout } from "@/api/monitor/online"; + +export default { + name: "Online", + data() { + return { + // 閬僵灞� + loading: true, + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ牸鏁版嵁 + list: [], + pageNum: 1, + pageSize: 10, + // 鏌ヨ鍙傛暟 + queryParams: { + ipaddr: undefined, + userName: undefined + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ鐧诲綍鏃ュ織鍒楄〃 */ + getList() { + this.loading = true; + list(this.queryParams).then(response => { + this.list = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 寮洪��鎸夐挳鎿嶄綔 */ + handleForceLogout(row) { + this.$confirm('鏄惁纭寮洪��鍚嶇О涓�"' + row.userName + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return forceLogout(row.tokenId); + }).then(() => { + this.getList(); + this.msgSuccess("寮洪��鎴愬姛"); + }).catch(function() {}); + } + } +}; +</script> + diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..9430168 --- /dev/null +++ b/ruoyi-ui/src/views/monitor/operlog/index.vue @@ -0,0 +1,315 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="绯荤粺妯″潡" prop="title"> + <el-input + v-model="queryParams.title" + placeholder="璇疯緭鍏ョ郴缁熸ā鍧�" + clearable + style="width: 240px;" + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鎿嶄綔浜哄憳" prop="operName"> + <el-input + v-model="queryParams.operName" + placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" + clearable + style="width: 240px;" + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="绫诲瀷" prop="businessType"> + <el-select + v-model="queryParams.businessType" + placeholder="鎿嶄綔绫诲瀷" + clearable + size="small" + style="width: 240px" + > + <el-option + v-for="dict in typeOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select + v-model="queryParams.status" + placeholder="鎿嶄綔鐘舵��" + clearable + size="small" + style="width: 240px" + > + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鎿嶄綔鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['monitor:operlog:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + @click="handleClean" + v-hasPermi="['monitor:operlog:remove']" + >娓呯┖</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:config:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" /> + <el-table-column label="绯荤粺妯″潡" align="center" prop="title" /> + <el-table-column label="鎿嶄綔绫诲瀷" align="center" prop="businessType" :formatter="typeFormat" /> + <el-table-column label="璇锋眰鏂瑰紡" align="center" prop="requestMethod" /> + <el-table-column label="鎿嶄綔浜哄憳" align="center" prop="operName" /> + <el-table-column label="涓绘満" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> + <el-table-column label="鎿嶄綔鍦扮偣" align="center" prop="operLocation" /> + <el-table-column label="鎿嶄綔鐘舵��" align="center" prop="status" :formatter="statusFormat" /> + <el-table-column label="鎿嶄綔鏃ユ湡" align="center" prop="operTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.operTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-view" + @click="handleView(scope.row,scope.index)" + v-hasPermi="['monitor:operlog:query']" + >璇︾粏</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 鎿嶄綔鏃ュ織璇︾粏 --> + <el-dialog title="鎿嶄綔鏃ュ織璇︾粏" :visible.sync="open" width="700px"> + <el-form ref="form" :model="form" label-width="100px" size="mini"> + <el-row> + <el-col :span="12"> + <el-form-item label="鎿嶄綔妯″潡锛�">{{ form.title }} / 淇敼</el-form-item> + <el-form-item + label="鐧诲綍淇℃伅锛�" + >{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="璇锋眰鍦板潃锛�">{{ form.operUrl }}</el-form-item> + <el-form-item label="璇锋眰鏂瑰紡锛�">{{ form.requestMethod }}</el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="鎿嶄綔鏂规硶锛�">{{ form.method }}</el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="璇锋眰鍙傛暟锛�">{{ form.operParam }}</el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="杩斿洖鍙傛暟锛�">{{ form.jsonResult }}</el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鎿嶄綔鐘舵�侊細"> + <div v-if="form.status === 0">姝e父</div> + <div v-else-if="form.status === 1">澶辫触</div> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鎿嶄綔鏃堕棿锛�">{{ parseTime(form.operTime) }}</el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="寮傚父淇℃伅锛�" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> + </el-col> + </el-row> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button @click="open = false">鍏� 闂�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/operlog"; + +export default { + name: "Operlog", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ牸鏁版嵁 + list: [], + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 绫诲瀷鏁版嵁瀛楀吀 + typeOptions: [], + // 绫诲瀷鏁版嵁瀛楀吀 + statusOptions: [], + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 琛ㄥ崟鍙傛暟 + form: {}, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + title: undefined, + operName: undefined, + businessType: undefined, + status: undefined + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_oper_type").then(response => { + this.typeOptions = response.data; + }); + this.getDicts("sys_common_status").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ鐧诲綍鏃ュ織 */ + getList() { + this.loading = true; + list(this.addDateRange(this.queryParams, this.dateRange)).then( response => { + this.list = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + // 鎿嶄綔鏃ュ織鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + // 鎿嶄綔鏃ュ織绫诲瀷瀛楀吀缈昏瘧 + typeFormat(row, column) { + return this.selectDictLabel(this.typeOptions, row.businessType); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.operId) + this.multiple = !selection.length + }, + /** 璇︾粏鎸夐挳鎿嶄綔 */ + handleView(row) { + this.open = true; + this.form = row; + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const operIds = row.operId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎鏃ュ織缂栧彿涓�"' + operIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delOperlog(operIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 娓呯┖鎸夐挳鎿嶄綔 */ + handleClean() { + this.$confirm('鏄惁纭娓呯┖鎵�鏈夋搷浣滄棩蹇楁暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return cleanOperlog(); + }).then(() => { + this.getList(); + this.msgSuccess("娓呯┖鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夋搷浣滄棩蹇楁暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportOperlog(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> + diff --git a/ruoyi-ui/src/views/monitor/server/index.vue b/ruoyi-ui/src/views/monitor/server/index.vue new file mode 100644 index 0000000..8ba3082 --- /dev/null +++ b/ruoyi-ui/src/views/monitor/server/index.vue @@ -0,0 +1,210 @@ +<template> + <div class="app-container"> + <el-row> + <el-col :span="12" class="card-box"> + <el-card> + <div slot="header"><span>CPU</span></div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <table cellspacing="0" style="width: 100%;"> + <thead> + <tr> + <th class="is-leaf"><div class="cell">灞炴��</div></th> + <th class="is-leaf"><div class="cell">鍊�</div></th> + </tr> + </thead> + <tbody> + <tr> + <td><div class="cell">鏍稿績鏁�</div></td> + <td><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td> + </tr> + <tr> + <td><div class="cell">鐢ㄦ埛浣跨敤鐜�</div></td> + <td><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td> + </tr> + <tr> + <td><div class="cell">绯荤粺浣跨敤鐜�</div></td> + <td><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td> + </tr> + <tr> + <td><div class="cell">褰撳墠绌洪棽鐜�</div></td> + <td><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td> + </tr> + </tbody> + </table> + </div> + </el-card> + </el-col> + + <el-col :span="12" class="card-box"> + <el-card> + <div slot="header"><span>鍐呭瓨</span></div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <table cellspacing="0" style="width: 100%;"> + <thead> + <tr> + <th class="is-leaf"><div class="cell">灞炴��</div></th> + <th class="is-leaf"><div class="cell">鍐呭瓨</div></th> + <th class="is-leaf"><div class="cell">JVM</div></th> + </tr> + </thead> + <tbody> + <tr> + <td><div class="cell">鎬诲唴瀛�</div></td> + <td><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td> + </tr> + <tr> + <td><div class="cell">宸茬敤鍐呭瓨</div></td> + <td><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td> + </tr> + <tr> + <td><div class="cell">鍓╀綑鍐呭瓨</div></td> + <td><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td> + </tr> + <tr> + <td><div class="cell">浣跨敤鐜�</div></td> + <td><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td> + <td><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td> + </tr> + </tbody> + </table> + </div> + </el-card> + </el-col> + + <el-col :span="24" class="card-box"> + <el-card> + <div slot="header"> + <span>鏈嶅姟鍣ㄤ俊鎭�</span> + </div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <table cellspacing="0" style="width: 100%;"> + <tbody> + <tr> + <td><div class="cell">鏈嶅姟鍣ㄥ悕绉�</div></td> + <td><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td> + <td><div class="cell">鎿嶄綔绯荤粺</div></td> + <td><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td> + </tr> + <tr> + <td><div class="cell">鏈嶅姟鍣↖P</div></td> + <td><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td> + <td><div class="cell">绯荤粺鏋舵瀯</div></td> + <td><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td> + </tr> + </tbody> + </table> + </div> + </el-card> + </el-col> + + <el-col :span="24" class="card-box"> + <el-card> + <div slot="header"> + <span>Java铏氭嫙鏈轰俊鎭�</span> + </div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <table cellspacing="0" style="width: 100%;"> + <tbody> + <tr> + <td><div class="cell">Java鍚嶇О</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td> + <td><div class="cell">Java鐗堟湰</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td> + </tr> + <tr> + <td><div class="cell">鍚姩鏃堕棿</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td> + <td><div class="cell">杩愯鏃堕暱</div></td> + <td><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td> + </tr> + <tr> + <td colspan="1"><div class="cell">瀹夎璺緞</div></td> + <td colspan="3"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td> + </tr> + <tr> + <td colspan="1"><div class="cell">椤圭洰璺緞</div></td> + <td colspan="3"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td> + </tr> + </tbody> + </table> + </div> + </el-card> + </el-col> + + <el-col :span="24" class="card-box"> + <el-card> + <div slot="header"> + <span>纾佺洏鐘舵��</span> + </div> + <div class="el-table el-table--enable-row-hover el-table--medium"> + <table cellspacing="0" style="width: 100%;"> + <thead> + <tr> + <th class="is-leaf"><div class="cell">鐩樼璺緞</div></th> + <th class="is-leaf"><div class="cell">鏂囦欢绯荤粺</div></th> + <th class="is-leaf"><div class="cell">鐩樼绫诲瀷</div></th> + <th class="is-leaf"><div class="cell">鎬诲ぇ灏�</div></th> + <th class="is-leaf"><div class="cell">鍙敤澶у皬</div></th> + <th class="is-leaf"><div class="cell">宸茬敤澶у皬</div></th> + <th class="is-leaf"><div class="cell">宸茬敤鐧惧垎姣�</div></th> + </tr> + </thead> + <tbody v-if="server.sysFiles"> + <tr v-for="sysFile in server.sysFiles"> + <td><div class="cell">{{ sysFile.dirName }}</div></td> + <td><div class="cell">{{ sysFile.sysTypeName }}</div></td> + <td><div class="cell">{{ sysFile.typeName }}</div></td> + <td><div class="cell">{{ sysFile.total }}</div></td> + <td><div class="cell">{{ sysFile.free }}</div></td> + <td><div class="cell">{{ sysFile.used }}</div></td> + <td><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td> + </tr> + </tbody> + </table> + </div> + </el-card> + </el-col> + </el-row> + </div> +</template> + +<script> +import { getServer } from "@/api/monitor/server"; + +export default { + name: "Server", + data() { + return { + // 鍔犺浇灞備俊鎭� + loading: [], + // 鏈嶅姟鍣ㄤ俊鎭� + server: [] + }; + }, + created() { + this.getList(); + this.openLoading(); + }, + methods: { + /** 鏌ヨ鏈嶅姟鍣ㄤ俊鎭� */ + getList() { + getServer().then(response => { + this.server = response.data; + this.loading.close(); + }); + }, + // 鎵撳紑鍔犺浇灞� + openLoading() { + this.loading = this.$loading({ + lock: true, + text: "鎷煎懡璇诲彇涓�", + spinner: "el-icon-loading", + background: "rgba(0, 0, 0, 0.7)" + }); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/redirect.vue b/ruoyi-ui/src/views/redirect.vue new file mode 100644 index 0000000..db4c1d6 --- /dev/null +++ b/ruoyi-ui/src/views/redirect.vue @@ -0,0 +1,12 @@ +<script> +export default { + created() { + const { params, query } = this.$route + const { path } = params + this.$router.replace({ path: '/' + path, query }) + }, + render: function(h) { + return h() // avoid warning message + } +} +</script> diff --git a/ruoyi-ui/src/views/system/config/index.vue b/ruoyi-ui/src/views/system/config/index.vue new file mode 100644 index 0000000..db27c63 --- /dev/null +++ b/ruoyi-ui/src/views/system/config/index.vue @@ -0,0 +1,346 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="鍙傛暟鍚嶇О" prop="configName"> + <el-input + v-model="queryParams.configName" + placeholder="璇疯緭鍏ュ弬鏁板悕绉�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鍙傛暟閿悕" prop="configKey"> + <el-input + v-model="queryParams.configKey" + placeholder="璇疯緭鍏ュ弬鏁伴敭鍚�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="绯荤粺鍐呯疆" prop="configType"> + <el-select v-model="queryParams.configType" placeholder="绯荤粺鍐呯疆" clearable size="small"> + <el-option + v-for="dict in typeOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鍒涘缓鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:config:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:config:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:config:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:config:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鍙傛暟涓婚敭" align="center" prop="configId" /> + <el-table-column label="鍙傛暟鍚嶇О" align="center" prop="configName" :show-overflow-tooltip="true" /> + <el-table-column label="鍙傛暟閿悕" align="center" prop="configKey" :show-overflow-tooltip="true" /> + <el-table-column label="鍙傛暟閿��" align="center" prop="configValue" /> + <el-table-column label="绯荤粺鍐呯疆" align="center" prop="configType" :formatter="typeFormat" /> + <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:config:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:config:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="500px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="鍙傛暟鍚嶇О" prop="configName"> + <el-input v-model="form.configName" placeholder="璇疯緭鍏ュ弬鏁板悕绉�" /> + </el-form-item> + <el-form-item label="鍙傛暟閿悕" prop="configKey"> + <el-input v-model="form.configKey" placeholder="璇疯緭鍏ュ弬鏁伴敭鍚�" /> + </el-form-item> + <el-form-item label="鍙傛暟閿��" prop="configValue"> + <el-input v-model="form.configValue" placeholder="璇疯緭鍏ュ弬鏁伴敭鍊�" /> + </el-form-item> + <el-form-item label="绯荤粺鍐呯疆" prop="configType"> + <el-radio-group v-model="form.configType"> + <el-radio + v-for="dict in typeOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="澶囨敞" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" /> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig } from "@/api/system/config"; + +export default { + name: "Config", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 鍙傛暟琛ㄦ牸鏁版嵁 + configList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 绫诲瀷鏁版嵁瀛楀吀 + typeOptions: [], + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + configName: undefined, + configKey: undefined, + configType: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + configName: [ + { required: true, message: "鍙傛暟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + configKey: [ + { required: true, message: "鍙傛暟閿悕涓嶈兘涓虹┖", trigger: "blur" } + ], + configValue: [ + { required: true, message: "鍙傛暟閿�间笉鑳戒负绌�", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_yes_no").then(response => { + this.typeOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ鍙傛暟鍒楄〃 */ + getList() { + this.loading = true; + listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.configList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + // 鍙傛暟绯荤粺鍐呯疆瀛楀吀缈昏瘧 + typeFormat(row, column) { + return this.selectDictLabel(this.typeOptions, row.configType); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + configId: undefined, + configName: undefined, + configKey: undefined, + configValue: undefined, + configType: "Y", + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞鍙傛暟"; + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.configId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const configId = row.configId || this.ids + getConfig(configId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鍙傛暟"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.configId != undefined) { + updateConfig(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addConfig(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const configIds = row.configId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎鍙傛暟缂栧彿涓�"' + configIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delConfig(configIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夊弬鏁版暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportConfig(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/dept/index.vue new file mode 100644 index 0000000..a375885 --- /dev/null +++ b/ruoyi-ui/src/views/system/dept/index.vue @@ -0,0 +1,308 @@ +<template> + <div class="app-container"> + <el-form :inline="true"> + <el-form-item label="閮ㄩ棬鍚嶇О"> + <el-input + v-model="queryParams.deptName" + placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��"> + <el-select v-model="queryParams.status" placeholder="閮ㄩ棬鐘舵��" clearable size="small"> + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button + class="filter-item" + type="primary" + icon="el-icon-search" + size="mini" + @click="handleQuery" + >鎼滅储</el-button> + <el-button + class="filter-item" + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:dept:add']" + >鏂板</el-button> + </el-form-item> + </el-form> + + <el-table + v-loading="loading" + :data="deptList" + row-key="deptId" + default-expand-all + :tree-props="{children: 'children', hasChildren: 'hasChildren'}" + > + <el-table-column prop="deptName" label="閮ㄩ棬鍚嶇О" width="200"></el-table-column> + <el-table-column prop="orderNum" label="鎺掑簭" width="200"></el-table-column> + <el-table-column prop="status" label="鐘舵��" :formatter="statusFormat" width="100"></el-table-column> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="200"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:dept:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-plus" + @click="handleAdd(scope.row)" + v-hasPermi="['system:dept:add']" + >鏂板</el-button> + <el-button + v-if="scope.row.parentId != 0" + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:dept:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <!-- 娣诲姞鎴栦慨鏀归儴闂ㄥ璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="600px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-row> + <el-col :span="24" v-if="form.parentId !== 0"> + <el-form-item label="涓婄骇閮ㄩ棬" prop="parentId"> + <treeselect v-model="form.parentId" :options="deptOptions" placeholder="閫夋嫨涓婄骇閮ㄩ棬" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName"> + <el-input v-model="form.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鏄剧ず鎺掑簭" prop="orderNum"> + <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="璐熻矗浜�" prop="leader"> + <el-input v-model="form.leader" placeholder="璇疯緭鍏ヨ礋璐d汉" maxlength="20" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鑱旂郴鐢佃瘽" prop="phone"> + <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" maxlength="11" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="閭" prop="email"> + <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="閮ㄩ棬鐘舵��"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + </el-row> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listDept, getDept, treeselect, delDept, addDept, updateDept } from "@/api/system/dept"; +import Treeselect from "@riophae/vue-treeselect"; +import "@riophae/vue-treeselect/dist/vue-treeselect.css"; + +export default { + name: "Dept", + components: { Treeselect }, + data() { + return { + // 閬僵灞� + loading: true, + // 琛ㄦ牸鏍戞暟鎹� + deptList: [], + // 閮ㄩ棬鏍戦�夐」 + deptOptions: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + deptName: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + parentId: [ + { required: true, message: "涓婄骇閮ㄩ棬涓嶈兘涓虹┖", trigger: "blur" } + ], + deptName: [ + { required: true, message: "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + orderNum: [ + { required: true, message: "鑿滃崟椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ], + email: [ + { + type: "email", + message: "'璇疯緭鍏ユ纭殑閭鍦板潃", + trigger: ["blur", "change"] + } + ], + phone: [ + { + pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, + message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", + trigger: "blur" + } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_normal_disable").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ閮ㄩ棬鍒楄〃 */ + getList() { + this.loading = true; + listDept(this.queryParams).then(response => { + this.deptList = response.data; + this.loading = false; + }); + }, + /** 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� */ + getTreeselect() { + treeselect().then(response => { + this.deptOptions = response.data; + }); + }, + // 瀛楀吀鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + deptId: undefined, + parentId: undefined, + deptName: undefined, + orderNum: undefined, + leader: undefined, + phone: undefined, + email: undefined, + status: "0" + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.getList(); + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd(row) { + this.reset(); + this.getTreeselect(); + if (row != undefined) { + this.form.parentId = row.deptId; + } + this.open = true; + this.title = "娣诲姞閮ㄩ棬"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + this.getTreeselect(); + getDept(row.deptId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼閮ㄩ棬"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.deptId != undefined) { + updateDept(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addDept(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + this.$confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.deptName + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delDept(row.deptId); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue new file mode 100644 index 0000000..1580646 --- /dev/null +++ b/ruoyi-ui/src/views/system/dict/data.vue @@ -0,0 +1,355 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true"> + <el-form-item label="瀛楀吀鍚嶇О" prop="dictType"> + <el-select v-model="queryParams.dictType" size="small"> + <el-option + v-for="item in typeOptions" + :key="item.dictId" + :label="item.dictName" + :value="item.dictType" + /> + </el-select> + </el-form-item> + <el-form-item label="瀛楀吀鏍囩" prop="dictLabel"> + <el-input + v-model="queryParams.dictLabel" + placeholder="璇疯緭鍏ュ瓧鍏告爣绛�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select v-model="queryParams.status" placeholder="鏁版嵁鐘舵��" clearable size="small"> + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:dict:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:dict:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:dict:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:dict:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="瀛楀吀缂栫爜" align="center" prop="dictCode" /> + <el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel" /> + <el-table-column label="瀛楀吀閿��" align="center" prop="dictValue" /> + <el-table-column label="瀛楀吀鎺掑簭" align="center" prop="dictSort" /> + <el-table-column label="鐘舵��" align="center" prop="status" :formatter="statusFormat" /> + <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:dict:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:dict:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="500px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="瀛楀吀绫诲瀷"> + <el-input v-model="form.dictType" :disabled="true" /> + </el-form-item> + <el-form-item label="鏁版嵁鏍囩" prop="dictLabel"> + <el-input v-model="form.dictLabel" placeholder="璇疯緭鍏ユ暟鎹爣绛�" /> + </el-form-item> + <el-form-item label="鏁版嵁閿��" prop="dictValue"> + <el-input v-model="form.dictValue" placeholder="璇疯緭鍏ユ暟鎹敭鍊�" /> + </el-form-item> + <el-form-item label="鏄剧ず鎺掑簭" prop="dictSort"> + <el-input-number v-model="form.dictSort" controls-position="right" :min="0" /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="澶囨敞" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listData, getData, delData, addData, updateData, exportData } from "@/api/system/dict/data"; +import { listType, getType } from "@/api/system/dict/type"; + +export default { + name: "Data", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 瀛楀吀琛ㄦ牸鏁版嵁 + dataList: [], + // 榛樿瀛楀吀绫诲瀷 + defaultDictType: "", + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 绫诲瀷鏁版嵁瀛楀吀 + typeOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + dictName: undefined, + dictType: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + dictLabel: [ + { required: true, message: "鏁版嵁鏍囩涓嶈兘涓虹┖", trigger: "blur" } + ], + dictValue: [ + { required: true, message: "鏁版嵁閿�间笉鑳戒负绌�", trigger: "blur" } + ], + dictSort: [ + { required: true, message: "鏁版嵁椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + const dictId = this.$route.params && this.$route.params.dictId; + this.getType(dictId); + this.getTypeList(); + this.getDicts("sys_normal_disable").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ瀛楀吀绫诲瀷璇︾粏 */ + getType(dictId) { + getType(dictId).then(response => { + this.queryParams.dictType = response.data.dictType; + this.defaultDictType = response.data.dictType; + this.getList(); + }); + }, + /** 鏌ヨ瀛楀吀绫诲瀷鍒楄〃 */ + getTypeList() { + listType().then(response => { + this.typeOptions = response.rows; + }); + }, + /** 鏌ヨ瀛楀吀鏁版嵁鍒楄〃 */ + getList() { + this.loading = true; + listData(this.queryParams).then(response => { + this.dataList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鏁版嵁鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + dictCode: undefined, + dictLabel: undefined, + dictValue: undefined, + dictSort: 0, + status: "0", + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.queryParams.dictType = this.defaultDictType; + this.handleQuery(); + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞瀛楀吀鏁版嵁"; + this.form.dictType = this.queryParams.dictType; + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.dictCode) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const dictCode = row.dictCode || this.ids + getData(dictCode).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼瀛楀吀鏁版嵁"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.dictCode != undefined) { + updateData(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addData(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const dictCodes = row.dictCode || this.ids; + this.$confirm('鏄惁纭鍒犻櫎瀛楀吀缂栫爜涓�"' + dictCodes + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delData(dictCodes); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夋暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportData(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue new file mode 100644 index 0000000..3d42b63 --- /dev/null +++ b/ruoyi-ui/src/views/system/dict/index.vue @@ -0,0 +1,350 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="瀛楀吀鍚嶇О" prop="dictName"> + <el-input + v-model="queryParams.dictName" + placeholder="璇疯緭鍏ュ瓧鍏稿悕绉�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="瀛楀吀绫诲瀷" prop="dictType"> + <el-input + v-model="queryParams.dictType" + placeholder="璇疯緭鍏ュ瓧鍏哥被鍨�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select + v-model="queryParams.status" + placeholder="瀛楀吀鐘舵��" + clearable + size="small" + style="width: 240px" + > + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鍒涘缓鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:dict:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:dict:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:dict:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:dict:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="瀛楀吀缂栧彿" align="center" prop="dictId" /> + <el-table-column label="瀛楀吀鍚嶇О" align="center" prop="dictName" :show-overflow-tooltip="true" /> + <el-table-column label="瀛楀吀绫诲瀷" align="center" :show-overflow-tooltip="true"> + <template slot-scope="scope"> + <router-link :to="'/dict/type/data/' + scope.row.dictId" class="link-type"> + <span>{{ scope.row.dictType }}</span> + </router-link> + </template> + </el-table-column> + <el-table-column label="鐘舵��" align="center" prop="status" :formatter="statusFormat" /> + <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:dict:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:dict:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="500px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="瀛楀吀鍚嶇О" prop="dictName"> + <el-input v-model="form.dictName" placeholder="璇疯緭鍏ュ瓧鍏稿悕绉�" /> + </el-form-item> + <el-form-item label="瀛楀吀绫诲瀷" prop="dictType"> + <el-input v-model="form.dictType" placeholder="璇疯緭鍏ュ瓧鍏哥被鍨�" /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="澶囨敞" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listType, getType, delType, addType, updateType, exportType } from "@/api/system/dict/type"; + +export default { + name: "Dict", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 瀛楀吀琛ㄦ牸鏁版嵁 + typeList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + dictName: undefined, + dictType: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + dictName: [ + { required: true, message: "瀛楀吀鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + dictType: [ + { required: true, message: "瀛楀吀绫诲瀷涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_normal_disable").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ瀛楀吀绫诲瀷鍒楄〃 */ + getList() { + this.loading = true; + listType(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.typeList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + // 瀛楀吀鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + dictId: undefined, + dictName: undefined, + dictType: undefined, + status: "0", + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞瀛楀吀绫诲瀷"; + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.dictId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const dictId = row.dictId || this.ids + getType(dictId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼瀛楀吀绫诲瀷"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.dictId != undefined) { + updateType(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addType(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const dictIds = row.dictId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎瀛楀吀缂栧彿涓�"' + dictIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delType(dictIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夌被鍨嬫暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportType(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/log/index.vue b/ruoyi-ui/src/views/system/log/index.vue new file mode 100644 index 0000000..7bf6148 --- /dev/null +++ b/ruoyi-ui/src/views/system/log/index.vue @@ -0,0 +1,3 @@ +<template > + <router-view /> +</template> diff --git a/ruoyi-ui/src/views/system/menu/index.vue b/ruoyi-ui/src/views/system/menu/index.vue new file mode 100644 index 0000000..5476329 --- /dev/null +++ b/ruoyi-ui/src/views/system/menu/index.vue @@ -0,0 +1,337 @@ +<template> + <div class="app-container"> + <el-form :inline="true"> + <el-form-item label="鑿滃崟鍚嶇О"> + <el-input + v-model="queryParams.menuName" + placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��"> + <el-select v-model="queryParams.visible" placeholder="鑿滃崟鐘舵��" clearable size="small"> + <el-option + v-for="dict in visibleOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['system:menu:add']">鏂板</el-button> + </el-form-item> + </el-form> + + <el-table + v-loading="loading" + :data="menuList" + row-key="menuId" + :tree-props="{children: 'children', hasChildren: 'hasChildren'}" + > + <el-table-column prop="menuName" label="鑿滃崟鍚嶇О" :show-overflow-tooltip="true" width="130px"></el-table-column> + <el-table-column prop="icon" label="鍥炬爣" align="center" width="100px"> + <template slot-scope="scope"> + <svg-icon :icon-class="scope.row.icon" /> + </template> + </el-table-column> + <el-table-column prop="orderNum" label="鎺掑簭" width="60px"></el-table-column> + <el-table-column prop="perms" label="鏉冮檺鏍囪瘑" width="130px" :show-overflow-tooltip="true"></el-table-column> + <el-table-column prop="component" label="缁勪欢璺緞" width="180px" :show-overflow-tooltip="true"></el-table-column> + <el-table-column prop="visible" label="鍙" :formatter="visibleFormat" width="80px"></el-table-column> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" width="180" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:menu:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-plus" + @click="handleAdd(scope.row)" + v-hasPermi="['system:menu:add']" + >鏂板</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:menu:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <!-- 娣诲姞鎴栦慨鏀硅彍鍗曞璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="600px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-row> + <el-col :span="24"> + <el-form-item label="涓婄骇鑿滃崟"> + <treeselect + v-model="form.parentId" + :options="menuOptions" + :show-count="true" + placeholder="閫夋嫨涓婄骇鑿滃崟" + /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="鑿滃崟绫诲瀷" prop="menuType"> + <el-radio-group v-model="form.menuType"> + <el-radio label="M">鐩綍</el-radio> + <el-radio label="C">鑿滃崟</el-radio> + <el-radio label="F">鎸夐挳</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item v-if="form.menuType != 'F'" label="鑿滃崟鍥炬爣"> + <el-popover + placement="bottom-start" + width="460" + trigger="click" + @show="$refs['iconSelect'].reset()" + > + <IconSelect ref="iconSelect" @selected="selected" /> + <el-input slot="reference" v-model="form.icon" placeholder="鐐瑰嚮閫夋嫨鍥炬爣" readonly> + <svg-icon + v-if="form.icon" + slot="prefix" + :icon-class="form.icon" + class="el-input__icon" + style="height: 32px;width: 16px;" + /> + <i v-else slot="prefix" class="el-icon-search el-input__icon" /> + </el-input> + </el-popover> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鑿滃崟鍚嶇О" prop="menuName"> + <el-input v-model="form.menuName" placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鏄剧ず鎺掑簭" prop="orderNum"> + <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item v-if="form.menuType != 'F'" label="鏄惁澶栭摼"> + <el-radio-group v-model="form.isFrame"> + <el-radio label="0">鏄�</el-radio> + <el-radio label="1">鍚�</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item v-if="form.menuType != 'F'" label="璺敱鍦板潃" prop="path"> + <el-input v-model="form.path" placeholder="璇疯緭鍏ヨ矾鐢卞湴鍧�" /> + </el-form-item> + </el-col> + <el-col :span="12" v-if="form.menuType == 'C'"> + <el-form-item label="缁勪欢璺緞" prop="component"> + <el-input v-model="form.component" placeholder="璇疯緭鍏ョ粍浠惰矾寰�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item v-if="form.menuType != 'M'" label="鏉冮檺鏍囪瘑"> + <el-input v-model="form.perms" placeholder="璇锋潈闄愭爣璇�" maxlength="50" /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item v-if="form.menuType != 'F'" label="鑿滃崟鐘舵��"> + <el-radio-group v-model="form.visible"> + <el-radio + v-for="dict in visibleOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + </el-row> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listMenu, getMenu, treeselect, delMenu, addMenu, updateMenu } from "@/api/system/menu"; +import Treeselect from "@riophae/vue-treeselect"; +import "@riophae/vue-treeselect/dist/vue-treeselect.css"; +import IconSelect from "@/components/IconSelect"; + +export default { + name: "Menu", + components: { Treeselect, IconSelect }, + data() { + return { + // 閬僵灞� + loading: true, + // 鑿滃崟琛ㄦ牸鏍戞暟鎹� + menuList: [], + // 鑿滃崟鏍戦�夐」 + menuOptions: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鑿滃崟鐘舵�佹暟鎹瓧鍏� + visibleOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + menuName: undefined, + visible: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + menuName: [ + { required: true, message: "鑿滃崟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + orderNum: [ + { required: true, message: "鑿滃崟椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_show_hide").then(response => { + this.visibleOptions = response.data; + }); + }, + methods: { + // 閫夋嫨鍥炬爣 + selected(name) { + this.form.icon = name; + }, + /** 鏌ヨ鑿滃崟鍒楄〃 */ + getList() { + this.loading = true; + listMenu(this.queryParams).then(response => { + this.menuList = response.data; + this.loading = false; + }); + }, + /** 鏌ヨ鑿滃崟涓嬫媺鏍戠粨鏋� */ + getTreeselect() { + treeselect().then(response => { + this.menuOptions = []; + const menu = { id: 0, label: '涓荤被鐩�', children: [] }; + menu.children = response.data; + this.menuOptions.push(menu); + }); + }, + // 鑿滃崟鏄剧ず鐘舵�佸瓧鍏哥炕璇� + visibleFormat(row, column) { + if (row.menuType == "F") { + return ""; + } + return this.selectDictLabel(this.visibleOptions, row.visible); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + menuId: undefined, + parentId: 0, + menuName: undefined, + icon: undefined, + menuType: "M", + orderNum: undefined, + isFrame: "1", + visible: "0" + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.getList(); + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd(row) { + this.reset(); + this.getTreeselect(); + if (row != null) { + this.form.parentId = row.menuId; + } + this.open = true; + this.title = "娣诲姞鑿滃崟"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + this.getTreeselect(); + getMenu(row.menuId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鑿滃崟"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.menuId != undefined) { + updateMenu(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addMenu(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + this.$confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.menuName + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delMenu(row.menuId); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/notice/index.vue b/ruoyi-ui/src/views/system/notice/index.vue new file mode 100644 index 0000000..555b33d --- /dev/null +++ b/ruoyi-ui/src/views/system/notice/index.vue @@ -0,0 +1,345 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="鍏憡鏍囬" prop="noticeTitle"> + <el-input + v-model="queryParams.noticeTitle" + placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鎿嶄綔浜哄憳" prop="createBy"> + <el-input + v-model="queryParams.createBy" + placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="绫诲瀷" prop="noticeType"> + <el-select v-model="queryParams.noticeType" placeholder="鍏憡绫诲瀷" clearable size="small"> + <el-option + v-for="dict in typeOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:notice:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:notice:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:notice:remove']" + >鍒犻櫎</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="搴忓彿" align="center" prop="noticeId" width="100" /> + <el-table-column + label="鍏憡鏍囬" + align="center" + prop="noticeTitle" + :show-overflow-tooltip="true" + /> + <el-table-column + label="鍏憡绫诲瀷" + align="center" + prop="noticeType" + :formatter="typeFormat" + width="100" + /> + <el-table-column + label="鐘舵��" + align="center" + prop="status" + :formatter="statusFormat" + width="100" + /> + <el-table-column label="鍒涘缓鑰�" align="center" prop="createBy" width="100" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="100"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:notice:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:notice:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀瑰叕鍛婂璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="780px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-row> + <el-col :span="12"> + <el-form-item label="鍏憡鏍囬" prop="noticeTitle"> + <el-input v-model="form.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鍏憡绫诲瀷" prop="noticeType"> + <el-select v-model="form.noticeType" placeholder="璇烽�夋嫨"> + <el-option + v-for="dict in typeOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="鐘舵��"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="鍐呭"> + <Editor v-model="form.noticeContent" /> + </el-form-item> + </el-col> + </el-row> + </el-form> + <div slot="footer" class="dialog-footer" style="padding-top:20px"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listNotice, getNotice, delNotice, addNotice, updateNotice, exportNotice } from "@/api/system/notice"; +import Editor from '@/components/Editor'; + +export default { + name: "Notice", + components: { + Editor + }, + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 鍏憡琛ㄦ牸鏁版嵁 + noticeList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 绫诲瀷鏁版嵁瀛楀吀 + statusOptions: [], + // 鐘舵�佹暟鎹瓧鍏� + typeOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + noticeTitle: undefined, + createBy: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + noticeTitle: [ + { required: true, message: "鍏憡鏍囬涓嶈兘涓虹┖", trigger: "blur" } + ], + noticeType: [ + { required: true, message: "鍏憡绫诲瀷涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_notice_status").then(response => { + this.statusOptions = response.data; + }); + this.getDicts("sys_notice_type").then(response => { + this.typeOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ鍏憡鍒楄〃 */ + getList() { + this.loading = true; + listNotice(this.queryParams).then(response => { + this.noticeList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍏憡鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + // 鍏憡鐘舵�佸瓧鍏哥炕璇� + typeFormat(row, column) { + return this.selectDictLabel(this.typeOptions, row.noticeType); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + noticeId: undefined, + noticeTitle: undefined, + noticeType: undefined, + noticeContent: undefined, + status: "0" + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.noticeId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞鍏憡"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const noticeId = row.noticeId || this.ids + getNotice(noticeId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鍏憡"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.noticeId != undefined) { + updateNotice(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addNotice(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const noticeIds = row.noticeId || this.ids + this.$confirm('鏄惁纭鍒犻櫎鍏憡缂栧彿涓�"' + noticeIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delNotice(noticeIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/post/index.vue b/ruoyi-ui/src/views/system/post/index.vue new file mode 100644 index 0000000..1bd01f3 --- /dev/null +++ b/ruoyi-ui/src/views/system/post/index.vue @@ -0,0 +1,327 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="宀椾綅缂栫爜" prop="postCode"> + <el-input + v-model="queryParams.postCode" + placeholder="璇疯緭鍏ュ矖浣嶇紪鐮�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="宀椾綅鍚嶇О" prop="postName"> + <el-input + v-model="queryParams.postName" + placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select v-model="queryParams.status" placeholder="宀椾綅鐘舵��" clearable size="small"> + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:post:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:post:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:post:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:post:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="宀椾綅缂栧彿" align="center" prop="postId" /> + <el-table-column label="宀椾綅缂栫爜" align="center" prop="postCode" /> + <el-table-column label="宀椾綅鍚嶇О" align="center" prop="postName" /> + <el-table-column label="宀椾綅鎺掑簭" align="center" prop="postSort" /> + <el-table-column label="鐘舵��" align="center" prop="status" :formatter="statusFormat" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:post:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:post:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀瑰矖浣嶅璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="500px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="宀椾綅鍚嶇О" prop="postName"> + <el-input v-model="form.postName" placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" /> + </el-form-item> + <el-form-item label="宀椾綅缂栫爜" prop="postCode"> + <el-input v-model="form.postCode" placeholder="璇疯緭鍏ョ紪鐮佸悕绉�" /> + </el-form-item> + <el-form-item label="宀椾綅椤哄簭" prop="postSort"> + <el-input-number v-model="form.postSort" controls-position="right" :min="0" /> + </el-form-item> + <el-form-item label="宀椾綅鐘舵��" prop="status"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="澶囨敞" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" /> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listPost, getPost, delPost, addPost, updatePost, exportPost } from "@/api/system/post"; + +export default { + name: "Post", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 宀椾綅琛ㄦ牸鏁版嵁 + postList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + postCode: undefined, + postName: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + postName: [ + { required: true, message: "宀椾綅鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + postCode: [ + { required: true, message: "宀椾綅缂栫爜涓嶈兘涓虹┖", trigger: "blur" } + ], + postSort: [ + { required: true, message: "宀椾綅椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_normal_disable").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ宀椾綅鍒楄〃 */ + getList() { + this.loading = true; + listPost(this.queryParams).then(response => { + this.postList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 宀椾綅鐘舵�佸瓧鍏哥炕璇� + statusFormat(row, column) { + return this.selectDictLabel(this.statusOptions, row.status); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + postId: undefined, + postCode: undefined, + postName: undefined, + postSort: 0, + status: "0", + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.postId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞宀椾綅"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const postId = row.postId || this.ids + getPost(postId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼宀椾綅"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.postId != undefined) { + updatePost(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addPost(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const postIds = row.postId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎宀椾綅缂栧彿涓�"' + postIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delPost(postIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夊矖浣嶆暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportPost(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue new file mode 100644 index 0000000..f234cd9 --- /dev/null +++ b/ruoyi-ui/src/views/system/role/index.vue @@ -0,0 +1,548 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true"> + <el-form-item label="瑙掕壊鍚嶇О" prop="roleName"> + <el-input + v-model="queryParams.roleName" + placeholder="璇疯緭鍏ヨ鑹插悕绉�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鏉冮檺瀛楃" prop="roleKey"> + <el-input + v-model="queryParams.roleKey" + placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select + v-model="queryParams.status" + placeholder="瑙掕壊鐘舵��" + clearable + size="small" + style="width: 240px" + > + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鍒涘缓鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:role:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:role:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:role:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:post:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="瑙掕壊缂栧彿" prop="roleId" width="120" /> + <el-table-column label="瑙掕壊鍚嶇О" prop="roleName" :show-overflow-tooltip="true" width="150" /> + <el-table-column label="鏉冮檺瀛楃" prop="roleKey" :show-overflow-tooltip="true" width="150" /> + <el-table-column label="鏄剧ず椤哄簭" prop="roleSort" width="100" /> + <el-table-column label="鐘舵��" align="center" width="100"> + <template slot-scope="scope"> + <el-switch + v-model="scope.row.status" + active-value="0" + inactive-value="1" + @change="handleStatusChange(scope.row)" + ></el-switch> + </template> + </el-table-column> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:role:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-circle-check" + @click="handleDataScope(scope.row)" + v-hasPermi="['system:role:edit']" + >鏁版嵁鏉冮檺</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:role:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀硅鑹查厤缃璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="500px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="瑙掕壊鍚嶇О" prop="roleName"> + <el-input v-model="form.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" /> + </el-form-item> + <el-form-item label="鏉冮檺瀛楃" prop="roleKey"> + <el-input v-model="form.roleKey" placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" /> + </el-form-item> + <el-form-item label="瑙掕壊椤哄簭" prop="roleSort"> + <el-input-number v-model="form.roleSort" controls-position="right" :min="0" /> + </el-form-item> + <el-form-item label="鐘舵��"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="鑿滃崟鏉冮檺"> + <el-tree + :data="menuOptions" + show-checkbox + ref="menu" + node-key="id" + empty-text="鍔犺浇涓紝璇风◢鍚�" + :props="defaultProps" + ></el-tree> + </el-form-item> + <el-form-item label="澶囨敞"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + + <!-- 鍒嗛厤瑙掕壊鏁版嵁鏉冮檺瀵硅瘽妗� --> + <el-dialog :title="title" :visible.sync="openDataScope" width="500px"> + <el-form :model="form" label-width="80px"> + <el-form-item label="瑙掕壊鍚嶇О"> + <el-input v-model="form.roleName" :disabled="true" /> + </el-form-item> + <el-form-item label="鏉冮檺瀛楃"> + <el-input v-model="form.roleKey" :disabled="true" /> + </el-form-item> + <el-form-item label="鏉冮檺鑼冨洿"> + <el-select v-model="form.dataScope"> + <el-option + v-for="item in dataScopeOptions" + :key="item.value" + :label="item.label" + :value="item.value" + ></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏁版嵁鏉冮檺" v-show="form.dataScope == 2"> + <el-tree + :data="deptOptions" + show-checkbox + default-expand-all + ref="dept" + node-key="id" + empty-text="鍔犺浇涓紝璇风◢鍚�" + :props="defaultProps" + ></el-tree> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitDataScope">纭� 瀹�</el-button> + <el-button @click="cancelDataScope">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listRole, getRole, delRole, addRole, updateRole, exportRole, dataScope, changeRoleStatus } from "@/api/system/role"; +import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu"; +import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept"; + +export default { + name: "Role", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 瑙掕壊琛ㄦ牸鏁版嵁 + roleList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏄惁鏄剧ず寮瑰嚭灞傦紙鏁版嵁鏉冮檺锛� + openDataScope: false, + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 鏁版嵁鑼冨洿閫夐」 + dataScopeOptions: [ + { + value: "1", + label: "鍏ㄩ儴鏁版嵁鏉冮檺" + }, + { + value: "2", + label: "鑷畾鏁版嵁鏉冮檺" + }, + { + value: "3", + label: "鏈儴闂ㄦ暟鎹潈闄�" + }, + { + value: "4", + label: "鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺" + }, + { + value: "5", + label: "浠呮湰浜烘暟鎹潈闄�" + } + ], + // 鑿滃崟鍒楄〃 + menuOptions: [], + // 閮ㄩ棬鍒楄〃 + deptOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + roleName: undefined, + roleKey: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + defaultProps: { + children: "children", + label: "label" + }, + // 琛ㄥ崟鏍¢獙 + rules: { + roleName: [ + { required: true, message: "瑙掕壊鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + roleKey: [ + { required: true, message: "鏉冮檺瀛楃涓嶈兘涓虹┖", trigger: "blur" } + ], + roleSort: [ + { required: true, message: "瑙掕壊椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + this.getDicts("sys_normal_disable").then(response => { + this.statusOptions = response.data; + }); + }, + methods: { + /** 鏌ヨ瑙掕壊鍒楄〃 */ + getList() { + this.loading = true; + listRole(this.addDateRange(this.queryParams, this.dateRange)).then( + response => { + this.roleList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + /** 鏌ヨ鑿滃崟鏍戠粨鏋� */ + getMenuTreeselect() { + menuTreeselect().then(response => { + this.menuOptions = response.data; + }); + }, + /** 鏌ヨ閮ㄩ棬鏍戠粨鏋� */ + getDeptTreeselect() { + deptTreeselect().then(response => { + this.deptOptions = response.data; + }); + }, + // 鎵�鏈夎彍鍗曡妭鐐规暟鎹� + getMenuAllCheckedKeys() { + // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐� + let checkedKeys = this.$refs.menu.getHalfCheckedKeys(); + // 鍗婇�変腑鐨勮彍鍗曡妭鐐� + let halfCheckedKeys = this.$refs.menu.getCheckedKeys(); + checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); + return checkedKeys; + }, + // 鎵�鏈夐儴闂ㄨ妭鐐规暟鎹� + getDeptAllCheckedKeys() { + // 鐩墠琚�変腑鐨勯儴闂ㄨ妭鐐� + let checkedKeys = this.$refs.dept.getHalfCheckedKeys(); + // 鍗婇�変腑鐨勯儴闂ㄨ妭鐐� + let halfCheckedKeys = this.$refs.dept.getCheckedKeys(); + checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); + return checkedKeys; + }, + /** 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戠粨鏋� */ + getRoleMenuTreeselect(roleId) { + roleMenuTreeselect(roleId).then(response => { + this.menuOptions = response.menus; + this.$refs.menu.setCheckedKeys(response.checkedKeys); + }); + }, + /** 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戠粨鏋� */ + getRoleDeptTreeselect(roleId) { + roleDeptTreeselect(roleId).then(response => { + this.deptOptions = response.depts; + this.$refs.dept.setCheckedKeys(response.checkedKeys); + }); + }, + // 瑙掕壊鐘舵�佷慨鏀� + handleStatusChange(row) { + let text = row.status === "0" ? "鍚敤" : "鍋滅敤"; + this.$confirm('纭瑕�"' + text + '""' + row.roleName + '"瑙掕壊鍚�?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return changeRoleStatus(row.roleId, row.status); + }).then(() => { + this.msgSuccess(text + "鎴愬姛"); + }).catch(function() { + row.status = row.status === "0" ? "1" : "0"; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 鍙栨秷鎸夐挳锛堟暟鎹潈闄愶級 + cancelDataScope() { + this.openDataScope = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + if (this.$refs.menu != undefined) { + this.$refs.menu.setCheckedKeys([]); + } + this.form = { + roleId: undefined, + roleName: undefined, + roleKey: undefined, + roleSort: 0, + status: "0", + menuIds: [], + deptIds: [], + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.roleId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.getMenuTreeselect(); + this.open = true; + this.title = "娣诲姞瑙掕壊"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const roleId = row.roleId || this.ids + this.$nextTick(() => { + this.getRoleMenuTreeselect(roleId); + }); + getRole(roleId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼瑙掕壊"; + }); + }, + /** 鍒嗛厤鏁版嵁鏉冮檺鎿嶄綔 */ + handleDataScope(row) { + this.reset(); + this.$nextTick(() => { + this.getRoleDeptTreeselect(row.roleId); + }); + getRole(row.roleId).then(response => { + this.form = response.data; + this.openDataScope = true; + this.title = "鍒嗛厤鏁版嵁鏉冮檺"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.roleId != undefined) { + this.form.menuIds = this.getMenuAllCheckedKeys(); + updateRole(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + this.form.menuIds = this.getMenuAllCheckedKeys(); + addRole(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鎻愪氦鎸夐挳锛堟暟鎹潈闄愶級 */ + submitDataScope: function() { + if (this.form.roleId != undefined) { + this.form.deptIds = this.getDeptAllCheckedKeys(); + dataScope(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.openDataScope = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const roleIds = row.roleId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎瑙掕壊缂栧彿涓�"' + roleIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delRole(roleIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夎鑹叉暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportRole(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue new file mode 100644 index 0000000..027f4ab --- /dev/null +++ b/ruoyi-ui/src/views/system/user/index.vue @@ -0,0 +1,663 @@ +<template> + <div class="app-container"> + <el-row :gutter="20"> + <!--閮ㄩ棬鏁版嵁--> + <el-col :span="4" :xs="24"> + <div class="head-container"> + <el-input + v-model="deptName" + placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" + clearable + size="small" + prefix-icon="el-icon-search" + style="margin-bottom: 20px" + /> + </div> + <div class="head-container"> + <el-tree + :data="deptOptions" + :props="defaultProps" + :expand-on-click-node="false" + :filter-node-method="filterNode" + ref="tree" + default-expand-all + @node-click="handleNodeClick" + /> + </div> + </el-col> + <!--鐢ㄦ埛鏁版嵁--> + <el-col :span="20" :xs="24"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName"> + <el-input + v-model="queryParams.userName" + placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input + v-model="queryParams.phonenumber" + placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" + clearable + size="small" + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select + v-model="queryParams.status" + placeholder="鐢ㄦ埛鐘舵��" + clearable + size="small" + style="width: 240px" + > + <el-option + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> + <el-form-item label="鍒涘缓鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['system:user:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['system:user:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['system:user:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="info" + icon="el-icon-upload2" + size="mini" + @click="handleImport" + v-hasPermi="['system:user:import']" + >瀵煎叆</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['system:user:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="40" align="center" /> + <el-table-column label="鐢ㄦ埛缂栧彿" align="center" prop="userId" /> + <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" /> + <el-table-column label="鐢ㄦ埛鏄电О" align="center" prop="nickName" :show-overflow-tooltip="true" /> + <el-table-column label="閮ㄩ棬" align="center" prop="dept.deptName" :show-overflow-tooltip="true" /> + <el-table-column label="鎵嬫満鍙风爜" align="center" prop="phonenumber" width="120" /> + <el-table-column label="鐘舵��" align="center"> + <template slot-scope="scope"> + <el-switch + v-model="scope.row.status" + active-value="0" + inactive-value="1" + @change="handleStatusChange(scope.row)" + ></el-switch> + </template> + </el-table-column> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="160"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column + label="鎿嶄綔" + align="center" + width="180" + class-name="small-padding fixed-width" + > + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:user:edit']" + >淇敼</el-button> + <el-button + v-if="scope.row.userId !== 1" + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:user:remove']" + >鍒犻櫎</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-key" + @click="handleResetPwd(scope.row)" + v-hasPermi="['system:user:resetPwd']" + >閲嶇疆</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + </el-col> + </el-row> + + <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 --> + <el-dialog :title="title" :visible.sync="open" width="600px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-row> + <el-col :span="12"> + <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName"> + <el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="褰掑睘閮ㄩ棬" prop="deptId"> + <treeselect v-model="form.deptId" :options="deptOptions" placeholder="璇烽�夋嫨褰掑睘閮ㄩ棬" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input v-model="form.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" maxlength="11" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="閭" prop="email"> + <el-input v-model="form.email" placeholder="璇疯緭鍏ラ偖绠�" maxlength="50" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鐢ㄦ埛鍚嶇О" prop="userName"> + <el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛瀵嗙爜" prop="password"> + <el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鐢ㄦ埛鎬у埆"> + <el-select v-model="form.sex" placeholder="璇烽�夋嫨"> + <el-option + v-for="dict in sexOptions" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鐘舵��"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in statusOptions" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item label="宀椾綅"> + <el-select v-model="form.postIds" multiple placeholder="璇烽�夋嫨"> + <el-option + v-for="item in postOptions" + :key="item.postId" + :label="item.postName" + :value="item.postId" + :disabled="item.status == 1" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="瑙掕壊"> + <el-select v-model="form.roleIds" multiple placeholder="璇烽�夋嫨"> + <el-option + v-for="item in roleOptions" + :key="item.roleId" + :label="item.roleName" + :value="item.roleId" + :disabled="item.status == 1" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="澶囨敞"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </el-form-item> + </el-col> + </el-row> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + + <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� --> + <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px"> + <el-upload + ref="upload" + :limit="1" + accept=".xlsx, .xls" + :headers="upload.headers" + :action="upload.url + '?updateSupport=' + upload.updateSupport" + :disabled="upload.isUploading" + :on-progress="handleFileUploadProgress" + :on-success="handleFileSuccess" + :auto-upload="false" + drag + > + <i class="el-icon-upload"></i> + <div class="el-upload__text"> + 灏嗘枃浠舵嫋鍒版澶勶紝鎴� + <em>鐐瑰嚮涓婁紶</em> + </div> + <div class="el-upload__tip" slot="tip"> + <el-checkbox v-model="upload.updateSupport" />鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹� + <el-link type="info" style="font-size:12px" @click="importTemplate">涓嬭浇妯℃澘</el-link> + </div> + <div class="el-upload__tip" style="color:red" slot="tip">鎻愮ず锛氫粎鍏佽瀵煎叆鈥渪ls鈥濇垨鈥渪lsx鈥濇牸寮忔枃浠讹紒</div> + </el-upload> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button> + <el-button @click="upload.open = false">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus, importTemplate } from "@/api/system/user"; +import { getToken } from "@/utils/auth"; +import { treeselect } from "@/api/system/dept"; +import Treeselect from "@riophae/vue-treeselect"; +import "@riophae/vue-treeselect/dist/vue-treeselect.css"; + +export default { + name: "User", + components: { Treeselect }, + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 鐢ㄦ埛琛ㄦ牸鏁版嵁 + userList: null, + // 寮瑰嚭灞傛爣棰� + title: "", + // 閮ㄩ棬鏍戦�夐」 + deptOptions: undefined, + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 閮ㄩ棬鍚嶇О + deptName: undefined, + // 榛樿瀵嗙爜 + initPassword: undefined, + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 鐘舵�佹暟鎹瓧鍏� + statusOptions: [], + // 鎬у埆鐘舵�佸瓧鍏� + sexOptions: [], + // 宀椾綅閫夐」 + postOptions: [], + // 瑙掕壊閫夐」 + roleOptions: [], + // 琛ㄥ崟鍙傛暟 + form: {}, + defaultProps: { + children: "children", + label: "label" + }, + // 鐢ㄦ埛瀵煎叆鍙傛暟 + upload: { + // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛� + open: false, + // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛� + title: "", + // 鏄惁绂佺敤涓婁紶 + isUploading: false, + // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹� + updateSupport: 0, + // 璁剧疆涓婁紶鐨勮姹傚ご閮� + headers: { Authorization: "Bearer " + getToken() }, + // 涓婁紶鐨勫湴鍧� + url: process.env.VUE_APP_BASE_API + "/system/user/importData" + }, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + userName: undefined, + phonenumber: undefined, + status: undefined, + deptId: undefined + }, + // 琛ㄥ崟鏍¢獙 + rules: { + userName: [ + { required: true, message: "鐢ㄦ埛鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + nickName: [ + { required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" } + ], + deptId: [ + { required: true, message: "褰掑睘閮ㄩ棬涓嶈兘涓虹┖", trigger: "blur" } + ], + password: [ + { required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" } + ], + email: [ + { + type: "email", + message: "'璇疯緭鍏ユ纭殑閭鍦板潃", + trigger: ["blur", "change"] + } + ], + phonenumber: [ + { + pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, + message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", + trigger: "blur" + } + ] + } + }; + }, + watch: { + // 鏍规嵁鍚嶇О绛涢�夐儴闂ㄦ爲 + deptName(val) { + this.$refs.tree.filter(val); + } + }, + created() { + this.getList(); + this.getTreeselect(); + this.getDicts("sys_normal_disable").then(response => { + this.statusOptions = response.data; + }); + this.getDicts("sys_user_sex").then(response => { + this.sexOptions = response.data; + }); + this.getConfigKey("sys.user.initPassword").then(response => { + this.initPassword = response.data; + }); + }, + methods: { + /** 鏌ヨ鐢ㄦ埛鍒楄〃 */ + getList() { + this.loading = true; + listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.userList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + /** 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� */ + getTreeselect() { + treeselect().then(response => { + this.deptOptions = response.data; + }); + }, + // 绛涢�夎妭鐐� + filterNode(value, data) { + if (!value) return true; + return data.label.indexOf(value) !== -1; + }, + // 鑺傜偣鍗曞嚮浜嬩欢 + handleNodeClick(data) { + this.queryParams.deptId = data.id; + this.getList(); + }, + // 鐢ㄦ埛鐘舵�佷慨鏀� + handleStatusChange(row) { + let text = row.status === "0" ? "鍚敤" : "鍋滅敤"; + this.$confirm('纭瑕�"' + text + '""' + row.userName + '"鐢ㄦ埛鍚�?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return changeUserStatus(row.userId, row.status); + }).then(() => { + this.msgSuccess(text + "鎴愬姛"); + }).catch(function() { + row.status = row.status === "0" ? "1" : "0"; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + userId: undefined, + deptId: undefined, + userName: undefined, + nickName: undefined, + password: undefined, + phonenumber: undefined, + email: undefined, + sex: undefined, + status: "0", + remark: undefined, + postIds: [], + roleIds: [] + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.page = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.userId); + this.single = selection.length != 1; + this.multiple = !selection.length; + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.getTreeselect(); + getUser().then(response => { + this.postOptions = response.posts; + this.roleOptions = response.roles; + this.open = true; + this.title = "娣诲姞鐢ㄦ埛"; + this.form.password = this.initPassword; + }); + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + this.getTreeselect(); + const userId = row.userId || this.ids; + getUser(userId).then(response => { + this.form = response.data; + this.postOptions = response.posts; + this.roleOptions = response.roles; + this.form.postIds = response.postIds; + this.form.roleIds = response.roleIds; + this.open = true; + this.title = "淇敼鐢ㄦ埛"; + this.form.password = ""; + }); + }, + /** 閲嶇疆瀵嗙爜鎸夐挳鎿嶄綔 */ + handleResetPwd(row) { + this.$prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷" + }).then(({ value }) => { + resetUserPwd(row.userId, value).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + value); + } else { + this.msgError(response.msg); + } + }); + }).catch(() => {}); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.userId != undefined) { + updateUser(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + addUser(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const userIds = row.userId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎鐢ㄦ埛缂栧彿涓�"' + userIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delUser(userIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈夌敤鎴锋暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return exportUser(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + }, + /** 瀵煎叆鎸夐挳鎿嶄綔 */ + handleImport() { + this.upload.title = "鐢ㄦ埛瀵煎叆"; + this.upload.open = true; + }, + /** 涓嬭浇妯℃澘鎿嶄綔 */ + importTemplate() { + importTemplate().then(response => { + this.download(response.msg); + }); + }, + // 鏂囦欢涓婁紶涓鐞� + handleFileUploadProgress(event, file, fileList) { + this.upload.isUploading = true; + }, + // 鏂囦欢涓婁紶鎴愬姛澶勭悊 + handleFileSuccess(response, file, fileList) { + this.upload.open = false; + this.upload.isUploading = false; + this.$refs.upload.clearFiles(); + this.$alert(response.msg, "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true }); + this.getList(); + }, + // 鎻愪氦涓婁紶鏂囦欢 + submitFileForm() { + this.$refs.upload.submit(); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/user/profile/index.vue b/ruoyi-ui/src/views/system/user/profile/index.vue new file mode 100644 index 0000000..69d07a0 --- /dev/null +++ b/ruoyi-ui/src/views/system/user/profile/index.vue @@ -0,0 +1,91 @@ +<template> + <div class="app-container"> + <el-row :gutter="20"> + <el-col :span="6" :xs="24"> + <el-card class="box-card"> + <div slot="header" class="clearfix"> + <span>涓汉淇℃伅</span> + </div> + <div> + <div class="text-center"> + <userAvatar :user="user" /> + </div> + <ul class="list-group list-group-striped"> + <li class="list-group-item"> + <svg-icon icon-class="user" />鐢ㄦ埛鍚嶇О + <div class="pull-right">{{ user.userName }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="phone" />鎵嬫満鍙风爜 + <div class="pull-right">{{ user.phonenumber }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="email" />鐢ㄦ埛閭 + <div class="pull-right">{{ user.email }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="tree" />鎵�灞為儴闂� + <div class="pull-right" v-if="user.dept">{{ user.dept.deptName }} / {{ postGroup }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="peoples" />鎵�灞炶鑹� + <div class="pull-right">{{ roleGroup }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="date" />鍒涘缓鏃ユ湡 + <div class="pull-right">2018-08-23 09:11:56</div> + </li> + </ul> + </div> + </el-card> + </el-col> + <el-col :span="18" :xs="24"> + <el-card> + <div slot="header" class="clearfix"> + <span>鍩烘湰璧勬枡</span> + </div> + <el-tabs v-model="activeTab"> + <el-tab-pane label="鍩烘湰璧勬枡" name="userinfo"> + <userInfo :user="user" /> + </el-tab-pane> + <el-tab-pane label="淇敼瀵嗙爜" name="resetPwd"> + <resetPwd :user="user" /> + </el-tab-pane> + </el-tabs> + </el-card> + </el-col> + </el-row> + </div> +</template> + +<script> +import userAvatar from "./userAvatar"; +import userInfo from "./userInfo"; +import resetPwd from "./resetPwd"; +import { getUserProfile } from "@/api/system/user"; + +export default { + name: "Profile", + components: { userAvatar, userInfo, resetPwd }, + data() { + return { + user: {}, + roleGroup: {}, + postGroup: {}, + activeTab: "userinfo" + }; + }, + created() { + this.getUser(); + }, + methods: { + getUser() { + getUserProfile().then(response => { + this.user = response.data; + this.roleGroup = response.roleGroup; + this.postGroup = response.postGroup; + }); + } + } +}; +</script> diff --git a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..3de5dfd --- /dev/null +++ b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,76 @@ +<template> + <el-form ref="form" :model="user" :rules="rules" label-width="80px"> + <el-form-item label="鏃у瘑鐮�" prop="oldPassword"> + <el-input v-model="user.oldPassword" placeholder="璇疯緭鍏ユ棫瀵嗙爜" type="password" /> + </el-form-item> + <el-form-item label="鏂板瘑鐮�" prop="newPassword"> + <el-input v-model="user.newPassword" placeholder="璇疯緭鍏ユ柊瀵嗙爜" type="password" /> + </el-form-item> + <el-form-item label="纭瀵嗙爜" prop="confirmPassword"> + <el-input v-model="user.confirmPassword" placeholder="璇风‘璁ゅ瘑鐮�" type="password" /> + </el-form-item> + <el-form-item> + <el-button type="primary" size="mini" @click="submit">淇濆瓨</el-button> + <el-button type="danger" size="mini" @click="close">鍏抽棴</el-button> + </el-form-item> + </el-form> +</template> + +<script> +import { updateUserPwd } from "@/api/system/user"; + +export default { + data() { + const equalToPassword = (rule, value, callback) => { + if (this.user.newPassword !== value) { + callback(new Error("涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�")); + } else { + callback(); + } + }; + return { + test: "1test", + user: { + oldPassword: undefined, + newPassword: undefined, + confirmPassword: undefined + }, + // 琛ㄥ崟鏍¢獙 + rules: { + oldPassword: [ + { required: true, message: "鏃у瘑鐮佷笉鑳戒负绌�", trigger: "blur" } + ], + newPassword: [ + { required: true, message: "鏂板瘑鐮佷笉鑳戒负绌�", trigger: "blur" }, + { min: 6, max: 20, message: "闀垮害鍦� 6 鍒� 20 涓瓧绗�", trigger: "blur" } + ], + confirmPassword: [ + { required: true, message: "纭瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, + { required: true, validator: equalToPassword, trigger: "blur" } + ] + } + }; + }, + methods: { + submit() { + this.$refs["form"].validate(valid => { + if (valid) { + updateUserPwd(this.user.oldPassword, this.user.newPassword).then( + response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + } else { + this.msgError(response.msg); + } + } + ); + } + }); + }, + close() { + this.$store.dispatch("tagsView/delView", this.$route); + this.$router.push({ path: "/index" }); + } + } +}; +</script> diff --git a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..3faf560 --- /dev/null +++ b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,138 @@ +<template> + <div> + <img v-bind:src="options.img" @click="editCropper()" title="鐐瑰嚮涓婁紶澶村儚" class="img-circle img-lg" /> + <el-dialog :title="title" :visible.sync="open" width="800px"> + <el-row> + <el-col :xs="24" :md="12" :style="{height: '350px'}"> + <vue-cropper + ref="cropper" + :img="options.img" + :info="true" + :autoCrop="options.autoCrop" + :autoCropWidth="options.autoCropWidth" + :autoCropHeight="options.autoCropHeight" + :fixedBox="options.fixedBox" + @realTime="realTime" + /> + </el-col> + <el-col :xs="24" :md="12" :style="{height: '350px'}"> + <div class="avatar-upload-preview"> + <img :src="previews.url" :style="previews.img" /> + </div> + </el-col> + </el-row> + <br /> + <el-row> + <el-col :lg="2" :md="2"> + <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload"> + <el-button size="small"> + 涓婁紶 + <i class="el-icon-upload el-icon--right"></i> + </el-button> + </el-upload> + </el-col> + <el-col :lg="{span: 1, offset: 2}" :md="2"> + <el-button icon="el-icon-plus" size="small" @click="changeScale(1)"></el-button> + </el-col> + <el-col :lg="{span: 1, offset: 1}" :md="2"> + <el-button icon="el-icon-minus" size="small" @click="changeScale(-1)"></el-button> + </el-col> + <el-col :lg="{span: 1, offset: 1}" :md="2"> + <el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()"></el-button> + </el-col> + <el-col :lg="{span: 1, offset: 1}" :md="2"> + <el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()"></el-button> + </el-col> + <el-col :lg="{span: 2, offset: 6}" :md="2"> + <el-button type="primary" size="small" @click="uploadImg()">鎻� 浜�</el-button> + </el-col> + </el-row> + </el-dialog> + </div> +</template> + +<script> +import store from "@/store"; +import { VueCropper } from "vue-cropper"; +import { uploadAvatar } from "@/api/system/user"; + +export default { + components: { VueCropper }, + props: { + user: { + type: Object + } + }, + data() { + return { + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 寮瑰嚭灞傛爣棰� + title: "淇敼澶村儚", + options: { + img: store.getters.avatar, //瑁佸壀鍥剧墖鐨勫湴鍧� + autoCrop: true, // 鏄惁榛樿鐢熸垚鎴浘妗� + autoCropWidth: 200, // 榛樿鐢熸垚鎴浘妗嗗搴� + autoCropHeight: 200, // 榛樿鐢熸垚鎴浘妗嗛珮搴� + fixedBox: true // 鍥哄畾鎴浘妗嗗ぇ灏� 涓嶅厑璁告敼鍙� + }, + previews: {} + }; + }, + methods: { + // 缂栬緫澶村儚 + editCropper() { + this.open = true; + }, + // 瑕嗙洊榛樿鐨勪笂浼犺涓� + requestUpload() { + }, + // 鍚戝乏鏃嬭浆 + rotateLeft() { + this.$refs.cropper.rotateLeft(); + }, + // 鍚戝彸鏃嬭浆 + rotateRight() { + this.$refs.cropper.rotateRight(); + }, + // 鍥剧墖缂╂斁 + changeScale(num) { + num = num || 1; + this.$refs.cropper.changeScale(num); + }, + // 涓婁紶棰勫鐞� + beforeUpload(file) { + if (file.type.indexOf("image/") == -1) { + this.msgError("鏂囦欢鏍煎紡閿欒锛岃涓婁紶鍥剧墖绫诲瀷,濡傦細JPG锛孭NG鍚庣紑鐨勬枃浠躲��"); + } else { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + this.options.img = reader.result; + }; + } + }, + // 涓婁紶鍥剧墖 + uploadImg() { + this.$refs.cropper.getCropBlob(data => { + let formData = new FormData(); + formData.append("avatarfile", data); + uploadAvatar(formData).then(response => { + if (response.code === 200) { + this.open = false; + this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl; + this.msgSuccess("淇敼鎴愬姛"); + } else { + this.msgError(response.msg); + } + this.$refs.cropper.clearCrop(); + }); + }); + }, + // 瀹炴椂棰勮 + realTime(data) { + this.previews = data; + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/system/user/profile/userInfo.vue b/ruoyi-ui/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..e50198f --- /dev/null +++ b/ruoyi-ui/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,80 @@ +<template> + <el-form ref="form" :model="user" :rules="rules" label-width="80px"> + <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName"> + <el-input v-model="user.nickName" /> + </el-form-item> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input v-model="user.phonenumber" maxlength="11" /> + </el-form-item> + <el-form-item label="閭" prop="email"> + <el-input v-model="user.email" maxlength="50" /> + </el-form-item> + <el-form-item label="鎬у埆"> + <el-radio-group v-model="user.sex"> + <el-radio label="0">鐢�</el-radio> + <el-radio label="1">濂�</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item> + <el-button type="primary" size="mini" @click="submit">淇濆瓨</el-button> + <el-button type="danger" size="mini" @click="close">鍏抽棴</el-button> + </el-form-item> + </el-form> +</template> + +<script> +import { updateUserProfile } from "@/api/system/user"; + +export default { + props: { + user: { + type: Object + } + }, + data() { + return { + // 琛ㄥ崟鏍¢獙 + rules: { + nickName: [ + { required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" } + ], + email: [ + { required: true, message: "閭鍦板潃涓嶈兘涓虹┖", trigger: "blur" }, + { + type: "email", + message: "'璇疯緭鍏ユ纭殑閭鍦板潃", + trigger: ["blur", "change"] + } + ], + phonenumber: [ + { required: true, message: "鎵嬫満鍙风爜涓嶈兘涓虹┖", trigger: "blur" }, + { + pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, + message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", + trigger: "blur" + } + ] + } + }; + }, + methods: { + submit() { + this.$refs["form"].validate(valid => { + if (valid) { + updateUserProfile(this.user).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + } else { + this.msgError(response.msg); + } + }); + } + }); + }, + close() { + this.$store.dispatch("tagsView/delView", this.$route); + this.$router.push({ path: "/index" }); + } + } +}; +</script> diff --git a/ruoyi-ui/src/views/tool/build/index.vue b/ruoyi-ui/src/views/tool/build/index.vue new file mode 100644 index 0000000..5d2b73a --- /dev/null +++ b/ruoyi-ui/src/views/tool/build/index.vue @@ -0,0 +1,5 @@ +<template> + <div class="app-container"> + 鏋勫缓宸ュ叿 + </div> +</template> \ No newline at end of file diff --git a/ruoyi-ui/src/views/tool/gen/basicInfoForm.vue b/ruoyi-ui/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..757962c --- /dev/null +++ b/ruoyi-ui/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,61 @@ +<template> + <el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="150px"> + <el-row> + <el-col :span="12"> + <el-form-item label="琛ㄥ悕绉�" prop="tableName"> + <el-input placeholder="璇疯緭鍏ヤ粨搴撳悕绉�" v-model="info.tableName" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="琛ㄦ弿杩�" prop="tableComment"> + <el-input placeholder="璇疯緭鍏�" v-model="info.tableComment" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item label="瀹炰綋绫诲悕绉�" prop="className"> + <el-input placeholder="璇疯緭鍏�" v-model="info.className" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="浣滆��" prop="functionAuthor"> + <el-input placeholder="璇疯緭鍏�" v-model="info.functionAuthor" /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="澶囨敞" prop="remark"> + <el-input type="textarea" :rows="3" v-model="info.remark"></el-input> + </el-form-item> + </el-col> + </el-row> + </el-form> +</template> +<script> +export default { + name: "BasicInfoForm", + props: { + info: { + type: Object, + default: null + } + }, + data() { + return { + rules: { + tableName: [ + { required: true, message: "璇疯緭鍏ヨ〃鍚嶇О", trigger: "blur" } + ], + tableComment: [ + { required: true, message: "璇疯緭鍏ヨ〃鎻忚堪", trigger: "blur" } + ], + className: [ + { required: true, message: "璇疯緭鍏ュ疄浣撶被鍚嶇О", trigger: "blur" } + ], + functionAuthor: [ + { required: true, message: "璇疯緭鍏ヤ綔鑰�", trigger: "blur" } + ] + } + }; + } +}; +</script> diff --git a/ruoyi-ui/src/views/tool/gen/editTable.vue b/ruoyi-ui/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..d91fb02 --- /dev/null +++ b/ruoyi-ui/src/views/tool/gen/editTable.vue @@ -0,0 +1,204 @@ +<template> + <el-card> + <el-tabs v-model="activeName"> + <el-tab-pane label="鍩烘湰淇℃伅" name="basic"> + <basic-info-form ref="basicInfo" :info="info" /> + </el-tab-pane> + <el-tab-pane label="瀛楁淇℃伅" name="cloum"> + <el-table :data="cloumns" :max-height="tableHeight"> + <el-table-column label="搴忓彿" type="index" min-width="5%" /> + <el-table-column + label="瀛楁鍒楀悕" + prop="columnName" + min-width="10%" + :show-overflow-tooltip="true" + /> + <el-table-column + label="瀛楁鎻忚堪" + prop="columnComment" + min-width="10%" + :show-overflow-tooltip="true" + /> + <el-table-column + label="鐗╃悊绫诲瀷" + prop="columnType" + min-width="10%" + :show-overflow-tooltip="true" + /> + <el-table-column label="Java绫诲瀷" min-width="11%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.javaType"> + <el-option label="Long" value="Long" /> + <el-option label="String" value="String" /> + <el-option label="Integer" value="Integer" /> + <el-option label="Double" value="Double" /> + <el-option label="BigDecimal" value="BigDecimal" /> + <el-option label="Date" value="Date" /> + </el-select> + </template> + </el-table-column> + <el-table-column label="java灞炴��" min-width="10%"> + <template slot-scope="scope"> + <el-input v-model="scope.row.javaField"></el-input> + </template> + </el-table-column> + + <el-table-column label="鎻掑叆" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" v-model="scope.row.isInsert"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="缂栬緫" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" v-model="scope.row.isEdit"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鍒楄〃" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" v-model="scope.row.isList"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鏌ヨ" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" v-model="scope.row.isQuery"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鏌ヨ鏂瑰紡" min-width="10%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.queryType"> + <el-option label="=" value="EQ" /> + <el-option label="!=" value="NE" /> + <el-option label=">" value="GT" /> + <el-option label=">=" value="GTE" /> + <el-option label="<" value="LT" /> + <el-option label="<=" value="LTE" /> + <el-option label="LIKE" value="LIKE" /> + <el-option label="BETWEEN" value="BETWEEN" /> + </el-select> + </template> + </el-table-column> + <el-table-column label="蹇呭~" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" v-model="scope.row.isRequired"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鏄剧ず绫诲瀷" min-width="12%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.htmlType"> + <el-option label="鏂囨湰妗�" value="input" /> + <el-option label="鏂囨湰鍩�" value="textarea" /> + <el-option label="涓嬫媺妗�" value="select" /> + <el-option label="鍗曢�夋" value="radio" /> + <el-option label="澶嶉�夋" value="checkbox" /> + <el-option label="鏃ユ湡鎺т欢" value="datetime" /> + </el-select> + </template> + </el-table-column> + <el-table-column label="瀛楀吀绫诲瀷" min-width="12%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.dictType" clearable filterable placeholder="璇烽�夋嫨"> + <el-option + v-for="dict in dictOptions" + :key="dict.dictType" + :label="dict.dictName" + :value="dict.dictType"> + <span style="float: left">{{ dict.dictName }}</span> + <span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span> + </el-option> + </el-select> + </template> + </el-table-column> + </el-table> + </el-tab-pane> + <el-tab-pane label="鐢熸垚淇℃伅" name="genInfo"> + <gen-info-form ref="genInfo" :info="info" /> + </el-tab-pane> + </el-tabs> + <el-form label-width="100px"> + <el-form-item style="text-align: center;margin-left:-100px;margin-top:10px;"> + <el-button type="primary" @click="submitForm()">鎻愪氦</el-button> + <el-button @click="close()">杩斿洖</el-button> + </el-form-item> + </el-form> + </el-card> +</template> +<script> +import { getGenTable, updateGenTable } from "@/api/tool/gen"; +import { optionselect as getDictOptionselect } from "@/api/system/dict/type"; +import basicInfoForm from "./basicInfoForm"; +import genInfoForm from "./genInfoForm"; +export default { + name: "GenEdit", + components: { + basicInfoForm, + genInfoForm + }, + data() { + return { + // 閫変腑閫夐」鍗$殑 name + activeName: "cloum", + // 琛ㄦ牸鐨勯珮搴� + tableHeight: document.documentElement.scrollHeight - 245 + "px", + // 琛ㄥ垪淇℃伅 + cloumns: [], + // 瀛楀吀淇℃伅 + dictOptions: [], + // 琛ㄨ缁嗕俊鎭� + info: {} + }; + }, + beforeCreate() { + const { tableId } = this.$route.query; + if (tableId) { + // 鑾峰彇琛ㄨ缁嗕俊鎭� + getGenTable(tableId).then(res => { + this.cloumns = res.data.rows; + this.info = res.data.info; + }); + /** 鏌ヨ瀛楀吀涓嬫媺鍒楄〃 */ + getDictOptionselect().then(response => { + this.dictOptions = response.data; + }); + } + }, + methods: { + /** 鎻愪氦鎸夐挳 */ + submitForm() { + const basicForm = this.$refs.basicInfo.$refs.basicInfoForm; + const genForm = this.$refs.genInfo.$refs.genInfoForm; + Promise.all([basicForm, genForm].map(this.getFormPromise)).then(res => { + const validateResult = res.every(item => !!item); + if (validateResult) { + const genTable = Object.assign({}, basicForm.model, genForm.model); + genTable.columns = this.cloumns; + genTable.params = { + treeCode: genTable.treeCode, + treeName: genTable.treeName, + treeParentCode: genTable.treeParentCode + }; + updateGenTable(genTable).then(res => { + this.msgSuccess(res.msg); + if (res.code === 200) { + this.close(); + } + }); + } else { + this.msgError("琛ㄥ崟鏍¢獙鏈�氳繃锛岃閲嶆柊妫�鏌ユ彁浜ゅ唴瀹�"); + } + }); + }, + getFormPromise(form) { + return new Promise(resolve => { + form.validate(res => { + resolve(res); + }); + }); + }, + /** 鍏抽棴鎸夐挳 */ + close() { + this.$store.dispatch("tagsView/delView", this.$route); + this.$router.push({ path: "/tool/gen", query: { t: Date.now()}}) + } + } +}; +</script> diff --git a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..659f903 --- /dev/null +++ b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,154 @@ +<template> + <el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px"> + <el-row> + <el-col :span="12"> + <el-form-item prop="tplCategory"> + <span slot="label">鐢熸垚妯℃澘</span> + <el-select v-model="info.tplCategory"> + <el-option label="鍗曡〃锛堝鍒犳敼鏌ワ級" value="crud" /> + <el-option label="鏍戣〃锛堝鍒犳敼鏌ワ級" value="tree" disabled/> + </el-select> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="packageName"> + <span slot="label"> + 鐢熸垚鍖呰矾寰� + <el-tooltip content="鐢熸垚鍦ㄥ摢涓猨ava鍖呬笅锛屼緥濡� com.ruoyi.system" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.packageName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="moduleName"> + <span slot="label"> + 鐢熸垚妯″潡鍚� + <el-tooltip content="鍙悊瑙d负瀛愮郴缁熷悕锛屼緥濡� system" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.moduleName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="businessName"> + <span slot="label"> + 鐢熸垚涓氬姟鍚� + <el-tooltip content="鍙悊瑙d负鍔熻兘鑻辨枃鍚嶏紝渚嬪 user" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.businessName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="functionName"> + <span slot="label"> + 鐢熸垚鍔熻兘鍚� + <el-tooltip content="鐢ㄤ綔绫绘弿杩帮紝渚嬪 鐢ㄦ埛" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.functionName" /> + </el-form-item> + </el-col> + </el-row> + + <el-row v-show="info.tplCategory == 'tree'"> + <h4 class="form-header">鍏朵粬淇℃伅</h4> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鏍戠紪鐮佸瓧娈� + <el-tooltip content="鏍戞樉绀虹殑缂栫爜瀛楁鍚嶏紝 濡傦細dept_id" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.treeCode" placeholder="璇烽�夋嫨"> + <el-option + v-for="column in info.columns" + :key="column.columnName" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鏍戠埗缂栫爜瀛楁 + <el-tooltip content="鏍戞樉绀虹殑鐖剁紪鐮佸瓧娈靛悕锛� 濡傦細parent_Id" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.treeParentCode" placeholder="璇烽�夋嫨"> + <el-option + v-for="column in info.columns" + :key="column.columnName" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鏍戝悕绉板瓧娈� + <el-tooltip content="鏍戣妭鐐圭殑鏄剧ず鍚嶇О瀛楁鍚嶏紝 濡傦細dept_name" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.treeName" placeholder="璇烽�夋嫨"> + <el-option + v-for="column in info.columns" + :key="column.columnName" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + </el-form> +</template> +<script> +export default { + name: "BasicInfoForm", + props: { + info: { + type: Object, + default: null + } + }, + data() { + return { + rules: { + tplCategory: [ + { required: true, message: "璇烽�夋嫨鐢熸垚妯℃澘", trigger: "blur" } + ], + packageName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愬寘璺緞", trigger: "blur" } + ], + moduleName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愭ā鍧楀悕", trigger: "blur" } + ], + businessName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愪笟鍔″悕", trigger: "blur" } + ], + functionName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愬姛鑳藉悕", trigger: "blur" } + ] + } + }; + }, + created() {} +}; +</script> diff --git a/ruoyi-ui/src/views/tool/gen/importTable.vue b/ruoyi-ui/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..e4b30c2 --- /dev/null +++ b/ruoyi-ui/src/views/tool/gen/importTable.vue @@ -0,0 +1,114 @@ +<template> + <!-- 瀵煎叆琛� --> + <el-dialog title="瀵煎叆琛�" :visible.sync="visible" width="800px" top="5vh"> + <el-form :model="queryParams" ref="queryForm" :inline="true"> + <el-form-item label="琛ㄥ悕绉�" prop="tableName"> + <el-input + v-model="queryParams.tableName" + placeholder="璇疯緭鍏ヨ〃鍚嶇О" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="琛ㄦ弿杩�" prop="tableComment"> + <el-input + v-model="queryParams.tableComment" + placeholder="璇疯緭鍏ヨ〃鎻忚堪" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + <el-row> + <el-table :data="dbTableList" @selection-change="handleSelectionChange" height="260px"> + <el-table-column type="selection" width="55"></el-table-column> + <el-table-column prop="tableName" label="琛ㄥ悕绉�"></el-table-column> + <el-table-column prop="tableComment" label="琛ㄦ弿杩�"></el-table-column> + <el-table-column prop="createTime" label="鍒涘缓鏃堕棿"></el-table-column> + <el-table-column prop="updateTime" label="鏇存柊鏃堕棿"></el-table-column> + </el-table> + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + </el-row> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="handleImportTable">纭� 瀹�</el-button> + <el-button @click="visible = false">鍙� 娑�</el-button> + </div> + </el-dialog> +</template> + +<script> +import { listDbTable, importTable } from "@/api/tool/gen"; +export default { + data() { + return { + // 閬僵灞� + visible: false, + // 閫変腑鏁扮粍鍊� + tables: [], + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ暟鎹� + dbTableList: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + tableName: undefined, + tableComment: undefined + } + }; + }, + methods: { + // 鏄剧ず寮规 + show() { + this.getList(); + this.visible = true; + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.tables = selection.map(item => item.tableName); + }, + // 鏌ヨ琛ㄦ暟鎹� + getList() { + listDbTable(this.queryParams).then(res => { + if (res.code === 200) { + this.dbTableList = res.rows; + this.total = res.total; + } + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 瀵煎叆鎸夐挳鎿嶄綔 */ + handleImportTable() { + importTable({ tables: this.tables.join(",") }).then(res => { + this.msgSuccess(res.msg); + if (res.code === 200) { + this.visible = false; + this.$emit("ok"); + } + }); + } + } +}; +</script> diff --git a/ruoyi-ui/src/views/tool/gen/index.vue b/ruoyi-ui/src/views/tool/gen/index.vue new file mode 100644 index 0000000..28fb5bc --- /dev/null +++ b/ruoyi-ui/src/views/tool/gen/index.vue @@ -0,0 +1,287 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="琛ㄥ悕绉�" prop="tableName"> + <el-input + v-model="queryParams.tableName" + placeholder="璇疯緭鍏ヨ〃鍚嶇О" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="琛ㄦ弿杩�" prop="tableComment"> + <el-input + v-model="queryParams.tableComment" + placeholder="璇疯緭鍏ヨ〃鎻忚堪" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鍒涘缓鏃堕棿"> + <el-date-picker + v-model="dateRange" + size="small" + style="width: 240px" + value-format="yyyy-MM-dd" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + ></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-download" + size="mini" + @click="handleGenTable" + v-hasPermi="['tool:gen:code']" + >鐢熸垚</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="info" + icon="el-icon-upload" + size="mini" + @click="openImportTable" + v-hasPermi="['tool:gen:import']" + >瀵煎叆</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleEditTable" + v-hasPermi="['tool:gen:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['tool:gen:remove']" + >鍒犻櫎</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55"></el-table-column> + <el-table-column label="搴忓彿" align="center" prop="tableId" width="50px" /> + <el-table-column + label="琛ㄥ悕绉�" + align="center" + prop="tableName" + :show-overflow-tooltip="true" + width="130" + /> + <el-table-column + label="琛ㄦ弿杩�" + align="center" + prop="tableComment" + :show-overflow-tooltip="true" + width="130" + /> + <el-table-column + label="瀹炰綋" + align="center" + prop="className" + :show-overflow-tooltip="true" + width="130" + /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="160" /> + <el-table-column label="鏇存柊鏃堕棿" align="center" prop="updateTime" width="160" /> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + type="text" + size="small" + icon="el-icon-view" + @click="handlePreview(scope.row)" + v-hasPermi="['tool:gen:preview']" + >棰勮</el-button> + <el-button + type="text" + size="small" + icon="el-icon-edit" + @click="handleEditTable(scope.row)" + v-hasPermi="['tool:gen:edit']" + >缂栬緫</el-button> + <el-button + type="text" + size="small" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['tool:gen:remove']" + >鍒犻櫎</el-button> + <el-button + type="text" + size="small" + icon="el-icon-download" + @click="handleGenTable(scope.row)" + v-hasPermi="['tool:gen:code']" + >鐢熸垚浠g爜</el-button> + </template> + </el-table-column> + </el-table> + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + <!-- 棰勮鐣岄潰 --> + <el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh"> + <el-tabs v-model="preview.activeName"> + <el-tab-pane + v-for="(value, key) in preview.data" + :label="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))" + :name="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))" + :key="key" + > + <pre>{{ value }}</pre> + </el-tab-pane> + </el-tabs> + </el-dialog> + <import-table ref="import" @ok="handleQuery" /> + </div> +</template> + +<script> +import { listTable, previewTable, delTable } from "@/api/tool/gen"; +import importTable from "./importTable"; +import { downLoadZip } from "@/utils/zipdownload"; +export default { + name: "Gen", + components: { importTable }, + data() { + return { + // 閬僵灞� + loading: true, + // 鍞竴鏍囪瘑绗� + uniqueId: "", + // 閫変腑鏁扮粍 + ids: [], + // 閫変腑琛ㄦ暟缁� + tableNames: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ暟鎹� + tableList: [], + // 鏃ユ湡鑼冨洿 + dateRange: "", + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + tableName: undefined, + tableComment: undefined + }, + // 棰勮鍙傛暟 + preview: { + open: false, + title: "浠g爜棰勮", + data: {}, + activeName: "domain.java" + } + }; + }, + created() { + this.getList(); + }, + activated() { + const time = this.$route.query.t; + if (time != null && time != this.uniqueId) { + this.uniqueId = time; + this.resetQuery(); + } + }, + methods: { + /** 鏌ヨ琛ㄩ泦鍚� */ + getList() { + this.loading = true; + listTable(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.tableList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 鐢熸垚浠g爜鎿嶄綔 */ + handleGenTable(row) { + const tableNames = row.tableName || this.tableNames; + if (tableNames == "") { + this.msgError("璇烽�夋嫨瑕佺敓鎴愮殑鏁版嵁"); + return; + } + downLoadZip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi"); + }, + /** 鎵撳紑瀵煎叆琛ㄥ脊绐� */ + openImportTable() { + this.$refs.import.show(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 棰勮鎸夐挳 */ + handlePreview(row) { + previewTable(row.tableId).then(response => { + this.preview.data = response.data; + this.preview.open = true; + }); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.tableId); + this.tableNames = selection.map(item => item.tableName); + this.single = selection.length != 1; + this.multiple = !selection.length; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleEditTable(row) { + const tableId = row.tableId || this.ids[0]; + this.$router.push({ path: "/gen/edit", query: { tableId: tableId } }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const tableIds = row.tableId || this.ids; + this.$confirm('鏄惁纭鍒犻櫎琛ㄧ紪鍙蜂负"' + tableIds + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return delTable(tableIds); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi-ui/src/views/tool/swagger/index.vue b/ruoyi-ui/src/views/tool/swagger/index.vue new file mode 100644 index 0000000..61cfcca --- /dev/null +++ b/ruoyi-ui/src/views/tool/swagger/index.vue @@ -0,0 +1,26 @@ +<template> + <div v-loading="loading" :style="'height:'+ height"> + <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" /> + </div> +</template> +<script> +export default { + name: "Swagger", + data() { + return { + src: process.env.VUE_APP_BASE_API + "/swagger-ui.html", + height: document.documentElement.clientHeight - 94.5 + "px;", + loading: true + }; + }, + mounted: function() { + setTimeout(() => { + this.loading = false; + }, 230); + const that = this; + window.onresize = function temp() { + that.height = document.documentElement.clientHeight - 94.5 + "px;"; + }; + } +}; +</script> diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js new file mode 100644 index 0000000..b62fbbf --- /dev/null +++ b/ruoyi-ui/vue.config.js @@ -0,0 +1,130 @@ +'use strict' +const path = require('path') +const defaultSettings = require('./src/settings.js') + +function resolve(dir) { + return path.join(__dirname, dir) +} + +const name = defaultSettings.title || '鑻ヤ緷绠$悊绯荤粺' // 鏍囬 + +const port = process.env.port || process.env.npm_config_port || 80 // 绔彛 + +// vue.config.js 閰嶇疆璇存槑 +//瀹樻柟vue.config.js 鍙傝�冩枃妗� https://cli.vuejs.org/zh/config/#css-loaderoptions +// 杩欓噷鍙垪涓�閮ㄥ垎锛屽叿浣撻厤缃弬鑰冩枃妗� +module.exports = { + // 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆� + // 榛樿鎯呭喌涓嬶紝Vue CLI 浼氬亣璁句綘鐨勫簲鐢ㄦ槸琚儴缃插湪涓�涓煙鍚嶇殑鏍硅矾寰勪笂 + // 渚嬪 https://www.ruoyi.vip/銆傚鏋滃簲鐢ㄨ閮ㄧ讲鍦ㄤ竴涓瓙璺緞涓婏紝浣犲氨闇�瑕佺敤杩欎釜閫夐」鎸囧畾杩欎釜瀛愯矾寰勩�備緥濡傦紝濡傛灉浣犵殑搴旂敤琚儴缃插湪 https://www.ruoyi.vip/admin/锛屽垯璁剧疆 baseUrl 涓� /admin/銆� + publicPath: process.env.NODE_ENV === "production" ? "/" : "/", + // 鍦╪pm run build 鎴� yarn build 鏃� 锛岀敓鎴愭枃浠剁殑鐩綍鍚嶇О锛堣鍜宐aseUrl鐨勭敓浜х幆澧冭矾寰勪竴鑷达級锛堥粯璁ist锛� + outputDir: 'dist', + // 鐢ㄤ簬鏀剧疆鐢熸垚鐨勯潤鎬佽祫婧� (js銆乧ss銆乮mg銆乫onts) 鐨勶紱锛堥」鐩墦鍖呬箣鍚庯紝闈欐�佽祫婧愪細鏀惧湪杩欎釜鏂囦欢澶逛笅锛� + assetsDir: 'static', + // 鏄惁寮�鍚痚slint淇濆瓨妫�娴嬶紝鏈夋晥鍊硷細ture | false | 'error' + lintOnSave: process.env.NODE_ENV === 'development', + // 濡傛灉浣犱笉闇�瑕佺敓浜х幆澧冪殑 source map锛屽彲浠ュ皢鍏惰缃负 false 浠ュ姞閫熺敓浜х幆澧冩瀯寤恒�� + productionSourceMap: false, + // webpack-dev-server 鐩稿叧閰嶇疆 + devServer: { + host: '0.0.0.0', + port: port, + proxy: { + // detail: https://cli.vuejs.org/config/#devserver-proxy + [process.env.VUE_APP_BASE_API]: { + target: `http://localhost:8080`, + changeOrigin: true, + pathRewrite: { + ['^' + process.env.VUE_APP_BASE_API]: '' + } + } + }, + disableHostCheck: true + }, + configureWebpack: { + name: name, + resolve: { + alias: { + '@': resolve('src') + } + } + }, + chainWebpack(config) { + config.plugins.delete('preload') // TODO: need test + config.plugins.delete('prefetch') // TODO: need test + + // set svg-sprite-loader + config.module + .rule('svg') + .exclude.add(resolve('src/assets/icons')) + .end() + config.module + .rule('icons') + .test(/\.svg$/) + .include.add(resolve('src/assets/icons')) + .end() + .use('svg-sprite-loader') + .loader('svg-sprite-loader') + .options({ + symbolId: 'icon-[name]' + }) + .end() + + // set preserveWhitespace + config.module + .rule('vue') + .use('vue-loader') + .loader('vue-loader') + .tap(options => { + options.compilerOptions.preserveWhitespace = true + return options + }) + .end() + + config + // https://webpack.js.org/configuration/devtool/#development + .when(process.env.NODE_ENV === 'development', + config => config.devtool('cheap-source-map') + ) + + config + .when(process.env.NODE_ENV !== 'development', + config => { + config + .plugin('ScriptExtHtmlWebpackPlugin') + .after('html') + .use('script-ext-html-webpack-plugin', [{ + // `runtime` must same as runtimeChunk name. default is `runtime` + inline: /runtime\..*\.js$/ + }]) + .end() + config + .optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial' // only package third parties that are initially dependent + }, + elementUI: { + name: 'chunk-elementUI', // split elementUI into a single package + priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app + test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // can customize your rules + minChunks: 3, // minimum common number + priority: 5, + reuseExistingChunk: true + } + } + }) + config.optimization.runtimeChunk('single') + } + ) + } +} diff --git a/ruoyi/.gitignore b/ruoyi/.gitignore new file mode 100644 index 0000000..fd446f4 --- /dev/null +++ b/ruoyi/.gitignore @@ -0,0 +1,43 @@ +###################################################################### +# Build Tools + +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +target/ +!.mvn/wrapper/maven-wrapper.jar + +###################################################################### +# IDE + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/* +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +###################################################################### +# Others +*.log +*.xml.versionsBackup + +!*/build/*.java +!*/build/*.html +!*/build/*.xml \ No newline at end of file diff --git a/ruoyi/bin/clean.bat b/ruoyi/bin/clean.bat new file mode 100644 index 0000000..5c2a3b2 --- /dev/null +++ b/ruoyi/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 清理生成路径。 +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/ruoyi/bin/package.bat b/ruoyi/bin/package.bat new file mode 100644 index 0000000..c693ec0 --- /dev/null +++ b/ruoyi/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 打包Web工程,生成war/jar包文件。 +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean package -Dmaven.test.skip=true + +pause \ No newline at end of file diff --git a/ruoyi/bin/run-tomcat.bat b/ruoyi/bin/run-tomcat.bat new file mode 100644 index 0000000..598e026 --- /dev/null +++ b/ruoyi/bin/run-tomcat.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [信息] 使用 Spring Boot Tomcat 运行 Web 工程。 +echo. + +%~d0 +cd %~dp0 + +cd .. +title %cd% +set MAVEN_OPTS=%MAVEN_OPTS% -Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m +call mvn clean spring-boot:run -Dmaven.test.skip=true -U + +pause \ No newline at end of file diff --git a/ruoyi/pom.xml b/ruoyi/pom.xml new file mode 100644 index 0000000..b317c40 --- /dev/null +++ b/ruoyi/pom.xml @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>com.ruoyi</groupId> + <artifactId>ruoyi</artifactId> + <version>2.0.0</version> + <packaging>jar</packaging> + + <name>ruoyi</name> + <url>http://www.ruoyi.vip</url> + <description>鑻ヤ緷绠$悊绯荤粺</description> + + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>2.1.1.RELEASE</version> + <relativePath /> + </parent> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <java.version>1.8</java.version> + <mybatis.spring.boot.starter.version>1.3.2</mybatis.spring.boot.starter.version> + <pagehelper.spring.boot.starter.version>1.2.5</pagehelper.spring.boot.starter.version> + <fastjson.version>1.2.47</fastjson.version> + <druid.version>1.1.14</druid.version> + <commons.io.version>2.5</commons.io.version> + <commons.fileupload.version>1.3.3</commons.fileupload.version> + <bitwalker.version>1.19</bitwalker.version> + <jwt.version>0.9.0</jwt.version> + <swagger.version>2.9.2</swagger.version> + <poi.version>3.17</poi.version> + <oshi.version>3.9.1</oshi.version> + <velocity.version>1.7</velocity.version> + </properties> + + <dependencies> + + <!-- SpringBoot 鏍稿績鍖� --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter</artifactId> + <!-- + <exclusions> + <exclusion> + <artifactId>spring-boot-starter-tomcat</artifactId> + <groupId>org.springframework.boot</groupId> + </exclusion> + </exclusions> + --> + </dependency> + + <!-- SpringBoot 娴嬭瘯 --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + + <!-- SpringBoot 鎷︽埅鍣� --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-aop</artifactId> + </dependency> + + <!-- SpringBoot Web瀹瑰櫒 --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + + <!-- spring-boot-devtools --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-devtools</artifactId> + <optional>true</optional> <!-- 琛ㄧず渚濊禆涓嶄細浼犻�� --> + </dependency> + + <!-- spring security 瀹夊叏璁よ瘉 --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + + <!-- redis 缂撳瓨鎿嶄綔 --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-redis</artifactId> + </dependency> + + <!-- pool 瀵硅薄姹� --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-pool2</artifactId> + </dependency> + + <!-- Mysql椹卞姩鍖� --> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <scope>runtime</scope> + </dependency> + + <!-- SpringBoot闆嗘垚mybatis妗嗘灦 --> + <dependency> + <groupId>org.mybatis.spring.boot</groupId> + <artifactId>mybatis-spring-boot-starter</artifactId> + <version>${mybatis.spring.boot.starter.version}</version> + </dependency> + + <!-- pagehelper 鍒嗛〉鎻掍欢 --> + <dependency> + <groupId>com.github.pagehelper</groupId> + <artifactId>pagehelper-spring-boot-starter</artifactId> + <version>${pagehelper.spring.boot.starter.version}</version> + </dependency> + + <!--闃块噷鏁版嵁搴撹繛鎺ユ睜 --> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>druid-spring-boot-starter</artifactId> + <version>${druid.version}</version> + </dependency> + + <!--甯哥敤宸ュ叿绫� --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + + <!--io甯哥敤宸ュ叿绫� --> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>${commons.io.version}</version> + </dependency> + + <!--鏂囦欢涓婁紶宸ュ叿绫� --> + <dependency> + <groupId>commons-fileupload</groupId> + <artifactId>commons-fileupload</artifactId> + <version>${commons.fileupload.version}</version> + </dependency> + + <!-- 瑙f瀽瀹㈡埛绔搷浣滅郴缁熴�佹祻瑙堝櫒绛� --> + <dependency> + <groupId>eu.bitwalker</groupId> + <artifactId>UserAgentUtils</artifactId> + <version>${bitwalker.version}</version> + </dependency> + + <!-- 闃块噷JSON瑙f瀽鍣� --> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>fastjson</artifactId> + <version>${fastjson.version}</version> + </dependency> + + <!--Spring妗嗘灦鍩烘湰鐨勬牳蹇冨伐鍏�--> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context-support</artifactId> + </dependency> + + <!--Token鐢熸垚涓庤В鏋�--> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt</artifactId> + <version>${jwt.version}</version> + </dependency> + + <!-- swagger2--> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>${swagger.version}</version> + <exclusions> + <exclusion> + <groupId>io.swagger</groupId> + <artifactId>swagger-annotations</artifactId> + </exclusion> + <exclusion> + <groupId>io.swagger</groupId> + <artifactId>swagger-models</artifactId> + </exclusion> + </exclusions> + </dependency> + + <!--闃叉杩涘叆swagger椤甸潰鎶ョ被鍨嬭浆鎹㈤敊璇紝鎺掗櫎2.9.2涓殑寮曠敤锛屾墜鍔ㄥ鍔�1.5.21鐗堟湰--> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-annotations</artifactId> + <version>1.5.21</version> + </dependency> + + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-models</artifactId> + <version>1.5.21</version> + </dependency> + + <!-- swagger2-UI--> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>${swagger.version}</version> + </dependency> + + <!-- 鑾峰彇绯荤粺淇℃伅 --> + <dependency> + <groupId>com.github.oshi</groupId> + <artifactId>oshi-core</artifactId> + <version>${oshi.version}</version> + </dependency> + + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna</artifactId> + </dependency> + + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna-platform</artifactId> + </dependency> + + <!-- excel宸ュ叿 --> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi-ooxml</artifactId> + <version>${poi.version}</version> + </dependency> + <!--velocity浠g爜鐢熸垚浣跨敤妯℃澘 --> + <dependency> + <groupId>org.apache.velocity</groupId> + <artifactId>velocity</artifactId> + <version>${velocity.version}</version> + </dependency> + + </dependencies> + + <build> + <finalName>${project.artifactId}</finalName> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <fork>true</fork> <!-- 濡傛灉娌℃湁璇ラ厤缃紝devtools涓嶄細鐢熸晥 --> + </configuration> + </plugin> + </plugins> + </build> + + <repositories> + <repository> + <id>public</id> + <name>aliyun nexus</name> + <url>http://maven.aliyun.com/nexus/content/groups/public/</url> + <releases> + <enabled>true</enabled> + </releases> + </repository> + </repositories> + + <pluginRepositories> + <pluginRepository> + <id>public</id> + <name>aliyun nexus</name> + <url>http://maven.aliyun.com/nexus/content/groups/public/</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + +</project> \ No newline at end of file diff --git a/ruoyi/ry.sh b/ruoyi/ry.sh new file mode 100644 index 0000000..706036c --- /dev/null +++ b/ruoyi/ry.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +AppName=ruoyi.jar + +#JVM鍙傛暟 +JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" +APP_HOME=`pwd` +LOG_PATH=$APP_HOME/logs/$AppName.log + +if [ "$1" = "" ]; +then + echo -e "\033[0;31m 鏈緭鍏ユ搷浣滃悕 \033[0m \033[0;34m {start|stop|restart|status} \033[0m" + exit 1 +fi + +if [ "$AppName" = "" ]; +then + echo -e "\033[0;31m 鏈緭鍏ュ簲鐢ㄥ悕 \033[0m" + exit 1 +fi + +function start() +{ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` + + if [ x"$PID" != x"" ]; then + echo "$AppName is running..." + else + nohup java -jar $JVM_OPTS target/$AppName > /dev/null 2>&1 & + echo "Start $AppName success..." + fi +} + +function stop() +{ + echo "Stop $AppName" + + PID="" + query(){ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` + } + + query + if [ x"$PID" != x"" ]; then + kill -TERM $PID + echo "$AppName (pid:$PID) exiting..." + while [ x"$PID" != x"" ] + do + sleep 1 + query + done + echo "$AppName exited." + else + echo "$AppName already stopped." + fi +} + +function restart() +{ + stop + sleep 2 + start +} + +function status() +{ + PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l` + if [ $PID != 0 ];then + echo "$AppName is running..." + else + echo "$AppName is not running..." + fi +} + +case $1 in + start) + start;; + stop) + stop;; + restart) + restart;; + status) + status;; + *) + +esac diff --git a/ruoyi/sql/ry_20191202.sql b/ruoyi/sql/ry_20191202.sql new file mode 100644 index 0000000..fcd629f --- /dev/null +++ b/ruoyi/sql/ry_20191202.sql @@ -0,0 +1,675 @@ +-- ---------------------------- +-- 1銆侀儴闂ㄨ〃 +-- ---------------------------- +drop table if exists sys_dept; +create table sys_dept ( + dept_id bigint(20) not null auto_increment comment '閮ㄩ棬id', + parent_id bigint(20) default 0 comment '鐖堕儴闂╥d', + ancestors varchar(50) default '' comment '绁栫骇鍒楄〃', + dept_name varchar(30) default '' comment '閮ㄩ棬鍚嶇О', + order_num int(4) default 0 comment '鏄剧ず椤哄簭', + leader varchar(20) default null comment '璐熻矗浜�', + phone varchar(11) default null comment '鑱旂郴鐢佃瘽', + email varchar(50) default null comment '閭', + status char(1) default '0' comment '閮ㄩ棬鐘舵�侊紙0姝e父 1鍋滅敤锛�', + del_flag char(1) default '0' comment '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + primary key (dept_id) +) engine=innodb auto_increment=200 comment = '閮ㄩ棬琛�'; + +-- ---------------------------- +-- 鍒濆鍖�-閮ㄩ棬琛ㄦ暟鎹� +-- ---------------------------- +insert into sys_dept values(100, 0, '0', '鑻ヤ緷绉戞妧', 0, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(101, 100, '0,100', '娣卞湷鎬诲叕鍙�', 1, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(102, 100, '0,100', '闀挎矙鍒嗗叕鍙�', 2, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(103, 101, '0,100,101', '鐮斿彂閮ㄩ棬', 1, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(104, 101, '0,100,101', '甯傚満閮ㄩ棬', 2, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(105, 101, '0,100,101', '娴嬭瘯閮ㄩ棬', 3, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(106, 101, '0,100,101', '璐㈠姟閮ㄩ棬', 4, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(107, 101, '0,100,101', '杩愮淮閮ㄩ棬', 5, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(108, 102, '0,100,102', '甯傚満閮ㄩ棬', 1, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); +insert into sys_dept values(109, 102, '0,100,102', '璐㈠姟閮ㄩ棬', 2, '鑻ヤ緷', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00'); + + +-- ---------------------------- +-- 2銆佺敤鎴蜂俊鎭〃 +-- ---------------------------- +drop table if exists sys_user; +create table sys_user ( + user_id bigint(20) not null auto_increment comment '鐢ㄦ埛ID', + dept_id bigint(20) default null comment '閮ㄩ棬ID', + user_name varchar(30) not null comment '鐢ㄦ埛璐﹀彿', + nick_name varchar(30) not null comment '鐢ㄦ埛鏄电О', + user_type varchar(2) default '00' comment '鐢ㄦ埛绫诲瀷锛�00绯荤粺鐢ㄦ埛锛�', + email varchar(50) default '' comment '鐢ㄦ埛閭', + phonenumber varchar(11) default '' comment '鎵嬫満鍙风爜', + sex char(1) default '0' comment '鐢ㄦ埛鎬у埆锛�0鐢� 1濂� 2鏈煡锛�', + avatar varchar(100) default '' comment '澶村儚鍦板潃', + password varchar(100) default '' comment '瀵嗙爜', + status char(1) default '0' comment '甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�', + del_flag char(1) default '0' comment '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�', + login_ip varchar(50) default '' comment '鏈�鍚庣櫥闄咺P', + login_date datetime comment '鏈�鍚庣櫥闄嗘椂闂�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (user_id) +) engine=innodb auto_increment=100 comment = '鐢ㄦ埛淇℃伅琛�'; + +-- ---------------------------- +-- 鍒濆鍖�-鐢ㄦ埛淇℃伅琛ㄦ暟鎹� +-- ---------------------------- +insert into sys_user values(1, 103, 'admin', '鑻ヤ緷', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2018-03-16 11-33-00', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绠$悊鍛�'); +insert into sys_user values(2, 105, 'ry', '鑻ヤ緷', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2018-03-16 11-33-00', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '娴嬭瘯鍛�'); + + +-- ---------------------------- +-- 3銆佸矖浣嶄俊鎭〃 +-- ---------------------------- +drop table if exists sys_post; +create table sys_post +( + post_id bigint(20) not null auto_increment comment '宀椾綅ID', + post_code varchar(64) not null comment '宀椾綅缂栫爜', + post_name varchar(50) not null comment '宀椾綅鍚嶇О', + post_sort int(4) not null comment '鏄剧ず椤哄簭', + status char(1) not null comment '鐘舵�侊紙0姝e父 1鍋滅敤锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (post_id) +) engine=innodb comment = '宀椾綅淇℃伅琛�'; + +-- ---------------------------- +-- 鍒濆鍖�-宀椾綅淇℃伅琛ㄦ暟鎹� +-- ---------------------------- +insert into sys_post values(1, 'ceo', '钁d簨闀�', 1, '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_post values(2, 'se', '椤圭洰缁忕悊', 2, '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_post values(3, 'hr', '浜哄姏璧勬簮', 3, '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_post values(4, 'user', '鏅�氬憳宸�', 4, '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); + + +-- ---------------------------- +-- 4銆佽鑹蹭俊鎭〃 +-- ---------------------------- +drop table if exists sys_role; +create table sys_role ( + role_id bigint(20) not null auto_increment comment '瑙掕壊ID', + role_name varchar(30) not null comment '瑙掕壊鍚嶇О', + role_key varchar(100) not null comment '瑙掕壊鏉冮檺瀛楃涓�', + role_sort int(4) not null comment '鏄剧ず椤哄簭', + data_scope char(1) default '1' comment '鏁版嵁鑼冨洿锛�1锛氬叏閮ㄦ暟鎹潈闄� 2锛氳嚜瀹氭暟鎹潈闄� 3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺 4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級', + status char(1) not null comment '瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛�', + del_flag char(1) default '0' comment '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (role_id) +) engine=innodb auto_increment=100 comment = '瑙掕壊淇℃伅琛�'; + +-- ---------------------------- +-- 鍒濆鍖�-瑙掕壊淇℃伅琛ㄦ暟鎹� +-- ---------------------------- +insert into sys_role values('1', '绠$悊鍛�', 'admin', 1, 1, '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绠$悊鍛�'); +insert into sys_role values('2', '鏅�氳鑹�', 'common', 2, 2, '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鏅�氳鑹�'); + + +-- ---------------------------- +-- 5銆佽彍鍗曟潈闄愯〃 +-- ---------------------------- +drop table if exists sys_menu; +create table sys_menu ( + menu_id bigint(20) not null auto_increment comment '鑿滃崟ID', + menu_name varchar(50) not null comment '鑿滃崟鍚嶇О', + parent_id bigint(20) default 0 comment '鐖惰彍鍗旾D', + order_num int(4) default 0 comment '鏄剧ず椤哄簭', + path varchar(200) default '' comment '璺敱鍦板潃', + component varchar(255) default null comment '缁勪欢璺緞', + is_frame int(1) default 1 comment '鏄惁涓哄閾撅紙0鏄� 1鍚︼級', + menu_type char(1) default '' comment '鑿滃崟绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛�', + visible char(1) default 0 comment '鑿滃崟鐘舵�侊紙0鏄剧ず 1闅愯棌锛�', + perms varchar(100) default null comment '鏉冮檺鏍囪瘑', + icon varchar(100) default '#' comment '鑿滃崟鍥炬爣', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default '' comment '澶囨敞', + primary key (menu_id) +) engine=innodb auto_increment=2000 comment = '鑿滃崟鏉冮檺琛�'; + +-- ---------------------------- +-- 鍒濆鍖�-鑿滃崟淇℃伅琛ㄦ暟鎹� +-- ---------------------------- +-- 涓�绾ц彍鍗� +insert into sys_menu values('1', '绯荤粺绠$悊', '0', '1', 'system', null, 1, 'M', '0', '', 'system', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺绠$悊鐩綍'); +insert into sys_menu values('2', '绯荤粺鐩戞帶', '0', '2', 'monitor', null, 1, 'M', '0', '', 'monitor', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺鐩戞帶鐩綍'); +insert into sys_menu values('3', '绯荤粺宸ュ叿', '0', '3', 'tool', null, 1, 'M', '0', '', 'tool', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺宸ュ叿鐩綍'); +insert into sys_menu values('4', '鑻ヤ緷瀹樼綉', '0', '4', 'http://ruoyi.vip', null , 0, 'M', '0', '', 'guide', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鑻ヤ緷瀹樼綉鍦板潃'); +-- 浜岀骇鑿滃崟 +insert into sys_menu values('100', '鐢ㄦ埛绠$悊', '1', '1', 'user', 'system/user/index', 1, 'C', '0', 'system:user:list', 'user', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鐢ㄦ埛绠$悊鑿滃崟'); +insert into sys_menu values('101', '瑙掕壊绠$悊', '1', '2', 'role', 'system/role/index', 1, 'C', '0', 'system:role:list', 'peoples', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '瑙掕壊绠$悊鑿滃崟'); +insert into sys_menu values('102', '鑿滃崟绠$悊', '1', '3', 'menu', 'system/menu/index', 1, 'C', '0', 'system:menu:list', 'tree-table', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鑿滃崟绠$悊鑿滃崟'); +insert into sys_menu values('103', '閮ㄩ棬绠$悊', '1', '4', 'dept', 'system/dept/index', 1, 'C', '0', 'system:dept:list', 'tree', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '閮ㄩ棬绠$悊鑿滃崟'); +insert into sys_menu values('104', '宀椾綅绠$悊', '1', '5', 'post', 'system/post/index', 1, 'C', '0', 'system:post:list', 'post', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '宀椾綅绠$悊鑿滃崟'); +insert into sys_menu values('105', '瀛楀吀绠$悊', '1', '6', 'dict', 'system/dict/index', 1, 'C', '0', 'system:dict:list', 'dict', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '瀛楀吀绠$悊鑿滃崟'); +insert into sys_menu values('106', '鍙傛暟璁剧疆', '1', '7', 'config', 'system/config/index', 1, 'C', '0', 'system:config:list', 'edit', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍙傛暟璁剧疆鑿滃崟'); +insert into sys_menu values('107', '閫氱煡鍏憡', '1', '8', 'notice', 'system/notice/index', 1, 'C', '0', 'system:notice:list', 'message', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '閫氱煡鍏憡鑿滃崟'); +insert into sys_menu values('108', '鏃ュ織绠$悊', '1', '9', 'log', 'system/log/index', 1, 'M', '0', '', 'log', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鏃ュ織绠$悊鑿滃崟'); +insert into sys_menu values('109', '鍦ㄧ嚎鐢ㄦ埛', '2', '1', 'online', 'monitor/online/index', 1, 'C', '0', 'monitor:online:list', 'online', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍦ㄧ嚎鐢ㄦ埛鑿滃崟'); +insert into sys_menu values('110', '瀹氭椂浠诲姟', '2', '2', 'job', 'monitor/job/index', 1, 'C', '0', 'monitor:job:list', 'job', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '瀹氭椂浠诲姟鑿滃崟'); +insert into sys_menu values('111', '鏁版嵁鐩戞帶', '2', '3', 'druid', 'monitor/druid/index', 1, 'C', '0', 'monitor:druid:list', 'druid', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鏁版嵁鐩戞帶鑿滃崟'); +insert into sys_menu values('112', '鏈嶅姟鐩戞帶', '2', '4', 'server', 'monitor/server/index', 1, 'C', '0', 'monitor:server:list', 'server', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鏈嶅姟鐩戞帶鑿滃崟'); +insert into sys_menu values('113', '琛ㄥ崟鏋勫缓', '3', '1', 'build', 'tool/build/index', 1 ,'C', '0', 'tool:build:list', 'build', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '琛ㄥ崟鏋勫缓鑿滃崟'); +insert into sys_menu values('114', '浠g爜鐢熸垚', '3', '2', 'gen', 'tool/gen/index', 1, 'C', '0', 'tool:gen:list', 'code', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '浠g爜鐢熸垚鑿滃崟'); +insert into sys_menu values('115', '绯荤粺鎺ュ彛', '3', '3', 'swagger', 'tool/swagger/index', 1, 'C', '0', 'tool:swagger:list', 'swagger', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺鎺ュ彛鑿滃崟'); +-- 涓夌骇鑿滃崟 +insert into sys_menu values('500', '鎿嶄綔鏃ュ織', '108', '1', 'operlog', 'monitor/operlog/index', 1, 'C', '0', 'monitor:operlog:list', 'form', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鎿嶄綔鏃ュ織鑿滃崟'); +insert into sys_menu values('501', '鐧诲綍鏃ュ織', '108', '2', 'logininfor', 'monitor/logininfor/index', 1, 'C', '0', 'monitor:logininfor:list', 'logininfor', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鐧诲綍鏃ュ織鑿滃崟'); +-- 鐢ㄦ埛绠$悊鎸夐挳 +insert into sys_menu values('1001', '鐢ㄦ埛鏌ヨ', '100', '1', '', '', 1, 'F', '0', 'system:user:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1002', '鐢ㄦ埛鏂板', '100', '2', '', '', 1, 'F', '0', 'system:user:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1003', '鐢ㄦ埛淇敼', '100', '3', '', '', 1, 'F', '0', 'system:user:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1004', '鐢ㄦ埛鍒犻櫎', '100', '4', '', '', 1, 'F', '0', 'system:user:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1005', '鐢ㄦ埛瀵煎嚭', '100', '5', '', '', 1, 'F', '0', 'system:user:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1006', '鐢ㄦ埛瀵煎叆', '100', '6', '', '', 1, 'F', '0', 'system:user:import', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1007', '閲嶇疆瀵嗙爜', '100', '7', '', '', 1, 'F', '0', 'system:user:resetPwd', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 瑙掕壊绠$悊鎸夐挳 +insert into sys_menu values('1008', '瑙掕壊鏌ヨ', '101', '1', '', '', 1, 'F', '0', 'system:role:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1009', '瑙掕壊鏂板', '101', '2', '', '', 1, 'F', '0', 'system:role:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1010', '瑙掕壊淇敼', '101', '3', '', '', 1, 'F', '0', 'system:role:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1011', '瑙掕壊鍒犻櫎', '101', '4', '', '', 1, 'F', '0', 'system:role:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1012', '瑙掕壊瀵煎嚭', '101', '5', '', '', 1, 'F', '0', 'system:role:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 鑿滃崟绠$悊鎸夐挳 +insert into sys_menu values('1013', '鑿滃崟鏌ヨ', '102', '1', '', '', 1, 'F', '0', 'system:menu:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1014', '鑿滃崟鏂板', '102', '2', '', '', 1, 'F', '0', 'system:menu:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1015', '鑿滃崟淇敼', '102', '3', '', '', 1, 'F', '0', 'system:menu:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1016', '鑿滃崟鍒犻櫎', '102', '4', '', '', 1, 'F', '0', 'system:menu:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 閮ㄩ棬绠$悊鎸夐挳 +insert into sys_menu values('1017', '閮ㄩ棬鏌ヨ', '103', '1', '', '', 1, 'F', '0', 'system:dept:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1018', '閮ㄩ棬鏂板', '103', '2', '', '', 1, 'F', '0', 'system:dept:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1019', '閮ㄩ棬淇敼', '103', '3', '', '', 1, 'F', '0', 'system:dept:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1020', '閮ㄩ棬鍒犻櫎', '103', '4', '', '', 1, 'F', '0', 'system:dept:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 宀椾綅绠$悊鎸夐挳 +insert into sys_menu values('1021', '宀椾綅鏌ヨ', '104', '1', '', '', 1, 'F', '0', 'system:post:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1022', '宀椾綅鏂板', '104', '2', '', '', 1, 'F', '0', 'system:post:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1023', '宀椾綅淇敼', '104', '3', '', '', 1, 'F', '0', 'system:post:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1024', '宀椾綅鍒犻櫎', '104', '4', '', '', 1, 'F', '0', 'system:post:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1025', '宀椾綅瀵煎嚭', '104', '5', '', '', 1, 'F', '0', 'system:post:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 瀛楀吀绠$悊鎸夐挳 +insert into sys_menu values('1026', '瀛楀吀鏌ヨ', '105', '1', '#', '', 1, 'F', '0', 'system:dict:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1027', '瀛楀吀鏂板', '105', '2', '#', '', 1, 'F', '0', 'system:dict:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1028', '瀛楀吀淇敼', '105', '3', '#', '', 1, 'F', '0', 'system:dict:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1029', '瀛楀吀鍒犻櫎', '105', '4', '#', '', 1, 'F', '0', 'system:dict:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1030', '瀛楀吀瀵煎嚭', '105', '5', '#', '', 1, 'F', '0', 'system:dict:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 鍙傛暟璁剧疆鎸夐挳 +insert into sys_menu values('1031', '鍙傛暟鏌ヨ', '106', '1', '#', '', 1, 'F', '0', 'system:config:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1032', '鍙傛暟鏂板', '106', '2', '#', '', 1, 'F', '0', 'system:config:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1033', '鍙傛暟淇敼', '106', '3', '#', '', 1, 'F', '0', 'system:config:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1034', '鍙傛暟鍒犻櫎', '106', '4', '#', '', 1, 'F', '0', 'system:config:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1035', '鍙傛暟瀵煎嚭', '106', '5', '#', '', 1, 'F', '0', 'system:config:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 閫氱煡鍏憡鎸夐挳 +insert into sys_menu values('1036', '鍏憡鏌ヨ', '107', '1', '#', '', 1, 'F', '0', 'system:notice:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1037', '鍏憡鏂板', '107', '2', '#', '', 1, 'F', '0', 'system:notice:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1038', '鍏憡淇敼', '107', '3', '#', '', 1, 'F', '0', 'system:notice:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1039', '鍏憡鍒犻櫎', '107', '4', '#', '', 1, 'F', '0', 'system:notice:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 鎿嶄綔鏃ュ織鎸夐挳 +insert into sys_menu values('1040', '鎿嶄綔鏌ヨ', '500', '1', '#', '', 1, 'F', '0', 'monitor:operlog:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1041', '鎿嶄綔鍒犻櫎', '500', '2', '#', '', 1, 'F', '0', 'monitor:operlog:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1042', '鏃ュ織瀵煎嚭', '500', '4', '#', '', 1, 'F', '0', 'monitor:operlog:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 鐧诲綍鏃ュ織鎸夐挳 +insert into sys_menu values('1043', '鐧诲綍鏌ヨ', '501', '1', '#', '', 1, 'F', '0', 'monitor:logininfor:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1044', '鐧诲綍鍒犻櫎', '501', '2', '#', '', 1, 'F', '0', 'monitor:logininfor:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1045', '鏃ュ織瀵煎嚭', '501', '3', '#', '', 1, 'F', '0', 'monitor:logininfor:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 鍦ㄧ嚎鐢ㄦ埛鎸夐挳 +insert into sys_menu values('1046', '鍦ㄧ嚎鏌ヨ', '109', '1', '#', '', 1, 'F', '0', 'monitor:online:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1047', '鎵归噺寮洪��', '109', '2', '#', '', 1, 'F', '0', 'monitor:online:batchLogout', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1048', '鍗曟潯寮洪��', '109', '3', '#', '', 1, 'F', '0', 'monitor:online:forceLogout', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 瀹氭椂浠诲姟鎸夐挳 +insert into sys_menu values('1049', '浠诲姟鏌ヨ', '110', '1', '#', '', 1, 'F', '0', 'monitor:job:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1050', '浠诲姟鏂板', '110', '2', '#', '', 1, 'F', '0', 'monitor:job:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1051', '浠诲姟淇敼', '110', '3', '#', '', 1, 'F', '0', 'monitor:job:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1052', '浠诲姟鍒犻櫎', '110', '4', '#', '', 1, 'F', '0', 'monitor:job:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1053', '鐘舵�佷慨鏀�', '110', '5', '#', '', 1, 'F', '0', 'monitor:job:changeStatus', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1054', '浠诲姟瀵煎嚭', '110', '7', '#', '', 1, 'F', '0', 'monitor:job:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +-- 浠g爜鐢熸垚鎸夐挳 +insert into sys_menu values('1055', '鐢熸垚鏌ヨ', '114', '1', '#', '', 1, 'F', '0', 'tool:gen:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1056', '鐢熸垚淇敼', '114', '2', '#', '', 1, 'F', '0', 'tool:gen:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1057', '鐢熸垚鍒犻櫎', '114', '3', '#', '', 1, 'F', '0', 'tool:gen:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1058', '瀵煎叆浠g爜', '114', '2', '#', '', 1, 'F', '0', 'tool:gen:import', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1059', '棰勮浠g爜', '114', '4', '#', '', 1, 'F', '0', 'tool:gen:preview', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_menu values('1060', '鐢熸垚浠g爜', '114', '5', '#', '', 1, 'F', '0', 'tool:gen:code', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); + + +-- ---------------------------- +-- 6銆佺敤鎴峰拰瑙掕壊鍏宠仈琛� 鐢ㄦ埛N-1瑙掕壊 +-- ---------------------------- +drop table if exists sys_user_role; +create table sys_user_role ( + user_id bigint(20) not null comment '鐢ㄦ埛ID', + role_id bigint(20) not null comment '瑙掕壊ID', + primary key(user_id, role_id) +) engine=innodb comment = '鐢ㄦ埛鍜岃鑹插叧鑱旇〃'; + +-- ---------------------------- +-- 鍒濆鍖�-鐢ㄦ埛鍜岃鑹插叧鑱旇〃鏁版嵁 +-- ---------------------------- +insert into sys_user_role values ('1', '1'); +insert into sys_user_role values ('2', '2'); + + +-- ---------------------------- +-- 7銆佽鑹插拰鑿滃崟鍏宠仈琛� 瑙掕壊1-N鑿滃崟 +-- ---------------------------- +drop table if exists sys_role_menu; +create table sys_role_menu ( + role_id bigint(20) not null comment '瑙掕壊ID', + menu_id bigint(20) not null comment '鑿滃崟ID', + primary key(role_id, menu_id) +) engine=innodb comment = '瑙掕壊鍜岃彍鍗曞叧鑱旇〃'; + +-- ---------------------------- +-- 鍒濆鍖�-瑙掕壊鍜岃彍鍗曞叧鑱旇〃鏁版嵁 +-- ---------------------------- +insert into sys_role_menu values ('2', '1'); +insert into sys_role_menu values ('2', '2'); +insert into sys_role_menu values ('2', '3'); +insert into sys_role_menu values ('2', '4'); +insert into sys_role_menu values ('2', '100'); +insert into sys_role_menu values ('2', '101'); +insert into sys_role_menu values ('2', '102'); +insert into sys_role_menu values ('2', '103'); +insert into sys_role_menu values ('2', '104'); +insert into sys_role_menu values ('2', '105'); +insert into sys_role_menu values ('2', '106'); +insert into sys_role_menu values ('2', '107'); +insert into sys_role_menu values ('2', '108'); +insert into sys_role_menu values ('2', '109'); +insert into sys_role_menu values ('2', '110'); +insert into sys_role_menu values ('2', '111'); +insert into sys_role_menu values ('2', '112'); +insert into sys_role_menu values ('2', '113'); +insert into sys_role_menu values ('2', '114'); +insert into sys_role_menu values ('2', '115'); +insert into sys_role_menu values ('2', '500'); +insert into sys_role_menu values ('2', '501'); +insert into sys_role_menu values ('2', '1000'); +insert into sys_role_menu values ('2', '1001'); +insert into sys_role_menu values ('2', '1002'); +insert into sys_role_menu values ('2', '1003'); +insert into sys_role_menu values ('2', '1004'); +insert into sys_role_menu values ('2', '1005'); +insert into sys_role_menu values ('2', '1006'); +insert into sys_role_menu values ('2', '1007'); +insert into sys_role_menu values ('2', '1008'); +insert into sys_role_menu values ('2', '1009'); +insert into sys_role_menu values ('2', '1010'); +insert into sys_role_menu values ('2', '1011'); +insert into sys_role_menu values ('2', '1012'); +insert into sys_role_menu values ('2', '1013'); +insert into sys_role_menu values ('2', '1014'); +insert into sys_role_menu values ('2', '1015'); +insert into sys_role_menu values ('2', '1016'); +insert into sys_role_menu values ('2', '1017'); +insert into sys_role_menu values ('2', '1018'); +insert into sys_role_menu values ('2', '1019'); +insert into sys_role_menu values ('2', '1020'); +insert into sys_role_menu values ('2', '1021'); +insert into sys_role_menu values ('2', '1022'); +insert into sys_role_menu values ('2', '1023'); +insert into sys_role_menu values ('2', '1024'); +insert into sys_role_menu values ('2', '1025'); +insert into sys_role_menu values ('2', '1026'); +insert into sys_role_menu values ('2', '1027'); +insert into sys_role_menu values ('2', '1028'); +insert into sys_role_menu values ('2', '1029'); +insert into sys_role_menu values ('2', '1030'); +insert into sys_role_menu values ('2', '1031'); +insert into sys_role_menu values ('2', '1032'); +insert into sys_role_menu values ('2', '1033'); +insert into sys_role_menu values ('2', '1034'); +insert into sys_role_menu values ('2', '1035'); +insert into sys_role_menu values ('2', '1036'); +insert into sys_role_menu values ('2', '1037'); +insert into sys_role_menu values ('2', '1038'); +insert into sys_role_menu values ('2', '1039'); +insert into sys_role_menu values ('2', '1040'); +insert into sys_role_menu values ('2', '1041'); +insert into sys_role_menu values ('2', '1042'); +insert into sys_role_menu values ('2', '1043'); +insert into sys_role_menu values ('2', '1044'); +insert into sys_role_menu values ('2', '1045'); +insert into sys_role_menu values ('2', '1046'); +insert into sys_role_menu values ('2', '1047'); +insert into sys_role_menu values ('2', '1048'); +insert into sys_role_menu values ('2', '1049'); +insert into sys_role_menu values ('2', '1050'); +insert into sys_role_menu values ('2', '1051'); +insert into sys_role_menu values ('2', '1052'); +insert into sys_role_menu values ('2', '1053'); +insert into sys_role_menu values ('2', '1054'); +insert into sys_role_menu values ('2', '1055'); +insert into sys_role_menu values ('2', '1056'); +insert into sys_role_menu values ('2', '1057'); +insert into sys_role_menu values ('2', '1058'); +insert into sys_role_menu values ('2', '1059'); +insert into sys_role_menu values ('2', '1060'); + +-- ---------------------------- +-- 8銆佽鑹插拰閮ㄩ棬鍏宠仈琛� 瑙掕壊1-N閮ㄩ棬 +-- ---------------------------- +drop table if exists sys_role_dept; +create table sys_role_dept ( + role_id bigint(20) not null comment '瑙掕壊ID', + dept_id bigint(20) not null comment '閮ㄩ棬ID', + primary key(role_id, dept_id) +) engine=innodb comment = '瑙掕壊鍜岄儴闂ㄥ叧鑱旇〃'; + +-- ---------------------------- +-- 鍒濆鍖�-瑙掕壊鍜岄儴闂ㄥ叧鑱旇〃鏁版嵁 +-- ---------------------------- +insert into sys_role_dept values ('2', '100'); +insert into sys_role_dept values ('2', '101'); +insert into sys_role_dept values ('2', '105'); + + +-- ---------------------------- +-- 9銆佺敤鎴蜂笌宀椾綅鍏宠仈琛� 鐢ㄦ埛1-N宀椾綅 +-- ---------------------------- +drop table if exists sys_user_post; +create table sys_user_post +( + user_id bigint(20) not null comment '鐢ㄦ埛ID', + post_id bigint(20) not null comment '宀椾綅ID', + primary key (user_id, post_id) +) engine=innodb comment = '鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃'; + +-- ---------------------------- +-- 鍒濆鍖�-鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃鏁版嵁 +-- ---------------------------- +insert into sys_user_post values ('1', '1'); +insert into sys_user_post values ('2', '2'); + + +-- ---------------------------- +-- 10銆佹搷浣滄棩蹇楄褰� +-- ---------------------------- +drop table if exists sys_oper_log; +create table sys_oper_log ( + oper_id bigint(20) not null auto_increment comment '鏃ュ織涓婚敭', + title varchar(50) default '' comment '妯″潡鏍囬', + business_type int(2) default 0 comment '涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛�', + method varchar(100) default '' comment '鏂规硶鍚嶇О', + request_method varchar(10) default '' comment '璇锋眰鏂瑰紡', + operator_type int(1) default 0 comment '鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級', + oper_name varchar(50) default '' comment '鎿嶄綔浜哄憳', + dept_name varchar(50) default '' comment '閮ㄩ棬鍚嶇О', + oper_url varchar(255) default '' comment '璇锋眰URL', + oper_ip varchar(50) default '' comment '涓绘満鍦板潃', + oper_location varchar(255) default '' comment '鎿嶄綔鍦扮偣', + oper_param varchar(2000) default '' comment '璇锋眰鍙傛暟', + json_result varchar(2000) default '' comment '杩斿洖鍙傛暟', + status int(1) default 0 comment '鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛�', + error_msg varchar(2000) default '' comment '閿欒娑堟伅', + oper_time datetime comment '鎿嶄綔鏃堕棿', + primary key (oper_id) +) engine=innodb auto_increment=100 comment = '鎿嶄綔鏃ュ織璁板綍'; + + +-- ---------------------------- +-- 11銆佸瓧鍏哥被鍨嬭〃 +-- ---------------------------- +drop table if exists sys_dict_type; +create table sys_dict_type +( + dict_id bigint(20) not null auto_increment comment '瀛楀吀涓婚敭', + dict_name varchar(100) default '' comment '瀛楀吀鍚嶇О', + dict_type varchar(100) default '' comment '瀛楀吀绫诲瀷', + status char(1) default '0' comment '鐘舵�侊紙0姝e父 1鍋滅敤锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (dict_id), + unique (dict_type) +) engine=innodb auto_increment=100 comment = '瀛楀吀绫诲瀷琛�'; + +insert into sys_dict_type values(1, '鐢ㄦ埛鎬у埆', 'sys_user_sex', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鐢ㄦ埛鎬у埆鍒楄〃'); +insert into sys_dict_type values(2, '鑿滃崟鐘舵��', 'sys_show_hide', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鑿滃崟鐘舵�佸垪琛�'); +insert into sys_dict_type values(3, '绯荤粺寮�鍏�', 'sys_normal_disable', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺寮�鍏冲垪琛�'); +insert into sys_dict_type values(4, '浠诲姟鐘舵��', 'sys_job_status', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '浠诲姟鐘舵�佸垪琛�'); +insert into sys_dict_type values(5, '浠诲姟鍒嗙粍', 'sys_job_group', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '浠诲姟鍒嗙粍鍒楄〃'); +insert into sys_dict_type values(6, '绯荤粺鏄惁', 'sys_yes_no', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺鏄惁鍒楄〃'); +insert into sys_dict_type values(7, '閫氱煡绫诲瀷', 'sys_notice_type', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '閫氱煡绫诲瀷鍒楄〃'); +insert into sys_dict_type values(8, '閫氱煡鐘舵��', 'sys_notice_status', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '閫氱煡鐘舵�佸垪琛�'); +insert into sys_dict_type values(9, '鎿嶄綔绫诲瀷', 'sys_oper_type', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鎿嶄綔绫诲瀷鍒楄〃'); +insert into sys_dict_type values(10, '绯荤粺鐘舵��', 'sys_common_status', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鐧诲綍鐘舵�佸垪琛�'); + + +-- ---------------------------- +-- 12銆佸瓧鍏告暟鎹〃 +-- ---------------------------- +drop table if exists sys_dict_data; +create table sys_dict_data +( + dict_code bigint(20) not null auto_increment comment '瀛楀吀缂栫爜', + dict_sort int(4) default 0 comment '瀛楀吀鎺掑簭', + dict_label varchar(100) default '' comment '瀛楀吀鏍囩', + dict_value varchar(100) default '' comment '瀛楀吀閿��', + dict_type varchar(100) default '' comment '瀛楀吀绫诲瀷', + css_class varchar(100) default null comment '鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛�', + list_class varchar(100) default null comment '琛ㄦ牸鍥炴樉鏍峰紡', + is_default char(1) default 'N' comment '鏄惁榛樿锛圷鏄� N鍚︼級', + status char(1) default '0' comment '鐘舵�侊紙0姝e父 1鍋滅敤锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (dict_code) +) engine=innodb auto_increment=100 comment = '瀛楀吀鏁版嵁琛�'; + +insert into sys_dict_data values(1, 1, '鐢�', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鎬у埆鐢�'); +insert into sys_dict_data values(2, 2, '濂�', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鎬у埆濂�'); +insert into sys_dict_data values(3, 3, '鏈煡', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鎬у埆鏈煡'); +insert into sys_dict_data values(4, 1, '鏄剧ず', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鏄剧ず鑿滃崟'); +insert into sys_dict_data values(5, 2, '闅愯棌', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '闅愯棌鑿滃崟'); +insert into sys_dict_data values(6, 1, '姝e父', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '姝e父鐘舵��'); +insert into sys_dict_data values(7, 2, '鍋滅敤', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍋滅敤鐘舵��'); +insert into sys_dict_data values(8, 1, '姝e父', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '姝e父鐘舵��'); +insert into sys_dict_data values(9, 2, '鏆傚仠', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍋滅敤鐘舵��'); +insert into sys_dict_data values(10, 1, '榛樿', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '榛樿鍒嗙粍'); +insert into sys_dict_data values(11, 2, '绯荤粺', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺鍒嗙粍'); +insert into sys_dict_data values(12, 1, '鏄�', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺榛樿鏄�'); +insert into sys_dict_data values(13, 2, '鍚�', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绯荤粺榛樿鍚�'); +insert into sys_dict_data values(14, 1, '閫氱煡', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '閫氱煡'); +insert into sys_dict_data values(15, 2, '鍏憡', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍏憡'); +insert into sys_dict_data values(16, 1, '姝e父', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '姝e父鐘舵��'); +insert into sys_dict_data values(17, 2, '鍏抽棴', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍏抽棴鐘舵��'); +insert into sys_dict_data values(18, 1, '鏂板', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鏂板鎿嶄綔'); +insert into sys_dict_data values(19, 2, '淇敼', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '淇敼鎿嶄綔'); +insert into sys_dict_data values(20, 3, '鍒犻櫎', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍒犻櫎鎿嶄綔'); +insert into sys_dict_data values(21, 4, '鎺堟潈', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鎺堟潈鎿嶄綔'); +insert into sys_dict_data values(22, 5, '瀵煎嚭', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '瀵煎嚭鎿嶄綔'); +insert into sys_dict_data values(23, 6, '瀵煎叆', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '瀵煎叆鎿嶄綔'); +insert into sys_dict_data values(24, 7, '寮洪��', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '寮洪��鎿嶄綔'); +insert into sys_dict_data values(25, 8, '鐢熸垚浠g爜', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鐢熸垚鎿嶄綔'); +insert into sys_dict_data values(26, 9, '娓呯┖鏁版嵁', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '娓呯┖鎿嶄綔'); +insert into sys_dict_data values(27, 1, '鎴愬姛', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '姝e父鐘舵��'); +insert into sys_dict_data values(28, 2, '澶辫触', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍋滅敤鐘舵��'); + + +-- ---------------------------- +-- 13銆佸弬鏁伴厤缃〃 +-- ---------------------------- +drop table if exists sys_config; +create table sys_config ( + config_id int(5) not null auto_increment comment '鍙傛暟涓婚敭', + config_name varchar(100) default '' comment '鍙傛暟鍚嶇О', + config_key varchar(100) default '' comment '鍙傛暟閿悕', + config_value varchar(500) default '' comment '鍙傛暟閿��', + config_type char(1) default 'N' comment '绯荤粺鍐呯疆锛圷鏄� N鍚︼級', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (config_id) +) engine=innodb auto_increment=100 comment = '鍙傛暟閰嶇疆琛�'; + +insert into sys_config values(1, '涓绘鏋堕〉-榛樿鐨偆鏍峰紡鍚嶇О', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '钃濊壊 skin-blue銆佺豢鑹� skin-green銆佺传鑹� skin-purple銆佺孩鑹� skin-red銆侀粍鑹� skin-yellow' ); +insert into sys_config values(2, '鐢ㄦ埛绠$悊-璐﹀彿鍒濆瀵嗙爜', 'sys.user.initPassword', '123456', 'Y', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '鍒濆鍖栧瘑鐮� 123456' ); +insert into sys_config values(3, '涓绘鏋堕〉-渚ц竟鏍忎富棰�', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '娣辫壊涓婚theme-dark锛屾祬鑹蹭富棰榯heme-light' ); + + +-- ---------------------------- +-- 14銆佺郴缁熻闂褰� +-- ---------------------------- +drop table if exists sys_logininfor; +create table sys_logininfor ( + info_id bigint(20) not null auto_increment comment '璁块棶ID', + user_name varchar(50) default '' comment '鐢ㄦ埛璐﹀彿', + ipaddr varchar(50) default '' comment '鐧诲綍IP鍦板潃', + login_location varchar(255) default '' comment '鐧诲綍鍦扮偣', + browser varchar(50) default '' comment '娴忚鍣ㄧ被鍨�', + os varchar(50) default '' comment '鎿嶄綔绯荤粺', + status char(1) default '0' comment '鐧诲綍鐘舵�侊紙0鎴愬姛 1澶辫触锛�', + msg varchar(255) default '' comment '鎻愮ず娑堟伅', + login_time datetime comment '璁块棶鏃堕棿', + primary key (info_id) +) engine=innodb auto_increment=100 comment = '绯荤粺璁块棶璁板綍'; + + +-- ---------------------------- +-- 15銆佸畾鏃朵换鍔¤皟搴﹁〃 +-- ---------------------------- +drop table if exists sys_job; +create table sys_job ( + job_id bigint(20) not null auto_increment comment '浠诲姟ID', + job_name varchar(64) default '' comment '浠诲姟鍚嶇О', + job_group varchar(64) default 'DEFAULT' comment '浠诲姟缁勫悕', + invoke_target varchar(500) not null comment '璋冪敤鐩爣瀛楃涓�', + cron_expression varchar(255) default '' comment 'cron鎵ц琛ㄨ揪寮�', + misfire_policy varchar(20) default '3' comment '璁″垝鎵ц閿欒绛栫暐锛�1绔嬪嵆鎵ц 2鎵ц涓�娆� 3鏀惧純鎵ц锛�', + concurrent char(1) default '1' comment '鏄惁骞跺彂鎵ц锛�0鍏佽 1绂佹锛�', + status char(1) default '0' comment '鐘舵�侊紙0姝e父 1鏆傚仠锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default '' comment '澶囨敞淇℃伅', + primary key (job_id, job_name, job_group) +) engine=innodb auto_increment=100 comment = '瀹氭椂浠诲姟璋冨害琛�'; + +insert into sys_job values(1, '绯荤粺榛樿锛堟棤鍙傦級', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_job values(2, '绯荤粺榛樿锛堟湁鍙傦級', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); +insert into sys_job values(3, '绯荤粺榛樿锛堝鍙傦級', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); + + +-- ---------------------------- +-- 16銆佸畾鏃朵换鍔¤皟搴︽棩蹇楄〃 +-- ---------------------------- +drop table if exists sys_job_log; +create table sys_job_log ( + job_log_id bigint(20) not null auto_increment comment '浠诲姟鏃ュ織ID', + job_name varchar(64) not null comment '浠诲姟鍚嶇О', + job_group varchar(64) not null comment '浠诲姟缁勫悕', + invoke_target varchar(500) not null comment '璋冪敤鐩爣瀛楃涓�', + job_message varchar(500) comment '鏃ュ織淇℃伅', + status char(1) default '0' comment '鎵ц鐘舵�侊紙0姝e父 1澶辫触锛�', + exception_info varchar(2000) default '' comment '寮傚父淇℃伅', + create_time datetime comment '鍒涘缓鏃堕棿', + primary key (job_log_id) +) engine=innodb comment = '瀹氭椂浠诲姟璋冨害鏃ュ織琛�'; + + +-- ---------------------------- +-- 17銆侀�氱煡鍏憡琛� +-- ---------------------------- +drop table if exists sys_notice; +create table sys_notice ( + notice_id int(4) not null auto_increment comment '鍏憡ID', + notice_title varchar(50) not null comment '鍏憡鏍囬', + notice_type char(1) not null comment '鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛�', + notice_content varchar(2000) default null comment '鍏憡鍐呭', + status char(1) default '0' comment '鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛�', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(255) default null comment '澶囨敞', + primary key (notice_id) +) engine=innodb auto_increment=10 comment = '閫氱煡鍏憡琛�'; + +-- ---------------------------- +-- 鍒濆鍖�-鍏憡淇℃伅琛ㄦ暟鎹� +-- ---------------------------- +insert into sys_notice values('1', '娓╅Θ鎻愰啋锛�2018-07-01 鑻ヤ緷鏂扮増鏈彂甯冨暒', '2', '鏂扮増鏈唴瀹�', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绠$悊鍛�'); +insert into sys_notice values('2', '缁存姢閫氱煡锛�2018-07-01 鑻ヤ緷绯荤粺鍑屾櫒缁存姢', '1', '缁存姢鍐呭', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '绠$悊鍛�'); + + +-- ---------------------------- +-- 18銆佷唬鐮佺敓鎴愪笟鍔¤〃 +-- ---------------------------- +drop table if exists gen_table; +create table gen_table ( + table_id bigint(20) not null auto_increment comment '缂栧彿', + table_name varchar(200) default '' comment '琛ㄥ悕绉�', + table_comment varchar(500) default '' comment '琛ㄦ弿杩�', + class_name varchar(100) default '' comment '瀹炰綋绫诲悕绉�', + tpl_category varchar(200) default 'crud' comment '浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔锛�', + package_name varchar(100) comment '鐢熸垚鍖呰矾寰�', + module_name varchar(30) comment '鐢熸垚妯″潡鍚�', + business_name varchar(30) comment '鐢熸垚涓氬姟鍚�', + function_name varchar(50) comment '鐢熸垚鍔熻兘鍚�', + function_author varchar(50) comment '鐢熸垚鍔熻兘浣滆��', + options varchar(1000) comment '鍏跺畠鐢熸垚閫夐」', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + remark varchar(500) default null comment '澶囨敞', + primary key (table_id) +) engine=innodb auto_increment=1 comment = '浠g爜鐢熸垚涓氬姟琛�'; + + +-- ---------------------------- +-- 19銆佷唬鐮佺敓鎴愪笟鍔¤〃瀛楁 +-- ---------------------------- +drop table if exists gen_table_column; +create table gen_table_column ( + column_id bigint(20) not null auto_increment comment '缂栧彿', + table_id varchar(64) comment '褰掑睘琛ㄧ紪鍙�', + column_name varchar(200) comment '鍒楀悕绉�', + column_comment varchar(500) comment '鍒楁弿杩�', + column_type varchar(100) comment '鍒楃被鍨�', + java_type varchar(500) comment 'JAVA绫诲瀷', + java_field varchar(200) comment 'JAVA瀛楁鍚�', + is_pk char(1) comment '鏄惁涓婚敭锛�1鏄級', + is_increment char(1) comment '鏄惁鑷锛�1鏄級', + is_required char(1) comment '鏄惁蹇呭~锛�1鏄級', + is_insert char(1) comment '鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級', + is_edit char(1) comment '鏄惁缂栬緫瀛楁锛�1鏄級', + is_list char(1) comment '鏄惁鍒楄〃瀛楁锛�1鏄級', + is_query char(1) comment '鏄惁鏌ヨ瀛楁锛�1鏄級', + query_type varchar(200) default 'EQ' comment '鏌ヨ鏂瑰紡锛堢瓑浜庛�佷笉绛変簬銆佸ぇ浜庛�佸皬浜庛�佽寖鍥达級', + html_type varchar(200) comment '鏄剧ず绫诲瀷锛堟枃鏈銆佹枃鏈煙銆佷笅鎷夋銆佸閫夋銆佸崟閫夋銆佹棩鏈熸帶浠讹級', + dict_type varchar(200) default '' comment '瀛楀吀绫诲瀷', + sort int comment '鎺掑簭', + create_by varchar(64) default '' comment '鍒涘缓鑰�', + create_time datetime comment '鍒涘缓鏃堕棿', + update_by varchar(64) default '' comment '鏇存柊鑰�', + update_time datetime comment '鏇存柊鏃堕棿', + primary key (column_id) +) engine=innodb auto_increment=1 comment = '浠g爜鐢熸垚涓氬姟琛ㄥ瓧娈�'; \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi/src/main/java/com/ruoyi/RuoYiApplication.java new file mode 100644 index 0000000..32eb6f1 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/RuoYiApplication.java @@ -0,0 +1,30 @@ +package com.ruoyi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 鍚姩绋嬪簭 + * + * @author ruoyi + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class RuoYiApplication +{ + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(RuoYiApplication.class, args); + System.out.println("(鈾モ棤鈥库棤)锞夛緸 鑻ヤ緷鍚姩鎴愬姛 醿�(麓凇`醿�)锞� \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/RuoYiServletInitializer.java b/ruoyi/src/main/java/com/ruoyi/RuoYiServletInitializer.java new file mode 100644 index 0000000..6de67dc --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/RuoYiServletInitializer.java @@ -0,0 +1,18 @@ +package com.ruoyi; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web瀹瑰櫒涓繘琛岄儴缃� + * + * @author ruoyi + */ +public class RuoYiServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(RuoYiApplication.class); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java new file mode 100644 index 0000000..3466445 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/constant/Constants.java @@ -0,0 +1,101 @@ +package com.ruoyi.common.constant; + +import io.jsonwebtoken.Claims; + +/** + * 閫氱敤甯搁噺淇℃伅 + * + * @author ruoyi + */ +public class Constants +{ + /** + * UTF-8 瀛楃闆� + */ + public static final String UTF8 = "UTF-8"; + + /** + * 閫氱敤鎴愬姛鏍囪瘑 + */ + public static final String SUCCESS = "0"; + + /** + * 閫氱敤澶辫触鏍囪瘑 + */ + public static final String FAIL = "1"; + + /** + * 鐧诲綍鎴愬姛 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 娉ㄩ攢 + */ + public static final String LOGOUT = "Logout"; + + /** + * 鐧诲綍澶辫触 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 楠岃瘉鐮� redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 鐧诲綍鐢ㄦ埛 redis key + */ + public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 楠岃瘉鐮佹湁鏁堟湡锛堝垎閽燂級 + */ + public static final Integer CAPTCHA_EXPIRATION = 2; + + /** + * 浠ょ墝 + */ + public static final String TOKEN = "token"; + + /** + * 浠ょ墝鍓嶇紑 + */ + public static final String TOKEN_PREFIX = "Bearer "; + + /** + * 浠ょ墝鍓嶇紑 + */ + public static final String LOGIN_USER_KEY = "login_user_key"; + + /** + * 鐢ㄦ埛ID + */ + public static final String JWT_USERID = "userid"; + + /** + * 鐢ㄦ埛鍚嶇О + */ + public static final String JWT_USERNAME = Claims.SUBJECT; + + /** + * 鐢ㄦ埛澶村儚 + */ + public static final String JWT_AVATAR = "avatar"; + + /** + * 鍒涘缓鏃堕棿 + */ + public static final String JWT_CREATED = "created"; + + /** + * 鐢ㄦ埛鏉冮檺 + */ + public static final String JWT_AUTHORITIES = "authorities"; + + /** + * 璧勬簮鏄犲皠璺緞 鍓嶇紑 + */ + public static final String RESOURCE_PREFIX = "/profile"; +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java b/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java new file mode 100644 index 0000000..a975241 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/constant/GenConstants.java @@ -0,0 +1,94 @@ +package com.ruoyi.common.constant; + +/** + * 浠g爜鐢熸垚閫氱敤甯搁噺 + * + * @author ruoyi + */ +public class GenConstants +{ + /** 鍗曡〃锛堝鍒犳敼鏌ワ級 */ + public static final String TPL_CRUD = "crud"; + + /** 鏍戣〃锛堝鍒犳敼鏌ワ級 */ + public static final String TPL_TREE = "tree"; + + /** 鏍戠紪鐮佸瓧娈� */ + public static final String TREE_CODE = "treeCode"; + + /** 鏍戠埗缂栫爜瀛楁 */ + public static final String TREE_PARENT_CODE = "treeParentCode"; + + /** 鏍戝悕绉板瓧娈� */ + public static final String TREE_NAME = "treeName"; + + /** 鏁版嵁搴撳瓧绗︿覆绫诲瀷 */ + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "narchar", "varchar2", "tinytext", "text", + "mediumtext", "longtext" }; + + /** 鏁版嵁搴撴椂闂寸被鍨� */ + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; + + /** 鏁版嵁搴撴暟瀛楃被鍨� */ + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", + "bigint", "float", "float", "double", "decimal" }; + + /** 椤甸潰涓嶉渶瑕佺紪杈戝瓧娈� */ + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; + + /** 椤甸潰涓嶉渶瑕佹樉绀虹殑鍒楄〃瀛楁 */ + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time" }; + + /** 椤甸潰涓嶉渶瑕佹煡璇㈠瓧娈� */ + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", + "update_time", "remark" }; + + /** Entity鍩虹被瀛楁 */ + public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; + + /** Tree鍩虹被瀛楁 */ + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" }; + + /** 鏂囨湰妗� */ + public static final String HTML_INPUT = "input"; + + /** 鏂囨湰鍩� */ + public static final String HTML_TEXTAREA = "textarea"; + + /** 涓嬫媺妗� */ + public static final String HTML_SELECT = "select"; + + /** 鍗曢�夋 */ + public static final String HTML_RADIO = "radio"; + + /** 澶嶉�夋 */ + public static final String HTML_CHECKBOX = "checkbox"; + + /** 鏃ユ湡鎺т欢 */ + public static final String HTML_DATETIME = "datetime"; + + /** 瀛楃涓茬被鍨� */ + public static final String TYPE_STRING = "String"; + + /** 鏁村瀷 */ + public static final String TYPE_INTEGER = "Integer"; + + /** 闀挎暣鍨� */ + public static final String TYPE_LONG = "Long"; + + /** 娴偣鍨� */ + public static final String TYPE_DOUBLE = "Double"; + + /** 楂樼簿搴﹁绠楃被鍨� */ + public static final String TYPE_BIGDECIMAL = "BigDecimal"; + + /** 鏃堕棿绫诲瀷 */ + public static final String TYPE_DATE = "Date"; + + /** 妯$硦鏌ヨ */ + public static final String QUERY_LIKE = "LIKE"; + + /** 闇�瑕� */ + public static final String REQUIRE = "1"; +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/constant/HttpStatus.java b/ruoyi/src/main/java/com/ruoyi/common/constant/HttpStatus.java new file mode 100644 index 0000000..e029d17 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/constant/HttpStatus.java @@ -0,0 +1,89 @@ +package com.ruoyi.common.constant; + +/** + * 杩斿洖鐘舵�佺爜 + * + * @author ruoyi + */ +public interface HttpStatus +{ + /** + * 鎿嶄綔鎴愬姛 + */ + public static final int SUCCESS = 200; + + /** + * 瀵硅薄鍒涘缓鎴愬姛 + */ + public static final int CREATED = 201; + + /** + * 璇锋眰宸茬粡琚帴鍙� + */ + public static final int ACCEPTED = 202; + + /** + * 鎿嶄綔宸茬粡鎵ц鎴愬姛锛屼絾鏄病鏈夎繑鍥炴暟鎹� + */ + public static final int NO_CONTENT = 204; + + /** + * 璧勬簮宸茶绉婚櫎 + */ + public static final int MOVED_PERM = 301; + + /** + * 閲嶅畾鍚� + */ + public static final int SEE_OTHER = 303; + + /** + * 璧勬簮娌℃湁琚慨鏀� + */ + public static final int NOT_MODIFIED = 304; + + /** + * 鍙傛暟鍒楄〃閿欒锛堢己灏戯紝鏍煎紡涓嶅尮閰嶏級 + */ + public static final int BAD_REQUEST = 400; + + /** + * 鏈巿鏉� + */ + public static final int UNAUTHORIZED = 401; + + /** + * 璁块棶鍙楅檺锛屾巿鏉冭繃鏈� + */ + public static final int FORBIDDEN = 403; + + /** + * 璧勬簮锛屾湇鍔℃湭鎵惧埌 + */ + public static final int NOT_FOUND = 404; + + /** + * 涓嶅厑璁哥殑http鏂规硶 + */ + public static final int BAD_METHOD = 405; + + /** + * 璧勬簮鍐茬獊锛屾垨鑰呰祫婧愯閿� + */ + public static final int CONFLICT = 409; + + /** + * 涓嶆敮鎸佺殑鏁版嵁锛屽獟浣撶被鍨� + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 绯荤粺鍐呴儴閿欒 + */ + public static final int ERROR = 500; + + /** + * 鎺ュ彛鏈疄鐜� + */ + public static final int NOT_IMPLEMENTED = 501; +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/constant/UserConstants.java b/ruoyi/src/main/java/com/ruoyi/common/constant/UserConstants.java new file mode 100644 index 0000000..4448fa4 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/constant/UserConstants.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.constant; + +/** + * 鐢ㄦ埛甯搁噺淇℃伅 + * + * @author ruoyi + */ +public class UserConstants +{ + /** + * 骞冲彴鍐呯郴缁熺敤鎴风殑鍞竴鏍囧織 + */ + public static final String SYS_USER = "SYS_USER"; + + /** 姝e父鐘舵�� */ + public static final String NORMAL = "0"; + + /** 寮傚父鐘舵�� */ + public static final String EXCEPTION = "1"; + + /** 鐢ㄦ埛灏佺鐘舵�� */ + public static final String USER_BLOCKED = "1"; + + /** 瑙掕壊灏佺鐘舵�� */ + public static final String ROLE_BLOCKED = "1"; + + /** 閮ㄩ棬姝e父鐘舵�� */ + public static final String DEPT_NORMAL = "0"; + + /** 瀛楀吀姝e父鐘舵�� */ + public static final String DICT_NORMAL = "0"; + + /** 鏄惁涓虹郴缁熼粯璁わ紙鏄級 */ + public static final String YES = "Y"; + + /** 鏍¢獙杩斿洖缁撴灉鐮� */ + public final static String UNIQUE = "0"; + public final static String NOT_UNIQUE = "1"; +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/lang/UUID.java b/ruoyi/src/main/java/com/ruoyi/common/core/lang/UUID.java new file mode 100644 index 0000000..3adf3df --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/core/lang/UUID.java @@ -0,0 +1,481 @@ +package com.ruoyi.common.core.lang; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import com.ruoyi.common.exception.UtilException; + +/** + * 鎻愪緵閫氱敤鍞竴璇嗗埆鐮侊紙universally unique identifier锛夛紙UUID锛夊疄鐜� + * + * @author ruoyi + */ +public final class UUID implements java.io.Serializable, Comparable<UUID> +{ + private static final long serialVersionUID = -1185015143654744140L; + + /** + * SecureRandom 鐨勫崟渚� + * + */ + private static class Holder + { + static final SecureRandom numberGenerator = getSecureRandom(); + } + + /** 姝UID鐨勬渶楂�64鏈夋晥浣� */ + private final long mostSigBits; + + /** 姝UID鐨勬渶浣�64鏈夋晥浣� */ + private final long leastSigBits; + + /** + * 绉佹湁鏋勯�� + * + * @param data 鏁版嵁 + */ + private UUID(byte[] data) + { + long msb = 0; + long lsb = 0; + assert data.length == 16 : "data must be 16 bytes in length"; + for (int i = 0; i < 8; i++) + { + msb = (msb << 8) | (data[i] & 0xff); + } + for (int i = 8; i < 16; i++) + { + lsb = (lsb << 8) | (data[i] & 0xff); + } + this.mostSigBits = msb; + this.leastSigBits = lsb; + } + + /** + * 浣跨敤鎸囧畾鐨勬暟鎹瀯閫犳柊鐨� UUID銆� + * + * @param mostSigBits 鐢ㄤ簬 {@code UUID} 鐨勬渶楂樻湁鏁� 64 浣� + * @param leastSigBits 鐢ㄤ簬 {@code UUID} 鐨勬渶浣庢湁鏁� 64 浣� + */ + public UUID(long mostSigBits, long leastSigBits) + { + this.mostSigBits = mostSigBits; + this.leastSigBits = leastSigBits; + } + + /** + * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘�� 浣跨敤鍔犲瘑鐨勬湰鍦扮嚎绋嬩吉闅忔満鏁扮敓鎴愬櫒鐢熸垚璇� UUID銆� + * + * @return 闅忔満鐢熸垚鐨� {@code UUID} + */ + public static UUID fastUUID() + { + return randomUUID(false); + } + + /** + * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘�� 浣跨敤鍔犲瘑鐨勫己浼殢鏈烘暟鐢熸垚鍣ㄧ敓鎴愯 UUID銆� + * + * @return 闅忔満鐢熸垚鐨� {@code UUID} + */ + public static UUID randomUUID() + { + return randomUUID(true); + } + + /** + * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘�� 浣跨敤鍔犲瘑鐨勫己浼殢鏈烘暟鐢熸垚鍣ㄧ敓鎴愯 UUID銆� + * + * @param isSecure 鏄惁浣跨敤{@link SecureRandom}濡傛灉鏄彲浠ヨ幏寰楁洿瀹夊叏鐨勯殢鏈虹爜锛屽惁鍒欏彲浠ュ緱鍒版洿濂界殑鎬ц兘 + * @return 闅忔満鐢熸垚鐨� {@code UUID} + */ + public static UUID randomUUID(boolean isSecure) + { + final Random ng = isSecure ? Holder.numberGenerator : getRandom(); + + byte[] randomBytes = new byte[16]; + ng.nextBytes(randomBytes); + randomBytes[6] &= 0x0f; /* clear version */ + randomBytes[6] |= 0x40; /* set to version 4 */ + randomBytes[8] &= 0x3f; /* clear variant */ + randomBytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(randomBytes); + } + + /** + * 鏍规嵁鎸囧畾鐨勫瓧鑺傛暟缁勮幏鍙栫被鍨� 3锛堝熀浜庡悕绉扮殑锛塙UID 鐨勯潤鎬佸伐鍘傘�� + * + * @param name 鐢ㄤ簬鏋勯�� UUID 鐨勫瓧鑺傛暟缁勩�� + * + * @return 鏍规嵁鎸囧畾鏁扮粍鐢熸垚鐨� {@code UUID} + */ + public static UUID nameUUIDFromBytes(byte[] name) + { + MessageDigest md; + try + { + md = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InternalError("MD5 not supported"); + } + byte[] md5Bytes = md.digest(name); + md5Bytes[6] &= 0x0f; /* clear version */ + md5Bytes[6] |= 0x30; /* set to version 3 */ + md5Bytes[8] &= 0x3f; /* clear variant */ + md5Bytes[8] |= 0x80; /* set to IETF variant */ + return new UUID(md5Bytes); + } + + /** + * 鏍规嵁 {@link #toString()} 鏂规硶涓弿杩扮殑瀛楃涓叉爣鍑嗚〃绀哄舰寮忓垱寤簕@code UUID}銆� + * + * @param name 鎸囧畾 {@code UUID} 瀛楃涓� + * @return 鍏锋湁鎸囧畾鍊肩殑 {@code UUID} + * @throws IllegalArgumentException 濡傛灉 name 涓� {@link #toString} 涓弿杩扮殑瀛楃涓茶〃绀哄舰寮忎笉绗︽姏鍑烘寮傚父 + * + */ + public static UUID fromString(String name) + { + String[] components = name.split("-"); + if (components.length != 5) + { + throw new IllegalArgumentException("Invalid UUID string: " + name); + } + for (int i = 0; i < 5; i++) + { + components[i] = "0x" + components[i]; + } + + long mostSigBits = Long.decode(components[0]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits <<= 16; + mostSigBits |= Long.decode(components[2]).longValue(); + + long leastSigBits = Long.decode(components[3]).longValue(); + leastSigBits <<= 48; + leastSigBits |= Long.decode(components[4]).longValue(); + + return new UUID(mostSigBits, leastSigBits); + } + + /** + * 杩斿洖姝� UUID 鐨� 128 浣嶅�间腑鐨勬渶浣庢湁鏁� 64 浣嶃�� + * + * @return 姝� UUID 鐨� 128 浣嶅�间腑鐨勬渶浣庢湁鏁� 64 浣嶃�� + */ + public long getLeastSignificantBits() + { + return leastSigBits; + } + + /** + * 杩斿洖姝� UUID 鐨� 128 浣嶅�间腑鐨勬渶楂樻湁鏁� 64 浣嶃�� + * + * @return 姝� UUID 鐨� 128 浣嶅�间腑鏈�楂樻湁鏁� 64 浣嶃�� + */ + public long getMostSignificantBits() + { + return mostSigBits; + } + + /** + * 涓庢 {@code UUID} 鐩稿叧鑱旂殑鐗堟湰鍙�. 鐗堟湰鍙锋弿杩版 {@code UUID} 鏄浣曠敓鎴愮殑銆� + * <p> + * 鐗堟湰鍙峰叿鏈変互涓嬪惈鎰�: + * <ul> + * <li>1 鍩轰簬鏃堕棿鐨� UUID + * <li>2 DCE 瀹夊叏 UUID + * <li>3 鍩轰簬鍚嶇О鐨� UUID + * <li>4 闅忔満鐢熸垚鐨� UUID + * </ul> + * + * @return 姝� {@code UUID} 鐨勭増鏈彿 + */ + public int version() + { + // Version is bits masked by 0x000000000000F000 in MS long + return (int) ((mostSigBits >> 12) & 0x0f); + } + + /** + * 涓庢 {@code UUID} 鐩稿叧鑱旂殑鍙樹綋鍙枫�傚彉浣撳彿鎻忚堪 {@code UUID} 鐨勫竷灞�銆� + * <p> + * 鍙樹綋鍙峰叿鏈変互涓嬪惈鎰忥細 + * <ul> + * <li>0 涓� NCS 鍚戝悗鍏煎淇濈暀 + * <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF RFC 4122</a>(Leach-Salz), 鐢ㄤ簬姝ょ被 + * <li>6 淇濈暀锛屽井杞悜鍚庡吋瀹� + * <li>7 淇濈暀渚涗互鍚庡畾涔変娇鐢� + * </ul> + * + * @return 姝� {@code UUID} 鐩稿叧鑱旂殑鍙樹綋鍙� + */ + public int variant() + { + // This field is composed of a varying number of bits. + // 0 - - Reserved for NCS backward compatibility + // 1 0 - The IETF aka Leach-Salz variant (used by this class) + // 1 1 0 Reserved, Microsoft backward compatibility + // 1 1 1 Reserved for future definition. + return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); + } + + /** + * 涓庢 UUID 鐩稿叧鑱旂殑鏃堕棿鎴冲�笺�� + * + * <p> + * 60 浣嶇殑鏃堕棿鎴冲�兼牴鎹 {@code UUID} 鐨� time_low銆乼ime_mid 鍜� time_hi 瀛楁鏋勯�犮��<br> + * 鎵�寰楀埌鐨勬椂闂存埑浠� 100 姣井绉掍负鍗曚綅锛屼粠 UTC锛堥�氱敤鍗忚皟鏃堕棿锛� 1582 骞� 10 鏈� 15 鏃ラ浂鏃跺紑濮嬨�� + * + * <p> + * 鏃堕棿鎴冲�间粎鍦ㄥ湪鍩轰簬鏃堕棿鐨� UUID锛堝叾 version 绫诲瀷涓� 1锛変腑鎵嶆湁鎰忎箟銆�<br> + * 濡傛灉姝� {@code UUID} 涓嶆槸鍩轰簬鏃堕棿鐨� UUID锛屽垯姝ゆ柟娉曟姏鍑� UnsupportedOperationException銆� + * + * @throws UnsupportedOperationException 濡傛灉姝� {@code UUID} 涓嶆槸 version 涓� 1 鐨� UUID銆� + */ + public long timestamp() throws UnsupportedOperationException + { + checkTimeBase(); + return (mostSigBits & 0x0FFFL) << 48// + | ((mostSigBits >> 16) & 0x0FFFFL) << 32// + | mostSigBits >>> 32; + } + + /** + * 涓庢 UUID 鐩稿叧鑱旂殑鏃堕挓搴忓垪鍊笺�� + * + * <p> + * 14 浣嶇殑鏃堕挓搴忓垪鍊兼牴鎹 UUID 鐨� clock_seq 瀛楁鏋勯�犮�俢lock_seq 瀛楁鐢ㄤ簬淇濊瘉鍦ㄥ熀浜庢椂闂寸殑 UUID 涓殑鏃堕棿鍞竴鎬с�� + * <p> + * {@code clockSequence} 鍊间粎鍦ㄥ熀浜庢椂闂寸殑 UUID锛堝叾 version 绫诲瀷涓� 1锛変腑鎵嶆湁鎰忎箟銆� 濡傛灉姝� UUID 涓嶆槸鍩轰簬鏃堕棿鐨� UUID锛屽垯姝ゆ柟娉曟姏鍑� + * UnsupportedOperationException銆� + * + * @return 姝� {@code UUID} 鐨勬椂閽熷簭鍒� + * + * @throws UnsupportedOperationException 濡傛灉姝� UUID 鐨� version 涓嶄负 1 + */ + public int clockSequence() throws UnsupportedOperationException + { + checkTimeBase(); + return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); + } + + /** + * 涓庢 UUID 鐩稿叧鐨勮妭鐐瑰�笺�� + * + * <p> + * 48 浣嶇殑鑺傜偣鍊兼牴鎹 UUID 鐨� node 瀛楁鏋勯�犮�傛瀛楁鏃ㄥ湪鐢ㄤ簬淇濆瓨鏈哄櫒鐨� IEEE 802 鍦板潃锛岃鍦板潃鐢ㄤ簬鐢熸垚姝� UUID 浠ヤ繚璇佺┖闂村敮涓�鎬с�� + * <p> + * 鑺傜偣鍊间粎鍦ㄥ熀浜庢椂闂寸殑 UUID锛堝叾 version 绫诲瀷涓� 1锛変腑鎵嶆湁鎰忎箟銆�<br> + * 濡傛灉姝� UUID 涓嶆槸鍩轰簬鏃堕棿鐨� UUID锛屽垯姝ゆ柟娉曟姏鍑� UnsupportedOperationException銆� + * + * @return 姝� {@code UUID} 鐨勮妭鐐瑰�� + * + * @throws UnsupportedOperationException 濡傛灉姝� UUID 鐨� version 涓嶄负 1 + */ + public long node() throws UnsupportedOperationException + { + checkTimeBase(); + return leastSigBits & 0x0000FFFFFFFFFFFFL; + } + + /** + * 杩斿洖姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡銆� + * + * <p> + * UUID 鐨勫瓧绗︿覆琛ㄧず褰㈠紡鐢辨 BNF 鎻忚堪锛� + * + * <pre> + * {@code + * UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node> + * time_low = 4*<hexOctet> + * time_mid = 2*<hexOctet> + * time_high_and_version = 2*<hexOctet> + * variant_and_sequence = 2*<hexOctet> + * node = 6*<hexOctet> + * hexOctet = <hexDigit><hexDigit> + * hexDigit = [0-9a-fA-F] + * } + * </pre> + * + * </blockquote> + * + * @return 姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡 + * @see #toString(boolean) + */ + @Override + public String toString() + { + return toString(false); + } + + /** + * 杩斿洖姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡銆� + * + * <p> + * UUID 鐨勫瓧绗︿覆琛ㄧず褰㈠紡鐢辨 BNF 鎻忚堪锛� + * + * <pre> + * {@code + * UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node> + * time_low = 4*<hexOctet> + * time_mid = 2*<hexOctet> + * time_high_and_version = 2*<hexOctet> + * variant_and_sequence = 2*<hexOctet> + * node = 6*<hexOctet> + * hexOctet = <hexDigit><hexDigit> + * hexDigit = [0-9a-fA-F] + * } + * </pre> + * + * </blockquote> + * + * @param isSimple 鏄惁绠�鍗曟ā寮忥紝绠�鍗曟ā寮忎负涓嶅甫'-'鐨刄UID瀛楃涓� + * @return 姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡 + */ + public String toString(boolean isSimple) + { + final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); + // time_low + builder.append(digits(mostSigBits >> 32, 8)); + if (false == isSimple) + { + builder.append('-'); + } + // time_mid + builder.append(digits(mostSigBits >> 16, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // time_high_and_version + builder.append(digits(mostSigBits, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // variant_and_sequence + builder.append(digits(leastSigBits >> 48, 4)); + if (false == isSimple) + { + builder.append('-'); + } + // node + builder.append(digits(leastSigBits, 12)); + + return builder.toString(); + } + + /** + * 杩斿洖姝� UUID 鐨勫搱甯岀爜銆� + * + * @return UUID 鐨勫搱甯岀爜鍊笺�� + */ + public int hashCode() + { + long hilo = mostSigBits ^ leastSigBits; + return ((int) (hilo >> 32)) ^ (int) hilo; + } + + /** + * 灏嗘瀵硅薄涓庢寚瀹氬璞℃瘮杈冦�� + * <p> + * 褰撲笖浠呭綋鍙傛暟涓嶄负 {@code null}銆佽�屾槸涓�涓� UUID 瀵硅薄銆佸叿鏈変笌姝� UUID 鐩稿悓鐨� varriant銆佸寘鍚浉鍚岀殑鍊硷紙姣忎竴浣嶅潎鐩稿悓锛夋椂锛岀粨鏋滄墠涓� {@code true}銆� + * + * @param obj 瑕佷笌涔嬫瘮杈冪殑瀵硅薄 + * + * @return 濡傛灉瀵硅薄鐩稿悓锛屽垯杩斿洖 {@code true}锛涘惁鍒欒繑鍥� {@code false} + */ + public boolean equals(Object obj) + { + if ((null == obj) || (obj.getClass() != UUID.class)) + { + return false; + } + UUID id = (UUID) obj; + return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); + } + + // Comparison Operations + + /** + * 灏嗘 UUID 涓庢寚瀹氱殑 UUID 姣旇緝銆� + * + * <p> + * 濡傛灉涓や釜 UUID 涓嶅悓锛屼笖绗竴涓� UUID 鐨勬渶楂樻湁鏁堝瓧娈靛ぇ浜庣浜屼釜 UUID 鐨勫搴斿瓧娈碉紝鍒欑涓�涓� UUID 澶т簬绗簩涓� UUID銆� + * + * @param val 涓庢 UUID 姣旇緝鐨� UUID + * + * @return 鍦ㄦ UUID 灏忎簬銆佺瓑浜庢垨澶т簬 val 鏃讹紝鍒嗗埆杩斿洖 -1銆�0 鎴� 1銆� + * + */ + public int compareTo(UUID val) + { + // The ordering is intentionally set up so that the UUIDs + // can simply be numerically compared as two numbers + return (this.mostSigBits < val.mostSigBits ? -1 : // + (this.mostSigBits > val.mostSigBits ? 1 : // + (this.leastSigBits < val.leastSigBits ? -1 : // + (this.leastSigBits > val.leastSigBits ? 1 : // + 0)))); + } + + // ------------------------------------------------------------------------------------------------------------------- + // Private method start + /** + * 杩斿洖鎸囧畾鏁板瓧瀵瑰簲鐨刪ex鍊� + * + * @param val 鍊� + * @param digits 浣� + * @return 鍊� + */ + private static String digits(long val, int digits) + { + long hi = 1L << (digits * 4); + return Long.toHexString(hi | (val & (hi - 1))).substring(1); + } + + /** + * 妫�鏌ユ槸鍚︿负time-based鐗堟湰UUID + */ + private void checkTimeBase() + { + if (version() != 1) + { + throw new UnsupportedOperationException("Not a time-based UUID"); + } + } + + /** + * 鑾峰彇{@link SecureRandom}锛岀被鎻愪緵鍔犲瘑鐨勫己闅忔満鏁扮敓鎴愬櫒 (RNG) + * + * @return {@link SecureRandom} + */ + public static SecureRandom getSecureRandom() + { + try + { + return SecureRandom.getInstance("SHA1PRNG"); + } + catch (NoSuchAlgorithmException e) + { + throw new UtilException(e); + } + } + + /** + * 鑾峰彇闅忔満鏁扮敓鎴愬櫒瀵硅薄<br> + * ThreadLocalRandom鏄疛DK 7涔嬪悗鎻愪緵骞跺彂浜х敓闅忔満鏁帮紝鑳藉瑙e喅澶氫釜绾跨▼鍙戠敓鐨勭珵浜変簤澶恒�� + * + * @return {@link ThreadLocalRandom} + */ + public static ThreadLocalRandom getRandom() + { + return ThreadLocalRandom.current(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/text/CharsetKit.java b/ruoyi/src/main/java/com/ruoyi/common/core/text/CharsetKit.java new file mode 100644 index 0000000..77b1a79 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/core/text/CharsetKit.java @@ -0,0 +1,86 @@ +package com.ruoyi.common.core.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.ruoyi.common.utils.StringUtils; + +/** + * 瀛楃闆嗗伐鍏风被 + * + * @author ruoyi + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 杞崲涓篊harset瀵硅薄 + * + * @param charset 瀛楃闆嗭紝涓虹┖鍒欒繑鍥為粯璁ゅ瓧绗﹂泦 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 杞崲瀛楃涓茬殑瀛楃闆嗙紪鐮� + * + * @param source 瀛楃涓� + * @param srcCharset 婧愬瓧绗﹂泦锛岄粯璁SO-8859-1 + * @param destCharset 鐩爣瀛楃闆嗭紝榛樿UTF-8 + * @return 杞崲鍚庣殑瀛楃闆� + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 杞崲瀛楃涓茬殑瀛楃闆嗙紪鐮� + * + * @param source 瀛楃涓� + * @param srcCharset 婧愬瓧绗﹂泦锛岄粯璁SO-8859-1 + * @param destCharset 鐩爣瀛楃闆嗭紝榛樿UTF-8 + * @return 杞崲鍚庣殑瀛楃闆� + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + srcCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 绯荤粺瀛楃闆嗙紪鐮� + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/text/Convert.java b/ruoyi/src/main/java/com/ruoyi/common/core/text/Convert.java new file mode 100644 index 0000000..b17dfdd --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/core/text/Convert.java @@ -0,0 +1,999 @@ +package com.ruoyi.common.core.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.ruoyi.common.utils.StringUtils; + +/** + * 绫诲瀷杞崲鍣� + * + * @author ruoyi + */ +public class Convert +{ + /** + * 杞崲涓哄瓧绗︿覆<br> + * 濡傛灉缁欏畾鐨勫�间负null锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 杞崲涓哄瓧绗︿覆<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 杞崲涓哄瓧绗�<br> + * 濡傛灉缁欏畾鐨勫�间负null锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 杞崲涓哄瓧绗�<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 杞崲涓篵yte<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篵yte<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 杞崲涓篠hort<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篠hort<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 杞崲涓篘umber<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篘umber<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 杞崲涓篿nt<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篿nt<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 杞崲涓篒nteger鏁扮粍<br> + * + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 杞崲涓篖ong鏁扮粍<br> + * + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 杞崲涓篒nteger鏁扮粍<br> + * + * @param split 鍒嗛殧绗� + * @param split 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 杞崲涓篖ong鏁扮粍<br> + * + * @param split 鍒嗛殧绗� + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 杞崲涓篠tring鏁扮粍<br> + * + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 杞崲涓篠tring鏁扮粍<br> + * + * @param split 鍒嗛殧绗� + * @param split 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 杞崲涓簂ong<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 鏀寔绉戝璁℃暟娉� + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓簂ong<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 杞崲涓篸ouble<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 鏀寔绉戝璁℃暟娉� + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篸ouble<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 杞崲涓篎loat<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篎loat<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 杞崲涓篵oolean<br> + * String鏀寔鐨勫�间负锛歵rue銆乫alse銆亂es銆乷k銆乶o锛�1,0 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + return true; + case "false": + return false; + case "yes": + return true; + case "ok": + return true; + case "no": + return false; + case "1": + return true; + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 杞崲涓篵oolean<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 杞崲涓篍num瀵硅薄<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * + * @param clazz Enum鐨凜lass + * @param value 鍊� + * @param defaultValue 榛樿鍊� + * @return Enum + */ + public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篍num瀵硅薄<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * + * @param clazz Enum鐨凜lass + * @param value 鍊� + * @return Enum + */ + public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 杞崲涓築igInteger<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓築igInteger<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 杞崲涓築igDecimal<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return new BigDecimal((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓築igDecimal<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 灏嗗璞¤浆涓哄瓧绗︿覆<br> + * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁� 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶 + * + * @param obj 瀵硅薄 + * @return 瀛楃涓� + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 灏嗗璞¤浆涓哄瓧绗︿覆<br> + * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁� 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶 + * + * @param obj 瀵硅薄 + * @param charsetName 瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 灏嗗璞¤浆涓哄瓧绗︿覆<br> + * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁� 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶 + * + * @param obj 瀵硅薄 + * @param charset 瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[] || obj instanceof Byte[]) + { + return str((Byte[]) obj, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 灏哹yte鏁扮粍杞负瀛楃涓� + * + * @param bytes byte鏁扮粍 + * @param charset 瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 瑙g爜瀛楄妭鐮� + * + * @param data 瀛楃涓� + * @param charset 瀛楃闆嗭紝濡傛灉姝ゅ瓧娈典负绌猴紝鍒欒В鐮佺殑缁撴灉鍙栧喅浜庡钩鍙� + * @return 瑙g爜鍚庣殑瀛楃涓� + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 灏嗙紪鐮佺殑byteBuffer鏁版嵁杞崲涓哄瓧绗︿覆 + * + * @param data 鏁版嵁 + * @param charset 瀛楃闆嗭紝濡傛灉涓虹┖浣跨敤褰撳墠绯荤粺瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 灏嗙紪鐮佺殑byteBuffer鏁版嵁杞崲涓哄瓧绗︿覆 + * + * @param data 鏁版嵁 + * @param charset 瀛楃闆嗭紝濡傛灉涓虹┖浣跨敤褰撳墠绯荤粺瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 鍏ㄨ鍗婅杞崲 + /** + * 鍗婅杞叏瑙� + * + * @param input String. + * @return 鍏ㄨ瀛楃涓�. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 鍗婅杞叏瑙� + * + * @param input String + * @param notConvertSet 涓嶆浛鎹㈢殑瀛楃闆嗗悎 + * @return 鍏ㄨ瀛楃涓�. + */ + public static String toSBC(String input, Set<Character> notConvertSet) + { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 璺宠繃涓嶆浛鎹㈢殑瀛楃 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 鍏ㄨ杞崐瑙� + * + * @param input String. + * @return 鍗婅瀛楃涓� + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 鏇挎崲鍏ㄨ涓哄崐瑙� + * + * @param text 鏂囨湰 + * @param notConvertSet 涓嶆浛鎹㈢殑瀛楃闆嗗悎 + * @return 鏇挎崲鍚庣殑瀛楃 + */ + public static String toDBC(String text, Set<Character> notConvertSet) + { + char c[] = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 璺宠繃涓嶆浛鎹㈢殑瀛楃 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + + return returnString; + } + + /** + * 鏁板瓧閲戦澶у啓杞崲 鍏堝啓涓畬鏁寸殑鐒跺悗灏嗗闆舵嬀鏇挎崲鎴愰浂 + * + * @param n 鏁板瓧 + * @return 涓枃澶у啓鏁板瓧 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "瑙�", "鍒�" }; + String[] digit = { "闆�", "澹�", "璐�", "鍙�", "鑲�", "浼�", "闄�", "鏌�", "鎹�", "鐜�" }; + String[][] unit = { { "鍏�", "涓�", "浜�" }, { "", "鎷�", "浣�", "浠�" } }; + + String head = n < 0 ? "璐�" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(闆�.)+", ""); + } + if (s.length() < 1) + { + s = "鏁�"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(闆�.)*闆�$", "").replaceAll("^$", "闆�") + unit[0][i] + s; + } + return head + s.replaceAll("(闆�.)*闆跺厓", "鍏�").replaceFirst("(闆�.)+", "").replaceAll("(闆�.)+", "闆�").replaceAll("^鏁�$", "闆跺厓鏁�"); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/core/text/StrFormatter.java b/ruoyi/src/main/java/com/ruoyi/common/core/text/StrFormatter.java new file mode 100644 index 0000000..c78ac77 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/core/text/StrFormatter.java @@ -0,0 +1,92 @@ +package com.ruoyi.common.core.text; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 瀛楃涓叉牸寮忓寲 + * + * @author ruoyi + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 鏍煎紡鍖栧瓧绗︿覆<br> + * 姝ゆ柟娉曞彧鏄畝鍗曞皢鍗犱綅绗� {} 鎸夌収椤哄簭鏇挎崲涓哄弬鏁�<br> + * 濡傛灉鎯宠緭鍑� {} 浣跨敤 \\杞箟 { 鍗冲彲锛屽鏋滄兂杈撳嚭 {} 涔嬪墠鐨� \ 浣跨敤鍙岃浆涔夌 \\\\ 鍗冲彲<br> + * 渚嬶細<br> + * 閫氬父浣跨敤锛歠ormat("this is {} for {}", "a", "b") -> this is a for b<br> + * 杞箟{}锛� format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> + * 杞箟\锛� format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> + * + * @param strPattern 瀛楃涓叉ā鏉� + * @param argArray 鍙傛暟鍒楄〃 + * @return 缁撴灉 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 鍒濆鍖栧畾涔夊ソ鐨勯暱搴︿互鑾峰緱鏇村ソ鐨勬�ц兘 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 鍗犱綅绗︽墍鍦ㄤ綅缃� + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 瀛楃涓叉ā鏉垮墿浣欓儴鍒嗕笉鍐嶅寘鍚崰浣嶇锛屽姞鍏ュ墿浣欓儴鍒嗗悗杩斿洖缁撴灉 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 杞箟绗︿箣鍓嶈繕鏈変竴涓浆涔夌锛屽崰浣嶇渚濇棫鏈夋晥 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 鍗犱綅绗﹁杞箟 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 姝e父鍗犱綅绗� + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 鍔犲叆鏈�鍚庝竴涓崰浣嶇鍚庢墍鏈夌殑瀛楃 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/enums/HttpMethod.java b/ruoyi/src/main/java/com/ruoyi/common/enums/HttpMethod.java new file mode 100644 index 0000000..be6f739 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/enums/HttpMethod.java @@ -0,0 +1,36 @@ +package com.ruoyi.common.enums; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.lang.Nullable; + +/** + * 璇锋眰鏂瑰紡 + * + * @author ruoyi + */ +public enum HttpMethod +{ + GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; + + private static final Map<String, HttpMethod> mappings = new HashMap<>(16); + + static + { + for (HttpMethod httpMethod : values()) + { + mappings.put(httpMethod.name(), httpMethod); + } + } + + @Nullable + public static HttpMethod resolve(@Nullable String method) + { + return (method != null ? mappings.get(method) : null); + } + + public boolean matches(String method) + { + return (this == resolve(method)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/enums/UserStatus.java b/ruoyi/src/main/java/com/ruoyi/common/enums/UserStatus.java new file mode 100644 index 0000000..d7ff44a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/enums/UserStatus.java @@ -0,0 +1,30 @@ +package com.ruoyi.common.enums; + +/** + * 鐢ㄦ埛鐘舵�� + * + * @author ruoyi + */ +public enum UserStatus +{ + OK("0", "姝e父"), DISABLE("1", "鍋滅敤"), DELETED("2", "鍒犻櫎"); + + private final String code; + private final String info; + + UserStatus(String code, String info) + { + this.code = code; + this.info = info; + } + + public String getCode() + { + return code; + } + + public String getInfo() + { + return info; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/BaseException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/BaseException.java new file mode 100644 index 0000000..92d6ae2 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/BaseException.java @@ -0,0 +1,97 @@ +package com.ruoyi.common.exception; + +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.StringUtils; + +/** + * 鍩虹寮傚父 + * + * @author ruoyi + */ +public class BaseException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 鎵�灞炴ā鍧� + */ + private String module; + + /** + * 閿欒鐮� + */ + private String code; + + /** + * 閿欒鐮佸搴旂殑鍙傛暟 + */ + private Object[] args; + + /** + * 閿欒娑堟伅 + */ + private String defaultMessage; + + public BaseException(String module, String code, Object[] args, String defaultMessage) + { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = defaultMessage; + } + + public BaseException(String module, String code, Object[] args) + { + this(module, code, args, null); + } + + public BaseException(String module, String defaultMessage) + { + this(module, null, null, defaultMessage); + } + + public BaseException(String code, Object[] args) + { + this(null, code, args, null); + } + + public BaseException(String defaultMessage) + { + this(null, null, null, defaultMessage); + } + + @Override + public String getMessage() + { + String message = null; + if (!StringUtils.isEmpty(code)) + { + message = MessageUtils.message(code, args); + } + if (message == null) + { + message = defaultMessage; + } + return message; + } + + public String getModule() + { + return module; + } + + public String getCode() + { + return code; + } + + public Object[] getArgs() + { + return args; + } + + public String getDefaultMessage() + { + return defaultMessage; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/CustomException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/CustomException.java new file mode 100644 index 0000000..d96c7ba --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/CustomException.java @@ -0,0 +1,43 @@ +package com.ruoyi.common.exception; + +/** + * 鑷畾涔夊紓甯� + * + * @author ruoyi + */ +public class CustomException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + private Integer code; + + private String message; + + public CustomException(String message) + { + this.message = message; + } + + public CustomException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public CustomException(String message, Throwable e) + { + super(message, e); + this.message = message; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/DemoModeException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/DemoModeException.java new file mode 100644 index 0000000..f6ad2ab --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/DemoModeException.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.exception; + +/** + * 婕旂ず妯″紡寮傚父 + * + * @author ruoyi + */ +public class DemoModeException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public DemoModeException() + { + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/UtilException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/UtilException.java new file mode 100644 index 0000000..980fa46 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.exception; + +/** + * 宸ュ叿绫诲紓甯� + * + * @author ruoyi + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileException.java new file mode 100644 index 0000000..75d6dbf --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileException.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.exception.file; + +import com.ruoyi.common.exception.BaseException; + +/** + * 鏂囦欢淇℃伅寮傚父绫� + * + * @author ruoyi + */ +public class FileException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public FileException(String code, Object[] args) + { + super("file", code, args, null); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java new file mode 100644 index 0000000..70e0ec9 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileNameLengthLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.file; + +/** + * 鏂囦欢鍚嶇О瓒呴暱闄愬埗寮傚父绫� + * + * @author ruoyi + */ +public class FileNameLengthLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileNameLengthLimitExceededException(int defaultFileNameLength) + { + super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java new file mode 100644 index 0000000..ec6ab05 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/file/FileSizeLimitExceededException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.file; + +/** + * 鏂囦欢鍚嶅ぇ灏忛檺鍒跺紓甯哥被 + * + * @author ruoyi + */ +public class FileSizeLimitExceededException extends FileException +{ + private static final long serialVersionUID = 1L; + + public FileSizeLimitExceededException(long defaultMaxSize) + { + super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java new file mode 100644 index 0000000..8f63a79 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java @@ -0,0 +1,71 @@ +package com.ruoyi.common.exception.file; + +import java.util.Arrays; +import org.apache.commons.fileupload.FileUploadException; + +/** + * 鏂囦欢涓婁紶 璇紓甯哥被 + * + * @author ruoyi + */ +public class InvalidExtensionException extends FileUploadException +{ + private static final long serialVersionUID = 1L; + + private String[] allowedExtension; + private String extension; + private String filename; + + public InvalidExtensionException(String[] allowedExtension, String extension, String filename) + { + super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); + this.allowedExtension = allowedExtension; + this.extension = extension; + this.filename = filename; + } + + public String[] getAllowedExtension() + { + return allowedExtension; + } + + public String getExtension() + { + return extension; + } + + public String getFilename() + { + return filename; + } + + public static class InvalidImageExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidFlashExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } + + public static class InvalidMediaExtensionException extends InvalidExtensionException + { + private static final long serialVersionUID = 1L; + + public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) + { + super(allowedExtension, extension, filename); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java new file mode 100644 index 0000000..389dbc7 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 楠岃瘉鐮侀敊璇紓甯哥被 + * + * @author ruoyi + */ +public class CaptchaException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaException() + { + super("user.jcaptcha.error", null); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java new file mode 100644 index 0000000..85f9486 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/user/CaptchaExpireException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 楠岃瘉鐮佸け鏁堝紓甯哥被 + * + * @author ruoyi + */ +public class CaptchaExpireException extends UserException +{ + private static final long serialVersionUID = 1L; + + public CaptchaExpireException() + { + super("user.jcaptcha.expire", null); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/user/UserException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/user/UserException.java new file mode 100644 index 0000000..aa015f8 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/user/UserException.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.exception.user; + +import com.ruoyi.common.exception.BaseException; + +/** + * 鐢ㄦ埛淇℃伅寮傚父绫� + * + * @author ruoyi + */ +public class UserException extends BaseException +{ + private static final long serialVersionUID = 1L; + + public UserException(String code, Object[] args) + { + super("user", code, args, null); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java b/ruoyi/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java new file mode 100644 index 0000000..a7f3e5f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/exception/user/UserPasswordNotMatchException.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.exception.user; + +/** + * 鐢ㄦ埛瀵嗙爜涓嶆纭垨涓嶇鍚堣鑼冨紓甯哥被 + * + * @author ruoyi + */ +public class UserPasswordNotMatchException extends UserException +{ + private static final long serialVersionUID = 1L; + + public UserPasswordNotMatchException() + { + super("user.password.not.match", null); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/Arith.java b/ruoyi/src/main/java/com/ruoyi/common/utils/Arith.java new file mode 100644 index 0000000..48a650e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/Arith.java @@ -0,0 +1,114 @@ +package com.ruoyi.common.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 绮剧‘鐨勬诞鐐规暟杩愮畻 + * + * @author ruoyi + */ +public class Arith +{ + + /** 榛樿闄ゆ硶杩愮畻绮惧害 */ + private static final int DEF_DIV_SCALE = 10; + + /** 杩欎釜绫讳笉鑳藉疄渚嬪寲 */ + private Arith() + { + } + + /** + * 鎻愪緵绮剧‘鐨勫姞娉曡繍绠椼�� + * @param v1 琚姞鏁� + * @param v2 鍔犳暟 + * @return 涓や釜鍙傛暟鐨勫拰 + */ + public static double add(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.add(b2).doubleValue(); + } + + /** + * 鎻愪緵绮剧‘鐨勫噺娉曡繍绠椼�� + * @param v1 琚噺鏁� + * @param v2 鍑忔暟 + * @return 涓や釜鍙傛暟鐨勫樊 + */ + public static double sub(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.subtract(b2).doubleValue(); + } + + /** + * 鎻愪緵绮剧‘鐨勪箻娉曡繍绠椼�� + * @param v1 琚箻鏁� + * @param v2 涔樻暟 + * @return 涓や釜鍙傛暟鐨勭Н + */ + public static double mul(double v1, double v2) + { + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + return b1.multiply(b2).doubleValue(); + } + + /** + * 鎻愪緵锛堢浉瀵癸級绮剧‘鐨勯櫎娉曡繍绠楋紝褰撳彂鐢熼櫎涓嶅敖鐨勬儏鍐垫椂锛岀簿纭埌 + * 灏忔暟鐐逛互鍚�10浣嶏紝浠ュ悗鐨勬暟瀛楀洓鑸嶄簲鍏ャ�� + * @param v1 琚櫎鏁� + * @param v2 闄ゆ暟 + * @return 涓や釜鍙傛暟鐨勫晢 + */ + public static double div(double v1, double v2) + { + return div(v1, v2, DEF_DIV_SCALE); + } + + /** + * 鎻愪緵锛堢浉瀵癸級绮剧‘鐨勯櫎娉曡繍绠椼�傚綋鍙戠敓闄や笉灏界殑鎯呭喌鏃讹紝鐢眘cale鍙傛暟鎸� + * 瀹氱簿搴︼紝浠ュ悗鐨勬暟瀛楀洓鑸嶄簲鍏ャ�� + * @param v1 琚櫎鏁� + * @param v2 闄ゆ暟 + * @param scale 琛ㄧず琛ㄧず闇�瑕佺簿纭埌灏忔暟鐐逛互鍚庡嚑浣嶃�� + * @return 涓や釜鍙傛暟鐨勫晢 + */ + public static double div(double v1, double v2, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b1 = new BigDecimal(Double.toString(v1)); + BigDecimal b2 = new BigDecimal(Double.toString(v2)); + if (b1.compareTo(BigDecimal.ZERO) == 0) + { + return BigDecimal.ZERO.doubleValue(); + } + return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue(); + } + + /** + * 鎻愪緵绮剧‘鐨勫皬鏁颁綅鍥涜垗浜斿叆澶勭悊銆� + * @param v 闇�瑕佸洓鑸嶄簲鍏ョ殑鏁板瓧 + * @param scale 灏忔暟鐐瑰悗淇濈暀鍑犱綅 + * @return 鍥涜垗浜斿叆鍚庣殑缁撴灉 + */ + public static double round(double v, int scale) + { + if (scale < 0) + { + throw new IllegalArgumentException( + "The scale must be a positive integer or zero"); + } + BigDecimal b = new BigDecimal(Double.toString(v)); + BigDecimal one = new BigDecimal("1"); + return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/DateUtils.java new file mode 100644 index 0000000..536cb3c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -0,0 +1,155 @@ +package com.ruoyi.common.utils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.apache.commons.lang3.time.DateFormatUtils; + +/** + * 鏃堕棿宸ュ叿绫� + * + * @author ruoyi + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 鑾峰彇褰撳墠Date鍨嬫棩鏈� + * + * @return Date() 褰撳墠鏃ユ湡 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd + * + * @return String + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 鏃ユ湡璺緞 鍗冲勾/鏈�/鏃� 濡�20180808 + */ + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂� + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 璁$畻涓や釜鏃堕棿宸� + */ + public static String getDatePoor(Date endDate, Date nowDate) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 鑾峰緱涓や釜鏃堕棿鐨勬绉掓椂闂村樊寮� + long diff = endDate.getTime() - nowDate.getTime(); + // 璁$畻宸灏戝ぉ + long day = diff / nd; + // 璁$畻宸灏戝皬鏃� + long hour = diff % nd / nh; + // 璁$畻宸灏戝垎閽� + long min = diff % nd % nh / nm; + // 璁$畻宸灏戠//杈撳嚭缁撴灉 + // long sec = diff % nd % nh % nm / ns; + return day + "澶�" + hour + "灏忔椂" + min + "鍒嗛挓"; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/IdUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/IdUtils.java new file mode 100644 index 0000000..a21313f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/IdUtils.java @@ -0,0 +1,51 @@ +package com.ruoyi.common.utils; + +import com.ruoyi.common.core.lang.UUID; + +/** + * ID鐢熸垚鍣ㄥ伐鍏风被 + * + * @author ruoyi + */ +public class IdUtils +{ + /** + * 鑾峰彇闅忔満UUID + * + * @return 闅忔満UUID + */ + public static String randomUUID() + { + return UUID.randomUUID().toString(); + } + + /** + * 绠�鍖栫殑UUID锛屽幓鎺変簡妯嚎 + * + * @return 绠�鍖栫殑UUID锛屽幓鎺変簡妯嚎 + */ + public static String simpleUUID() + { + return UUID.randomUUID().toString(true); + } + + /** + * 鑾峰彇闅忔満UUID锛屼娇鐢ㄦ�ц兘鏇村ソ鐨凾hreadLocalRandom鐢熸垚UUID + * + * @return 闅忔満UUID + */ + public static String fastUUID() + { + return UUID.fastUUID().toString(); + } + + /** + * 绠�鍖栫殑UUID锛屽幓鎺変簡妯嚎锛屼娇鐢ㄦ�ц兘鏇村ソ鐨凾hreadLocalRandom鐢熸垚UUID + * + * @return 绠�鍖栫殑UUID锛屽幓鎺変簡妯嚎 + */ + public static String fastSimpleUUID() + { + return UUID.fastUUID().toString(true); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/LogUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/LogUtils.java new file mode 100644 index 0000000..0de30c6 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/LogUtils.java @@ -0,0 +1,18 @@ +package com.ruoyi.common.utils; + +/** + * 澶勭悊骞惰褰曟棩蹇楁枃浠� + * + * @author ruoyi + */ +public class LogUtils +{ + public static String getBlock(Object msg) + { + if (msg == null) + { + msg = ""; + } + return "[" + msg.toString() + "]"; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/MessageUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/MessageUtils.java new file mode 100644 index 0000000..7dac75a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/MessageUtils.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.utils; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import com.ruoyi.common.utils.spring.SpringUtils; + +/** + * 鑾峰彇i18n璧勬簮鏂囦欢 + * + * @author ruoyi + */ +public class MessageUtils +{ + /** + * 鏍规嵁娑堟伅閿拰鍙傛暟 鑾峰彇娑堟伅 濮旀墭缁檚pring messageSource + * + * @param code 娑堟伅閿� + * @param args 鍙傛暟 + * @return 鑾峰彇鍥介檯鍖栫炕璇戝�� + */ + public static String message(String code, Object... args) + { + MessageSource messageSource = SpringUtils.getBean(MessageSource.class); + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/SecurityUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/SecurityUtils.java new file mode 100644 index 0000000..1c86837 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/SecurityUtils.java @@ -0,0 +1,90 @@ +package com.ruoyi.common.utils; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.framework.security.LoginUser; + +/** + * 瀹夊叏鏈嶅姟宸ュ叿绫� + * + * @author ruoyi + */ +public class SecurityUtils +{ + /** + * 鑾峰彇鐢ㄦ埛璐︽埛 + **/ + public static String getUsername() + { + try + { + return getLoginUser().getUsername(); + } + catch (Exception e) + { + throw new CustomException("鑾峰彇鐢ㄦ埛璐︽埛寮傚父", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 鑾峰彇鐢ㄦ埛 + **/ + public static LoginUser getLoginUser() + { + try + { + return (LoginUser) getAuthentication().getPrincipal(); + } + catch (Exception e) + { + throw new CustomException("鑾峰彇鐢ㄦ埛淇℃伅寮傚父", HttpStatus.UNAUTHORIZED); + } + } + + /** + * 鑾峰彇Authentication + */ + public static Authentication getAuthentication() + { + return SecurityContextHolder.getContext().getAuthentication(); + } + + /** + * 鐢熸垚BCryptPasswordEncoder瀵嗙爜 + * + * @param password 瀵嗙爜 + * @return 鍔犲瘑瀛楃涓� + */ + public static String encryptPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.encode(password); + } + + /** + * 鍒ゆ柇瀵嗙爜鏄惁鐩稿悓 + * + * @param rawPassword 鐪熷疄瀵嗙爜 + * @param encodedPassword 鍔犲瘑鍚庡瓧绗� + * @return 缁撴灉 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.matches(rawPassword, encodedPassword); + } + + /** + * 鏄惁涓虹鐞嗗憳 + * + * @param userId 鐢ㄦ埛ID + * @return 缁撴灉 + */ + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/ServletUtils.java new file mode 100644 index 0000000..ab9ebcf --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/ServletUtils.java @@ -0,0 +1,136 @@ +package com.ruoyi.common.utils; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import com.ruoyi.common.core.text.Convert; + +/** + * 瀹㈡埛绔伐鍏风被 + * + * @author ruoyi + */ +public class ServletUtils +{ + /** + * 鑾峰彇String鍙傛暟 + */ + public static String getParameter(String name) + { + return getRequest().getParameter(name); + } + + /** + * 鑾峰彇String鍙傛暟 + */ + public static String getParameter(String name, String defaultValue) + { + return Convert.toStr(getRequest().getParameter(name), defaultValue); + } + + /** + * 鑾峰彇Integer鍙傛暟 + */ + public static Integer getParameterToInt(String name) + { + return Convert.toInt(getRequest().getParameter(name)); + } + + /** + * 鑾峰彇Integer鍙傛暟 + */ + public static Integer getParameterToInt(String name, Integer defaultValue) + { + return Convert.toInt(getRequest().getParameter(name), defaultValue); + } + + /** + * 鑾峰彇request + */ + public static HttpServletRequest getRequest() + { + return getRequestAttributes().getRequest(); + } + + /** + * 鑾峰彇response + */ + public static HttpServletResponse getResponse() + { + return getRequestAttributes().getResponse(); + } + + /** + * 鑾峰彇session + */ + public static HttpSession getSession() + { + return getRequest().getSession(); + } + + public static ServletRequestAttributes getRequestAttributes() + { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return (ServletRequestAttributes) attributes; + } + + /** + * 灏嗗瓧绗︿覆娓叉煋鍒板鎴风 + * + * @param response 娓叉煋瀵硅薄 + * @param string 寰呮覆鏌撶殑瀛楃涓� + * @return null + */ + public static String renderString(HttpServletResponse response, String string) + { + try + { + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } + catch (IOException e) + { + e.printStackTrace(); + } + return null; + } + + /** + * 鏄惁鏄疉jax寮傛璇锋眰 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.indexOf("application/json") != -1) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")) + { + return true; + } + return false; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/StringUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/StringUtils.java new file mode 100644 index 0000000..e32daa5 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/StringUtils.java @@ -0,0 +1,453 @@ +package com.ruoyi.common.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import com.ruoyi.common.core.text.StrFormatter; + +/** + * 瀛楃涓插伐鍏风被 + * + * @author ruoyi + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils +{ + /** 绌哄瓧绗︿覆 */ + private static final String NULLSTR = ""; + + /** 涓嬪垝绾� */ + private static final char SEPARATOR = '_'; + + /** + * 鑾峰彇鍙傛暟涓嶄负绌哄�� + * + * @param value defaultValue 瑕佸垽鏂殑value + * @return value 杩斿洖鍊� + */ + public static <T> T nvl(T value, T defaultValue) + { + return value != null ? value : defaultValue; + } + + /** + * * 鍒ゆ柇涓�涓狢ollection鏄惁涓虹┖锛� 鍖呭惈List锛孲et锛孮ueue + * + * @param coll 瑕佸垽鏂殑Collection + * @return true锛氫负绌� false锛氶潪绌� + */ + public static boolean isEmpty(Collection<?> coll) + { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 鍒ゆ柇涓�涓狢ollection鏄惁闈炵┖锛屽寘鍚獿ist锛孲et锛孮ueue + * + * @param coll 瑕佸垽鏂殑Collection + * @return true锛氶潪绌� false锛氱┖ + */ + public static boolean isNotEmpty(Collection<?> coll) + { + return !isEmpty(coll); + } + + /** + * * 鍒ゆ柇涓�涓璞℃暟缁勬槸鍚︿负绌� + * + * @param objects 瑕佸垽鏂殑瀵硅薄鏁扮粍 + ** @return true锛氫负绌� false锛氶潪绌� + */ + public static boolean isEmpty(Object[] objects) + { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 鍒ゆ柇涓�涓璞℃暟缁勬槸鍚﹂潪绌� + * + * @param objects 瑕佸垽鏂殑瀵硅薄鏁扮粍 + * @return true锛氶潪绌� false锛氱┖ + */ + public static boolean isNotEmpty(Object[] objects) + { + return !isEmpty(objects); + } + + /** + * * 鍒ゆ柇涓�涓狹ap鏄惁涓虹┖ + * + * @param map 瑕佸垽鏂殑Map + * @return true锛氫负绌� false锛氶潪绌� + */ + public static boolean isEmpty(Map<?, ?> map) + { + return isNull(map) || map.isEmpty(); + } + + /** + * * 鍒ゆ柇涓�涓狹ap鏄惁涓虹┖ + * + * @param map 瑕佸垽鏂殑Map + * @return true锛氶潪绌� false锛氱┖ + */ + public static boolean isNotEmpty(Map<?, ?> map) + { + return !isEmpty(map); + } + + /** + * * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁涓虹┖涓� + * + * @param str String + * @return true锛氫负绌� false锛氶潪绌� + */ + public static boolean isEmpty(String str) + { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 鍒ゆ柇涓�涓瓧绗︿覆鏄惁涓洪潪绌轰覆 + * + * @param str String + * @return true锛氶潪绌轰覆 false锛氱┖涓� + */ + public static boolean isNotEmpty(String str) + { + return !isEmpty(str); + } + + /** + * * 鍒ゆ柇涓�涓璞℃槸鍚︿负绌� + * + * @param object Object + * @return true锛氫负绌� false锛氶潪绌� + */ + public static boolean isNull(Object object) + { + return object == null; + } + + /** + * * 鍒ゆ柇涓�涓璞℃槸鍚﹂潪绌� + * + * @param object Object + * @return true锛氶潪绌� false锛氱┖ + */ + public static boolean isNotNull(Object object) + { + return !isNull(object); + } + + /** + * * 鍒ゆ柇涓�涓璞℃槸鍚︽槸鏁扮粍绫诲瀷锛圝ava鍩烘湰鍨嬪埆鐨勬暟缁勶級 + * + * @param object 瀵硅薄 + * @return true锛氭槸鏁扮粍 false锛氫笉鏄暟缁� + */ + public static boolean isArray(Object object) + { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 鍘荤┖鏍� + */ + public static String trim(String str) + { + return (str == null ? "" : str.trim()); + } + + /** + * 鎴彇瀛楃涓� + * + * @param str 瀛楃涓� + * @param start 寮�濮� + * @return 缁撴灉 + */ + public static String substring(final String str, int start) + { + if (str == null) + { + return NULLSTR; + } + + if (start < 0) + { + start = str.length() + start; + } + + if (start < 0) + { + start = 0; + } + if (start > str.length()) + { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 鎴彇瀛楃涓� + * + * @param str 瀛楃涓� + * @param start 寮�濮� + * @param end 缁撴潫 + * @return 缁撴灉 + */ + public static String substring(final String str, int start, int end) + { + if (str == null) + { + return NULLSTR; + } + + if (end < 0) + { + end = str.length() + end; + } + if (start < 0) + { + start = str.length() + start; + } + + if (end > str.length()) + { + end = str.length(); + } + + if (start > end) + { + return NULLSTR; + } + + if (start < 0) + { + start = 0; + } + if (end < 0) + { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 鏍煎紡鍖栨枃鏈�, {} 琛ㄧず鍗犱綅绗�<br> + * 姝ゆ柟娉曞彧鏄畝鍗曞皢鍗犱綅绗� {} 鎸夌収椤哄簭鏇挎崲涓哄弬鏁�<br> + * 濡傛灉鎯宠緭鍑� {} 浣跨敤 \\杞箟 { 鍗冲彲锛屽鏋滄兂杈撳嚭 {} 涔嬪墠鐨� \ 浣跨敤鍙岃浆涔夌 \\\\ 鍗冲彲<br> + * 渚嬶細<br> + * 閫氬父浣跨敤锛歠ormat("this is {} for {}", "a", "b") -> this is a for b<br> + * 杞箟{}锛� format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> + * 杞箟\锛� format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> + * + * @param template 鏂囨湰妯℃澘锛岃鏇挎崲鐨勯儴鍒嗙敤 {} 琛ㄧず + * @param params 鍙傛暟鍊� + * @return 鏍煎紡鍖栧悗鐨勬枃鏈� + */ + public static String format(String template, Object... params) + { + if (isEmpty(params) || isEmpty(template)) + { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 瀛楃涓茶浆set + * + * @param str 瀛楃涓� + * @param sep 鍒嗛殧绗� + * @return set闆嗗悎 + */ + public static final Set<String> str2Set(String str, String sep) + { + return new HashSet<String>(str2List(str, sep, true, false)); + } + + /** + * 瀛楃涓茶浆list + * + * @param str 瀛楃涓� + * @param sep 鍒嗛殧绗� + * @param filterBlank 杩囨护绾┖鐧� + * @param trim 鍘绘帀棣栧熬绌虹櫧 + * @return list闆嗗悎 + */ + public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) + { + List<String> list = new ArrayList<String>(); + if (StringUtils.isEmpty(str)) + { + return list; + } + + // 杩囨护绌虹櫧瀛楃涓� + if (filterBlank && StringUtils.isBlank(str)) + { + return list; + } + String[] split = str.split(sep); + for (String string : split) + { + if (filterBlank && StringUtils.isBlank(string)) + { + continue; + } + if (trim) + { + string = string.trim(); + } + list.add(string); + } + + return list; + } + + /** + * 涓嬪垝绾胯浆椹煎嘲鍛藉悕 + */ + public static String toUnderScoreCase(String str) + { + if (str == null) + { + return null; + } + StringBuilder sb = new StringBuilder(); + // 鍓嶇疆瀛楃鏄惁澶у啓 + boolean preCharIsUpperCase = true; + // 褰撳墠瀛楃鏄惁澶у啓 + boolean curreCharIsUpperCase = true; + // 涓嬩竴瀛楃鏄惁澶у啓 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) + { + char c = str.charAt(i); + if (i > 0) + { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } + else + { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) + { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) + { + sb.append(SEPARATOR); + } + else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) + { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 鏄惁鍖呭惈瀛楃涓� + * + * @param str 楠岃瘉瀛楃涓� + * @param strs 瀛楃涓茬粍 + * @return 鍖呭惈杩斿洖true + */ + public static boolean inStringIgnoreCase(String str, String... strs) + { + if (str != null && strs != null) + { + for (String s : strs) + { + if (str.equalsIgnoreCase(trim(s))) + { + return true; + } + } + } + return false; + } + + /** + * 灏嗕笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆杞崲涓洪┘宄板紡銆傚鏋滆浆鎹㈠墠鐨勪笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆涓虹┖锛屽垯杩斿洖绌哄瓧绗︿覆銆� 渚嬪锛欻ELLO_WORLD->HelloWorld + * + * @param name 杞崲鍓嶇殑涓嬪垝绾垮ぇ鍐欐柟寮忓懡鍚嶇殑瀛楃涓� + * @return 杞崲鍚庣殑椹煎嘲寮忓懡鍚嶇殑瀛楃涓� + */ + public static String convertToCamelCase(String name) + { + StringBuilder result = new StringBuilder(); + // 蹇�熸鏌� + if (name == null || name.isEmpty()) + { + // 娌″繀瑕佽浆鎹� + return ""; + } + else if (!name.contains("_")) + { + // 涓嶅惈涓嬪垝绾匡紝浠呭皢棣栧瓧姣嶅ぇ鍐� + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 鐢ㄤ笅鍒掔嚎灏嗗師濮嬪瓧绗︿覆鍒嗗壊 + String[] camels = name.split("_"); + for (String camel : camels) + { + // 璺宠繃鍘熷瀛楃涓蹭腑寮�澶淬�佺粨灏剧殑涓嬫崲绾挎垨鍙岄噸涓嬪垝绾� + if (camel.isEmpty()) + { + continue; + } + // 棣栧瓧姣嶅ぇ鍐� + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 椹煎嘲寮忓懡鍚嶆硶 渚嬪锛歶ser_name->userName + */ + public static String toCamelCase(String s) + { + if (s == null) + { + return null; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + + if (c == SEPARATOR) + { + upperCase = true; + } + else if (upperCase) + { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } + else + { + sb.append(c); + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/Threads.java b/ruoyi/src/main/java/com/ruoyi/common/utils/Threads.java new file mode 100644 index 0000000..1934195 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/Threads.java @@ -0,0 +1,99 @@ +package com.ruoyi.common.utils; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 绾跨▼鐩稿叧宸ュ叿绫�. + * + * @author ruoyi + */ +public class Threads +{ + private static final Logger logger = LoggerFactory.getLogger(Threads.class); + + /** + * sleep绛夊緟,鍗曚綅涓烘绉� + */ + public static void sleep(long milliseconds) + { + try + { + Thread.sleep(milliseconds); + } + catch (InterruptedException e) + { + return; + } + } + + /** + * 鍋滄绾跨▼姹� + * 鍏堜娇鐢╯hutdown, 鍋滄鎺ユ敹鏂颁换鍔″苟灏濊瘯瀹屾垚鎵�鏈夊凡瀛樺湪浠诲姟. + * 濡傛灉瓒呮椂, 鍒欒皟鐢╯hutdownNow, 鍙栨秷鍦╳orkQueue涓璓ending鐨勪换鍔�,骞朵腑鏂墍鏈夐樆濉炲嚱鏁�. + * 濡傛灉浠嶄汉瓒呮檪锛屽墖寮峰埗閫�鍑�. + * 鍙﹀鍦╯hutdown鏃剁嚎绋嬫湰韬璋冪敤涓柇鍋氫簡澶勭悊. + */ + public static void shutdownAndAwaitTermination(ExecutorService pool) + { + if (pool != null && !pool.isShutdown()) + { + pool.shutdown(); + try + { + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + pool.shutdownNow(); + if (!pool.awaitTermination(120, TimeUnit.SECONDS)) + { + logger.info("Pool did not terminate"); + } + } + } + catch (InterruptedException ie) + { + pool.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + } + + /** + * 鎵撳嵃绾跨▼寮傚父淇℃伅 + */ + public static void printException(Runnable r, Throwable t) + { + if (t == null && r instanceof Future<?>) + { + try + { + Future<?> future = (Future<?>) r; + if (future.isDone()) + { + future.get(); + } + } + catch (CancellationException ce) + { + t = ce; + } + catch (ExecutionException ee) + { + t = ee.getCause(); + } + catch (InterruptedException ie) + { + Thread.currentThread().interrupt(); + } + } + if (t != null) + { + logger.error(t.getMessage(), t); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/VerifyCodeUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/VerifyCodeUtils.java new file mode 100644 index 0000000..912bc04 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/VerifyCodeUtils.java @@ -0,0 +1,226 @@ +package com.ruoyi.common.utils; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Random; +import javax.imageio.ImageIO; + +/** + * 楠岃瘉鐮佸伐鍏风被 + * + * @author ruoyi + */ +public class VerifyCodeUtils +{ + // 浣跨敤鍒癆lgerian瀛椾綋锛岀郴缁熼噷娌℃湁鐨勮瘽闇�瑕佸畨瑁呭瓧浣擄紝瀛椾綋鍙樉绀哄ぇ鍐欙紝鍘绘帀浜�1,0,i,o鍑犱釜瀹规槗娣锋穯鐨勫瓧绗� + public static final String VERIFY_CODES = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ"; + + private static Random random = new SecureRandom(); + + /** + * 浣跨敤绯荤粺榛樿瀛楃婧愮敓鎴愰獙璇佺爜 + * + * @param verifySize 楠岃瘉鐮侀暱搴� + * @return + */ + public static String generateVerifyCode(int verifySize) + { + return generateVerifyCode(verifySize, VERIFY_CODES); + } + + /** + * 浣跨敤鎸囧畾婧愮敓鎴愰獙璇佺爜 + * + * @param verifySize 楠岃瘉鐮侀暱搴� + * @param sources 楠岃瘉鐮佸瓧绗︽簮 + * @return + */ + public static String generateVerifyCode(int verifySize, String sources) + { + if (sources == null || sources.length() == 0) + { + sources = VERIFY_CODES; + } + int codesLen = sources.length(); + Random rand = new Random(System.currentTimeMillis()); + StringBuilder verifyCode = new StringBuilder(verifySize); + for (int i = 0; i < verifySize; i++) + { + verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1))); + } + return verifyCode.toString(); + } + + /** + * 杈撳嚭鎸囧畾楠岃瘉鐮佸浘鐗囨祦 + * + * @param w + * @param h + * @param os + * @param code + * @throws IOException + */ + public static void outputImage(int w, int h, OutputStream os, String code) throws IOException + { + int verifySize = code.length(); + BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Random rand = new Random(); + Graphics2D g2 = image.createGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Color[] colors = new Color[5]; + Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, + Color.ORANGE, Color.PINK, Color.YELLOW }; + float[] fractions = new float[colors.length]; + for (int i = 0; i < colors.length; i++) + { + colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; + fractions[i] = rand.nextFloat(); + } + Arrays.sort(fractions); + + g2.setColor(Color.GRAY);// 璁剧疆杈规鑹� + g2.fillRect(0, 0, w, h); + + Color c = getRandColor(200, 250); + g2.setColor(c);// 璁剧疆鑳屾櫙鑹� + g2.fillRect(0, 2, w, h - 4); + + // 缁樺埗骞叉壈绾� + Random random = new Random(); + g2.setColor(getRandColor(160, 200));// 璁剧疆绾挎潯鐨勯鑹� + for (int i = 0; i < 20; i++) + { + int x = random.nextInt(w - 1); + int y = random.nextInt(h - 1); + int xl = random.nextInt(6) + 1; + int yl = random.nextInt(12) + 1; + g2.drawLine(x, y, x + xl + 40, y + yl + 20); + } + + // 娣诲姞鍣偣 + float yawpRate = 0.05f;// 鍣0鐜� + int area = (int) (yawpRate * w * h); + for (int i = 0; i < area; i++) + { + int x = random.nextInt(w); + int y = random.nextInt(h); + int rgb = getRandomIntColor(); + image.setRGB(x, y, rgb); + } + + shear(g2, w, h, c);// 浣垮浘鐗囨壄鏇� + + g2.setColor(getRandColor(100, 160)); + int fontSize = h - 4; + Font font = new Font("Algerian", Font.ITALIC, fontSize); + g2.setFont(font); + char[] chars = code.toCharArray(); + for (int i = 0; i < verifySize; i++) + { + AffineTransform affine = new AffineTransform(); + affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), + (w / verifySize) * i + fontSize / 2, h / 2); + g2.setTransform(affine); + g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10); + } + + g2.dispose(); + ImageIO.write(image, "jpg", os); + } + + private static Color getRandColor(int fc, int bc) + { + if (fc > 255) + fc = 255; + if (bc > 255) + bc = 255; + int r = fc + random.nextInt(bc - fc); + int g = fc + random.nextInt(bc - fc); + int b = fc + random.nextInt(bc - fc); + return new Color(r, g, b); + } + + private static int getRandomIntColor() + { + int[] rgb = getRandomRgb(); + int color = 0; + for (int c : rgb) + { + color = color << 8; + color = color | c; + } + return color; + } + + private static int[] getRandomRgb() + { + int[] rgb = new int[3]; + for (int i = 0; i < 3; i++) + { + rgb[i] = random.nextInt(255); + } + return rgb; + } + + private static void shear(Graphics g, int w1, int h1, Color color) + { + shearX(g, w1, h1, color); + shearY(g, w1, h1, color); + } + + private static void shearX(Graphics g, int w1, int h1, Color color) + { + + int period = random.nextInt(2); + + boolean borderGap = true; + int frames = 1; + int phase = random.nextInt(2); + + for (int i = 0; i < h1; i++) + { + double d = (double) (period >> 1) + * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); + g.copyArea(0, i, w1, 1, (int) d, 0); + if (borderGap) + { + g.setColor(color); + g.drawLine((int) d, i, 0, i); + g.drawLine((int) d + w1, i, w1, i); + } + } + + } + + private static void shearY(Graphics g, int w1, int h1, Color color) + { + + int period = random.nextInt(40) + 10; // 50; + + boolean borderGap = true; + int frames = 20; + int phase = 7; + for (int i = 0; i < w1; i++) + { + double d = (double) (period >> 1) + * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); + g.copyArea(i, 0, 1, h1, 0, (int) d); + if (borderGap) + { + g.setColor(color); + g.drawLine(i, (int) d, i, 0); + g.drawLine(i, (int) d + h1, i, h1); + } + + } + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java new file mode 100644 index 0000000..821ddfe --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java @@ -0,0 +1,243 @@ +package com.ruoyi.common.utils.file; + +import java.io.File; +import java.io.IOException; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException; +import com.ruoyi.common.exception.file.FileSizeLimitExceededException; +import com.ruoyi.common.exception.file.InvalidExtensionException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.security.Md5Utils; +import com.ruoyi.framework.config.RuoYiConfig; + +/** + * 鏂囦欢涓婁紶宸ュ叿绫� + * + * @author ruoyi + */ +public class FileUploadUtils +{ + /** + * 榛樿澶у皬 50M + */ + public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; + + /** + * 榛樿鐨勬枃浠跺悕鏈�澶ч暱搴� 100 + */ + public static final int DEFAULT_FILE_NAME_LENGTH = 100; + + /** + * 榛樿涓婁紶鐨勫湴鍧� + */ + private static String defaultBaseDir = RuoYiConfig.getProfile(); + + private static int counter = 0; + + public static void setDefaultBaseDir(String defaultBaseDir) + { + FileUploadUtils.defaultBaseDir = defaultBaseDir; + } + + public static String getDefaultBaseDir() + { + return defaultBaseDir; + } + + /** + * 浠ラ粯璁ら厤缃繘琛屾枃浠朵笂浼� + * + * @param file 涓婁紶鐨勬枃浠� + * @return 鏂囦欢鍚嶇О + * @throws Exception + */ + public static final String upload(MultipartFile file) throws IOException + { + try + { + return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 鏍规嵁鏂囦欢璺緞涓婁紶 + * + * @param baseDir 鐩稿搴旂敤鐨勫熀鐩綍 + * @param file 涓婁紶鐨勬枃浠� + * @return 鏂囦欢鍚嶇О + * @throws IOException + */ + public static final String upload(String baseDir, MultipartFile file) throws IOException + { + try + { + return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + + /** + * 鏂囦欢涓婁紶 + * + * @param baseDir 鐩稿搴旂敤鐨勫熀鐩綍 + * @param file 涓婁紶鐨勬枃浠� + * @param extension 涓婁紶鏂囦欢绫诲瀷 + * @return 杩斿洖涓婁紶鎴愬姛鐨勬枃浠跺悕 + * @throws FileSizeLimitExceededException 濡傛灉瓒呭嚭鏈�澶уぇ灏� + * @throws FileNameLengthLimitExceededException 鏂囦欢鍚嶅お闀� + * @throws IOException 姣斿璇诲啓鏂囦欢鍑洪敊鏃� + * @throws InvalidExtensionException 鏂囦欢鏍¢獙寮傚父 + */ + public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = file.getOriginalFilename().length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = extractFilename(file); + + File desc = getAbsoluteFile(baseDir, fileName); + file.transferTo(desc); + String pathFileName = getPathFileName(baseDir, fileName); + return pathFileName; + } + + /** + * 缂栫爜鏂囦欢鍚� + */ + public static final String extractFilename(MultipartFile file) + { + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + fileName = DateUtils.datePath() + "/" + encodingFilename(fileName) + "." + extension; + return fileName; + } + + private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + if (!desc.exists()) + { + desc.createNewFile(); + } + return desc; + } + + private static final String getPathFileName(String uploadDir, String fileName) throws IOException + { + int dirLastIndex = RuoYiConfig.getProfile().length() + 1; + String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; + return pathFileName; + } + + /** + * 缂栫爜鏂囦欢鍚� + */ + private static final String encodingFilename(String fileName) + { + fileName = fileName.replace("_", " "); + fileName = Md5Utils.hash(fileName + System.nanoTime() + counter++); + return fileName; + } + + /** + * 鏂囦欢澶у皬鏍¢獙 + * + * @param file 涓婁紶鐨勬枃浠� + * @return + * @throws FileSizeLimitExceededException 濡傛灉瓒呭嚭鏈�澶уぇ灏� + * @throws InvalidExtensionException + */ + public static final void assertAllowed(MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, InvalidExtensionException + { + long size = file.getSize(); + if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) + { + throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); + } + + String fileName = file.getOriginalFilename(); + String extension = getExtension(file); + if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) + { + if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) + { + throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) + { + throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, + fileName); + } + else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) + { + throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, + fileName); + } + else + { + throw new InvalidExtensionException(allowedExtension, extension, fileName); + } + } + + } + + /** + * 鍒ゆ柇MIME绫诲瀷鏄惁鏄厑璁哥殑MIME绫诲瀷 + * + * @param extension + * @param allowedExtension + * @return + */ + public static final boolean isAllowedExtension(String extension, String[] allowedExtension) + { + for (String str : allowedExtension) + { + if (str.equalsIgnoreCase(extension)) + { + return true; + } + } + return false; + } + + /** + * 鑾峰彇鏂囦欢鍚嶇殑鍚庣紑 + * + * @param file 琛ㄥ崟鏂囦欢 + * @return 鍚庣紑鍚� + */ + public static final String getExtension(MultipartFile file) + { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + if (StringUtils.isEmpty(extension)) + { + extension = MimeTypeUtils.getExtension(file.getContentType()); + } + return extension; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java new file mode 100644 index 0000000..04d4703 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/file/FileUtils.java @@ -0,0 +1,142 @@ +package com.ruoyi.common.utils.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import javax.servlet.http.HttpServletRequest; + +/** + * 鏂囦欢澶勭悊宸ュ叿绫� + * + * @author ruoyi + */ +public class FileUtils +{ + public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + + /** + * 杈撳嚭鎸囧畾鏂囦欢鐨刡yte鏁扮粍 + * + * @param filePath 鏂囦欢璺緞 + * @param os 杈撳嚭娴� + * @return + */ + public static void writeBytes(String filePath, OutputStream os) throws IOException + { + FileInputStream fis = null; + try + { + File file = new File(filePath); + if (!file.exists()) + { + throw new FileNotFoundException(filePath); + } + fis = new FileInputStream(file); + byte[] b = new byte[1024]; + int length; + while ((length = fis.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + if (os != null) + { + try + { + os.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (fis != null) + { + try + { + fis.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 鍒犻櫎鏂囦欢 + * + * @param filePath 鏂囦欢 + * @return + */ + public static boolean deleteFile(String filePath) + { + boolean flag = false; + File file = new File(filePath); + // 璺緞涓烘枃浠朵笖涓嶄负绌哄垯杩涜鍒犻櫎 + if (file.isFile() && file.exists()) + { + file.delete(); + flag = true; + } + return flag; + } + + /** + * 鏂囦欢鍚嶇О楠岃瘉 + * + * @param filename 鏂囦欢鍚嶇О + * @return true 姝e父 false 闈炴硶 + */ + public static boolean isValidFilename(String filename) + { + return filename.matches(FILENAME_PATTERN); + } + + /** + * 涓嬭浇鏂囦欢鍚嶉噸鏂扮紪鐮� + * + * @param request 璇锋眰瀵硅薄 + * @param fileName 鏂囦欢鍚� + * @return 缂栫爜鍚庣殑鏂囦欢鍚� + */ + public static String setFileDownloadHeader(HttpServletRequest request, String fileName) + throws UnsupportedEncodingException + { + final String agent = request.getHeader("USER-AGENT"); + String filename = fileName; + if (agent.contains("MSIE")) + { + // IE娴忚鍣� + filename = URLEncoder.encode(filename, "utf-8"); + filename = filename.replace("+", " "); + } + else if (agent.contains("Firefox")) + { + // 鐏嫄娴忚鍣� + filename = new String(fileName.getBytes(), "ISO8859-1"); + } + else if (agent.contains("Chrome")) + { + // google娴忚鍣� + filename = URLEncoder.encode(filename, "utf-8"); + } + else + { + // 鍏跺畠娴忚鍣� + filename = URLEncoder.encode(filename, "utf-8"); + } + return filename; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java new file mode 100644 index 0000000..6984641 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java @@ -0,0 +1,55 @@ +package com.ruoyi.common.utils.file; + +/** + * 濯掍綋绫诲瀷宸ュ叿绫� + * + * @author ruoyi + */ +public class MimeTypeUtils +{ + public static final String IMAGE_PNG = "image/png"; + + public static final String IMAGE_JPG = "image/jpg"; + + public static final String IMAGE_JPEG = "image/jpeg"; + + public static final String IMAGE_BMP = "image/bmp"; + + public static final String IMAGE_GIF = "image/gif"; + + public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; + + public static final String[] FLASH_EXTENSION = { "swf", "flv" }; + + public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", + "asf", "rm", "rmvb" }; + + public static final String[] DEFAULT_ALLOWED_EXTENSION = { + // 鍥剧墖 + "bmp", "gif", "jpg", "jpeg", "png", + // word excel powerpoint + "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", + // 鍘嬬缉鏂囦欢 + "rar", "zip", "gz", "bz2", + // pdf + "pdf" }; + + public static String getExtension(String prefix) + { + switch (prefix) + { + case IMAGE_PNG: + return "png"; + case IMAGE_JPG: + return "jpg"; + case IMAGE_JPEG: + return "jpeg"; + case IMAGE_BMP: + return "bmp"; + case IMAGE_GIF: + return "gif"; + default: + return ""; + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java b/ruoyi/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java new file mode 100644 index 0000000..62b4b18 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java @@ -0,0 +1,152 @@ +package com.ruoyi.common.utils.html; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 杞箟鍜屽弽杞箟宸ュ叿绫� + * + * @author ruoyi + */ +public class EscapeUtil +{ + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static + { + for (int i = 0; i < 64; i++) + { + TEXT[i] = new char[] { (char) i }; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 鍗曞紩鍙� + TEXT['"'] = """.toCharArray(); // 鍗曞紩鍙� + TEXT['&'] = "&".toCharArray(); // &绗� + TEXT['<'] = "<".toCharArray(); // 灏忎簬鍙� + TEXT['>'] = ">".toCharArray(); // 澶т簬鍙� + } + + /** + * 杞箟鏂囨湰涓殑HTML瀛楃涓哄畨鍏ㄧ殑瀛楃 + * + * @param text 琚浆涔夌殑鏂囨湰 + * @return 杞箟鍚庣殑鏂囨湰 + */ + public static String escape(String text) + { + return encode(text); + } + + /** + * 杩樺師琚浆涔夌殑HTML鐗规畩瀛楃 + * + * @param content 鍖呭惈杞箟绗︾殑HTML鍐呭 + * @return 杞崲鍚庣殑瀛楃涓� + */ + public static String unescape(String content) + { + return decode(content); + } + + /** + * 娓呴櫎鎵�鏈塇TML鏍囩锛屼絾鏄笉鍒犻櫎鏍囩鍐呯殑鍐呭 + * + * @param content 鏂囨湰 + * @return 娓呴櫎鏍囩鍚庣殑鏂囨湰 + */ + public static String clean(String content) + { + return new HTMLFilter().filter(content); + } + + /** + * Escape缂栫爜 + * + * @param text 琚紪鐮佺殑鏂囨湰 + * @return 缂栫爜鍚庣殑瀛楃 + */ + private static String encode(String text) + { + int len; + if ((text == null) || ((len = text.length()) == 0)) + { + return StringUtils.EMPTY; + } + StringBuilder buffer = new StringBuilder(len + (len >> 2)); + char c; + for (int i = 0; i < len; i++) + { + c = text.charAt(i); + if (c < 64) + { + buffer.append(TEXT[c]); + } + else + { + buffer.append(c); + } + } + return buffer.toString(); + } + + /** + * Escape瑙g爜 + * + * @param content 琚浆涔夌殑鍐呭 + * @return 瑙g爜鍚庣殑瀛楃涓� + */ + public static String decode(String content) + { + if (StringUtils.isEmpty(content)) + { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) + { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) + { + if (content.charAt(pos + 1) == 'u') + { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } + else + { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } + else + { + if (pos == -1) + { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } + else + { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) + { + String html = "<script>alert(1);</script>"; + System.out.println(EscapeUtil.clean(html)); + System.out.println(EscapeUtil.escape(html)); + System.out.println(EscapeUtil.unescape(html)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java b/ruoyi/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java new file mode 100644 index 0000000..6244cd5 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java @@ -0,0 +1,569 @@ +package com.ruoyi.common.utils.html; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML杩囨护鍣紝鐢ㄤ簬鍘婚櫎XSS婕忔礊闅愭偅銆� + * + * @author ruoyi + */ +public final class HTMLFilter +{ + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("\""); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map<String, List<String>> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map<String, Integer> vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "<img />") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "<b></b>") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + /** + * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>" + * becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() + { + vAllowed = new HashMap<>(); + + final ArrayList<String> a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList<String> img_atts = new ArrayList<>(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList<String> no_atts = new ArrayList<>(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[] { "img" }; + vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" }; + vDisallowed = new String[] {}; + vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp. + vProtocolAtts = new String[] { "src", "href" }; + vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" }; + vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" }; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = true; + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map<String, Object> conf) + { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() + { + vTagCounts.clear(); + } + + // --------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) + { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) + { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + // --------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) + { + reset(); + String s = input; + + s = escapeComments(s); + + s = balanceHTML(s); + + s = checkTags(s); + + s = processRemoveBlanks(s); + + s = validateEntities(s); + + return s; + } + + public boolean isAlwaysMakeTags() + { + return alwaysMakeTags; + } + + public boolean isStripComments() + { + return stripComment; + } + + private String escapeComments(final String s) + { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) + { + final String match = m.group(1); // (.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) + { + if (alwaysMakeTags) + { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } + else + { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) + { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) + { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + final StringBuilder sBuilder = new StringBuilder(buf.toString()); + for (String key : vTagCounts.keySet()) + { + for (int ii = 0; ii < vTagCounts.get(key); ii++) + { + sBuilder.append("</").append(key).append(">"); + } + } + s = sBuilder.toString(); + + return s; + } + + private String processRemoveBlanks(final String s) + { + String result = s; + for (String tag : vRemoveBlanks) + { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) + { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) + { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) + { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) + { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) + { + if (false == inArray(name, vSelfClosingTags)) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return "</" + name + ">"; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) + { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) + { + final StringBuilder params = new StringBuilder(); + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List<String> paramNames = new ArrayList<>(); + final List<String> paramValues = new ArrayList<>(); + while (m2.find()) + { + paramNames.add(m2.group(1)); // ([a-z0-9]+) + paramValues.add(m2.group(3)); // (.*?) + } + while (m3.find()) + { + paramNames.add(m3.group(1)); // ([a-z0-9]+) + paramValues.add(m3.group(3)); // ([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) + { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + + // debug( "paramName='" + paramName + "'" ); + // debug( "paramValue='" + paramValue + "'" ); + // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) + { + if (inArray(paramName, vProtocolAtts)) + { + paramValue = processParamProtocol(paramValue); + } + params.append(' ').append(paramName).append("=\"").append(paramValue).append("\""); + } + } + + if (inArray(name, vSelfClosingTags)) + { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) + { + ending = ""; + } + + if (ending == null || ending.length() < 1) + { + if (vTagCounts.containsKey(name)) + { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } + else + { + vTagCounts.put(name, 1); + } + } + else + { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } + else + { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) + { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) + { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) + { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) + { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1); + if (s.startsWith("#//")) + { + s = "#" + s.substring(3); + } + } + } + + return s; + } + + private String decodeEntities(String s) + { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) + { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) + { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // ([^&;]*) + final String two = m.group(2); // (?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) + { + if (encodeQuotes) + { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) + { + final String one = m.group(1); // (>|^) + final String two = m.group(2); // ([^<]+?) + final String three = m.group(3); // (<|$) + // 涓嶆浛鎹㈠弻寮曞彿涓�"锛岄槻姝son鏍煎紡鏃犳晥 regexReplace(P_QUOTE, """, two) + m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three)); + } + m.appendTail(buf); + return buf.toString(); + } + else + { + return s; + } + } + + private String checkEntity(final String preamble, final String term) + { + + return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; + } + + private boolean isValidEntity(final String entity) + { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) + { + for (String item : array) + { + if (item != null && item.equals(s)) + { + return true; + } + } + return false; + } + + private boolean allowed(final String name) + { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) + { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java new file mode 100644 index 0000000..a027518 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java @@ -0,0 +1,248 @@ +package com.ruoyi.common.utils.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLConnection; +import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 閫氱敤http鍙戦�佹柟娉� + * + * @author ruoyi + */ +public class HttpUtils +{ + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 鍚戞寚瀹� URL 鍙戦�丟ET鏂规硶鐨勮姹� + * + * @param url 鍙戦�佽姹傜殑 URL + * @param param 璇锋眰鍙傛暟锛岃姹傚弬鏁板簲璇ユ槸 name1=value1&name2=value2 鐨勫舰寮忋�� + * @return 鎵�浠h〃杩滅▼璧勬簮鐨勫搷搴旂粨鏋� + */ + public static String sendGet(String url, String param) + { + StringBuilder result = new StringBuilder(); + BufferedReader in = null; + try + { + String urlNameString = url + "?" + param; + log.info("sendGet - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection connection = realUrl.openConnection(); + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + connection.connect(); + in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("璋冪敤HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("璋冪敤HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("璋冪敤HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("璋冪敤HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (in != null) + { + in.close(); + } + } + catch (Exception ex) + { + log.error("璋冪敤in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + /** + * 鍚戞寚瀹� URL 鍙戦�丳OST鏂规硶鐨勮姹� + * + * @param url 鍙戦�佽姹傜殑 URL + * @param param 璇锋眰鍙傛暟锛岃姹傚弬鏁板簲璇ユ槸 name1=value1&name2=value2 鐨勫舰寮忋�� + * @return 鎵�浠h〃杩滅▼璧勬簮鐨勫搷搴旂粨鏋� + */ + public static String sendPost(String url, String param) + { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try + { + String urlNameString = url + "?" + param; + log.info("sendPost - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + out = new PrintWriter(conn.getOutputStream()); + out.print(param); + out.flush(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); + String line; + while ((line = in.readLine()) != null) + { + result.append(line); + } + log.info("recv - {}", result); + } + catch (ConnectException e) + { + log.error("璋冪敤HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("璋冪敤HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("璋冪敤HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("璋冪敤HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + if (in != null) + { + in.close(); + } + } + catch (IOException ex) + { + log.error("璋冪敤in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString(); + } + + public static String sendSSLPost(String url, String param) + { + StringBuilder result = new StringBuilder(); + String urlNameString = url + "?" + param; + try + { + log.info("sendSSLPost - {}", urlNameString); + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); + URL console = new URL(urlNameString); + HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("contentType", "utf-8"); + conn.setDoOutput(true); + conn.setDoInput(true); + + conn.setSSLSocketFactory(sc.getSocketFactory()); + conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); + conn.connect(); + InputStream is = conn.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String ret = ""; + while ((ret = br.readLine()) != null) + { + if (ret != null && !ret.trim().equals("")) + { + result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8")); + } + } + log.info("recv - {}", result); + conn.disconnect(); + br.close(); + } + catch (ConnectException e) + { + log.error("璋冪敤HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); + } + catch (SocketTimeoutException e) + { + log.error("璋冪敤HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } + catch (IOException e) + { + log.error("璋冪敤HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); + } + catch (Exception e) + { + log.error("璋冪敤HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); + } + return result.toString(); + } + + private static class TrustAnyTrustManager implements X509TrustManager + { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + { + } + + @Override + public X509Certificate[] getAcceptedIssuers() + { + return new X509Certificate[] {}; + } + } + + private static class TrustAnyHostnameVerifier implements HostnameVerifier + { + @Override + public boolean verify(String hostname, SSLSession session) + { + return true; + } + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java new file mode 100644 index 0000000..3ee6b80 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java @@ -0,0 +1,41 @@ +package com.ruoyi.common.utils.ip; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.http.HttpUtils; + +/** + * 鑾峰彇鍦板潃绫� + * + * @author ruoyi + */ +public class AddressUtils +{ + private static final Logger log = LoggerFactory.getLogger(AddressUtils.class); + + public static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php"; + + public static String getRealAddressByIP(String ip) + { + String address = "XX XX"; + // 鍐呯綉涓嶆煡璇� + if (IpUtils.internalIp(ip)) + { + return "鍐呯綉IP"; + } + String rspStr = HttpUtils.sendPost(IP_URL, "ip=" + ip); + if (StringUtils.isEmpty(rspStr)) + { + log.error("鑾峰彇鍦扮悊浣嶇疆寮傚父 {}", ip); + return address; + } + JSONObject obj = JSONObject.parseObject(rspStr); + JSONObject data = obj.getObject("data", JSONObject.class); + String region = data.getString("region"); + String city = data.getString("city"); + address = region + " " + city; + return address; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java new file mode 100644 index 0000000..2b9a267 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java @@ -0,0 +1,189 @@ +package com.ruoyi.common.utils.ip; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import javax.servlet.http.HttpServletRequest; +import com.ruoyi.common.utils.StringUtils; + +/** + * 鑾峰彇IP鏂规硶 + * + * @author ruoyi + */ +public class IpUtils +{ + public static String getIpAddr(HttpServletRequest request) + { + if (request == null) + { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; + } + + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + private static boolean internalIp(byte[] addr) + { + if (StringUtils.isNull(addr) || addr.length < 2) + { + return true; + } + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) + { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) + { + return true; + } + case SECTION_5: + switch (b1) + { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 灏咺Pv4鍦板潃杞崲鎴愬瓧鑺� + * + * @param text IPv4鍦板潃 + * @return byte 瀛楄妭 + */ + public static byte[] textToNumericFormatV4(String text) + { + if (text.length() == 0) + { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try + { + long l; + int i; + switch (elements.length) + { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) + return null; + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) + return null; + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) + return null; + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + return null; + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) + return null; + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + return null; + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } + catch (NumberFormatException e) + { + return null; + } + return bytes; + } + + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "鏈煡"; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java new file mode 100644 index 0000000..27652fe --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -0,0 +1,872 @@ +package com.ruoyi.common.utils.poi; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.Type; +import com.ruoyi.framework.aspectj.lang.annotation.Excels; +import com.ruoyi.framework.config.RuoYiConfig; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.reflect.ReflectUtils; + +/** + * Excel鐩稿叧澶勭悊 + * + * @author ruoyi + */ +public class ExcelUtil<T> +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + /** + * Excel sheet鏈�澶ц鏁帮紝榛樿65536 + */ + public static final int sheetSize = 65536; + + /** + * 宸ヤ綔琛ㄥ悕绉� + */ + private String sheetName; + + /** + * 瀵煎嚭绫诲瀷锛圗XPORT:瀵煎嚭鏁版嵁锛汭MPORT锛氬鍏ユā鏉匡級 + */ + private Type type; + + /** + * 宸ヤ綔钖勫璞� + */ + private Workbook wb; + + /** + * 宸ヤ綔琛ㄥ璞� + */ + private Sheet sheet; + + /** + * 鏍峰紡鍒楄〃 + */ + private Map<String, CellStyle> styles; + + /** + * 瀵煎叆瀵煎嚭鏁版嵁鍒楄〃 + */ + private List<T> list; + + /** + * 娉ㄨВ鍒楄〃 + */ + private List<Object[]> fields; + + /** + * 瀹炰綋瀵硅薄 + */ + public Class<T> clazz; + + public ExcelUtil(Class<T> clazz) + { + this.clazz = clazz; + } + + public void init(List<T> list, String sheetName, Type type) + { + if (list == null) + { + list = new ArrayList<T>(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + createExcelField(); + createWorkbook(); + } + + /** + * 瀵筫xcel琛ㄥ崟榛樿绗竴涓储寮曞悕杞崲鎴恖ist + * + * @param is 杈撳叆娴� + * @return 杞崲鍚庨泦鍚� + */ + public List<T> importExcel(InputStream is) throws Exception + { + return importExcel(StringUtils.EMPTY, is); + } + + /** + * 瀵筫xcel琛ㄥ崟鎸囧畾琛ㄦ牸绱㈠紩鍚嶈浆鎹㈡垚list + * + * @param sheetName 琛ㄦ牸绱㈠紩鍚� + * @param is 杈撳叆娴� + * @return 杞崲鍚庨泦鍚� + */ + public List<T> importExcel(String sheetName, InputStream is) throws Exception + { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List<T> list = new ArrayList<T>(); + Sheet sheet = null; + if (StringUtils.isNotEmpty(sheetName)) + { + // 濡傛灉鎸囧畾sheet鍚�,鍒欏彇鎸囧畾sheet涓殑鍐呭. + sheet = wb.getSheet(sheetName); + } + else + { + // 濡傛灉浼犲叆鐨剆heet鍚嶄笉瀛樺湪鍒欓粯璁ゆ寚鍚戠1涓猻heet. + sheet = wb.getSheetAt(0); + } + + if (sheet == null) + { + throw new IOException("鏂囦欢sheet涓嶅瓨鍦�"); + } + + int rows = sheet.getPhysicalNumberOfRows(); + + if (rows > 0) + { + // 瀹氫箟涓�涓猰ap鐢ㄤ簬瀛樻斁excel鍒楃殑搴忓彿鍜宖ield. + Map<String, Integer> cellMap = new HashMap<String, Integer>(); + // 鑾峰彇琛ㄥご + Row heard = sheet.getRow(0); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) + { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell != null)) + { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } + else + { + cellMap.put(null, i); + } + } + // 鏈夋暟鎹椂鎵嶅鐞� 寰楀埌绫荤殑鎵�鏈塮ield. + Field[] allFields = clazz.getDeclaredFields(); + // 瀹氫箟涓�涓猰ap鐢ㄤ簬瀛樻斁鍒楃殑搴忓彿鍜宖ield. + Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>(); + for (int col = 0; col < allFields.length; col++) + { + Field field = allFields[col]; + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + // 璁剧疆绫荤殑绉佹湁瀛楁灞炴�у彲璁块棶. + field.setAccessible(true); + Integer column = cellMap.get(attr.name()); + fieldsMap.put(column, field); + } + } + for (int i = 1; i < rows; i++) + { + // 浠庣2琛屽紑濮嬪彇鏁版嵁,榛樿绗竴琛屾槸琛ㄥご. + Row row = sheet.getRow(i); + T entity = null; + for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet()) + { + Object val = this.getCellValue(row, entry.getKey()); + + // 濡傛灉涓嶅瓨鍦ㄥ疄渚嬪垯鏂板缓. + entity = (entity == null ? clazz.newInstance() : entity); + // 浠巑ap涓緱鍒板搴斿垪鐨刦ield. + Field field = fieldsMap.get(entry.getKey()); + // 鍙栧緱绫诲瀷,骞舵牴鎹璞$被鍨嬭缃��. + Class<?> fieldType = field.getType(); + if (String.class == fieldType) + { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) + { + val = StringUtils.substringBefore(s, ".0"); + } + else + { + val = Convert.toStr(val); + } + } + else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) + { + val = Convert.toInt(val); + } + else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) + { + val = Convert.toLong(val); + } + else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) + { + val = Convert.toDouble(val); + } + else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) + { + val = Convert.toFloat(val); + } + else if (BigDecimal.class == fieldType) + { + val = Convert.toBigDecimal(val); + } + else if (Date.class == fieldType) + { + if (val instanceof String) + { + val = DateUtils.parseDate(val); + } + else if (val instanceof Double) + { + val = DateUtil.getJavaDate((Double) val); + } + } + if (StringUtils.isNotNull(fieldType)) + { + Excel attr = field.getAnnotation(Excel.class); + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) + { + propertyName = field.getName() + "." + attr.targetAttr(); + } + else if (StringUtils.isNotEmpty(attr.readConverterExp())) + { + val = reverseByExp(String.valueOf(val), attr.readConverterExp()); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟 + * + * @param list 瀵煎嚭鏁版嵁闆嗗悎 + * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О + * @return 缁撴灉 + */ + public AjaxResult exportExcel(List<T> list, String sheetName) + { + this.init(list, sheetName, Type.EXPORT); + return exportExcel(); + } + + /** + * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟 + * + * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О + * @return 缁撴灉 + */ + public AjaxResult importTemplateExcel(String sheetName) + { + this.init(null, sheetName, Type.IMPORT); + return exportExcel(); + } + + /** + * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟 + * + * @return 缁撴灉 + */ + public AjaxResult exportExcel() + { + OutputStream out = null; + try + { + // 鍙栧嚭涓�鍏辨湁澶氬皯涓猻heet. + double sheetNo = Math.ceil(list.size() / sheetSize); + for (int index = 0; index <= sheetNo; index++) + { + createSheet(sheetNo, index); + + // 浜х敓涓�琛� + Row row = sheet.createRow(0); + int column = 0; + // 鍐欏叆鍚勪釜瀛楁鐨勫垪澶村悕绉� + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + this.createCell(excel, row, column++); + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + } + } + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return AjaxResult.success(filename); + } + catch (Exception e) + { + log.error("瀵煎嚭Excel寮傚父{}", e.getMessage()); + throw new CustomException("瀵煎嚭Excel澶辫触锛岃鑱旂郴缃戠珯绠$悊鍛橈紒"); + } + finally + { + if (wb != null) + { + try + { + wb.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (out != null) + { + try + { + out.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + + /** + * 濉厖excel鏁版嵁 + * + * @param index 搴忓彿 + * @param row 鍗曞厓鏍艰 + */ + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + for (int i = startNo; i < endNo; i++) + { + row = sheet.createRow(i + 1 - startNo); + // 寰楀埌瀵煎嚭瀵硅薄. + T vo = (T) list.get(i); + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + // 璁剧疆瀹炰綋绫荤鏈夊睘鎬у彲璁块棶 + field.setAccessible(true); + this.addCell(excel, row, vo, field, column++); + } + } + } + + /** + * 鍒涘缓琛ㄦ牸鏍峰紡 + * + * @param wb 宸ヤ綔钖勫璞� + * @return 鏍峰紡鍒楄〃 + */ + private Map<String, CellStyle> createStyles(Workbook wb) + { + // 鍐欏叆鍚勬潯璁板綍,姣忔潯璁板綍瀵瑰簲excel琛ㄤ腑鐨勪竴琛� + Map<String, CellStyle> styles = new HashMap<String, CellStyle>(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(IndexedColors.WHITE.getIndex()); + style.setFont(headerFont); + styles.put("header", style); + + return styles; + } + + /** + * 鍒涘缓鍗曞厓鏍� + */ + public Cell createCell(Excel attr, Row row, int column) + { + // 鍒涘缓鍒� + Cell cell = row.createCell(column); + // 鍐欏叆鍒椾俊鎭� + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get("header")); + return cell; + } + + /** + * 璁剧疆鍗曞厓鏍间俊鎭� + * + * @param value 鍗曞厓鏍煎�� + * @param attr 娉ㄨВ鐩稿叧 + * @param cell 鍗曞厓鏍间俊鎭� + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType()) + { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(Integer.parseInt(value + "")); + } + } + + /** + * 鍒涘缓琛ㄦ牸鏍峰紡 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("娉細") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 璁剧疆鍒楀 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + row.setHeight((short) (attr.height() * 20)); + } + // 濡傛灉璁剧疆浜嗘彁绀轰俊鎭垯榧犳爣鏀句笂鍘绘彁绀�. + if (StringUtils.isNotEmpty(attr.prompt())) + { + // 杩欓噷榛樿璁句簡2-101鍒楁彁绀�. + setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); + } + // 濡傛灉璁剧疆浜哻ombo灞炴�у垯鏈垪鍙兘閫夋嫨涓嶈兘杈撳叆 + if (attr.combo().length > 0) + { + // 杩欓噷榛樿璁句簡2-101鍒楀彧鑳介�夋嫨涓嶈兘杈撳叆. + setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); + } + } + + /** + * 娣诲姞鍗曞厓鏍� + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 璁剧疆琛岄珮 + row.setHeight((short) (attr.height() * 20)); + // 鏍规嵁Excel涓缃儏鍐靛喅瀹氭槸鍚﹀鍑�,鏈変簺鎯呭喌闇�瑕佷繚鎸佷负绌�,甯屾湜鐢ㄦ埛濉啓杩欎竴鍒�. + if (attr.isExport()) + { + // 鍒涘缓cell + cell = row.createCell(column); + cell.setCellStyle(styles.get("data")); + + // 鐢ㄤ簬璇诲彇瀵硅薄涓殑灞炴�� + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) + { + cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) + { + cell.setCellValue(convertByExp(String.valueOf(value), readConverterExp)); + } + else + { + // 璁剧疆鍒楃被鍨� + setCellVo(value, attr, cell); + } + } + } + catch (Exception e) + { + log.error("瀵煎嚭Excel澶辫触{}", e); + } + return cell; + } + + /** + * 璁剧疆 POI XSSFSheet 鍗曞厓鏍兼彁绀� + * + * @param sheet 琛ㄥ崟 + * @param promptTitle 鎻愮ず鏍囬 + * @param promptContent 鎻愮ず鍐呭 + * @param firstRow 寮�濮嬭 + * @param endRow 缁撴潫琛� + * @param firstCol 寮�濮嬪垪 + * @param endCol 缁撴潫鍒� + */ + public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + dataValidation.createPromptBox(promptTitle, promptContent); + dataValidation.setShowPromptBox(true); + sheet.addValidationData(dataValidation); + } + + /** + * 璁剧疆鏌愪簺鍒楃殑鍊煎彧鑳借緭鍏ラ鍒剁殑鏁版嵁,鏄剧ず涓嬫媺妗�. + * + * @param sheet 瑕佽缃殑sheet. + * @param textlist 涓嬫媺妗嗘樉绀虹殑鍐呭 + * @param firstRow 寮�濮嬭 + * @param endRow 缁撴潫琛� + * @param firstCol 寮�濮嬪垪 + * @param endCol 缁撴潫鍒� + * @return 璁剧疆濂界殑sheet. + */ + public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 鍔犺浇涓嬫媺鍒楄〃鍐呭 + DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); + // 璁剧疆鏁版嵁鏈夋晥鎬у姞杞藉湪鍝釜鍗曞厓鏍间笂,鍥涗釜鍙傛暟鍒嗗埆鏄細璧峰琛屻�佺粓姝㈣銆佽捣濮嬪垪銆佺粓姝㈠垪 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 鏁版嵁鏈夋晥鎬у璞� + DataValidation dataValidation = helper.createValidation(constraint, regions); + // 澶勭悊Excel鍏煎鎬ч棶棰� + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + } + + /** + * 瑙f瀽瀵煎嚭鍊� 0=鐢�,1=濂�,2=鏈煡 + * + * @param propertyValue 鍙傛暟鍊� + * @param converterExp 缈昏瘧娉ㄨВ + * @return 瑙f瀽鍚庡�� + * @throws Exception + */ + public static String convertByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 鍙嶅悜瑙f瀽鍊� 鐢�=0,濂�=1,鏈煡=2 + * + * @param propertyValue 鍙傛暟鍊� + * @param converterExp 缈昏瘧娉ㄨВ + * @return 瑙f瀽鍚庡�� + * @throws Exception + */ + public static String reverseByExp(String propertyValue, String converterExp) throws Exception + { + try + { + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + catch (Exception e) + { + throw e; + } + return propertyValue; + } + + /** + * 缂栫爜鏂囦欢鍚� + */ + public String encodingFilename(String filename) + { + filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 鑾峰彇涓嬭浇璺緞 + * + * @param filename 鏂囦欢鍚嶇О + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = RuoYiConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 鑾峰彇bean涓殑灞炴�у�� + * + * @param vo 瀹炰綋瀵硅薄 + * @param field 瀛楁 + * @param excel 娉ㄨВ + * @return 鏈�缁堢殑灞炴�у�� + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.indexOf(".") > -1) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 浠ョ被鐨勫睘鎬х殑get鏂规硶鏂规硶褰㈠紡鑾峰彇鍊� + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (StringUtils.isNotEmpty(name)) + { + Class<?> clazz = o.getClass(); + String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); + Method method = clazz.getMethod(methodName); + o = method.invoke(o); + } + return o; + } + + /** + * 寰楀埌鎵�鏈夊畾涔夊瓧娈� + */ + private void createExcelField() + { + this.fields = new ArrayList<Object[]>(); + List<Field> tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + // 鍗曟敞瑙� + if (field.isAnnotationPresent(Excel.class)) + { + putToField(field, field.getAnnotation(Excel.class)); + } + + // 澶氭敞瑙� + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel excel : excels) + { + putToField(field, excel); + } + } + } + } + + /** + * 鏀惧埌瀛楁闆嗗悎涓� + */ + private void putToField(Field field, Excel attr) + { + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + this.fields.add(new Object[] { field, attr }); + } + } + + /** + * 鍒涘缓涓�涓伐浣滅翱 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + } + + /** + * 鍒涘缓宸ヤ綔琛� + * + * @param sheetNo sheet鏁伴噺 + * @param index 搴忓彿 + */ + public void createSheet(double sheetNo, int index) + { + this.sheet = wb.createSheet(); + this.styles = createStyles(wb); + // 璁剧疆宸ヤ綔琛ㄧ殑鍚嶇О. + if (sheetNo == 0) + { + wb.setSheetName(index, sheetName); + } + else + { + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 鑾峰彇鍗曞厓鏍煎�� + * + * @param row 鑾峰彇鐨勮 + * @param column 鑾峰彇鍗曞厓鏍煎垪鍙� + * @return 鍗曞厓鏍煎�� + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (cell != null) + { + if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (HSSFDateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 鏃ユ湡鏍煎紡杞崲 + } + else + { + if ((Double) val % 1 > 0) + { + val = new DecimalFormat("0.00").format(val); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellTypeEnum() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellTypeEnum() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java new file mode 100644 index 0000000..b78e53e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java @@ -0,0 +1,406 @@ +package com.ruoyi.common.utils.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Date; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.DateUtils; + +/** + * 鍙嶅皠宸ュ叿绫�. 鎻愪緵璋冪敤getter/setter鏂规硶, 璁块棶绉佹湁鍙橀噺, 璋冪敤绉佹湁鏂规硶, 鑾峰彇娉涘瀷绫诲瀷Class, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟. + * + * @author ruoyi + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils +{ + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 璋冪敤Getter鏂规硶. + * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶 + */ + @SuppressWarnings("unchecked") + public static <E> E invokeGetter(Object obj, String propertyName) + { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 璋冪敤Setter鏂规硶, 浠呭尮閰嶆柟娉曞悕銆� + * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶 + */ + public static <E> void invokeSetter(Object obj, String propertyName, E value) + { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) + { + if (i < names.length - 1) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else + { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 鐩存帴璇诲彇瀵硅薄灞炴�у��, 鏃犺private/protected淇グ绗�, 涓嶇粡杩噂etter鍑芥暟. + */ + @SuppressWarnings("unchecked") + public static <E> E getFieldValue(final Object obj, final String fieldName) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + fieldName + "] 瀛楁 "); + return null; + } + E result = null; + try + { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("涓嶅彲鑳芥姏鍑虹殑寮傚父{}", e.getMessage()); + } + return result; + } + + /** + * 鐩存帴璁剧疆瀵硅薄灞炴�у��, 鏃犺private/protected淇グ绗�, 涓嶇粡杩噑etter鍑芥暟. + */ + public static <E> void setFieldValue(final Object obj, final String fieldName, final E value) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + // throw new IllegalArgumentException("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + fieldName + "] 瀛楁 "); + logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + fieldName + "] 瀛楁 "); + return; + } + try + { + field.set(obj, value); + } + catch (IllegalAccessException e) + { + logger.error("涓嶅彲鑳芥姏鍑虹殑寮傚父: {}", e.getMessage()); + } + } + + /** + * 鐩存帴璋冪敤瀵硅薄鏂规硶, 鏃犺private/protected淇グ绗�. + * 鐢ㄤ簬涓�娆℃�ц皟鐢ㄧ殑鎯呭喌锛屽惁鍒欏簲浣跨敤getAccessibleMethod()鍑芥暟鑾峰緱Method鍚庡弽澶嶈皟鐢�. + * 鍚屾椂鍖归厤鏂规硶鍚�+鍙傛暟绫诲瀷锛� + */ + @SuppressWarnings("unchecked") + public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes, + final Object[] args) + { + if (obj == null || methodName == null) + { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) + { + logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + methodName + "] 鏂规硶 "); + return null; + } + try + { + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 鐩存帴璋冪敤瀵硅薄鏂规硶, 鏃犺private/protected淇グ绗︼紝 + * 鐢ㄤ簬涓�娆℃�ц皟鐢ㄧ殑鎯呭喌锛屽惁鍒欏簲浣跨敤getAccessibleMethodByName()鍑芥暟鑾峰緱Method鍚庡弽澶嶈皟鐢�. + * 鍙尮閰嶅嚱鏁板悕锛屽鏋滄湁澶氫釜鍚屽悕鍑芥暟璋冪敤绗竴涓�� + */ + @SuppressWarnings("unchecked") + public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args) + { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) + { + // 濡傛灉涓虹┖涓嶆姤閿欙紝鐩存帴杩斿洖绌恒�� + logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + methodName + "] 鏂规硶 "); + return null; + } + try + { + // 绫诲瀷杞崲锛堝皢鍙傛暟鏁版嵁绫诲瀷杞崲涓虹洰鏍囨柟娉曞弬鏁扮被鍨嬶級 + Class<?>[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) + { + if (args[i] != null && !args[i].getClass().equals(cs[i])) + { + if (cs[i] == String.class) + { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) + { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } + else if (cs[i] == Integer.class) + { + args[i] = Convert.toInt(args[i]); + } + else if (cs[i] == Long.class) + { + args[i] = Convert.toLong(args[i]); + } + else if (cs[i] == Double.class) + { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) + { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) + { + if (args[i] instanceof String) + { + args[i] = DateUtils.parseDate(args[i]); + } + else + { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredField, 骞跺己鍒惰缃负鍙闂�. + * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) + { + // 涓虹┖涓嶆姤閿欍�傜洿鎺ヨ繑鍥� null + if (obj == null) + { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) + { + try + { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) + { + continue; + } + } + return null; + } + + /** + * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�. + * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null. + * 鍖归厤鍑芥暟鍚�+鍙傛暟绫诲瀷銆� + * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class<?>... parameterTypes) + { + // 涓虹┖涓嶆姤閿欍�傜洿鎺ヨ繑鍥� null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + try + { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) + { + continue; + } + } + return null; + } + + /** + * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�. + * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null. + * 鍙尮閰嶅嚱鏁板悕銆� + * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) + { + // 涓虹┖涓嶆姤閿欍�傜洿鎺ヨ繑鍥� null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) + { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) + { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 鏀瑰彉private/protected鐨勬柟娉曚负public锛屽敖閲忎笉璋冪敤瀹為檯鏀瑰姩鐨勮鍙ワ紝閬垮厤JDK鐨凷ecurityManager鎶辨�ㄣ�� + */ + public static void makeAccessible(Method method) + { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) + { + method.setAccessible(true); + } + } + + /** + * 鏀瑰彉private/protected鐨勬垚鍛樺彉閲忎负public锛屽敖閲忎笉璋冪敤瀹為檯鏀瑰姩鐨勮鍙ワ紝閬垮厤JDK鐨凷ecurityManager鎶辨�ㄣ�� + */ + public static void makeAccessible(Field field) + { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) + { + field.setAccessible(true); + } + } + + /** + * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑娉涘瀷鍙傛暟鐨勭被鍨�, 娉ㄦ剰娉涘瀷蹇呴』瀹氫箟鍦ㄧ埗绫诲 + * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class. + */ + @SuppressWarnings("unchecked") + public static <T> Class<T> getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑鐖剁被鐨勬硾鍨嬪弬鏁扮殑绫诲瀷. + * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) + { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) + { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) + { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) + { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class<?> getUserClass(Object instance) + { + if (instance == null) + { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) + { + Class<?> superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) + { + return superClass; + } + } + return clazz; + + } + + /** + * 灏嗗弽灏勬椂鐨刢hecked exception杞崲涓簎nchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) + { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) + { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) + { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java new file mode 100644 index 0000000..2bb1a8b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java @@ -0,0 +1,66 @@ +package com.ruoyi.common.utils.security; + +import java.security.MessageDigest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Md5鍔犲瘑鏂规硶 + * + * @author ruoyi + */ +public class Md5Utils +{ + private static final Logger log = LoggerFactory.getLogger(Md5Utils.class); + + private static byte[] md5(String s) + { + MessageDigest algorithm; + try + { + algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(s.getBytes("UTF-8")); + byte[] messageDigest = algorithm.digest(); + return messageDigest; + } + catch (Exception e) + { + log.error("MD5 Error...", e); + } + return null; + } + + private static final String toHex(byte hash[]) + { + if (hash == null) + { + return null; + } + StringBuffer buf = new StringBuffer(hash.length * 2); + int i; + + for (i = 0; i < hash.length; i++) + { + if ((hash[i] & 0xff) < 0x10) + { + buf.append("0"); + } + buf.append(Long.toString(hash[i] & 0xff, 16)); + } + return buf.toString(); + } + + public static String hash(String s) + { + try + { + return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8"); + } + catch (Exception e) + { + log.error("not supported charset...{}", e); + return s; + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/sign/Base64.java b/ruoyi/src/main/java/com/ruoyi/common/utils/sign/Base64.java new file mode 100644 index 0000000..ca1cd92 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/sign/Base64.java @@ -0,0 +1,291 @@ +package com.ruoyi.common.utils.sign; + +/** + * Base64宸ュ叿绫� + * + * @author ruoyi + */ +public final class Base64 +{ + static private final int BASELENGTH = 128; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final char PAD = '='; + static final private byte[] base64Alphabet = new byte[BASELENGTH]; + static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; + + static + { + for (int i = 0; i < BASELENGTH; ++i) + { + base64Alphabet[i] = -1; + } + for (int i = 'Z'; i >= 'A'; i--) + { + base64Alphabet[i] = (byte) (i - 'A'); + } + for (int i = 'z'; i >= 'a'; i--) + { + base64Alphabet[i] = (byte) (i - 'a' + 26); + } + + for (int i = '9'; i >= '0'; i--) + { + base64Alphabet[i] = (byte) (i - '0' + 52); + } + + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; + + for (int i = 0; i <= 25; i++) + { + lookUpBase64Alphabet[i] = (char) ('A' + i); + } + + for (int i = 26, j = 0; i <= 51; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('a' + j); + } + + for (int i = 52, j = 0; i <= 61; i++, j++) + { + lookUpBase64Alphabet[i] = (char) ('0' + j); + } + lookUpBase64Alphabet[62] = (char) '+'; + lookUpBase64Alphabet[63] = (char) '/'; + } + + private static boolean isWhiteSpace(char octect) + { + return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); + } + + private static boolean isPad(char octect) + { + return (octect == PAD); + } + + private static boolean isData(char octect) + { + return (octect < BASELENGTH && base64Alphabet[octect] != -1); + } + + /** + * Encodes hex octects into Base64 + * + * @param binaryData Array containing binaryData + * @return Encoded Base64 array + */ + public static String encode(byte[] binaryData) + { + if (binaryData == null) + { + return null; + } + + int lengthDataBits = binaryData.length * EIGHTBIT; + if (lengthDataBits == 0) + { + return ""; + } + + int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; + int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; + char encodedData[] = null; + + encodedData = new char[numberQuartet * 4]; + + byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + + for (int i = 0; i < numberTriplets; i++) + { + b1 = binaryData[dataIndex++]; + b2 = binaryData[dataIndex++]; + b3 = binaryData[dataIndex++]; + + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; + } + + // form integral number of 6-bit groups + if (fewerThan24bits == EIGHTBIT) + { + b1 = binaryData[dataIndex]; + k = (byte) (b1 & 0x03); + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; + encodedData[encodedIndex++] = PAD; + encodedData[encodedIndex++] = PAD; + } + else if (fewerThan24bits == SIXTEENBIT) + { + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); + byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); + + encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; + encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; + encodedData[encodedIndex++] = PAD; + } + return new String(encodedData); + } + + /** + * Decodes Base64 data into octects + * + * @param encoded string containing Base64 data + * @return Array containind decoded data. + */ + public static byte[] decode(String encoded) + { + if (encoded == null) + { + return null; + } + + char[] base64Data = encoded.toCharArray(); + // remove white spaces + int len = removeWhiteSpace(base64Data); + + if (len % FOURBYTE != 0) + { + return null;// should be divisible by four + } + + int numberQuadruple = (len / FOURBYTE); + + if (numberQuadruple == 0) + { + return new byte[0]; + } + + byte decodedData[] = null; + byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; + char d1 = 0, d2 = 0, d3 = 0, d4 = 0; + + int i = 0; + int encodedIndex = 0; + int dataIndex = 0; + decodedData = new byte[(numberQuadruple) * 3]; + + for (; i < numberQuadruple - 1; i++) + { + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) + || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) + { + return null; + } // if found "no data" just return null + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + } + + if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) + { + return null;// if found "no data" just return null + } + + b1 = base64Alphabet[d1]; + b2 = base64Alphabet[d2]; + + d3 = base64Data[dataIndex++]; + d4 = base64Data[dataIndex++]; + if (!isData((d3)) || !isData((d4))) + {// Check if they are PAD characters + if (isPad(d3) && isPad(d4)) + { + if ((b2 & 0xf) != 0)// last 4 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 1]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); + return tmp; + } + else if (!isPad(d3) && isPad(d4)) + { + b3 = base64Alphabet[d3]; + if ((b3 & 0x3) != 0)// last 2 bits should be zero + { + return null; + } + byte[] tmp = new byte[i * 3 + 2]; + System.arraycopy(decodedData, 0, tmp, 0, i * 3); + tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + return tmp; + } + else + { + return null; + } + } + else + { // No PAD e.g 3cQl + b3 = base64Alphabet[d3]; + b4 = base64Alphabet[d4]; + decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); + decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); + decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); + + } + return decodedData; + } + + /** + * remove WhiteSpace from MIME containing encoded Base64 data. + * + * @param data the byte array of base64 data (with WS) + * @return the new length + */ + private static int removeWhiteSpace(char[] data) + { + if (data == null) + { + return 0; + } + + // count characters that's not whitespace + int newSize = 0; + int len = data.length; + for (int i = 0; i < len; i++) + { + if (!isWhiteSpace(data[i])) + { + data[newSize++] = data[i]; + } + } + return newSize; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java b/ruoyi/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java new file mode 100644 index 0000000..19bd77e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java @@ -0,0 +1,114 @@ +package com.ruoyi.common.utils.spring; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.stereotype.Component; + +/** + * spring宸ュ叿绫� 鏂逛究鍦ㄩ潪spring绠$悊鐜涓幏鍙朾ean + * + * @author ruoyi + */ +@Component +public final class SpringUtils implements BeanFactoryPostProcessor +{ + /** Spring搴旂敤涓婁笅鏂囩幆澧� */ + private static ConfigurableListableBeanFactory beanFactory; + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException + { + SpringUtils.beanFactory = beanFactory; + } + + /** + * 鑾峰彇瀵硅薄 + * + * @param name + * @return Object 涓�涓互鎵�缁欏悕瀛楁敞鍐岀殑bean鐨勫疄渚� + * @throws org.springframework.beans.BeansException + * + */ + @SuppressWarnings("unchecked") + public static <T> T getBean(String name) throws BeansException + { + return (T) beanFactory.getBean(name); + } + + /** + * 鑾峰彇绫诲瀷涓簉equiredType鐨勫璞� + * + * @param clz + * @return + * @throws org.springframework.beans.BeansException + * + */ + public static <T> T getBean(Class<T> clz) throws BeansException + { + T result = (T) beanFactory.getBean(clz); + return result; + } + + /** + * 濡傛灉BeanFactory鍖呭惈涓�涓笌鎵�缁欏悕绉板尮閰嶇殑bean瀹氫箟锛屽垯杩斿洖true + * + * @param name + * @return boolean + */ + public static boolean containsBean(String name) + { + return beanFactory.containsBean(name); + } + + /** + * 鍒ゆ柇浠ョ粰瀹氬悕瀛楁敞鍐岀殑bean瀹氫箟鏄竴涓猻ingleton杩樻槸涓�涓猵rototype銆� 濡傛灉涓庣粰瀹氬悕瀛楃浉搴旂殑bean瀹氫箟娌℃湁琚壘鍒帮紝灏嗕細鎶涘嚭涓�涓紓甯革紙NoSuchBeanDefinitionException锛� + * + * @param name + * @return boolean + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.isSingleton(name); + } + + /** + * @param name + * @return Class 娉ㄥ唽瀵硅薄鐨勭被鍨� + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static Class<?> getType(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getType(name); + } + + /** + * 濡傛灉缁欏畾鐨刡ean鍚嶅瓧鍦╞ean瀹氫箟涓湁鍒悕锛屽垯杩斿洖杩欎簺鍒悕 + * + * @param name + * @return + * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException + * + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException + { + return beanFactory.getAliases(name); + } + + /** + * 鑾峰彇aop浠g悊瀵硅薄 + * + * @param invoker + * @return + */ + @SuppressWarnings("unchecked") + public static <T> T getAopProxy(T invoker) + { + return (T) AopContext.currentProxy(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java b/ruoyi/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java new file mode 100644 index 0000000..b31804b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java @@ -0,0 +1,36 @@ +package com.ruoyi.common.utils.sql; + +import com.ruoyi.common.utils.StringUtils; + +/** + * sql鎿嶄綔宸ュ叿绫� + * + * @author ruoyi + */ +public class SqlUtil +{ + /** + * 浠呮敮鎸佸瓧姣嶃�佹暟瀛椼�佷笅鍒掔嚎銆佺┖鏍笺�侀�楀彿锛堟敮鎸佸涓瓧娈垫帓搴忥級 + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+"; + + /** + * 妫�鏌ュ瓧绗︼紝闃叉娉ㄥ叆缁曡繃 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + return StringUtils.EMPTY; + } + return value; + } + + /** + * 楠岃瘉 order by 璇硶鏄惁绗﹀悎瑙勮寖 + */ + public static boolean isValidOrderBySql(String value) + { + return value.matches(SQL_PATTERN); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/text/CharsetKit.java b/ruoyi/src/main/java/com/ruoyi/common/utils/text/CharsetKit.java new file mode 100644 index 0000000..7a463be --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/text/CharsetKit.java @@ -0,0 +1,87 @@ +package com.ruoyi.common.utils.text; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import com.ruoyi.common.utils.StringUtils; + +/** + * 瀛楃闆嗗伐鍏风被 + * + * @author ruoyi + * + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 杞崲涓篊harset瀵硅薄 + * + * @param charset 瀛楃闆嗭紝涓虹┖鍒欒繑鍥為粯璁ゅ瓧绗﹂泦 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 杞崲瀛楃涓茬殑瀛楃闆嗙紪鐮� + * + * @param source 瀛楃涓� + * @param srcCharset 婧愬瓧绗﹂泦锛岄粯璁SO-8859-1 + * @param destCharset 鐩爣瀛楃闆嗭紝榛樿UTF-8 + * @return 杞崲鍚庣殑瀛楃闆� + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 杞崲瀛楃涓茬殑瀛楃闆嗙紪鐮� + * + * @param source 瀛楃涓� + * @param srcCharset 婧愬瓧绗﹂泦锛岄粯璁SO-8859-1 + * @param destCharset 鐩爣瀛楃闆嗭紝榛樿UTF-8 + * @return 杞崲鍚庣殑瀛楃闆� + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + srcCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 绯荤粺瀛楃闆嗙紪鐮� + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/text/Convert.java b/ruoyi/src/main/java/com/ruoyi/common/utils/text/Convert.java new file mode 100644 index 0000000..2a025ba --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/text/Convert.java @@ -0,0 +1,999 @@ +package com.ruoyi.common.utils.text; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; +import com.ruoyi.common.utils.StringUtils; + +/** + * 绫诲瀷杞崲鍣� + * + * @author ruoyi + */ +public class Convert +{ + /** + * 杞崲涓哄瓧绗︿覆<br> + * 濡傛灉缁欏畾鐨勫�间负null锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 杞崲涓哄瓧绗︿覆<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 杞崲涓哄瓧绗�<br> + * 濡傛灉缁欏畾鐨勫�间负null锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 杞崲涓哄瓧绗�<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 杞崲涓篵yte<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篵yte<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 杞崲涓篠hort<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篠hort<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 杞崲涓篘umber<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篘umber<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 杞崲涓篿nt<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篿nt<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 杞崲涓篒nteger鏁扮粍<br> + * + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 杞崲涓篖ong鏁扮粍<br> + * + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 杞崲涓篒nteger鏁扮粍<br> + * + * @param split 鍒嗛殧绗� + * @param split 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 杞崲涓篖ong鏁扮粍<br> + * + * @param split 鍒嗛殧绗� + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 杞崲涓篠tring鏁扮粍<br> + * + * @param str 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 杞崲涓篠tring鏁扮粍<br> + * + * @param split 鍒嗛殧绗� + * @param split 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 杞崲涓簂ong<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 鏀寔绉戝璁℃暟娉� + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓簂ong<br> + * 濡傛灉缁欏畾鐨勫�间负<code>null</code>锛屾垨鑰呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 杞崲涓篸ouble<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 鏀寔绉戝璁℃暟娉� + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篸ouble<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 杞崲涓篎loat<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篎loat<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 杞崲涓篵oolean<br> + * String鏀寔鐨勫�间负锛歵rue銆乫alse銆亂es銆乷k銆乶o锛�1,0 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + return true; + case "false": + return false; + case "yes": + return true; + case "ok": + return true; + case "no": + return false; + case "1": + return true; + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 杞崲涓篵oolean<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 杞崲涓篍num瀵硅薄<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * + * @param clazz Enum鐨凜lass + * @param value 鍊� + * @param defaultValue 榛樿鍊� + * @return Enum + */ + public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓篍num瀵硅薄<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * + * @param clazz Enum鐨凜lass + * @param value 鍊� + * @return Enum + */ + public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 杞崲涓築igInteger<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓築igInteger<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<code>null</code><br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 杞崲涓築igDecimal<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @param defaultValue 杞崲閿欒鏃剁殑榛樿鍊� + * @return 缁撴灉 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return new BigDecimal((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 杞崲涓築igDecimal<br> + * 濡傛灉缁欏畾鐨勫�间负绌猴紝鎴栬�呰浆鎹㈠け璐ワ紝杩斿洖榛樿鍊�<br> + * 杞崲澶辫触涓嶄細鎶ラ敊 + * + * @param value 琚浆鎹㈢殑鍊� + * @return 缁撴灉 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 灏嗗璞¤浆涓哄瓧绗︿覆<br> + * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁� 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶 + * + * @param obj 瀵硅薄 + * @return 瀛楃涓� + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 灏嗗璞¤浆涓哄瓧绗︿覆<br> + * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁� 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶 + * + * @param obj 瀵硅薄 + * @param charsetName 瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 灏嗗璞¤浆涓哄瓧绗︿覆<br> + * 1銆丅yte鏁扮粍鍜孊yteBuffer浼氳杞崲涓哄搴斿瓧绗︿覆鐨勬暟缁� 2銆佸璞℃暟缁勪細璋冪敤Arrays.toString鏂规硶 + * + * @param obj 瀵硅薄 + * @param charset 瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[] || obj instanceof Byte[]) + { + return str((Byte[]) obj, charset); + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 灏哹yte鏁扮粍杞负瀛楃涓� + * + * @param bytes byte鏁扮粍 + * @param charset 瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 瑙g爜瀛楄妭鐮� + * + * @param data 瀛楃涓� + * @param charset 瀛楃闆嗭紝濡傛灉姝ゅ瓧娈典负绌猴紝鍒欒В鐮佺殑缁撴灉鍙栧喅浜庡钩鍙� + * @return 瑙g爜鍚庣殑瀛楃涓� + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 灏嗙紪鐮佺殑byteBuffer鏁版嵁杞崲涓哄瓧绗︿覆 + * + * @param data 鏁版嵁 + * @param charset 瀛楃闆嗭紝濡傛灉涓虹┖浣跨敤褰撳墠绯荤粺瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 灏嗙紪鐮佺殑byteBuffer鏁版嵁杞崲涓哄瓧绗︿覆 + * + * @param data 鏁版嵁 + * @param charset 瀛楃闆嗭紝濡傛灉涓虹┖浣跨敤褰撳墠绯荤粺瀛楃闆� + * @return 瀛楃涓� + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 鍏ㄨ鍗婅杞崲 + /** + * 鍗婅杞叏瑙� + * + * @param input String. + * @return 鍏ㄨ瀛楃涓�. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 鍗婅杞叏瑙� + * + * @param input String + * @param notConvertSet 涓嶆浛鎹㈢殑瀛楃闆嗗悎 + * @return 鍏ㄨ瀛楃涓�. + */ + public static String toSBC(String input, Set<Character> notConvertSet) + { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 璺宠繃涓嶆浛鎹㈢殑瀛楃 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 鍏ㄨ杞崐瑙� + * + * @param input String. + * @return 鍗婅瀛楃涓� + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 鏇挎崲鍏ㄨ涓哄崐瑙� + * + * @param text 鏂囨湰 + * @param notConvertSet 涓嶆浛鎹㈢殑瀛楃闆嗗悎 + * @return 鏇挎崲鍚庣殑瀛楃 + */ + public static String toDBC(String text, Set<Character> notConvertSet) + { + char c[] = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 璺宠繃涓嶆浛鎹㈢殑瀛楃 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + + return returnString; + } + + /** + * 鏁板瓧閲戦澶у啓杞崲 鍏堝啓涓畬鏁寸殑鐒跺悗灏嗗闆舵嬀鏇挎崲鎴愰浂 + * + * @param n 鏁板瓧 + * @return 涓枃澶у啓鏁板瓧 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "瑙�", "鍒�" }; + String[] digit = { "闆�", "澹�", "璐�", "鍙�", "鑲�", "浼�", "闄�", "鏌�", "鎹�", "鐜�" }; + String[][] unit = { { "鍏�", "涓�", "浜�" }, { "", "鎷�", "浣�", "浠�" } }; + + String head = n < 0 ? "璐�" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(闆�.)+", ""); + } + if (s.length() < 1) + { + s = "鏁�"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(闆�.)*闆�$", "").replaceAll("^$", "闆�") + unit[0][i] + s; + } + return head + s.replaceAll("(闆�.)*闆跺厓", "鍏�").replaceFirst("(闆�.)+", "").replaceAll("(闆�.)+", "闆�").replaceAll("^鏁�$", "闆跺厓鏁�"); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/utils/text/StrFormatter.java b/ruoyi/src/main/java/com/ruoyi/common/utils/text/StrFormatter.java new file mode 100644 index 0000000..40e6214 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/utils/text/StrFormatter.java @@ -0,0 +1,93 @@ +package com.ruoyi.common.utils.text; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 瀛楃涓叉牸寮忓寲 + * + * @author ruoyi + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 鏍煎紡鍖栧瓧绗︿覆<br> + * 姝ゆ柟娉曞彧鏄畝鍗曞皢鍗犱綅绗� {} 鎸夌収椤哄簭鏇挎崲涓哄弬鏁�<br> + * 濡傛灉鎯宠緭鍑� {} 浣跨敤 \\杞箟 { 鍗冲彲锛屽鏋滄兂杈撳嚭 {} 涔嬪墠鐨� \ 浣跨敤鍙岃浆涔夌 \\\\ 鍗冲彲<br> + * 渚嬶細<br> + * 閫氬父浣跨敤锛歠ormat("this is {} for {}", "a", "b") -> this is a for b<br> + * 杞箟{}锛� format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> + * 杞箟\锛� format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> + * + * @param strPattern 瀛楃涓叉ā鏉� + * @param argArray 鍙傛暟鍒楄〃 + * @return 缁撴灉 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 鍒濆鍖栧畾涔夊ソ鐨勯暱搴︿互鑾峰緱鏇村ソ鐨勬�ц兘 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 鍗犱綅绗︽墍鍦ㄤ綅缃� + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 瀛楃涓叉ā鏉垮墿浣欓儴鍒嗕笉鍐嶅寘鍚崰浣嶇锛屽姞鍏ュ墿浣欓儴鍒嗗悗杩斿洖缁撴灉 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 杞箟绗︿箣鍓嶈繕鏈変竴涓浆涔夌锛屽崰浣嶇渚濇棫鏈夋晥 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 鍗犱綅绗﹁杞箟 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 姝e父鍗犱綅绗� + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // append the characters following the last {} pair. + // 鍔犲叆鏈�鍚庝竴涓崰浣嶇鍚庢墍鏈夌殑瀛楃 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java b/ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java new file mode 100644 index 0000000..9310402 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/xss/XssFilter.java @@ -0,0 +1,97 @@ +package com.ruoyi.common.xss; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import com.ruoyi.common.utils.StringUtils; + +/** + * 闃叉XSS鏀诲嚮鐨勮繃婊ゅ櫒 + * + * @author ruoyi + */ +public class XssFilter implements Filter +{ + /** + * 鎺掗櫎閾炬帴 + */ + public List<String> excludes = new ArrayList<>(); + + /** + * xss杩囨护寮�鍏� + */ + public boolean enabled = false; + + @Override + public void init(FilterConfig filterConfig) throws ServletException + { + String tempExcludes = filterConfig.getInitParameter("excludes"); + String tempEnabled = filterConfig.getInitParameter("enabled"); + if (StringUtils.isNotEmpty(tempExcludes)) + { + String[] url = tempExcludes.split(","); + for (int i = 0; url != null && i < url.length; i++) + { + excludes.add(url[i]); + } + } + if (StringUtils.isNotEmpty(tempEnabled)) + { + enabled = Boolean.valueOf(tempEnabled); + } + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + if (handleExcludeURL(req, resp)) + { + chain.doFilter(request, response); + return; + } + XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); + chain.doFilter(xssRequest, response); + } + + private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) + { + if (!enabled) + { + return true; + } + if (excludes == null || excludes.isEmpty()) + { + return false; + } + String url = request.getServletPath(); + for (String pattern : excludes) + { + Pattern p = Pattern.compile("^" + pattern); + Matcher m = p.matcher(url); + if (m.find()) + { + return true; + } + } + return false; + } + + @Override + public void destroy() + { + + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java b/ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..178d759 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java @@ -0,0 +1,105 @@ +package com.ruoyi.common.xss; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import org.apache.commons.io.IOUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.html.EscapeUtil; + +/** + * XSS杩囨护澶勭悊 + * + * @author ruoyi + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper +{ + /** + * @param request + */ + public XssHttpServletRequestWrapper(HttpServletRequest request) + { + super(request); + } + + @Override + public String[] getParameterValues(String name) + { + String[] values = super.getParameterValues(name); + if (values != null) + { + int length = values.length; + String[] escapseValues = new String[length]; + for (int i = 0; i < length; i++) + { + // 闃瞲ss鏀诲嚮鍜岃繃婊ゅ墠鍚庣┖鏍� + escapseValues[i] = EscapeUtil.clean(values[i]).trim(); + } + return escapseValues; + } + return super.getParameterValues(name); + } + + @Override + public ServletInputStream getInputStream() throws IOException + { + // 闈瀓son绫诲瀷锛岀洿鎺ヨ繑鍥� + if (!isJsonRequest()) + { + return super.getInputStream(); + } + + // 涓虹┖锛岀洿鎺ヨ繑鍥� + String json = IOUtils.toString(super.getInputStream(), "utf-8"); + if (StringUtils.isEmpty(json)) + { + return super.getInputStream(); + } + + // xss杩囨护 + json = EscapeUtil.clean(json).trim(); + final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8")); + return new ServletInputStream() + { + @Override + public boolean isFinished() + { + return true; + } + + @Override + public boolean isReady() + { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) + { + } + + @Override + public int read() throws IOException + { + return bis.read(); + } + }; + } + + /** + * 鏄惁鏄疛son璇锋眰 + * + * @param request + */ + public boolean isJsonRequest() + { + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + return MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(header) + || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(header); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java new file mode 100644 index 0000000..c976d95 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java @@ -0,0 +1,160 @@ +package com.ruoyi.framework.aspectj; + +import java.lang.reflect.Method; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.DataScope; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.framework.web.domain.BaseEntity; +import com.ruoyi.project.system.domain.SysRole; +import com.ruoyi.project.system.domain.SysUser; + +/** + * 鏁版嵁杩囨护澶勭悊 + * + * @author ruoyi + */ +@Aspect +@Component +public class DataScopeAspect +{ + /** + * 鍏ㄩ儴鏁版嵁鏉冮檺 + */ + public static final String DATA_SCOPE_ALL = "1"; + + /** + * 鑷畾鏁版嵁鏉冮檺 + */ + public static final String DATA_SCOPE_CUSTOM = "2"; + + /** + * 閮ㄩ棬鏁版嵁鏉冮檺 + */ + public static final String DATA_SCOPE_DEPT = "3"; + + /** + * 閮ㄩ棬鍙婁互涓嬫暟鎹潈闄� + */ + public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; + + /** + * 浠呮湰浜烘暟鎹潈闄� + */ + public static final String DATA_SCOPE_SELF = "5"; + + // 閰嶇疆缁囧叆鐐� + @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataScope)") + public void dataScopePointCut() + { + } + + @Before("dataScopePointCut()") + public void doBefore(JoinPoint point) throws Throwable + { + handleDataScope(point); + } + + protected void handleDataScope(final JoinPoint joinPoint) + { + // 鑾峰緱娉ㄨВ + DataScope controllerDataScope = getAnnotationLog(joinPoint); + if (controllerDataScope == null) + { + return; + } + // 鑾峰彇褰撳墠鐨勭敤鎴� + LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); + SysUser currentUser = loginUser.getUser(); + if (currentUser != null) + { + // 濡傛灉鏄秴绾х鐞嗗憳锛屽垯涓嶈繃婊ゆ暟鎹� + if (!currentUser.isAdmin()) + { + dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), + controllerDataScope.userAlias()); + } + } + } + + /** + * 鏁版嵁鑼冨洿杩囨护 + * + * @param joinPoint 鍒囩偣 + * @param user 鐢ㄦ埛 + * @param alias 鍒悕 + */ + public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias) + { + StringBuilder sqlString = new StringBuilder(); + + for (SysRole role : user.getRoles()) + { + String dataScope = role.getDataScope(); + if (DATA_SCOPE_ALL.equals(dataScope)) + { + sqlString = new StringBuilder(); + break; + } + else if (DATA_SCOPE_CUSTOM.equals(dataScope)) + { + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, + role.getRoleId())); + } + else if (DATA_SCOPE_DEPT.equals(dataScope)) + { + sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); + } + else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) + { + sqlString.append(StringUtils.format( + " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", + deptAlias, user.getDeptId(), user.getDeptId())); + } + else if (DATA_SCOPE_SELF.equals(dataScope)) + { + if (StringUtils.isNotBlank(userAlias)) + { + sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); + } + else + { + // 鏁版嵁鏉冮檺涓轰粎鏈汉涓旀病鏈塽serAlias鍒悕涓嶆煡璇换浣曟暟鎹� + sqlString.append(" OR 1=0 "); + } + } + } + + if (StringUtils.isNotBlank(sqlString.toString())) + { + BaseEntity baseEntity = (BaseEntity) joinPoint.getArgs()[0]; + baseEntity.setDataScope(" AND (" + sqlString.substring(4) + ")"); + } + } + + /** + * 鏄惁瀛樺湪娉ㄨВ锛屽鏋滃瓨鍦ㄥ氨鑾峰彇 + */ + private DataScope getAnnotationLog(JoinPoint joinPoint) + { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + if (method != null) + { + return method.getAnnotation(DataScope.class); + } + return null; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java new file mode 100644 index 0000000..ae3d8e3 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java @@ -0,0 +1,76 @@ +package com.ruoyi.framework.aspectj; + +import java.lang.reflect.Method; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.DataSource; +import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder; + +/** + * 澶氭暟鎹簮澶勭悊 + * + * @author ruoyi + */ +@Aspect +@Order(1) +@Component +public class DataSourceAspect +{ + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataSource)" + + "|| @within(com.ruoyi.framework.aspectj.lang.annotation.DataSource)") + public void dsPointCut() + { + + } + + @Around("dsPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable + { + DataSource dataSource = getDataSource(point); + + if (StringUtils.isNotNull(dataSource)) + { + DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); + } + + try + { + return point.proceed(); + } + finally + { + // 閿�姣佹暟鎹簮 鍦ㄦ墽琛屾柟娉曚箣鍚� + DynamicDataSourceContextHolder.clearDataSourceType(); + } + } + + /** + * 鑾峰彇闇�瑕佸垏鎹㈢殑鏁版嵁婧� + */ + public DataSource getDataSource(ProceedingJoinPoint point) + { + MethodSignature signature = (MethodSignature) point.getSignature(); + Class<? extends Object> targetClass = point.getTarget().getClass(); + DataSource targetDataSource = targetClass.getAnnotation(DataSource.class); + if (StringUtils.isNotNull(targetDataSource)) + { + return targetDataSource; + } + else + { + Method method = signature.getMethod(); + DataSource dataSource = method.getAnnotation(DataSource.class); + return dataSource; + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java new file mode 100644 index 0000000..4ccf8ec --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -0,0 +1,217 @@ +package com.ruoyi.framework.aspectj; + +import java.lang.reflect.Method; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.HandlerMapping; +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.enums.HttpMethod; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessStatus; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.project.monitor.domain.SysOperLog; + +/** + * 鎿嶄綔鏃ュ織璁板綍澶勭悊 + * + * @author ruoyi + */ +@Aspect +@Component +public class LogAspect +{ + private static final Logger log = LoggerFactory.getLogger(LogAspect.class); + + // 閰嶇疆缁囧叆鐐� + @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Log)") + public void logPointCut() + { + } + + /** + * 澶勭悊瀹岃姹傚悗鎵ц + * + * @param joinPoint 鍒囩偣 + */ + @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) + { + handleLog(joinPoint, null, jsonResult); + } + + /** + * 鎷︽埅寮傚父鎿嶄綔 + * + * @param joinPoint 鍒囩偣 + * @param e 寮傚父 + */ + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) + { + handleLog(joinPoint, e, null); + } + + protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) + { + try + { + // 鑾峰緱娉ㄨВ + Log controllerLog = getAnnotationLog(joinPoint); + if (controllerLog == null) + { + return; + } + + // 鑾峰彇褰撳墠鐨勭敤鎴� + LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); + + // *========鏁版嵁搴撴棩蹇�=========*// + SysOperLog operLog = new SysOperLog(); + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); + // 璇锋眰鐨勫湴鍧� + String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + operLog.setOperIp(ip); + // 杩斿洖鍙傛暟 + operLog.setJsonResult(JSON.toJSONString(jsonResult)); + + operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); + if (loginUser != null) + { + operLog.setOperName(loginUser.getUsername()); + } + + if (e != null) + { + operLog.setStatus(BusinessStatus.FAIL.ordinal()); + operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); + } + // 璁剧疆鏂规硶鍚嶇О + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + operLog.setMethod(className + "." + methodName + "()"); + // 璁剧疆璇锋眰鏂瑰紡 + operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + // 澶勭悊璁剧疆娉ㄨВ涓婄殑鍙傛暟 + getControllerMethodDescription(joinPoint, controllerLog, operLog); + // 淇濆瓨鏁版嵁搴� + AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); + } + catch (Exception exp) + { + // 璁板綍鏈湴寮傚父鏃ュ織 + log.error("==鍓嶇疆閫氱煡寮傚父=="); + log.error("寮傚父淇℃伅:{}", exp.getMessage()); + exp.printStackTrace(); + } + } + + /** + * 鑾峰彇娉ㄨВ涓鏂规硶鐨勬弿杩颁俊鎭� 鐢ㄤ簬Controller灞傛敞瑙� + * + * @param log 鏃ュ織 + * @param operLog 鎿嶄綔鏃ュ織 + * @throws Exception + */ + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception + { + // 璁剧疆action鍔ㄤ綔 + operLog.setBusinessType(log.businessType().ordinal()); + // 璁剧疆鏍囬 + operLog.setTitle(log.title()); + // 璁剧疆鎿嶄綔浜虹被鍒� + operLog.setOperatorType(log.operatorType().ordinal()); + // 鏄惁闇�瑕佷繚瀛榬equest锛屽弬鏁板拰鍊� + if (log.isSaveRequestData()) + { + // 鑾峰彇鍙傛暟鐨勪俊鎭紝浼犲叆鍒版暟鎹簱涓�� + setRequestValue(joinPoint, operLog); + } + } + + /** + * 鑾峰彇璇锋眰鐨勫弬鏁帮紝鏀惧埌log涓� + * + * @param operLog 鎿嶄綔鏃ュ織 + * @throws Exception 寮傚父 + */ + private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception + { + String requestMethod = operLog.getRequestMethod(); + if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) + { + String params = argsArrayToString(joinPoint.getArgs()); + operLog.setOperParam(StringUtils.substring(params, 0, 2000)); + } + else + { + Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); + operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000)); + } + } + + /** + * 鏄惁瀛樺湪娉ㄨВ锛屽鏋滃瓨鍦ㄥ氨鑾峰彇 + */ + private Log getAnnotationLog(JoinPoint joinPoint) throws Exception + { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + if (method != null) + { + return method.getAnnotation(Log.class); + } + return null; + } + + /** + * 鍙傛暟鎷艰 + */ + private String argsArrayToString(Object[] paramsArray) + { + String params = ""; + if (paramsArray != null && paramsArray.length > 0) + { + for (int i = 0; i < paramsArray.length; i++) + { + if (!isFilterObject(paramsArray[i])) + { + Object jsonObj = JSON.toJSON(paramsArray[i]); + params += jsonObj.toString() + " "; + } + } + } + return params.trim(); + } + + /** + * 鍒ゆ柇鏄惁闇�瑕佽繃婊ょ殑瀵硅薄銆� + * + * @param o 瀵硅薄淇℃伅銆� + * @return 濡傛灉鏄渶瑕佽繃婊ょ殑瀵硅薄锛屽垯杩斿洖true锛涘惁鍒欒繑鍥瀎alse銆� + */ + public boolean isFilterObject(final Object o) + { + return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataScope.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataScope.java new file mode 100644 index 0000000..abb5978 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataScope.java @@ -0,0 +1,28 @@ +package com.ruoyi.framework.aspectj.lang.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 鏁版嵁鏉冮檺杩囨护娉ㄨВ + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataScope +{ + /** + * 閮ㄩ棬琛ㄧ殑鍒悕 + */ + public String deptAlias() default ""; + + /** + * 鐢ㄦ埛琛ㄧ殑鍒悕 + */ + public String userAlias() default ""; +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java new file mode 100644 index 0000000..a89c7b9 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/DataSource.java @@ -0,0 +1,26 @@ +package com.ruoyi.framework.aspectj.lang.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.ruoyi.framework.aspectj.lang.enums.DataSourceType; + +/** + * 鑷畾涔夊鏁版嵁婧愬垏鎹㈡敞瑙� + * + * @author ruoyi + */ +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource +{ + /** + * 鍒囨崲鏁版嵁婧愬悕绉� + */ + public DataSourceType value() default DataSourceType.MASTER; +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java new file mode 100644 index 0000000..8037cb8 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java @@ -0,0 +1,113 @@ +package com.ruoyi.framework.aspectj.lang.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 鑷畾涔夊鍑篍xcel鏁版嵁娉ㄨВ + * + * @author ruoyi + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 瀵煎嚭鍒癊xcel涓殑鍚嶅瓧. + */ + public String name() default ""; + + /** + * 鏃ユ湡鏍煎紡, 濡�: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 璇诲彇鍐呭杞〃杈惧紡 (濡�: 0=鐢�,1=濂�,2=鏈煡) + */ + public String readConverterExp() default ""; + + /** + * 瀵煎嚭绫诲瀷锛�0鏁板瓧 1瀛楃涓诧級 + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 瀵煎嚭鏃跺湪excel涓瘡涓垪鐨勯珮搴� 鍗曚綅涓哄瓧绗� + */ + public double height() default 14; + + /** + * 瀵煎嚭鏃跺湪excel涓瘡涓垪鐨勫 鍗曚綅涓哄瓧绗� + */ + public double width() default 16; + + /** + * 鏂囧瓧鍚庣紑,濡�% 90 鍙樻垚90% + */ + public String suffix() default ""; + + /** + * 褰撳�间负绌烘椂,瀛楁鐨勯粯璁ゅ�� + */ + public String defaultValue() default ""; + + /** + * 鎻愮ず淇℃伅 + */ + public String prompt() default ""; + + /** + * 璁剧疆鍙兘閫夋嫨涓嶈兘杈撳叆鐨勫垪鍐呭. + */ + public String[] combo() default {}; + + /** + * 鏄惁瀵煎嚭鏁版嵁,搴斿闇�姹�:鏈夋椂鎴戜滑闇�瑕佸鍑轰竴浠芥ā鏉�,杩欐槸鏍囬闇�瑕佷絾鍐呭闇�瑕佺敤鎴锋墜宸ュ~鍐�. + */ + public boolean isExport() default true; + + /** + * 鍙︿竴涓被涓殑灞炴�у悕绉�,鏀寔澶氱骇鑾峰彇,浠ュ皬鏁扮偣闅斿紑 + */ + public String targetAttr() default ""; + + /** + * 瀛楁绫诲瀷锛�0锛氬鍑哄鍏ワ紱1锛氫粎瀵煎嚭锛�2锛氫粎瀵煎叆锛� + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java new file mode 100644 index 0000000..ff22802 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.ruoyi.framework.aspectj.lang.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel娉ㄨВ闆� + * + * @author ruoyi + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + Excel[] value(); +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java new file mode 100644 index 0000000..8388f70 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Log.java @@ -0,0 +1,41 @@ +package com.ruoyi.framework.aspectj.lang.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.aspectj.lang.enums.OperatorType; + +/** + * 鑷畾涔夋搷浣滄棩蹇楄褰曟敞瑙� + * + * @author ruoyi + * + */ +@Target({ ElementType.PARAMETER, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Log +{ + /** + * 妯″潡 + */ + public String title() default ""; + + /** + * 鍔熻兘 + */ + public BusinessType businessType() default BusinessType.OTHER; + + /** + * 鎿嶄綔浜虹被鍒� + */ + public OperatorType operatorType() default OperatorType.MANAGE; + + /** + * 鏄惁淇濆瓨璇锋眰鐨勫弬鏁� + */ + public boolean isSaveRequestData() default true; +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java new file mode 100644 index 0000000..2e1c7af --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessStatus.java @@ -0,0 +1,20 @@ +package com.ruoyi.framework.aspectj.lang.enums; + +/** + * 鎿嶄綔鐘舵�� + * + * @author ruoyi + * + */ +public enum BusinessStatus +{ + /** + * 鎴愬姛 + */ + SUCCESS, + + /** + * 澶辫触 + */ + FAIL, +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java new file mode 100644 index 0000000..2810215 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/BusinessType.java @@ -0,0 +1,59 @@ +package com.ruoyi.framework.aspectj.lang.enums; + +/** + * 涓氬姟鎿嶄綔绫诲瀷 + * + * @author ruoyi + */ +public enum BusinessType +{ + /** + * 鍏跺畠 + */ + OTHER, + + /** + * 鏂板 + */ + INSERT, + + /** + * 淇敼 + */ + UPDATE, + + /** + * 鍒犻櫎 + */ + DELETE, + + /** + * 鎺堟潈 + */ + GRANT, + + /** + * 瀵煎嚭 + */ + EXPORT, + + /** + * 瀵煎叆 + */ + IMPORT, + + /** + * 寮洪�� + */ + FORCE, + + /** + * 鐢熸垚浠g爜 + */ + GENCODE, + + /** + * 娓呯┖鏁版嵁 + */ + CLEAN, +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java new file mode 100644 index 0000000..103cd80 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/DataSourceType.java @@ -0,0 +1,19 @@ +package com.ruoyi.framework.aspectj.lang.enums; + +/** + * 鏁版嵁婧� + * + * @author ruoyi + */ +public enum DataSourceType +{ + /** + * 涓诲簱 + */ + MASTER, + + /** + * 浠庡簱 + */ + SLAVE +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java new file mode 100644 index 0000000..e3d87db --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/enums/OperatorType.java @@ -0,0 +1,24 @@ +package com.ruoyi.framework.aspectj.lang.enums; + +/** + * 鎿嶄綔浜虹被鍒� + * + * @author ruoyi + */ +public enum OperatorType +{ + /** + * 鍏跺畠 + */ + OTHER, + + /** + * 鍚庡彴鐢ㄦ埛 + */ + MANAGE, + + /** + * 鎵嬫満绔敤鎴� + */ + MOBILE +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java new file mode 100644 index 0000000..55de6f7 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/ApplicationConfig.java @@ -0,0 +1,30 @@ +package com.ruoyi.framework.config; + +import java.util.TimeZone; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * 绋嬪簭娉ㄨВ閰嶇疆 + * + * @author ruoyi + */ +@Configuration +// 琛ㄧず閫氳繃aop妗嗘灦鏆撮湶璇ヤ唬鐞嗗璞�,AopContext鑳藉璁块棶 +@EnableAspectJAutoProxy(exposeProxy = true) +// 鎸囧畾瑕佹壂鎻忕殑Mapper绫荤殑鍖呯殑璺緞 +@MapperScan("com.ruoyi.project.**.mapper") +public class ApplicationConfig +{ + /** + * 鏃跺尯閰嶇疆 + */ + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() + { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java new file mode 100644 index 0000000..7a8fd82 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/DruidConfig.java @@ -0,0 +1,126 @@ +package com.ruoyi.framework.config; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.sql.DataSource; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; +import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; +import com.alibaba.druid.util.Utils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.aspectj.lang.enums.DataSourceType; +import com.ruoyi.framework.config.properties.DruidProperties; +import com.ruoyi.framework.datasource.DynamicDataSource; + +/** + * druid 閰嶇疆澶氭暟鎹簮 + * + * @author ruoyi + */ +@Configuration +public class DruidConfig +{ + @Bean + @ConfigurationProperties("spring.datasource.druid.master") + public DataSource masterDataSource(DruidProperties druidProperties) + { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean + @ConfigurationProperties("spring.datasource.druid.slave") + @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true") + public DataSource slaveDataSource(DruidProperties druidProperties) + { + DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); + return druidProperties.dataSource(dataSource); + } + + @Bean(name = "dynamicDataSource") + @Primary + public DynamicDataSource dataSource(DataSource masterDataSource) + { + Map<Object, Object> targetDataSources = new HashMap<>(); + targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource); + setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource"); + return new DynamicDataSource(masterDataSource, targetDataSources); + } + + /** + * 璁剧疆鏁版嵁婧� + * + * @param targetDataSources 澶囬�夋暟鎹簮闆嗗悎 + * @param sourceName 鏁版嵁婧愬悕绉� + * @param beanName bean鍚嶇О + */ + public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName) + { + try + { + DataSource dataSource = SpringUtils.getBean(beanName); + targetDataSources.put(sourceName, dataSource); + } + catch (Exception e) + { + } + } + + /** + * 鍘婚櫎鐩戞帶椤甸潰搴曢儴鐨勫箍鍛� + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") + public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) + { + // 鑾峰彇web鐩戞帶椤甸潰鐨勫弬鏁� + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); + // 鎻愬彇common.js鐨勯厤缃矾寰� + String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; + String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); + final String filePath = "support/http/resources/js/common.js"; + // 鍒涘缓filter杩涜杩囨护 + Filter filter = new Filter() + { + @Override + public void init(javax.servlet.FilterConfig filterConfig) throws ServletException + { + } + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException + { + chain.doFilter(request, response); + // 閲嶇疆缂撳啿鍖猴紝鍝嶅簲澶翠笉浼氳閲嶇疆 + response.resetBuffer(); + // 鑾峰彇common.js + String text = Utils.readFromResource(filePath); + // 姝e垯鏇挎崲banner, 闄ゅ幓搴曢儴鐨勫箍鍛婁俊鎭� + text = text.replaceAll("<a.*?banner\"></a><br/>", ""); + text = text.replaceAll("powered.*?shrek.wang</a>", ""); + response.getWriter().write(text); + } + @Override + public void destroy() + { + } + }; + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + registrationBean.setFilter(filter); + registrationBean.addUrlPatterns(commonJsPattern); + return registrationBean; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java b/ruoyi/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..2f27ed1 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,69 @@ +package com.ruoyi.framework.config; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import com.alibaba.fastjson.parser.ParserConfig; +import org.springframework.util.Assert; +import java.nio.charset.Charset; + +/** + * Redis浣跨敤FastJson搴忓垪鍖� + * + * @author ruoyi + */ +public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> +{ + @SuppressWarnings("unused") + private ObjectMapper objectMapper = new ObjectMapper(); + + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + private Class<T> clazz; + + static + { + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + } + + public FastJson2JsonRedisSerializer(Class<T> clazz) + { + super(); + this.clazz = clazz; + } + + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz); + } + + public void setObjectMapper(ObjectMapper objectMapper) + { + Assert.notNull(objectMapper, "'objectMapper' must not be null"); + this.objectMapper = objectMapper; + } + + protected JavaType getJavaType(Class<?> clazz) + { + return TypeFactory.defaultInstance().constructType(clazz); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java new file mode 100644 index 0000000..478b33c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -0,0 +1,46 @@ +package com.ruoyi.framework.config; + +import java.util.HashMap; +import java.util.Map; +import javax.servlet.DispatcherType; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.xss.XssFilter; + +/** + * Filter閰嶇疆 + * + * @author ruoyi + */ +@Configuration +public class FilterConfig +{ + @Value("${xss.enabled}") + private String enabled; + + @Value("${xss.excludes}") + private String excludes; + + @Value("${xss.urlPatterns}") + private String urlPatterns; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean xssFilterRegistration() + { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); + registration.setName("xssFilter"); + registration.setOrder(Integer.MAX_VALUE); + Map<String, String> initParameters = new HashMap<String, String>(); + initParameters.put("excludes", excludes); + initParameters.put("enabled", enabled); + registration.setInitParameters(initParameters); + return registration; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/GenConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/GenConfig.java new file mode 100644 index 0000000..ef4456b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/GenConfig.java @@ -0,0 +1,66 @@ +package com.ruoyi.framework.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 璇诲彇浠g爜鐢熸垚鐩稿叧閰嶇疆 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "gen") +public class GenConfig +{ + /** 浣滆�� */ + public static String author; + + /** 鐢熸垚鍖呰矾寰� */ + public static String packageName; + + /** 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true */ + public static boolean autoRemovePre; + + /** 琛ㄥ墠缂�(绫诲悕涓嶄細鍖呭惈琛ㄥ墠缂�) */ + public static String tablePrefix; + + public static String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + GenConfig.author = author; + } + + public static String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + GenConfig.packageName = packageName; + } + + public static boolean getAutoRemovePre() + { + return autoRemovePre; + } + + public void setAutoRemovePre(boolean autoRemovePre) + { + GenConfig.autoRemovePre = autoRemovePre; + } + + public static String getTablePrefix() + { + return tablePrefix; + } + + public void setTablePrefix(String tablePrefix) + { + GenConfig.tablePrefix = tablePrefix; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java new file mode 100644 index 0000000..7ecfd9d --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java @@ -0,0 +1,105 @@ +package com.ruoyi.framework.config; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import javax.sql.DataSource; +import org.apache.ibatis.io.VFS; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.util.ClassUtils; + +/** + * Mybatis鏀寔*鍖归厤鎵弿鍖� + * + * @author ruoyi + */ +@Configuration +public class MyBatisConfig +{ + @Autowired + private Environment env; + + static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; + + public static String setTypeAliasesPackage(String typeAliasesPackage) + { + ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); + MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); + List<String> allResult = new ArrayList<String>(); + try + { + for (String aliasesPackage : typeAliasesPackage.split(",")) + { + List<String> result = new ArrayList<String>(); + aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; + Resource[] resources = resolver.getResources(aliasesPackage); + if (resources != null && resources.length > 0) + { + MetadataReader metadataReader = null; + for (Resource resource : resources) + { + if (resource.isReadable()) + { + metadataReader = metadataReaderFactory.getMetadataReader(resource); + try + { + result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); + } + catch (ClassNotFoundException e) + { + e.printStackTrace(); + } + } + } + } + if (result.size() > 0) + { + HashSet<String> hashResult = new HashSet<String>(result); + allResult.addAll(hashResult); + } + } + if (allResult.size() > 0) + { + typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); + } + else + { + throw new RuntimeException("mybatis typeAliasesPackage 璺緞鎵弿閿欒,鍙傛暟typeAliasesPackage:" + typeAliasesPackage + "鏈壘鍒颁换浣曞寘"); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + return typeAliasesPackage; + } + + @Bean + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception + { + String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); + String mapperLocations = env.getProperty("mybatis.mapperLocations"); + typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); + VFS.addImplClass(SpringBootVFS.class); + + final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); + sessionFactory.setDataSource(dataSource); + sessionFactory.setTypeAliasesPackage(typeAliasesPackage); + sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); + return sessionFactory.getObject(); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java new file mode 100644 index 0000000..8eb4fb2 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -0,0 +1,43 @@ +package com.ruoyi.framework.config; + +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * redis閰嶇疆 + * + * @author ruoyi + */ +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport +{ + @Bean + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) + { + RedisTemplate<Object, Object> template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); + + ObjectMapper mapper = new ObjectMapper(); + mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + serializer.setObjectMapper(mapper); + + template.setValueSerializer(serializer); + // 浣跨敤StringRedisSerializer鏉ュ簭鍒楀寲鍜屽弽搴忓垪鍖杛edis鐨刱ey鍊� + template.setKeySerializer(new StringRedisSerializer()); + template.afterPropertiesSet(); + return template; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java new file mode 100644 index 0000000..f1a5168 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -0,0 +1,41 @@ +package com.ruoyi.framework.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 閫氱敤閰嶇疆 + * + * @author ruoyi + */ +@Configuration +public class ResourcesConfig implements WebMvcConfigurer +{ + @Autowired + private RepeatSubmitInterceptor repeatSubmitInterceptor; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) + { + /** 鏈湴鏂囦欢涓婁紶璺緞 */ + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); + + /** swagger閰嶇疆 */ + registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + } + + /** + * 鑷畾涔夋嫤鎴鍒� + */ + @Override + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java new file mode 100644 index 0000000..ed524cd --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java @@ -0,0 +1,116 @@ +package com.ruoyi.framework.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 璇诲彇椤圭洰鐩稿叧閰嶇疆 + * + * @author ruoyi + */ +@Component +@ConfigurationProperties(prefix = "ruoyi") +public class RuoYiConfig +{ + /** 椤圭洰鍚嶇О */ + private String name; + + /** 鐗堟湰 */ + private String version; + + /** 鐗堟潈骞翠唤 */ + private String copyrightYear; + + /** 瀹炰緥婕旂ず寮�鍏� */ + private boolean demoEnabled; + + /** 涓婁紶璺緞 */ + private static String profile; + + /** 鑾峰彇鍦板潃寮�鍏� */ + private static boolean addressEnabled; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getCopyrightYear() + { + return copyrightYear; + } + + public void setCopyrightYear(String copyrightYear) + { + this.copyrightYear = copyrightYear; + } + + public boolean isDemoEnabled() + { + return demoEnabled; + } + + public void setDemoEnabled(boolean demoEnabled) + { + this.demoEnabled = demoEnabled; + } + + public static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + RuoYiConfig.profile = profile; + } + + public static boolean isAddressEnabled() + { + return addressEnabled; + } + + public void setAddressEnabled(boolean addressEnabled) + { + RuoYiConfig.addressEnabled = addressEnabled; + } + + /** + * 鑾峰彇澶村儚涓婁紶璺緞 + */ + public static String getAvatarPath() + { + return getProfile() + "/avatar"; + } + + /** + * 鑾峰彇涓嬭浇璺緞 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } + + /** + * 鑾峰彇涓婁紶璺緞 + */ + public static String getUploadPath() + { + return getProfile() + "/upload"; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java new file mode 100644 index 0000000..bfa248b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -0,0 +1,134 @@ +package com.ruoyi.framework.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; +import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; +import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; + +/** + * spring security閰嶇疆 + * + * @author ruoyi + */ +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter +{ + /** + * 鑷畾涔夌敤鎴疯璇侀�昏緫 + */ + @Autowired + private UserDetailsService userDetailsService; + + /** + * 璁よ瘉澶辫触澶勭悊绫� + */ + @Autowired + private AuthenticationEntryPointImpl unauthorizedHandler; + + /** + * 閫�鍑哄鐞嗙被 + */ + @Autowired + private LogoutSuccessHandlerImpl logoutSuccessHandler; + + /** + * token璁よ瘉杩囨护鍣� + */ + @Autowired + private JwtAuthenticationTokenFilter authenticationTokenFilter; + + /** + * 瑙e喅 鏃犳硶鐩存帴娉ㄥ叆 AuthenticationManager + * + * @return + * @throws Exception + */ + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception + { + return super.authenticationManagerBean(); + } + + /** + * anyRequest | 鍖归厤鎵�鏈夎姹傝矾寰� + * access | SpringEl琛ㄨ揪寮忕粨鏋滀负true鏃跺彲浠ヨ闂� + * anonymous | 鍖垮悕鍙互璁块棶 + * denyAll | 鐢ㄦ埛涓嶈兘璁块棶 + * fullyAuthenticated | 鐢ㄦ埛瀹屽叏璁よ瘉鍙互璁块棶锛堥潪remember-me涓嬭嚜鍔ㄧ櫥褰曪級 + * hasAnyAuthority | 濡傛灉鏈夊弬鏁帮紝鍙傛暟琛ㄧず鏉冮檺锛屽垯鍏朵腑浠讳綍涓�涓潈闄愬彲浠ヨ闂� + * hasAnyRole | 濡傛灉鏈夊弬鏁帮紝鍙傛暟琛ㄧず瑙掕壊锛屽垯鍏朵腑浠讳綍涓�涓鑹插彲浠ヨ闂� + * hasAuthority | 濡傛灉鏈夊弬鏁帮紝鍙傛暟琛ㄧず鏉冮檺锛屽垯鍏舵潈闄愬彲浠ヨ闂� + * hasIpAddress | 濡傛灉鏈夊弬鏁帮紝鍙傛暟琛ㄧずIP鍦板潃锛屽鏋滅敤鎴稩P鍜屽弬鏁板尮閰嶏紝鍒欏彲浠ヨ闂� + * hasRole | 濡傛灉鏈夊弬鏁帮紝鍙傛暟琛ㄧず瑙掕壊锛屽垯鍏惰鑹插彲浠ヨ闂� + * permitAll | 鐢ㄦ埛鍙互浠绘剰璁块棶 + * rememberMe | 鍏佽閫氳繃remember-me鐧诲綍鐨勭敤鎴疯闂� + * authenticated | 鐢ㄦ埛鐧诲綍鍚庡彲璁块棶 + */ + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception + { + httpSecurity + // CRSF绂佺敤锛屽洜涓轰笉浣跨敤session + .csrf().disable() + // 璁よ瘉澶辫触澶勭悊绫� + .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() + // 鍩轰簬token锛屾墍浠ヤ笉闇�瑕乻ession + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + // 杩囨护璇锋眰 + .authorizeRequests() + // 瀵逛簬鐧诲綍login 楠岃瘉鐮乧aptchaImage 鍏佽鍖垮悕璁块棶 + .antMatchers("/login", "/captchaImage").anonymous() + .antMatchers( + HttpMethod.GET, + "/*.html", + "/**/*.html", + "/**/*.css", + "/**/*.js" + ).permitAll() + .antMatchers("/profile/**").anonymous() + .antMatchers("/common/download**").anonymous() + .antMatchers("/swagger-ui.html").anonymous() + .antMatchers("/swagger-resources/**").anonymous() + .antMatchers("/webjars/**").anonymous() + .antMatchers("/*/api-docs").anonymous() + .antMatchers("/druid/**").anonymous() + // 闄や笂闈㈠鐨勬墍鏈夎姹傚叏閮ㄩ渶瑕侀壌鏉冭璇� + .anyRequest().authenticated() + .and() + .headers().frameOptions().disable(); + httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); + // 娣诲姞JWT filter + httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + } + + + /** + * 寮烘暎鍒楀搱甯屽姞瀵嗗疄鐜� + */ + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() + { + return new BCryptPasswordEncoder(); + } + + /** + * 韬唤璁よ瘉鎺ュ彛 + */ + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception + { + auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/ServerConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/ServerConfig.java new file mode 100644 index 0000000..b5b7de3 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/ServerConfig.java @@ -0,0 +1,32 @@ +package com.ruoyi.framework.config; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; +import com.ruoyi.common.utils.ServletUtils; + +/** + * 鏈嶅姟鐩稿叧閰嶇疆 + * + * @author ruoyi + */ +@Component +public class ServerConfig +{ + /** + * 鑾峰彇瀹屾暣鐨勮姹傝矾寰勶紝鍖呮嫭锛氬煙鍚嶏紝绔彛锛屼笂涓嬫枃璁块棶璺緞 + * + * @return 鏈嶅姟鍦板潃 + */ + public String getUrl() + { + HttpServletRequest request = ServletUtils.getRequest(); + return getDomain(request); + } + + public static String getDomain(HttpServletRequest request) + { + StringBuffer url = request.getRequestURL(); + String contextPath = request.getServletContext().getContextPath(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java new file mode 100644 index 0000000..bd60b8f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java @@ -0,0 +1,113 @@ +package com.ruoyi.framework.config; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * Swagger2鐨勬帴鍙i厤缃� + * + * @author ruoyi + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig +{ + /** 绯荤粺鍩虹閰嶇疆 */ + @Autowired + private RuoYiConfig ruoyiConfig; + + /** + * 鍒涘缓API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.SWAGGER_2) + .pathMapping("/dev-api") + // 鐢ㄦ潵鍒涘缓璇PI鐨勫熀鏈俊鎭紝灞曠ず鍦ㄦ枃妗g殑椤甸潰涓紙鑷畾涔夊睍绀虹殑淇℃伅锛� + .apiInfo(apiInfo()) + // 璁剧疆鍝簺鎺ュ彛鏆撮湶缁橲wagger灞曠ず + .select() + // 鎵弿鎵�鏈夋湁娉ㄨВ鐨刟pi锛岀敤杩欑鏂瑰紡鏇寸伒娲� + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 鎵弿鎸囧畾鍖呬腑鐨剆wagger娉ㄨВ + //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) + // 鎵弿鎵�鏈� .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + /* 璁剧疆瀹夊叏妯″紡锛宻wagger鍙互璁剧疆璁块棶token */ + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()); + } + + /** + * 瀹夊叏妯″紡锛岃繖閲屾寚瀹歵oken閫氳繃Authorization澶磋姹傚ご浼犻�� + */ + private List<ApiKey> securitySchemes() + { + List<ApiKey> apiKeyList = new ArrayList<ApiKey>(); + apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); + return apiKeyList; + } + + /** + * 瀹夊叏涓婁笅鏂� + */ + private List<SecurityContext> securityContexts() + { + List<SecurityContext> securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex("^(?!auth).*$")) + .build()); + return securityContexts; + } + + /** + * 榛樿鐨勫畨鍏ㄤ笂寮曠敤 + */ + private List<SecurityReference> defaultAuth() + { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List<SecurityReference> securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); + return securityReferences; + } + + /** + * 娣诲姞鎽樿淇℃伅 + */ + private ApiInfo apiInfo() + { + // 鐢ˋpiInfoBuilder杩涜瀹氬埗 + return new ApiInfoBuilder() + // 璁剧疆鏍囬 + .title("鏍囬锛氳嫢渚濈鐞嗙郴缁焈鎺ュ彛鏂囨。") + // 鎻忚堪 + .description("鎻忚堪锛氱敤浜庣鐞嗛泦鍥㈡棗涓嬪叕鍙哥殑浜哄憳淇℃伅,鍏蜂綋鍖呮嫭XXX,XXX妯″潡...") + // 浣滆�呬俊鎭� + .contact(new Contact(ruoyiConfig.getName(), null, null)) + // 鐗堟湰 + .version("鐗堟湰鍙�:" + ruoyiConfig.getVersion()) + .build(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java new file mode 100644 index 0000000..0d67c22 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java @@ -0,0 +1,62 @@ +package com.ruoyi.framework.config; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import com.ruoyi.common.utils.Threads; + +/** + * 绾跨▼姹犻厤缃� + * + * @author ruoyi + **/ +@Configuration +public class ThreadPoolConfig +{ + // 鏍稿績绾跨▼姹犲ぇ灏� + private int corePoolSize = 50; + + // 鏈�澶у彲鍒涘缓鐨勭嚎绋嬫暟 + private int maxPoolSize = 200; + + // 闃熷垪鏈�澶ч暱搴� + private int queueCapacity = 1000; + + // 绾跨▼姹犵淮鎶ょ嚎绋嬫墍鍏佽鐨勭┖闂叉椂闂� + private int keepAliveSeconds = 300; + + @Bean(name = "threadPoolTaskExecutor") + public ThreadPoolTaskExecutor threadPoolTaskExecutor() + { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setMaxPoolSize(maxPoolSize); + executor.setCorePoolSize(corePoolSize); + executor.setQueueCapacity(queueCapacity); + executor.setKeepAliveSeconds(keepAliveSeconds); + // 绾跨▼姹犲鎷掔粷浠诲姟(鏃犵嚎绋嬪彲鐢�)鐨勫鐞嗙瓥鐣� + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + return executor; + } + + /** + * 鎵ц鍛ㄦ湡鎬ф垨瀹氭椂浠诲姟 + */ + @Bean(name = "scheduledExecutorService") + protected ScheduledExecutorService scheduledExecutorService() + { + return new ScheduledThreadPoolExecutor(corePoolSize, + new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) + { + @Override + protected void afterExecute(Runnable r, Throwable t) + { + super.afterExecute(r, t); + Threads.printException(r, t); + } + }; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java new file mode 100644 index 0000000..84f7e00 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java @@ -0,0 +1,77 @@ +package com.ruoyi.framework.config.properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import com.alibaba.druid.pool.DruidDataSource; + +/** + * druid 閰嶇疆灞炴�� + * + * @author ruoyi + */ +@Configuration +public class DruidProperties +{ + @Value("${spring.datasource.druid.initialSize}") + private int initialSize; + + @Value("${spring.datasource.druid.minIdle}") + private int minIdle; + + @Value("${spring.datasource.druid.maxActive}") + private int maxActive; + + @Value("${spring.datasource.druid.maxWait}") + private int maxWait; + + @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}") + private int timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}") + private int minEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}") + private int maxEvictableIdleTimeMillis; + + @Value("${spring.datasource.druid.validationQuery}") + private String validationQuery; + + @Value("${spring.datasource.druid.testWhileIdle}") + private boolean testWhileIdle; + + @Value("${spring.datasource.druid.testOnBorrow}") + private boolean testOnBorrow; + + @Value("${spring.datasource.druid.testOnReturn}") + private boolean testOnReturn; + + public DruidDataSource dataSource(DruidDataSource datasource) + { + /** 閰嶇疆鍒濆鍖栧ぇ灏忋�佹渶灏忋�佹渶澶� */ + datasource.setInitialSize(initialSize); + datasource.setMaxActive(maxActive); + datasource.setMinIdle(minIdle); + + /** 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂� */ + datasource.setMaxWait(maxWait); + + /** 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣 */ + datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + + /** 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忋�佹渶澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 */ + datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); + + /** + * 鐢ㄦ潵妫�娴嬭繛鎺ユ槸鍚︽湁鏁堢殑sql锛岃姹傛槸涓�涓煡璇㈣鍙ワ紝甯哥敤select 'x'銆傚鏋渧alidationQuery涓簄ull锛宼estOnBorrow銆乼estOnReturn銆乼estWhileIdle閮戒笉浼氳捣浣滅敤銆� + */ + datasource.setValidationQuery(validationQuery); + /** 寤鸿閰嶇疆涓簍rue锛屼笉褰卞搷鎬ц兘锛屽苟涓斾繚璇佸畨鍏ㄦ�с�傜敵璇疯繛鎺ョ殑鏃跺�欐娴嬶紝濡傛灉绌洪棽鏃堕棿澶т簬timeBetweenEvictionRunsMillis锛屾墽琛寁alidationQuery妫�娴嬭繛鎺ユ槸鍚︽湁鏁堛�� */ + datasource.setTestWhileIdle(testWhileIdle); + /** 鐢宠杩炴帴鏃舵墽琛寁alidationQuery妫�娴嬭繛鎺ユ槸鍚︽湁鏁堬紝鍋氫簡杩欎釜閰嶇疆浼氶檷浣庢�ц兘銆� */ + datasource.setTestOnBorrow(testOnBorrow); + /** 褰掕繕杩炴帴鏃舵墽琛寁alidationQuery妫�娴嬭繛鎺ユ槸鍚︽湁鏁堬紝鍋氫簡杩欎釜閰嶇疆浼氶檷浣庢�ц兘銆� */ + datasource.setTestOnReturn(testOnReturn); + return datasource; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java b/ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java new file mode 100644 index 0000000..e70b8cf --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java @@ -0,0 +1,26 @@ +package com.ruoyi.framework.datasource; + +import java.util.Map; +import javax.sql.DataSource; +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 鍔ㄦ�佹暟鎹簮 + * + * @author ruoyi + */ +public class DynamicDataSource extends AbstractRoutingDataSource +{ + public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) + { + super.setDefaultTargetDataSource(defaultTargetDataSource); + super.setTargetDataSources(targetDataSources); + super.afterPropertiesSet(); + } + + @Override + protected Object determineCurrentLookupKey() + { + return DynamicDataSourceContextHolder.getDataSourceType(); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java b/ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java new file mode 100644 index 0000000..3572db9 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java @@ -0,0 +1,45 @@ +package com.ruoyi.framework.datasource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 鏁版嵁婧愬垏鎹㈠鐞� + * + * @author ruoyi + */ +public class DynamicDataSourceContextHolder +{ + public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); + + /** + * 浣跨敤ThreadLocal缁存姢鍙橀噺锛孴hreadLocal涓烘瘡涓娇鐢ㄨ鍙橀噺鐨勭嚎绋嬫彁渚涚嫭绔嬬殑鍙橀噺鍓湰锛� + * 鎵�浠ユ瘡涓�涓嚎绋嬮兘鍙互鐙珛鍦版敼鍙樿嚜宸辩殑鍓湰锛岃�屼笉浼氬奖鍝嶅叾瀹冪嚎绋嬫墍瀵瑰簲鐨勫壇鏈�� + */ + private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 璁剧疆鏁版嵁婧愮殑鍙橀噺 + */ + public static void setDataSourceType(String dsType) + { + log.info("鍒囨崲鍒皗}鏁版嵁婧�", dsType); + CONTEXT_HOLDER.set(dsType); + } + + /** + * 鑾峰緱鏁版嵁婧愮殑鍙橀噺 + */ + public static String getDataSourceType() + { + return CONTEXT_HOLDER.get(); + } + + /** + * 娓呯┖鏁版嵁婧愬彉閲� + */ + public static void clearDataSourceType() + { + CONTEXT_HOLDER.remove(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java new file mode 100644 index 0000000..088798d --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java @@ -0,0 +1,55 @@ +package com.ruoyi.framework.interceptor; + +import java.lang.reflect.Method; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.framework.interceptor.annotation.RepeatSubmit; +import com.ruoyi.framework.web.domain.AjaxResult; + +/** + * 闃叉閲嶅鎻愪氦鎷︽埅鍣� + * + * @author ruoyi + */ +@Component +public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter +{ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (handler instanceof HandlerMethod) + { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + if (annotation != null) + { + if (this.isRepeatSubmit(request)) + { + AjaxResult ajaxResult = AjaxResult.error("涓嶅厑璁搁噸澶嶆彁浜わ紝璇风◢鍚庡啀璇�"); + ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult)); + return false; + } + } + return true; + } + else + { + return super.preHandle(request, response, handler); + } + } + + /** + * 楠岃瘉鏄惁閲嶅鎻愪氦鐢卞瓙绫诲疄鐜板叿浣撶殑闃查噸澶嶆彁浜ょ殑瑙勫垯 + * + * @param httpServletRequest + * @return + * @throws Exception + */ + public abstract boolean isRepeatSubmit(HttpServletRequest request); +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/interceptor/annotation/RepeatSubmit.java b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/annotation/RepeatSubmit.java new file mode 100644 index 0000000..0fbd73b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/annotation/RepeatSubmit.java @@ -0,0 +1,23 @@ +package com.ruoyi.framework.interceptor.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 鑷畾涔夋敞瑙i槻姝㈣〃鍗曢噸澶嶆彁浜� + * + * @author ruoyi + * + */ +@Inherited +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit +{ + +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java new file mode 100644 index 0000000..9d915c6 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -0,0 +1,94 @@ +package com.ruoyi.framework.interceptor.impl; + +import java.util.HashMap; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; + +/** + * 鍒ゆ柇璇锋眰url鍜屾暟鎹槸鍚﹀拰涓婁竴娆$浉鍚岋紝 + * 濡傛灉鍜屼笂娆$浉鍚岋紝鍒欐槸閲嶅鎻愪氦琛ㄥ崟銆� 鏈夋晥鏃堕棿涓�10绉掑唴銆� + * + * @author ruoyi + */ +@Component +public class SameUrlDataInterceptor extends RepeatSubmitInterceptor +{ + public final String REPEAT_PARAMS = "repeatParams"; + + public final String REPEAT_TIME = "repeatTime"; + + public final String SESSION_REPEAT_KEY = "repeatData"; + + /** + * 闂撮殧鏃堕棿锛屽崟浣�:绉� 榛樿10绉� + * + * 涓ゆ鐩稿悓鍙傛暟鐨勮姹傦紝濡傛灉闂撮殧鏃堕棿澶т簬璇ュ弬鏁帮紝绯荤粺涓嶄細璁ゅ畾涓洪噸澶嶆彁浜ょ殑鏁版嵁 + */ + private int intervalTime = 10; + + public void setIntervalTime(int intervalTime) + { + this.intervalTime = intervalTime; + } + + @SuppressWarnings("unchecked") + @Override + public boolean isRepeatSubmit(HttpServletRequest request) + { + // 鏈鍙傛暟鍙婄郴缁熸椂闂� + String nowParams = JSONObject.toJSONString(request.getParameterMap()); + Map<String, Object> nowDataMap = new HashMap<String, Object>(); + nowDataMap.put(REPEAT_PARAMS, nowParams); + nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); + + // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀緎ession鐨刱ey鍊硷級 + String url = request.getRequestURI(); + + HttpSession session = request.getSession(); + Object sessionObj = session.getAttribute(SESSION_REPEAT_KEY); + if (sessionObj != null) + { + Map<String, Object> sessionMap = (Map<String, Object>) sessionObj; + if (sessionMap.containsKey(url)) + { + Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url); + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap)) + { + return true; + } + } + } + Map<String, Object> sessionMap = new HashMap<String, Object>(); + sessionMap.put(url, nowDataMap); + session.setAttribute(SESSION_REPEAT_KEY, sessionMap); + return false; + } + + /** + * 鍒ゆ柇鍙傛暟鏄惁鐩稿悓 + */ + private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) + { + String nowParams = (String) nowMap.get(REPEAT_PARAMS); + String preParams = (String) preMap.get(REPEAT_PARAMS); + return nowParams.equals(preParams); + } + + /** + * 鍒ゆ柇涓ゆ闂撮殧鏃堕棿 + */ + private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap) + { + long time1 = (Long) nowMap.get(REPEAT_TIME); + long time2 = (Long) preMap.get(REPEAT_TIME); + if ((time1 - time2) < (this.intervalTime * 1000)) + { + return true; + } + return false; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/manager/AsyncManager.java b/ruoyi/src/main/java/com/ruoyi/framework/manager/AsyncManager.java new file mode 100644 index 0000000..7387a02 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/manager/AsyncManager.java @@ -0,0 +1,55 @@ +package com.ruoyi.framework.manager; + +import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import com.ruoyi.common.utils.Threads; +import com.ruoyi.common.utils.spring.SpringUtils; + +/** + * 寮傛浠诲姟绠$悊鍣� + * + * @author ruoyi + */ +public class AsyncManager +{ + /** + * 鎿嶄綔寤惰繜10姣 + */ + private final int OPERATE_DELAY_TIME = 10; + + /** + * 寮傛鎿嶄綔浠诲姟璋冨害绾跨▼姹� + */ + private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); + + /** + * 鍗曚緥妯″紡 + */ + private AsyncManager(){} + + private static AsyncManager me = new AsyncManager(); + + public static AsyncManager me() + { + return me; + } + + /** + * 鎵ц浠诲姟 + * + * @param task 浠诲姟 + */ + public void execute(TimerTask task) + { + executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); + } + + /** + * 鍋滄浠诲姟绾跨▼姹� + */ + public void shutdown() + { + Threads.shutdownAndAwaitTermination(executor); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java b/ruoyi/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java new file mode 100644 index 0000000..e36ca3c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java @@ -0,0 +1,39 @@ +package com.ruoyi.framework.manager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import javax.annotation.PreDestroy; + +/** + * 纭繚搴旂敤閫�鍑烘椂鑳藉叧闂悗鍙扮嚎绋� + * + * @author ruoyi + */ +@Component +public class ShutdownManager +{ + private static final Logger logger = LoggerFactory.getLogger("sys-user"); + + @PreDestroy + public void destroy() + { + shutdownAsyncManager(); + } + + /** + * 鍋滄寮傛鎵ц浠诲姟 + */ + private void shutdownAsyncManager() + { + try + { + logger.info("====鍏抽棴鍚庡彴浠诲姟浠诲姟绾跨▼姹�===="); + AsyncManager.me().shutdown(); + } + catch (Exception e) + { + logger.error(e.getMessage(), e); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java b/ruoyi/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java new file mode 100644 index 0000000..88633ad --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java @@ -0,0 +1,101 @@ +package com.ruoyi.framework.manager.factory; + +import java.util.TimerTask; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.LogUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.ip.AddressUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.project.monitor.domain.SysLogininfor; +import com.ruoyi.project.monitor.domain.SysOperLog; +import com.ruoyi.project.monitor.service.ISysLogininforService; +import com.ruoyi.project.monitor.service.ISysOperLogService; +import eu.bitwalker.useragentutils.UserAgent; + +/** + * 寮傛宸ュ巶锛堜骇鐢熶换鍔$敤锛� + * + * @author ruoyi + */ +public class AsyncFactory +{ + private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user"); + + /** + * 璁板綍鐧婚檰淇℃伅 + * + * @param username 鐢ㄦ埛鍚� + * @param status 鐘舵�� + * @param message 娑堟伅 + * @param args 鍒楄〃 + * @return 浠诲姟task + */ + public static TimerTask recordLogininfor(final String username, final String status, final String message, + final Object... args) + { + final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + final String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + return new TimerTask() + { + @Override + public void run() + { + String address = AddressUtils.getRealAddressByIP(ip); + StringBuilder s = new StringBuilder(); + s.append(LogUtils.getBlock(ip)); + s.append(address); + s.append(LogUtils.getBlock(username)); + s.append(LogUtils.getBlock(status)); + s.append(LogUtils.getBlock(message)); + // 鎵撳嵃淇℃伅鍒版棩蹇� + sys_user_logger.info(s.toString(), args); + // 鑾峰彇瀹㈡埛绔搷浣滅郴缁� + String os = userAgent.getOperatingSystem().getName(); + // 鑾峰彇瀹㈡埛绔祻瑙堝櫒 + String browser = userAgent.getBrowser().getName(); + // 灏佽瀵硅薄 + SysLogininfor logininfor = new SysLogininfor(); + logininfor.setUserName(username); + logininfor.setIpaddr(ip); + logininfor.setLoginLocation(address); + logininfor.setBrowser(browser); + logininfor.setOs(os); + logininfor.setMsg(message); + // 鏃ュ織鐘舵�� + if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) + { + logininfor.setStatus(Constants.SUCCESS); + } + else if (Constants.LOGIN_FAIL.equals(status)) + { + logininfor.setStatus(Constants.FAIL); + } + // 鎻掑叆鏁版嵁 + SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor); + } + }; + } + + /** + * 鎿嶄綔鏃ュ織璁板綍 + * + * @param operLog 鎿嶄綔鏃ュ織淇℃伅 + * @return 浠诲姟task + */ + public static TimerTask recordOper(final SysOperLog operLog) + { + return new TimerTask() + { + @Override + public void run() + { + // 杩滅▼鏌ヨ鎿嶄綔鍦扮偣 + operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); + SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog); + } + }; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java b/ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java new file mode 100644 index 0000000..1bc6050 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java @@ -0,0 +1,207 @@ +package com.ruoyi.framework.redis; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.ListOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Component; + +/** + * spring redis 宸ュ叿绫� + * + * @author ruoyi + **/ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@Component +public class RedisCache +{ + @Autowired + public RedisTemplate redisTemplate; + + /** + * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛� + * + * @param key 缂撳瓨鐨勯敭鍊� + * @param value 缂撳瓨鐨勫�� + * @return 缂撳瓨鐨勫璞� + */ + public <T> ValueOperations<String, T> setCacheObject(String key, T value) + { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + operation.set(key, value); + return operation; + } + + /** + * 缂撳瓨鍩烘湰鐨勫璞★紝Integer銆丼tring銆佸疄浣撶被绛� + * + * @param key 缂撳瓨鐨勯敭鍊� + * @param value 缂撳瓨鐨勫�� + * @param timeout 鏃堕棿 + * @param timeUnit 鏃堕棿棰楃矑搴� + * @return 缂撳瓨鐨勫璞� + */ + public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) + { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + operation.set(key, value, timeout, timeUnit); + return operation; + } + + /** + * 鑾峰緱缂撳瓨鐨勫熀鏈璞°�� + * + * @param key 缂撳瓨閿�� + * @return 缂撳瓨閿�煎搴旂殑鏁版嵁 + */ + public <T> T getCacheObject(String key) + { + ValueOperations<String, T> operation = redisTemplate.opsForValue(); + return operation.get(key); + } + + /** + * 鍒犻櫎鍗曚釜瀵硅薄 + * + * @param key + */ + public void deleteObject(String key) + { + redisTemplate.delete(key); + } + + /** + * 鍒犻櫎闆嗗悎瀵硅薄 + * + * @param collection + */ + public void deleteObject(Collection collection) + { + redisTemplate.delete(collection); + } + + /** + * 缂撳瓨List鏁版嵁 + * + * @param key 缂撳瓨鐨勯敭鍊� + * @param dataList 寰呯紦瀛樼殑List鏁版嵁 + * @return 缂撳瓨鐨勫璞� + */ + public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) + { + ListOperations listOperation = redisTemplate.opsForList(); + if (null != dataList) + { + int size = dataList.size(); + for (int i = 0; i < size; i++) + { + listOperation.leftPush(key, dataList.get(i)); + } + } + return listOperation; + } + + /** + * 鑾峰緱缂撳瓨鐨刲ist瀵硅薄 + * + * @param key 缂撳瓨鐨勯敭鍊� + * @return 缂撳瓨閿�煎搴旂殑鏁版嵁 + */ + public <T> List<T> getCacheList(String key) + { + List<T> dataList = new ArrayList<T>(); + ListOperations<String, T> listOperation = redisTemplate.opsForList(); + Long size = listOperation.size(key); + + for (int i = 0; i < size; i++) + { + dataList.add(listOperation.index(key, i)); + } + return dataList; + } + + /** + * 缂撳瓨Set + * + * @param key 缂撳瓨閿�� + * @param dataSet 缂撳瓨鐨勬暟鎹� + * @return 缂撳瓨鏁版嵁鐨勫璞� + */ + public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) + { + BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key); + Iterator<T> it = dataSet.iterator(); + while (it.hasNext()) + { + setOperation.add(it.next()); + } + return setOperation; + } + + /** + * 鑾峰緱缂撳瓨鐨剆et + * + * @param key + * @return + */ + public <T> Set<T> getCacheSet(String key) + { + Set<T> dataSet = new HashSet<T>(); + BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key); + dataSet = operation.members(); + return dataSet; + } + + /** + * 缂撳瓨Map + * + * @param key + * @param dataMap + * @return + */ + public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) + { + HashOperations hashOperations = redisTemplate.opsForHash(); + if (null != dataMap) + { + for (Map.Entry<String, T> entry : dataMap.entrySet()) + { + hashOperations.put(key, entry.getKey(), entry.getValue()); + } + } + return hashOperations; + } + + /** + * 鑾峰緱缂撳瓨鐨凪ap + * + * @param key + * @return + */ + public <T> Map<String, T> getCacheMap(String key) + { + Map<String, T> map = redisTemplate.opsForHash().entries(key); + return map; + } + + /** + * 鑾峰緱缂撳瓨鐨勫熀鏈璞″垪琛� + * + * @param pattern 瀛楃涓插墠缂� + * @return 瀵硅薄鍒楄〃 + */ + public Collection<String> keys(String pattern) + { + return redisTemplate.keys(pattern); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java b/ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java new file mode 100644 index 0000000..e6b997e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java @@ -0,0 +1,228 @@ +package com.ruoyi.framework.security; + +import java.util.Collection; +import java.util.Set; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.ruoyi.project.system.domain.SysUser; + +/** + * 鐧诲綍鐢ㄦ埛韬唤鏉冮檺 + * + * @author ruoyi + */ +public class LoginUser implements UserDetails +{ + private static final long serialVersionUID = 1L; + + /** + * 鐢ㄦ埛鍞竴鏍囪瘑 + */ + private String token; + + /** + * 鐧婚檰鏃堕棿 + */ + private Long loginTime; + + /** + * 杩囨湡鏃堕棿 + */ + private Long expireTime; + + /** + * 鐧诲綍IP鍦板潃 + */ + private String ipaddr; + + /** + * 鐧诲綍鍦扮偣 + */ + private String loginLocation; + + /** + * 娴忚鍣ㄧ被鍨� + */ + private String browser; + + /** + * 鎿嶄綔绯荤粺 + */ + private String os; + + /** + * 鏉冮檺鍒楄〃 + */ + private Set<String> permissions; + + /** + * 鐢ㄦ埛淇℃伅 + */ + private SysUser user; + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } + + public LoginUser() + { + } + + public LoginUser(SysUser user, Set<String> permissions) + { + this.user = user; + this.permissions = permissions; + } + + @JsonIgnore + @Override + public String getPassword() + { + return user.getPassword(); + } + + @Override + public String getUsername() + { + return user.getUserName(); + } + + /** + * 璐︽埛鏄惁鏈繃鏈�,杩囨湡鏃犳硶楠岃瘉 + */ + @JsonIgnore + @Override + public boolean isAccountNonExpired() + { + return true; + } + + /** + * 鎸囧畾鐢ㄦ埛鏄惁瑙i攣,閿佸畾鐨勭敤鎴锋棤娉曡繘琛岃韩浠介獙璇� + * + * @return + */ + @JsonIgnore + @Override + public boolean isAccountNonLocked() + { + return true; + } + + /** + * 鎸囩ず鏄惁宸茶繃鏈熺殑鐢ㄦ埛鐨勫嚟鎹�(瀵嗙爜),杩囨湡鐨勫嚟鎹槻姝㈣璇� + * + * @return + */ + @JsonIgnore + @Override + public boolean isCredentialsNonExpired() + { + return true; + } + + /** + * 鏄惁鍙敤 ,绂佺敤鐨勭敤鎴蜂笉鑳借韩浠介獙璇� + * + * @return + */ + @JsonIgnore + @Override + public boolean isEnabled() + { + return true; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Long expireTime) + { + this.expireTime = expireTime; + } + + public Set<String> getPermissions() + { + return permissions; + } + + public void setPermissions(Set<String> permissions) + { + this.permissions = permissions; + } + + public SysUser getUser() + { + return user; + } + + public void setUser(SysUser user) + { + this.user = user; + } + + @Override + public Collection<? extends GrantedAuthority> getAuthorities() + { + return null; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java b/ruoyi/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..fa8a654 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -0,0 +1,44 @@ +package com.ruoyi.framework.security.filter; + +import java.io.IOException; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; + +/** + * token杩囨护鍣� 楠岃瘉token鏈夋晥鎬� + * + * @author ruoyi + */ +@Component +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter +{ + @Autowired + private TokenService tokenService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) + { + tokenService.verifyToken(loginUser); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + chain.doFilter(request, response); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java b/ruoyi/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java new file mode 100644 index 0000000..f20bf2e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java @@ -0,0 +1,34 @@ +package com.ruoyi.framework.security.handle; + +import java.io.IOException; +import java.io.Serializable; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.domain.AjaxResult; + +/** + * 璁よ瘉澶辫触澶勭悊绫� 杩斿洖鏈巿鏉� + * + * @author ruoyi + */ +@Component +public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable +{ + private static final long serialVersionUID = -8970718410437077606L; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) + throws IOException + { + int code = HttpStatus.UNAUTHORIZED; + String msg = StringUtils.format("璇锋眰璁块棶锛歿}锛岃璇佸け璐ワ紝鏃犳硶璁块棶绯荤粺璧勬簮", request.getRequestURI()); + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java b/ruoyi/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java new file mode 100644 index 0000000..a41cd0a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java @@ -0,0 +1,53 @@ +package com.ruoyi.framework.security.handle; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.framework.web.domain.AjaxResult; + +/** + * 鑷畾涔夐��鍑哄鐞嗙被 杩斿洖鎴愬姛 + * + * @author ruoyi + */ +@Configuration +public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler +{ + @Autowired + private TokenService tokenService; + + /** + * 閫�鍑哄鐞� + * + * @return + */ + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException + { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) + { + String userName = loginUser.getUsername(); + // 鍒犻櫎鐢ㄦ埛缂撳瓨璁板綍 + tokenService.delLoginUser(loginUser.getToken()); + // 璁板綍鐢ㄦ埛閫�鍑烘棩蹇� + AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "閫�鍑烘垚鍔�")); + } + ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "閫�鍑烘垚鍔�"))); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/service/PermissionService.java b/ruoyi/src/main/java/com/ruoyi/framework/security/service/PermissionService.java new file mode 100644 index 0000000..be68cc2 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/service/PermissionService.java @@ -0,0 +1,169 @@ +package com.ruoyi.framework.security.service; + +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.project.system.domain.SysRole; + +/** + * RuoYi棣栧垱 鑷畾涔夋潈闄愬疄鐜帮紝ss鍙栬嚜SpringSecurity棣栧瓧姣� + * + * @author ruoyi + */ +@Service("ss") +public class PermissionService +{ + /** 鎵�鏈夋潈闄愭爣璇� */ + private static final String ALL_PERMISSION = "*:*:*"; + + /** 绠$悊鍛樿鑹叉潈闄愭爣璇� */ + private static final String SUPER_ADMIN = "admin"; + + private static final String ROLE_DELIMETER = ","; + + private static final String PERMISSION_DELIMETER = ","; + + @Autowired + private TokenService tokenService; + + /** + * 楠岃瘉鐢ㄦ埛鏄惁鍏峰鏌愭潈闄� + * + * @param permission 鏉冮檺瀛楃涓� + * @return 鐢ㄦ埛鏄惁鍏峰鏌愭潈闄� + */ + public boolean hasPermi(String permission) + { + if (StringUtils.isEmpty(permission)) + { + return false; + } + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + return hasPermissions(loginUser.getPermissions(), permission); + } + + /** + * 楠岃瘉鐢ㄦ埛鏄惁涓嶅叿澶囨煇鏉冮檺锛屼笌 hasPermi閫昏緫鐩稿弽 + * + * @param permission 鏉冮檺瀛楃涓� + * @return 鐢ㄦ埛鏄惁涓嶅叿澶囨煇鏉冮檺 + */ + public boolean lacksPermi(String permission) + { + return hasPermi(permission) != true; + } + + /** + * 楠岃瘉鐢ㄦ埛鏄惁鍏锋湁浠ヤ笅浠绘剰涓�涓潈闄� + * + * @param permissions 浠� PERMISSION_NAMES_DELIMETER 涓哄垎闅旂鐨勬潈闄愬垪琛� + * @return 鐢ㄦ埛鏄惁鍏锋湁浠ヤ笅浠绘剰涓�涓潈闄� + */ + public boolean hasAnyPermi(String permissions) + { + if (StringUtils.isEmpty(permissions)) + { + return false; + } + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) + { + return false; + } + Set<String> authorities = loginUser.getPermissions(); + for (String permission : permissions.split(PERMISSION_DELIMETER)) + { + if (permission != null && hasPermissions(authorities, permission)) + { + return true; + } + } + return false; + } + + /** + * 鍒ゆ柇鐢ㄦ埛鏄惁鎷ユ湁鏌愪釜瑙掕壊 + * + * @param role 瑙掕壊瀛楃涓� + * @return 鐢ㄦ埛鏄惁鍏峰鏌愯鑹� + */ + public boolean hasRole(String role) + { + if (StringUtils.isEmpty(role)) + { + return false; + } + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (SysRole sysRole : loginUser.getUser().getRoles()) + { + String roleKey = sysRole.getRoleKey(); + if (SUPER_ADMIN.contains(roleKey) || roleKey.contains(StringUtils.trim(role))) + { + return true; + } + } + return false; + } + + /** + * 楠岃瘉鐢ㄦ埛鏄惁涓嶅叿澶囨煇瑙掕壊锛屼笌 isRole閫昏緫鐩稿弽銆� + * + * @param role 瑙掕壊鍚嶇О + * @return 鐢ㄦ埛鏄惁涓嶅叿澶囨煇瑙掕壊 + */ + public boolean lacksRole(String role) + { + return hasRole(role) != true; + } + + /** + * 楠岃瘉鐢ㄦ埛鏄惁鍏锋湁浠ヤ笅浠绘剰涓�涓鑹� + * + * @param roles 浠� ROLE_NAMES_DELIMETER 涓哄垎闅旂鐨勮鑹插垪琛� + * @return 鐢ㄦ埛鏄惁鍏锋湁浠ヤ笅浠绘剰涓�涓鑹� + */ + public boolean hasAnyRoles(String roles) + { + if (StringUtils.isEmpty(roles)) + { + return false; + } + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) + { + return false; + } + for (String role : roles.split(ROLE_DELIMETER)) + { + if (hasRole(role)) + { + return true; + } + } + return false; + } + + /** + * 鍒ゆ柇鏄惁鍖呭惈鏉冮檺 + * + * @param permissions 鏉冮檺鍒楄〃 + * @param permission 鏉冮檺瀛楃涓� + * @return 鐢ㄦ埛鏄惁鍏峰鏌愭潈闄� + */ + private boolean hasPermissions(Set<String> permissions, String permission) + { + return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/service/SysLoginService.java b/ruoyi/src/main/java/com/ruoyi/framework/security/service/SysLoginService.java new file mode 100644 index 0000000..3bb1155 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/service/SysLoginService.java @@ -0,0 +1,88 @@ +package com.ruoyi.framework.security.service; + +import javax.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.exception.user.CaptchaException; +import com.ruoyi.common.exception.user.CaptchaExpireException; +import com.ruoyi.common.exception.user.UserPasswordNotMatchException; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.redis.RedisCache; +import com.ruoyi.framework.security.LoginUser; + +/** + * 鐧诲綍鏍¢獙鏂规硶 + * + * @author ruoyi + */ +@Component +public class SysLoginService +{ + @Autowired + private TokenService tokenService; + + @Resource + private AuthenticationManager authenticationManager; + + @Autowired + private RedisCache redisCache; + + /** + * 鐧诲綍楠岃瘉 + * + * @param username 鐢ㄦ埛鍚� + * @param password 瀵嗙爜 + * @param captcha 楠岃瘉鐮� + * @param uuid 鍞竴鏍囪瘑 + * @return 缁撴灉 + */ + public String login(String username, String password, String code, String uuid) + { + String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; + String captcha = redisCache.getCacheObject(verifyKey); + redisCache.deleteObject(verifyKey); + if (captcha == null) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); + throw new CaptchaExpireException(); + } + if (!code.equalsIgnoreCase(captcha)) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); + throw new CaptchaException(); + } + // 鐢ㄦ埛楠岃瘉 + Authentication authentication = null; + try + { + // 璇ユ柟娉曚細鍘昏皟鐢║serDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager + .authenticate(new UsernamePasswordAuthenticationToken(username, password)); + } + catch (Exception e) + { + if (e instanceof BadCredentialsException) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); + throw new CustomException(e.getMessage()); + } + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + // 鐢熸垚token + return tokenService.createToken(loginUser); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/service/SysPermissionService.java b/ruoyi/src/main/java/com/ruoyi/framework/security/service/SysPermissionService.java new file mode 100644 index 0000000..dfa26e2 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/service/SysPermissionService.java @@ -0,0 +1,66 @@ +package com.ruoyi.framework.security.service; + +import java.util.HashSet; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.service.ISysMenuService; +import com.ruoyi.project.system.service.ISysRoleService; + +/** + * 鐢ㄦ埛鏉冮檺澶勭悊 + * + * @author ruoyi + */ +@Component +public class SysPermissionService +{ + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysMenuService menuService; + + /** + * 鑾峰彇瑙掕壊鏁版嵁鏉冮檺 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 瑙掕壊鏉冮檺淇℃伅 + */ + public Set<String> getRolePermission(SysUser user) + { + Set<String> roles = new HashSet<String>(); + // 绠$悊鍛樻嫢鏈夋墍鏈夋潈闄� + if (user.isAdmin()) + { + roles.add("admin"); + } + else + { + roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); + } + return roles; + } + + /** + * 鑾峰彇鑿滃崟鏁版嵁鏉冮檺 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 鑿滃崟鏉冮檺淇℃伅 + */ + public Set<String> getMenuPermission(SysUser user) + { + Set<String> roles = new HashSet<String>(); + // 绠$悊鍛樻嫢鏈夋墍鏈夋潈闄� + if (user.isAdmin()) + { + roles.add("*:*:*"); + } + else + { + roles.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); + } + return roles; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java b/ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java new file mode 100644 index 0000000..ed427b3 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java @@ -0,0 +1,220 @@ +package com.ruoyi.framework.security.service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.IdUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.AddressUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.redis.RedisCache; +import com.ruoyi.framework.security.LoginUser; +import eu.bitwalker.useragentutils.UserAgent; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * token楠岃瘉澶勭悊 + * + * @author ruoyi + */ +@Component +public class TokenService +{ + // 浠ょ墝鑷畾涔夋爣璇� + @Value("${token.header}") + private String header; + + // 浠ょ墝绉橀挜 + @Value("${token.secret}") + private String secret; + + // 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛� + @Value("${token.expireTime}") + private int expireTime; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; + + @Autowired + private RedisCache redisCache; + + /** + * 鑾峰彇鐢ㄦ埛韬唤淇℃伅 + * + * @return 鐢ㄦ埛淇℃伅 + */ + public LoginUser getLoginUser(HttpServletRequest request) + { + // 鑾峰彇璇锋眰鎼哄甫鐨勪护鐗� + String token = getToken(request); + if (StringUtils.isNotEmpty(token)) + { + Claims claims = parseToken(token); + // 瑙f瀽瀵瑰簲鐨勬潈闄愪互鍙婄敤鎴蜂俊鎭� + String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); + String userKey = getTokenKey(uuid); + LoginUser user = redisCache.getCacheObject(userKey); + return user; + } + return null; + } + + /** + * 璁剧疆鐢ㄦ埛韬唤淇℃伅 + */ + public void setLoginUser(LoginUser loginUser) + { + if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) + { + String userKey = getTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser); + } + } + + /** + * 鍒犻櫎鐢ㄦ埛韬唤淇℃伅 + */ + public void delLoginUser(String token) + { + if (StringUtils.isNotEmpty(token)) + { + String userKey = getTokenKey(token); + redisCache.deleteObject(userKey); + } + } + + /** + * 鍒涘缓浠ょ墝 + * + * @param loginUser 鐢ㄦ埛淇℃伅 + * @return 浠ょ墝 + */ + public String createToken(LoginUser loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + setUserAgent(loginUser); + refreshToken(loginUser); + + Map<String, Object> claims = new HashMap<>(); + claims.put(Constants.LOGIN_USER_KEY, token); + return createToken(claims); + } + + /** + * 楠岃瘉浠ょ墝鏈夋晥鏈燂紝鐩稿樊涓嶈冻20鍒嗛挓锛岃嚜鍔ㄥ埛鏂扮紦瀛� + * + * @param token 浠ょ墝 + * @return 浠ょ墝 + */ + public void verifyToken(LoginUser loginUser) + { + long expireTime = loginUser.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) + { + refreshToken(loginUser); + } + } + + /** + * 鍒锋柊浠ょ墝鏈夋晥鏈� + * + * @param loginUser 鐧诲綍淇℃伅 + */ + public void refreshToken(LoginUser loginUser) + { + loginUser.setLoginTime(System.currentTimeMillis()); + loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); + // 鏍规嵁uuid灏唋oginUser缂撳瓨 + String userKey = getTokenKey(loginUser.getToken()); + redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + } + + /** + * 璁剧疆鐢ㄦ埛浠g悊淇℃伅 + * + * @param loginUser 鐧诲綍淇℃伅 + */ + public void setUserAgent(LoginUser loginUser) + { + UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); + String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); + loginUser.setIpaddr(ip); + loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); + loginUser.setBrowser(userAgent.getBrowser().getName()); + loginUser.setOs(userAgent.getOperatingSystem().getName()); + } + + /** + * 浠庢暟鎹0鏄庣敓鎴愪护鐗� + * + * @param claims 鏁版嵁澹版槑 + * @return 浠ょ墝 + */ + private String createToken(Map<String, Object> claims) + { + String token = Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 浠庝护鐗屼腑鑾峰彇鏁版嵁澹版槑 + * + * @param token 浠ょ墝 + * @return 鏁版嵁澹版槑 + */ + private Claims parseToken(String token) + { + return Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + } + + /** + * 浠庝护鐗屼腑鑾峰彇鐢ㄦ埛鍚� + * + * @param token 浠ょ墝 + * @return 鐢ㄦ埛鍚� + */ + public String getUsernameFromToken(String token) + { + Claims claims = parseToken(token); + return claims.getSubject(); + } + + /** + * 鑾峰彇璇锋眰token + * + * @param request + * @return token + */ + private String getToken(HttpServletRequest request) + { + String token = request.getHeader(header); + if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) + { + token = token.replace(Constants.TOKEN_PREFIX, ""); + } + return token; + } + + private String getTokenKey(String uuid) + { + return Constants.LOGIN_TOKEN_KEY + uuid; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/security/service/UserDetailsServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/framework/security/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..940191f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/security/service/UserDetailsServiceImpl.java @@ -0,0 +1,60 @@ +package com.ruoyi.framework.security.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.BaseException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.service.ISysUserService; + +/** + * 鐢ㄦ埛楠岃瘉澶勭悊 + * + * @author ruoyi + */ +@Service +public class UserDetailsServiceImpl implements UserDetailsService +{ + private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPermissionService permissionService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException + { + SysUser user = userService.selectUserByUserName(username); + if (StringUtils.isNull(user)) + { + log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", username); + throw new UsernameNotFoundException("鐧诲綍鐢ㄦ埛锛�" + username + " 涓嶅瓨鍦�"); + } + else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍒犻櫎.", username); + throw new BaseException("瀵逛笉璧凤紝鎮ㄧ殑璐﹀彿锛�" + username + " 宸茶鍒犻櫎"); + } + else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", username); + throw new BaseException("瀵逛笉璧凤紝鎮ㄧ殑璐﹀彿锛�" + username + " 宸插仠鐢�"); + } + + return createLoginUser(user); + } + + public UserDetails createLoginUser(SysUser user) + { + return new LoginUser(user, permissionService.getMenuPermission(user)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java b/ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java new file mode 100644 index 0000000..58e6cc1 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/controller/BaseController.java @@ -0,0 +1,85 @@ +package com.ruoyi.framework.web.controller; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.sql.SqlUtil; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.PageDomain; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.framework.web.page.TableSupport; + +/** + * web灞傞�氱敤鏁版嵁澶勭悊 + * + * @author ruoyi + */ +public class BaseController +{ + protected final Logger logger = LoggerFactory.getLogger(BaseController.class); + + /** + * 灏嗗墠鍙颁紶閫掕繃鏉ョ殑鏃ユ湡鏍煎紡鐨勫瓧绗︿覆锛岃嚜鍔ㄨ浆鍖栦负Date绫诲瀷 + */ + @InitBinder + public void initBinder(WebDataBinder binder) + { + // Date 绫诲瀷杞崲 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() + { + @Override + public void setAsText(String text) + { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 璁剧疆璇锋眰鍒嗛〉鏁版嵁 + */ + protected void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) + { + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + PageHelper.startPage(pageNum, pageSize, orderBy); + } + } + + /** + * 鍝嶅簲璇锋眰鍒嗛〉鏁版嵁 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected TableDataInfo getDataTable(List<?> list) + { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setRows(list); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + /** + * 鍝嶅簲杩斿洖缁撴灉 + * + * @param rows 褰卞搷琛屾暟 + * @return 鎿嶄綔缁撴灉 + */ + protected AjaxResult toAjax(int rows) + { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/AjaxResult.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/AjaxResult.java new file mode 100644 index 0000000..84c0dbf --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/AjaxResult.java @@ -0,0 +1,148 @@ +package com.ruoyi.framework.web.domain; + +import java.util.HashMap; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.utils.StringUtils; + +/** + * 鎿嶄綔娑堟伅鎻愰啋 + * + * @author ruoyi + */ +public class AjaxResult extends HashMap<String, Object> +{ + private static final long serialVersionUID = 1L; + + /** 鐘舵�佺爜 */ + public static final String CODE_TAG = "code"; + + /** 杩斿洖鍐呭 */ + public static final String MSG_TAG = "msg"; + + /** 鏁版嵁瀵硅薄 */ + public static final String DATA_TAG = "data"; + + /** + * 鍒濆鍖栦竴涓柊鍒涘缓鐨� AjaxResult 瀵硅薄锛屼娇鍏惰〃绀轰竴涓┖娑堟伅銆� + */ + public AjaxResult() + { + } + + /** + * 鍒濆鍖栦竴涓柊鍒涘缓鐨� AjaxResult 瀵硅薄 + * + * @param code 鐘舵�佺爜 + * @param msg 杩斿洖鍐呭 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 鍒濆鍖栦竴涓柊鍒涘缓鐨� AjaxResult 瀵硅薄 + * + * @param code 鐘舵�佺爜 + * @param msg 杩斿洖鍐呭 + * @param data 鏁版嵁瀵硅薄 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 杩斿洖鎴愬姛娑堟伅 + * + * @return 鎴愬姛娑堟伅 + */ + public static AjaxResult success() + { + return AjaxResult.success("鎿嶄綔鎴愬姛"); + } + + /** + * 杩斿洖鎴愬姛鏁版嵁 + * + * @return 鎴愬姛娑堟伅 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("鎿嶄綔鎴愬姛", data); + } + + /** + * 杩斿洖鎴愬姛娑堟伅 + * + * @param msg 杩斿洖鍐呭 + * @return 鎴愬姛娑堟伅 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 杩斿洖鎴愬姛娑堟伅 + * + * @param msg 杩斿洖鍐呭 + * @param data 鏁版嵁瀵硅薄 + * @return 鎴愬姛娑堟伅 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 杩斿洖閿欒娑堟伅 + * + * @return + */ + public static AjaxResult error() + { + return AjaxResult.error("鎿嶄綔澶辫触"); + } + + /** + * 杩斿洖閿欒娑堟伅 + * + * @param msg 杩斿洖鍐呭 + * @return 璀﹀憡娑堟伅 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 杩斿洖閿欒娑堟伅 + * + * @param msg 杩斿洖鍐呭 + * @param data 鏁版嵁瀵硅薄 + * @return 璀﹀憡娑堟伅 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 杩斿洖閿欒娑堟伅 + * + * @param code 鐘舵�佺爜 + * @param msg 杩斿洖鍐呭 + * @return 璀﹀憡娑堟伅 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/BaseEntity.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/BaseEntity.java new file mode 100644 index 0000000..24beda0 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/BaseEntity.java @@ -0,0 +1,156 @@ +package com.ruoyi.framework.web.domain; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * Entity鍩虹被 + * + * @author ruoyi + */ +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 鎼滅储鍊� */ + private String searchValue; + + /** 鍒涘缓鑰� */ + private String createBy; + + /** 鍒涘缓鏃堕棿 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 鏇存柊鑰� */ + private String updateBy; + + /** 鏇存柊鏃堕棿 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 澶囨敞 */ + private String remark; + + /** 鏁版嵁鏉冮檺 */ + private String dataScope; + + /** 寮�濮嬫椂闂� */ + @JsonIgnore + private String beginTime; + + /** 缁撴潫鏃堕棿 */ + @JsonIgnore + private String endTime; + + /** 璇锋眰鍙傛暟 */ + private Map<String, Object> params; + + public String getSearchValue() + { + return searchValue; + } + + public void setSearchValue(String searchValue) + { + this.searchValue = searchValue; + } + + public String getCreateBy() + { + return createBy; + } + + public void setCreateBy(String createBy) + { + this.createBy = createBy; + } + + public Date getCreateTime() + { + return createTime; + } + + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } + + public String getUpdateBy() + { + return updateBy; + } + + public void setUpdateBy(String updateBy) + { + this.updateBy = updateBy; + } + + public Date getUpdateTime() + { + return updateTime; + } + + public void setUpdateTime(Date updateTime) + { + this.updateTime = updateTime; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public String getBeginTime() + { + return beginTime; + } + + public void setBeginTime(String beginTime) + { + this.beginTime = beginTime; + } + + public String getEndTime() + { + return endTime; + } + + public void setEndTime(String endTime) + { + this.endTime = endTime; + } + + public Map<String, Object> getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + public void setParams(Map<String, Object> params) + { + this.params = params; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/Server.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/Server.java new file mode 100644 index 0000000..bc68a32 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/Server.java @@ -0,0 +1,241 @@ +package com.ruoyi.framework.web.domain; + +import java.net.UnknownHostException; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import com.ruoyi.common.utils.Arith; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.web.domain.server.Cpu; +import com.ruoyi.framework.web.domain.server.Jvm; +import com.ruoyi.framework.web.domain.server.Mem; +import com.ruoyi.framework.web.domain.server.Sys; +import com.ruoyi.framework.web.domain.server.SysFile; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.CentralProcessor.TickType; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.Util; + +/** + * 鏈嶅姟鍣ㄧ浉鍏充俊鎭� + * + * @author ruoyi + */ +public class Server +{ + + private static final int OSHI_WAIT_SECOND = 1000; + + /** + * CPU鐩稿叧淇℃伅 + */ + private Cpu cpu = new Cpu(); + + /** + * 鍏у瓨鐩稿叧淇℃伅 + */ + private Mem mem = new Mem(); + + /** + * JVM鐩稿叧淇℃伅 + */ + private Jvm jvm = new Jvm(); + + /** + * 鏈嶅姟鍣ㄧ浉鍏充俊鎭� + */ + private Sys sys = new Sys(); + + /** + * 纾佺洏鐩稿叧淇℃伅 + */ + private List<SysFile> sysFiles = new LinkedList<SysFile>(); + + public Cpu getCpu() + { + return cpu; + } + + public void setCpu(Cpu cpu) + { + this.cpu = cpu; + } + + public Mem getMem() + { + return mem; + } + + public void setMem(Mem mem) + { + this.mem = mem; + } + + public Jvm getJvm() + { + return jvm; + } + + public void setJvm(Jvm jvm) + { + this.jvm = jvm; + } + + public Sys getSys() + { + return sys; + } + + public void setSys(Sys sys) + { + this.sys = sys; + } + + public List<SysFile> getSysFiles() + { + return sysFiles; + } + + public void setSysFiles(List<SysFile> sysFiles) + { + this.sysFiles = sysFiles; + } + + public void copyTo() throws Exception + { + SystemInfo si = new SystemInfo(); + HardwareAbstractionLayer hal = si.getHardware(); + + setCpuInfo(hal.getProcessor()); + + setMemInfo(hal.getMemory()); + + setSysInfo(); + + setJvmInfo(); + + setSysFiles(si.getOperatingSystem()); + } + + /** + * 璁剧疆CPU淇℃伅 + */ + private void setCpuInfo(CentralProcessor processor) + { + // CPU淇℃伅 + long[] prevTicks = processor.getSystemCpuLoadTicks(); + Util.sleep(OSHI_WAIT_SECOND); + long[] ticks = processor.getSystemCpuLoadTicks(); + long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; + long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; + long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; + long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; + long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; + long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; + long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; + long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; + long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal; + cpu.setCpuNum(processor.getLogicalProcessorCount()); + cpu.setTotal(totalCpu); + cpu.setSys(cSys); + cpu.setUsed(user); + cpu.setWait(iowait); + cpu.setFree(idle); + } + + /** + * 璁剧疆鍐呭瓨淇℃伅 + */ + private void setMemInfo(GlobalMemory memory) + { + mem.setTotal(memory.getTotal()); + mem.setUsed(memory.getTotal() - memory.getAvailable()); + mem.setFree(memory.getAvailable()); + } + + /** + * 璁剧疆鏈嶅姟鍣ㄤ俊鎭� + */ + private void setSysInfo() + { + Properties props = System.getProperties(); + sys.setComputerName(IpUtils.getHostName()); + sys.setComputerIp(IpUtils.getHostIp()); + sys.setOsName(props.getProperty("os.name")); + sys.setOsArch(props.getProperty("os.arch")); + sys.setUserDir(props.getProperty("user.dir")); + } + + /** + * 璁剧疆Java铏氭嫙鏈� + */ + private void setJvmInfo() throws UnknownHostException + { + Properties props = System.getProperties(); + jvm.setTotal(Runtime.getRuntime().totalMemory()); + jvm.setMax(Runtime.getRuntime().maxMemory()); + jvm.setFree(Runtime.getRuntime().freeMemory()); + jvm.setVersion(props.getProperty("java.version")); + jvm.setHome(props.getProperty("java.home")); + } + + /** + * 璁剧疆纾佺洏淇℃伅 + */ + private void setSysFiles(OperatingSystem os) + { + FileSystem fileSystem = os.getFileSystem(); + OSFileStore[] fsArray = fileSystem.getFileStores(); + for (OSFileStore fs : fsArray) + { + long free = fs.getUsableSpace(); + long total = fs.getTotalSpace(); + long used = total - free; + SysFile sysFile = new SysFile(); + sysFile.setDirName(fs.getMount()); + sysFile.setSysTypeName(fs.getType()); + sysFile.setTypeName(fs.getName()); + sysFile.setTotal(convertFileSize(total)); + sysFile.setFree(convertFileSize(free)); + sysFile.setUsed(convertFileSize(used)); + sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100)); + sysFiles.add(sysFile); + } + } + + /** + * 瀛楄妭杞崲 + * + * @param size 瀛楄妭澶у皬 + * @return 杞崲鍚庡�� + */ + public String convertFileSize(long size) + { + long kb = 1024; + long mb = kb * 1024; + long gb = mb * 1024; + if (size >= gb) + { + return String.format("%.1f GB", (float) size / gb); + } + else if (size >= mb) + { + float f = (float) size / mb; + return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); + } + else if (size >= kb) + { + float f = (float) size / kb; + return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); + } + else + { + return String.format("%d B", size); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeSelect.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeSelect.java new file mode 100644 index 0000000..680d65b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/TreeSelect.java @@ -0,0 +1,77 @@ +package com.ruoyi.framework.web.domain; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.ruoyi.project.system.domain.SysDept; +import com.ruoyi.project.system.domain.SysMenu; + +/** + * Treeselect鏍戠粨鏋勫疄浣撶被 + * + * @author ruoyi + */ +public class TreeSelect implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 鑺傜偣ID */ + private Long id; + + /** 鑺傜偣鍚嶇О */ + private String label; + + /** 瀛愯妭鐐� */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List<TreeSelect> children; + + public TreeSelect() + { + + } + + public TreeSelect(SysDept dept) + { + this.id = dept.getDeptId(); + this.label = dept.getDeptName(); + this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public TreeSelect(SysMenu menu) + { + this.id = menu.getMenuId(); + this.label = menu.getMenuName(); + this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + public String getLabel() + { + return label; + } + + public void setLabel(String label) + { + this.label = label; + } + + public List<TreeSelect> getChildren() + { + return children; + } + + public void setChildren(List<TreeSelect> children) + { + this.children = children; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java new file mode 100644 index 0000000..a13a66c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java @@ -0,0 +1,101 @@ +package com.ruoyi.framework.web.domain.server; + +import com.ruoyi.common.utils.Arith; + +/** + * CPU鐩稿叧淇℃伅 + * + * @author ruoyi + */ +public class Cpu +{ + /** + * 鏍稿績鏁� + */ + private int cpuNum; + + /** + * CPU鎬荤殑浣跨敤鐜� + */ + private double total; + + /** + * CPU绯荤粺浣跨敤鐜� + */ + private double sys; + + /** + * CPU鐢ㄦ埛浣跨敤鐜� + */ + private double used; + + /** + * CPU褰撳墠绛夊緟鐜� + */ + private double wait; + + /** + * CPU褰撳墠绌洪棽鐜� + */ + private double free; + + public int getCpuNum() + { + return cpuNum; + } + + public void setCpuNum(int cpuNum) + { + this.cpuNum = cpuNum; + } + + public double getTotal() + { + return Arith.round(Arith.mul(total, 100), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getSys() + { + return Arith.round(Arith.mul(sys / total, 100), 2); + } + + public void setSys(double sys) + { + this.sys = sys; + } + + public double getUsed() + { + return Arith.round(Arith.mul(used / total, 100), 2); + } + + public void setUsed(double used) + { + this.used = used; + } + + public double getWait() + { + return Arith.round(Arith.mul(wait / total, 100), 2); + } + + public void setWait(double wait) + { + this.wait = wait; + } + + public double getFree() + { + return Arith.round(Arith.mul(free / total, 100), 2); + } + + public void setFree(double free) + { + this.free = free; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java new file mode 100644 index 0000000..485d201 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java @@ -0,0 +1,122 @@ +package com.ruoyi.framework.web.domain.server; + +import java.lang.management.ManagementFactory; +import com.ruoyi.common.utils.Arith; +import com.ruoyi.common.utils.DateUtils; + +/** + * JVM鐩稿叧淇℃伅 + * + * @author ruoyi + */ +public class Jvm +{ + /** + * 褰撳墠JVM鍗犵敤鐨勫唴瀛樻�绘暟(M) + */ + private double total; + + /** + * JVM鏈�澶у彲鐢ㄥ唴瀛樻�绘暟(M) + */ + private double max; + + /** + * JVM绌洪棽鍐呭瓨(M) + */ + private double free; + + /** + * JDK鐗堟湰 + */ + private String version; + + /** + * JDK璺緞 + */ + private String home; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024), 2); + } + + public void setTotal(double total) + { + this.total = total; + } + + public double getMax() + { + return Arith.div(max, (1024 * 1024), 2); + } + + public void setMax(double max) + { + this.max = max; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024), 2); + } + + public void setFree(double free) + { + this.free = free; + } + + public double getUsed() + { + return Arith.div(total - free, (1024 * 1024), 2); + } + + public double getUsage() + { + return Arith.mul(Arith.div(total - free, total, 4), 100); + } + + /** + * 鑾峰彇JDK鍚嶇О + */ + public String getName() + { + return ManagementFactory.getRuntimeMXBean().getVmName(); + } + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getHome() + { + return home; + } + + public void setHome(String home) + { + this.home = home; + } + + /** + * JDK鍚姩鏃堕棿 + */ + public String getStartTime() + { + return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate()); + } + + /** + * JDK杩愯鏃堕棿 + */ + public String getRunTime() + { + return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate()); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java new file mode 100644 index 0000000..13eec52 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java @@ -0,0 +1,61 @@ +package com.ruoyi.framework.web.domain.server; + +import com.ruoyi.common.utils.Arith; + +/** + * 鍏у瓨鐩稿叧淇℃伅 + * + * @author ruoyi + */ +public class Mem +{ + /** + * 鍐呭瓨鎬婚噺 + */ + private double total; + + /** + * 宸茬敤鍐呭瓨 + */ + private double used; + + /** + * 鍓╀綑鍐呭瓨 + */ + private double free; + + public double getTotal() + { + return Arith.div(total, (1024 * 1024 * 1024), 2); + } + + public void setTotal(long total) + { + this.total = total; + } + + public double getUsed() + { + return Arith.div(used, (1024 * 1024 * 1024), 2); + } + + public void setUsed(long used) + { + this.used = used; + } + + public double getFree() + { + return Arith.div(free, (1024 * 1024 * 1024), 2); + } + + public void setFree(long free) + { + this.free = free; + } + + public double getUsage() + { + return Arith.mul(Arith.div(used, total, 4), 100); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java new file mode 100644 index 0000000..45d64d9 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java @@ -0,0 +1,84 @@ +package com.ruoyi.framework.web.domain.server; + +/** + * 绯荤粺鐩稿叧淇℃伅 + * + * @author ruoyi + */ +public class Sys +{ + /** + * 鏈嶅姟鍣ㄥ悕绉� + */ + private String computerName; + + /** + * 鏈嶅姟鍣↖p + */ + private String computerIp; + + /** + * 椤圭洰璺緞 + */ + private String userDir; + + /** + * 鎿嶄綔绯荤粺 + */ + private String osName; + + /** + * 绯荤粺鏋舵瀯 + */ + private String osArch; + + public String getComputerName() + { + return computerName; + } + + public void setComputerName(String computerName) + { + this.computerName = computerName; + } + + public String getComputerIp() + { + return computerIp; + } + + public void setComputerIp(String computerIp) + { + this.computerIp = computerIp; + } + + public String getUserDir() + { + return userDir; + } + + public void setUserDir(String userDir) + { + this.userDir = userDir; + } + + public String getOsName() + { + return osName; + } + + public void setOsName(String osName) + { + this.osName = osName; + } + + public String getOsArch() + { + return osArch; + } + + public void setOsArch(String osArch) + { + this.osArch = osArch; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java new file mode 100644 index 0000000..1320cde --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java @@ -0,0 +1,114 @@ +package com.ruoyi.framework.web.domain.server; + +/** + * 绯荤粺鏂囦欢鐩稿叧淇℃伅 + * + * @author ruoyi + */ +public class SysFile +{ + /** + * 鐩樼璺緞 + */ + private String dirName; + + /** + * 鐩樼绫诲瀷 + */ + private String sysTypeName; + + /** + * 鏂囦欢绫诲瀷 + */ + private String typeName; + + /** + * 鎬诲ぇ灏� + */ + private String total; + + /** + * 鍓╀綑澶у皬 + */ + private String free; + + /** + * 宸茬粡浣跨敤閲� + */ + private String used; + + /** + * 璧勬簮鐨勪娇鐢ㄧ巼 + */ + private double usage; + + public String getDirName() + { + return dirName; + } + + public void setDirName(String dirName) + { + this.dirName = dirName; + } + + public String getSysTypeName() + { + return sysTypeName; + } + + public void setSysTypeName(String sysTypeName) + { + this.sysTypeName = sysTypeName; + } + + public String getTypeName() + { + return typeName; + } + + public void setTypeName(String typeName) + { + this.typeName = typeName; + } + + public String getTotal() + { + return total; + } + + public void setTotal(String total) + { + this.total = total; + } + + public String getFree() + { + return free; + } + + public void setFree(String free) + { + this.free = free; + } + + public String getUsed() + { + return used; + } + + public void setUsed(String used) + { + this.used = used; + } + + public double getUsage() + { + return usage; + } + + public void setUsage(double usage) + { + this.usage = usage; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..9450a55 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -0,0 +1,117 @@ +package com.ruoyi.framework.web.exception; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.authentication.AccountExpiredException; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.NoHandlerFoundException; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.BaseException; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.exception.DemoModeException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.domain.AjaxResult; + +/** + * 鍏ㄥ眬寮傚父澶勭悊鍣� + * + * @author ruoyi + */ +@RestControllerAdvice +public class GlobalExceptionHandler +{ + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 鍩虹寮傚父 + */ + @ExceptionHandler(BaseException.class) + public AjaxResult baseException(BaseException e) + { + return AjaxResult.error(e.getMessage()); + } + + /** + * 涓氬姟寮傚父 + */ + @ExceptionHandler(CustomException.class) + public AjaxResult businessException(CustomException e) + { + if (StringUtils.isNull(e.getCode())) + { + return AjaxResult.error(e.getMessage()); + } + return AjaxResult.error(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(NoHandlerFoundException.class) + public AjaxResult handlerNoFoundException(Exception e) + { + log.error(e.getMessage(), e); + return AjaxResult.error(HttpStatus.NOT_FOUND, "璺緞涓嶅瓨鍦紝璇锋鏌ヨ矾寰勬槸鍚︽纭�"); + } + + @ExceptionHandler(AccessDeniedException.class) + public AjaxResult handleAuthorizationException(AccessDeniedException e) + { + log.error(e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "娌℃湁鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�"); + } + + @ExceptionHandler(AccountExpiredException.class) + public AjaxResult handleAccountExpiredException(AccountExpiredException e) + { + log.error(e.getMessage(), e); + return AjaxResult.error(e.getMessage()); + } + + @ExceptionHandler(UsernameNotFoundException.class) + public AjaxResult handleUsernameNotFoundException(UsernameNotFoundException e) + { + log.error(e.getMessage(), e); + return AjaxResult.error(e.getMessage()); + } + + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e) + { + log.error(e.getMessage(), e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 鑷畾涔夐獙璇佸紓甯� + */ + @ExceptionHandler(BindException.class) + public AjaxResult validatedBindException(BindException e) + { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 鑷畾涔夐獙璇佸紓甯� + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object validExceptionHandler(MethodArgumentNotValidException e) + { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 婕旂ず妯″紡寮傚父 + */ + @ExceptionHandler(DemoModeException.class) + public AjaxResult demoModeException(DemoModeException e) + { + return AjaxResult.error("婕旂ず妯″紡锛屼笉鍏佽鎿嶄綔"); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/page/PageDomain.java b/ruoyi/src/main/java/com/ruoyi/framework/web/page/PageDomain.java new file mode 100644 index 0000000..84f7004 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/page/PageDomain.java @@ -0,0 +1,69 @@ +package com.ruoyi.framework.web.page; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 鍒嗛〉鏁版嵁 + * + * @author ruoyi + */ +public class PageDomain +{ + /** 褰撳墠璁板綍璧峰绱㈠紩 */ + private Integer pageNum; + /** 姣忛〉鏄剧ず璁板綍鏁� */ + private Integer pageSize; + /** 鎺掑簭鍒� */ + private String orderByColumn; + /** 鎺掑簭鐨勬柟鍚� "desc" 鎴栬�� "asc". */ + private String isAsc; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + this.isAsc = isAsc; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java b/ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java new file mode 100644 index 0000000..a01a9ae --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.ruoyi.framework.web.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 琛ㄦ牸鍒嗛〉鏁版嵁瀵硅薄 + * + * @author ruoyi + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 鎬昏褰曟暟 */ + private long total; + + /** 鍒楄〃鏁版嵁 */ + private List<?> rows; + + /** 娑堟伅鐘舵�佺爜 */ + private int code; + + /** 娑堟伅鍐呭 */ + private int msg; + + /** + * 琛ㄦ牸鏁版嵁瀵硅薄 + */ + public TableDataInfo() + { + } + + /** + * 鍒嗛〉 + * + * @param list 鍒楄〃鏁版嵁 + * @param total 鎬昏褰曟暟 + */ + public TableDataInfo(List<?> list, int total) + { + this.rows = list; + this.total = total; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public List<?> getRows() + { + return rows; + } + + public void setRows(List<?> rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public int getMsg() + { + return msg; + } + + public void setMsg(int msg) + { + this.msg = msg; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/framework/web/page/TableSupport.java b/ruoyi/src/main/java/com/ruoyi/framework/web/page/TableSupport.java new file mode 100644 index 0000000..156417a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/framework/web/page/TableSupport.java @@ -0,0 +1,49 @@ +package com.ruoyi.framework.web.page; + +import com.ruoyi.common.utils.ServletUtils; + +/** + * 琛ㄦ牸鏁版嵁澶勭悊 + * + * @author ruoyi + */ +public class TableSupport +{ + /** + * 褰撳墠璁板綍璧峰绱㈠紩 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 姣忛〉鏄剧ず璁板綍鏁� + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 鎺掑簭鍒� + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 鎺掑簭鐨勬柟鍚� "desc" 鎴栬�� "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 灏佽鍒嗛〉瀵硅薄 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(ServletUtils.getParameterToInt(PAGE_NUM)); + pageDomain.setPageSize(ServletUtils.getParameterToInt(PAGE_SIZE)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/common/CaptchaController.java b/ruoyi/src/main/java/com/ruoyi/project/common/CaptchaController.java new file mode 100644 index 0000000..c5ea830 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/common/CaptchaController.java @@ -0,0 +1,62 @@ +package com.ruoyi.project.common; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.IdUtils; +import com.ruoyi.common.utils.VerifyCodeUtils; +import com.ruoyi.common.utils.sign.Base64; +import com.ruoyi.framework.redis.RedisCache; +import com.ruoyi.framework.web.domain.AjaxResult; + +/** + * 楠岃瘉鐮佹搷浣滃鐞� + * + * @author ruoyi + */ +@RestController +public class CaptchaController +{ + @Autowired + private RedisCache redisCache; + + /** + * 鐢熸垚楠岃瘉鐮� + */ + @GetMapping("/captchaImage") + public AjaxResult getCode(HttpServletResponse response) throws IOException + { + // 鐢熸垚闅忔満瀛椾覆 + String verifyCode = VerifyCodeUtils.generateVerifyCode(4); + // 鍞竴鏍囪瘑 + String uuid = IdUtils.simpleUUID(); + String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; + + redisCache.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 鐢熸垚鍥剧墖 + int w = 111, h = 36; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + VerifyCodeUtils.outputImage(w, h, stream, verifyCode); + try + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(stream.toByteArray())); + return ajax; + } + catch (Exception e) + { + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } + finally + { + stream.close(); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java b/ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java new file mode 100644 index 0000000..b9c3937 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java @@ -0,0 +1,89 @@ +package com.ruoyi.project.common; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.framework.config.RuoYiConfig; +import com.ruoyi.framework.config.ServerConfig; +import com.ruoyi.framework.web.domain.AjaxResult; + +/** + * 閫氱敤璇锋眰澶勭悊 + * + * @author ruoyi + */ +@RestController +public class CommonController +{ + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + /** + * 閫氱敤涓嬭浇璇锋眰 + * + * @param fileName 鏂囦欢鍚嶇О + * @param delete 鏄惁鍒犻櫎 + */ + @GetMapping("common/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) + { + try + { + if (!FileUtils.isValidFilename(fileName)) + { + throw new Exception(StringUtils.format("鏂囦欢鍚嶇О({})闈炴硶锛屼笉鍏佽涓嬭浇銆� ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = RuoYiConfig.getDownloadPath() + fileName; + + response.setCharacterEncoding("utf-8"); + response.setContentType("multipart/form-data"); + response.setHeader("Content-Disposition", + "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName)); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) + { + FileUtils.deleteFile(filePath); + } + } + catch (Exception e) + { + log.error("涓嬭浇鏂囦欢澶辫触", e); + } + } + + /** + * 閫氱敤涓婁紶璇锋眰 + */ + @PostMapping("/common/upload") + public AjaxResult uploadFile(MultipartFile file) throws Exception + { + try + { + // 涓婁紶鏂囦欢璺緞 + String filePath = RuoYiConfig.getUploadPath(); + // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("fileName", fileName); + ajax.put("url", url); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/ServerController.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/ServerController.java new file mode 100644 index 0000000..c9d8007 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/ServerController.java @@ -0,0 +1,28 @@ +package com.ruoyi.project.monitor.controller; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.domain.Server; + +/** + * 鏈嶅姟鍣ㄧ洃鎺� + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/server") +public class ServerController extends BaseController +{ + @PreAuthorize("@ss.hasPermi('monitor:server:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception + { + Server server = new Server(); + server.copyTo(); + return AjaxResult.success(server); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java new file mode 100644 index 0000000..d9258fe --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java @@ -0,0 +1,67 @@ +package com.ruoyi.project.monitor.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.monitor.domain.SysLogininfor; +import com.ruoyi.project.monitor.service.ISysLogininforService; + +/** + * 绯荤粺璁块棶璁板綍 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + @Autowired + private ISysLogininforService logininforService; + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") + @GetMapping("/list") + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "鐧婚檰鏃ュ織", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") + @GetMapping("/export") + public AjaxResult export(SysLogininfor logininfor) + { + List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); + ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class); + return util.exportExcel(list, "鐧婚檰鏃ュ織"); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "鐧婚檰鏃ュ織", businessType = BusinessType.DELETE) + @DeleteMapping("/{infoIds}") + public AjaxResult remove(@PathVariable Long[] infoIds) + { + return toAjax(logininforService.deleteLogininforByIds(infoIds)); + } + + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") + @Log(title = "鐧婚檰鏃ュ織", businessType = BusinessType.CLEAN) + @DeleteMapping("/clean") + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return AjaxResult.success(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java new file mode 100644 index 0000000..0cabf92 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java @@ -0,0 +1,66 @@ +package com.ruoyi.project.monitor.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.monitor.domain.SysOperLog; +import com.ruoyi.project.monitor.service.ISysOperLogService; + +/** + * 鎿嶄綔鏃ュ織璁板綍 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + @Autowired + private ISysOperLogService operLogService; + + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')") + @GetMapping("/list") + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List<SysOperLog> list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')") + @GetMapping("/export") + public AjaxResult export(SysOperLog operLog) + { + List<SysOperLog> list = operLogService.selectOperLogList(operLog); + ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class); + return util.exportExcel(list, "鎿嶄綔鏃ュ織"); + } + + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/{operIds}") + public AjaxResult remove(@PathVariable Long[] operIds) + { + return toAjax(operLogService.deleteOperLogByIds(operIds)); + } + + @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.CLEAN) + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") + @DeleteMapping("/clean") + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return AjaxResult.success(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java new file mode 100644 index 0000000..1d28b19 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java @@ -0,0 +1,92 @@ +package com.ruoyi.project.monitor.controller; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.redis.RedisCache; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.monitor.domain.SysUserOnline; +import com.ruoyi.project.system.service.ISysUserOnlineService; + +/** + * 鍦ㄧ嚎鐢ㄦ埛鐩戞帶 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/monitor/online") +public class SysUserOnlineController extends BaseController +{ + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private RedisCache redisCache; + + @PreAuthorize("@ss.hasPermi('monitor:online:list')") + @GetMapping("/list") + public TableDataInfo list(String ipaddr, String userName) + { + Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*"); + List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>(); + for (String key : keys) + { + LoginUser user = redisCache.getCacheObject(key); + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); + } + } + else if (StringUtils.isNotEmpty(ipaddr)) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); + } + } + else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) + { + if (StringUtils.equals(userName, user.getUsername())) + { + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); + } + } + else + { + userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); + } + } + Collections.reverse(userOnlineList); + userOnlineList.removeAll(Collections.singleton(null)); + return getDataTable(userOnlineList); + } + + /** + * 寮洪��鐢ㄦ埛 + */ + @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") + @Log(title = "鍦ㄧ嚎鐢ㄦ埛", businessType = BusinessType.DELETE) + @DeleteMapping("/{tokenId}") + public AjaxResult forceLogout(@PathVariable String tokenId) + { + redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); + return AjaxResult.success(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java new file mode 100644 index 0000000..ff5ddc7 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java @@ -0,0 +1,142 @@ +package com.ruoyi.project.monitor.domain; + +import java.util.Date; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 绯荤粺璁块棶璁板綍琛� sys_logininfor + * + * @author ruoyi + */ +public class SysLogininfor extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Excel(name = "搴忓彿", cellType = ColumnType.NUMERIC) + private Long infoId; + + /** 鐢ㄦ埛璐﹀彿 */ + @Excel(name = "鐢ㄦ埛璐﹀彿") + private String userName; + + /** 鐧诲綍鐘舵�� 0鎴愬姛 1澶辫触 */ + @Excel(name = "鐧诲綍鐘舵��", readConverterExp = "0=鎴愬姛,1=澶辫触") + private String status; + + /** 鐧诲綍IP鍦板潃 */ + @Excel(name = "鐧诲綍鍦板潃") + private String ipaddr; + + /** 鐧诲綍鍦扮偣 */ + @Excel(name = "鐧诲綍鍦扮偣") + private String loginLocation; + + /** 娴忚鍣ㄧ被鍨� */ + @Excel(name = "娴忚鍣�") + private String browser; + + /** 鎿嶄綔绯荤粺 */ + @Excel(name = "鎿嶄綔绯荤粺") + private String os; + + /** 鎻愮ず娑堟伅 */ + @Excel(name = "鎻愮ず娑堟伅") + private String msg; + + /** 璁块棶鏃堕棿 */ + @Excel(name = "璁块棶鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date loginTime; + + public Long getInfoId() + { + return infoId; + } + + public void setInfoId(Long infoId) + { + this.infoId = infoId; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public Date getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Date loginTime) + { + this.loginTime = loginTime; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java new file mode 100644 index 0000000..c3027c1 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java @@ -0,0 +1,253 @@ +package com.ruoyi.project.monitor.domain; + +import java.util.Date; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 鎿嶄綔鏃ュ織璁板綍琛� oper_log + * + * @author ruoyi + */ +public class SysOperLog extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 鏃ュ織涓婚敭 */ + @Excel(name = "鎿嶄綔搴忓彿", cellType = ColumnType.NUMERIC) + private Long operId; + + /** 鎿嶄綔妯″潡 */ + @Excel(name = "鎿嶄綔妯″潡") + private String title; + + /** 涓氬姟绫诲瀷锛�0鍏跺畠 1鏂板 2淇敼 3鍒犻櫎锛� */ + @Excel(name = "涓氬姟绫诲瀷", readConverterExp = "0=鍏跺畠,1=鏂板,2=淇敼,3=鍒犻櫎,4=鎺堟潈,5=瀵煎嚭,6=瀵煎叆,7=寮洪��,8=鐢熸垚浠g爜,9=娓呯┖鏁版嵁") + private Integer businessType; + + /** 涓氬姟绫诲瀷鏁扮粍 */ + private Integer[] businessTypes; + + /** 璇锋眰鏂规硶 */ + @Excel(name = "璇锋眰鏂规硶") + private String method; + + /** 璇锋眰鏂瑰紡 */ + @Excel(name = "璇锋眰鏂瑰紡") + private String requestMethod; + + /** 鎿嶄綔绫诲埆锛�0鍏跺畠 1鍚庡彴鐢ㄦ埛 2鎵嬫満绔敤鎴凤級 */ + @Excel(name = "鎿嶄綔绫诲埆", readConverterExp = "0=鍏跺畠,1=鍚庡彴鐢ㄦ埛,2=鎵嬫満绔敤鎴�") + private Integer operatorType; + + /** 鎿嶄綔浜哄憳 */ + @Excel(name = "鎿嶄綔浜哄憳") + private String operName; + + /** 閮ㄩ棬鍚嶇О */ + @Excel(name = "閮ㄩ棬鍚嶇О") + private String deptName; + + /** 璇锋眰url */ + @Excel(name = "璇锋眰鍦板潃") + private String operUrl; + + /** 鎿嶄綔鍦板潃 */ + @Excel(name = "鎿嶄綔鍦板潃") + private String operIp; + + /** 鎿嶄綔鍦扮偣 */ + @Excel(name = "鎿嶄綔鍦扮偣") + private String operLocation; + + /** 璇锋眰鍙傛暟 */ + @Excel(name = "璇锋眰鍙傛暟") + private String operParam; + + /** 杩斿洖鍙傛暟 */ + @Excel(name = "杩斿洖鍙傛暟") + private String jsonResult; + + /** 鎿嶄綔鐘舵�侊紙0姝e父 1寮傚父锛� */ + @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,1=寮傚父") + private Integer status; + + /** 閿欒娑堟伅 */ + @Excel(name = "閿欒娑堟伅") + private String errorMsg; + + /** 鎿嶄綔鏃堕棿 */ + @Excel(name = "鎿嶄綔鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date operTime; + + public Long getOperId() + { + return operId; + } + + public void setOperId(Long operId) + { + this.operId = operId; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public Integer getBusinessType() + { + return businessType; + } + + public void setBusinessType(Integer businessType) + { + this.businessType = businessType; + } + + public Integer[] getBusinessTypes() + { + return businessTypes; + } + + public void setBusinessTypes(Integer[] businessTypes) + { + this.businessTypes = businessTypes; + } + + public String getMethod() + { + return method; + } + + public void setMethod(String method) + { + this.method = method; + } + + public String getRequestMethod() + { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) + { + this.requestMethod = requestMethod; + } + + public Integer getOperatorType() + { + return operatorType; + } + + public void setOperatorType(Integer operatorType) + { + this.operatorType = operatorType; + } + + public String getOperName() + { + return operName; + } + + public void setOperName(String operName) + { + this.operName = operName; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getOperUrl() + { + return operUrl; + } + + public void setOperUrl(String operUrl) + { + this.operUrl = operUrl; + } + + public String getOperIp() + { + return operIp; + } + + public void setOperIp(String operIp) + { + this.operIp = operIp; + } + + public String getOperLocation() + { + return operLocation; + } + + public void setOperLocation(String operLocation) + { + this.operLocation = operLocation; + } + + public String getOperParam() + { + return operParam; + } + + public void setOperParam(String operParam) + { + this.operParam = operParam; + } + + public String getJsonResult() + { + return jsonResult; + } + + public void setJsonResult(String jsonResult) + { + this.jsonResult = jsonResult; + } + + public Integer getStatus() + { + return status; + } + + public void setStatus(Integer status) + { + this.status = status; + } + + public String getErrorMsg() + { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) + { + this.errorMsg = errorMsg; + } + + public Date getOperTime() + { + return operTime; + } + + public void setOperTime(Date operTime) + { + this.operTime = operTime; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java new file mode 100644 index 0000000..387d49c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java @@ -0,0 +1,113 @@ +package com.ruoyi.project.monitor.domain; + +/** + * 褰撳墠鍦ㄧ嚎浼氳瘽 + * + * @author ruoyi + */ +public class SysUserOnline +{ + /** 浼氳瘽缂栧彿 */ + private String tokenId; + + /** 閮ㄩ棬鍚嶇О */ + private String deptName; + + /** 鐢ㄦ埛鍚嶇О */ + private String userName; + + /** 鐧诲綍IP鍦板潃 */ + private String ipaddr; + + /** 鐧诲綍鍦板潃 */ + private String loginLocation; + + /** 娴忚鍣ㄧ被鍨� */ + private String browser; + + /** 鎿嶄綔绯荤粺 */ + private String os; + + /** 鐧诲綍鏃堕棿 */ + private Long loginTime; + + public String getTokenId() + { + return tokenId; + } + + public void setTokenId(String tokenId) + { + this.tokenId = tokenId; + } + + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getIpaddr() + { + return ipaddr; + } + + public void setIpaddr(String ipaddr) + { + this.ipaddr = ipaddr; + } + + public String getLoginLocation() + { + return loginLocation; + } + + public void setLoginLocation(String loginLocation) + { + this.loginLocation = loginLocation; + } + + public String getBrowser() + { + return browser; + } + + public void setBrowser(String browser) + { + this.browser = browser; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public Long getLoginTime() + { + return loginTime; + } + + public void setLoginTime(Long loginTime) + { + this.loginTime = loginTime; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java new file mode 100644 index 0000000..05b8c9b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java @@ -0,0 +1,42 @@ +package com.ruoyi.project.monitor.mapper; + +import java.util.List; +import com.ruoyi.project.monitor.domain.SysLogininfor; + +/** + * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysLogininforMapper +{ + /** + * 鏂板绯荤粺鐧诲綍鏃ュ織 + * + * @param logininfor 璁块棶鏃ュ織瀵硅薄 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎 + * + * @param logininfor 璁块棶鏃ュ織瀵硅薄 + * @return 鐧诲綍璁板綍闆嗗悎 + */ + public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor); + + /** + * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織 + * + * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID + * @return 缁撴灉 + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 娓呯┖绯荤粺鐧诲綍鏃ュ織 + * + * @return 缁撴灉 + */ + public int cleanLogininfor(); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java new file mode 100644 index 0000000..ed5d573 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java @@ -0,0 +1,48 @@ +package com.ruoyi.project.monitor.mapper; + +import java.util.List; +import com.ruoyi.project.monitor.domain.SysOperLog; + +/** + * 鎿嶄綔鏃ュ織 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysOperLogMapper +{ + /** + * 鏂板鎿嶄綔鏃ュ織 + * + * @param operLog 鎿嶄綔鏃ュ織瀵硅薄 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎 + * + * @param operLog 鎿嶄綔鏃ュ織瀵硅薄 + * @return 鎿嶄綔鏃ュ織闆嗗悎 + */ + public List<SysOperLog> selectOperLogList(SysOperLog operLog); + + /** + * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織 + * + * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID + * @return 缁撴灉 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏 + * + * @param operId 鎿嶄綔ID + * @return 鎿嶄綔鏃ュ織瀵硅薄 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 娓呯┖鎿嶄綔鏃ュ織 + */ + public void cleanOperLog(); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java new file mode 100644 index 0000000..d3eede4 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysLogininforService.java @@ -0,0 +1,40 @@ +package com.ruoyi.project.monitor.service; + +import java.util.List; +import com.ruoyi.project.monitor.domain.SysLogininfor; + +/** + * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysLogininforService +{ + /** + * 鏂板绯荤粺鐧诲綍鏃ュ織 + * + * @param logininfor 璁块棶鏃ュ織瀵硅薄 + */ + public void insertLogininfor(SysLogininfor logininfor); + + /** + * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎 + * + * @param logininfor 璁块棶鏃ュ織瀵硅薄 + * @return 鐧诲綍璁板綍闆嗗悎 + */ + public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor); + + /** + * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織 + * + * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID + * @return + */ + public int deleteLogininforByIds(Long[] infoIds); + + /** + * 娓呯┖绯荤粺鐧诲綍鏃ュ織 + */ + public void cleanLogininfor(); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java new file mode 100644 index 0000000..0e63d8d --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/ISysOperLogService.java @@ -0,0 +1,48 @@ +package com.ruoyi.project.monitor.service; + +import java.util.List; +import com.ruoyi.project.monitor.domain.SysOperLog; + +/** + * 鎿嶄綔鏃ュ織 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysOperLogService +{ + /** + * 鏂板鎿嶄綔鏃ュ織 + * + * @param operLog 鎿嶄綔鏃ュ織瀵硅薄 + */ + public void insertOperlog(SysOperLog operLog); + + /** + * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎 + * + * @param operLog 鎿嶄綔鏃ュ織瀵硅薄 + * @return 鎿嶄綔鏃ュ織闆嗗悎 + */ + public List<SysOperLog> selectOperLogList(SysOperLog operLog); + + /** + * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織 + * + * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID + * @return 缁撴灉 + */ + public int deleteOperLogByIds(Long[] operIds); + + /** + * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏 + * + * @param operId 鎿嶄綔ID + * @return 鎿嶄綔鏃ュ織瀵硅薄 + */ + public SysOperLog selectOperLogById(Long operId); + + /** + * 娓呯┖鎿嶄綔鏃ュ織 + */ + public void cleanOperLog(); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java new file mode 100644 index 0000000..d10bac6 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysLogininforServiceImpl.java @@ -0,0 +1,65 @@ +package com.ruoyi.project.monitor.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.project.monitor.domain.SysLogininfor; +import com.ruoyi.project.monitor.mapper.SysLogininforMapper; +import com.ruoyi.project.monitor.service.ISysLogininforService; + +/** + * 绯荤粺璁块棶鏃ュ織鎯呭喌淇℃伅 鏈嶅姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysLogininforServiceImpl implements ISysLogininforService +{ + + @Autowired + private SysLogininforMapper logininforMapper; + + /** + * 鏂板绯荤粺鐧诲綍鏃ュ織 + * + * @param logininfor 璁块棶鏃ュ織瀵硅薄 + */ + @Override + public void insertLogininfor(SysLogininfor logininfor) + { + logininforMapper.insertLogininfor(logininfor); + } + + /** + * 鏌ヨ绯荤粺鐧诲綍鏃ュ織闆嗗悎 + * + * @param logininfor 璁块棶鏃ュ織瀵硅薄 + * @return 鐧诲綍璁板綍闆嗗悎 + */ + @Override + public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor) + { + return logininforMapper.selectLogininforList(logininfor); + } + + /** + * 鎵归噺鍒犻櫎绯荤粺鐧诲綍鏃ュ織 + * + * @param infoIds 闇�瑕佸垹闄ょ殑鐧诲綍鏃ュ織ID + * @return + */ + @Override + public int deleteLogininforByIds(Long[] infoIds) + { + return logininforMapper.deleteLogininforByIds(infoIds); + } + + /** + * 娓呯┖绯荤粺鐧诲綍鏃ュ織 + */ + @Override + public void cleanLogininfor() + { + logininforMapper.cleanLogininfor(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java new file mode 100644 index 0000000..2f11469 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/monitor/service/impl/SysOperLogServiceImpl.java @@ -0,0 +1,75 @@ +package com.ruoyi.project.monitor.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.project.monitor.domain.SysOperLog; +import com.ruoyi.project.monitor.mapper.SysOperLogMapper; +import com.ruoyi.project.monitor.service.ISysOperLogService; + +/** + * 鎿嶄綔鏃ュ織 鏈嶅姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysOperLogServiceImpl implements ISysOperLogService +{ + @Autowired + private SysOperLogMapper operLogMapper; + + /** + * 鏂板鎿嶄綔鏃ュ織 + * + * @param operLog 鎿嶄綔鏃ュ織瀵硅薄 + */ + @Override + public void insertOperlog(SysOperLog operLog) + { + operLogMapper.insertOperlog(operLog); + } + + /** + * 鏌ヨ绯荤粺鎿嶄綔鏃ュ織闆嗗悎 + * + * @param operLog 鎿嶄綔鏃ュ織瀵硅薄 + * @return 鎿嶄綔鏃ュ織闆嗗悎 + */ + @Override + public List<SysOperLog> selectOperLogList(SysOperLog operLog) + { + return operLogMapper.selectOperLogList(operLog); + } + + /** + * 鎵归噺鍒犻櫎绯荤粺鎿嶄綔鏃ュ織 + * + * @param operIds 闇�瑕佸垹闄ょ殑鎿嶄綔鏃ュ織ID + * @return 缁撴灉 + */ + public int deleteOperLogByIds(Long[] operIds) + { + return operLogMapper.deleteOperLogByIds(operIds); + } + + /** + * 鏌ヨ鎿嶄綔鏃ュ織璇︾粏 + * + * @param operId 鎿嶄綔ID + * @return 鎿嶄綔鏃ュ織瀵硅薄 + */ + @Override + public SysOperLog selectOperLogById(Long operId) + { + return operLogMapper.selectOperLogById(operId); + } + + /** + * 娓呯┖鎿嶄綔鏃ュ織 + */ + @Override + public void cleanOperLog() + { + operLogMapper.cleanOperLog(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java new file mode 100644 index 0000000..db95669 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysConfigController.java @@ -0,0 +1,121 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysConfig; +import com.ruoyi.project.system.service.ISysConfigService; + +/** + * 鍙傛暟閰嶇疆 淇℃伅鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + @Autowired + private ISysConfigService configService; + + /** + * 鑾峰彇鍙傛暟閰嶇疆鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('system:config:list')") + @GetMapping("/list") + public TableDataInfo list(SysConfig config) + { + startPage(); + List<SysConfig> list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @GetMapping("/export") + public AjaxResult export(SysConfig config) + { + List<SysConfig> list = configService.selectConfigList(config); + ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class); + return util.exportExcel(list, "鍙傛暟鏁版嵁"); + } + + /** + * 鏍规嵁鍙傛暟缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:config:query')") + @GetMapping(value = "/{configId}") + public AjaxResult getInfo(@PathVariable Long configId) + { + return AjaxResult.success(configService.selectConfigById(configId)); + } + + /** + * 鏍规嵁鍙傛暟閿悕鏌ヨ鍙傛暟鍊� + */ + @GetMapping(value = "/configKey/{configKey}") + public AjaxResult getConfigKey(@PathVariable String configKey) + { + return AjaxResult.success(configService.selectConfigByKey(configKey)); + } + + /** + * 鏂板鍙傛暟閰嶇疆 + */ + @PreAuthorize("@ss.hasPermi('system:config:add')") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysConfig config) + { + if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return AjaxResult.error("鏂板鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪"); + } + config.setCreateBy(SecurityUtils.getUsername()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 淇敼鍙傛暟閰嶇疆 + */ + @PreAuthorize("@ss.hasPermi('system:config:edit')") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysConfig config) + { + if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return AjaxResult.error("淇敼鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪"); + } + config.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 鍒犻櫎鍙傛暟閰嶇疆 + */ + @PreAuthorize("@ss.hasPermi('system:config:remove')") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.DELETE) + @DeleteMapping("/{configIds}") + public AjaxResult remove(@PathVariable Long[] configIds) + { + return toAjax(configService.deleteConfigByIds(configIds)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java new file mode 100644 index 0000000..0b104e4 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDeptController.java @@ -0,0 +1,134 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.project.system.domain.SysDept; +import com.ruoyi.project.system.service.ISysDeptService; + +/** + * 閮ㄩ棬淇℃伅 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + @Autowired + private ISysDeptService deptService; + + /** + * 鑾峰彇閮ㄩ棬鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('system:dept:list')") + @GetMapping("/list") + public AjaxResult list(SysDept dept) + { + List<SysDept> depts = deptService.selectDeptList(dept); + return AjaxResult.success(deptService.buildDeptTree(depts)); + } + + /** + * 鏍规嵁閮ㄩ棬缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:dept:query')") + @GetMapping(value = "/{deptId}") + public AjaxResult getInfo(@PathVariable Long deptId) + { + return AjaxResult.success(deptService.selectDeptById(deptId)); + } + + /** + * 鑾峰彇閮ㄩ棬涓嬫媺鏍戝垪琛� + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysDept dept) + { + List<SysDept> depts = deptService.selectDeptList(dept); + return AjaxResult.success(deptService.buildDeptTreeSelect(depts)); + } + + /** + * 鍔犺浇瀵瑰簲瑙掕壊閮ㄩ棬鍒楄〃鏍� + */ + @GetMapping(value = "/roleDeptTreeselect/{roleId}") + public AjaxResult roleDeptTreeselect(@PathVariable("roleId") Long roleId) + { + List<SysDept> depts = deptService.selectDeptList(new SysDept()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId)); + ajax.put("depts", deptService.buildDeptTreeSelect(depts)); + return ajax; + } + + /** + * 鏂板閮ㄩ棬 + */ + @PreAuthorize("@ss.hasPermi('system:dept:add')") + @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDept dept) + { + if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return AjaxResult.error("鏂板閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪"); + } + dept.setCreateBy(SecurityUtils.getUsername()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 淇敼閮ㄩ棬 + */ + @PreAuthorize("@ss.hasPermi('system:dept:edit')") + @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDept dept) + { + if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return AjaxResult.error("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪"); + } + else if (dept.getParentId().equals(dept.getDeptId())) + { + return AjaxResult.error("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛屼笂绾ч儴闂ㄤ笉鑳芥槸鑷繁"); + } + dept.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 鍒犻櫎閮ㄩ棬 + */ + @PreAuthorize("@ss.hasPermi('system:dept:remove')") + @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.DELETE) + @DeleteMapping("/{deptId}") + public AjaxResult remove(@PathVariable Long deptId) + { + if (deptService.hasChildByDeptId(deptId)) + { + return AjaxResult.error("瀛樺湪涓嬬骇閮ㄩ棬,涓嶅厑璁稿垹闄�"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return AjaxResult.error("閮ㄩ棬瀛樺湪鐢ㄦ埛,涓嶅厑璁稿垹闄�"); + } + return toAjax(deptService.deleteDeptById(deptId)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java new file mode 100644 index 0000000..3fa53d5 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictDataController.java @@ -0,0 +1,109 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysDictData; +import com.ruoyi.project.system.service.ISysDictDataService; + +/** + * 鏁版嵁瀛楀吀淇℃伅 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + @Autowired + private ISysDictDataService dictDataService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List<SysDictData> list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @GetMapping("/export") + public AjaxResult export(SysDictData dictData) + { + List<SysDictData> list = dictDataService.selectDictDataList(dictData); + ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class); + return util.exportExcel(list, "瀛楀吀鏁版嵁"); + } + + /** + * 鏌ヨ瀛楀吀鏁版嵁璇︾粏 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictCode}") + public AjaxResult getInfo(@PathVariable Long dictCode) + { + return AjaxResult.success(dictDataService.selectDictDataById(dictCode)); + } + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁淇℃伅 + */ + @GetMapping(value = "/dictType/{dictType}") + public AjaxResult dictType(@PathVariable String dictType) + { + return AjaxResult.success(dictDataService.selectDictDataByType(dictType)); + } + + /** + * 鏂板瀛楀吀绫诲瀷 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictData dict) + { + dict.setCreateBy(SecurityUtils.getUsername()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 淇敼淇濆瓨瀛楀吀绫诲瀷 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictData dict) + { + dict.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(dictDataService.updateDictData(dict)); + } + + /** + * 鍒犻櫎瀛楀吀绫诲瀷 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictCodes}") + public AjaxResult remove(@PathVariable Long[] dictCodes) + { + return toAjax(dictDataService.deleteDictDataByIds(dictCodes)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java new file mode 100644 index 0000000..82d93d9 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysDictTypeController.java @@ -0,0 +1,119 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysDictType; +import com.ruoyi.project.system.service.ISysDictTypeService; + +/** + * 鏁版嵁瀛楀吀淇℃伅 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/dict/type") +public class SysDictTypeController extends BaseController +{ + @Autowired + private ISysDictTypeService dictTypeService; + + @PreAuthorize("@ss.hasPermi('system:dict:list')") + @GetMapping("/list") + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:dict:export')") + @GetMapping("/export") + public AjaxResult export(SysDictType dictType) + { + List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class); + return util.exportExcel(list, "瀛楀吀绫诲瀷"); + } + + /** + * 鏌ヨ瀛楀吀绫诲瀷璇︾粏 + */ + @PreAuthorize("@ss.hasPermi('system:dict:query')") + @GetMapping(value = "/{dictId}") + public AjaxResult getInfo(@PathVariable Long dictId) + { + return AjaxResult.success(dictTypeService.selectDictTypeById(dictId)); + } + + /** + * 鏂板瀛楀吀绫诲瀷 + */ + @PreAuthorize("@ss.hasPermi('system:dict:add')") + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysDictType dict) + { + if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return AjaxResult.error("鏂板瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪"); + } + dict.setCreateBy(SecurityUtils.getUsername()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 淇敼瀛楀吀绫诲瀷 + */ + @PreAuthorize("@ss.hasPermi('system:dict:edit')") + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysDictType dict) + { + if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return AjaxResult.error("淇敼瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪"); + } + dict.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + /** + * 鍒犻櫎瀛楀吀绫诲瀷 + */ + @PreAuthorize("@ss.hasPermi('system:dict:remove')") + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE) + @DeleteMapping("/{dictIds}") + public AjaxResult remove(@PathVariable Long[] dictIds) + { + return toAjax(dictTypeService.deleteDictTypeByIds(dictIds)); + } + + /** + * 鑾峰彇瀛楀吀閫夋嫨妗嗗垪琛� + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); + return AjaxResult.success(dictTypes); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysLoginController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysLoginController.java new file mode 100644 index 0000000..09a5d13 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysLoginController.java @@ -0,0 +1,94 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.SysLoginService; +import com.ruoyi.framework.security.service.SysPermissionService; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.project.system.domain.SysMenu; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.service.ISysMenuService; + +/** + * 鐧诲綍楠岃瘉 + * + * @author ruoyi + */ +@RestController +public class SysLoginController +{ + @Autowired + private SysLoginService loginService; + + @Autowired + private ISysMenuService menuService; + + @Autowired + private SysPermissionService permissionService; + + @Autowired + private TokenService tokenService; + + /** + * 鐧诲綍鏂规硶 + * + * @param username 鐢ㄦ埛鍚� + * @param password 瀵嗙爜 + * @param captcha 楠岃瘉鐮� + * @param uuid 鍞竴鏍囪瘑 + * @return 缁撴灉 + */ + @PostMapping("/login") + public AjaxResult login(String username, String password, String code, String uuid) + { + AjaxResult ajax = AjaxResult.success(); + // 鐢熸垚浠ょ墝 + String token = loginService.login(username, password, code, uuid); + ajax.put(Constants.TOKEN, token); + return ajax; + } + + /** + * 鑾峰彇鐢ㄦ埛淇℃伅 + * + * @return 鐢ㄦ埛淇℃伅 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + SysUser user = loginUser.getUser(); + // 瑙掕壊闆嗗悎 + Set<String> roles = permissionService.getRolePermission(user); + // 鏉冮檺闆嗗悎 + Set<String> permissions = permissionService.getMenuPermission(user); + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + return ajax; + } + + /** + * 鑾峰彇璺敱淇℃伅 + * + * @return 璺敱淇℃伅 + */ + @GetMapping("getRouters") + public AjaxResult getRouters() + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + // 鐢ㄦ埛淇℃伅 + SysUser user = loginUser.getUser(); + List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId()); + return AjaxResult.success(menuService.buildMenus(menus)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java new file mode 100644 index 0000000..d862ceb --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysMenuController.java @@ -0,0 +1,141 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.project.system.domain.SysMenu; +import com.ruoyi.project.system.service.ISysMenuService; + +/** + * 鑿滃崟淇℃伅 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + @Autowired + private TokenService tokenService; + + /** + * 鑾峰彇鑿滃崟鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('system:menu:list')") + @GetMapping("/list") + public AjaxResult list(SysMenu menu) + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + Long userId = loginUser.getUser().getUserId(); + List<SysMenu> menus = menuService.selectMenuList(menu, userId); + return AjaxResult.success(menuService.buildMenuTree(menus)); + } + + /** + * 鏍规嵁鑿滃崟缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:menu:query')") + @GetMapping(value = "/{menuId}") + public AjaxResult getInfo(@PathVariable Long menuId) + { + return AjaxResult.success(menuService.selectMenuById(menuId)); + } + + /** + * 鑾峰彇鑿滃崟涓嬫媺鏍戝垪琛� + */ + @GetMapping("/treeselect") + public AjaxResult treeselect(SysMenu menu) + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + Long userId = loginUser.getUser().getUserId(); + List<SysMenu> menus = menuService.selectMenuList(menu, userId); + return AjaxResult.success(menuService.buildMenuTreeSelect(menus)); + } + + /** + * 鍔犺浇瀵瑰簲瑙掕壊鑿滃崟鍒楄〃鏍� + */ + @GetMapping(value = "/roleMenuTreeselect/{roleId}") + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + List<SysMenu> menus = menuService.selectMenuList(loginUser.getUser().getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); + ajax.put("menus", menuService.buildMenuTreeSelect(menus)); + return ajax; + } + + /** + * 鏂板鑿滃崟 + */ + @PreAuthorize("@ss.hasPermi('system:menu:add')") + @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysMenu menu) + { + if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return AjaxResult.error("鏂板鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪"); + } + menu.setCreateBy(SecurityUtils.getUsername()); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 淇敼鑿滃崟 + */ + @PreAuthorize("@ss.hasPermi('system:menu:edit')") + @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysMenu menu) + { + if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return AjaxResult.error("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪"); + } + menu.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 鍒犻櫎鑿滃崟 + */ + @PreAuthorize("@ss.hasPermi('system:menu:remove')") + @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.DELETE) + @DeleteMapping("/{menuId}") + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.hasChildByMenuId(menuId)) + { + return AjaxResult.error("瀛樺湪瀛愯彍鍗�,涓嶅厑璁稿垹闄�"); + } + if (menuService.checkMenuExistRole(menuId)) + { + return AjaxResult.error("鑿滃崟宸插垎閰�,涓嶅厑璁稿垹闄�"); + } + return toAjax(menuService.deleteMenuById(menuId)); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java new file mode 100644 index 0000000..c96ef12 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysNoticeController.java @@ -0,0 +1,92 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysNotice; +import com.ruoyi.project.system.service.ISysNoticeService; + +/** + * 鍏憡 淇℃伅鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/notice") +public class SysNoticeController extends BaseController +{ + @Autowired + private ISysNoticeService noticeService; + + /** + * 鑾峰彇閫氱煡鍏憡鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('system:notice:list')") + @GetMapping("/list") + public TableDataInfo list(SysNotice notice) + { + startPage(); + List<SysNotice> list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 鏍规嵁閫氱煡鍏憡缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:notice:query')") + @GetMapping(value = "/{noticeId}") + public AjaxResult getInfo(@PathVariable Long noticeId) + { + return AjaxResult.success(noticeService.selectNoticeById(noticeId)); + } + + /** + * 鏂板閫氱煡鍏憡 + */ + @PreAuthorize("@ss.hasPermi('system:notice:add')") + @Log(title = "閫氱煡鍏憡", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysNotice notice) + { + notice.setCreateBy(SecurityUtils.getUsername()); + return toAjax(noticeService.insertNotice(notice)); + } + + /** + * 淇敼閫氱煡鍏憡 + */ + @PreAuthorize("@ss.hasPermi('system:notice:edit')") + @Log(title = "閫氱煡鍏憡", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysNotice notice) + { + notice.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 鍒犻櫎閫氱煡鍏憡 + */ + @PreAuthorize("@ss.hasPermi('system:notice:remove')") + @Log(title = "閫氱煡鍏憡", businessType = BusinessType.DELETE) + @DeleteMapping("/{noticeId}") + public AjaxResult remove(@PathVariable Long noticeId) + { + return toAjax(noticeService.deleteNoticeById(noticeId)); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java new file mode 100644 index 0000000..5bce6a6 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysPostController.java @@ -0,0 +1,130 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysPost; +import com.ruoyi.project.system.service.ISysPostService; + +/** + * 宀椾綅淇℃伅鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + @Autowired + private ISysPostService postService; + + /** + * 鑾峰彇宀椾綅鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('system:post:list')") + @GetMapping("/list") + public TableDataInfo list(SysPost post) + { + startPage(); + List<SysPost> list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:config:export')") + @GetMapping("/export") + public AjaxResult export(SysPost post) + { + List<SysPost> list = postService.selectPostList(post); + ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class); + return util.exportExcel(list, "宀椾綅鏁版嵁"); + } + + /** + * 鏍规嵁宀椾綅缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:post:query')") + @GetMapping(value = "/{postId}") + public AjaxResult getInfo(@PathVariable Long postId) + { + return AjaxResult.success(postService.selectPostById(postId)); + } + + /** + * 鏂板宀椾綅 + */ + @PreAuthorize("@ss.hasPermi('system:post:add')") + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysPost post) + { + if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return AjaxResult.error("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return AjaxResult.error("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪"); + } + post.setCreateBy(SecurityUtils.getUsername()); + return toAjax(postService.insertPost(post)); + } + + /** + * 淇敼宀椾綅 + */ + @PreAuthorize("@ss.hasPermi('system:post:edit')") + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysPost post) + { + if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return AjaxResult.error("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return AjaxResult.error("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪"); + } + post.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(postService.updatePost(post)); + } + + /** + * 鍒犻櫎宀椾綅 + */ + @PreAuthorize("@ss.hasPermi('system:post:remove')") + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.DELETE) + @DeleteMapping("/{postIds}") + public AjaxResult remove(@PathVariable Long[] postIds) + { + return toAjax(postService.deletePostByIds(postIds)); + } + + /** + * 鑾峰彇宀椾綅閫夋嫨妗嗗垪琛� + */ + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + List<SysPost> posts = postService.selectPostAll(); + return AjaxResult.success(posts); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysProfileController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysProfileController.java new file mode 100644 index 0000000..2486507 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysProfileController.java @@ -0,0 +1,127 @@ +package com.ruoyi.project.system.controller; + +import java.io.IOException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.config.RuoYiConfig; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.service.ISysUserService; + +/** + * 涓汉淇℃伅 涓氬姟澶勭悊 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private TokenService tokenService; + + /** + * 涓汉淇℃伅 + */ + @GetMapping + public AjaxResult profile() + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + SysUser user = loginUser.getUser(); + AjaxResult ajax = AjaxResult.success(user); + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); + return ajax; + } + + /** + * 淇敼鐢ㄦ埛 + */ + @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult updateProfile(@RequestBody SysUser user) + { + if (userService.updateUserProfile(user) > 0) + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + // 鏇存柊缂撳瓨鐢ㄦ埛淇℃伅 + loginUser.getUser().setNickName(user.getNickName()); + loginUser.getUser().setPhonenumber(user.getPhonenumber()); + loginUser.getUser().setEmail(user.getEmail()); + loginUser.getUser().setSex(user.getSex()); + tokenService.setLoginUser(loginUser); + return AjaxResult.success(); + } + return AjaxResult.error("淇敼涓汉淇℃伅寮傚父锛岃鑱旂郴绠$悊鍛�"); + } + + /** + * 閲嶇疆瀵嗙爜 + */ + @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE) + @PutMapping("/updatePwd") + public AjaxResult updatePwd(String oldPassword, String newPassword) + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + String userName = loginUser.getUsername(); + String password = loginUser.getPassword(); + if (!SecurityUtils.matchesPassword(oldPassword, password)) + { + return AjaxResult.error("淇敼瀵嗙爜澶辫触锛屾棫瀵嗙爜閿欒"); + } + if (SecurityUtils.matchesPassword(newPassword, password)) + { + return AjaxResult.error("鏂板瘑鐮佷笉鑳戒笌鏃у瘑鐮佺浉鍚�"); + } + if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) + { + // 鏇存柊缂撳瓨鐢ㄦ埛瀵嗙爜 + loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword)); + tokenService.setLoginUser(loginUser); + return AjaxResult.success(); + } + return AjaxResult.error("淇敼瀵嗙爜寮傚父锛岃鑱旂郴绠$悊鍛�"); + } + + /** + * 澶村儚涓婁紶 + */ + @Log(title = "鐢ㄦ埛澶村儚", businessType = BusinessType.UPDATE) + @PostMapping("/avatar") + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException + { + if (!file.isEmpty()) + { + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file); + if (userService.updateUserAvatar(loginUser.getUsername(), avatar)) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("imgUrl", avatar); + // 鏇存柊缂撳瓨鐢ㄦ埛澶村儚 + loginUser.getUser().setAvatar(avatar); + tokenService.setLoginUser(loginUser); + return ajax; + } + } + return AjaxResult.error("涓婁紶鍥剧墖寮傚父锛岃鑱旂郴绠$悊鍛�"); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java new file mode 100644 index 0000000..2343ed9 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysRoleController.java @@ -0,0 +1,154 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysRole; +import com.ruoyi.project.system.service.ISysRoleService; + +/** + * 瑙掕壊淇℃伅 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + @Autowired + private ISysRoleService roleService; + + @PreAuthorize("@ss.hasPermi('system:role:list')") + @GetMapping("/list") + public TableDataInfo list(SysRole role) + { + startPage(); + List<SysRole> list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:role:export')") + @GetMapping("/export") + public AjaxResult export(SysRole role) + { + List<SysRole> list = roleService.selectRoleList(role); + ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class); + return util.exportExcel(list, "瑙掕壊鏁版嵁"); + } + + /** + * 鏍规嵁瑙掕壊缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping(value = "/{roleId}") + public AjaxResult getInfo(@PathVariable Long roleId) + { + return AjaxResult.success(roleService.selectRoleById(roleId)); + } + + /** + * 鏂板瑙掕壊 + */ + @PreAuthorize("@ss.hasPermi('system:role:add')") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysRole role) + { + if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return AjaxResult.error("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return AjaxResult.error("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪"); + } + role.setCreateBy(SecurityUtils.getUsername()); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 淇敼淇濆瓨瑙掕壊 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return AjaxResult.error("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return AjaxResult.error("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪"); + } + role.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(roleService.updateRole(role)); + } + + /** + * 淇敼淇濆瓨鏁版嵁鏉冮檺 + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE) + @PutMapping("/dataScope") + public AjaxResult dataScope(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + return toAjax(roleService.authDataScope(role)); + } + + /** + * 鐘舵�佷慨鏀� + */ + @PreAuthorize("@ss.hasPermi('system:role:edit')") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysRole role) + { + roleService.checkRoleAllowed(role); + role.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(roleService.updateRoleStatus(role)); + } + + /** + * 鍒犻櫎瑙掕壊 + */ + @PreAuthorize("@ss.hasPermi('system:role:remove')") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.DELETE) + @DeleteMapping("/{roleIds}") + public AjaxResult remove(@PathVariable Long[] roleIds) + { + return toAjax(roleService.deleteRoleByIds(roleIds)); + } + + /** + * 鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛� + */ + @PreAuthorize("@ss.hasPermi('system:role:query')") + @GetMapping("/optionselect") + public AjaxResult optionselect() + { + return AjaxResult.success(roleService.selectRoleAll()); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java new file mode 100644 index 0000000..a1eb442 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/controller/SysUserController.java @@ -0,0 +1,198 @@ +package com.ruoyi.project.system.controller; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.framework.security.service.TokenService; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.service.ISysPostService; +import com.ruoyi.project.system.service.ISysRoleService; +import com.ruoyi.project.system.service.ISysUserService; + +/** + * 鐢ㄦ埛淇℃伅 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysPostService postService; + + @Autowired + private TokenService tokenService; + + /** + * 鑾峰彇鐢ㄦ埛鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('system:user:list')") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List<SysUser> list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.EXPORT) + @PreAuthorize("@ss.hasPermi('system:user:export')") + @GetMapping("/export") + public AjaxResult export(SysUser user) + { + List<SysUser> list = userService.selectUserList(user); + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); + return util.exportExcel(list, "鐢ㄦ埛鏁版嵁"); + } + + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.IMPORT) + @PreAuthorize("@ss.hasPermi('system:user:import')") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); + List<SysUser> userList = util.importExcel(file.getInputStream()); + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + String operName = loginUser.getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return AjaxResult.success(message); + } + + @GetMapping("/importTemplate") + public AjaxResult importTemplate() + { + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); + return util.importTemplateExcel("鐢ㄦ埛鏁版嵁"); + } + + /** + * 鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('system:user:query')") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + AjaxResult ajax = AjaxResult.success(); + ajax.put("roles", roleService.selectRoleAll()); + ajax.put("posts", postService.selectPostAll()); + if (StringUtils.isNotNull(userId)) + { + ajax.put(AjaxResult.DATA_TAG, userService.selectUserById(userId)); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", roleService.selectRoleListByUserId(userId)); + } + return ajax; + } + + /** + * 鏂板鐢ㄦ埛 + */ + @PreAuthorize("@ss.hasPermi('system:user:add')") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) + { + return AjaxResult.error("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岀櫥褰曡处鍙峰凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return AjaxResult.error("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return AjaxResult.error("鏂板鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪"); + } + user.setCreateBy(SecurityUtils.getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + return toAjax(userService.insertUser(user)); + } + + /** + * 淇敼鐢ㄦ埛 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + if (UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return AjaxResult.error("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪"); + } + else if (UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return AjaxResult.error("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪"); + } + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 鍒犻櫎鐢ㄦ埛 + */ + @PreAuthorize("@ss.hasPermi('system:user:remove')") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 閲嶇疆瀵嗙爜 + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 鐘舵�佷慨鏀� + */ + @PreAuthorize("@ss.hasPermi('system:user:edit')") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUserStatus(user)); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java new file mode 100644 index 0000000..f9b290b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysConfig.java @@ -0,0 +1,111 @@ +package com.ruoyi.project.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 鍙傛暟閰嶇疆琛� sys_config + * + * @author ruoyi + */ +public class SysConfig extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 鍙傛暟涓婚敭 */ + @Excel(name = "鍙傛暟涓婚敭", cellType = ColumnType.NUMERIC) + private Long configId; + + /** 鍙傛暟鍚嶇О */ + @Excel(name = "鍙傛暟鍚嶇О") + private String configName; + + /** 鍙傛暟閿悕 */ + @Excel(name = "鍙傛暟閿悕") + private String configKey; + + /** 鍙傛暟閿�� */ + @Excel(name = "鍙傛暟閿��") + private String configValue; + + /** 绯荤粺鍐呯疆锛圷鏄� N鍚︼級 */ + @Excel(name = "绯荤粺鍐呯疆", readConverterExp = "Y=鏄�,N=鍚�") + private String configType; + + public Long getConfigId() + { + return configId; + } + + public void setConfigId(Long configId) + { + this.configId = configId; + } + + @NotBlank(message = "鍙傛暟鍚嶇О涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "鍙傛暟鍚嶇О涓嶈兘瓒呰繃100涓瓧绗�") + public String getConfigName() + { + return configName; + } + + public void setConfigName(String configName) + { + this.configName = configName; + } + + @NotBlank(message = "鍙傛暟閿悕闀垮害涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "鍙傛暟閿悕闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getConfigKey() + { + return configKey; + } + + public void setConfigKey(String configKey) + { + this.configKey = configKey; + } + + @NotBlank(message = "鍙傛暟閿�间笉鑳戒负绌�") + @Size(min = 0, max = 500, message = "鍙傛暟閿�奸暱搴︿笉鑳借秴杩�500涓瓧绗�") + public String getConfigValue() + { + return configValue; + } + + public void setConfigValue(String configValue) + { + this.configValue = configValue; + } + + public String getConfigType() + { + return configType; + } + + public void setConfigType(String configType) + { + this.configType = configType; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("configId", getConfigId()) + .append("configName", getConfigName()) + .append("configKey", getConfigKey()) + .append("configValue", getConfigValue()) + .append("configType", getConfigType()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java new file mode 100644 index 0000000..9073439 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDept.java @@ -0,0 +1,202 @@ +package com.ruoyi.project.system.domain; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 閮ㄩ棬琛� sys_dept + * + * @author ruoyi + */ +public class SysDept extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 閮ㄩ棬ID */ + private Long deptId; + + /** 鐖堕儴闂↖D */ + private Long parentId; + + /** 绁栫骇鍒楄〃 */ + private String ancestors; + + /** 閮ㄩ棬鍚嶇О */ + private String deptName; + + /** 鏄剧ず椤哄簭 */ + private String orderNum; + + /** 璐熻矗浜� */ + private String leader; + + /** 鑱旂郴鐢佃瘽 */ + private String phone; + + /** 閭 */ + private String email; + + /** 閮ㄩ棬鐘舵��:0姝e父,1鍋滅敤 */ + private String status; + + /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */ + private String delFlag; + + /** 鐖堕儴闂ㄥ悕绉� */ + private String parentName; + + /** 瀛愰儴闂� */ + private List<SysDept> children = new ArrayList<SysDept>(); + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAncestors() + { + return ancestors; + } + + public void setAncestors(String ancestors) + { + this.ancestors = ancestors; + } + + @NotBlank(message = "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖") + @Size(min = 0, max = 30, message = "閮ㄩ棬鍚嶇О闀垮害涓嶈兘瓒呰繃30涓瓧绗�") + public String getDeptName() + { + return deptName; + } + + public void setDeptName(String deptName) + { + this.deptName = deptName; + } + + @NotBlank(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖") + public String getOrderNum() + { + return orderNum; + } + + public void setOrderNum(String orderNum) + { + this.orderNum = orderNum; + } + + public String getLeader() + { + return leader; + } + + public void setLeader(String leader) + { + this.leader = leader; + } + + @Size(min = 0, max = 11, message = "鑱旂郴鐢佃瘽闀垮害涓嶈兘瓒呰繃11涓瓧绗�") + public String getPhone() + { + return phone; + } + + public void setPhone(String phone) + { + this.phone = phone; + } + + @Email(message = "閭鏍煎紡涓嶆纭�") + @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃50涓瓧绗�") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public List<SysDept> getChildren() + { + return children; + } + + public void setChildren(List<SysDept> children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("deptId", getDeptId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("deptName", getDeptName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java new file mode 100644 index 0000000..d149653 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictData.java @@ -0,0 +1,176 @@ +package com.ruoyi.project.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 瀛楀吀鏁版嵁琛� sys_dict_data + * + * @author ruoyi + */ +public class SysDictData extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 瀛楀吀缂栫爜 */ + @Excel(name = "瀛楀吀缂栫爜", cellType = ColumnType.NUMERIC) + private Long dictCode; + + /** 瀛楀吀鎺掑簭 */ + @Excel(name = "瀛楀吀鎺掑簭", cellType = ColumnType.NUMERIC) + private Long dictSort; + + /** 瀛楀吀鏍囩 */ + @Excel(name = "瀛楀吀鏍囩") + private String dictLabel; + + /** 瀛楀吀閿�� */ + @Excel(name = "瀛楀吀閿��") + private String dictValue; + + /** 瀛楀吀绫诲瀷 */ + @Excel(name = "瀛楀吀绫诲瀷") + private String dictType; + + /** 鏍峰紡灞炴�э紙鍏朵粬鏍峰紡鎵╁睍锛� */ + private String cssClass; + + /** 琛ㄦ牸瀛楀吀鏍峰紡 */ + private String listClass; + + /** 鏄惁榛樿锛圷鏄� N鍚︼級 */ + @Excel(name = "鏄惁榛樿", readConverterExp = "Y=鏄�,N=鍚�") + private String isDefault; + + /** 鐘舵�侊紙0姝e父 1鍋滅敤锛� */ + @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤") + private String status; + + public Long getDictCode() + { + return dictCode; + } + + public void setDictCode(Long dictCode) + { + this.dictCode = dictCode; + } + + public Long getDictSort() + { + return dictSort; + } + + public void setDictSort(Long dictSort) + { + this.dictSort = dictSort; + } + + @NotBlank(message = "瀛楀吀鏍囩涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "瀛楀吀鏍囩闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getDictLabel() + { + return dictLabel; + } + + public void setDictLabel(String dictLabel) + { + this.dictLabel = dictLabel; + } + + @NotBlank(message = "瀛楀吀閿�间笉鑳戒负绌�") + @Size(min = 0, max = 100, message = "瀛楀吀閿�奸暱搴︿笉鑳借秴杩�100涓瓧绗�") + public String getDictValue() + { + return dictValue; + } + + public void setDictValue(String dictValue) + { + this.dictValue = dictValue; + } + + @NotBlank(message = "瀛楀吀绫诲瀷涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + @Size(min = 0, max = 100, message = "鏍峰紡灞炴�ч暱搴︿笉鑳借秴杩�100涓瓧绗�") + public String getCssClass() + { + return cssClass; + } + + public void setCssClass(String cssClass) + { + this.cssClass = cssClass; + } + + public String getListClass() + { + return listClass; + } + + public void setListClass(String listClass) + { + this.listClass = listClass; + } + + public boolean getDefault() + { + return UserConstants.YES.equals(this.isDefault) ? true : false; + } + + public String getIsDefault() + { + return isDefault; + } + + public void setIsDefault(String isDefault) + { + this.isDefault = isDefault; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictCode", getDictCode()) + .append("dictSort", getDictSort()) + .append("dictLabel", getDictLabel()) + .append("dictValue", getDictValue()) + .append("dictType", getDictType()) + .append("cssClass", getCssClass()) + .append("listClass", getListClass()) + .append("isDefault", getIsDefault()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java new file mode 100644 index 0000000..7887e66 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysDictType.java @@ -0,0 +1,94 @@ +package com.ruoyi.project.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 瀛楀吀绫诲瀷琛� sys_dict_type + * + * @author ruoyi + */ +public class SysDictType extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 瀛楀吀涓婚敭 */ + @Excel(name = "瀛楀吀涓婚敭", cellType = ColumnType.NUMERIC) + private Long dictId; + + /** 瀛楀吀鍚嶇О */ + @Excel(name = "瀛楀吀鍚嶇О") + private String dictName; + + /** 瀛楀吀绫诲瀷 */ + @Excel(name = "瀛楀吀绫诲瀷") + private String dictType; + + /** 鐘舵�侊紙0姝e父 1鍋滅敤锛� */ + @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤") + private String status; + + public Long getDictId() + { + return dictId; + } + + public void setDictId(Long dictId) + { + this.dictId = dictId; + } + + @NotBlank(message = "瀛楀吀鍚嶇О涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷鍚嶇О闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getDictName() + { + return dictName; + } + + public void setDictName(String dictName) + { + this.dictName = dictName; + } + + @NotBlank(message = "瀛楀吀绫诲瀷涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "瀛楀吀绫诲瀷绫诲瀷闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getDictType() + { + return dictType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("dictId", getDictId()) + .append("dictName", getDictName()) + .append("dictType", getDictType()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java new file mode 100644 index 0000000..36c8592 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysMenu.java @@ -0,0 +1,217 @@ +package com.ruoyi.project.system.domain; + +import java.util.ArrayList; +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 鑿滃崟鏉冮檺琛� sys_menu + * + * @author ruoyi + */ +public class SysMenu extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 鑿滃崟ID */ + private Long menuId; + + /** 鑿滃崟鍚嶇О */ + private String menuName; + + /** 鐖惰彍鍗曞悕绉� */ + private String parentName; + + /** 鐖惰彍鍗旾D */ + private Long parentId; + + /** 鏄剧ず椤哄簭 */ + private String orderNum; + + /** 璺敱鍦板潃 */ + private String path; + + /** 缁勪欢璺緞 */ + private String component; + + /** 鏄惁涓哄閾撅紙0鏄� 1鍚︼級 */ + private String isFrame; + + /** 绫诲瀷锛圡鐩綍 C鑿滃崟 F鎸夐挳锛� */ + private String menuType; + + /** 鑿滃崟鐘舵��:0鏄剧ず,1闅愯棌 */ + private String visible; + + /** 鏉冮檺瀛楃涓� */ + private String perms; + + /** 鑿滃崟鍥炬爣 */ + private String icon; + + /** 瀛愯彍鍗� */ + private List<SysMenu> children = new ArrayList<SysMenu>(); + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @NotBlank(message = "鑿滃崟鍚嶇О涓嶈兘涓虹┖") + @Size(min = 0, max = 50, message = "鑿滃崟鍚嶇О闀垮害涓嶈兘瓒呰繃50涓瓧绗�") + public String getMenuName() + { + return menuName; + } + + public void setMenuName(String menuName) + { + this.menuName = menuName; + } + + public String getParentName() + { + return parentName; + } + + public void setParentName(String parentName) + { + this.parentName = parentName; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + @NotBlank(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖") + public String getOrderNum() + { + return orderNum; + } + + public void setOrderNum(String orderNum) + { + this.orderNum = orderNum; + } + + @Size(min = 0, max = 200, message = "璺敱鍦板潃涓嶈兘瓒呰繃200涓瓧绗�") + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + @Size(min = 0, max = 200, message = "缁勪欢璺緞涓嶈兘瓒呰繃255涓瓧绗�") + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public String getIsFrame() + { + return isFrame; + } + + public void setIsFrame(String isFrame) + { + this.isFrame = isFrame; + } + + @NotBlank(message = "鑿滃崟绫诲瀷涓嶈兘涓虹┖") + public String getMenuType() + { + return menuType; + } + + public void setMenuType(String menuType) + { + this.menuType = menuType; + } + + public String getVisible() + { + return visible; + } + + public void setVisible(String visible) + { + this.visible = visible; + } + + @Size(min = 0, max = 100, message = "鏉冮檺鏍囪瘑闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getPerms() + { + return perms; + } + + public void setPerms(String perms) + { + this.perms = perms; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } + + public List<SysMenu> getChildren() + { + return children; + } + + public void setChildren(List<SysMenu> children) + { + this.children = children; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("menuId", getMenuId()) + .append("menuName", getMenuName()) + .append("parentId", getParentId()) + .append("orderNum", getOrderNum()) + .append("path", getPath()) + .append("component", getComponent()) + .append("isFrame", getIsFrame()) + .append("menuType", getMenuType()) + .append("visible", getVisible()) + .append("perms", getPerms()) + .append("icon", getIcon()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java new file mode 100644 index 0000000..0215f4a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysNotice.java @@ -0,0 +1,100 @@ +package com.ruoyi.project.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 閫氱煡鍏憡琛� sys_notice + * + * @author ruoyi + */ +public class SysNotice extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 鍏憡ID */ + private Long noticeId; + + /** 鍏憡鏍囬 */ + private String noticeTitle; + + /** 鍏憡绫诲瀷锛�1閫氱煡 2鍏憡锛� */ + private String noticeType; + + /** 鍏憡鍐呭 */ + private String noticeContent; + + /** 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛� */ + private String status; + + public Long getNoticeId() + { + return noticeId; + } + + public void setNoticeId(Long noticeId) + { + this.noticeId = noticeId; + } + + public void setNoticeTitle(String noticeTitle) + { + this.noticeTitle = noticeTitle; + } + + @NotBlank(message = "鍏憡鏍囬涓嶈兘涓虹┖") + @Size(min = 0, max = 50, message = "鍏憡鏍囬涓嶈兘瓒呰繃50涓瓧绗�") + public String getNoticeTitle() + { + return noticeTitle; + } + + public void setNoticeType(String noticeType) + { + this.noticeType = noticeType; + } + + public String getNoticeType() + { + return noticeType; + } + + public void setNoticeContent(String noticeContent) + { + this.noticeContent = noticeContent; + } + + public String getNoticeContent() + { + return noticeContent; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("noticeId", getNoticeId()) + .append("noticeTitle", getNoticeTitle()) + .append("noticeType", getNoticeType()) + .append("noticeContent", getNoticeContent()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java new file mode 100644 index 0000000..c41a995 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysPost.java @@ -0,0 +1,123 @@ +package com.ruoyi.project.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 宀椾綅琛� sys_post + * + * @author ruoyi + */ +public class SysPost extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 宀椾綅搴忓彿 */ + @Excel(name = "宀椾綅搴忓彿", cellType = ColumnType.NUMERIC) + private Long postId; + + /** 宀椾綅缂栫爜 */ + @Excel(name = "宀椾綅缂栫爜") + private String postCode; + + /** 宀椾綅鍚嶇О */ + @Excel(name = "宀椾綅鍚嶇О") + private String postName; + + /** 宀椾綅鎺掑簭 */ + @Excel(name = "宀椾綅鎺掑簭") + private String postSort; + + /** 鐘舵�侊紙0姝e父 1鍋滅敤锛� */ + @Excel(name = "鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤") + private String status; + + /** 鐢ㄦ埛鏄惁瀛樺湪姝ゅ矖浣嶆爣璇� 榛樿涓嶅瓨鍦� */ + private boolean flag = false; + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @NotBlank(message = "宀椾綅缂栫爜涓嶈兘涓虹┖") + @Size(min = 0, max = 64, message = "宀椾綅缂栫爜闀垮害涓嶈兘瓒呰繃64涓瓧绗�") + public String getPostCode() + { + return postCode; + } + + public void setPostCode(String postCode) + { + this.postCode = postCode; + } + + @NotBlank(message = "宀椾綅鍚嶇О涓嶈兘涓虹┖") + @Size(min = 0, max = 50, message = "宀椾綅鍚嶇О闀垮害涓嶈兘瓒呰繃50涓瓧绗�") + public String getPostName() + { + return postName; + } + + public void setPostName(String postName) + { + this.postName = postName; + } + + @NotBlank(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖") + public String getPostSort() + { + return postSort; + } + + public void setPostSort(String postSort) + { + this.postSort = postSort; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("postId", getPostId()) + .append("postCode", getPostCode()) + .append("postName", getPostName()) + .append("postSort", getPostSort()) + .append("status", getStatus()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java new file mode 100644 index 0000000..d9acb73 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRole.java @@ -0,0 +1,197 @@ +package com.ruoyi.project.system.domain; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 瑙掕壊琛� sys_role + * + * @author ruoyi + */ +public class SysRole extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 瑙掕壊ID */ + @Excel(name = "瑙掕壊搴忓彿", cellType = ColumnType.NUMERIC) + private Long roleId; + + /** 瑙掕壊鍚嶇О */ + @Excel(name = "瑙掕壊鍚嶇О") + private String roleName; + + /** 瑙掕壊鏉冮檺 */ + @Excel(name = "瑙掕壊鏉冮檺") + private String roleKey; + + /** 瑙掕壊鎺掑簭 */ + @Excel(name = "瑙掕壊鎺掑簭") + private String roleSort; + + /** 鏁版嵁鑼冨洿锛�1锛氭墍鏈夋暟鎹潈闄愶紱2锛氳嚜瀹氫箟鏁版嵁鏉冮檺锛�3锛氭湰閮ㄩ棬鏁版嵁鏉冮檺锛�4锛氭湰閮ㄩ棬鍙婁互涓嬫暟鎹潈闄愶級 */ + @Excel(name = "鏁版嵁鑼冨洿", readConverterExp = "1=鎵�鏈夋暟鎹潈闄�,2=鑷畾涔夋暟鎹潈闄�,3=鏈儴闂ㄦ暟鎹潈闄�,4=鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺") + private String dataScope; + + /** 瑙掕壊鐘舵�侊紙0姝e父 1鍋滅敤锛� */ + @Excel(name = "瑙掕壊鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤") + private String status; + + /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */ + private String delFlag; + + /** 鐢ㄦ埛鏄惁瀛樺湪姝よ鑹叉爣璇� 榛樿涓嶅瓨鍦� */ + private boolean flag = false; + + /** 鑿滃崟缁� */ + private Long[] menuIds; + + /** 閮ㄩ棬缁勶紙鏁版嵁鏉冮檺锛� */ + private Long[] deptIds; + + public SysRole() + { + + } + + public SysRole(Long roleId) + { + this.roleId = roleId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public boolean isAdmin() + { + return isAdmin(this.roleId); + } + + public static boolean isAdmin(Long roleId) + { + return roleId != null && 1L == roleId; + } + + @NotBlank(message = "瑙掕壊鍚嶇О涓嶈兘涓虹┖") + @Size(min = 0, max = 30, message = "瑙掕壊鍚嶇О闀垮害涓嶈兘瓒呰繃30涓瓧绗�") + public String getRoleName() + { + return roleName; + } + + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + @NotBlank(message = "鏉冮檺瀛楃涓嶈兘涓虹┖") + @Size(min = 0, max = 100, message = "鏉冮檺瀛楃闀垮害涓嶈兘瓒呰繃100涓瓧绗�") + public String getRoleKey() + { + return roleKey; + } + + public void setRoleKey(String roleKey) + { + this.roleKey = roleKey; + } + + @NotBlank(message = "鏄剧ず椤哄簭涓嶈兘涓虹┖") + public String getRoleSort() + { + return roleSort; + } + + public void setRoleSort(String roleSort) + { + this.roleSort = roleSort; + } + + public String getDataScope() + { + return dataScope; + } + + public void setDataScope(String dataScope) + { + this.dataScope = dataScope; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public boolean isFlag() + { + return flag; + } + + public void setFlag(boolean flag) + { + this.flag = flag; + } + + public Long[] getMenuIds() + { + return menuIds; + } + + public void setMenuIds(Long[] menuIds) + { + this.menuIds = menuIds; + } + + public Long[] getDeptIds() + { + return deptIds; + } + + public void setDeptIds(Long[] deptIds) + { + this.deptIds = deptIds; + } + + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("roleName", getRoleName()) + .append("roleKey", getRoleKey()) + .append("roleSort", getRoleSort()) + .append("dataScope", getDataScope()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleDept.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleDept.java new file mode 100644 index 0000000..5cbeed4 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleDept.java @@ -0,0 +1,46 @@ +package com.ruoyi.project.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 瑙掕壊鍜岄儴闂ㄥ叧鑱� sys_role_dept + * + * @author ruoyi + */ +public class SysRoleDept +{ + /** 瑙掕壊ID */ + private Long roleId; + + /** 閮ㄩ棬ID */ + private Long deptId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("deptId", getDeptId()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleMenu.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleMenu.java new file mode 100644 index 0000000..2772cbb --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysRoleMenu.java @@ -0,0 +1,46 @@ +package com.ruoyi.project.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 瑙掕壊鍜岃彍鍗曞叧鑱� sys_role_menu + * + * @author ruoyi + */ +public class SysRoleMenu +{ + /** 瑙掕壊ID */ + private Long roleId; + + /** 鑿滃崟ID */ + private Long menuId; + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + public Long getMenuId() + { + return menuId; + } + + public void setMenuId(Long menuId) + { + this.menuId = menuId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("roleId", getRoleId()) + .append("menuId", getMenuId()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java new file mode 100644 index 0000000..8c461b1 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUser.java @@ -0,0 +1,324 @@ +package com.ruoyi.project.system.domain; + +import java.util.Date; +import java.util.List; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType; +import com.ruoyi.framework.aspectj.lang.annotation.Excel.Type; +import com.ruoyi.framework.aspectj.lang.annotation.Excels; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 鐢ㄦ埛瀵硅薄 sys_user + * + * @author ruoyi + */ +public class SysUser extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 鐢ㄦ埛ID */ + @Excel(name = "鐢ㄦ埛搴忓彿", cellType = ColumnType.NUMERIC, prompt = "鐢ㄦ埛缂栧彿") + private Long userId; + + /** 閮ㄩ棬ID */ + @Excel(name = "閮ㄩ棬缂栧彿", type = Type.IMPORT) + private Long deptId; + + /** 鐢ㄦ埛璐﹀彿 */ + @Excel(name = "鐧诲綍鍚嶇О") + private String userName; + + /** 鐢ㄦ埛鏄电О */ + @Excel(name = "鐢ㄦ埛鍚嶇О") + private String nickName; + + /** 鐢ㄦ埛閭 */ + @Excel(name = "鐢ㄦ埛閭") + private String email; + + /** 鎵嬫満鍙风爜 */ + @Excel(name = "鎵嬫満鍙风爜") + private String phonenumber; + + /** 鐢ㄦ埛鎬у埆 */ + @Excel(name = "鐢ㄦ埛鎬у埆", readConverterExp = "0=鐢�,1=濂�,2=鏈煡") + private String sex; + + /** 鐢ㄦ埛澶村儚 */ + private String avatar; + + /** 瀵嗙爜 */ + private String password; + + /** 鐩愬姞瀵� */ + private String salt; + + /** 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛� */ + @Excel(name = "甯愬彿鐘舵��", readConverterExp = "0=姝e父,1=鍋滅敤") + private String status; + + /** 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛� */ + private String delFlag; + + /** 鏈�鍚庣櫥闄咺P */ + @Excel(name = "鏈�鍚庣櫥闄咺P", type = Type.EXPORT) + private String loginIp; + + /** 鏈�鍚庣櫥闄嗘椂闂� */ + @Excel(name = "鏈�鍚庣櫥闄嗘椂闂�", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Date loginDate; + + /** 閮ㄩ棬瀵硅薄 */ + @Excels({ + @Excel(name = "閮ㄩ棬鍚嶇О", targetAttr = "deptName", type = Type.EXPORT), + @Excel(name = "閮ㄩ棬璐熻矗浜�", targetAttr = "leader", type = Type.EXPORT) + }) + private SysDept dept; + + /** 瑙掕壊瀵硅薄 */ + private List<SysRole> roles; + + /** 瑙掕壊缁� */ + private Long[] roleIds; + + /** 宀椾綅缁� */ + private Long[] postIds; + + public SysUser() + { + + } + + public SysUser(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public boolean isAdmin() + { + return isAdmin(this.userId); + } + + public static boolean isAdmin(Long userId) + { + return userId != null && 1L == userId; + } + + public Long getDeptId() + { + return deptId; + } + + public void setDeptId(Long deptId) + { + this.deptId = deptId; + } + + @Size(min = 0, max = 30, message = "鐢ㄦ埛鏄电О闀垮害涓嶈兘瓒呰繃30涓瓧绗�") + public String getNickName() + { + return nickName; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + @NotBlank(message = "鐢ㄦ埛璐﹀彿涓嶈兘涓虹┖") + @Size(min = 0, max = 30, message = "鐢ㄦ埛璐﹀彿闀垮害涓嶈兘瓒呰繃30涓瓧绗�") + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + @Email(message = "閭鏍煎紡涓嶆纭�") + @Size(min = 0, max = 50, message = "閭闀垮害涓嶈兘瓒呰繃50涓瓧绗�") + public String getEmail() + { + return email; + } + + public void setEmail(String email) + { + this.email = email; + } + + @Size(min = 0, max = 11, message = "鎵嬫満鍙风爜闀垮害涓嶈兘瓒呰繃11涓瓧绗�") + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getAvatar() + { + return avatar; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getSalt() + { + return salt; + } + + public void setSalt(String salt) + { + this.salt = salt; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getLoginIp() + { + return loginIp; + } + + public void setLoginIp(String loginIp) + { + this.loginIp = loginIp; + } + + public Date getLoginDate() + { + return loginDate; + } + + public void setLoginDate(Date loginDate) + { + this.loginDate = loginDate; + } + + public SysDept getDept() + { + return dept; + } + + public void setDept(SysDept dept) + { + this.dept = dept; + } + + public List<SysRole> getRoles() + { + return roles; + } + + public void setRoles(List<SysRole> roles) + { + this.roles = roles; + } + + public Long[] getRoleIds() + { + return roleIds; + } + + public void setRoleIds(Long[] roleIds) + { + this.roleIds = roleIds; + } + + public Long[] getPostIds() + { + return postIds; + } + + public void setPostIds(Long[] postIds) + { + this.postIds = postIds; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("deptId", getDeptId()) + .append("userName", getUserName()) + .append("nickName", getNickName()) + .append("email", getEmail()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("avatar", getAvatar()) + .append("password", getPassword()) + .append("salt", getSalt()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("loginIp", getLoginIp()) + .append("loginDate", getLoginDate()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .append("dept", getDept()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserPost.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserPost.java new file mode 100644 index 0000000..2633a2f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserPost.java @@ -0,0 +1,46 @@ +package com.ruoyi.project.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 鐢ㄦ埛鍜屽矖浣嶅叧鑱� sys_user_post + * + * @author ruoyi + */ +public class SysUserPost +{ + /** 鐢ㄦ埛ID */ + private Long userId; + + /** 宀椾綅ID */ + private Long postId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getPostId() + { + return postId; + } + + public void setPostId(Long postId) + { + this.postId = postId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("postId", getPostId()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserRole.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserRole.java new file mode 100644 index 0000000..3be4829 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/SysUserRole.java @@ -0,0 +1,46 @@ +package com.ruoyi.project.system.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 鐢ㄦ埛鍜岃鑹插叧鑱� sys_user_role + * + * @author ruoyi + */ +public class SysUserRole +{ + /** 鐢ㄦ埛ID */ + private Long userId; + + /** 瑙掕壊ID */ + private Long roleId; + + public Long getUserId() + { + return userId; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getRoleId() + { + return roleId; + } + + public void setRoleId(Long roleId) + { + this.roleId = roleId; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("userId", getUserId()) + .append("roleId", getRoleId()) + .toString(); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/MetaVo.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/MetaVo.java new file mode 100644 index 0000000..9a1ccb6 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/MetaVo.java @@ -0,0 +1,49 @@ +package com.ruoyi.project.system.domain.vo; + +/** + * 璺敱鏄剧ず淇℃伅 + * + * @author ruoyi + */ +public class MetaVo +{ + /** + * 璁剧疆璇ヨ矾鐢卞湪渚ц竟鏍忓拰闈㈠寘灞戜腑灞曠ず鐨勫悕瀛� + */ + private String title; + + /** + * 璁剧疆璇ヨ矾鐢辩殑鍥炬爣锛屽搴旇矾寰剆rc/icons/svg + */ + private String icon; + + public MetaVo() + { + } + + public MetaVo(String title, String icon) + { + this.title = title; + this.icon = icon; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getIcon() + { + return icon; + } + + public void setIcon(String icon) + { + this.icon = icon; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/RouterVo.java b/ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/RouterVo.java new file mode 100644 index 0000000..13fb3e6 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/domain/vo/RouterVo.java @@ -0,0 +1,133 @@ +package com.ruoyi.project.system.domain.vo; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; + +/** + * 璺敱閰嶇疆淇℃伅 + * + * @author ruoyi + */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class RouterVo +{ + /** + * 璺敱鍚嶅瓧 + */ + private String name; + + /** + * 璺敱鍦板潃 + */ + private String path; + + /** + * 鏄惁闅愯棌璺敱锛屽綋璁剧疆 true 鐨勬椂鍊欒璺敱涓嶄細鍐嶄晶杈规爮鍑虹幇 + */ + private String hidden; + + /** + * 閲嶅畾鍚戝湴鍧�锛屽綋璁剧疆 noRedirect 鐨勬椂鍊欒璺敱鍦ㄩ潰鍖呭睉瀵艰埅涓笉鍙鐐瑰嚮 + */ + private String redirect; + + /** + * 缁勪欢鍦板潃 + */ + private String component; + + /** + * 褰撲綘涓�涓矾鐢变笅闈㈢殑 children 澹版槑鐨勮矾鐢卞ぇ浜�1涓椂锛岃嚜鍔ㄤ細鍙樻垚宓屽鐨勬ā寮�--濡傜粍浠堕〉闈� + */ + private Boolean alwaysShow; + + /** + * 鍏朵粬鍏冪礌 + */ + private MetaVo meta; + + /** + * 瀛愯矾鐢� + */ + private List<RouterVo> children; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPath() + { + return path; + } + + public void setPath(String path) + { + this.path = path; + } + + public String getHidden() + { + return hidden; + } + + public void setHidden(String hidden) + { + this.hidden = hidden; + } + + public String getRedirect() + { + return redirect; + } + + public void setRedirect(String redirect) + { + this.redirect = redirect; + } + + public String getComponent() + { + return component; + } + + public void setComponent(String component) + { + this.component = component; + } + + public Boolean getAlwaysShow() + { + return alwaysShow; + } + + public void setAlwaysShow(Boolean alwaysShow) + { + this.alwaysShow = alwaysShow; + } + + public MetaVo getMeta() + { + return meta; + } + + public void setMeta(MetaVo meta) + { + this.meta = meta; + } + + public List<RouterVo> getChildren() + { + return children; + } + + public void setChildren(List<RouterVo> children) + { + this.children = children; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java new file mode 100644 index 0000000..ea275d7 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysConfigMapper.java @@ -0,0 +1,68 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysConfig; + +/** + * 鍙傛暟閰嶇疆 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysConfigMapper +{ + /** + * 鏌ヨ鍙傛暟閰嶇疆淇℃伅 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 鍙傛暟閰嶇疆淇℃伅 + */ + public SysConfig selectConfig(SysConfig config); + + /** + * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 鍙傛暟閰嶇疆闆嗗悎 + */ + public List<SysConfig> selectConfigList(SysConfig config); + + /** + * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅 + * + * @param configKey 鍙傛暟閿悕 + * @return 鍙傛暟閰嶇疆淇℃伅 + */ + public SysConfig checkConfigKeyUnique(String configKey); + + /** + * 鏂板鍙傛暟閰嶇疆 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + public int insertConfig(SysConfig config); + + /** + * 淇敼鍙傛暟閰嶇疆 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + public int updateConfig(SysConfig config); + + /** + * 鍒犻櫎鍙傛暟閰嶇疆 + * + * @param configId 鍙傛暟ID + * @return 缁撴灉 + */ + public int deleteConfigById(Long configId); + + /** + * 鎵归噺鍒犻櫎鍙傛暟淇℃伅 + * + * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID + * @return 缁撴灉 + */ + public int deleteConfigByIds(Long[] configIds); +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java new file mode 100644 index 0000000..1df5f2e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java @@ -0,0 +1,109 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.project.system.domain.SysDept; + +/** + * 閮ㄩ棬绠$悊 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysDeptMapper +{ + /** + * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 閮ㄩ棬淇℃伅闆嗗悎 + */ + public List<SysDept> selectDeptList(SysDept dept); + + /** + * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭� + * + * @param roleId 瑙掕壊ID + * @return 閫変腑閮ㄩ棬鍒楄〃 + */ + public List<Integer> selectDeptListByRoleId(Long roleId); + + /** + * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅 + * + * @param deptId 閮ㄩ棬ID + * @return 閮ㄩ棬淇℃伅 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 鏍规嵁ID鏌ヨ鎵�鏈夊瓙閮ㄩ棬 + * + * @param deptId 閮ㄩ棬ID + * @return 閮ㄩ棬鍒楄〃 + */ + public List<SysDept> selectChildrenDeptById(Long deptId); + + /** + * 鏄惁瀛樺湪瀛愯妭鐐� + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + public int hasChildByDeptId(Long deptId); + + /** + * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + public int checkDeptExistUser(Long deptId); + + /** + * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴 + * + * @param deptName 閮ㄩ棬鍚嶇О + * @param parentId 鐖堕儴闂↖D + * @return 缁撴灉 + */ + public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId); + + /** + * 鏂板閮ㄩ棬淇℃伅 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + public int insertDept(SysDept dept); + + /** + * 淇敼閮ㄩ棬淇℃伅 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + public int updateDept(SysDept dept); + + /** + * 淇敼鎵�鍦ㄩ儴闂ㄧ殑鐖剁骇閮ㄩ棬鐘舵�� + * + * @param dept 閮ㄩ棬 + */ + public void updateDeptStatus(SysDept dept); + + /** + * 淇敼瀛愬厓绱犲叧绯� + * + * @param depts 瀛愬厓绱� + * @return 缁撴灉 + */ + public int updateDeptChildren(@Param("depts") List<SysDept> depts); + + /** + * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java new file mode 100644 index 0000000..4977bb4 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictDataMapper.java @@ -0,0 +1,95 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.project.system.domain.SysDictData; + +/** + * 瀛楀吀琛� 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysDictDataMapper +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅 + */ + public List<SysDictData> selectDictDataList(SysDictData dictData); + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅 + */ + public List<SysDictData> selectDictDataByType(String dictType); + + /** + * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭� + * + * @param dictType 瀛楀吀绫诲瀷 + * @param dictValue 瀛楀吀閿�� + * @return 瀛楀吀鏍囩 + */ + public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue); + + /** + * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅 + * + * @param dictCode 瀛楀吀鏁版嵁ID + * @return 瀛楀吀鏁版嵁 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀鏁版嵁 + */ + public int countDictDataByType(String dictType); + + /** + * 閫氳繃瀛楀吀ID鍒犻櫎瀛楀吀鏁版嵁淇℃伅 + * + * @param dictCode 瀛楀吀鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅 + * + * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 鏂板瀛楀吀鏁版嵁淇℃伅 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 缁撴灉 + */ + public int insertDictData(SysDictData dictData); + + /** + * 淇敼瀛楀吀鏁版嵁淇℃伅 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 缁撴灉 + */ + public int updateDictData(SysDictData dictData); + + /** + * 鍚屾淇敼瀛楀吀绫诲瀷 + * + * @param oldDictType 鏃у瓧鍏哥被鍨� + * @param newDictType 鏂版棫瀛楀吀绫诲瀷 + * @return 缁撴灉 + */ + public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java new file mode 100644 index 0000000..a070955 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysDictTypeMapper.java @@ -0,0 +1,85 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Mapper; +import com.ruoyi.project.system.domain.SysDictType; + +/** + * 瀛楀吀琛� 鏁版嵁灞� + * + * @author ruoyi + */ +@Mapper +public interface SysDictTypeMapper +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅 + */ + public List<SysDictType> selectDictTypeList(SysDictType dictType); + + /** + * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨� + * + * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅 + */ + public List<SysDictType> selectDictTypeAll(); + + /** + * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅 + * + * @param dictId 瀛楀吀绫诲瀷ID + * @return 瀛楀吀绫诲瀷 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀绫诲瀷 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 閫氳繃瀛楀吀ID鍒犻櫎瀛楀吀淇℃伅 + * + * @param dictId 瀛楀吀ID + * @return 缁撴灉 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 鎵归噺鍒犻櫎瀛楀吀绫诲瀷淇℃伅 + * + * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID + * @return 缁撴灉 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 鏂板瀛楀吀绫诲瀷淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 缁撴灉 + */ + public int insertDictType(SysDictType dictType); + + /** + * 淇敼瀛楀吀绫诲瀷淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 缁撴灉 + */ + public int updateDictType(SysDictType dictType); + + /** + * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓� + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 缁撴灉 + */ + public SysDictType checkDictTypeUnique(String dictType); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..f4e0c32 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java @@ -0,0 +1,116 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.project.system.domain.SysMenu; + +/** + * 鑿滃崟琛� 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysMenuMapper +{ + /** + * 鏌ヨ绯荤粺鑿滃崟鍒楄〃 + * + * @param menu 鑿滃崟淇℃伅 + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuList(SysMenu menu); + + /** + * 鏍规嵁鐢ㄦ埛鎵�鏈夋潈闄� + * + * @return 鏉冮檺鍒楄〃 + */ + public List<String> selectMenuPerms(); + + /** + * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃 + * + * @param menu 鑿滃崟淇℃伅 + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuListByUserId(SysMenu menu); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺 + * + * @param userId 鐢ㄦ埛ID + * @return 鏉冮檺鍒楄〃 + */ + public List<String> selectMenuPermsByUserId(Long userId); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟 + * + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuTreeAll(); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟 + * + * @param username 鐢ㄦ埛ID + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuTreeByUserId(Long userId); + + /** + * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭� + * + * @param roleId 瑙掕壊ID + * @return 閫変腑鑿滃崟鍒楄〃 + */ + public List<Integer> selectMenuListByRoleId(Long roleId); + + /** + * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅 + * + * @param menuId 鑿滃崟ID + * @return 鑿滃崟淇℃伅 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐� + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + public int hasChildByMenuId(Long menuId); + + /** + * 鏂板鑿滃崟淇℃伅 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + public int insertMenu(SysMenu menu); + + /** + * 淇敼鑿滃崟淇℃伅 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + public int updateMenu(SysMenu menu); + + /** + * 鍒犻櫎鑿滃崟绠$悊淇℃伅 + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + public int deleteMenuById(Long menuId); + + /** + * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴 + * + * @param menuName 鑿滃崟鍚嶇О + * @param parentId 鐖惰彍鍗旾D + * @return 缁撴灉 + */ + public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java new file mode 100644 index 0000000..77f0320 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysNoticeMapper.java @@ -0,0 +1,60 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysNotice; + +/** + * 閫氱煡鍏憡琛� 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysNoticeMapper +{ + /** + * 鏌ヨ鍏憡淇℃伅 + * + * @param noticeId 鍏憡ID + * @return 鍏憡淇℃伅 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 鏌ヨ鍏憡鍒楄〃 + * + * @param notice 鍏憡淇℃伅 + * @return 鍏憡闆嗗悎 + */ + public List<SysNotice> selectNoticeList(SysNotice notice); + + /** + * 鏂板鍏憡 + * + * @param notice 鍏憡淇℃伅 + * @return 缁撴灉 + */ + public int insertNotice(SysNotice notice); + + /** + * 淇敼鍏憡 + * + * @param notice 鍏憡淇℃伅 + * @return 缁撴灉 + */ + public int updateNotice(SysNotice notice); + + /** + * 鎵归噺鍒犻櫎鍏憡 + * + * @param noticeId 鍏憡ID + * @return 缁撴灉 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 鎵归噺鍒犻櫎鍏憡淇℃伅 + * + * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID + * @return 缁撴灉 + */ + public int deleteNoticeByIds(Long noticeIds); +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java new file mode 100644 index 0000000..c7cec0c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysPostMapper.java @@ -0,0 +1,99 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysPost; + +/** + * 宀椾綅淇℃伅 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysPostMapper +{ + /** + * 鏌ヨ宀椾綅鏁版嵁闆嗗悎 + * + * @param post 宀椾綅淇℃伅 + * @return 宀椾綅鏁版嵁闆嗗悎 + */ + public List<SysPost> selectPostList(SysPost post); + + /** + * 鏌ヨ鎵�鏈夊矖浣� + * + * @return 宀椾綅鍒楄〃 + */ + public List<SysPost> selectPostAll(); + + /** + * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅 + * + * @param postId 宀椾綅ID + * @return 瑙掕壊瀵硅薄淇℃伅 + */ + public SysPost selectPostById(Long postId); + + /** + * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛� + * + * @param userId 鐢ㄦ埛ID + * @return 閫変腑宀椾綅ID鍒楄〃 + */ + public List<Integer> selectPostListByUserId(Long userId); + + /** + * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍 + * + * @param userName 鐢ㄦ埛鍚� + * @return 缁撴灉 + */ + public List<SysPost> selectPostsByUserName(String userName); + + /** + * 鍒犻櫎宀椾綅淇℃伅 + * + * @param postId 宀椾綅ID + * @return 缁撴灉 + */ + public int deletePostById(Long postId); + + /** + * 鎵归噺鍒犻櫎宀椾綅淇℃伅 + * + * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID + * @return 缁撴灉 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 淇敼宀椾綅淇℃伅 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + public int updatePost(SysPost post); + + /** + * 鏂板宀椾綅淇℃伅 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + public int insertPost(SysPost post); + + /** + * 鏍¢獙宀椾綅鍚嶇О + * + * @param postName 宀椾綅鍚嶇О + * @return 缁撴灉 + */ + public SysPost checkPostNameUnique(String postName); + + /** + * 鏍¢獙宀椾綅缂栫爜 + * + * @param postCode 宀椾綅缂栫爜 + * @return 缁撴灉 + */ + public SysPost checkPostCodeUnique(String postCode); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleDeptMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleDeptMapper.java new file mode 100644 index 0000000..77ead08 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleDeptMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysRoleDept; + +/** + * 瑙掕壊涓庨儴闂ㄥ叧鑱旇〃 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysRoleDeptMapper +{ + /** + * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊鍜岄儴闂ㄥ叧鑱� + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleDeptByRoleId(Long roleId); + + /** + * 鎵归噺鍒犻櫎瑙掕壊閮ㄩ棬鍏宠仈淇℃伅 + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteRoleDept(Long[] ids); + + /** + * 鏌ヨ閮ㄩ棬浣跨敤鏁伴噺 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + public int selectCountRoleDeptByDeptId(Long deptId); + + /** + * 鎵归噺鏂板瑙掕壊閮ㄩ棬淇℃伅 + * + * @param roleDeptList 瑙掕壊閮ㄩ棬鍒楄〃 + * @return 缁撴灉 + */ + public int batchRoleDept(List<SysRoleDept> roleDeptList); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..fad471b --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMapper.java @@ -0,0 +1,107 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysRole; + +/** + * 瑙掕壊琛� 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysRoleMapper +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁 + * + * @param role 瑙掕壊淇℃伅 + * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅 + */ + public List<SysRole> selectRoleList(SysRole role); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊 + * + * @param userId 鐢ㄦ埛ID + * @return 瑙掕壊鍒楄〃 + */ + public List<SysRole> selectRolePermissionByUserId(Long userId); + + /** + * 鏌ヨ鎵�鏈夎鑹� + * + * @return 瑙掕壊鍒楄〃 + */ + public List<SysRole> selectRoleAll(); + + /** + * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛� + * + * @param userId 鐢ㄦ埛ID + * @return 閫変腑瑙掕壊ID鍒楄〃 + */ + public List<Integer> selectRoleListByUserId(Long userId); + + /** + * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @return 瑙掕壊瀵硅薄淇℃伅 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊 + * + * @param userName 鐢ㄦ埛鍚� + * @return 瑙掕壊鍒楄〃 + */ + public List<SysRole> selectRolesByUserName(String userName); + + /** + * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴 + * + * @param roleName 瑙掕壊鍚嶇О + * @return 瑙掕壊淇℃伅 + */ + public SysRole checkRoleNameUnique(String roleName); + + /** + * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴 + * + * @param roleKey 瑙掕壊鏉冮檺 + * @return 瑙掕壊淇℃伅 + */ + public SysRole checkRoleKeyUnique(String roleKey); + + /** + * 淇敼瑙掕壊淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int updateRole(SysRole role); + + /** + * 鏂板瑙掕壊淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int insertRole(SysRole role); + + /** + * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleById(Long roleId); + + /** + * 鎵归噺鍒犻櫎瑙掕壊淇℃伅 + * + * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleByIds(Long[] roleIds); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMenuMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..50666f4 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysRoleMenuMapper.java @@ -0,0 +1,36 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysRoleMenu; + +/** + * 瑙掕壊涓庤彍鍗曞叧鑱旇〃 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysRoleMenuMapper +{ + /** + * 鏌ヨ鑿滃崟浣跨敤鏁伴噺 + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + public int checkMenuExistRole(Long menuId); + + /** + * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊鍜岃彍鍗曞叧鑱� + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleMenuByRoleId(Long roleId); + + /** + * 鎵归噺鏂板瑙掕壊鑿滃崟淇℃伅 + * + * @param roleMenuList 瑙掕壊鑿滃崟鍒楄〃 + * @return 缁撴灉 + */ + public int batchRoleMenu(List<SysRoleMenu> roleMenuList); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..aad463e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java @@ -0,0 +1,113 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; + +import com.ruoyi.project.system.domain.SysUser; + +/** + * 鐢ㄦ埛琛� 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysUserMapper +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃 + * + * @param sysUser 鐢ㄦ埛淇℃伅 + * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅 + */ + public List<SysUser> selectUserList(SysUser sysUser); + + /** + * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴� + * + * @param userName 鐢ㄦ埛鍚� + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛 + * + * @param userId 鐢ㄦ埛ID + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + public SysUser selectUserById(Long userId); + + /** + * 鏂板鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int insertUser(SysUser user); + + /** + * 淇敼鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int updateUser(SysUser user); + + /** + * 淇敼鐢ㄦ埛澶村儚 + * + * @param userName 鐢ㄦ埛鍚� + * @param avatar 澶村儚鍦板潃 + * @return 缁撴灉 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 閲嶇疆鐢ㄦ埛瀵嗙爜 + * + * @param userName 鐢ㄦ埛鍚� + * @param password 瀵嗙爜 + * @return 缁撴灉 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛 + * + * @param userId 鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserById(Long userId); + + /** + * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅 + * + * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴 + * + * @param userName 鐢ㄦ埛鍚嶇О + * @return 缁撴灉 + */ + public int checkUserNameUnique(String userName); + + /** + * 鏍¢獙鎵嬫満鍙风爜鏄惁鍞竴 + * + * @param phonenumber 鎵嬫満鍙风爜 + * @return 缁撴灉 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 鏍¢獙email鏄惁鍞竴 + * + * @param email 鐢ㄦ埛閭 + * @return 缁撴灉 + */ + public SysUser checkEmailUnique(String email); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserPostMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserPostMapper.java new file mode 100644 index 0000000..7c54fdf --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserPostMapper.java @@ -0,0 +1,44 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import com.ruoyi.project.system.domain.SysUserPost; + +/** + * 鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysUserPostMapper +{ + /** + * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛鍜屽矖浣嶅叧鑱� + * + * @param userId 鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserPostByUserId(Long userId); + + /** + * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺 + * + * @param postId 宀椾綅ID + * @return 缁撴灉 + */ + public int countUserPostById(Long postId); + + /** + * 鎵归噺鍒犻櫎鐢ㄦ埛鍜屽矖浣嶅叧鑱� + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteUserPost(Long[] ids); + + /** + * 鎵归噺鏂板鐢ㄦ埛宀椾綅淇℃伅 + * + * @param userPostList 鐢ㄦ埛瑙掕壊鍒楄〃 + * @return 缁撴灉 + */ + public int batchUserPost(List<SysUserPost> userPostList); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserRoleMapper.java b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..e535905 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,62 @@ +package com.ruoyi.project.system.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.project.system.domain.SysUserRole; + +/** + * 鐢ㄦ埛涓庤鑹插叧鑱旇〃 鏁版嵁灞� + * + * @author ruoyi + */ +public interface SysUserRoleMapper +{ + /** + * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛鍜岃鑹插叧鑱� + * + * @param userId 鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserRoleByUserId(Long userId); + + /** + * 鎵归噺鍒犻櫎鐢ㄦ埛鍜岃鑹插叧鑱� + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteUserRole(Long[] ids); + + /** + * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺 + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 鎵归噺鏂板鐢ㄦ埛瑙掕壊淇℃伅 + * + * @param userRoleList 鐢ㄦ埛瑙掕壊鍒楄〃 + * @return 缁撴灉 + */ + public int batchUserRole(List<SysUserRole> userRoleList); + + /** + * 鍒犻櫎鐢ㄦ埛鍜岃鑹插叧鑱斾俊鎭� + * + * @param userRole 鐢ㄦ埛鍜岃鑹插叧鑱斾俊鎭� + * @return 缁撴灉 + */ + public int deleteUserRoleInfo(SysUserRole userRole); + + /** + * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteUserRoleInfos(@Param("roleId") Long roleId, @Param("userIds") Long[] userIds); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java new file mode 100644 index 0000000..ec24110 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysConfigService.java @@ -0,0 +1,76 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.project.system.domain.SysConfig; + +/** + * 鍙傛暟閰嶇疆 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysConfigService +{ + /** + * 鏌ヨ鍙傛暟閰嶇疆淇℃伅 + * + * @param configId 鍙傛暟閰嶇疆ID + * @return 鍙傛暟閰嶇疆淇℃伅 + */ + public SysConfig selectConfigById(Long configId); + + /** + * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅 + * + * @param configKey 鍙傛暟閿悕 + * @return 鍙傛暟閿�� + */ + public String selectConfigByKey(String configKey); + + /** + * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 鍙傛暟閰嶇疆闆嗗悎 + */ + public List<SysConfig> selectConfigList(SysConfig config); + + /** + * 鏂板鍙傛暟閰嶇疆 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + public int insertConfig(SysConfig config); + + /** + * 淇敼鍙傛暟閰嶇疆 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + public int updateConfig(SysConfig config); + + /** + * 鍒犻櫎鍙傛暟閰嶇疆淇℃伅 + * + * @param configId 鍙傛暟ID + * @return 缁撴灉 + */ + public int deleteConfigById(Long configId); + + /** + * 鎵归噺鍒犻櫎鍙傛暟淇℃伅 + * + * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID + * @return 缁撴灉 + */ + public int deleteConfigByIds(Long[] configIds); + + /** + * 鏍¢獙鍙傛暟閿悕鏄惁鍞竴 + * + * @param config 鍙傛暟淇℃伅 + * @return 缁撴灉 + */ + public String checkConfigKeyUnique(SysConfig config); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDeptService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDeptService.java new file mode 100644 index 0000000..c7a7c78 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDeptService.java @@ -0,0 +1,101 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.framework.web.domain.TreeSelect; +import com.ruoyi.project.system.domain.SysDept; + +/** + * 閮ㄩ棬绠$悊 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysDeptService +{ + /** + * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 閮ㄩ棬淇℃伅闆嗗悎 + */ + public List<SysDept> selectDeptList(SysDept dept); + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯 + * + * @param depts 閮ㄩ棬鍒楄〃 + * @return 鏍戠粨鏋勫垪琛� + */ + public List<SysDept> buildDeptTree(List<SysDept> depts); + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯 + * + * @param depts 閮ㄩ棬鍒楄〃 + * @return 涓嬫媺鏍戠粨鏋勫垪琛� + */ + public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts); + + /** + * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭� + * + * @param roleId 瑙掕壊ID + * @return 閫変腑閮ㄩ棬鍒楄〃 + */ + public List<Integer> selectDeptListByRoleId(Long roleId); + + /** + * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅 + * + * @param deptId 閮ㄩ棬ID + * @return 閮ㄩ棬淇℃伅 + */ + public SysDept selectDeptById(Long deptId); + + /** + * 鏄惁瀛樺湪閮ㄩ棬瀛愯妭鐐� + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + public boolean hasChildByDeptId(Long deptId); + + /** + * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦� + */ + public boolean checkDeptExistUser(Long deptId); + + /** + * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + public String checkDeptNameUnique(SysDept dept); + + /** + * 鏂板淇濆瓨閮ㄩ棬淇℃伅 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + public int insertDept(SysDept dept); + + /** + * 淇敼淇濆瓨閮ㄩ棬淇℃伅 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + public int updateDept(SysDept dept); + + /** + * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + public int deleteDeptById(Long deptId); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java new file mode 100644 index 0000000..8330365 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictDataService.java @@ -0,0 +1,77 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.project.system.domain.SysDictData; + +/** + * 瀛楀吀 涓氬姟灞� + * + * @author ruoyi + */ +public interface ISysDictDataService +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅 + */ + public List<SysDictData> selectDictDataList(SysDictData dictData); + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅 + */ + public List<SysDictData> selectDictDataByType(String dictType); + + /** + * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭� + * + * @param dictType 瀛楀吀绫诲瀷 + * @param dictValue 瀛楀吀閿�� + * @return 瀛楀吀鏍囩 + */ + public String selectDictLabel(String dictType, String dictValue); + + /** + * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅 + * + * @param dictCode 瀛楀吀鏁版嵁ID + * @return 瀛楀吀鏁版嵁 + */ + public SysDictData selectDictDataById(Long dictCode); + + /** + * 閫氳繃瀛楀吀ID鍒犻櫎瀛楀吀鏁版嵁淇℃伅 + * + * @param dictCode 瀛楀吀鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteDictDataById(Long dictCode); + + /** + * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅 + * + * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteDictDataByIds(Long[] dictCodes); + + /** + * 鏂板淇濆瓨瀛楀吀鏁版嵁淇℃伅 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 缁撴灉 + */ + public int insertDictData(SysDictData dictData); + + /** + * 淇敼淇濆瓨瀛楀吀鏁版嵁淇℃伅 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 缁撴灉 + */ + public int updateDictData(SysDictData dictData); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java new file mode 100644 index 0000000..7c650db --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysDictTypeService.java @@ -0,0 +1,83 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.project.system.domain.SysDictType; + +/** + * 瀛楀吀 涓氬姟灞� + * + * @author ruoyi + */ +public interface ISysDictTypeService +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅 + */ + public List<SysDictType> selectDictTypeList(SysDictType dictType); + + /** + * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨� + * + * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅 + */ + public List<SysDictType> selectDictTypeAll(); + + /** + * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅 + * + * @param dictId 瀛楀吀绫诲瀷ID + * @return 瀛楀吀绫诲瀷 + */ + public SysDictType selectDictTypeById(Long dictId); + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀绫诲瀷 + */ + public SysDictType selectDictTypeByType(String dictType); + + /** + * 閫氳繃瀛楀吀ID鍒犻櫎瀛楀吀淇℃伅 + * + * @param dictId 瀛楀吀ID + * @return 缁撴灉 + */ + public int deleteDictTypeById(Long dictId); + + /** + * 鎵归噺鍒犻櫎瀛楀吀淇℃伅 + * + * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID + * @return 缁撴灉 + */ + public int deleteDictTypeByIds(Long[] dictIds); + + /** + * 鏂板淇濆瓨瀛楀吀绫诲瀷淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 缁撴灉 + */ + public int insertDictType(SysDictType dictType); + + /** + * 淇敼淇濆瓨瀛楀吀绫诲瀷淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 缁撴灉 + */ + public int updateDictType(SysDictType dictType); + + /** + * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓� + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 缁撴灉 + */ + public String checkDictTypeUnique(SysDictType dictType); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysMenuService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysMenuService.java new file mode 100644 index 0000000..dbd2cde --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysMenuService.java @@ -0,0 +1,136 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import java.util.Set; +import com.ruoyi.framework.web.domain.TreeSelect; +import com.ruoyi.project.system.domain.SysMenu; +import com.ruoyi.project.system.domain.vo.RouterVo; + +/** + * 鑿滃崟 涓氬姟灞� + * + * @author ruoyi + */ +public interface ISysMenuService +{ + /** + * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃 + * + * @param userId 鐢ㄦ埛ID + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuList(Long userId); + + /** + * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃 + * + * @param menu 鑿滃崟淇℃伅 + * @param userId 鐢ㄦ埛ID + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuList(SysMenu menu, Long userId); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺 + * + * @param userId 鐢ㄦ埛ID + * @return 鏉冮檺鍒楄〃 + */ + public Set<String> selectMenuPermsByUserId(Long userId); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟鏍戜俊鎭� + * + * @param userId 鐢ㄦ埛ID + * @return 鑿滃崟鍒楄〃 + */ + public List<SysMenu> selectMenuTreeByUserId(Long userId); + + /** + * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭� + * + * @param roleId 瑙掕壊ID + * @return 閫変腑鑿滃崟鍒楄〃 + */ + public List<Integer> selectMenuListByRoleId(Long roleId); + + /** + * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟 + * + * @param menus 鑿滃崟鍒楄〃 + * @return 璺敱鍒楄〃 + */ + public List<RouterVo> buildMenus(List<SysMenu> menus); + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯 + * + * @param menus 鑿滃崟鍒楄〃 + * @return 鏍戠粨鏋勫垪琛� + */ + public List<SysMenu> buildMenuTree(List<SysMenu> menus); + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯 + * + * @param menus 鑿滃崟鍒楄〃 + * @return 涓嬫媺鏍戠粨鏋勫垪琛� + */ + public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus); + + /** + * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅 + * + * @param menuId 鑿滃崟ID + * @return 鑿滃崟淇℃伅 + */ + public SysMenu selectMenuById(Long menuId); + + /** + * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐� + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦� + */ + public boolean hasChildByMenuId(Long menuId); + + /** + * 鏌ヨ鑿滃崟鏄惁瀛樺湪瑙掕壊 + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦� + */ + public boolean checkMenuExistRole(Long menuId); + + /** + * 鏂板淇濆瓨鑿滃崟淇℃伅 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + public int insertMenu(SysMenu menu); + + /** + * 淇敼淇濆瓨鑿滃崟淇℃伅 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + public int updateMenu(SysMenu menu); + + /** + * 鍒犻櫎鑿滃崟绠$悊淇℃伅 + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + public int deleteMenuById(Long menuId); + + /** + * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + public String checkMenuNameUnique(SysMenu menu); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java new file mode 100644 index 0000000..ed60c48 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysNoticeService.java @@ -0,0 +1,60 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.project.system.domain.SysNotice; + +/** + * 鍏憡 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysNoticeService +{ + /** + * 鏌ヨ鍏憡淇℃伅 + * + * @param noticeId 鍏憡ID + * @return 鍏憡淇℃伅 + */ + public SysNotice selectNoticeById(Long noticeId); + + /** + * 鏌ヨ鍏憡鍒楄〃 + * + * @param notice 鍏憡淇℃伅 + * @return 鍏憡闆嗗悎 + */ + public List<SysNotice> selectNoticeList(SysNotice notice); + + /** + * 鏂板鍏憡 + * + * @param notice 鍏憡淇℃伅 + * @return 缁撴灉 + */ + public int insertNotice(SysNotice notice); + + /** + * 淇敼鍏憡 + * + * @param notice 鍏憡淇℃伅 + * @return 缁撴灉 + */ + public int updateNotice(SysNotice notice); + + /** + * 鍒犻櫎鍏憡淇℃伅 + * + * @param noticeId 鍏憡ID + * @return 缁撴灉 + */ + public int deleteNoticeById(Long noticeId); + + /** + * 鎵归噺鍒犻櫎鍏憡淇℃伅 + * + * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID + * @return 缁撴灉 + */ + public int deleteNoticeByIds(Long noticeIds); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java new file mode 100644 index 0000000..b93e100 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysPostService.java @@ -0,0 +1,100 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.project.system.domain.SysPost; + +/** + * 宀椾綅淇℃伅 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysPostService +{ + /** + * 鏌ヨ宀椾綅淇℃伅闆嗗悎 + * + * @param post 宀椾綅淇℃伅 + * @return 宀椾綅鍒楄〃 + */ + public List<SysPost> selectPostList(SysPost post); + + /** + * 鏌ヨ鎵�鏈夊矖浣� + * + * @return 宀椾綅鍒楄〃 + */ + public List<SysPost> selectPostAll(); + + /** + * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅 + * + * @param postId 宀椾綅ID + * @return 瑙掕壊瀵硅薄淇℃伅 + */ + public SysPost selectPostById(Long postId); + + /** + * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛� + * + * @param userId 鐢ㄦ埛ID + * @return 閫変腑宀椾綅ID鍒楄〃 + */ + public List<Integer> selectPostListByUserId(Long userId); + + /** + * 鏍¢獙宀椾綅鍚嶇О + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + public String checkPostNameUnique(SysPost post); + + /** + * 鏍¢獙宀椾綅缂栫爜 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + public String checkPostCodeUnique(SysPost post); + + /** + * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺 + * + * @param postId 宀椾綅ID + * @return 缁撴灉 + */ + public int countUserPostById(Long postId); + + /** + * 鍒犻櫎宀椾綅淇℃伅 + * + * @param postId 宀椾綅ID + * @return 缁撴灉 + */ + public int deletePostById(Long postId); + + /** + * 鎵归噺鍒犻櫎宀椾綅淇℃伅 + * + * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID + * @return 缁撴灉 + * @throws Exception 寮傚父 + */ + public int deletePostByIds(Long[] postIds); + + /** + * 鏂板淇濆瓨宀椾綅淇℃伅 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + public int insertPost(SysPost post); + + /** + * 淇敼淇濆瓨宀椾綅淇℃伅 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + public int updatePost(SysPost post); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java new file mode 100644 index 0000000..93b013f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysRoleService.java @@ -0,0 +1,131 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import java.util.Set; +import com.ruoyi.project.system.domain.SysRole; + +/** + * 瑙掕壊涓氬姟灞� + * + * @author ruoyi + */ +public interface ISysRoleService +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁 + * + * @param role 瑙掕壊淇℃伅 + * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅 + */ + public List<SysRole> selectRoleList(SysRole role); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ瑙掕壊 + * + * @param userId 鐢ㄦ埛ID + * @return 鏉冮檺鍒楄〃 + */ + public Set<String> selectRolePermissionByUserId(Long userId); + + /** + * 鏌ヨ鎵�鏈夎鑹� + * + * @return 瑙掕壊鍒楄〃 + */ + public List<SysRole> selectRoleAll(); + + /** + * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛� + * + * @param userId 鐢ㄦ埛ID + * @return 閫変腑瑙掕壊ID鍒楄〃 + */ + public List<Integer> selectRoleListByUserId(Long userId); + + /** + * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @return 瑙掕壊瀵硅薄淇℃伅 + */ + public SysRole selectRoleById(Long roleId); + + /** + * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public String checkRoleNameUnique(SysRole role); + + /** + * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public String checkRoleKeyUnique(SysRole role); + + /** + * 鏍¢獙瑙掕壊鏄惁鍏佽鎿嶄綔 + * + * @param role 瑙掕壊淇℃伅 + */ + public void checkRoleAllowed(SysRole role); + + /** + * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺 + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + public int countUserRoleByRoleId(Long roleId); + + /** + * 鏂板淇濆瓨瑙掕壊淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int insertRole(SysRole role); + + /** + * 淇敼淇濆瓨瑙掕壊淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int updateRole(SysRole role); + + /** + * 淇敼瑙掕壊鐘舵�� + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int updateRoleStatus(SysRole role); + + /** + * 淇敼鏁版嵁鏉冮檺淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int authDataScope(SysRole role); + + /** + * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleById(Long roleId); + + /** + * 鎵归噺鍒犻櫎瑙掕壊淇℃伅 + * + * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleByIds(Long[] roleIds); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java new file mode 100644 index 0000000..7974ae7 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java @@ -0,0 +1,48 @@ +package com.ruoyi.project.system.service; + +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.project.monitor.domain.SysUserOnline; + +/** + * 鍦ㄧ嚎鐢ㄦ埛 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface ISysUserOnlineService +{ + /** + * 閫氳繃鐧诲綍鍦板潃鏌ヨ淇℃伅 + * + * @param ipaddr 鐧诲綍鍦板潃 + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛淇℃伅 + */ + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); + + /** + * 閫氳繃鐢ㄦ埛鍚嶇О鏌ヨ淇℃伅 + * + * @param userName 鐢ㄦ埛鍚嶇О + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛淇℃伅 + */ + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); + + /** + * 閫氳繃鐧诲綍鍦板潃/鐢ㄦ埛鍚嶇О鏌ヨ淇℃伅 + * + * @param ipaddr 鐧诲綍鍦板潃 + * @param userName 鐢ㄦ埛鍚嶇О + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛淇℃伅 + */ + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); + + /** + * 璁剧疆鍦ㄧ嚎鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java new file mode 100644 index 0000000..366fb45 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserService.java @@ -0,0 +1,167 @@ +package com.ruoyi.project.system.service; + +import java.util.List; +import com.ruoyi.project.system.domain.SysUser; + +/** + * 鐢ㄦ埛 涓氬姟灞� + * + * @author ruoyi + */ +public interface ISysUserService +{ + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅 + */ + public List<SysUser> selectUserList(SysUser user); + + /** + * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴� + * + * @param userName 鐢ㄦ埛鍚� + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛 + * + * @param userId 鐢ㄦ埛ID + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + public SysUser selectUserById(Long userId); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍 + * + * @param userName 鐢ㄦ埛鍚� + * @return 缁撴灉 + */ + public String selectUserRoleGroup(String userName); + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍 + * + * @param userName 鐢ㄦ埛鍚� + * @return 缁撴灉 + */ + public String selectUserPostGroup(String userName); + + /** + * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴 + * + * @param userName 鐢ㄦ埛鍚嶇О + * @return 缁撴灉 + */ + public String checkUserNameUnique(String userName); + + /** + * 鏍¢獙鎵嬫満鍙风爜鏄惁鍞竴 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public String checkPhoneUnique(SysUser user); + + /** + * 鏍¢獙email鏄惁鍞竴 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public String checkEmailUnique(SysUser user); + + /** + * 鏍¢獙鐢ㄦ埛鏄惁鍏佽鎿嶄綔 + * + * @param user 鐢ㄦ埛淇℃伅 + */ + public void checkUserAllowed(SysUser user); + + /** + * 鏂板鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int insertUser(SysUser user); + + /** + * 淇敼鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int updateUser(SysUser user); + + /** + * 淇敼鐢ㄦ埛鐘舵�� + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int updateUserStatus(SysUser user); + + /** + * 淇敼鐢ㄦ埛鍩烘湰淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int updateUserProfile(SysUser user); + + /** + * 淇敼鐢ㄦ埛澶村儚 + * + * @param userName 鐢ㄦ埛鍚� + * @param avatar 澶村儚鍦板潃 + * @return 缁撴灉 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 閲嶇疆鐢ㄦ埛瀵嗙爜 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + public int resetPwd(SysUser user); + + /** + * 閲嶇疆鐢ㄦ埛瀵嗙爜 + * + * @param userName 鐢ㄦ埛鍚� + * @param password 瀵嗙爜 + * @return 缁撴灉 + */ + public int resetUserPwd(String userName, String password); + + /** + * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛 + * + * @param userId 鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserById(Long userId); + + /** + * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅 + * + * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 瀵煎叆鐢ㄦ埛鏁版嵁 + * + * @param userList 鐢ㄦ埛鏁版嵁鍒楄〃 + * @param isUpdateSupport 鏄惁鏇存柊鏀寔锛屽鏋滃凡瀛樺湪锛屽垯杩涜鏇存柊鏁版嵁 + * @param operName 鎿嶄綔鐢ㄦ埛 + * @return 缁撴灉 + */ + public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..6843388 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,129 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.project.system.domain.SysConfig; +import com.ruoyi.project.system.mapper.SysConfigMapper; +import com.ruoyi.project.system.service.ISysConfigService; + +/** + * 鍙傛暟閰嶇疆 鏈嶅姟灞傚疄鐜� + * + * @author ruoyi + */ +@Service +public class SysConfigServiceImpl implements ISysConfigService +{ + @Autowired + private SysConfigMapper configMapper; + + /** + * 鏌ヨ鍙傛暟閰嶇疆淇℃伅 + * + * @param configId 鍙傛暟閰嶇疆ID + * @return 鍙傛暟閰嶇疆淇℃伅 + */ + @Override + public SysConfig selectConfigById(Long configId) + { + SysConfig config = new SysConfig(); + config.setConfigId(configId); + return configMapper.selectConfig(config); + } + + /** + * 鏍规嵁閿悕鏌ヨ鍙傛暟閰嶇疆淇℃伅 + * + * @param configKey 鍙傛暟key + * @return 鍙傛暟閿�� + */ + @Override + public String selectConfigByKey(String configKey) + { + SysConfig config = new SysConfig(); + config.setConfigKey(configKey); + SysConfig retConfig = configMapper.selectConfig(config); + return StringUtils.isNotNull(retConfig) ? retConfig.getConfigValue() : ""; + } + + /** + * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 鍙傛暟閰嶇疆闆嗗悎 + */ + @Override + public List<SysConfig> selectConfigList(SysConfig config) + { + return configMapper.selectConfigList(config); + } + + /** + * 鏂板鍙傛暟閰嶇疆 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertConfig(SysConfig config) + { + return configMapper.insertConfig(config); + } + + /** + * 淇敼鍙傛暟閰嶇疆 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateConfig(SysConfig config) + { + return configMapper.updateConfig(config); + } + + /** + * 鍒犻櫎鍙傛暟閰嶇疆淇℃伅 + * + * @param configId 鍙傛暟ID + * @return 缁撴灉 + */ + @Override + public int deleteConfigById(Long configId) + { + return configMapper.deleteConfigById(configId); + } + + /** + * 鎵归噺鍒犻櫎鍙傛暟淇℃伅 + * + * @param configIds 闇�瑕佸垹闄ょ殑鍙傛暟ID + * @return 缁撴灉 + */ + @Override + public int deleteConfigByIds(Long[] configIds) + { + return configMapper.deleteConfigByIds(configIds); + } + + /** + * 鏍¢獙鍙傛暟閿悕鏄惁鍞竴 + * + * @param config 鍙傛暟閰嶇疆淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkConfigKeyUnique(SysConfig config) + { + Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId(); + SysConfig info = configMapper.checkConfigKeyUnique(config.getConfigKey()); + if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..9257495 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,294 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.DataScope; +import com.ruoyi.framework.web.domain.TreeSelect; +import com.ruoyi.project.system.domain.SysDept; +import com.ruoyi.project.system.mapper.SysDeptMapper; +import com.ruoyi.project.system.service.ISysDeptService; + +/** + * 閮ㄩ棬绠$悊 鏈嶅姟瀹炵幇 + * + * @author ruoyi + */ +@Service +public class SysDeptServiceImpl implements ISysDeptService +{ + @Autowired + private SysDeptMapper deptMapper; + + /** + * 鏌ヨ閮ㄩ棬绠$悊鏁版嵁 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 閮ㄩ棬淇℃伅闆嗗悎 + */ + @Override + @DataScope(deptAlias = "d") + public List<SysDept> selectDeptList(SysDept dept) + { + return deptMapper.selectDeptList(dept); + } + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯 + * + * @param depts 閮ㄩ棬鍒楄〃 + * @return 鏍戠粨鏋勫垪琛� + */ + @Override + public List<SysDept> buildDeptTree(List<SysDept> depts) + { + List<SysDept> returnList = new ArrayList<SysDept>(); + List<Long> tempList = new ArrayList<Long>(); + for (SysDept dept : depts) + { + tempList.add(dept.getDeptId()); + } + for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext();) + { + SysDept dept = (SysDept) iterator.next(); + // 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣 + if (!tempList.contains(dept.getParentId())) + { + recursionFn(depts, dept); + returnList.add(dept); + } + } + if (returnList.isEmpty()) + { + returnList = depts; + } + return returnList; + } + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯 + * + * @param depts 閮ㄩ棬鍒楄〃 + * @return 涓嬫媺鏍戠粨鏋勫垪琛� + */ + @Override + public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts) + { + List<SysDept> deptTrees = buildDeptTree(depts); + return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭� + * + * @param roleId 瑙掕壊ID + * @return 閫変腑閮ㄩ棬鍒楄〃 + */ + @Override + public List<Integer> selectDeptListByRoleId(Long roleId) + { + return deptMapper.selectDeptListByRoleId(roleId); + } + + /** + * 鏍规嵁閮ㄩ棬ID鏌ヨ淇℃伅 + * + * @param deptId 閮ㄩ棬ID + * @return 閮ㄩ棬淇℃伅 + */ + @Override + public SysDept selectDeptById(Long deptId) + { + return deptMapper.selectDeptById(deptId); + } + + /** + * 鏄惁瀛樺湪瀛愯妭鐐� + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + @Override + public boolean hasChildByDeptId(Long deptId) + { + int result = deptMapper.hasChildByDeptId(deptId); + return result > 0 ? true : false; + } + + /** + * 鏌ヨ閮ㄩ棬鏄惁瀛樺湪鐢ㄦ埛 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦� + */ + @Override + public boolean checkDeptExistUser(Long deptId) + { + int result = deptMapper.checkDeptExistUser(deptId); + return result > 0 ? true : false; + } + + /** + * 鏍¢獙閮ㄩ棬鍚嶇О鏄惁鍞竴 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkDeptNameUnique(SysDept dept) + { + Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId(); + SysDept info = deptMapper.checkDeptNameUnique(dept.getDeptName(), dept.getParentId()); + if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏂板淇濆瓨閮ㄩ棬淇℃伅 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertDept(SysDept dept) + { + SysDept info = deptMapper.selectDeptById(dept.getParentId()); + // 濡傛灉鐖惰妭鐐逛笉涓烘甯哥姸鎬�,鍒欎笉鍏佽鏂板瀛愯妭鐐� + if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) + { + throw new CustomException("閮ㄩ棬鍋滅敤锛屼笉鍏佽鏂板"); + } + dept.setAncestors(info.getAncestors() + "," + dept.getParentId()); + return deptMapper.insertDept(dept); + } + + /** + * 淇敼淇濆瓨閮ㄩ棬淇℃伅 + * + * @param dept 閮ㄩ棬淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateDept(SysDept dept) + { + SysDept newParentDept = deptMapper.selectDeptById(dept.getParentId()); + SysDept oldDept = deptMapper.selectDeptById(dept.getDeptId()); + if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) + { + String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId(); + String oldAncestors = oldDept.getAncestors(); + dept.setAncestors(newAncestors); + updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); + } + int result = deptMapper.updateDept(dept); + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus())) + { + // 濡傛灉璇ラ儴闂ㄦ槸鍚敤鐘舵�侊紝鍒欏惎鐢ㄨ閮ㄩ棬鐨勬墍鏈変笂绾ч儴闂� + updateParentDeptStatus(dept); + } + return result; + } + + /** + * 淇敼璇ラ儴闂ㄧ殑鐖剁骇閮ㄩ棬鐘舵�� + * + * @param dept 褰撳墠閮ㄩ棬 + */ + private void updateParentDeptStatus(SysDept dept) + { + String updateBy = dept.getUpdateBy(); + dept = deptMapper.selectDeptById(dept.getDeptId()); + dept.setUpdateBy(updateBy); + deptMapper.updateDeptStatus(dept); + } + + /** + * 淇敼瀛愬厓绱犲叧绯� + * + * @param deptId 琚慨鏀圭殑閮ㄩ棬ID + * @param newAncestors 鏂扮殑鐖禝D闆嗗悎 + * @param oldAncestors 鏃х殑鐖禝D闆嗗悎 + */ + public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) + { + List<SysDept> children = deptMapper.selectChildrenDeptById(deptId); + for (SysDept child : children) + { + child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors)); + } + if (children.size() > 0) + { + deptMapper.updateDeptChildren(children); + } + } + + /** + * 鍒犻櫎閮ㄩ棬绠$悊淇℃伅 + * + * @param deptId 閮ㄩ棬ID + * @return 缁撴灉 + */ + @Override + public int deleteDeptById(Long deptId) + { + return deptMapper.deleteDeptById(deptId); + } + + /** + * 閫掑綊鍒楄〃 + */ + private void recursionFn(List<SysDept> list, SysDept t) + { + // 寰楀埌瀛愯妭鐐瑰垪琛� + List<SysDept> childList = getChildList(list, t); + t.setChildren(childList); + for (SysDept tChild : childList) + { + if (hasChild(list, tChild)) + { + // 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣 + Iterator<SysDept> it = childList.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + recursionFn(list, n); + } + } + } + } + + /** + * 寰楀埌瀛愯妭鐐瑰垪琛� + */ + private List<SysDept> getChildList(List<SysDept> list, SysDept t) + { + List<SysDept> tlist = new ArrayList<SysDept>(); + Iterator<SysDept> it = list.iterator(); + while (it.hasNext()) + { + SysDept n = (SysDept) it.next(); + if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣 + */ + private boolean hasChild(List<SysDept> list, SysDept t) + { + return getChildList(list, t).size() > 0 ? true : false; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..d3ac0bf --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,116 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.project.system.domain.SysDictData; +import com.ruoyi.project.system.mapper.SysDictDataMapper; +import com.ruoyi.project.system.service.ISysDictDataService; + +/** + * 瀛楀吀 涓氬姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysDictDataServiceImpl implements ISysDictDataService +{ + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅 + */ + @Override + public List<SysDictData> selectDictDataList(SysDictData dictData) + { + return dictDataMapper.selectDictDataList(dictData); + } + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀鏁版嵁闆嗗悎淇℃伅 + */ + @Override + public List<SysDictData> selectDictDataByType(String dictType) + { + return dictDataMapper.selectDictDataByType(dictType); + } + + /** + * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏搁敭鍊兼煡璇㈠瓧鍏告暟鎹俊鎭� + * + * @param dictType 瀛楀吀绫诲瀷 + * @param dictValue 瀛楀吀閿�� + * @return 瀛楀吀鏍囩 + */ + @Override + public String selectDictLabel(String dictType, String dictValue) + { + return dictDataMapper.selectDictLabel(dictType, dictValue); + } + + /** + * 鏍规嵁瀛楀吀鏁版嵁ID鏌ヨ淇℃伅 + * + * @param dictCode 瀛楀吀鏁版嵁ID + * @return 瀛楀吀鏁版嵁 + */ + @Override + public SysDictData selectDictDataById(Long dictCode) + { + return dictDataMapper.selectDictDataById(dictCode); + } + + /** + * 閫氳繃瀛楀吀ID鍒犻櫎瀛楀吀鏁版嵁淇℃伅 + * + * @param dictCode 瀛楀吀鏁版嵁ID + * @return 缁撴灉 + */ + @Override + public int deleteDictDataById(Long dictCode) + { + return dictDataMapper.deleteDictDataById(dictCode); + } + + /** + * 鎵归噺鍒犻櫎瀛楀吀鏁版嵁淇℃伅 + * + * @param dictCodes 闇�瑕佸垹闄ょ殑瀛楀吀鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteDictDataByIds(Long[] dictCodes) + { + return dictDataMapper.deleteDictDataByIds(dictCodes); + } + + /** + * 鏂板淇濆瓨瀛楀吀鏁版嵁淇℃伅 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertDictData(SysDictData dictData) + { + return dictDataMapper.insertDictData(dictData); + } + + /** + * 淇敼淇濆瓨瀛楀吀鏁版嵁淇℃伅 + * + * @param dictData 瀛楀吀鏁版嵁淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateDictData(SysDictData dictData) + { + return dictDataMapper.updateDictData(dictData); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..8249dca --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,141 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.project.system.domain.SysDictType; +import com.ruoyi.project.system.mapper.SysDictDataMapper; +import com.ruoyi.project.system.mapper.SysDictTypeMapper; +import com.ruoyi.project.system.service.ISysDictTypeService; + +/** + * 瀛楀吀 涓氬姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysDictTypeServiceImpl implements ISysDictTypeService +{ + @Autowired + private SysDictTypeMapper dictTypeMapper; + + @Autowired + private SysDictDataMapper dictDataMapper; + + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瀛楀吀绫诲瀷 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅 + */ + @Override + public List<SysDictType> selectDictTypeList(SysDictType dictType) + { + return dictTypeMapper.selectDictTypeList(dictType); + } + + /** + * 鏍规嵁鎵�鏈夊瓧鍏哥被鍨� + * + * @return 瀛楀吀绫诲瀷闆嗗悎淇℃伅 + */ + @Override + public List<SysDictType> selectDictTypeAll() + { + return dictTypeMapper.selectDictTypeAll(); + } + + /** + * 鏍规嵁瀛楀吀绫诲瀷ID鏌ヨ淇℃伅 + * + * @param dictId 瀛楀吀绫诲瀷ID + * @return 瀛楀吀绫诲瀷 + */ + @Override + public SysDictType selectDictTypeById(Long dictId) + { + return dictTypeMapper.selectDictTypeById(dictId); + } + + /** + * 鏍规嵁瀛楀吀绫诲瀷鏌ヨ淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷 + * @return 瀛楀吀绫诲瀷 + */ + public SysDictType selectDictTypeByType(String dictType) + { + return dictTypeMapper.selectDictTypeByType(dictType); + } + + /** + * 閫氳繃瀛楀吀ID鍒犻櫎瀛楀吀淇℃伅 + * + * @param dictId 瀛楀吀ID + * @return 缁撴灉 + */ + @Override + public int deleteDictTypeById(Long dictId) + { + return dictTypeMapper.deleteDictTypeById(dictId); + } + + /** + * 鎵归噺鍒犻櫎瀛楀吀绫诲瀷淇℃伅 + * + * @param dictIds 闇�瑕佸垹闄ょ殑瀛楀吀ID + * @return 缁撴灉 + */ + public int deleteDictTypeByIds(Long[] dictIds) + { + return dictTypeMapper.deleteDictTypeByIds(dictIds); + } + + /** + * 鏂板淇濆瓨瀛楀吀绫诲瀷淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertDictType(SysDictType dictType) + { + return dictTypeMapper.insertDictType(dictType); + } + + /** + * 淇敼淇濆瓨瀛楀吀绫诲瀷淇℃伅 + * + * @param dictType 瀛楀吀绫诲瀷淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public int updateDictType(SysDictType dictType) + { + SysDictType oldDict = dictTypeMapper.selectDictTypeById(dictType.getDictId()); + dictDataMapper.updateDictDataType(oldDict.getDictType(), dictType.getDictType()); + return dictTypeMapper.updateDictType(dictType); + } + + /** + * 鏍¢獙瀛楀吀绫诲瀷绉版槸鍚﹀敮涓� + * + * @param dict 瀛楀吀绫诲瀷 + * @return 缁撴灉 + */ + @Override + public String checkDictTypeUnique(SysDictType dict) + { + Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId(); + SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType()); + if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..c88db37 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,381 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.domain.TreeSelect; +import com.ruoyi.project.system.domain.SysMenu; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.domain.vo.MetaVo; +import com.ruoyi.project.system.domain.vo.RouterVo; +import com.ruoyi.project.system.mapper.SysMenuMapper; +import com.ruoyi.project.system.mapper.SysRoleMenuMapper; +import com.ruoyi.project.system.service.ISysMenuService; + +/** + * 鑿滃崟 涓氬姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysMenuServiceImpl implements ISysMenuService +{ + public static final String PREMISSION_STRING = "perms[\"{0}\"]"; + + @Autowired + private SysMenuMapper menuMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + /** + * 鏍规嵁鐢ㄦ埛鏌ヨ绯荤粺鑿滃崟鍒楄〃 + * + * @param userId 鐢ㄦ埛ID + * @return 鑿滃崟鍒楄〃 + */ + @Override + public List<SysMenu> selectMenuList(Long userId) + { + return selectMenuList(new SysMenu(), userId); + } + + /** + * 鏌ヨ绯荤粺鑿滃崟鍒楄〃 + * + * @param menu 鑿滃崟淇℃伅 + * @return 鑿滃崟鍒楄〃 + */ + @Override + public List<SysMenu> selectMenuList(SysMenu menu, Long userId) + { + List<SysMenu> menuList = null; + // 绠$悊鍛樻樉绀烘墍鏈夎彍鍗曚俊鎭� + if (SysUser.isAdmin(userId)) + { + menuList = menuMapper.selectMenuList(menu); + } + else + { + menu.getParams().put("userId", userId); + menuList = menuMapper.selectMenuListByUserId(menu); + } + return menuList; + } + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺 + * + * @param userId 鐢ㄦ埛ID + * @return 鏉冮檺鍒楄〃 + */ + @Override + public Set<String> selectMenuPermsByUserId(Long userId) + { + List<String> perms = menuMapper.selectMenuPermsByUserId(userId); + Set<String> permsSet = new HashSet<>(); + for (String perm : perms) + { + if (StringUtils.isNotEmpty(perm)) + { + permsSet.addAll(Arrays.asList(perm.trim().split(","))); + } + } + return permsSet; + } + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟 + * + * @param userId 鐢ㄦ埛鍚嶇О + * @return 鑿滃崟鍒楄〃 + */ + @Override + public List<SysMenu> selectMenuTreeByUserId(Long userId) + { + List<SysMenu> menus = null; + if (SecurityUtils.isAdmin(userId)) + { + menus = menuMapper.selectMenuTreeAll(); + } + else + { + menus = menuMapper.selectMenuTreeByUserId(userId); + } + return getChildPerms(menus, 0); + } + + /** + * 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戜俊鎭� + * + * @param roleId 瑙掕壊ID + * @return 閫変腑鑿滃崟鍒楄〃 + */ + public List<Integer> selectMenuListByRoleId(Long roleId) + { + return menuMapper.selectMenuListByRoleId(roleId); + } + + /** + * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟 + * + * @param menus 鑿滃崟鍒楄〃 + * @return 璺敱鍒楄〃 + */ + @Override + public List<RouterVo> buildMenus(List<SysMenu> menus) + { + List<RouterVo> routers = new LinkedList<RouterVo>(); + for (SysMenu menu : menus) + { + RouterVo router = new RouterVo(); + router.setName(StringUtils.capitalize(menu.getPath())); + router.setPath(getRouterPath(menu)); + router.setComponent(StringUtils.isEmpty(menu.getComponent()) ? "Layout" : menu.getComponent()); + router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + List<SysMenu> cMenus = menu.getChildren(); + if (!cMenus.isEmpty() && cMenus.size() > 0 && "M".equals(menu.getMenuType())) + { + router.setAlwaysShow(true); + router.setRedirect("noRedirect"); + router.setChildren(buildMenus(cMenus)); + } + routers.add(router); + } + return routers; + } + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯 + * + * @param menus 鑿滃崟鍒楄〃 + * @return 鏍戠粨鏋勫垪琛� + */ + @Override + public List<SysMenu> buildMenuTree(List<SysMenu> menus) + { + List<SysMenu> returnList = new ArrayList<SysMenu>(); + for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 鏍规嵁浼犲叆鐨勬煇涓埗鑺傜偣ID,閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣 + if (t.getParentId() == 0) + { + recursionFn(menus, t); + returnList.add(t); + } + } + if (returnList.isEmpty()) + { + returnList = menus; + } + return returnList; + } + + /** + * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯 + * + * @param menus 鑿滃崟鍒楄〃 + * @return 涓嬫媺鏍戠粨鏋勫垪琛� + */ + @Override + public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) + { + List<SysMenu> menuTrees = buildMenuTree(menus); + return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList()); + } + + /** + * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅 + * + * @param menuId 鑿滃崟ID + * @return 鑿滃崟淇℃伅 + */ + @Override + public SysMenu selectMenuById(Long menuId) + { + return menuMapper.selectMenuById(menuId); + } + + /** + * 鏄惁瀛樺湪鑿滃崟瀛愯妭鐐� + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + @Override + public boolean hasChildByMenuId(Long menuId) + { + int result = menuMapper.hasChildByMenuId(menuId); + return result > 0 ? true : false; + } + + /** + * 鏌ヨ鑿滃崟浣跨敤鏁伴噺 + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + @Override + public boolean checkMenuExistRole(Long menuId) + { + int result = roleMenuMapper.checkMenuExistRole(menuId); + return result > 0 ? true : false; + } + + /** + * 鏂板淇濆瓨鑿滃崟淇℃伅 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertMenu(SysMenu menu) + { + return menuMapper.insertMenu(menu); + } + + /** + * 淇敼淇濆瓨鑿滃崟淇℃伅 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateMenu(SysMenu menu) + { + return menuMapper.updateMenu(menu); + } + + /** + * 鍒犻櫎鑿滃崟绠$悊淇℃伅 + * + * @param menuId 鑿滃崟ID + * @return 缁撴灉 + */ + @Override + public int deleteMenuById(Long menuId) + { + return menuMapper.deleteMenuById(menuId); + } + + /** + * 鏍¢獙鑿滃崟鍚嶇О鏄惁鍞竴 + * + * @param menu 鑿滃崟淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkMenuNameUnique(SysMenu menu) + { + Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId(); + SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId()); + if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鑾峰彇璺敱鍦板潃 + * + * @param menu 鑿滃崟淇℃伅 + * @return 璺敱鍦板潃 + */ + public String getRouterPath(SysMenu menu) + { + String routerPath = menu.getPath(); + // 闈炲閾惧苟涓旀槸涓�绾х洰褰� + if (0 == menu.getParentId() && "1".equals(menu.getIsFrame())) + { + routerPath = "/" + menu.getPath(); + } + return routerPath; + } + + /** + * 鏍规嵁鐖惰妭鐐圭殑ID鑾峰彇鎵�鏈夊瓙鑺傜偣 + * + * @param list 鍒嗙被琛� + * @param parentId 浼犲叆鐨勭埗鑺傜偣ID + * @return String + */ + public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) + { + List<SysMenu> returnList = new ArrayList<SysMenu>(); + for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext();) + { + SysMenu t = (SysMenu) iterator.next(); + // 涓�銆佹牴鎹紶鍏ョ殑鏌愪釜鐖惰妭鐐笽D,閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣 + if (t.getParentId() == parentId) + { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + /** + * 閫掑綊鍒楄〃 + * + * @param list + * @param t + */ + private void recursionFn(List<SysMenu> list, SysMenu t) + { + // 寰楀埌瀛愯妭鐐瑰垪琛� + List<SysMenu> childList = getChildList(list, t); + t.setChildren(childList); + for (SysMenu tChild : childList) + { + if (hasChild(list, tChild)) + { + // 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣 + Iterator<SysMenu> it = childList.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + recursionFn(list, n); + } + } + } + } + + /** + * 寰楀埌瀛愯妭鐐瑰垪琛� + */ + private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) + { + List<SysMenu> tlist = new ArrayList<SysMenu>(); + Iterator<SysMenu> it = list.iterator(); + while (it.hasNext()) + { + SysMenu n = (SysMenu) it.next(); + if (n.getParentId().longValue() == t.getMenuId().longValue()) + { + tlist.add(n); + } + } + return tlist; + } + + /** + * 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣 + */ + private boolean hasChild(List<SysMenu> list, SysMenu t) + { + return getChildList(list, t).size() > 0 ? true : false; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java new file mode 100644 index 0000000..0f05dd5 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java @@ -0,0 +1,91 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.project.system.domain.SysNotice; +import com.ruoyi.project.system.mapper.SysNoticeMapper; +import com.ruoyi.project.system.service.ISysNoticeService; + +/** + * 鍏憡 鏈嶅姟灞傚疄鐜� + * + * @author ruoyi + */ +@Service +public class SysNoticeServiceImpl implements ISysNoticeService +{ + @Autowired + private SysNoticeMapper noticeMapper; + + /** + * 鏌ヨ鍏憡淇℃伅 + * + * @param noticeId 鍏憡ID + * @return 鍏憡淇℃伅 + */ + @Override + public SysNotice selectNoticeById(Long noticeId) + { + return noticeMapper.selectNoticeById(noticeId); + } + + /** + * 鏌ヨ鍏憡鍒楄〃 + * + * @param notice 鍏憡淇℃伅 + * @return 鍏憡闆嗗悎 + */ + @Override + public List<SysNotice> selectNoticeList(SysNotice notice) + { + return noticeMapper.selectNoticeList(notice); + } + + /** + * 鏂板鍏憡 + * + * @param notice 鍏憡淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertNotice(SysNotice notice) + { + return noticeMapper.insertNotice(notice); + } + + /** + * 淇敼鍏憡 + * + * @param notice 鍏憡淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateNotice(SysNotice notice) + { + return noticeMapper.updateNotice(notice); + } + + /** + * 鍒犻櫎鍏憡瀵硅薄 + * + * @param noticeId 鍏憡ID + * @return 缁撴灉 + */ + @Override + public int deleteNoticeById(Long noticeId) + { + return noticeMapper.deleteNoticeById(noticeId); + } + + /** + * 鎵归噺鍒犻櫎鍏憡淇℃伅 + * + * @param noticeIds 闇�瑕佸垹闄ょ殑鍏憡ID + * @return 缁撴灉 + */ + public int deleteNoticeByIds(Long noticeIds) + { + return noticeMapper.deleteNoticeByIds(noticeIds); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java new file mode 100644 index 0000000..b31e8cb --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysPostServiceImpl.java @@ -0,0 +1,177 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.project.system.domain.SysPost; +import com.ruoyi.project.system.mapper.SysPostMapper; +import com.ruoyi.project.system.mapper.SysUserPostMapper; +import com.ruoyi.project.system.service.ISysPostService; + +/** + * 宀椾綅淇℃伅 鏈嶅姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysPostServiceImpl implements ISysPostService +{ + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + /** + * 鏌ヨ宀椾綅淇℃伅闆嗗悎 + * + * @param post 宀椾綅淇℃伅 + * @return 宀椾綅淇℃伅闆嗗悎 + */ + @Override + public List<SysPost> selectPostList(SysPost post) + { + return postMapper.selectPostList(post); + } + + /** + * 鏌ヨ鎵�鏈夊矖浣� + * + * @return 宀椾綅鍒楄〃 + */ + @Override + public List<SysPost> selectPostAll() + { + return postMapper.selectPostAll(); + } + + /** + * 閫氳繃宀椾綅ID鏌ヨ宀椾綅淇℃伅 + * + * @param postId 宀椾綅ID + * @return 瑙掕壊瀵硅薄淇℃伅 + */ + @Override + public SysPost selectPostById(Long postId) + { + return postMapper.selectPostById(postId); + } + + /** + * 鏍规嵁鐢ㄦ埛ID鑾峰彇宀椾綅閫夋嫨妗嗗垪琛� + * + * @param userId 鐢ㄦ埛ID + * @return 閫変腑宀椾綅ID鍒楄〃 + */ + public List<Integer> selectPostListByUserId(Long userId) + { + return postMapper.selectPostListByUserId(userId); + } + + /** + * 鏍¢獙宀椾綅鍚嶇О鏄惁鍞竴 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkPostNameUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostNameUnique(post.getPostName()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏍¢獙宀椾綅缂栫爜鏄惁鍞竴 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkPostCodeUnique(SysPost post) + { + Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId(); + SysPost info = postMapper.checkPostCodeUnique(post.getPostCode()); + if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 閫氳繃宀椾綅ID鏌ヨ宀椾綅浣跨敤鏁伴噺 + * + * @param postId 宀椾綅ID + * @return 缁撴灉 + */ + @Override + public int countUserPostById(Long postId) + { + return userPostMapper.countUserPostById(postId); + } + + /** + * 鍒犻櫎宀椾綅淇℃伅 + * + * @param postId 宀椾綅ID + * @return 缁撴灉 + */ + @Override + public int deletePostById(Long postId) + { + return postMapper.deletePostById(postId); + } + + /** + * 鎵归噺鍒犻櫎宀椾綅淇℃伅 + * + * @param postIds 闇�瑕佸垹闄ょ殑宀椾綅ID + * @return 缁撴灉 + * @throws Exception 寮傚父 + */ + public int deletePostByIds(Long[] postIds) + { + for (Long postId : postIds) + { + SysPost post = selectPostById(postId); + if (countUserPostById(postId) > 0) + { + throw new CustomException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", post.getPostName())); + } + } + return postMapper.deletePostByIds(postIds); + } + + /** + * 鏂板淇濆瓨宀椾綅淇℃伅 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertPost(SysPost post) + { + return postMapper.insertPost(post); + } + + /** + * 淇敼淇濆瓨宀椾綅淇℃伅 + * + * @param post 宀椾綅淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updatePost(SysPost post) + { + return postMapper.updatePost(post); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..45898d7 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,311 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.DataScope; +import com.ruoyi.project.system.domain.SysRole; +import com.ruoyi.project.system.domain.SysRoleDept; +import com.ruoyi.project.system.domain.SysRoleMenu; +import com.ruoyi.project.system.mapper.SysRoleDeptMapper; +import com.ruoyi.project.system.mapper.SysRoleMapper; +import com.ruoyi.project.system.mapper.SysRoleMenuMapper; +import com.ruoyi.project.system.mapper.SysUserRoleMapper; +import com.ruoyi.project.system.service.ISysRoleService; + +/** + * 瑙掕壊 涓氬姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysRoleServiceImpl implements ISysRoleService +{ + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysRoleMenuMapper roleMenuMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysRoleDeptMapper roleDeptMapper; + + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ瑙掕壊鏁版嵁 + * + * @param role 瑙掕壊淇℃伅 + * @return 瑙掕壊鏁版嵁闆嗗悎淇℃伅 + */ + @Override + @DataScope(deptAlias = "d") + public List<SysRole> selectRoleList(SysRole role) + { + return roleMapper.selectRoleList(role); + } + + /** + * 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺 + * + * @param userId 鐢ㄦ埛ID + * @return 鏉冮檺鍒楄〃 + */ + @Override + public Set<String> selectRolePermissionByUserId(Long userId) + { + List<SysRole> perms = roleMapper.selectRolePermissionByUserId(userId); + Set<String> permsSet = new HashSet<>(); + for (SysRole perm : perms) + { + if (StringUtils.isNotNull(perm)) + { + permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(","))); + } + } + return permsSet; + } + + /** + * 鏌ヨ鎵�鏈夎鑹� + * + * @return 瑙掕壊鍒楄〃 + */ + public List<SysRole> selectRoleAll() + { + return roleMapper.selectRoleAll(); + } + + /** + * 鏍规嵁鐢ㄦ埛ID鑾峰彇瑙掕壊閫夋嫨妗嗗垪琛� + * + * @param userId 鐢ㄦ埛ID + * @return 閫変腑瑙掕壊ID鍒楄〃 + */ + public List<Integer> selectRoleListByUserId(Long userId) + { + return roleMapper.selectRoleListByUserId(userId); + } + + /** + * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @return 瑙掕壊瀵硅薄淇℃伅 + */ + public SysRole selectRoleById(Long roleId) + { + return roleMapper.selectRoleById(roleId); + } + + /** + * 鏍¢獙瑙掕壊鍚嶇О鏄惁鍞竴 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkRoleNameUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleNameUnique(role.getRoleName()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏍¢獙瑙掕壊鏉冮檺鏄惁鍞竴 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + @Override + public String checkRoleKeyUnique(SysRole role) + { + Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId(); + SysRole info = roleMapper.checkRoleKeyUnique(role.getRoleKey()); + if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏍¢獙瑙掕壊鏄惁鍏佽鎿嶄綔 + * + * @param role 瑙掕壊淇℃伅 + */ + public void checkRoleAllowed(SysRole role) + { + if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) + { + throw new CustomException("涓嶅厑璁告搷浣滆秴绾х鐞嗗憳瑙掕壊"); + } + } + + /** + * 閫氳繃瑙掕壊ID鏌ヨ瑙掕壊浣跨敤鏁伴噺 + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + @Override + public int countUserRoleByRoleId(Long roleId) + { + return userRoleMapper.countUserRoleByRoleId(roleId); + } + + /** + * 鏂板淇濆瓨瑙掕壊淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public int insertRole(SysRole role) + { + // 鏂板瑙掕壊淇℃伅 + roleMapper.insertRole(role); + return insertRoleMenu(role); + } + + /** + * 淇敼淇濆瓨瑙掕壊淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public int updateRole(SysRole role) + { + // 淇敼瑙掕壊淇℃伅 + roleMapper.updateRole(role); + // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱� + roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId()); + return insertRoleMenu(role); + } + + /** + * 淇敼瑙掕壊鐘舵�� + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + public int updateRoleStatus(SysRole role) + { + return roleMapper.updateRole(role); + } + + /** + * 淇敼鏁版嵁鏉冮檺淇℃伅 + * + * @param role 瑙掕壊淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public int authDataScope(SysRole role) + { + // 淇敼瑙掕壊淇℃伅 + roleMapper.updateRole(role); + // 鍒犻櫎瑙掕壊涓庨儴闂ㄥ叧鑱� + roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId()); + // 鏂板瑙掕壊鍜岄儴闂ㄤ俊鎭紙鏁版嵁鏉冮檺锛� + return insertRoleDept(role); + } + + /** + * 鏂板瑙掕壊鑿滃崟淇℃伅 + * + * @param role 瑙掕壊瀵硅薄 + */ + public int insertRoleMenu(SysRole role) + { + int rows = 1; + // 鏂板鐢ㄦ埛涓庤鑹茬鐞� + List<SysRoleMenu> list = new ArrayList<SysRoleMenu>(); + for (Long menuId : role.getMenuIds()) + { + SysRoleMenu rm = new SysRoleMenu(); + rm.setRoleId(role.getRoleId()); + rm.setMenuId(menuId); + list.add(rm); + } + if (list.size() > 0) + { + rows = roleMenuMapper.batchRoleMenu(list); + } + return rows; + } + + /** + * 鏂板瑙掕壊閮ㄩ棬淇℃伅(鏁版嵁鏉冮檺) + * + * @param role 瑙掕壊瀵硅薄 + */ + public int insertRoleDept(SysRole role) + { + int rows = 1; + // 鏂板瑙掕壊涓庨儴闂紙鏁版嵁鏉冮檺锛夌鐞� + List<SysRoleDept> list = new ArrayList<SysRoleDept>(); + for (Long deptId : role.getDeptIds()) + { + SysRoleDept rd = new SysRoleDept(); + rd.setRoleId(role.getRoleId()); + rd.setDeptId(deptId); + list.add(rd); + } + if (list.size() > 0) + { + rows = roleDeptMapper.batchRoleDept(list); + } + return rows; + } + + /** + * 閫氳繃瑙掕壊ID鍒犻櫎瑙掕壊 + * + * @param roleId 瑙掕壊ID + * @return 缁撴灉 + */ + @Override + public int deleteRoleById(Long roleId) + { + return roleMapper.deleteRoleById(roleId); + } + + /** + * 鎵归噺鍒犻櫎瑙掕壊淇℃伅 + * + * @param roleIds 闇�瑕佸垹闄ょ殑瑙掕壊ID + * @return 缁撴灉 + */ + public int deleteRoleByIds(Long[] roleIds) + { + for (Long roleId : roleIds) + { + checkRoleAllowed(new SysRole(roleId)); + SysRole role = selectRoleById(roleId); + if (countUserRoleByRoleId(roleId) > 0) + { + throw new CustomException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", role.getRoleName())); + } + } + return roleMapper.deleteRoleByIds(roleIds); + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java new file mode 100644 index 0000000..261e7f1 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java @@ -0,0 +1,95 @@ +package com.ruoyi.project.system.service.impl; + +import org.springframework.stereotype.Service; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.security.LoginUser; +import com.ruoyi.project.monitor.domain.SysUserOnline; +import com.ruoyi.project.system.service.ISysUserOnlineService; + +/** + * 鍦ㄧ嚎鐢ㄦ埛 鏈嶅姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysUserOnlineServiceImpl implements ISysUserOnlineService +{ + /** + * 閫氳繃鐧诲綍鍦板潃鏌ヨ淇℃伅 + * + * @param ipaddr 鐧诲綍鍦板潃 + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛淇℃伅 + */ + @Override + public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 閫氳繃鐢ㄦ埛鍚嶇О鏌ヨ淇℃伅 + * + * @param userName 鐢ㄦ埛鍚嶇О + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛淇℃伅 + */ + @Override + public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) + { + if (StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 閫氳繃鐧诲綍鍦板潃/鐢ㄦ埛鍚嶇О鏌ヨ淇℃伅 + * + * @param ipaddr 鐧诲綍鍦板潃 + * @param userName 鐢ㄦ埛鍚嶇О + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛淇℃伅 + */ + @Override + public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) + { + if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) + { + return loginUserToUserOnline(user); + } + return null; + } + + /** + * 璁剧疆鍦ㄧ嚎鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 鍦ㄧ嚎鐢ㄦ埛 + */ + public SysUserOnline loginUserToUserOnline(LoginUser user) + { + if (StringUtils.isNull(user) && StringUtils.isNull(user.getUser())) + { + return null; + } + SysUserOnline sysUserOnline = new SysUserOnline(); + sysUserOnline.setTokenId(user.getToken()); + sysUserOnline.setUserName(user.getUsername()); + sysUserOnline.setIpaddr(user.getIpaddr()); + sysUserOnline.setLoginLocation(user.getLoginLocation()); + sysUserOnline.setBrowser(user.getBrowser()); + sysUserOnline.setOs(user.getOs()); + sysUserOnline.setLoginTime(user.getLoginTime()); + if (StringUtils.isNotNull(user.getUser().getDept())) + { + sysUserOnline.setDeptName(user.getUser().getDept().getDeptName()); + } + return sysUserOnline; + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..396ea3a --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,455 @@ +package com.ruoyi.project.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.aspectj.lang.annotation.DataScope; +import com.ruoyi.project.system.domain.SysPost; +import com.ruoyi.project.system.domain.SysRole; +import com.ruoyi.project.system.domain.SysUser; +import com.ruoyi.project.system.domain.SysUserPost; +import com.ruoyi.project.system.domain.SysUserRole; +import com.ruoyi.project.system.mapper.SysPostMapper; +import com.ruoyi.project.system.mapper.SysRoleMapper; +import com.ruoyi.project.system.mapper.SysUserMapper; +import com.ruoyi.project.system.mapper.SysUserPostMapper; +import com.ruoyi.project.system.mapper.SysUserRoleMapper; +import com.ruoyi.project.system.service.ISysConfigService; +import com.ruoyi.project.system.service.ISysUserService; + +/** + * 鐢ㄦ埛 涓氬姟灞傚鐞� + * + * @author ruoyi + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private ISysConfigService configService; + + /** + * 鏍规嵁鏉′欢鍒嗛〉鏌ヨ鐢ㄦ埛鍒楄〃 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 鐢ㄦ埛淇℃伅闆嗗悎淇℃伅 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List<SysUser> selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴� + * + * @param userName 鐢ㄦ埛鍚� + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + /** + * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛 + * + * @param userId 鐢ㄦ埛ID + * @return 鐢ㄦ埛瀵硅薄淇℃伅 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + /** + * 鏌ヨ鐢ㄦ埛鎵�灞炶鑹茬粍 + * + * @param userName 鐢ㄦ埛鍚� + * @return 缁撴灉 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List<SysRole> list = roleMapper.selectRolesByUserName(userName); + StringBuffer idsStr = new StringBuffer(); + for (SysRole role : list) + { + idsStr.append(role.getRoleName()).append(","); + } + if (StringUtils.isNotEmpty(idsStr.toString())) + { + return idsStr.substring(0, idsStr.length() - 1); + } + return idsStr.toString(); + } + + /** + * 鏌ヨ鐢ㄦ埛鎵�灞炲矖浣嶇粍 + * + * @param userName 鐢ㄦ埛鍚� + * @return 缁撴灉 + */ + @Override + public String selectUserPostGroup(String userName) + { + List<SysPost> list = postMapper.selectPostsByUserName(userName); + StringBuffer idsStr = new StringBuffer(); + for (SysPost post : list) + { + idsStr.append(post.getPostName()).append(","); + } + if (StringUtils.isNotEmpty(idsStr.toString())) + { + return idsStr.substring(0, idsStr.length() - 1); + } + return idsStr.toString(); + } + + /** + * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴 + * + * @param userName 鐢ㄦ埛鍚嶇О + * @return 缁撴灉 + */ + @Override + public String checkUserNameUnique(String userName) + { + int count = userMapper.checkUserNameUnique(userName); + if (count > 0) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏍¢獙鐢ㄦ埛鍚嶇О鏄惁鍞竴 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return + */ + @Override + public String checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏍¢獙email鏄惁鍞竴 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return + */ + @Override + public String checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 鏍¢獙鐢ㄦ埛鏄惁鍏佽鎿嶄綔 + * + * @param user 鐢ㄦ埛淇℃伅 + */ + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new CustomException("涓嶅厑璁告搷浣滆秴绾х鐞嗗憳鐢ㄦ埛"); + } + } + + /** + * 鏂板淇濆瓨鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public int insertUser(SysUser user) + { + // 鏂板鐢ㄦ埛淇℃伅 + int rows = userMapper.insertUser(user); + // 鏂板鐢ㄦ埛宀椾綅鍏宠仈 + insertUserPost(user); + // 鏂板鐢ㄦ埛涓庤鑹茬鐞� + insertUserRole(user); + return rows; + } + + /** + * 淇敼淇濆瓨鐢ㄦ埛淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public int updateUser(SysUser user) + { + Long userId = user.getUserId(); + // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱� + userRoleMapper.deleteUserRoleByUserId(userId); + // 鏂板鐢ㄦ埛涓庤鑹茬鐞� + insertUserRole(user); + // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶅叧鑱� + userPostMapper.deleteUserPostByUserId(userId); + // 鏂板鐢ㄦ埛涓庡矖浣嶇鐞� + insertUserPost(user); + return userMapper.updateUser(user); + } + + /** + * 淇敼鐢ㄦ埛鐘舵�� + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateUserStatus(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 淇敼鐢ㄦ埛鍩烘湰淇℃伅 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateUserProfile(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 淇敼鐢ㄦ埛澶村儚 + * + * @param userId 鐢ㄦ埛ID + * @param avatar 澶村儚鍦板潃 + * @return 缁撴灉 + */ + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 閲嶇疆鐢ㄦ埛瀵嗙爜 + * + * @param user 鐢ㄦ埛淇℃伅 + * @return 缁撴灉 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 閲嶇疆鐢ㄦ埛瀵嗙爜 + * + * @param userName 鐢ㄦ埛鍚� + * @param password 瀵嗙爜 + * @return 缁撴灉 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 鏂板鐢ㄦ埛瑙掕壊淇℃伅 + * + * @param user 鐢ㄦ埛瀵硅薄 + */ + public void insertUserRole(SysUser user) + { + Long[] roles = user.getRoleIds(); + if (StringUtils.isNotNull(roles)) + { + // 鏂板鐢ㄦ埛涓庤鑹茬鐞� + List<SysUserRole> list = new ArrayList<SysUserRole>(); + for (Long roleId : roles) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(user.getUserId()); + ur.setRoleId(roleId); + list.add(ur); + } + if (list.size() > 0) + { + userRoleMapper.batchUserRole(list); + } + } + } + + /** + * 鏂板鐢ㄦ埛宀椾綅淇℃伅 + * + * @param user 鐢ㄦ埛瀵硅薄 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotNull(posts)) + { + // 鏂板鐢ㄦ埛涓庡矖浣嶇鐞� + List<SysUserPost> list = new ArrayList<SysUserPost>(); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + if (list.size() > 0) + { + userPostMapper.batchUserPost(list); + } + } + } + + /** + * 閫氳繃鐢ㄦ埛ID鍒犻櫎鐢ㄦ埛 + * + * @param userId 鐢ㄦ埛ID + * @return 缁撴灉 + */ + @Override + public int deleteUserById(Long userId) + { + // 鍒犻櫎鐢ㄦ埛涓庤鑹插叧鑱� + userRoleMapper.deleteUserRoleByUserId(userId); + // 鍒犻櫎鐢ㄦ埛涓庡矖浣嶈〃 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 鎵归噺鍒犻櫎鐢ㄦ埛淇℃伅 + * + * @param userIds 闇�瑕佸垹闄ょ殑鐢ㄦ埛ID + * @return 缁撴灉 + */ + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + } + return userMapper.deleteUserByIds(userIds); + } + + /** + * 瀵煎叆鐢ㄦ埛鏁版嵁 + * + * @param userList 鐢ㄦ埛鏁版嵁鍒楄〃 + * @param isUpdateSupport 鏄惁鏇存柊鏀寔锛屽鏋滃凡瀛樺湪锛屽垯杩涜鏇存柊鏁版嵁 + * @param operName 鎿嶄綔鐢ㄦ埛 + * @return 缁撴灉 + */ + @Override + public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new CustomException("瀵煎叆鐢ㄦ埛鏁版嵁涓嶈兘涓虹┖锛�"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + String password = configService.selectConfigByKey("sys.user.initPassword"); + for (SysUser user : userList) + { + try + { + // 楠岃瘉鏄惁瀛樺湪杩欎釜鐢ㄦ埛 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + this.insertUser(user); + successNum++; + successMsg.append("<br/>" + successNum + "銆佽处鍙� " + user.getUserName() + " 瀵煎叆鎴愬姛"); + } + else if (isUpdateSupport) + { + user.setUpdateBy(operName); + this.updateUser(user); + successNum++; + successMsg.append("<br/>" + successNum + "銆佽处鍙� " + user.getUserName() + " 鏇存柊鎴愬姛"); + } + else + { + failureNum++; + failureMsg.append("<br/>" + failureNum + "銆佽处鍙� " + user.getUserName() + " 宸插瓨鍦�"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "<br/>" + failureNum + "銆佽处鍙� " + user.getUserName() + " 瀵煎叆澶辫触锛�"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "寰堟姳姝夛紝瀵煎叆澶辫触锛佸叡 " + failureNum + " 鏉℃暟鎹牸寮忎笉姝g‘锛岄敊璇涓嬶細"); + throw new CustomException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "鎭枩鎮紝鏁版嵁宸插叏閮ㄥ鍏ユ垚鍔燂紒鍏� " + successNum + " 鏉★紝鏁版嵁濡備笅锛�"); + } + return successMsg.toString(); + } + +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java new file mode 100644 index 0000000..69eea9f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/controller/GenController.java @@ -0,0 +1,185 @@ +package com.ruoyi.project.tool.gen.controller; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.utils.text.Convert; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.framework.web.page.TableDataInfo; +import com.ruoyi.project.tool.gen.domain.GenTable; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; +import com.ruoyi.project.tool.gen.service.IGenTableColumnService; +import com.ruoyi.project.tool.gen.service.IGenTableService; + +/** + * 浠g爜鐢熸垚 鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/tool/gen") +public class GenController extends BaseController +{ + + @Autowired + private IGenTableService genTableService; + + @Autowired + private IGenTableColumnService genTableColumnService; + + /** + * 鏌ヨ浠g爜鐢熸垚鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/list") + public TableDataInfo genList(GenTable genTable) + { + startPage(); + List<GenTable> list = genTableService.selectGenTableList(genTable); + return getDataTable(list); + } + + /** + * 淇敼浠g爜鐢熸垚涓氬姟 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:query')") + @GetMapping(value = "/{talbleId}") + public AjaxResult getInfo(@PathVariable Long talbleId) + { + GenTable table = genTableService.selectGenTableById(talbleId); + List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(talbleId); + Map<String, Object> map = new HashMap<String, Object>(); + map.put("info", table); + map.put("rows", list); + return AjaxResult.success(map); + } + + /** + * 鏌ヨ鏁版嵁搴撳垪琛� + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping("/db/list") + public TableDataInfo dataList(GenTable genTable) + { + startPage(); + List<GenTable> list = genTableService.selectDbTableList(genTable); + return getDataTable(list); + } + + /** + * 鏌ヨ鏁版嵁琛ㄥ瓧娈靛垪琛� + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @GetMapping(value = "/column/{talbleId}") + public TableDataInfo columnList(Long tableId) + { + TableDataInfo dataInfo = new TableDataInfo(); + List<GenTableColumn> list = genTableColumnService.selectGenTableColumnListByTableId(tableId); + dataInfo.setRows(list); + dataInfo.setTotal(list.size()); + return dataInfo; + } + + /** + * 瀵煎叆琛ㄧ粨鏋勶紙淇濆瓨锛� + */ + @PreAuthorize("@ss.hasPermi('tool:gen:list')") + @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.IMPORT) + @PostMapping("/importTable") + public AjaxResult importTableSave(String tables) + { + String[] tableNames = Convert.toStrArray(tables); + // 鏌ヨ琛ㄤ俊鎭� + List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames); + genTableService.importGenTable(tableList); + return AjaxResult.success(); + } + + /** + * 淇敼淇濆瓨浠g爜鐢熸垚涓氬姟 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:edit')") + @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult editSave(@Validated @RequestBody GenTable genTable) + { + System.out.println(genTable.getParams().size()); + genTableService.validateEdit(genTable); + genTableService.updateGenTable(genTable); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('tool:gen:remove')") + @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.DELETE) + @DeleteMapping("/{tableIds}") + public AjaxResult remove(@PathVariable Long[] tableIds) + { + genTableService.deleteGenTableByIds(tableIds); + return AjaxResult.success(); + } + + /** + * 棰勮浠g爜 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:preview')") + @GetMapping("/preview/{tableId}") + public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException + { + Map<String, String> dataMap = genTableService.previewCode(tableId); + return AjaxResult.success(dataMap); + } + + /** + * 鐢熸垚浠g爜 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE) + @GetMapping("/genCode/{tableName}") + public void genCode(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException + { + byte[] data = genTableService.generatorCode(tableName); + genCode(response, data); + } + + /** + * 鎵归噺鐢熸垚浠g爜 + */ + @PreAuthorize("@ss.hasPermi('tool:gen:code')") + @Log(title = "浠g爜鐢熸垚", businessType = BusinessType.GENCODE) + @GetMapping("/batchGenCode") + public void batchGenCode(HttpServletResponse response, String tables) throws IOException + { + String[] tableNames = Convert.toStrArray(tables); + byte[] data = genTableService.generatorCode(tableNames); + genCode(response, data); + } + + /** + * 鐢熸垚zip鏂囦欢 + */ + private void genCode(HttpServletResponse response, byte[] data) throws IOException + { + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + IOUtils.write(data, response.getOutputStream()); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTable.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTable.java new file mode 100644 index 0000000..58bcf41 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTable.java @@ -0,0 +1,269 @@ +package com.ruoyi.project.tool.gen.domain; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 涓氬姟琛� gen_table + * + * @author ruoyi + */ +public class GenTable extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 缂栧彿 */ + private Long tableId; + + /** 琛ㄥ悕绉� */ + @NotBlank(message = "琛ㄥ悕绉颁笉鑳戒负绌�") + private String tableName; + + /** 琛ㄦ弿杩� */ + @NotBlank(message = "琛ㄦ弿杩颁笉鑳戒负绌�") + private String tableComment; + + /** 瀹炰綋绫诲悕绉�(棣栧瓧姣嶅ぇ鍐�) */ + @NotBlank(message = "瀹炰綋绫诲悕绉颁笉鑳戒负绌�") + private String className; + + /** 浣跨敤鐨勬ā鏉匡紙crud鍗曡〃鎿嶄綔 tree鏍戣〃鎿嶄綔锛� */ + private String tplCategory; + + /** 鐢熸垚鍖呰矾寰� */ + @NotBlank(message = "鐢熸垚鍖呰矾寰勪笉鑳戒负绌�") + private String packageName; + + /** 鐢熸垚妯″潡鍚� */ + @NotBlank(message = "鐢熸垚妯″潡鍚嶄笉鑳戒负绌�") + private String moduleName; + + /** 鐢熸垚涓氬姟鍚� */ + @NotBlank(message = "鐢熸垚涓氬姟鍚嶄笉鑳戒负绌�") + private String businessName; + + /** 鐢熸垚鍔熻兘鍚� */ + @NotBlank(message = "鐢熸垚鍔熻兘鍚嶄笉鑳戒负绌�") + private String functionName; + + /** 鐢熸垚浣滆�� */ + @NotBlank(message = "浣滆�呬笉鑳戒负绌�") + private String functionAuthor; + + /** 涓婚敭淇℃伅 */ + private GenTableColumn pkColumn; + + /** 琛ㄥ垪淇℃伅 */ + @Valid + private List<GenTableColumn> columns; + + /** 鍏跺畠鐢熸垚閫夐」 */ + private String options; + + /** 鏍戠紪鐮佸瓧娈� */ + private String treeCode; + + /** 鏍戠埗缂栫爜瀛楁 */ + private String treeParentCode; + + /** 鏍戝悕绉板瓧娈� */ + private String treeName; + + public Long getTableId() + { + return tableId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public String getTableName() + { + return tableName; + } + + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + public String getTableComment() + { + return tableComment; + } + + public void setTableComment(String tableComment) + { + this.tableComment = tableComment; + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getTplCategory() + { + return tplCategory; + } + + public void setTplCategory(String tplCategory) + { + this.tplCategory = tplCategory; + } + + public String getPackageName() + { + return packageName; + } + + public void setPackageName(String packageName) + { + this.packageName = packageName; + } + + public String getModuleName() + { + return moduleName; + } + + public void setModuleName(String moduleName) + { + this.moduleName = moduleName; + } + + public String getBusinessName() + { + return businessName; + } + + public void setBusinessName(String businessName) + { + this.businessName = businessName; + } + + public String getFunctionName() + { + return functionName; + } + + public void setFunctionName(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionAuthor() + { + return functionAuthor; + } + + public void setFunctionAuthor(String functionAuthor) + { + this.functionAuthor = functionAuthor; + } + + public GenTableColumn getPkColumn() + { + return pkColumn; + } + + public void setPkColumn(GenTableColumn pkColumn) + { + this.pkColumn = pkColumn; + } + + public List<GenTableColumn> getColumns() + { + return columns; + } + + public void setColumns(List<GenTableColumn> columns) + { + this.columns = columns; + } + + public String getOptions() + { + return options; + } + + public void setOptions(String options) + { + this.options = options; + } + + public String getTreeCode() + { + return treeCode; + } + + public void setTreeCode(String treeCode) + { + this.treeCode = treeCode; + } + + public String getTreeParentCode() + { + return treeParentCode; + } + + public void setTreeParentCode(String treeParentCode) + { + this.treeParentCode = treeParentCode; + } + + public String getTreeName() + { + return treeName; + } + + public void setTreeName(String treeName) + { + this.treeName = treeName; + } + + public boolean isTree() + { + return isTree(this.tplCategory); + } + + public static boolean isTree(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); + } + + public boolean isCrud() + { + return isCrud(this.tplCategory); + } + + public static boolean isCrud(String tplCategory) + { + return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); + } + + public boolean isSuperColumn(String javaField) + { + return isSuperColumn(this.tplCategory, javaField); + } + + public static boolean isSuperColumn(String tplCategory, String javaField) + { + if (isTree(tplCategory)) + { + StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.TREE_ENTITY); + } + return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTableColumn.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTableColumn.java new file mode 100644 index 0000000..b73f28c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/domain/GenTableColumn.java @@ -0,0 +1,368 @@ +package com.ruoyi.project.tool.gen.domain; + +import javax.validation.constraints.NotBlank; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.domain.BaseEntity; + +/** + * 浠g爜鐢熸垚涓氬姟瀛楁琛� gen_table_column + * + * @author ruoyi + */ +public class GenTableColumn extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 缂栧彿 */ + private Long columnId; + + /** 褰掑睘琛ㄧ紪鍙� */ + private Long tableId; + + /** 鍒楀悕绉� */ + private String columnName; + + /** 鍒楁弿杩� */ + private String columnComment; + + /** 鍒楃被鍨� */ + private String columnType; + + /** JAVA绫诲瀷 */ + private String javaType; + + /** JAVA瀛楁鍚� */ + @NotBlank(message = "Java灞炴�т笉鑳戒负绌�") + private String javaField; + + /** 鏄惁涓婚敭锛�1鏄級 */ + private String isPk; + + /** 鏄惁鑷锛�1鏄級 */ + private String isIncrement; + + /** 鏄惁蹇呭~锛�1鏄級 */ + private String isRequired; + + /** 鏄惁涓烘彃鍏ュ瓧娈碉紙1鏄級 */ + private String isInsert; + + /** 鏄惁缂栬緫瀛楁锛�1鏄級 */ + private String isEdit; + + /** 鏄惁鍒楄〃瀛楁锛�1鏄級 */ + private String isList; + + /** 鏄惁鏌ヨ瀛楁锛�1鏄級 */ + private String isQuery; + + /** 鏌ヨ鏂瑰紡锛圗Q绛変簬銆丯E涓嶇瓑浜庛�丟T澶т簬銆丩T灏忎簬銆丩IKE妯$硦銆丅ETWEEN鑼冨洿锛� */ + private String queryType; + + /** 鏄剧ず绫诲瀷锛坕nput鏂囨湰妗嗐�乼extarea鏂囨湰鍩熴�乻elect涓嬫媺妗嗐�乧heckbox澶嶉�夋銆乺adio鍗曢�夋銆乨atetime鏃ユ湡鎺т欢锛� */ + private String htmlType; + + /** 瀛楀吀绫诲瀷 */ + private String dictType; + + /** 鎺掑簭 */ + private Integer sort; + + public void setColumnId(Long columnId) + { + this.columnId = columnId; + } + + public Long getColumnId() + { + return columnId; + } + + public void setTableId(Long tableId) + { + this.tableId = tableId; + } + + public Long getTableId() + { + return tableId; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnComment(String columnComment) + { + this.columnComment = columnComment; + } + + public String getColumnComment() + { + return columnComment; + } + + public void setColumnType(String columnType) + { + this.columnType = columnType; + } + + public String getColumnType() + { + return columnType; + } + + public void setJavaType(String javaType) + { + this.javaType = javaType; + } + + public String getJavaType() + { + return javaType; + } + + public void setJavaField(String javaField) + { + this.javaField = javaField; + } + + public String getJavaField() + { + return javaField; + } + + public void setIsPk(String isPk) + { + this.isPk = isPk; + } + + public String getIsPk() + { + return isPk; + } + + public boolean isPk() + { + return isPk(this.isPk); + } + + public boolean isPk(String isPk) + { + return isPk != null && StringUtils.equals("1", isPk); + } + + public String getIsIncrement() + { + return isIncrement; + } + + public void setIsIncrement(String isIncrement) + { + this.isIncrement = isIncrement; + } + + public boolean isIncrement() + { + return isIncrement(this.isIncrement); + } + + public boolean isIncrement(String isIncrement) + { + return isIncrement != null && StringUtils.equals("1", isIncrement); + } + + public void setIsRequired(String isRequired) + { + this.isRequired = isRequired; + } + + public String getIsRequired() + { + return isRequired; + } + + public boolean isRequired() + { + return isRequired(this.isRequired); + } + + public boolean isRequired(String isRequired) + { + return isRequired != null && StringUtils.equals("1", isRequired); + } + + public void setIsInsert(String isInsert) + { + this.isInsert = isInsert; + } + + public String getIsInsert() + { + return isInsert; + } + + public boolean isInsert() + { + return isInsert(this.isInsert); + } + + public boolean isInsert(String isInsert) + { + return isInsert != null && StringUtils.equals("1", isInsert); + } + + public void setIsEdit(String isEdit) + { + this.isEdit = isEdit; + } + + public String getIsEdit() + { + return isEdit; + } + + public boolean isEdit() + { + return isInsert(this.isEdit); + } + + public boolean isEdit(String isEdit) + { + return isEdit != null && StringUtils.equals("1", isEdit); + } + + public void setIsList(String isList) + { + this.isList = isList; + } + + public String getIsList() + { + return isList; + } + + public boolean isList() + { + return isList(this.isList); + } + + public boolean isList(String isList) + { + return isList != null && StringUtils.equals("1", isList); + } + + public void setIsQuery(String isQuery) + { + this.isQuery = isQuery; + } + + public String getIsQuery() + { + return isQuery; + } + + public boolean isQuery() + { + return isQuery(this.isQuery); + } + + public boolean isQuery(String isQuery) + { + return isQuery != null && StringUtils.equals("1", isQuery); + } + + public void setQueryType(String queryType) + { + this.queryType = queryType; + } + + public String getQueryType() + { + return queryType; + } + + public String getHtmlType() + { + return htmlType; + } + + public void setHtmlType(String htmlType) + { + this.htmlType = htmlType; + } + + public void setDictType(String dictType) + { + this.dictType = dictType; + } + + public String getDictType() + { + return dictType; + } + + public void setSort(Integer sort) + { + this.sort = sort; + } + + public Integer getSort() + { + return sort; + } + + public boolean isSuperColumn() + { + return isSuperColumn(this.javaField); + } + + public static boolean isSuperColumn(String javaField) + { + return StringUtils.equalsAnyIgnoreCase(javaField, + // BaseEntity + "createBy", "createTime", "updateBy", "updateTime", "remark", + // TreeEntity + "parentName", "parentId", "orderNum", "ancestors"); + } + + public boolean isUsableColumn() + { + return isUsableColumn(javaField); + } + + public static boolean isUsableColumn(String javaField) + { + // isSuperColumn()涓殑鍚嶅崟鐢ㄤ簬閬垮厤鐢熸垚澶氫綑Domain灞炴�э紝鑻ユ煇浜涘睘鎬у湪鐢熸垚椤甸潰鏃堕渶瑕佺敤鍒颁笉鑳藉拷鐣ワ紝鍒欐斁鍦ㄦ澶勭櫧鍚嶅崟 + return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum"); + } + + public String readConverterExp() + { + String remarks = StringUtils.substringBetween(this.columnComment, "锛�", "锛�"); + StringBuffer sb = new StringBuffer(); + if (StringUtils.isNotEmpty(remarks)) + { + for (String value : remarks.split(" ")) + { + if (StringUtils.isNotEmpty(value)) + { + Object startStr = value.subSequence(0, 1); + String endStr = value.substring(1); + sb.append("").append(startStr).append("=").append(endStr).append(","); + } + } + return sb.deleteCharAt(sb.length() - 1).toString(); + } + else + { + return this.columnComment; + } + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableColumnMapper.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableColumnMapper.java new file mode 100644 index 0000000..3aa09e8 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableColumnMapper.java @@ -0,0 +1,52 @@ +package com.ruoyi.project.tool.gen.mapper; + +import java.util.List; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; + +/** + * 涓氬姟瀛楁 鏁版嵁灞� + * + * @author ruoyi + */ +public interface GenTableColumnMapper +{ + /** + * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅 + * + * @param tableName 琛ㄥ悕绉� + * @return 鍒椾俊鎭� + */ + public List<GenTableColumn> selectDbTableColumnsByName(String tableName); + + /** + * 鏌ヨ涓氬姟瀛楁鍒楄〃 + * + * @param tableId 涓氬姟瀛楁缂栧彿 + * @return 涓氬姟瀛楁闆嗗悎 + */ + public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId); + + /** + * 鏂板涓氬姟瀛楁 + * + * @param genTableColumn 涓氬姟瀛楁淇℃伅 + * @return 缁撴灉 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 淇敼涓氬姟瀛楁 + * + * @param genTableColumn 涓氬姟瀛楁淇℃伅 + * @return 缁撴灉 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 鎵归噺鍒犻櫎涓氬姟瀛楁 + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteGenTableColumnByIds(Long[] ids); +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableMapper.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableMapper.java new file mode 100644 index 0000000..a7bcf95 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/mapper/GenTableMapper.java @@ -0,0 +1,76 @@ +package com.ruoyi.project.tool.gen.mapper; + +import java.util.List; +import com.ruoyi.project.tool.gen.domain.GenTable; + +/** + * 涓氬姟 鏁版嵁灞� + * + * @author ruoyi + */ +public interface GenTableMapper +{ + /** + * 鏌ヨ涓氬姟鍒楄〃 + * + * @param genTable 涓氬姟淇℃伅 + * @return 涓氬姟闆嗗悎 + */ + public List<GenTable> selectGenTableList(GenTable genTable); + + /** + * 鏌ヨ鎹簱鍒楄〃 + * + * @param genTable 涓氬姟淇℃伅 + * @return 鏁版嵁搴撹〃闆嗗悎 + */ + public List<GenTable> selectDbTableList(GenTable genTable); + + /** + * 鏌ヨ鎹簱鍒楄〃 + * + * @param tableNames 琛ㄥ悕绉扮粍 + * @return 鏁版嵁搴撹〃闆嗗悎 + */ + public List<GenTable> selectDbTableListByNames(String[] tableNames); + + /** + * 鏌ヨ琛↖D涓氬姟淇℃伅 + * + * @param id 涓氬姟ID + * @return 涓氬姟淇℃伅 + */ + public GenTable selectGenTableById(Long id); + + /** + * 鏌ヨ琛ㄥ悕绉颁笟鍔′俊鎭� + * + * @param tableName 琛ㄥ悕绉� + * @return 涓氬姟淇℃伅 + */ + public GenTable selectGenTableByName(String tableName); + + /** + * 鏂板涓氬姟 + * + * @param genTable 涓氬姟淇℃伅 + * @return 缁撴灉 + */ + public int insertGenTable(GenTable genTable); + + /** + * 淇敼涓氬姟 + * + * @param genTable 涓氬姟淇℃伅 + * @return 缁撴灉 + */ + public int updateGenTable(GenTable genTable); + + /** + * 鎵归噺鍒犻櫎涓氬姟 + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteGenTableByIds(Long[] ids); +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableColumnServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableColumnServiceImpl.java new file mode 100644 index 0000000..5e3a472 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableColumnServiceImpl.java @@ -0,0 +1,68 @@ +package com.ruoyi.project.tool.gen.service; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.utils.text.Convert; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; +import com.ruoyi.project.tool.gen.mapper.GenTableColumnMapper; + +/** + * 涓氬姟瀛楁 鏈嶅姟灞傚疄鐜� + * + * @author ruoyi + */ +@Service +public class GenTableColumnServiceImpl implements IGenTableColumnService +{ + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 鏌ヨ涓氬姟瀛楁鍒楄〃 + * + * @param genTableColumn 涓氬姟瀛楁缂栧彿 + * @return 涓氬姟瀛楁闆嗗悎 + */ + @Override + public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId) + { + return genTableColumnMapper.selectGenTableColumnListByTableId(tableId); + } + + /** + * 鏂板涓氬姟瀛楁 + * + * @param genTableColumn 涓氬姟瀛楁淇℃伅 + * @return 缁撴灉 + */ + @Override + public int insertGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.insertGenTableColumn(genTableColumn); + } + + /** + * 淇敼涓氬姟瀛楁 + * + * @param genTableColumn 涓氬姟瀛楁淇℃伅 + * @return 缁撴灉 + */ + @Override + public int updateGenTableColumn(GenTableColumn genTableColumn) + { + return genTableColumnMapper.updateGenTableColumn(genTableColumn); + } + + /** + * 鍒犻櫎涓氬姟瀛楁瀵硅薄 + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + @Override + public int deleteGenTableColumnByIds(String ids) + { + return genTableColumnMapper.deleteGenTableColumnByIds(Convert.toLongArray(ids)); + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableServiceImpl.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableServiceImpl.java new file mode 100644 index 0000000..85a3613 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/GenTableServiceImpl.java @@ -0,0 +1,341 @@ +package com.ruoyi.project.tool.gen.service; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.IOUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.exception.CustomException; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.project.tool.gen.domain.GenTable; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; +import com.ruoyi.project.tool.gen.mapper.GenTableColumnMapper; +import com.ruoyi.project.tool.gen.mapper.GenTableMapper; +import com.ruoyi.project.tool.gen.util.GenUtils; +import com.ruoyi.project.tool.gen.util.VelocityInitializer; +import com.ruoyi.project.tool.gen.util.VelocityUtils; + +/** + * 涓氬姟 鏈嶅姟灞傚疄鐜� + * + * @author ruoyi + */ +@Service +public class GenTableServiceImpl implements IGenTableService +{ + private static final Logger log = LoggerFactory.getLogger(GenTableServiceImpl.class); + + @Autowired + private GenTableMapper genTableMapper; + + @Autowired + private GenTableColumnMapper genTableColumnMapper; + + /** + * 鏌ヨ涓氬姟淇℃伅 + * + * @param id 涓氬姟ID + * @return 涓氬姟淇℃伅 + */ + @Override + public GenTable selectGenTableById(Long id) + { + GenTable genTable = genTableMapper.selectGenTableById(id); + setTableFromOptions(genTable); + return genTable; + } + + /** + * 鏌ヨ涓氬姟鍒楄〃 + * + * @param genTable 涓氬姟淇℃伅 + * @return 涓氬姟闆嗗悎 + */ + @Override + public List<GenTable> selectGenTableList(GenTable genTable) + { + return genTableMapper.selectGenTableList(genTable); + } + + /** + * 鏌ヨ鎹簱鍒楄〃 + * + * @param genTable 涓氬姟淇℃伅 + * @return 鏁版嵁搴撹〃闆嗗悎 + */ + public List<GenTable> selectDbTableList(GenTable genTable) + { + return genTableMapper.selectDbTableList(genTable); + } + + /** + * 鏌ヨ鎹簱鍒楄〃 + * + * @param tableNames 琛ㄥ悕绉扮粍 + * @return 鏁版嵁搴撹〃闆嗗悎 + */ + public List<GenTable> selectDbTableListByNames(String[] tableNames) + { + return genTableMapper.selectDbTableListByNames(tableNames); + } + + /** + * 淇敼涓氬姟 + * + * @param genTable 涓氬姟淇℃伅 + * @return 缁撴灉 + */ + @Override + @Transactional + public void updateGenTable(GenTable genTable) + { + String options = JSON.toJSONString(genTable.getParams()); + genTable.setOptions(options); + int row = genTableMapper.updateGenTable(genTable); + if (row > 0) + { + for (GenTableColumn cenTableColumn : genTable.getColumns()) + { + genTableColumnMapper.updateGenTableColumn(cenTableColumn); + } + } + } + + /** + * 鍒犻櫎涓氬姟瀵硅薄 + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + @Override + @Transactional + public void deleteGenTableByIds(Long[] tableIds) + { + genTableMapper.deleteGenTableByIds(tableIds); + genTableColumnMapper.deleteGenTableColumnByIds(tableIds); + } + + /** + * 瀵煎叆琛ㄧ粨鏋� + * + * @param tableList 瀵煎叆琛ㄥ垪琛� + */ + @Override + @Transactional + public void importGenTable(List<GenTable> tableList) + { + String operName = SecurityUtils.getUsername(); + for (GenTable table : tableList) + { + try + { + String tableName = table.getTableName(); + GenUtils.initTable(table, operName); + int row = genTableMapper.insertGenTable(table); + if (row > 0) + { + // 淇濆瓨鍒椾俊鎭� + List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName); + for (GenTableColumn column : genTableColumns) + { + GenUtils.initColumnField(column, table); + genTableColumnMapper.insertGenTableColumn(column); + } + } + } + catch (Exception e) + { + log.error("琛ㄥ悕 " + table.getTableName() + " 瀵煎叆澶辫触锛�", e); + } + } + } + + /** + * 棰勮浠g爜 + * + * @param tableId 琛ㄧ紪鍙� + * @return 棰勮鏁版嵁鍒楄〃 + */ + public Map<String, String> previewCode(Long tableId) + { + Map<String, String> dataMap = new LinkedHashMap<>(); + // 鏌ヨ琛ㄤ俊鎭� + GenTable table = genTableMapper.selectGenTableById(tableId); + // 鏌ヨ鍒椾俊鎭� + List<GenTableColumn> columns = table.getColumns(); + setPkColumn(table, columns); + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 鑾峰彇妯℃澘鍒楄〃 + List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 娓叉煋妯℃澘 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + dataMap.put(template, sw.toString()); + } + return dataMap; + } + + /** + * 鐢熸垚浠g爜 + * + * @param tableName 琛ㄥ悕绉� + * @return 鏁版嵁 + */ + @Override + public byte[] generatorCode(String tableName) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + generatorCode(tableName, zip); + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 鎵归噺鐢熸垚浠g爜 + * + * @param tableNames 琛ㄦ暟缁� + * @return 鏁版嵁 + */ + @Override + public byte[] generatorCode(String[] tableNames) + { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + for (String tableName : tableNames) + { + generatorCode(tableName, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + + /** + * 鏌ヨ琛ㄤ俊鎭苟鐢熸垚浠g爜 + */ + private void generatorCode(String tableName, ZipOutputStream zip) + { + // 鏌ヨ琛ㄤ俊鎭� + GenTable table = genTableMapper.selectGenTableByName(tableName); + // 鏌ヨ鍒椾俊鎭� + List<GenTableColumn> columns = table.getColumns(); + setPkColumn(table, columns); + + VelocityInitializer.initVelocity(); + + VelocityContext context = VelocityUtils.prepareContext(table); + + // 鑾峰彇妯℃澘鍒楄〃 + List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); + for (String template : templates) + { + // 娓叉煋妯℃澘 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, Constants.UTF8); + tpl.merge(context, sw); + try + { + // 娣诲姞鍒皕ip + zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); + IOUtils.write(sw.toString(), zip, Constants.UTF8); + IOUtils.closeQuietly(sw); + zip.flush(); + zip.closeEntry(); + } + catch (IOException e) + { + log.error("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName(), e); + } + } + } + + /** + * 淇敼淇濆瓨鍙傛暟鏍¢獙 + * + * @param genTable 涓氬姟淇℃伅 + */ + public void validateEdit(GenTable genTable) + { + if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) + { + String options = JSON.toJSONString(genTable.getParams()); + JSONObject paramsObj = JSONObject.parseObject(options); + if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) + { + throw new CustomException("鏍戠紪鐮佸瓧娈典笉鑳戒负绌�"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) + { + throw new CustomException("鏍戠埗缂栫爜瀛楁涓嶈兘涓虹┖"); + } + else if (StringUtils.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) + { + throw new CustomException("鏍戝悕绉板瓧娈典笉鑳戒负绌�"); + } + } + } + + /** + * 璁剧疆涓婚敭鍒椾俊鎭� + * + * @param genTable 涓氬姟琛ㄤ俊鎭� + * @param columns 涓氬姟瀛楁鍒楄〃 + */ + public void setPkColumn(GenTable table, List<GenTableColumn> columns) + { + for (GenTableColumn column : columns) + { + if (column.isPk()) + { + table.setPkColumn(column); + break; + } + } + if (StringUtils.isNull(table.getPkColumn())) + { + table.setPkColumn(columns.get(0)); + } + } + + /** + * 璁剧疆浠g爜鐢熸垚鍏朵粬閫夐」鍊� + * + * @param genTable 璁剧疆鍚庣殑鐢熸垚瀵硅薄 + */ + public void setTableFromOptions(GenTable genTable) + { + JSONObject paramsObj = JSONObject.parseObject(genTable.getOptions()); + if (StringUtils.isNotNull(paramsObj)) + { + String treeCode = paramsObj.getString(GenConstants.TREE_CODE); + String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + genTable.setTreeCode(treeCode); + genTable.setTreeParentCode(treeParentCode); + genTable.setTreeName(treeName); + } + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableColumnService.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableColumnService.java new file mode 100644 index 0000000..c8c5c6f --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableColumnService.java @@ -0,0 +1,44 @@ +package com.ruoyi.project.tool.gen.service; + +import java.util.List; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; + +/** + * 涓氬姟瀛楁 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface IGenTableColumnService +{ + /** + * 鏌ヨ涓氬姟瀛楁鍒楄〃 + * + * @param genTableColumn 涓氬姟瀛楁缂栧彿 + * @return 涓氬姟瀛楁闆嗗悎 + */ + public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId); + + /** + * 鏂板涓氬姟瀛楁 + * + * @param genTableColumn 涓氬姟瀛楁淇℃伅 + * @return 缁撴灉 + */ + public int insertGenTableColumn(GenTableColumn genTableColumn); + + /** + * 淇敼涓氬姟瀛楁 + * + * @param genTableColumn 涓氬姟瀛楁淇℃伅 + * @return 缁撴灉 + */ + public int updateGenTableColumn(GenTableColumn genTableColumn); + + /** + * 鍒犻櫎涓氬姟瀛楁淇℃伅 + * + * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int deleteGenTableColumnByIds(String ids); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableService.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableService.java new file mode 100644 index 0000000..2bf015c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/service/IGenTableService.java @@ -0,0 +1,99 @@ +package com.ruoyi.project.tool.gen.service; + +import java.util.List; +import java.util.Map; +import com.ruoyi.project.tool.gen.domain.GenTable; + +/** + * 涓氬姟 鏈嶅姟灞� + * + * @author ruoyi + */ +public interface IGenTableService +{ + /** + * 鏌ヨ涓氬姟鍒楄〃 + * + * @param genTable 涓氬姟淇℃伅 + * @return 涓氬姟闆嗗悎 + */ + public List<GenTable> selectGenTableList(GenTable genTable); + + /** + * 鏌ヨ鎹簱鍒楄〃 + * + * @param genTable 涓氬姟淇℃伅 + * @return 鏁版嵁搴撹〃闆嗗悎 + */ + public List<GenTable> selectDbTableList(GenTable genTable); + + /** + * 鏌ヨ鎹簱鍒楄〃 + * + * @param tableNames 琛ㄥ悕绉扮粍 + * @return 鏁版嵁搴撹〃闆嗗悎 + */ + public List<GenTable> selectDbTableListByNames(String[] tableNames); + + /** + * 鏌ヨ涓氬姟淇℃伅 + * + * @param id 涓氬姟ID + * @return 涓氬姟淇℃伅 + */ + public GenTable selectGenTableById(Long id); + + /** + * 淇敼涓氬姟 + * + * @param genTable 涓氬姟淇℃伅 + * @return 缁撴灉 + */ + public void updateGenTable(GenTable genTable); + + /** + * 鍒犻櫎涓氬姟淇℃伅 + * + * @param tableIds 闇�瑕佸垹闄ょ殑琛ㄦ暟鎹甀D + * @return 缁撴灉 + */ + public void deleteGenTableByIds(Long[] tableIds); + + /** + * 瀵煎叆琛ㄧ粨鏋� + * + * @param tableList 瀵煎叆琛ㄥ垪琛� + */ + public void importGenTable(List<GenTable> tableList); + + /** + * 棰勮浠g爜 + * + * @param tableId 琛ㄧ紪鍙� + * @return 棰勮鏁版嵁鍒楄〃 + */ + public Map<String, String> previewCode(Long tableId); + + /** + * 鐢熸垚浠g爜 + * + * @param tableName 琛ㄥ悕绉� + * @return 鏁版嵁 + */ + public byte[] generatorCode(String tableName); + + /** + * 鎵归噺鐢熸垚浠g爜 + * + * @param tableNames 琛ㄦ暟缁� + * @return 鏁版嵁 + */ + public byte[] generatorCode(String[] tableNames); + + /** + * 淇敼淇濆瓨鍙傛暟鏍¢獙 + * + * @param genTable 涓氬姟淇℃伅 + */ + public void validateEdit(GenTable genTable); +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/GenUtils.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/GenUtils.java new file mode 100644 index 0000000..9098f7c --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/GenUtils.java @@ -0,0 +1,238 @@ +package com.ruoyi.project.tool.gen.util; + +import java.util.Arrays; +import org.apache.commons.lang3.RegExUtils; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.config.GenConfig; +import com.ruoyi.project.tool.gen.domain.GenTable; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; + +/** + * 浠g爜鐢熸垚鍣� 宸ュ叿绫� + * + * @author ruoyi + */ +public class GenUtils +{ + /** + * 鍒濆鍖栬〃淇℃伅 + */ + public static void initTable(GenTable genTable, String operName) + { + genTable.setClassName(convertClassName(genTable.getTableName())); + genTable.setPackageName(GenConfig.getPackageName()); + genTable.setModuleName(getModuleName(GenConfig.getPackageName())); + genTable.setBusinessName(getBusinessName(genTable.getTableName())); + genTable.setFunctionName(replaceText(genTable.getTableComment())); + genTable.setFunctionAuthor(GenConfig.getAuthor()); + genTable.setCreateBy(operName); + } + + /** + * 鍒濆鍖栧垪灞炴�у瓧娈� + */ + public static void initColumnField(GenTableColumn column, GenTable table) + { + String dataType = getDbType(column.getColumnType()); + String columnName = column.getColumnName(); + column.setTableId(table.getTableId()); + column.setCreateBy(table.getCreateBy()); + // 璁剧疆java瀛楁鍚� + column.setJavaField(StringUtils.toCamelCase(columnName)); + + if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType)) + { + column.setJavaType(GenConstants.TYPE_STRING); + // 瀛楃涓查暱搴﹁秴杩�500璁剧疆涓烘枃鏈煙 + Integer columnLength = getColumnLength(column.getColumnType()); + String htmlType = columnLength >= 500 ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; + column.setHtmlType(htmlType); + } + else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) + { + column.setJavaType(GenConstants.TYPE_DATE); + column.setHtmlType(GenConstants.HTML_DATETIME); + } + else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) + { + column.setHtmlType(GenConstants.HTML_INPUT); + + // 濡傛灉鏄诞鐐瑰瀷 + String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ","); + if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) + { + column.setJavaType(GenConstants.TYPE_DOUBLE); + } + // 濡傛灉鏄暣褰� + else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) + { + column.setJavaType(GenConstants.TYPE_INTEGER); + } + // 闀挎暣褰� + else + { + column.setJavaType(GenConstants.TYPE_LONG); + } + } + + // 鎻掑叆瀛楁锛堥粯璁ゆ墍鏈夊瓧娈甸兘闇�瑕佹彃鍏ワ級 + column.setIsInsert(GenConstants.REQUIRE); + + // 缂栬緫瀛楁 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk()) + { + column.setIsEdit(GenConstants.REQUIRE); + } + // 鍒楄〃瀛楁 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk()) + { + column.setIsList(GenConstants.REQUIRE); + } + // 鏌ヨ瀛楁 + if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) + { + column.setIsQuery(GenConstants.REQUIRE); + } + + // 鏌ヨ瀛楁绫诲瀷 + if (StringUtils.endsWithIgnoreCase(columnName, "name")) + { + column.setQueryType(GenConstants.QUERY_LIKE); + } + // 鐘舵�佸瓧娈佃缃崟閫夋 + if (StringUtils.endsWithIgnoreCase(columnName, "status")) + { + column.setHtmlType(GenConstants.HTML_RADIO); + } + // 绫诲瀷&鎬у埆瀛楁璁剧疆涓嬫媺妗� + else if (StringUtils.endsWithIgnoreCase(columnName, "type") + || StringUtils.endsWithIgnoreCase(columnName, "sex")) + { + column.setHtmlType(GenConstants.HTML_SELECT); + } + } + + /** + * 鏍¢獙鏁扮粍鏄惁鍖呭惈鎸囧畾鍊� + * + * @param arr 鏁扮粍 + * @param targetValue 鍊� + * @return 鏄惁鍖呭惈 + */ + public static boolean arraysContains(String[] arr, String targetValue) + { + return Arrays.asList(arr).contains(targetValue); + } + + /** + * 鑾峰彇妯″潡鍚� + * + * @param packageName 鍖呭悕 + * @return 妯″潡鍚� + */ + public static String getModuleName(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + int nameLength = packageName.length(); + String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength); + return moduleName; + } + + /** + * 鑾峰彇涓氬姟鍚� + * + * @param tableName 琛ㄥ悕 + * @return 涓氬姟鍚� + */ + public static String getBusinessName(String tableName) + { + int lastIndex = tableName.lastIndexOf("_"); + int nameLength = tableName.length(); + String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength); + return businessName; + } + + /** + * 琛ㄥ悕杞崲鎴怞ava绫诲悕 + * + * @param tableName 琛ㄥ悕绉� + * @return 绫诲悕 + */ + public static String convertClassName(String tableName) + { + boolean autoRemovePre = GenConfig.getAutoRemovePre(); + String tablePrefix = GenConfig.getTablePrefix(); + if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) + { + String[] searchList = StringUtils.split(tablePrefix, ","); + String[] replacementList = emptyList(searchList.length); + tableName = StringUtils.replaceEach(tableName, searchList, replacementList); + } + return StringUtils.convertToCamelCase(tableName); + } + + /** + * 鍏抽敭瀛楁浛鎹� + * + * @param name 闇�瑕佽鏇挎崲鐨勫悕瀛� + * @return 鏇挎崲鍚庣殑鍚嶅瓧 + */ + public static String replaceText(String text) + { + return RegExUtils.replaceAll(text, "(?:琛▅鑻ヤ緷)", ""); + } + + /** + * 鑾峰彇鏁版嵁搴撶被鍨嬪瓧娈� + * + * @param columnType 鍒楃被鍨� + * @return 鎴彇鍚庣殑鍒楃被鍨� + */ + public static String getDbType(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + return StringUtils.substringBefore(columnType, "("); + } + else + { + return columnType; + } + } + + /** + * 鑾峰彇瀛楁闀垮害 + * + * @param columnType 鍒楃被鍨� + * @return 鎴彇鍚庣殑鍒楃被鍨� + */ + public static Integer getColumnLength(String columnType) + { + if (StringUtils.indexOf(columnType, "(") > 0) + { + String length = StringUtils.substringBetween(columnType, "(", ")"); + return Integer.valueOf(length); + } + else + { + return 0; + } + } + + /** + * 鑾峰彇绌烘暟缁勫垪琛� + * + * @param length 闀垮害 + * @return 鏁扮粍淇℃伅 + */ + public static String[] emptyList(int length) + { + String[] values = new String[length]; + for (int i = 0; i < length; i++) + { + values[i] = StringUtils.EMPTY; + } + return values; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityInitializer.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityInitializer.java new file mode 100644 index 0000000..28d7c30 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityInitializer.java @@ -0,0 +1,35 @@ +package com.ruoyi.project.tool.gen.util; + +import java.util.Properties; +import org.apache.velocity.app.Velocity; +import com.ruoyi.common.constant.Constants; + +/** + * VelocityEngine宸ュ巶 + * + * @author RuoYi + */ +public class VelocityInitializer +{ + /** + * 鍒濆鍖杤m鏂规硶 + */ + public static void initVelocity() + { + Properties p = new Properties(); + try + { + // 鍔犺浇classpath鐩綍涓嬬殑vm鏂囦欢 + p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + // 瀹氫箟瀛楃闆� + p.setProperty(Velocity.ENCODING_DEFAULT, Constants.UTF8); + p.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8); + // 鍒濆鍖朧elocity寮曟搸锛屾寚瀹氶厤缃甈roperties + Velocity.init(p); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } +} diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityUtils.java b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityUtils.java new file mode 100644 index 0000000..27a935e --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/gen/util/VelocityUtils.java @@ -0,0 +1,281 @@ +package com.ruoyi.project.tool.gen.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import org.apache.velocity.VelocityContext; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.constant.GenConstants; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.project.tool.gen.domain.GenTable; +import com.ruoyi.project.tool.gen.domain.GenTableColumn; + +public class VelocityUtils +{ + /** 椤圭洰绌洪棿璺緞 */ + private static final String PROJECT_PATH = "main/java"; + + /** mybatis绌洪棿璺緞 */ + private static final String MYBATIS_PATH = "main/resources/mybatis"; + + /** + * 璁剧疆妯℃澘鍙橀噺淇℃伅 + * + * @return 妯℃澘鍒楄〃 + */ + public static VelocityContext prepareContext(GenTable genTable) + { + String moduleName = genTable.getModuleName(); + String businessName = genTable.getBusinessName(); + String packageName = genTable.getPackageName(); + String tplCategory = genTable.getTplCategory(); + String functionName = genTable.getFunctionName(); + + VelocityContext velocityContext = new VelocityContext(); + velocityContext.put("tplCategory", genTable.getTplCategory()); + velocityContext.put("tableName", genTable.getTableName()); + velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "銆愯濉啓鍔熻兘鍚嶇О銆�"); + velocityContext.put("ClassName", genTable.getClassName()); + velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); + velocityContext.put("moduleName", genTable.getModuleName()); + velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); + velocityContext.put("businessName", genTable.getBusinessName()); + velocityContext.put("basePackage", getPackagePrefix(packageName)); + velocityContext.put("packageName", packageName); + velocityContext.put("author", genTable.getFunctionAuthor()); + velocityContext.put("datetime", DateUtils.getDate()); + velocityContext.put("pkColumn", genTable.getPkColumn()); + velocityContext.put("importList", getImportList(genTable.getColumns())); + velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); + velocityContext.put("columns", genTable.getColumns()); + velocityContext.put("table", genTable); + if (GenConstants.TPL_TREE.equals(tplCategory)) + { + setTreeVelocityContext(velocityContext, genTable); + } + return velocityContext; + } + + public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSONObject.parseObject(options); + String treeCode = getTreecode(paramsObj); + String treeParentCode = getTreeParentCode(paramsObj); + String treeName = getTreeName(paramsObj); + + context.put("treeCode", treeCode); + context.put("treeParentCode", treeParentCode); + context.put("treeName", treeName); + context.put("expandColumn", getExpandColumn(genTable)); + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME)); + } + } + + /** + * 鑾峰彇妯℃澘淇℃伅 + * + * @return 妯℃澘鍒楄〃 + */ + public static List<String> getTemplateList(String tplCategory) + { + List<String> templates = new ArrayList<String>(); + templates.add("vm/java/domain.java.vm"); + templates.add("vm/java/mapper.java.vm"); + templates.add("vm/java/service.java.vm"); + templates.add("vm/java/serviceImpl.java.vm"); + templates.add("vm/java/controller.java.vm"); + templates.add("vm/xml/mapper.xml.vm"); + templates.add("vm/sql/sql.vm"); + templates.add("vm/js/api.js.vm"); + templates.add("vm/vue/index.vue.vm"); + return templates; + } + + /** + * 鑾峰彇鏂囦欢鍚� + */ + public static String getFileName(String template, GenTable genTable) + { + // 鏂囦欢鍚嶇О + String fileName = ""; + // 鍖呰矾寰� + String packageName = genTable.getPackageName(); + // 妯″潡鍚� + String moduleName = genTable.getModuleName(); + // 澶у啓绫诲悕 + String className = genTable.getClassName(); + // 涓氬姟鍚嶇О + String businessName = genTable.getBusinessName(); + + String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); + String mybatisPath = MYBATIS_PATH + "/" + moduleName; + String vuePath = "vue"; + + if (template.contains("domain.java.vm")) + { + fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); + } + else if (template.contains("mapper.java.vm")) + { + fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); + } + else if (template.contains("service.java.vm")) + { + fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); + } + else if (template.contains("serviceImpl.java.vm")) + { + fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); + } + else if (template.contains("controller.java.vm")) + { + fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); + } + else if (template.contains("mapper.xml.vm")) + { + fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); + } + else if (template.contains("sql.vm")) + { + fileName = businessName + "Menu.sql"; + } + else if (template.contains("js.vm")) + { + fileName = StringUtils.format("{}/api/{}/{}.js", vuePath, moduleName, businessName); + } + else if (template.contains("vue.vm")) + { + fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); + } + return fileName; + } + + /** + * 鑾峰彇鍖呭墠缂� + * + * @param packageName 鍖呭悕绉� + * @return 鍖呭墠缂�鍚嶇О + */ + public static String getPackagePrefix(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + String basePackage = StringUtils.substring(packageName, 0, lastIndex); + return basePackage; + } + + /** + * 鏍规嵁鍒楃被鍨嬭幏鍙栧鍏ュ寘 + * + * @param column 鍒楅泦鍚� + * @return 杩斿洖闇�瑕佸鍏ョ殑鍖呭垪琛� + */ + public static HashSet<String> getImportList(List<GenTableColumn> columns) + { + HashSet<String> importList = new HashSet<String>(); + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) + { + importList.add("java.util.Date"); + } + else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) + { + importList.add("java.math.BigDecimal"); + } + } + return importList; + } + + /** + * 鑾峰彇鏉冮檺鍓嶇紑 + * + * @param moduleName 妯″潡鍚嶇О + * @param businessName 涓氬姟鍚嶇О + * @return 杩斿洖鏉冮檺鍓嶇紑 + */ + public static String getPermissionPrefix(String moduleName, String businessName) + { + return StringUtils.format("{}:{}", moduleName, businessName); + + } + + /** + * 鑾峰彇鏍戠紪鐮� + * + * @param options 鐢熸垚鍏朵粬閫夐」 + * @return 鏍戠紪鐮� + */ + public static String getTreecode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE)); + } + return ""; + } + + /** + * 鑾峰彇鏍戠埗缂栫爜 + * + * @param options 鐢熸垚鍏朵粬閫夐」 + * @return 鏍戠埗缂栫爜 + */ + public static String getTreeParentCode(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE)); + } + return ""; + } + + /** + * 鑾峰彇鏍戝悕绉� + * + * @param options 鐢熸垚鍏朵粬閫夐」 + * @return 鏍戝悕绉� + */ + public static String getTreeName(JSONObject paramsObj) + { + if (paramsObj.containsKey(GenConstants.TREE_NAME)) + { + return StringUtils.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME)); + } + return ""; + } + + /** + * 鑾峰彇闇�瑕佸湪鍝竴鍒椾笂闈㈡樉绀哄睍寮�鎸夐挳 + * + * @param genTable 涓氬姟琛ㄥ璞� + * @return 灞曞紑鎸夐挳鍒楀簭鍙� + */ + public static int getExpandColumn(GenTable genTable) + { + String options = genTable.getOptions(); + JSONObject paramsObj = JSONObject.parseObject(options); + String treeName = paramsObj.getString(GenConstants.TREE_NAME); + int num = 0; + for (GenTableColumn column : genTable.getColumns()) + { + if (column.isList()) + { + num++; + String columnName = column.getColumnName(); + if (columnName.equals(treeName)) + { + break; + } + } + } + return num; + } +} \ No newline at end of file diff --git a/ruoyi/src/main/java/com/ruoyi/project/tool/swagger/TestController.java b/ruoyi/src/main/java/com/ruoyi/project/tool/swagger/TestController.java new file mode 100644 index 0000000..841b531 --- /dev/null +++ b/ruoyi/src/main/java/com/ruoyi/project/tool/swagger/TestController.java @@ -0,0 +1,175 @@ +package com.ruoyi.project.tool.swagger; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 鐢ㄦ埛娴嬭瘯鏂规硶 + * + * @author ruoyi + */ +@Api("鐢ㄦ埛淇℃伅绠$悊") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("鑾峰彇鐢ㄦ埛鍒楄〃") + @GetMapping("/list") + public AjaxResult userList() + { + List<UserEntity> userList = new ArrayList<UserEntity>(users.values()); + return AjaxResult.success(userList); + } + + @ApiOperation("鑾峰彇鐢ㄦ埛璇︾粏") + @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path") + @GetMapping("/{userId}") + public AjaxResult getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return AjaxResult.success(users.get(userId)); + } + else + { + return AjaxResult.error("鐢ㄦ埛涓嶅瓨鍦�"); + } + } + + @ApiOperation("鏂板鐢ㄦ埛") + @ApiImplicitParam(name = "userEntity", value = "鏂板鐢ㄦ埛淇℃伅", dataType = "UserEntity") + @PostMapping("/save") + public AjaxResult save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return AjaxResult.error("鐢ㄦ埛ID涓嶈兘涓虹┖"); + } + return AjaxResult.success(users.put(user.getUserId(), user)); + } + + @ApiOperation("鏇存柊鐢ㄦ埛") + @ApiImplicitParam(name = "userEntity", value = "鏂板鐢ㄦ埛淇℃伅", dataType = "UserEntity") + @PutMapping("/update") + public AjaxResult update(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return AjaxResult.error("鐢ㄦ埛ID涓嶈兘涓虹┖"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return AjaxResult.error("鐢ㄦ埛涓嶅瓨鍦�"); + } + users.remove(user.getUserId()); + return AjaxResult.success(users.put(user.getUserId(), user)); + } + + @ApiOperation("鍒犻櫎鐢ㄦ埛淇℃伅") + @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path") + @DeleteMapping("/{userId}") + public AjaxResult delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return AjaxResult.success(); + } + else + { + return AjaxResult.error("鐢ㄦ埛涓嶅瓨鍦�"); + } + } +} + +@ApiModel("鐢ㄦ埛瀹炰綋") +class UserEntity +{ + @ApiModelProperty("鐢ㄦ埛ID") + private Integer userId; + + @ApiModelProperty("鐢ㄦ埛鍚嶇О") + private String username; + + @ApiModelProperty("鐢ㄦ埛瀵嗙爜") + private String password; + + @ApiModelProperty("鐢ㄦ埛鎵嬫満") + private String mobile; + + public UserEntity() + { + + } + + public UserEntity(Integer userId, String username, String password, String mobile) + { + this.userId = userId; + this.username = username; + this.password = password; + this.mobile = mobile; + } + + public Integer getUserId() + { + return userId; + } + + public void setUserId(Integer userId) + { + this.userId = userId; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getMobile() + { + return mobile; + } + + public void setMobile(String mobile) + { + this.mobile = mobile; + } +} diff --git a/ruoyi/src/main/resources/application-druid.yml b/ruoyi/src/main/resources/application-druid.yml new file mode 100644 index 0000000..13e1a5c --- /dev/null +++ b/ruoyi/src/main/resources/application-druid.yml @@ -0,0 +1,57 @@ +# 鏁版嵁婧愰厤缃� +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 涓诲簱鏁版嵁婧� + master: + url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: password + # 浠庡簱鏁版嵁婧� + slave: + # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴 + enabled: false + url: + username: + password: + # 鍒濆杩炴帴鏁� + initialSize: 5 + # 鏈�灏忚繛鎺ユ睜鏁伴噺 + minIdle: 10 + # 鏈�澶ц繛鎺ユ睜鏁伴噺 + maxActive: 20 + # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂� + maxWait: 60000 + # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣 + timeBetweenEvictionRunsMillis: 60000 + # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 + minEvictableIdleTimeMillis: 300000 + # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 + maxEvictableIdleTimeMillis: 900000 + # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁� + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂� + allow: + url-pattern: /druid/* + # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮� + login-username: + login-password: + filter: + stat: + enabled: true + # 鎱QL璁板綍 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true \ No newline at end of file diff --git a/ruoyi/src/main/resources/application.yml b/ruoyi/src/main/resources/application.yml new file mode 100644 index 0000000..4ced552 --- /dev/null +++ b/ruoyi/src/main/resources/application.yml @@ -0,0 +1,122 @@ +# 椤圭洰鐩稿叧閰嶇疆 +ruoyi: + # 鍚嶇О + name: RuoYi + # 鐗堟湰 + version: 2.0.0 + # 鐗堟潈骞翠唤 + copyrightYear: 2019 + # 瀹炰緥婕旂ず寮�鍏� + demoEnabled: true + # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛� + profile: D:/ruoyi/uploadPath + # 鑾峰彇ip鍦板潃寮�鍏� + addressEnabled: true + +# 寮�鍙戠幆澧冮厤缃� +server: + # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080 + port: 8080 + servlet: + # 搴旂敤鐨勮闂矾寰� + context-path: / + tomcat: + # tomcat鐨刄RI缂栫爜 + uri-encoding: UTF-8 + # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200 + max-threads: 800 + # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�25 + min-spare-threads: 30 + + +# 鏃ュ織閰嶇疆 +logging: + level: + com.ruoyi: debug + org.springframework: warn + +# Spring閰嶇疆 +spring: + # 璧勬簮淇℃伅 + messages: + # 鍥介檯鍖栬祫婧愭枃浠惰矾寰� + basename: i18n/messages + profiles: + active: druid + # 鏂囦欢涓婁紶 + servlet: + multipart: + # 鍗曚釜鏂囦欢澶у皬 + max-file-size: 10MB + # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬 + max-request-size: 20MB + # 鏈嶅姟妯″潡 + devtools: + restart: + # 鐑儴缃插紑鍏� + enabled: true + # redis 閰嶇疆 + redis: + # 鍦板潃 + host: localhost + # 绔彛锛岄粯璁や负6379 + port: 6379 + # 瀵嗙爜 + password: + # 杩炴帴瓒呮椂鏃堕棿 + timeout: 10s + lettuce: + pool: + # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺� + min-idle: 0 + # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺� + max-idle: 8 + # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁� + max-active: 8 + # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級 + max-wait: -1ms + +# token閰嶇疆 +token: + # 浠ょ墝鑷畾涔夋爣璇� + header: Authorization + # 浠ょ墝绉橀挜 + secret: abcdefghijklmnopqrstuvwxyz + # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛� + expireTime: 30 + +# MyBatis閰嶇疆 +mybatis: + # 鎼滅储鎸囧畾鍖呭埆鍚� + typeAliasesPackage: com.ruoyi.project.**.domain + # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢 + mapperLocations: classpath*:mybatis/**/*Mapper.xml + # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠� + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper鍒嗛〉鎻掍欢 +pagehelper: + helperDialect: mysql + reasonable: true + supportMethodsArguments: true + params: count=countSql + +# 闃叉XSS鏀诲嚮 +xss: + # 杩囨护寮�鍏� + enabled: true + # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛� + excludes: /system/notice/* + # 鍖归厤閾炬帴 + urlPatterns: /system/*,/monitor/*,/tool/* + +# 浠g爜鐢熸垚 +gen: + # 浣滆�� + author: ruoyi + # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool + packageName: com.ruoyi.project.system + # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true + autoRemovePre: false + # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛� + tablePrefix: sys_ \ No newline at end of file diff --git a/ruoyi/src/main/resources/banner.txt b/ruoyi/src/main/resources/banner.txt new file mode 100644 index 0000000..0931cb8 --- /dev/null +++ b/ruoyi/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${ruoyi.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 浣涚淇濅綉 姘镐笉瀹曟満 姘告棤BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/ruoyi/src/main/resources/i18n/messages.properties b/ruoyi/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..d63aa1f --- /dev/null +++ b/ruoyi/src/main/resources/i18n/messages.properties @@ -0,0 +1,36 @@ +#閿欒娑堟伅 +not.null=* 蹇呴』濉啓 +user.jcaptcha.error=楠岃瘉鐮侀敊璇� +user.jcaptcha.expire=楠岃瘉鐮佸凡澶辨晥 +user.not.exists=鐢ㄦ埛涓嶅瓨鍦�/瀵嗙爜閿欒 +user.password.not.match=鐢ㄦ埛涓嶅瓨鍦�/瀵嗙爜閿欒 +user.password.retry.limit.count=瀵嗙爜杈撳叆閿欒{0}娆� +user.password.retry.limit.exceed=瀵嗙爜杈撳叆閿欒{0}娆★紝甯愭埛閿佸畾10鍒嗛挓 +user.password.delete=瀵逛笉璧凤紝鎮ㄧ殑璐﹀彿宸茶鍒犻櫎 +user.blocked=鐢ㄦ埛宸插皝绂侊紝璇疯仈绯荤鐞嗗憳 +role.blocked=瑙掕壊宸插皝绂侊紝璇疯仈绯荤鐞嗗憳 +user.logout.success=閫�鍑烘垚鍔� + +length.not.valid=闀垮害蹇呴』鍦▄min}鍒皗max}涓瓧绗︿箣闂� + +user.username.not.valid=* 2鍒�20涓眽瀛椼�佸瓧姣嶃�佹暟瀛楁垨涓嬪垝绾跨粍鎴愶紝涓斿繀椤讳互闈炴暟瀛楀紑澶� +user.password.not.valid=* 5-50涓瓧绗� + +user.email.not.valid=閭鏍煎紡閿欒 +user.mobile.phone.number.not.valid=鎵嬫満鍙锋牸寮忛敊璇� +user.login.success=鐧诲綍鎴愬姛 +user.notfound=璇烽噸鏂扮櫥褰� +user.forcelogout=绠$悊鍛樺己鍒堕��鍑猴紝璇烽噸鏂扮櫥褰� +user.unknown.error=鏈煡閿欒锛岃閲嶆柊鐧诲綍 + +##鏂囦欢涓婁紶娑堟伅 +upload.exceed.maxSize=涓婁紶鐨勬枃浠跺ぇ灏忚秴鍑洪檺鍒剁殑鏂囦欢澶у皬锛�<br/>鍏佽鐨勬枃浠舵渶澶уぇ灏忔槸锛歿0}MB锛� +upload.filename.exceed.length=涓婁紶鐨勬枃浠跺悕鏈�闀縶0}涓瓧绗� + +##鏉冮檺 +no.permission=鎮ㄦ病鏈夋暟鎹殑鏉冮檺锛岃鑱旂郴绠$悊鍛樻坊鍔犳潈闄� [{0}] +no.create.permission=鎮ㄦ病鏈夊垱寤烘暟鎹殑鏉冮檺锛岃鑱旂郴绠$悊鍛樻坊鍔犳潈闄� [{0}] +no.update.permission=鎮ㄦ病鏈変慨鏀规暟鎹殑鏉冮檺锛岃鑱旂郴绠$悊鍛樻坊鍔犳潈闄� [{0}] +no.delete.permission=鎮ㄦ病鏈夊垹闄ゆ暟鎹殑鏉冮檺锛岃鑱旂郴绠$悊鍛樻坊鍔犳潈闄� [{0}] +no.export.permission=鎮ㄦ病鏈夊鍑烘暟鎹殑鏉冮檺锛岃鑱旂郴绠$悊鍛樻坊鍔犳潈闄� [{0}] +no.view.permission=鎮ㄦ病鏈夋煡鐪嬫暟鎹殑鏉冮檺锛岃鑱旂郴绠$悊鍛樻坊鍔犳潈闄� [{0}] diff --git a/ruoyi/src/main/resources/logback.xml b/ruoyi/src/main/resources/logback.xml new file mode 100644 index 0000000..a360583 --- /dev/null +++ b/ruoyi/src/main/resources/logback.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <!-- 鏃ュ織瀛樻斁璺緞 --> + <property name="log.path" value="/home/ruoyi/logs" /> + <!-- 鏃ュ織杈撳嚭鏍煎紡 --> + <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> + + <!-- 鎺у埗鍙拌緭鍑� --> + <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + </appender> + + <!-- 绯荤粺鏃ュ織杈撳嚭 --> + <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/sys-info.log</file> + <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� --> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> + <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> + <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <!-- 杩囨护鐨勭骇鍒� --> + <level>INFO</level> + <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� --> + <onMatch>ACCEPT</onMatch> + <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� --> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/sys-error.log</file> + <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� --> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� --> + <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> + <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <!-- 杩囨护鐨勭骇鍒� --> + <level>ERROR</level> + <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� --> + <onMatch>ACCEPT</onMatch> + <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� --> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <!-- 鐢ㄦ埛璁块棶鏃ュ織杈撳嚭 --> + <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${log.path}/sys-user.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <!-- 鎸夊ぉ鍥炴粴 daily --> + <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern> + <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� --> + <maxHistory>60</maxHistory> + </rollingPolicy> + <encoder> + <pattern>${log.pattern}</pattern> + </encoder> + </appender> + + <!-- 绯荤粺妯″潡鏃ュ織绾у埆鎺у埗 --> + <logger name="com.ruoyi" level="info" /> + <!-- Spring鏃ュ織绾у埆鎺у埗 --> + <logger name="org.springframework" level="warn" /> + + <root level="info"> + <appender-ref ref="console" /> + </root> + + <!--绯荤粺鎿嶄綔鏃ュ織--> + <root level="info"> + <appender-ref ref="file_info" /> + <appender-ref ref="file_error" /> + </root> + + <!--绯荤粺鐢ㄦ埛鎿嶄綔鏃ュ織--> + <logger name="sys-user" level="info"> + <appender-ref ref="sys-user"/> + </logger> +</configuration> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml b/ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml new file mode 100644 index 0000000..cf8e19a --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/monitor/SysLogininforMapper.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.monitor.mapper.SysLogininforMapper"> + + <resultMap type="SysLogininfor" id="SysLogininforResult"> + <id property="infoId" column="info_id" /> + <result property="userName" column="user_name" /> + <result property="status" column="status" /> + <result property="ipaddr" column="ipaddr" /> + <result property="loginLocation" column="login_location" /> + <result property="browser" column="browser" /> + <result property="os" column="os" /> + <result property="msg" column="msg" /> + <result property="loginTime" column="login_time" /> + </resultMap> + + <insert id="insertLogininfor" parameterType="SysLogininfor"> + insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time) + values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate()) + </insert> + + <select id="selectLogininforList" parameterType="SysLogininfor" resultMap="SysLogininforResult"> + select info_id, user_name, ipaddr, login_location, browser, os, status, msg, login_time from sys_logininfor + <where> + <if test="ipaddr != null and ipaddr != ''"> + AND ipaddr like concat('%', #{ipaddr}, '%') + </if> + <if test="status != null and status != ''"> + AND status = #{status} + </if> + <if test="userName != null and userName != ''"> + AND user_name like concat('%', #{userName}, '%') + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + and date_format(login_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + and date_format(login_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + </where> + </select> + + <delete id="deleteLogininforByIds" parameterType="Long"> + delete from sys_logininfor where info_id in + <foreach collection="array" item="infoId" open="(" separator="," close=")"> + #{infoId} + </foreach> + </delete> + + <update id="cleanLogininfor"> + truncate table sys_logininfor + </update> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml b/ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml new file mode 100644 index 0000000..0cc840b --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/monitor/SysOperLogMapper.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.monitor.mapper.SysOperLogMapper"> + + <resultMap type="SysOperLog" id="SysOperLogResult"> + <id property="operId" column="oper_id" /> + <result property="title" column="title" /> + <result property="businessType" column="business_type" /> + <result property="method" column="method" /> + <result property="requestMethod" column="request_method" /> + <result property="operatorType" column="operator_type" /> + <result property="operName" column="oper_name" /> + <result property="deptName" column="dept_name" /> + <result property="operUrl" column="oper_url" /> + <result property="operIp" column="oper_ip" /> + <result property="operLocation" column="oper_location" /> + <result property="operParam" column="oper_param" /> + <result property="jsonResult" column="json_result" /> + <result property="status" column="status" /> + <result property="errorMsg" column="error_msg" /> + <result property="operTime" column="oper_time" /> + </resultMap> + + <sql id="selectOperLogVo"> + select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time + from sys_oper_log + </sql> + + <insert id="insertOperlog" parameterType="SysOperLog"> + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time) + values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, sysdate()) + </insert> + + <select id="selectOperLogList" parameterType="SysOperLog" resultMap="SysOperLogResult"> + <include refid="selectOperLogVo"/> + <where> + <if test="title != null and title != ''"> + AND title like concat('%', #{title}, '%') + </if> + <if test="businessType != null"> + AND business_type = #{businessType} + </if> + <if test="businessTypes != null and businessTypes.length > 0"> + AND business_type in + <foreach collection="businessTypes" item="businessType" open="(" separator="," close=")"> + #{businessType} + </foreach> + </if> + <if test="status != null"> + AND status = #{status} + </if> + <if test="operName != null and operName != ''"> + AND oper_name like concat('%', #{operName}, '%') + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + and date_format(oper_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + and date_format(oper_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + </where> + </select> + + <delete id="deleteOperLogByIds" parameterType="Long"> + delete from sys_oper_log where oper_id in + <foreach collection="array" item="operId" open="(" separator="," close=")"> + #{operId} + </foreach> + </delete> + + <select id="selectOperLogById" parameterType="Long" resultMap="SysOperLogResult"> + <include refid="selectOperLogVo"/> + where oper_id = #{operId} + </select> + + <update id="cleanOperLog"> + truncate table sys_oper_log + </update> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/mybatis-config.xml b/ruoyi/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..e8b52be --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE configuration +PUBLIC "-//mybatis.org//DTD Config 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-config.dtd"> +<configuration> + + <settings> + <setting name="cacheEnabled" value="true" /> <!-- 鍏ㄥ眬鏄犲皠鍣ㄥ惎鐢ㄧ紦瀛� --> + <setting name="useGeneratedKeys" value="true" /> <!-- 鍏佽 JDBC 鏀寔鑷姩鐢熸垚涓婚敭 --> + <setting name="defaultExecutorType" value="REUSE" /> <!-- 閰嶇疆榛樿鐨勬墽琛屽櫒 --> + <setting name="logImpl" value="SLF4J" /> <!-- 鎸囧畾 MyBatis 鎵�鐢ㄦ棩蹇楃殑鍏蜂綋瀹炵幇 --> + <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> 椹煎嘲寮忓懡鍚� --> + </settings> + +</configuration> diff --git a/ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml new file mode 100644 index 0000000..30ae39f --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysConfigMapper.xml @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysConfigMapper"> + + <resultMap type="SysConfig" id="SysConfigResult"> + <id property="configId" column="config_id" /> + <result property="configName" column="config_name" /> + <result property="configKey" column="config_key" /> + <result property="configValue" column="config_value" /> + <result property="configType" column="config_type" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + </resultMap> + + <sql id="selectConfigVo"> + select config_id, config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark + from sys_config + </sql> + + <!-- 鏌ヨ鏉′欢 --> + <sql id="sqlwhereSearch"> + <where> + <if test="configId !=null"> + and config_id = #{configId} + </if> + <if test="configKey !=null and configKey != ''"> + and config_key = #{configKey} + </if> + </where> + </sql> + + <select id="selectConfig" parameterType="SysConfig" resultMap="SysConfigResult"> + <include refid="selectConfigVo"/> + <include refid="sqlwhereSearch"/> + </select> + + <select id="selectConfigList" parameterType="SysConfig" resultMap="SysConfigResult"> + <include refid="selectConfigVo"/> + <where> + <if test="configName != null and configName != ''"> + AND config_name like concat('%', #{configName}, '%') + </if> + <if test="configType != null and configType != ''"> + AND config_type = #{configType} + </if> + <if test="configKey != null and configKey != ''"> + AND config_key like concat('%', #{configKey}, '%') + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + and date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + and date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + </where> + </select> + + <select id="checkConfigKeyUnique" parameterType="String" resultMap="SysConfigResult"> + <include refid="selectConfigVo"/> + where config_key = #{configKey} + </select> + + <insert id="insertConfig" parameterType="SysConfig"> + insert into sys_config ( + <if test="configName != null and configName != '' ">config_name,</if> + <if test="configKey != null and configKey != '' ">config_key,</if> + <if test="configValue != null and configValue != '' ">config_value,</if> + <if test="configType != null and configType != '' ">config_type,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + <if test="remark != null and remark != ''">remark,</if> + create_time + )values( + <if test="configName != null and configName != ''">#{configName},</if> + <if test="configKey != null and configKey != ''">#{configKey},</if> + <if test="configValue != null and configValue != ''">#{configValue},</if> + <if test="configType != null and configType != ''">#{configType},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + <if test="remark != null and remark != ''">#{remark},</if> + sysdate() + ) + </insert> + + <update id="updateConfig" parameterType="SysConfig"> + update sys_config + <set> + <if test="configName != null and configName != ''">config_name = #{configName},</if> + <if test="configKey != null and configKey != ''">config_key = #{configKey},</if> + <if test="configValue != null and configValue != ''">config_value = #{configValue},</if> + <if test="configType != null and configType != ''">config_type = #{configType},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + <if test="remark != null">remark = #{remark},</if> + update_time = sysdate() + </set> + where config_id = #{configId} + </update> + + <delete id="deleteConfigById" parameterType="Long"> + delete from sys_config where config_id = #{configId} + </delete> + + <delete id="deleteConfigByIds" parameterType="Long"> + delete from sys_config where config_id in + <foreach item="configId" collection="array" open="(" separator="," close=")"> + #{configId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysDeptMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysDeptMapper.xml new file mode 100644 index 0000000..39c9b23 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysDeptMapper.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysDeptMapper"> + + <resultMap type="SysDept" id="SysDeptResult"> + <id property="deptId" column="dept_id" /> + <result property="parentId" column="parent_id" /> + <result property="ancestors" column="ancestors" /> + <result property="deptName" column="dept_name" /> + <result property="orderNum" column="order_num" /> + <result property="leader" column="leader" /> + <result property="phone" column="phone" /> + <result property="email" column="email" /> + <result property="status" column="status" /> + <result property="delFlag" column="del_flag" /> + <result property="parentName" column="parent_name" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + </resultMap> + + <sql id="selectDeptVo"> + select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time + from sys_dept d + </sql> + + <select id="selectDeptList" parameterType="SysDept" resultMap="SysDeptResult"> + <include refid="selectDeptVo"/> + where d.del_flag = '0' + <if test="parentId != null and parentId != 0"> + AND parent_id = #{parentId} + </if> + <if test="deptName != null and deptName != ''"> + AND dept_name like concat('%', #{deptName}, '%') + </if> + <if test="status != null and status != ''"> + AND status = #{status} + </if> + <!-- 鏁版嵁鑼冨洿杩囨护 --> + ${dataScope} + order by d.parent_id, d.order_num + </select> + + <select id="selectDeptListByRoleId" parameterType="Long" resultType="Integer"> + select d.dept_id, d.parent_id + from sys_dept d + left join sys_role_dept rd on d.dept_id = rd.dept_id + where rd.role_id = #{roleId} + and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = #{roleId}) + order by d.parent_id, d.order_num + </select> + + <select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult"> + <include refid="selectDeptVo"/> + where dept_id = #{deptId} + </select> + + <select id="checkDeptExistUser" parameterType="Long" resultType="int"> + select count(1) from sys_user where dept_id = #{deptId} and del_flag = '0' + </select> + + <select id="hasChildByDeptId" parameterType="Long" resultType="int"> + select count(1) from sys_dept + where del_flag = '0' and parent_id = #{deptId} + </select> + + <select id="selectChildrenDeptById" parameterType="Long" resultMap="SysDeptResult"> + select * from sys_dept where find_in_set(#{deptId}, ancestors) + </select> + + <select id="checkDeptNameUnique" resultMap="SysDeptResult"> + <include refid="selectDeptVo"/> + where dept_name=#{deptName} and parent_id = #{parentId} + </select> + + <insert id="insertDept" parameterType="SysDept"> + insert into sys_dept( + <if test="deptId != null and deptId != 0">dept_id,</if> + <if test="parentId != null and parentId != 0">parent_id,</if> + <if test="deptName != null and deptName != ''">dept_name,</if> + <if test="ancestors != null and ancestors != ''">ancestors,</if> + <if test="orderNum != null and orderNum != ''">order_num,</if> + <if test="leader != null and leader != ''">leader,</if> + <if test="phone != null and phone != ''">phone,</if> + <if test="email != null and email != ''">email,</if> + <if test="status != null">status,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="deptId != null and deptId != 0">#{deptId},</if> + <if test="parentId != null and parentId != 0">#{parentId},</if> + <if test="deptName != null and deptName != ''">#{deptName},</if> + <if test="ancestors != null and ancestors != ''">#{ancestors},</if> + <if test="orderNum != null and orderNum != ''">#{orderNum},</if> + <if test="leader != null and leader != ''">#{leader},</if> + <if test="phone != null and phone != ''">#{phone},</if> + <if test="email != null and email != ''">#{email},</if> + <if test="status != null">#{status},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <update id="updateDept" parameterType="SysDept"> + update sys_dept + <set> + <if test="parentId != null and parentId != 0">parent_id = #{parentId},</if> + <if test="deptName != null and deptName != ''">dept_name = #{deptName},</if> + <if test="ancestors != null and ancestors != ''">ancestors = #{ancestors},</if> + <if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if> + <if test="leader != null">leader = #{leader},</if> + <if test="phone != null">phone = #{phone},</if> + <if test="email != null">email = #{email},</if> + <if test="status != null and status != ''">status = #{status},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where dept_id = #{deptId} + </update> + + <update id="updateDeptChildren" parameterType="java.util.List"> + update sys_dept set ancestors = + <foreach collection="depts" item="item" index="index" + separator=" " open="case dept_id" close="end"> + when #{item.deptId} then #{item.ancestors} + </foreach> + where dept_id in + <foreach collection="depts" item="item" index="index" + separator="," open="(" close=")"> + #{item.deptId} + </foreach> + </update> + + <update id="updateDeptStatus" parameterType="SysDept"> + update sys_dept + <set> + <if test="status != null and status != ''">status = #{status},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where dept_id in (${ancestors}) + </update> + + <delete id="deleteDeptById" parameterType="Long"> + update sys_dept set del_flag = '2' where dept_id = #{deptId} + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml new file mode 100644 index 0000000..0b341a7 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysDictDataMapper.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysDictDataMapper"> + + <resultMap type="SysDictData" id="SysDictDataResult"> + <id property="dictCode" column="dict_code" /> + <result property="dictSort" column="dict_sort" /> + <result property="dictLabel" column="dict_label" /> + <result property="dictValue" column="dict_value" /> + <result property="dictType" column="dict_type" /> + <result property="cssClass" column="css_class" /> + <result property="listClass" column="list_class" /> + <result property="isDefault" column="is_default" /> + <result property="status" column="status" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + </resultMap> + + <sql id="selectDictDataVo"> + select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark + from sys_dict_data + </sql> + + <select id="selectDictDataList" parameterType="SysDictData" resultMap="SysDictDataResult"> + <include refid="selectDictDataVo"/> + <where> + <if test="dictType != null and dictType != ''"> + AND dict_type = #{dictType} + </if> + <if test="dictLabel != null and dictLabel != ''"> + AND dict_label like concat('%', #{dictLabel}, '%') + </if> + <if test="status != null and status != ''"> + AND status = #{status} + </if> + </where> + </select> + + <select id="selectDictDataByType" parameterType="SysDictData" resultMap="SysDictDataResult"> + <include refid="selectDictDataVo"/> + where status = '0' and dict_type = #{dictType} order by dict_sort asc + </select> + + <select id="selectDictLabel" resultType="String"> + select dict_label from sys_dict_data + where dict_type = #{dictType} and dict_value = #{dictValue} + </select> + + <select id="selectDictDataById" parameterType="Long" resultMap="SysDictDataResult"> + <include refid="selectDictDataVo"/> + where dict_code = #{dictCode} + </select> + + <select id="countDictDataByType" resultType="Integer"> + select count(1) from sys_dict_data where dict_type=#{dictType} + </select> + + <delete id="deleteDictDataById" parameterType="Long"> + delete from sys_dict_data where dict_code = #{dictCode} + </delete> + + <delete id="deleteDictDataByIds" parameterType="Long"> + delete from sys_dict_data where dict_code in + <foreach collection="array" item="dictCode" open="(" separator="," close=")"> + #{dictCode} + </foreach> + </delete> + + <update id="updateDictData" parameterType="SysDictData"> + update sys_dict_data + <set> + <if test="dictSort != null and dictSort != ''">dict_sort = #{dictSort},</if> + <if test="dictLabel != null and dictLabel != ''">dict_label = #{dictLabel},</if> + <if test="dictValue != null and dictValue != ''">dict_value = #{dictValue},</if> + <if test="dictType != null and dictType != ''">dict_type = #{dictType},</if> + <if test="cssClass != null">css_class = #{cssClass},</if> + <if test="listClass != null">list_class = #{listClass},</if> + <if test="isDefault != null and isDefault != ''">is_default = #{isDefault},</if> + <if test="status != null">status = #{status},</if> + <if test="remark != null">remark = #{remark},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where dict_code = #{dictCode} + </update> + + <update id="updateDictDataType" parameterType="String"> + update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} + </update> + + <insert id="insertDictData" parameterType="SysDictData"> + insert into sys_dict_data( + <if test="dictSort != null and dictSort != ''">dict_sort,</if> + <if test="dictLabel != null and dictLabel != ''">dict_label,</if> + <if test="dictValue != null and dictValue != ''">dict_value,</if> + <if test="dictType != null and dictType != ''">dict_type,</if> + <if test="cssClass != null and cssClass != ''">css_class,</if> + <if test="listClass != null and listClass != ''">list_class,</if> + <if test="isDefault != null and isDefault != ''">is_default,</if> + <if test="status != null">status,</if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="dictSort != null and dictSort != ''">#{dictSort},</if> + <if test="dictLabel != null and dictLabel != ''">#{dictLabel},</if> + <if test="dictValue != null and dictValue != ''">#{dictValue},</if> + <if test="dictType != null and dictType != ''">#{dictType},</if> + <if test="cssClass != null and cssClass != ''">#{cssClass},</if> + <if test="listClass != null and listClass != ''">#{listClass},</if> + <if test="isDefault != null and isDefault != ''">#{isDefault},</if> + <if test="status != null">#{status},</if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml new file mode 100644 index 0000000..3b6c5c6 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysDictTypeMapper.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysDictTypeMapper"> + + <resultMap type="SysDictType" id="SysDictTypeResult"> + <id property="dictId" column="dict_id" /> + <result property="dictName" column="dict_name" /> + <result property="dictType" column="dict_type" /> + <result property="status" column="status" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + </resultMap> + + <sql id="selectDictTypeVo"> + select dict_id, dict_name, dict_type, status, create_by, create_time, remark + from sys_dict_type + </sql> + + <select id="selectDictTypeList" parameterType="SysDictType" resultMap="SysDictTypeResult"> + <include refid="selectDictTypeVo"/> + <where> + <if test="dictName != null and dictName != ''"> + AND dict_name like concat('%', #{dictName}, '%') + </if> + <if test="status != null and status != ''"> + AND status = #{status} + </if> + <if test="dictType != null and dictType != ''"> + AND dict_type like concat('%', #{dictType}, '%') + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + and date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + and date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + </where> + </select> + + <select id="selectDictTypeAll" resultMap="SysDictTypeResult"> + <include refid="selectDictTypeVo"/> + </select> + + <select id="selectDictTypeById" parameterType="Long" resultMap="SysDictTypeResult"> + <include refid="selectDictTypeVo"/> + where dict_id = #{dictId} + </select> + + <select id="selectDictTypeByType" parameterType="String" resultMap="SysDictTypeResult"> + <include refid="selectDictTypeVo"/> + where dict_type = #{dictType} + </select> + + <select id="checkDictTypeUnique" parameterType="String" resultMap="SysDictTypeResult"> + <include refid="selectDictTypeVo"/> + where dict_type = #{dictType} + </select> + + <delete id="deleteDictTypeById" parameterType="Long"> + delete from sys_dict_type where dict_id = #{dictId} + </delete> + + <delete id="deleteDictTypeByIds" parameterType="Long"> + delete from sys_dict_type where dict_id in + <foreach collection="array" item="dictId" open="(" separator="," close=")"> + #{dictId} + </foreach> + </delete> + + <update id="updateDictType" parameterType="SysDictType"> + update sys_dict_type + <set> + <if test="dictName != null and dictName != ''">dict_name = #{dictName},</if> + <if test="dictType != null and dictType != ''">dict_type = #{dictType},</if> + <if test="status != null">status = #{status},</if> + <if test="remark != null">remark = #{remark},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where dict_id = #{dictId} + </update> + + <insert id="insertDictType" parameterType="SysDictType"> + insert into sys_dict_type( + <if test="dictName != null and dictName != ''">dict_name,</if> + <if test="dictType != null and dictType != ''">dict_type,</if> + <if test="status != null">status,</if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="dictName != null and dictName != ''">#{dictName},</if> + <if test="dictType != null and dictType != ''">#{dictType},</if> + <if test="status != null">#{status},</if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysMenuMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysMenuMapper.xml new file mode 100644 index 0000000..28fb502 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysMenuMapper.xml @@ -0,0 +1,174 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysMenuMapper"> + + <resultMap type="SysMenu" id="SysMenuResult"> + <id property="menuId" column="menu_id" /> + <result property="menuName" column="menu_name" /> + <result property="parentName" column="parent_name" /> + <result property="parentId" column="parent_id" /> + <result property="orderNum" column="order_num" /> + <result property="path" column="path" /> + <result property="component" column="component" /> + <result property="isFrame" column="is_frame" /> + <result property="menuType" column="menu_type" /> + <result property="visible" column="visible" /> + <result property="perms" column="perms" /> + <result property="icon" column="icon" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateTime" column="update_time" /> + <result property="updateBy" column="update_by" /> + <result property="remark" column="remark" /> + </resultMap> + + <sql id="selectMenuVo"> + select menu_id, menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, ifnull(perms,'') as perms, icon, create_time + from sys_menu + </sql> + + <select id="selectMenuList" parameterType="SysMenu" resultMap="SysMenuResult"> + <include refid="selectMenuVo"/> + <where> + <if test="menuName != null and menuName != ''"> + AND menu_name like concat('%', #{menuName}, '%') + </if> + <if test="visible != null and visible != ''"> + AND visible = #{visible} + </if> + </where> + order by parent_id, order_num + </select> + + <select id="selectMenuTreeAll" resultMap="SysMenuResult"> + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.visible, ifnull(m.perms,'') as perms, m.is_frame, m.menu_type, m.icon, m.order_num, m.create_time + from sys_menu m where m.menu_type in ('M', 'C') and m.visible = 0 + order by m.parent_id, m.order_num + </select> + + <select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult"> + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.visible, ifnull(m.perms,'') as perms, m.is_frame, m.menu_type, m.icon, m.order_num, m.create_time + from sys_menu m + left join sys_role_menu rm on m.menu_id = rm.menu_id + left join sys_user_role ur on rm.role_id = ur.role_id + left join sys_role ro on ur.role_id = ro.role_id + where ur.user_id = #{params.userId} + <if test="menuName != null and menuName != ''"> + AND menu_name like concat('%', #{menuName}, '%') + </if> + <if test="visible != null and visible != ''"> + AND visible = #{visible} + </if> + order by m.parent_id, m.order_num + </select> + + <select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult"> + select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.visible, ifnull(m.perms,'') as perms, m.is_frame, m.menu_type, m.icon, m.order_num, m.create_time + from sys_menu m + left join sys_role_menu rm on m.menu_id = rm.menu_id + left join sys_user_role ur on rm.role_id = ur.role_id + left join sys_role ro on ur.role_id = ro.role_id + left join sys_user u on ur.user_id = u.user_id + where u.user_id = #{userId} and m.menu_type in ('M', 'C') and m.visible = 0 AND ro.status = 0 + order by m.parent_id, m.order_num + </select> + + <select id="selectMenuListByRoleId" parameterType="Long" resultType="Integer"> + select m.menu_id, m.parent_id + from sys_menu m + left join sys_role_menu rm on m.menu_id = rm.menu_id + where rm.role_id = #{roleId} + and m.menu_id not in (select m.parent_id from sys_menu m inner join sys_role_menu rm on m.menu_id = rm.menu_id and rm.role_id = #{roleId}) + order by m.parent_id, m.order_num + </select> + + <select id="selectMenuPerms" resultType="String"> + select distinct m.perms + from sys_menu m + left join sys_role_menu rm on m.menu_id = rm.menu_id + left join sys_user_role ur on rm.role_id = ur.role_id + </select> + + <select id="selectMenuPermsByUserId" parameterType="Long" resultType="String"> + select distinct m.perms + from sys_menu m + left join sys_role_menu rm on m.menu_id = rm.menu_id + left join sys_user_role ur on rm.role_id = ur.role_id + where ur.user_id = #{userId} + </select> + + <select id="selectMenuById" parameterType="Long" resultMap="SysMenuResult"> + <include refid="selectMenuVo"/> + where menu_id = #{menuId} + </select> + + <select id="hasChildByMenuId" resultType="Integer"> + select count(1) from sys_menu where parent_id = #{menuId} + </select> + + <select id="checkMenuNameUnique" parameterType="SysMenu" resultMap="SysMenuResult"> + <include refid="selectMenuVo"/> + where menu_name=#{menuName} and parent_id = #{parentId} + </select> + + <update id="updateMenu" parameterType="SysMenu"> + update sys_menu + <set> + <if test="menuName != null and menuName != ''">menu_name = #{menuName},</if> + <if test="parentId != null">parent_id = #{parentId},</if> + <if test="orderNum != null and orderNum != ''">order_num = #{orderNum},</if> + <if test="path != null and path != ''">path = #{path},</if> + <if test="component != null and component != ''">component = #{component},</if> + <if test="isFrame != null and isFrame != ''">is_frame = #{isFrame},</if> + <if test="menuType != null and menuType != ''">menu_type = #{menuType},</if> + <if test="visible != null">visible = #{visible},</if> + <if test="perms !=null">perms = #{perms},</if> + <if test="icon !=null and icon != ''">icon = #{icon},</if> + <if test="remark != null and remark != ''">remark = #{remark},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where menu_id = #{menuId} + </update> + + <insert id="insertMenu" parameterType="SysMenu"> + insert into sys_menu( + <if test="menuId != null and menuId != 0">menu_id,</if> + <if test="parentId != null and parentId != 0">parent_id,</if> + <if test="menuName != null and menuName != ''">menu_name,</if> + <if test="orderNum != null and orderNum != ''">order_num,</if> + <if test="path != null and path != ''">path,</if> + <if test="component != null and component != ''">component,</if> + <if test="isFrame != null and isFrame != ''">is_frame,</if> + <if test="menuType != null and menuType != ''">menu_type,</if> + <if test="visible != null">visible,</if> + <if test="perms !=null and perms != ''">perms,</if> + <if test="icon != null and icon != ''">icon,</if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="menuId != null and menuId != 0">#{menuId},</if> + <if test="parentId != null and parentId != 0">#{parentId},</if> + <if test="menuName != null and menuName != ''">#{menuName},</if> + <if test="orderNum != null and orderNum != ''">#{orderNum},</if> + <if test="path != null and path != ''">#{path},</if> + <if test="component != null and component != ''">#{component},</if> + <if test="isFrame != null and isFrame != ''">#{isFrame},</if> + <if test="menuType != null and menuType != ''">#{menuType},</if> + <if test="visible != null">#{visible},</if> + <if test="perms !=null and perms != ''">#{perms},</if> + <if test="icon != null and icon != ''">#{icon},</if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <delete id="deleteMenuById" parameterType="Long"> + delete from sys_menu where menu_id = #{menuId} + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml new file mode 100644 index 0000000..a0c9b20 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysNoticeMapper.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysNoticeMapper"> + + <resultMap type="SysNotice" id="SysNoticeResult"> + <result property="noticeId" column="notice_id" /> + <result property="noticeTitle" column="notice_title" /> + <result property="noticeType" column="notice_type" /> + <result property="noticeContent" column="notice_content" /> + <result property="status" column="status" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + <result property="remark" column="remark" /> + </resultMap> + + <sql id="selectNoticeVo"> + select notice_id, notice_title, notice_type, notice_content, status, create_by, create_time, update_by, update_time, remark + from sys_notice + </sql> + + <select id="selectNoticeById" parameterType="Long" resultMap="SysNoticeResult"> + <include refid="selectNoticeVo"/> + where notice_id = #{noticeId} + </select> + + <select id="selectNoticeList" parameterType="SysNotice" resultMap="SysNoticeResult"> + <include refid="selectNoticeVo"/> + <where> + <if test="noticeTitle != null and noticeTitle != ''"> + AND notice_title like concat('%', #{noticeTitle}, '%') + </if> + <if test="noticeType != null and noticeType != ''"> + AND notice_type = #{noticeType} + </if> + <if test="createBy != null and createBy != ''"> + AND create_by like concat('%', #{createBy}, '%') + </if> + </where> + </select> + + <insert id="insertNotice" parameterType="SysNotice"> + insert into sys_notice ( + <if test="noticeTitle != null and noticeTitle != '' ">notice_title, </if> + <if test="noticeType != null and noticeType != '' ">notice_type, </if> + <if test="noticeContent != null and noticeContent != '' ">notice_content, </if> + <if test="status != null and status != '' ">status, </if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="noticeTitle != null and noticeTitle != ''">#{noticeTitle}, </if> + <if test="noticeType != null and noticeType != ''">#{noticeType}, </if> + <if test="noticeContent != null and noticeContent != ''">#{noticeContent}, </if> + <if test="status != null and status != ''">#{status}, </if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <update id="updateNotice" parameterType="SysNotice"> + update sys_notice + <set> + <if test="noticeTitle != null and noticeTitle != ''">notice_title = #{noticeTitle}, </if> + <if test="noticeType != null and noticeType != ''">notice_type = #{noticeType}, </if> + <if test="noticeContent != null">notice_content = #{noticeContent}, </if> + <if test="status != null and status != ''">status = #{status}, </if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where notice_id = #{noticeId} + </update> + + <delete id="deleteNoticeById" parameterType="Long"> + delete from sys_notice where notice_id = #{noticeId} + </delete> + + <delete id="deleteNoticeByIds" parameterType="Long"> + delete from sys_notice where notice_id in + <foreach item="noticeId" collection="array" open="(" separator="," close=")"> + #{noticeId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml new file mode 100644 index 0000000..d2a20ad --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysPostMapper.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysPostMapper"> + + <resultMap type="SysPost" id="SysPostResult"> + <id property="postId" column="post_id" /> + <result property="postCode" column="post_code" /> + <result property="postName" column="post_name" /> + <result property="postSort" column="post_sort" /> + <result property="status" column="status" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + <result property="remark" column="remark" /> + </resultMap> + + <sql id="selectPostVo"> + select post_id, post_code, post_name, post_sort, status, create_by, create_time, remark + from sys_post + </sql> + + <select id="selectPostList" parameterType="SysPost" resultMap="SysPostResult"> + <include refid="selectPostVo"/> + <where> + <if test="postCode != null and postCode != ''"> + AND post_code like concat('%', #{postCode}, '%') + </if> + <if test="status != null and status != ''"> + AND status = #{status} + </if> + <if test="postName != null and postName != ''"> + AND post_name like concat('%', #{postName}, '%') + </if> + </where> + </select> + + <select id="selectPostAll" resultMap="SysPostResult"> + <include refid="selectPostVo"/> + </select> + + <select id="selectPostById" parameterType="Long" resultMap="SysPostResult"> + <include refid="selectPostVo"/> + where post_id = #{postId} + </select> + + <select id="selectPostListByUserId" parameterType="Long" resultType="Integer"> + select p.post_id + from sys_post p + left join sys_user_post up on up.post_id = p.post_id + left join sys_user u on u.user_id = up.user_id + where u.user_id = #{userId} + </select> + + <select id="selectPostsByUserName" parameterType="String" resultMap="SysPostResult"> + select p.post_id, p.post_name, p.post_code + from sys_post p + left join sys_user_post up on up.post_id = p.post_id + left join sys_user u on u.user_id = up.user_id + where u.user_name = #{userName} + </select> + + <select id="checkPostNameUnique" parameterType="String" resultMap="SysPostResult"> + <include refid="selectPostVo"/> + where post_name=#{postName} + </select> + + <select id="checkPostCodeUnique" parameterType="String" resultMap="SysPostResult"> + <include refid="selectPostVo"/> + where post_code=#{postCode} + </select> + + <update id="updatePost" parameterType="SysPost"> + update sys_post + <set> + <if test="postCode != null and postCode != ''">post_code = #{postCode},</if> + <if test="postName != null and postName != ''">post_name = #{postName},</if> + <if test="postSort != null and postSort != ''">post_sort = #{postSort},</if> + <if test="status != null and status != ''">status = #{status},</if> + <if test="remark != null">remark = #{remark},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where post_id = #{postId} + </update> + + <insert id="insertPost" parameterType="SysPost" useGeneratedKeys="true" keyProperty="postId"> + insert into sys_post( + <if test="postId != null and postId != 0">post_id,</if> + <if test="postCode != null and postCode != ''">post_code,</if> + <if test="postName != null and postName != ''">post_name,</if> + <if test="postSort != null and postSort != ''">post_sort,</if> + <if test="status != null and status != ''">status,</if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="postId != null and postId != 0">#{postId},</if> + <if test="postCode != null and postCode != ''">#{postCode},</if> + <if test="postName != null and postName != ''">#{postName},</if> + <if test="postSort != null and postSort != ''">#{postSort},</if> + <if test="status != null and status != ''">#{status},</if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <delete id="deletePostById" parameterType="Long"> + delete from sys_post where post_id = #{postId} + </delete> + + <delete id="deletePostByIds" parameterType="Long"> + delete from sys_post where post_id in + <foreach collection="array" item="postId" open="(" separator="," close=")"> + #{postId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysRoleDeptMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysRoleDeptMapper.xml new file mode 100644 index 0000000..23d2cb5 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysRoleDeptMapper.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysRoleDeptMapper"> + + <resultMap type="SysRoleDept" id="SysRoleDeptResult"> + <result property="roleId" column="role_id" /> + <result property="deptId" column="dept_id" /> + </resultMap> + + <delete id="deleteRoleDeptByRoleId" parameterType="Long"> + delete from sys_role_dept where role_id=#{roleId} + </delete> + + <select id="selectCountRoleDeptByDeptId" resultType="Integer"> + select count(1) from sys_role_dept where dept_id=#{deptId} + </select> + + <delete id="deleteRoleDept" parameterType="Long"> + delete from sys_role_dept where role_id in + <foreach collection="array" item="roleId" open="(" separator="," close=")"> + #{roleId} + </foreach> + </delete> + + <insert id="batchRoleDept"> + insert into sys_role_dept(role_id, dept_id) values + <foreach item="item" index="index" collection="list" separator=","> + (#{item.roleId},#{item.deptId}) + </foreach> + </insert> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml new file mode 100644 index 0000000..e2750f6 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysRoleMapper.xml @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysRoleMapper"> + + <resultMap type="SysRole" id="SysRoleResult"> + <id property="roleId" column="role_id" /> + <result property="roleName" column="role_name" /> + <result property="roleKey" column="role_key" /> + <result property="roleSort" column="role_sort" /> + <result property="dataScope" column="data_scope" /> + <result property="status" column="status" /> + <result property="delFlag" column="del_flag" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + <result property="remark" column="remark" /> + </resultMap> + + <sql id="selectRoleVo"> + select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, + r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id + </sql> + + <select id="selectRoleList" parameterType="SysRole" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + where r.del_flag = '0' + <if test="roleName != null and roleName != ''"> + AND r.role_name like concat('%', #{roleName}, '%') + </if> + <if test="status != null and status != ''"> + AND r.status = #{status} + </if> + <if test="roleKey != null and roleKey != ''"> + AND r.role_key like concat('%', #{roleKey}, '%') + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + and date_format(r.create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + and date_format(r.create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + <!-- 鏁版嵁鑼冨洿杩囨护 --> + ${dataScope} + </select> + + <select id="selectRolePermissionByUserId" parameterType="Long" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + WHERE r.del_flag = '0' and ur.user_id = #{userId} + </select> + + <select id="selectRoleAll" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + </select> + + <select id="selectRoleListByUserId" parameterType="Long" resultType="Integer"> + select r.role_id + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + where u.user_id = #{userId} + </select> + + <select id="selectRoleById" parameterType="Long" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + where r.role_id = #{roleId} + </select> + + <select id="selectRolesByUserName" parameterType="String" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + WHERE r.del_flag = '0' and u.user_name = #{userName} + </select> + + <select id="checkRoleNameUnique" parameterType="String" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + where r.role_name=#{roleName} + </select> + + <select id="checkRoleKeyUnique" parameterType="String" resultMap="SysRoleResult"> + <include refid="selectRoleVo"/> + where r.role_key=#{roleKey} + </select> + + <insert id="insertRole" parameterType="SysRole" useGeneratedKeys="true" keyProperty="roleId"> + insert into sys_role( + <if test="roleId != null and roleId != 0">role_id,</if> + <if test="roleName != null and roleName != ''">role_name,</if> + <if test="roleKey != null and roleKey != ''">role_key,</if> + <if test="roleSort != null and roleSort != ''">role_sort,</if> + <if test="dataScope != null and dataScope != ''">data_scope,</if> + <if test="status != null and status != ''">status,</if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="roleId != null and roleId != 0">#{roleId},</if> + <if test="roleName != null and roleName != ''">#{roleName},</if> + <if test="roleKey != null and roleKey != ''">#{roleKey},</if> + <if test="roleSort != null and roleSort != ''">#{roleSort},</if> + <if test="dataScope != null and dataScope != ''">#{dataScope},</if> + <if test="status != null and status != ''">#{status},</if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <update id="updateRole" parameterType="SysRole"> + update sys_role + <set> + <if test="roleName != null and roleName != ''">role_name = #{roleName},</if> + <if test="roleKey != null and roleKey != ''">role_key = #{roleKey},</if> + <if test="roleSort != null and roleSort != ''">role_sort = #{roleSort},</if> + <if test="dataScope != null and dataScope != ''">data_scope = #{dataScope},</if> + <if test="status != null and status != ''">status = #{status},</if> + <if test="remark != null">remark = #{remark},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + update_time = sysdate() + </set> + where role_id = #{roleId} + </update> + + <update id="updateRoleStatus" parameterType="SysRole"> + update sys_user set status = #{status} where user_id = #{userId} + </update> + + <delete id="deleteRoleById" parameterType="Long"> + delete from sys_role where role_id = #{roleId} + </delete> + + <delete id="deleteRoleByIds" parameterType="Long"> + update sys_role set del_flag = '2' where role_id in + <foreach collection="array" item="roleId" open="(" separator="," close=")"> + #{roleId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysRoleMenuMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysRoleMenuMapper.xml new file mode 100644 index 0000000..0e2e3d8 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysRoleMenuMapper.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysRoleMenuMapper"> + + <resultMap type="SysRoleMenu" id="SysRoleMenuResult"> + <result property="roleId" column="role_id" /> + <result property="menuId" column="menu_id" /> + </resultMap> + + <select id="checkMenuExistRole" resultType="Integer"> + select count(1) from sys_role_menu where menu_id = #{menuId} + </select> + + <delete id="deleteRoleMenuByRoleId" parameterType="Long"> + delete from sys_role_menu where role_id=#{roleId} + </delete> + + <insert id="batchRoleMenu"> + insert into sys_role_menu(role_id, menu_id) values + <foreach item="item" index="index" collection="list" separator=","> + (#{item.roleId},#{item.menuId}) + </foreach> + </insert> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml new file mode 100644 index 0000000..4ee6d8f --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysUserMapper.xml @@ -0,0 +1,182 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysUserMapper"> + + <resultMap type="SysUser" id="SysUserResult"> + <id property="userId" column="user_id" /> + <result property="deptId" column="dept_id" /> + <result property="userName" column="user_name" /> + <result property="nickName" column="nick_name" /> + <result property="email" column="email" /> + <result property="phonenumber" column="phonenumber" /> + <result property="sex" column="sex" /> + <result property="avatar" column="avatar" /> + <result property="password" column="password" /> + <result property="status" column="status" /> + <result property="delFlag" column="del_flag" /> + <result property="loginIp" column="login_ip" /> + <result property="loginDate" column="login_date" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + <result property="remark" column="remark" /> + <association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" /> + <collection property="roles" javaType="java.util.List" resultMap="RoleResult" /> + </resultMap> + + <resultMap id="deptResult" type="SysDept"> + <id property="deptId" column="dept_id" /> + <result property="parentId" column="parent_id" /> + <result property="deptName" column="dept_name" /> + <result property="orderNum" column="order_num" /> + <result property="leader" column="leader" /> + <result property="status" column="dept_status" /> + </resultMap> + + <resultMap id="RoleResult" type="SysRole"> + <id property="roleId" column="role_id" /> + <result property="roleName" column="role_name" /> + <result property="roleKey" column="role_key" /> + <result property="roleSort" column="role_sort" /> + <result property="dataScope" column="data_scope" /> + <result property="status" column="role_status" /> + </resultMap> + + <sql id="selectUserVo"> + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status + from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + </sql> + + <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult"> + select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u + left join sys_dept d on u.dept_id = d.dept_id + where u.del_flag = '0' + <if test="userName != null and userName != ''"> + AND u.user_name like concat('%', #{userName}, '%') + </if> + <if test="status != null and status != ''"> + AND u.status = #{status} + </if> + <if test="phonenumber != null and phonenumber != ''"> + AND u.phonenumber like concat('%', #{phonenumber}, '%') + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + AND date_format(u.create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + AND date_format(u.create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + <if test="deptId != null and deptId != 0"> + AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE FIND_IN_SET (#{deptId},ancestors) )) + </if> + <!-- 鏁版嵁鑼冨洿杩囨护 --> + ${dataScope} + </select> + + <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult"> + <include refid="selectUserVo"/> + where u.user_name = #{userName} + </select> + + <select id="selectUserById" parameterType="Long" resultMap="SysUserResult"> + <include refid="selectUserVo"/> + where u.user_id = #{userId} + </select> + + <select id="checkUserNameUnique" parameterType="String" resultType="int"> + select count(1) from sys_user where user_name = #{userName} + </select> + + <select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult"> + select user_id, phonenumber from sys_user where phonenumber = #{phonenumber} + </select> + + <select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult"> + select user_id, email from sys_user where email = #{email} + </select> + + <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId"> + insert into sys_user( + <if test="userId != null and userId != 0">user_id,</if> + <if test="deptId != null and deptId != 0">dept_id,</if> + <if test="userName != null and userName != ''">user_name,</if> + <if test="nickName != null and nickName != ''">nick_name,</if> + <if test="email != null and email != ''">email,</if> + <if test="avatar != null and avatar != ''">avatar,</if> + <if test="phonenumber != null and phonenumber != ''">phonenumber,</if> + <if test="sex != null and sex != ''">sex,</if> + <if test="password != null and password != ''">password,</if> + <if test="status != null and status != ''">status,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + <if test="remark != null and remark != ''">remark,</if> + create_time + )values( + <if test="userId != null and userId != ''">#{userId},</if> + <if test="deptId != null and deptId != ''">#{deptId},</if> + <if test="userName != null and userName != ''">#{userName},</if> + <if test="nickName != null and nickName != ''">#{nickName},</if> + <if test="email != null and email != ''">#{email},</if> + <if test="avatar != null and avatar != ''">#{avatar},</if> + <if test="phonenumber != null and phonenumber != ''">#{phonenumber},</if> + <if test="sex != null and sex != ''">#{sex},</if> + <if test="password != null and password != ''">#{password},</if> + <if test="status != null and status != ''">#{status},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + <if test="remark != null and remark != ''">#{remark},</if> + sysdate() + ) + </insert> + + <update id="updateUser" parameterType="SysUser"> + update sys_user + <set> + <if test="deptId != null and deptId != 0">dept_id = #{deptId},</if> + <if test="userName != null and userName != ''">user_name = #{userName},</if> + <if test="nickName != null and nickName != ''">nick_name = #{nickName},</if> + <if test="email != null and email != ''">email = #{email},</if> + <if test="phonenumber != null and phonenumber != ''">phonenumber = #{phonenumber},</if> + <if test="sex != null and sex != ''">sex = #{sex},</if> + <if test="avatar != null and avatar != ''">avatar = #{avatar},</if> + <if test="password != null and password != ''">password = #{password},</if> + <if test="status != null and status != ''">status = #{status},</if> + <if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if> + <if test="loginDate != null">login_date = #{loginDate},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + <if test="remark != null">remark = #{remark},</if> + update_time = sysdate() + </set> + where user_id = #{userId} + </update> + + <update id="updateUserStatus" parameterType="SysUser"> + update sys_user set status = #{status} where user_id = #{userId} + </update> + + <update id="updateUserAvatar" parameterType="SysUser"> + update sys_user set avatar = #{avatar} where user_name = #{userName} + </update> + + <update id="resetUserPwd" parameterType="SysUser"> + update sys_user set password = #{password} where user_name = #{userName} + </update> + + <delete id="deleteUserById" parameterType="Long"> + delete from sys_user where user_id = #{userId} + </delete> + + <delete id="deleteUserByIds" parameterType="Long"> + update sys_user set del_flag = '2' where user_id in + <foreach collection="array" item="userId" open="(" separator="," close=")"> + #{userId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysUserPostMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysUserPostMapper.xml new file mode 100644 index 0000000..d048078 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysUserPostMapper.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysUserPostMapper"> + + <resultMap type="SysUserPost" id="SysUserPostResult"> + <result property="userId" column="user_id" /> + <result property="postId" column="post_id" /> + </resultMap> + + <delete id="deleteUserPostByUserId" parameterType="Long"> + delete from sys_user_post where user_id=#{userId} + </delete> + + <select id="countUserPostById" resultType="Integer"> + select count(1) from sys_user_post where post_id=#{postId} + </select> + + <delete id="deleteUserPost" parameterType="Long"> + delete from sys_user_post where user_id in + <foreach collection="array" item="userId" open="(" separator="," close=")"> + #{userId} + </foreach> + </delete> + + <insert id="batchUserPost"> + insert into sys_user_post(user_id, post_id) values + <foreach item="item" index="index" collection="list" separator=","> + (#{item.userId},#{item.postId}) + </foreach> + </insert> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/system/SysUserRoleMapper.xml b/ruoyi/src/main/resources/mybatis/system/SysUserRoleMapper.xml new file mode 100644 index 0000000..d7324eb --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/system/SysUserRoleMapper.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.system.mapper.SysUserRoleMapper"> + + <resultMap type="SysUserRole" id="SysUserRoleResult"> + <result property="userId" column="user_id" /> + <result property="roleId" column="role_id" /> + </resultMap> + + <delete id="deleteUserRoleByUserId" parameterType="Long"> + delete from sys_user_role where user_id=#{userId} + </delete> + + <select id="countUserRoleByRoleId" resultType="Integer"> + select count(1) from sys_user_role where role_id=#{roleId} + </select> + + <delete id="deleteUserRole" parameterType="Long"> + delete from sys_user_role where user_id in + <foreach collection="array" item="userId" open="(" separator="," close=")"> + #{userId} + </foreach> + </delete> + + <insert id="batchUserRole"> + insert into sys_user_role(user_id, role_id) values + <foreach item="item" index="index" collection="list" separator=","> + (#{item.userId},#{item.roleId}) + </foreach> + </insert> + + <delete id="deleteUserRoleInfo" parameterType="SysUserRole"> + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} + </delete> + + <delete id="deleteUserRoleInfos"> + delete from sys_user_role where role_id=#{roleId} and user_id in + <foreach collection="userIds" item="userId" open="(" separator="," close=")"> + #{userId} + </foreach> + </delete> +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/tool/GenTableColumnMapper.xml b/ruoyi/src/main/resources/mybatis/tool/GenTableColumnMapper.xml new file mode 100644 index 0000000..77d9e7d --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/tool/GenTableColumnMapper.xml @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.tool.gen.mapper.GenTableColumnMapper"> + + <resultMap type="GenTableColumn" id="GenTableColumnResult"> + <id property="columnId" column="column_id" /> + <result property="tableId" column="table_id" /> + <result property="columnName" column="column_name" /> + <result property="columnComment" column="column_comment" /> + <result property="columnType" column="column_type" /> + <result property="javaType" column="java_type" /> + <result property="javaField" column="java_field" /> + <result property="isPk" column="is_pk" /> + <result property="isIncrement" column="is_increment" /> + <result property="isRequired" column="is_required" /> + <result property="isInsert" column="is_insert" /> + <result property="isEdit" column="is_edit" /> + <result property="isList" column="is_list" /> + <result property="isQuery" column="is_query" /> + <result property="queryType" column="query_type" /> + <result property="htmlType" column="html_type" /> + <result property="dictType" column="dict_type" /> + <result property="sort" column="sort" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + </resultMap> + + <sql id="selectGenTableColumnVo"> + select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column + </sql> + + <select id="selectGenTableColumnListByTableId" parameterType="Long" resultMap="GenTableColumnResult"> + <include refid="selectGenTableColumnVo"/> + where table_id = #{tableId} + order by sort + </select> + + <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult"> + select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type + from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName}) + order by ordinal_position + </select> + + <insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId"> + insert into gen_table_column ( + <if test="tableId != null and tableId != ''">table_id,</if> + <if test="columnName != null and columnName != ''">column_name,</if> + <if test="columnComment != null and columnComment != ''">column_comment,</if> + <if test="columnType != null and columnType != ''">column_type,</if> + <if test="javaType != null and javaType != ''">java_type,</if> + <if test="javaField != null and javaField != ''">java_field,</if> + <if test="isPk != null and isPk != ''">is_pk,</if> + <if test="isIncrement != null and isIncrement != ''">is_increment,</if> + <if test="isRequired != null and isRequired != ''">is_required,</if> + <if test="isInsert != null and isInsert != ''">is_insert,</if> + <if test="isEdit != null and isEdit != ''">is_edit,</if> + <if test="isList != null and isList != ''">is_list,</if> + <if test="isQuery != null and isQuery != ''">is_query,</if> + <if test="queryType != null and queryType != ''">query_type,</if> + <if test="htmlType != null and htmlType != ''">html_type,</if> + <if test="dictType != null and dictType != ''">dict_type,</if> + <if test="sort != null">sort,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="tableId != null and tableId != ''">#{tableId},</if> + <if test="columnName != null and columnName != ''">#{columnName},</if> + <if test="columnComment != null and columnComment != ''">#{columnComment},</if> + <if test="columnType != null and columnType != ''">#{columnType},</if> + <if test="javaType != null and javaType != ''">#{javaType},</if> + <if test="javaField != null and javaField != ''">#{javaField},</if> + <if test="isPk != null and isPk != ''">#{isPk},</if> + <if test="isIncrement != null and isIncrement != ''">#{isIncrement},</if> + <if test="isRequired != null and isRequired != ''">#{isRequired},</if> + <if test="isInsert != null and isInsert != ''">#{isInsert},</if> + <if test="isEdit != null and isEdit != ''">#{isEdit},</if> + <if test="isList != null and isList != ''">#{isList},</if> + <if test="isQuery != null and isQuery != ''">#{isQuery},</if> + <if test="queryType != null and queryType != ''">#{queryType},</if> + <if test="htmlType != null and htmlType != ''">#{htmlType},</if> + <if test="dictType != null and dictType != ''">#{dictType},</if> + <if test="sort != null">#{sort},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <update id="updateGenTableColumn" parameterType="GenTableColumn"> + update gen_table_column + <set> + column_comment = #{columnComment}, + java_type = #{javaType}, + java_field = #{javaField}, + is_insert = #{isInsert}, + is_edit = #{isEdit}, + is_list = #{isList}, + is_query = #{isQuery}, + is_required = #{isRequired}, + query_type = #{queryType}, + html_type = #{htmlType}, + dict_type = #{dictType}, + sort = #{sort}, + update_by = #{updateBy}, + update_time = sysdate() + </set> + where column_id = #{columnId} + </update> + + <delete id="deleteGenTableColumnByIds" parameterType="Long"> + delete from gen_table_column where table_id in + <foreach collection="array" item="tableId" open="(" separator="," close=")"> + #{tableId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/mybatis/tool/GenTableMapper.xml b/ruoyi/src/main/resources/mybatis/tool/GenTableMapper.xml new file mode 100644 index 0000000..50af4d3 --- /dev/null +++ b/ruoyi/src/main/resources/mybatis/tool/GenTableMapper.xml @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.project.tool.gen.mapper.GenTableMapper"> + + <resultMap type="GenTable" id="GenTableResult"> + <id property="tableId" column="table_id" /> + <result property="tableName" column="table_name" /> + <result property="tableComment" column="table_comment" /> + <result property="className" column="class_name" /> + <result property="tplCategory" column="tpl_category" /> + <result property="packageName" column="package_name" /> + <result property="moduleName" column="module_name" /> + <result property="businessName" column="business_name" /> + <result property="functionName" column="function_name" /> + <result property="functionAuthor" column="function_author" /> + <result property="options" column="options" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + <result property="remark" column="remark" /> + <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" /> + </resultMap> + + <resultMap type="GenTableColumn" id="GenTableColumnResult"> + <id property="columnId" column="column_id" /> + <result property="tableId" column="table_id" /> + <result property="columnName" column="column_name" /> + <result property="columnComment" column="column_comment" /> + <result property="columnType" column="column_type" /> + <result property="javaType" column="java_type" /> + <result property="javaField" column="java_field" /> + <result property="isPk" column="is_pk" /> + <result property="isIncrement" column="is_increment" /> + <result property="isRequired" column="is_required" /> + <result property="isInsert" column="is_insert" /> + <result property="isEdit" column="is_edit" /> + <result property="isList" column="is_list" /> + <result property="isQuery" column="is_query" /> + <result property="queryType" column="query_type" /> + <result property="htmlType" column="html_type" /> + <result property="dictType" column="dict_type" /> + <result property="sort" column="sort" /> + <result property="createBy" column="create_by" /> + <result property="createTime" column="create_time" /> + <result property="updateBy" column="update_by" /> + <result property="updateTime" column="update_time" /> + </resultMap> + + <sql id="selectGenTableVo"> + select table_id, table_name, table_comment, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, options, create_by, create_time, update_by, update_time, remark from gen_table + </sql> + + <select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult"> + <include refid="selectGenTableVo"/> + <where> + <if test="tableName != null and tableName != ''"> + AND lower(table_name) like lower(concat('%', #{tableName}, '%')) + </if> + <if test="tableComment != null and tableComment != ''"> + AND lower(table_comment) like lower(concat('%', #{tableComment}, '%')) + </if> +<!-- <if test="beginTime != null and beginTime != ''">寮�濮嬫椂闂存绱� --> +<!-- AND date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') --> +<!-- </if> --> +<!-- <if test="endTime != null and endTime != ''">缁撴潫鏃堕棿妫�绱� --> +<!-- AND date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') --> +<!-- </if> --> + </where> + </select> + + <select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult"> + select table_name, table_comment, create_time, update_time from information_schema.tables + where table_schema = (select database()) + AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%' + AND table_name NOT IN (select table_name from gen_table) + <if test="tableName != null and tableName != ''"> + AND lower(table_name) like lower(concat('%', #{tableName}, '%')) + </if> + <if test="tableComment != null and tableComment != ''"> + AND lower(table_comment) like lower(concat('%', #{tableComment}, '%')) + </if> + <if test="beginTime != null and beginTime != ''"><!-- 寮�濮嬫椂闂存绱� --> + AND date_format(create_time,'%y%m%d') >= date_format(#{beginTime},'%y%m%d') + </if> + <if test="endTime != null and endTime != ''"><!-- 缁撴潫鏃堕棿妫�绱� --> + AND date_format(create_time,'%y%m%d') <= date_format(#{endTime},'%y%m%d') + </if> + </select> + + <select id="selectDbTableListByNames" resultMap="GenTableResult"> + select table_name, table_comment, create_time, update_time from information_schema.tables + where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) + and table_name in + <foreach collection="array" item="name" open="(" separator="," close=")"> + #{name} + </foreach> + </select> + + <select id="selectTableByName" parameterType="String" resultMap="GenTableResult"> + select table_name, table_comment, create_time, update_time from information_schema.tables + where table_comment <![CDATA[ <> ]]> '' and table_schema = (select database()) + and table_name = #{tableName} + </select> + + <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult"> + SELECT t.table_id, t.table_name, t.table_comment, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark, + c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort + FROM gen_table t + LEFT JOIN gen_table_column c ON t.table_id = c.table_id + where t.table_id = #{tableId} + </select> + + <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult"> + SELECT t.table_id, t.table_name, t.table_comment, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark, + c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort + FROM gen_table t + LEFT JOIN gen_table_column c ON t.table_id = c.table_id + where t.table_name = #{tableName} + </select> + + <insert id="insertGenTable" parameterType="GenTable" useGeneratedKeys="true" keyProperty="tableId"> + insert into gen_table ( + <if test="tableName != null">table_name,</if> + <if test="tableComment != null and tableComment != ''">table_comment,</if> + <if test="className != null and className != ''">class_name,</if> + <if test="tplCategory != null and tplCategory != ''">tpl_category,</if> + <if test="packageName != null and packageName != ''">package_name,</if> + <if test="moduleName != null and moduleName != ''">module_name,</if> + <if test="businessName != null and businessName != ''">business_name,</if> + <if test="functionName != null and functionName != ''">function_name,</if> + <if test="functionAuthor != null and functionAuthor != ''">function_author,</if> + <if test="remark != null and remark != ''">remark,</if> + <if test="createBy != null and createBy != ''">create_by,</if> + create_time + )values( + <if test="tableName != null">#{tableName},</if> + <if test="tableComment != null and tableComment != ''">#{tableComment},</if> + <if test="className != null and className != ''">#{className},</if> + <if test="tplCategory != null and tplCategory != ''">#{tplCategory},</if> + <if test="packageName != null and packageName != ''">#{packageName},</if> + <if test="moduleName != null and moduleName != ''">#{moduleName},</if> + <if test="businessName != null and businessName != ''">#{businessName},</if> + <if test="functionName != null and functionName != ''">#{functionName},</if> + <if test="functionAuthor != null and functionAuthor != ''">#{functionAuthor},</if> + <if test="remark != null and remark != ''">#{remark},</if> + <if test="createBy != null and createBy != ''">#{createBy},</if> + sysdate() + ) + </insert> + + <update id="updateGenTable" parameterType="GenTable"> + update gen_table + <set> + <if test="tableName != null">table_name = #{tableName},</if> + <if test="tableComment != null and tableComment != ''">table_comment = #{tableComment},</if> + <if test="className != null and className != ''">class_name = #{className},</if> + <if test="functionAuthor != null and functionAuthor != ''">function_author = #{functionAuthor},</if> + <if test="tplCategory != null and tplCategory != ''">tpl_category = #{tplCategory},</if> + <if test="packageName != null and packageName != ''">package_name = #{packageName},</if> + <if test="moduleName != null and moduleName != ''">module_name = #{moduleName},</if> + <if test="businessName != null and businessName != ''">business_name = #{businessName},</if> + <if test="functionName != null and functionName != ''">function_name = #{functionName},</if> + <if test="options != null and options != ''">options = #{options},</if> + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> + <if test="remark != null">remark = #{remark},</if> + update_time = sysdate() + </set> + where table_id = #{tableId} + </update> + + <delete id="deleteGenTableByIds" parameterType="Long"> + delete from gen_table where table_id in + <foreach collection="array" item="tableId" open="(" separator="," close=")"> + #{tableId} + </foreach> + </delete> + +</mapper> \ No newline at end of file diff --git a/ruoyi/src/main/resources/vm/java/controller.java.vm b/ruoyi/src/main/resources/vm/java/controller.java.vm new file mode 100644 index 0000000..ba4ec9f --- /dev/null +++ b/ruoyi/src/main/resources/vm/java/controller.java.vm @@ -0,0 +1,103 @@ +package ${packageName}.controller; + +import java.util.List; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.framework.aspectj.lang.annotation.Log; +import com.ruoyi.framework.aspectj.lang.enums.BusinessType; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; +import com.ruoyi.framework.web.controller.BaseController; +import com.ruoyi.framework.web.domain.AjaxResult; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.web.page.TableDataInfo; + +/** + * ${functionName}Controller + * + * @author ${author} + * @date ${datetime} + */ +@RestController +@RequestMapping("/${moduleName}/${businessName}") +public class ${ClassName}Controller extends BaseController +{ + @Autowired + private I${ClassName}Service ${className}Service; + + /** + * 鏌ヨ${functionName}鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") + @GetMapping("/list") + public TableDataInfo list(${ClassName} ${className}) + { + startPage(); + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + return getDataTable(list); + } + + /** + * 瀵煎嚭${functionName}鍒楄〃 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") + @Log(title = "${functionName}", businessType = BusinessType.EXPORT) + @GetMapping("/export") + public AjaxResult export(${ClassName} ${className}) + { + List<${ClassName}> list = ${className}Service.select${ClassName}List(${className}); + ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class); + return util.exportExcel(list, "${businessName}"); + } + + /** + * 鑾峰彇${functionName}璇︾粏淇℃伅 + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") + @GetMapping(value = "/{${pkColumn.javaField}}") + public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) + { + return AjaxResult.success(${className}Service.select${ClassName}ById(${pkColumn.javaField})); + } + + /** + * 鏂板${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") + @Log(title = "${functionName}", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.insert${ClassName}(${className})); + } + + /** + * 淇敼${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") + @Log(title = "${functionName}", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody ${ClassName} ${className}) + { + return toAjax(${className}Service.update${ClassName}(${className})); + } + + /** + * 鍒犻櫎${functionName} + */ + @PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") + @Log(title = "${functionName}", businessType = BusinessType.DELETE) + @DeleteMapping("/{${pkColumn.javaField}s}") + public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return toAjax(${className}Service.delete${ClassName}ByIds(${pkColumn.javaField}s)); + } +} diff --git a/ruoyi/src/main/resources/vm/java/domain.java.vm b/ruoyi/src/main/resources/vm/java/domain.java.vm new file mode 100644 index 0000000..23240c8 --- /dev/null +++ b/ruoyi/src/main/resources/vm/java/domain.java.vm @@ -0,0 +1,76 @@ +package ${packageName}.domain; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.framework.aspectj.lang.annotation.Excel; +import com.ruoyi.framework.web.domain.BaseEntity; +#foreach ($import in $importList) +import ${import}; +#end + +/** + * ${functionName}瀵硅薄 ${tableName} + * + * @author ${author} + * @date ${datetime} + */ +#set($Entity="BaseEntity") +public class ${ClassName} extends ${Entity} +{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) + /** $column.columnComment */ +#if($column.list) +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($parentheseIndex != -1) + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") +#elseif($column.javaType == 'Date') + @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd") +#else + @Excel(name = "${comment}") +#end +#end + private $column.javaType $column.javaField; + +#end +#end +#foreach ($column in $columns) +#if(!$table.isSuperColumn($column.javaField)) +#if($column.javaField > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + public void set${AttrName}($column.javaType $column.javaField) + { + this.$column.javaField = $column.javaField; + } + + public $column.javaType get${AttrName}() + { + return $column.javaField; + } +#end +#end + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) +#foreach ($column in $columns) +#if($column.javaField > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) +#set($AttrName=$column.javaField) +#else +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#end + .append("${column.javaField}", get${AttrName}()) +#end + .toString(); + } +} diff --git a/ruoyi/src/main/resources/vm/java/mapper.java.vm b/ruoyi/src/main/resources/vm/java/mapper.java.vm new file mode 100644 index 0000000..dc3a5df --- /dev/null +++ b/ruoyi/src/main/resources/vm/java/mapper.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.mapper; + +import ${packageName}.domain.${ClassName}; +import java.util.List; + +/** + * ${functionName}Mapper鎺ュ彛 + * + * @author ${author} + * @date ${datetime} + */ +public interface ${ClassName}Mapper +{ + /** + * 鏌ヨ${functionName} + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return ${functionName} + */ + public ${ClassName} select${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 鏌ヨ${functionName}鍒楄〃 + * + * @param ${className} ${functionName} + * @return ${functionName}闆嗗悎 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 鏂板${functionName} + * + * @param ${className} ${functionName} + * @return 缁撴灉 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 淇敼${functionName} + * + * @param ${className} ${functionName} + * @return 缁撴灉 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 鍒犻櫎${functionName} + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 缁撴灉 + */ + public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 鎵归噺鍒犻櫎${functionName} + * + * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑鏁版嵁ID + * @return 缁撴灉 + */ + public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s); +} diff --git a/ruoyi/src/main/resources/vm/java/service.java.vm b/ruoyi/src/main/resources/vm/java/service.java.vm new file mode 100644 index 0000000..678f6dc --- /dev/null +++ b/ruoyi/src/main/resources/vm/java/service.java.vm @@ -0,0 +1,61 @@ +package ${packageName}.service; + +import ${packageName}.domain.${ClassName}; +import java.util.List; + +/** + * ${functionName}Service鎺ュ彛 + * + * @author ${author} + * @date ${datetime} + */ +public interface I${ClassName}Service +{ + /** + * 鏌ヨ${functionName} + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return ${functionName} + */ + public ${ClassName} select${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + + /** + * 鏌ヨ${functionName}鍒楄〃 + * + * @param ${className} ${functionName} + * @return ${functionName}闆嗗悎 + */ + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}); + + /** + * 鏂板${functionName} + * + * @param ${className} ${functionName} + * @return 缁撴灉 + */ + public int insert${ClassName}(${ClassName} ${className}); + + /** + * 淇敼${functionName} + * + * @param ${className} ${functionName} + * @return 缁撴灉 + */ + public int update${ClassName}(${ClassName} ${className}); + + /** + * 鎵归噺鍒犻櫎${functionName} + * + * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑${functionName}ID + * @return 缁撴灉 + */ + public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s); + + /** + * 鍒犻櫎${functionName}淇℃伅 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 缁撴灉 + */ + public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); +} diff --git a/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm new file mode 100644 index 0000000..9f8c53f --- /dev/null +++ b/ruoyi/src/main/resources/vm/java/serviceImpl.java.vm @@ -0,0 +1,109 @@ +package ${packageName}.service.impl; + +import java.util.List; +#foreach ($column in $columns) +#if($column.javaField == 'createTime' || $column.javaField == 'updateTime') +import com.ruoyi.common.utils.DateUtils; +#break +#end +#end +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ${packageName}.mapper.${ClassName}Mapper; +import ${packageName}.domain.${ClassName}; +import ${packageName}.service.I${ClassName}Service; + +/** + * ${functionName}Service涓氬姟灞傚鐞� + * + * @author ${author} + * @date ${datetime} + */ +@Service +public class ${ClassName}ServiceImpl implements I${ClassName}Service +{ + @Autowired + private ${ClassName}Mapper ${className}Mapper; + + /** + * 鏌ヨ${functionName} + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return ${functionName} + */ + @Override + public ${ClassName} select${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.select${ClassName}ById(${pkColumn.javaField}); + } + + /** + * 鏌ヨ${functionName}鍒楄〃 + * + * @param ${className} ${functionName} + * @return ${functionName} + */ + @Override + public List<${ClassName}> select${ClassName}List(${ClassName} ${className}) + { + return ${className}Mapper.select${ClassName}List(${className}); + } + + /** + * 鏂板${functionName} + * + * @param ${className} ${functionName} + * @return 缁撴灉 + */ + @Override + public int insert${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'createTime') + ${className}.setCreateTime(DateUtils.getNowDate()); +#end +#end + return ${className}Mapper.insert${ClassName}(${className}); + } + + /** + * 淇敼${functionName} + * + * @param ${className} ${functionName} + * @return 缁撴灉 + */ + @Override + public int update${ClassName}(${ClassName} ${className}) + { +#foreach ($column in $columns) +#if($column.javaField == 'updateTime') + ${className}.setUpdateTime(DateUtils.getNowDate()); +#end +#end + return ${className}Mapper.update${ClassName}(${className}); + } + + /** + * 鎵归噺鍒犻櫎${functionName} + * + * @param ${pkColumn.javaField}s 闇�瑕佸垹闄ょ殑${functionName}ID + * @return 缁撴灉 + */ + @Override + public int delete${ClassName}ByIds(${pkColumn.javaType}[] ${pkColumn.javaField}s) + { + return ${className}Mapper.delete${ClassName}ByIds(${pkColumn.javaField}s); + } + + /** + * 鍒犻櫎${functionName}淇℃伅 + * + * @param ${pkColumn.javaField} ${functionName}ID + * @return 缁撴灉 + */ + @Override + public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}) + { + return ${className}Mapper.delete${ClassName}ById(${pkColumn.javaField}); + } +} diff --git a/ruoyi/src/main/resources/vm/js/api.js.vm b/ruoyi/src/main/resources/vm/js/api.js.vm new file mode 100644 index 0000000..296d41a --- /dev/null +++ b/ruoyi/src/main/resources/vm/js/api.js.vm @@ -0,0 +1,53 @@ +import request from '@/utils/request' + +// 鏌ヨ${functionName}鍒楄〃 +export function list${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ${functionName}璇︾粏 +export function get${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'get' + }) +} + +// 鏂板${functionName} +export function add${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'post', + data: data + }) +} + +// 淇敼${functionName} +export function update${BusinessName}(data) { + return request({ + url: '/${moduleName}/${businessName}', + method: 'put', + data: data + }) +} + +// 鍒犻櫎${functionName} +export function del${BusinessName}(${pkColumn.javaField}) { + return request({ + url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, + method: 'delete' + }) +} + +// 瀵煎嚭${functionName} +export function export${BusinessName}(query) { + return request({ + url: '/${moduleName}/${businessName}/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/ruoyi/src/main/resources/vm/sql/sql.vm b/ruoyi/src/main/resources/vm/sql/sql.vm new file mode 100644 index 0000000..948ce97 --- /dev/null +++ b/ruoyi/src/main/resources/vm/sql/sql.vm @@ -0,0 +1,22 @@ +-- 鑿滃崟 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}', '3', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 'C', '0', '${permissionPrefix}:list', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', '${functionName}鑿滃崟'); + +-- 鎸夐挳鐖惰彍鍗旾D +SELECT @parentId := LAST_INSERT_ID(); + +-- 鎸夐挳 SQL +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}鏌ヨ', @parentId, '1', '#', '', 1, 'F', '0', '${permissionPrefix}:query', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}鏂板', @parentId, '2', '#', '', 1, 'F', '0', '${permissionPrefix}:add', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}淇敼', @parentId, '3', '#', '', 1, 'F', '0', '${permissionPrefix}:edit', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}鍒犻櫎', @parentId, '4', '#', '', 1, 'F', '0', '${permissionPrefix}:remove', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', ''); + +insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, menu_type, visible, perms, icon, create_by, create_time, update_by, update_time, remark) +values('${functionName}瀵煎嚭', @parentId, '5', '#', '', 1, 'F', '0', '${permissionPrefix}:export', '#', 'admin', '2018-03-01', 'ry', '2018-03-01', ''); \ No newline at end of file diff --git a/ruoyi/src/main/resources/vm/vue/index.vue.vm b/ruoyi/src/main/resources/vm/vue/index.vue.vm new file mode 100644 index 0000000..9348194 --- /dev/null +++ b/ruoyi/src/main/resources/vm/vue/index.vue.vm @@ -0,0 +1,439 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> +#foreach($column in $columns) +#if($column.query) +#set($dictType=$column.dictType) +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($column.htmlType == "input") + <el-form-item label="${comment}" prop="${column.javaField}"> + <el-input + v-model="queryParams.${column.javaField}" + placeholder="璇疯緭鍏�${comment}" + clearable + size="small" + @keyup.enter.native="handleQuery" + /> + </el-form-item> +#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) + <el-form-item label="${comment}" prop="${column.javaField}"> + <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable size="small"> + <el-option + v-for="dict in ${column.javaField}Options" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + /> + </el-select> + </el-form-item> +#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) + <el-form-item label="${comment}" prop="${column.javaField}"> + <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable size="small"> + <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" /> + </el-select> + </el-form-item> +#elseif($column.htmlType == "datetime") + <el-form-item label="${comment}" prop="${column.javaField}"> + <el-date-picker clearable size="small" style="width: 200px" + v-model="queryParams.${column.javaField}" + type="date" + value-format="yyyy-MM-dd" + placeholder="閫夋嫨${comment}"> + </el-date-picker> + </el-form-item> +#end +#end +#end + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['${moduleName}:${businessName}:add']" + >鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['${moduleName}:${businessName}:edit']" + >淇敼</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['${moduleName}:${businessName}:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['${moduleName}:${businessName}:export']" + >瀵煎嚭</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> +#foreach($column in $columns) +#set($javaField=$column.javaField) +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if($column.pk) + <el-table-column label="${comment}" align="center" prop="${javaField}" /> +#elseif($column.list && $column.htmlType == "datetime") + <el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.${javaField}) }}</span> + </template> + </el-table-column> +#elseif($column.list && "" != $column.dictType) + <el-table-column label="${comment}" align="center" prop="${javaField}" :formatter="${javaField}Format" /> +#elseif($column.list && "" != $javaField) + <el-table-column label="${comment}" align="center" prop="${javaField}" /> +#end +#end + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['${moduleName}:${businessName}:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['${moduleName}:${businessName}:remove']" + >鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� --> + <el-dialog :title="title" :visible.sync="open" width="500px"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> +#foreach($column in $columns) +#set($field=$column.javaField) +#if($column.insert && !$column.pk) +#if(($column.usableColumn) || (!$column.superColumn)) +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#set($dictType=$column.dictType) +#if($column.htmlType == "input") + <el-form-item label="${comment}" prop="${field}"> + <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" /> + </el-form-item> +#elseif($column.htmlType == "select" && "" != $dictType) + <el-form-item label="${comment}"> + <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}"> + <el-option + v-for="dict in ${field}Options" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="dict.dictValue" + ></el-option> + </el-select> + </el-form-item> +#elseif($column.htmlType == "select" && $dictType) + <el-form-item label="${comment}"> + <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}"> + <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" /> + </el-select> + </el-form-item> +#elseif($column.htmlType == "radio" && "" != $dictType) + <el-form-item label="${comment}"> + <el-radio-group v-model="form.${field}"> + <el-radio + v-for="dict in ${field}Options" + :key="dict.dictValue" + :label="dict.dictValue" + >{{dict.dictLabel}}</el-radio> + </el-radio-group> + </el-form-item> +#elseif($column.htmlType == "radio" && $dictType) + <el-form-item label="${comment}"> + <el-radio-group v-model="form.${field}"> + <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio> + </el-radio-group> + </el-form-item> +#elseif($column.htmlType == "datetime") + <el-form-item label="${comment}" prop="${field}"> + <el-date-picker clearable size="small" style="width: 200px" + v-model="form.${field}" + type="date" + value-format="yyyy-MM-dd" + placeholder="閫夋嫨${comment}"> + </el-date-picker> + </el-form-item> +#elseif($column.htmlType == "textarea") + <el-form-item label="${comment}" prop="${field}"> + <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" /> + </el-form-item> +#end +#end +#end +#end + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}"; + +export default { + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // ${functionName}琛ㄦ牸鏁版嵁 + ${businessName}List: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, +#foreach ($column in $columns) +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#if(${column.dictType} != '') + // $comment瀛楀吀 + ${column.javaField}Options: []#if($velocityCount != $columns.size()),#end + +#end +#end + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, +#foreach ($column in $columns) +#if($column.query) + $column.javaField: undefined#if($velocityCount != $columns.size()),#end + +#end +#end + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { +#foreach ($column in $columns) +#if($column.required) +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end +#set($comment=$column.columnComment) + $column.javaField: [ + { required: true, message: "$comment涓嶈兘涓虹┖", trigger: "blur" } + ]#if($velocityCount != $columns.size()),#end +#end +#end + } + }; + }, + created() { + this.getList(); +#foreach ($column in $columns) +#if(${column.dictType} != '') + this.getDicts("${column.dictType}").then(response => { + this.${column.javaField}Options = response.data; + }); +#end +#end + }, + methods: { + /** 鏌ヨ${functionName}鍒楄〃 */ + getList() { + this.loading = true; + list${BusinessName}(this.queryParams).then(response => { + this.${businessName}List = response.rows; + this.total = response.total; + this.loading = false; + }); + }, +#foreach ($column in $columns) +#if(${column.dictType} != '') +#set($parentheseIndex=$column.columnComment.indexOf("锛�")) +#if($parentheseIndex != -1) +#set($comment=$column.columnComment.substring(0, $parentheseIndex)) +#else +#set($comment=$column.columnComment) +#end + // $comment瀛楀吀缈昏瘧 + ${column.javaField}Format(row, column) { + return this.selectDictLabel(this.${column.javaField}Options, row.${column.javaField}); + }, +#end +#end + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { +#foreach ($column in $columns) +#if($column.htmlType == "radio") + $column.javaField: "0"#if($velocityCount != $columns.size()),#end + +#else + $column.javaField: undefined#if($velocityCount != $columns.size()),#end + +#end +#end + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.${pkColumn.javaField}) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞${functionName}"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids + get${BusinessName}(${pkColumn.javaField}).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼${functionName}"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.#[[$]]#refs["form"].validate(valid => { + if (valid) { + if (this.form.${pkColumn.javaField} != undefined) { + update${BusinessName}(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } else { + add${BusinessName}(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + } else { + this.msgError(response.msg); + } + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const ${pkColumn.javaField}s = row.${pkColumn.javaField} || this.ids; + this.$confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + ${pkColumn.javaField}s + '"鐨勬暟鎹」?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return del${BusinessName}(${pkColumn.javaField}s); + }).then(() => { + this.getList(); + this.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(function() {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('鏄惁纭瀵煎嚭鎵�鏈�${functionName}鏁版嵁椤�?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(function() { + return export${BusinessName}(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } +}; +</script> \ No newline at end of file diff --git a/ruoyi/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi/src/main/resources/vm/xml/mapper.xml.vm new file mode 100644 index 0000000..7d75aa3 --- /dev/null +++ b/ruoyi/src/main/resources/vm/xml/mapper.xml.vm @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE mapper +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="${packageName}.mapper.${ClassName}Mapper"> + + <resultMap type="${ClassName}" id="${ClassName}Result"> +#foreach ($column in $columns) + <result property="${column.javaField}" column="${column.columnName}" /> +#end + </resultMap> + + <sql id="select${ClassName}Vo"> + select#foreach($column in $columns) $column.columnName#if($velocityCount != $columns.size()),#end#end from ${tableName} + </sql> + + <select id="select${ClassName}List" parameterType="${ClassName}" resultMap="${ClassName}Result"> + <include refid="select${ClassName}Vo"/> + <where> +#foreach($column in $columns) +#set($queryType=$column.queryType) +#set($javaField=$column.javaField) +#set($javaType=$column.javaType) +#set($columnName=$column.columnName) +#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) +#if($column.query) +#if($column.queryType == "EQ") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName = #{$javaField}</if> +#elseif($queryType == "NE") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName != #{$javaField}</if> +#elseif($queryType == "GT") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName > #{$javaField}</if> +#elseif($queryType == "GTE") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName >= #{$javaField}</if> +#elseif($queryType == "LT") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName < #{$javaField}</if> +#elseif($queryType == "LTE") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName <= #{$javaField}</if> +#elseif($queryType == "LIKE") + <if test="$javaField != null #if($javaType == 'String' ) and $javaField.trim() != ''#end"> and $columnName like concat('%', #{$javaField}, '%')</if> +#elseif($queryType == "BETWEEN") + <if test="params.begin$AttrName != null and params.begin$AttrName != '' and params.end$AttrName != null and params.end$AttrName != ''"> and $columnName between #{params.begin$AttrName} and #{params.end$AttrName}</if> +#end +#end +#end + </where> + </select> + + <select id="select${ClassName}ById" parameterType="${pkColumn.javaType}" resultMap="${ClassName}Result"> + <include refid="select${ClassName}Vo"/> + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + </select> + + <insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end> + insert into ${tableName} + <trim prefix="(" suffix=")" suffixOverrides=","> +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + <if test="$column.javaField != null #if($column.javaType == 'String' ) and $column.javaField != ''#end">$column.columnName,</if> +#end +#end + </trim> + <trim prefix="values (" suffix=")" suffixOverrides=","> +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment) + <if test="$column.javaField != null #if($column.javaType == 'String' ) and $column.javaField != ''#end">#{$column.javaField},</if> +#end +#end + </trim> + </insert> + + <update id="update${ClassName}" parameterType="${ClassName}"> + update ${tableName} + <trim prefix="SET" suffixOverrides=","> +#foreach($column in $columns) +#if($column.columnName != $pkColumn.columnName) + <if test="$column.javaField != null #if($column.javaType == 'String' ) and $column.javaField != ''#end">$column.columnName = #{$column.javaField},</if> +#end +#end + </trim> + where ${pkColumn.columnName} = #{${pkColumn.javaField}} + </update> + + <delete id="delete${ClassName}ById" parameterType="${pkColumn.javaType}"> + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} + </delete> + + <delete id="delete${ClassName}ByIds" parameterType="String"> + delete from ${tableName} where ${pkColumn.columnName} in + <foreach item="${pkColumn.javaField}" collection="array" open="(" separator="," close=")"> + #{${pkColumn.javaField}} + </foreach> + </delete> + +</mapper> \ No newline at end of file -- Gitblit v1.9.3